4 * Copyright 1998 Eric Kohl
5 * Copyright 1999 Francis Beaudet
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define WIN32_NO_STATUS
29 #define NONAMELESSUNION
30 #define NONAMELESSSTRUCT
34 //#include "winuser.h"
35 //#include "winerror.h"
36 #include <wine/debug.h>
39 //#include "compobj_private.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
43 #define INITIAL_SINKS 10
45 static void release_statdata(STATDATA
*data
)
47 if(data
->formatetc
.ptd
)
49 CoTaskMemFree(data
->formatetc
.ptd
);
50 data
->formatetc
.ptd
= NULL
;
55 IAdviseSink_Release(data
->pAdvSink
);
56 data
->pAdvSink
= NULL
;
60 static HRESULT
copy_statdata(STATDATA
*dst
, const STATDATA
*src
)
63 if(src
->formatetc
.ptd
)
65 dst
->formatetc
.ptd
= CoTaskMemAlloc(src
->formatetc
.ptd
->tdSize
);
66 if(!dst
->formatetc
.ptd
) return E_OUTOFMEMORY
;
67 memcpy(dst
->formatetc
.ptd
, src
->formatetc
.ptd
, src
->formatetc
.ptd
->tdSize
);
69 if(dst
->pAdvSink
) IAdviseSink_AddRef(dst
->pAdvSink
);
73 /**************************************************************************
74 * EnumSTATDATA Implementation
77 static HRESULT
EnumSTATDATA_Construct(IUnknown
*holder
, ULONG index
, DWORD array_len
, STATDATA
*data
, IEnumSTATDATA
**ppenum
);
81 IEnumSTATDATA IEnumSTATDATA_iface
;
90 static inline EnumSTATDATA
*impl_from_IEnumSTATDATA(IEnumSTATDATA
*iface
)
92 return CONTAINING_RECORD(iface
, EnumSTATDATA
, IEnumSTATDATA_iface
);
95 static HRESULT WINAPI
EnumSTATDATA_QueryInterface(IEnumSTATDATA
*iface
, REFIID riid
, void **ppv
)
97 TRACE("(%s, %p)\n", debugstr_guid(riid
), ppv
);
98 if (IsEqualIID(riid
, &IID_IUnknown
) ||
99 IsEqualIID(riid
, &IID_IEnumSTATDATA
))
101 IEnumSTATDATA_AddRef(iface
);
105 return E_NOINTERFACE
;
108 static ULONG WINAPI
EnumSTATDATA_AddRef(IEnumSTATDATA
*iface
)
110 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
112 return InterlockedIncrement(&This
->ref
);
115 static ULONG WINAPI
EnumSTATDATA_Release(IEnumSTATDATA
*iface
)
117 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
118 LONG refs
= InterlockedDecrement(&This
->ref
);
123 for(i
= 0; i
< This
->num_of_elems
; i
++)
124 release_statdata(This
->statdata
+ i
);
125 HeapFree(GetProcessHeap(), 0, This
->statdata
);
126 IUnknown_Release(This
->holder
);
127 HeapFree(GetProcessHeap(), 0, This
);
132 static HRESULT WINAPI
EnumSTATDATA_Next(IEnumSTATDATA
*iface
, ULONG num
, LPSTATDATA data
,
135 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
139 TRACE("(%d, %p, %p)\n", num
, data
, fetched
);
143 if (This
->index
>= This
->num_of_elems
)
149 copy_statdata(data
+ count
, This
->statdata
+ This
->index
);
155 if (fetched
) *fetched
= count
;
160 static HRESULT WINAPI
EnumSTATDATA_Skip(IEnumSTATDATA
*iface
, ULONG num
)
162 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
164 TRACE("(%d)\n", num
);
166 if(This
->index
+ num
>= This
->num_of_elems
)
168 This
->index
= This
->num_of_elems
;
176 static HRESULT WINAPI
EnumSTATDATA_Reset(IEnumSTATDATA
*iface
)
178 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
186 static HRESULT WINAPI
EnumSTATDATA_Clone(IEnumSTATDATA
*iface
, IEnumSTATDATA
**ppenum
)
188 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
190 return EnumSTATDATA_Construct(This
->holder
, This
->index
, This
->num_of_elems
, This
->statdata
, ppenum
);
193 static const IEnumSTATDATAVtbl EnumSTATDATA_VTable
=
195 EnumSTATDATA_QueryInterface
,
197 EnumSTATDATA_Release
,
204 static HRESULT
EnumSTATDATA_Construct(IUnknown
*holder
, ULONG index
, DWORD array_len
, STATDATA
*data
,
205 IEnumSTATDATA
**ppenum
)
207 EnumSTATDATA
*This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
210 if (!This
) return E_OUTOFMEMORY
;
212 This
->IEnumSTATDATA_iface
.lpVtbl
= &EnumSTATDATA_VTable
;
216 This
->statdata
= HeapAlloc(GetProcessHeap(), 0, array_len
* sizeof(*This
->statdata
));
219 HeapFree(GetProcessHeap(), 0, This
);
220 return E_OUTOFMEMORY
;
223 for(i
= 0, count
= 0; i
< array_len
; i
++)
227 copy_statdata(This
->statdata
+ count
, data
+ i
);
232 This
->num_of_elems
= count
;
233 This
->holder
= holder
;
234 IUnknown_AddRef(holder
);
235 *ppenum
= &This
->IEnumSTATDATA_iface
;
239 /**************************************************************************
240 * OleAdviseHolder Implementation
244 IOleAdviseHolder IOleAdviseHolder_iface
;
249 STATDATA
*connections
;
250 } OleAdviseHolderImpl
;
252 static inline OleAdviseHolderImpl
*impl_from_IOleAdviseHolder(IOleAdviseHolder
*iface
)
254 return CONTAINING_RECORD(iface
, OleAdviseHolderImpl
, IOleAdviseHolder_iface
);
257 /**************************************************************************
258 * OleAdviseHolderImpl_Destructor
260 static void OleAdviseHolderImpl_Destructor(OleAdviseHolderImpl
*This
)
265 for (index
= 0; index
< This
->max_cons
; index
++)
267 if (This
->connections
[index
].pAdvSink
!= NULL
)
268 release_statdata(This
->connections
+ index
);
271 HeapFree(GetProcessHeap(), 0, This
->connections
);
272 HeapFree(GetProcessHeap(), 0, This
);
275 /**************************************************************************
276 * OleAdviseHolderImpl_QueryInterface
278 static HRESULT WINAPI
OleAdviseHolderImpl_QueryInterface(IOleAdviseHolder
*iface
,
279 REFIID iid
, void **obj
)
281 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
282 TRACE("(%p)->(%s,%p)\n",This
, debugstr_guid(iid
), obj
);
289 if (IsEqualIID(iid
, &IID_IUnknown
) ||
290 IsEqualIID(iid
, &IID_IOleAdviseHolder
))
292 *obj
= &This
->IOleAdviseHolder_iface
;
296 return E_NOINTERFACE
;
298 IUnknown_AddRef((IUnknown
*)*obj
);
303 /******************************************************************************
304 * OleAdviseHolderImpl_AddRef
306 static ULONG WINAPI
OleAdviseHolderImpl_AddRef(IOleAdviseHolder
*iface
)
308 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
309 ULONG ref
= InterlockedIncrement(&This
->ref
);
311 TRACE("(%p)->(ref=%d)\n", This
, ref
- 1);
316 /******************************************************************************
317 * OleAdviseHolderImpl_Release
319 static ULONG WINAPI
OleAdviseHolderImpl_Release(IOleAdviseHolder
*iface
)
321 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
323 TRACE("(%p)->(ref=%d)\n", This
, This
->ref
);
324 ref
= InterlockedDecrement(&This
->ref
);
326 if (ref
== 0) OleAdviseHolderImpl_Destructor(This
);
331 /******************************************************************************
332 * OleAdviseHolderImpl_Advise
334 static HRESULT WINAPI
OleAdviseHolderImpl_Advise(IOleAdviseHolder
*iface
,
335 IAdviseSink
*pAdvise
,
336 DWORD
*pdwConnection
)
339 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
341 static const FORMATETC empty_fmtetc
= {0, NULL
, 0, -1, 0};
343 TRACE("(%p)->(%p, %p)\n", This
, pAdvise
, pdwConnection
);
345 if (pdwConnection
==NULL
)
350 for (index
= 0; index
< This
->max_cons
; index
++)
352 if (This
->connections
[index
].pAdvSink
== NULL
)
356 if (index
== This
->max_cons
)
358 This
->max_cons
+= INITIAL_SINKS
;
359 This
->connections
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, This
->connections
,
360 This
->max_cons
* sizeof(*This
->connections
));
363 new_conn
.pAdvSink
= pAdvise
;
365 new_conn
.formatetc
= empty_fmtetc
;
366 new_conn
.dwConnection
= index
+ 1; /* 0 is not a valid cookie, so increment the index */
368 copy_statdata(This
->connections
+ index
, &new_conn
);
370 *pdwConnection
= new_conn
.dwConnection
;
375 /******************************************************************************
376 * OleAdviseHolderImpl_Unadvise
378 static HRESULT WINAPI
OleAdviseHolderImpl_Unadvise(IOleAdviseHolder
*iface
,
381 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
384 TRACE("(%p)->(%u)\n", This
, dwConnection
);
386 /* The connection number is 1 more than the index, see OleAdviseHolder_Advise */
387 index
= dwConnection
- 1;
389 if (index
>= This
->max_cons
|| This
->connections
[index
].pAdvSink
== NULL
)
390 return OLE_E_NOCONNECTION
;
392 release_statdata(This
->connections
+ index
);
397 /******************************************************************************
398 * OleAdviseHolderImpl_EnumAdvise
400 static HRESULT WINAPI
OleAdviseHolderImpl_EnumAdvise(IOleAdviseHolder
*iface
, IEnumSTATDATA
**enum_advise
)
402 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
406 TRACE("(%p)->(%p)\n", This
, enum_advise
);
408 IOleAdviseHolder_QueryInterface(iface
, &IID_IUnknown
, (void**)&unk
);
409 hr
= EnumSTATDATA_Construct(unk
, 0, This
->max_cons
, This
->connections
, enum_advise
);
410 IUnknown_Release(unk
);
414 /******************************************************************************
415 * OleAdviseHolderImpl_SendOnRename
417 static HRESULT WINAPI
OleAdviseHolderImpl_SendOnRename(IOleAdviseHolder
*iface
, IMoniker
*pmk
)
419 IEnumSTATDATA
*pEnum
;
422 TRACE("(%p)->(%p)\n", iface
, pmk
);
424 hr
= IOleAdviseHolder_EnumAdvise(iface
, &pEnum
);
428 while (IEnumSTATDATA_Next(pEnum
, 1, &statdata
, NULL
) == S_OK
)
430 IAdviseSink_OnRename(statdata
.pAdvSink
, pmk
);
432 IAdviseSink_Release(statdata
.pAdvSink
);
434 IEnumSTATDATA_Release(pEnum
);
440 /******************************************************************************
441 * OleAdviseHolderImpl_SendOnSave
443 static HRESULT WINAPI
OleAdviseHolderImpl_SendOnSave(IOleAdviseHolder
*iface
)
445 IEnumSTATDATA
*pEnum
;
448 TRACE("(%p)->()\n", iface
);
450 hr
= IOleAdviseHolder_EnumAdvise(iface
, &pEnum
);
454 while (IEnumSTATDATA_Next(pEnum
, 1, &statdata
, NULL
) == S_OK
)
456 IAdviseSink_OnSave(statdata
.pAdvSink
);
458 IAdviseSink_Release(statdata
.pAdvSink
);
460 IEnumSTATDATA_Release(pEnum
);
466 /******************************************************************************
467 * OleAdviseHolderImpl_SendOnClose
469 static HRESULT WINAPI
OleAdviseHolderImpl_SendOnClose(IOleAdviseHolder
*iface
)
471 IEnumSTATDATA
*pEnum
;
474 TRACE("(%p)->()\n", iface
);
476 hr
= IOleAdviseHolder_EnumAdvise(iface
, &pEnum
);
480 while (IEnumSTATDATA_Next(pEnum
, 1, &statdata
, NULL
) == S_OK
)
482 IAdviseSink_OnClose(statdata
.pAdvSink
);
484 IAdviseSink_Release(statdata
.pAdvSink
);
486 IEnumSTATDATA_Release(pEnum
);
492 /**************************************************************************
493 * OleAdviseHolderImpl_VTable
495 static const IOleAdviseHolderVtbl oahvt
=
497 OleAdviseHolderImpl_QueryInterface
,
498 OleAdviseHolderImpl_AddRef
,
499 OleAdviseHolderImpl_Release
,
500 OleAdviseHolderImpl_Advise
,
501 OleAdviseHolderImpl_Unadvise
,
502 OleAdviseHolderImpl_EnumAdvise
,
503 OleAdviseHolderImpl_SendOnRename
,
504 OleAdviseHolderImpl_SendOnSave
,
505 OleAdviseHolderImpl_SendOnClose
508 /**************************************************************************
509 * OleAdviseHolderImpl_Constructor
512 static IOleAdviseHolder
*OleAdviseHolderImpl_Constructor(void)
514 OleAdviseHolderImpl
* lpoah
;
516 lpoah
= HeapAlloc(GetProcessHeap(), 0, sizeof(OleAdviseHolderImpl
));
518 lpoah
->IOleAdviseHolder_iface
.lpVtbl
= &oahvt
;
520 lpoah
->max_cons
= INITIAL_SINKS
;
521 lpoah
->connections
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
522 lpoah
->max_cons
* sizeof(*lpoah
->connections
));
524 TRACE("returning %p\n", &lpoah
->IOleAdviseHolder_iface
);
525 return &lpoah
->IOleAdviseHolder_iface
;
528 /**************************************************************************
529 * DataAdviseHolder Implementation
533 IDataAdviseHolder IDataAdviseHolder_iface
;
537 STATDATA
* connections
;
538 DWORD
* remote_connections
;
539 IDataObject
* delegate
;
542 /* this connection has also has been advised to the delegate data object */
543 #define WINE_ADVF_REMOTE 0x80000000
545 static inline DataAdviseHolder
*impl_from_IDataAdviseHolder(IDataAdviseHolder
*iface
)
547 return CONTAINING_RECORD(iface
, DataAdviseHolder
, IDataAdviseHolder_iface
);
550 /******************************************************************************
551 * DataAdviseHolder_Destructor
553 static void DataAdviseHolder_Destructor(DataAdviseHolder
* ptrToDestroy
)
556 TRACE("%p\n", ptrToDestroy
);
558 for (index
= 0; index
< ptrToDestroy
->maxCons
; index
++)
560 if (ptrToDestroy
->connections
[index
].pAdvSink
!= NULL
)
562 if (ptrToDestroy
->delegate
&&
563 (ptrToDestroy
->connections
[index
].advf
& WINE_ADVF_REMOTE
))
564 IDataObject_DUnadvise(ptrToDestroy
->delegate
,
565 ptrToDestroy
->remote_connections
[index
]);
567 release_statdata(ptrToDestroy
->connections
+ index
);
571 HeapFree(GetProcessHeap(), 0, ptrToDestroy
->remote_connections
);
572 HeapFree(GetProcessHeap(), 0, ptrToDestroy
->connections
);
573 HeapFree(GetProcessHeap(), 0, ptrToDestroy
);
576 /************************************************************************
577 * DataAdviseHolder_QueryInterface (IUnknown)
579 static HRESULT WINAPI
DataAdviseHolder_QueryInterface(IDataAdviseHolder
*iface
,
580 REFIID riid
, void **ppvObject
)
582 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
583 TRACE("(%p)->(%s,%p)\n",This
,debugstr_guid(riid
),ppvObject
);
585 if ( (This
==0) || (ppvObject
==0) )
590 if ( IsEqualIID(&IID_IUnknown
, riid
) ||
591 IsEqualIID(&IID_IDataAdviseHolder
, riid
) )
598 return E_NOINTERFACE
;
601 IUnknown_AddRef((IUnknown
*)*ppvObject
);
605 /************************************************************************
606 * DataAdviseHolder_AddRef (IUnknown)
608 static ULONG WINAPI
DataAdviseHolder_AddRef(IDataAdviseHolder
*iface
)
610 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
611 TRACE("(%p) (ref=%d)\n", This
, This
->ref
);
612 return InterlockedIncrement(&This
->ref
);
615 /************************************************************************
616 * DataAdviseHolder_Release (IUnknown)
618 static ULONG WINAPI
DataAdviseHolder_Release(IDataAdviseHolder
*iface
)
620 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
622 TRACE("(%p) (ref=%d)\n", This
, This
->ref
);
624 ref
= InterlockedDecrement(&This
->ref
);
625 if (ref
==0) DataAdviseHolder_Destructor(This
);
630 /************************************************************************
631 * DataAdviseHolder_Advise
634 static HRESULT WINAPI
DataAdviseHolder_Advise(IDataAdviseHolder
*iface
,
635 IDataObject
*pDataObject
, FORMATETC
*pFetc
,
636 DWORD advf
, IAdviseSink
*pAdvise
,
637 DWORD
*pdwConnection
)
641 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
643 TRACE("(%p)->(%p, %p, %08x, %p, %p)\n", This
, pDataObject
, pFetc
, advf
,
644 pAdvise
, pdwConnection
);
646 if (pdwConnection
==NULL
)
651 for (index
= 0; index
< This
->maxCons
; index
++)
653 if (This
->connections
[index
].pAdvSink
== NULL
)
657 if (index
== This
->maxCons
)
659 This
->maxCons
+=INITIAL_SINKS
;
660 This
->connections
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
662 This
->maxCons
* sizeof(*This
->connections
));
663 This
->remote_connections
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
664 This
->remote_connections
,
665 This
->maxCons
* sizeof(*This
->remote_connections
));
668 new_conn
.pAdvSink
= pAdvise
;
669 new_conn
.advf
= advf
& ~WINE_ADVF_REMOTE
;
670 new_conn
.formatetc
= *pFetc
;
671 new_conn
.dwConnection
= index
+ 1; /* 0 is not a valid cookie, so increment the index */
673 copy_statdata(This
->connections
+ index
, &new_conn
);
675 if (This
->connections
[index
].pAdvSink
!= NULL
)
677 /* if we are already connected advise the remote object */
682 hr
= IDataObject_DAdvise(This
->delegate
, &new_conn
.formatetc
,
683 new_conn
.advf
, new_conn
.pAdvSink
,
684 &This
->remote_connections
[index
]);
687 IDataAdviseHolder_Unadvise(iface
, new_conn
.dwConnection
);
690 This
->connections
[index
].advf
|= WINE_ADVF_REMOTE
;
692 else if(advf
& ADVF_PRIMEFIRST
)
693 /* only do this if we have no delegate, since in the above case the
694 * delegate will do the priming for us */
695 IDataAdviseHolder_SendOnDataChange(iface
, pDataObject
, 0, advf
);
698 *pdwConnection
= new_conn
.dwConnection
;
703 /******************************************************************************
704 * DataAdviseHolder_Unadvise
706 static HRESULT WINAPI
DataAdviseHolder_Unadvise(IDataAdviseHolder
*iface
,
709 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
711 TRACE("(%p)->(%u)\n", This
, dwConnection
);
713 /* The connection number is 1 more than the index, see DataAdviseHolder_Advise */
714 index
= dwConnection
- 1;
716 if (index
>= This
->maxCons
|| This
->connections
[index
].pAdvSink
== NULL
)
717 return OLE_E_NOCONNECTION
;
719 if (This
->delegate
&& This
->connections
[index
].advf
& WINE_ADVF_REMOTE
)
721 IDataObject_DUnadvise(This
->delegate
, This
->remote_connections
[index
]);
722 This
->remote_connections
[index
] = 0;
725 release_statdata(This
->connections
+ index
);
730 /******************************************************************************
731 * DataAdviseHolder_EnumAdvise
733 static HRESULT WINAPI
DataAdviseHolder_EnumAdvise(IDataAdviseHolder
*iface
,
734 IEnumSTATDATA
**enum_advise
)
736 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
740 TRACE("(%p)->(%p)\n", This
, enum_advise
);
742 IDataAdviseHolder_QueryInterface(iface
, &IID_IUnknown
, (void**)&unk
);
743 hr
= EnumSTATDATA_Construct(unk
, 0, This
->maxCons
, This
->connections
, enum_advise
);
744 IUnknown_Release(unk
);
748 /******************************************************************************
749 * DataAdviseHolder_SendOnDataChange
751 static HRESULT WINAPI
DataAdviseHolder_SendOnDataChange(IDataAdviseHolder
*iface
,
752 IDataObject
*data_obj
,
753 DWORD dwReserved
, DWORD advf
)
755 IEnumSTATDATA
*pEnum
;
758 TRACE("(%p)->(%p, %08x, %08x)\n", iface
, data_obj
, dwReserved
, advf
);
760 hr
= IDataAdviseHolder_EnumAdvise(iface
, &pEnum
);
764 while (IEnumSTATDATA_Next(pEnum
, 1, &statdata
, NULL
) == S_OK
)
767 stg
.tymed
= TYMED_NULL
;
769 stg
.pUnkForRelease
= NULL
;
771 if(!(statdata
.advf
& ADVF_NODATA
))
773 hr
= IDataObject_GetData(data_obj
, &statdata
.formatetc
, &stg
);
776 IAdviseSink_OnDataChange(statdata
.pAdvSink
, &statdata
.formatetc
, &stg
);
778 if(statdata
.advf
& ADVF_ONLYONCE
)
780 IDataAdviseHolder_Unadvise(iface
, statdata
.dwConnection
);
783 release_statdata(&statdata
);
785 IEnumSTATDATA_Release(pEnum
);
791 /**************************************************************************
792 * DataAdviseHolderImpl_VTable
794 static const IDataAdviseHolderVtbl DataAdviseHolderImpl_VTable
=
796 DataAdviseHolder_QueryInterface
,
797 DataAdviseHolder_AddRef
,
798 DataAdviseHolder_Release
,
799 DataAdviseHolder_Advise
,
800 DataAdviseHolder_Unadvise
,
801 DataAdviseHolder_EnumAdvise
,
802 DataAdviseHolder_SendOnDataChange
805 HRESULT
DataAdviseHolder_OnConnect(IDataAdviseHolder
*iface
, IDataObject
*pDelegate
)
807 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
811 for(index
= 0; index
< This
->maxCons
; index
++)
813 if(This
->connections
[index
].pAdvSink
!= NULL
)
815 hr
= IDataObject_DAdvise(pDelegate
, &This
->connections
[index
].formatetc
,
816 This
->connections
[index
].advf
,
817 This
->connections
[index
].pAdvSink
,
818 &This
->remote_connections
[index
]);
819 if (FAILED(hr
)) break;
820 This
->connections
[index
].advf
|= WINE_ADVF_REMOTE
;
823 This
->delegate
= pDelegate
;
827 void DataAdviseHolder_OnDisconnect(IDataAdviseHolder
*iface
)
829 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
832 for(index
= 0; index
< This
->maxCons
; index
++)
834 if((This
->connections
[index
].pAdvSink
!= NULL
) &&
835 (This
->connections
[index
].advf
& WINE_ADVF_REMOTE
))
837 IDataObject_DUnadvise(This
->delegate
, This
->remote_connections
[index
]);
838 This
->remote_connections
[index
] = 0;
839 This
->connections
[index
].advf
&= ~WINE_ADVF_REMOTE
;
842 This
->delegate
= NULL
;
845 /******************************************************************************
846 * DataAdviseHolder_Constructor
848 static IDataAdviseHolder
*DataAdviseHolder_Constructor(void)
850 DataAdviseHolder
* newHolder
;
852 newHolder
= HeapAlloc(GetProcessHeap(), 0, sizeof(DataAdviseHolder
));
854 newHolder
->IDataAdviseHolder_iface
.lpVtbl
= &DataAdviseHolderImpl_VTable
;
856 newHolder
->maxCons
= INITIAL_SINKS
;
857 newHolder
->connections
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
858 newHolder
->maxCons
* sizeof(*newHolder
->connections
));
859 newHolder
->remote_connections
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
860 newHolder
->maxCons
* sizeof(*newHolder
->remote_connections
));
861 newHolder
->delegate
= NULL
;
863 TRACE("returning %p\n", &newHolder
->IDataAdviseHolder_iface
);
864 return &newHolder
->IDataAdviseHolder_iface
;
867 /***********************************************************************
871 /***********************************************************************
872 * CreateOleAdviseHolder [OLE32.@]
874 HRESULT WINAPI
CreateOleAdviseHolder(IOleAdviseHolder
**ppOAHolder
)
876 TRACE("(%p)\n", ppOAHolder
);
878 if (ppOAHolder
==NULL
)
881 *ppOAHolder
= OleAdviseHolderImpl_Constructor ();
883 if (*ppOAHolder
!= NULL
)
886 return E_OUTOFMEMORY
;
889 /******************************************************************************
890 * CreateDataAdviseHolder [OLE32.@]
892 HRESULT WINAPI
CreateDataAdviseHolder(IDataAdviseHolder
**ppDAHolder
)
894 TRACE("(%p)\n", ppDAHolder
);
896 if (ppDAHolder
==NULL
)
899 *ppDAHolder
= DataAdviseHolder_Constructor();
901 if (*ppDAHolder
!= NULL
)
904 return E_OUTOFMEMORY
;