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
27 #define NONAMELESSUNION
33 #include "wine/debug.h"
36 #include "compobj_private.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
40 #define INITIAL_SINKS 10
42 static void release_statdata(STATDATA
*data
)
44 if(data
->formatetc
.ptd
)
46 CoTaskMemFree(data
->formatetc
.ptd
);
47 data
->formatetc
.ptd
= NULL
;
52 IAdviseSink_Release(data
->pAdvSink
);
53 data
->pAdvSink
= NULL
;
57 static HRESULT
copy_statdata(STATDATA
*dst
, const STATDATA
*src
)
60 if(src
->formatetc
.ptd
)
62 dst
->formatetc
.ptd
= CoTaskMemAlloc(src
->formatetc
.ptd
->tdSize
);
63 if(!dst
->formatetc
.ptd
) return E_OUTOFMEMORY
;
64 memcpy(dst
->formatetc
.ptd
, src
->formatetc
.ptd
, src
->formatetc
.ptd
->tdSize
);
66 if(dst
->pAdvSink
) IAdviseSink_AddRef(dst
->pAdvSink
);
70 /**************************************************************************
71 * EnumSTATDATA Implementation
74 static HRESULT
EnumSTATDATA_Construct(IUnknown
*holder
, ULONG index
, DWORD array_len
, STATDATA
*data
, IEnumSTATDATA
**ppenum
);
78 IEnumSTATDATA IEnumSTATDATA_iface
;
87 static inline EnumSTATDATA
*impl_from_IEnumSTATDATA(IEnumSTATDATA
*iface
)
89 return CONTAINING_RECORD(iface
, EnumSTATDATA
, IEnumSTATDATA_iface
);
92 static HRESULT WINAPI
EnumSTATDATA_QueryInterface(IEnumSTATDATA
*iface
, REFIID riid
, void **ppv
)
94 TRACE("(%s, %p)\n", debugstr_guid(riid
), ppv
);
95 if (IsEqualIID(riid
, &IID_IUnknown
) ||
96 IsEqualIID(riid
, &IID_IEnumSTATDATA
))
98 IEnumSTATDATA_AddRef(iface
);
102 return E_NOINTERFACE
;
105 static ULONG WINAPI
EnumSTATDATA_AddRef(IEnumSTATDATA
*iface
)
107 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
109 return InterlockedIncrement(&This
->ref
);
112 static ULONG WINAPI
EnumSTATDATA_Release(IEnumSTATDATA
*iface
)
114 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
115 LONG refs
= InterlockedDecrement(&This
->ref
);
120 for(i
= 0; i
< This
->num_of_elems
; i
++)
121 release_statdata(This
->statdata
+ i
);
122 HeapFree(GetProcessHeap(), 0, This
->statdata
);
123 IUnknown_Release(This
->holder
);
124 HeapFree(GetProcessHeap(), 0, This
);
129 static HRESULT WINAPI
EnumSTATDATA_Next(IEnumSTATDATA
*iface
, ULONG num
, LPSTATDATA data
,
132 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
136 TRACE("(%d, %p, %p)\n", num
, data
, fetched
);
140 if (This
->index
>= This
->num_of_elems
)
146 copy_statdata(data
+ count
, This
->statdata
+ This
->index
);
152 if (fetched
) *fetched
= count
;
157 static HRESULT WINAPI
EnumSTATDATA_Skip(IEnumSTATDATA
*iface
, ULONG num
)
159 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
161 TRACE("(%d)\n", num
);
163 if(This
->index
+ num
>= This
->num_of_elems
)
165 This
->index
= This
->num_of_elems
;
173 static HRESULT WINAPI
EnumSTATDATA_Reset(IEnumSTATDATA
*iface
)
175 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
183 static HRESULT WINAPI
EnumSTATDATA_Clone(IEnumSTATDATA
*iface
, IEnumSTATDATA
**ppenum
)
185 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
187 return EnumSTATDATA_Construct(This
->holder
, This
->index
, This
->num_of_elems
, This
->statdata
, ppenum
);
190 static const IEnumSTATDATAVtbl EnumSTATDATA_VTable
=
192 EnumSTATDATA_QueryInterface
,
194 EnumSTATDATA_Release
,
201 static HRESULT
EnumSTATDATA_Construct(IUnknown
*holder
, ULONG index
, DWORD array_len
, STATDATA
*data
,
202 IEnumSTATDATA
**ppenum
)
204 EnumSTATDATA
*This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
207 if (!This
) return E_OUTOFMEMORY
;
209 This
->IEnumSTATDATA_iface
.lpVtbl
= &EnumSTATDATA_VTable
;
213 This
->statdata
= HeapAlloc(GetProcessHeap(), 0, array_len
* sizeof(*This
->statdata
));
216 HeapFree(GetProcessHeap(), 0, This
);
217 return E_OUTOFMEMORY
;
220 for(i
= 0, count
= 0; i
< array_len
; i
++)
224 copy_statdata(This
->statdata
+ count
, data
+ i
);
229 This
->num_of_elems
= count
;
230 This
->holder
= holder
;
231 IUnknown_AddRef(holder
);
232 *ppenum
= &This
->IEnumSTATDATA_iface
;
236 /**************************************************************************
237 * OleAdviseHolder Implementation
241 IOleAdviseHolder IOleAdviseHolder_iface
;
246 STATDATA
*connections
;
247 } OleAdviseHolderImpl
;
249 static inline OleAdviseHolderImpl
*impl_from_IOleAdviseHolder(IOleAdviseHolder
*iface
)
251 return CONTAINING_RECORD(iface
, OleAdviseHolderImpl
, IOleAdviseHolder_iface
);
254 /**************************************************************************
255 * OleAdviseHolderImpl_Destructor
257 static void OleAdviseHolderImpl_Destructor(OleAdviseHolderImpl
*This
)
262 for (index
= 0; index
< This
->max_cons
; index
++)
264 if (This
->connections
[index
].pAdvSink
!= NULL
)
265 release_statdata(This
->connections
+ index
);
268 HeapFree(GetProcessHeap(), 0, This
->connections
);
269 HeapFree(GetProcessHeap(), 0, This
);
272 /**************************************************************************
273 * OleAdviseHolderImpl_QueryInterface
275 static HRESULT WINAPI
OleAdviseHolderImpl_QueryInterface(IOleAdviseHolder
*iface
,
276 REFIID iid
, void **obj
)
278 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
279 TRACE("(%p)->(%s,%p)\n",This
, debugstr_guid(iid
), obj
);
286 if (IsEqualIID(iid
, &IID_IUnknown
) ||
287 IsEqualIID(iid
, &IID_IOleAdviseHolder
))
289 *obj
= &This
->IOleAdviseHolder_iface
;
293 return E_NOINTERFACE
;
295 IUnknown_AddRef((IUnknown
*)*obj
);
300 /******************************************************************************
301 * OleAdviseHolderImpl_AddRef
303 static ULONG WINAPI
OleAdviseHolderImpl_AddRef(IOleAdviseHolder
*iface
)
305 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
306 ULONG ref
= InterlockedIncrement(&This
->ref
);
308 TRACE("(%p)->(ref=%d)\n", This
, ref
- 1);
313 /******************************************************************************
314 * OleAdviseHolderImpl_Release
316 static ULONG WINAPI
OleAdviseHolderImpl_Release(IOleAdviseHolder
*iface
)
318 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
320 TRACE("(%p)->(ref=%d)\n", This
, This
->ref
);
321 ref
= InterlockedDecrement(&This
->ref
);
323 if (ref
== 0) OleAdviseHolderImpl_Destructor(This
);
328 /******************************************************************************
329 * OleAdviseHolderImpl_Advise
331 static HRESULT WINAPI
OleAdviseHolderImpl_Advise(IOleAdviseHolder
*iface
,
332 IAdviseSink
*pAdvise
,
333 DWORD
*pdwConnection
)
336 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
338 static const FORMATETC empty_fmtetc
= {0, NULL
, 0, -1, 0};
340 TRACE("(%p)->(%p, %p)\n", This
, pAdvise
, pdwConnection
);
342 if (pdwConnection
==NULL
)
347 for (index
= 0; index
< This
->max_cons
; index
++)
349 if (This
->connections
[index
].pAdvSink
== NULL
)
353 if (index
== This
->max_cons
)
355 This
->max_cons
+= INITIAL_SINKS
;
356 This
->connections
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, This
->connections
,
357 This
->max_cons
* sizeof(*This
->connections
));
360 new_conn
.pAdvSink
= pAdvise
;
362 new_conn
.formatetc
= empty_fmtetc
;
363 new_conn
.dwConnection
= index
+ 1; /* 0 is not a valid cookie, so increment the index */
365 copy_statdata(This
->connections
+ index
, &new_conn
);
367 *pdwConnection
= new_conn
.dwConnection
;
372 /******************************************************************************
373 * OleAdviseHolderImpl_Unadvise
375 static HRESULT WINAPI
OleAdviseHolderImpl_Unadvise(IOleAdviseHolder
*iface
,
378 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
381 TRACE("(%p)->(%u)\n", This
, dwConnection
);
383 /* The connection number is 1 more than the index, see OleAdviseHolder_Advise */
384 index
= dwConnection
- 1;
386 if (index
>= This
->max_cons
|| This
->connections
[index
].pAdvSink
== NULL
)
387 return OLE_E_NOCONNECTION
;
389 release_statdata(This
->connections
+ index
);
394 /******************************************************************************
395 * OleAdviseHolderImpl_EnumAdvise
397 static HRESULT WINAPI
OleAdviseHolderImpl_EnumAdvise(IOleAdviseHolder
*iface
, IEnumSTATDATA
**enum_advise
)
399 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
403 TRACE("(%p)->(%p)\n", This
, enum_advise
);
405 IOleAdviseHolder_QueryInterface(iface
, &IID_IUnknown
, (void**)&unk
);
406 hr
= EnumSTATDATA_Construct(unk
, 0, This
->max_cons
, This
->connections
, enum_advise
);
407 IUnknown_Release(unk
);
411 /******************************************************************************
412 * OleAdviseHolderImpl_SendOnRename
414 static HRESULT WINAPI
OleAdviseHolderImpl_SendOnRename(IOleAdviseHolder
*iface
, IMoniker
*pmk
)
416 IEnumSTATDATA
*pEnum
;
419 TRACE("(%p)->(%p)\n", iface
, pmk
);
421 hr
= IOleAdviseHolder_EnumAdvise(iface
, &pEnum
);
425 while (IEnumSTATDATA_Next(pEnum
, 1, &statdata
, NULL
) == S_OK
)
427 IAdviseSink_OnRename(statdata
.pAdvSink
, pmk
);
429 IAdviseSink_Release(statdata
.pAdvSink
);
431 IEnumSTATDATA_Release(pEnum
);
437 /******************************************************************************
438 * OleAdviseHolderImpl_SendOnSave
440 static HRESULT WINAPI
OleAdviseHolderImpl_SendOnSave(IOleAdviseHolder
*iface
)
442 IEnumSTATDATA
*pEnum
;
445 TRACE("(%p)->()\n", iface
);
447 hr
= IOleAdviseHolder_EnumAdvise(iface
, &pEnum
);
451 while (IEnumSTATDATA_Next(pEnum
, 1, &statdata
, NULL
) == S_OK
)
453 IAdviseSink_OnSave(statdata
.pAdvSink
);
455 IAdviseSink_Release(statdata
.pAdvSink
);
457 IEnumSTATDATA_Release(pEnum
);
463 /******************************************************************************
464 * OleAdviseHolderImpl_SendOnClose
466 static HRESULT WINAPI
OleAdviseHolderImpl_SendOnClose(IOleAdviseHolder
*iface
)
468 IEnumSTATDATA
*pEnum
;
471 TRACE("(%p)->()\n", iface
);
473 hr
= IOleAdviseHolder_EnumAdvise(iface
, &pEnum
);
477 while (IEnumSTATDATA_Next(pEnum
, 1, &statdata
, NULL
) == S_OK
)
479 IAdviseSink_OnClose(statdata
.pAdvSink
);
481 IAdviseSink_Release(statdata
.pAdvSink
);
483 IEnumSTATDATA_Release(pEnum
);
489 /**************************************************************************
490 * OleAdviseHolderImpl_VTable
492 static const IOleAdviseHolderVtbl oahvt
=
494 OleAdviseHolderImpl_QueryInterface
,
495 OleAdviseHolderImpl_AddRef
,
496 OleAdviseHolderImpl_Release
,
497 OleAdviseHolderImpl_Advise
,
498 OleAdviseHolderImpl_Unadvise
,
499 OleAdviseHolderImpl_EnumAdvise
,
500 OleAdviseHolderImpl_SendOnRename
,
501 OleAdviseHolderImpl_SendOnSave
,
502 OleAdviseHolderImpl_SendOnClose
505 /**************************************************************************
506 * OleAdviseHolderImpl_Constructor
509 static IOleAdviseHolder
*OleAdviseHolderImpl_Constructor(void)
511 OleAdviseHolderImpl
* lpoah
;
513 lpoah
= HeapAlloc(GetProcessHeap(), 0, sizeof(OleAdviseHolderImpl
));
515 lpoah
->IOleAdviseHolder_iface
.lpVtbl
= &oahvt
;
517 lpoah
->max_cons
= INITIAL_SINKS
;
518 lpoah
->connections
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
519 lpoah
->max_cons
* sizeof(*lpoah
->connections
));
521 TRACE("returning %p\n", &lpoah
->IOleAdviseHolder_iface
);
522 return &lpoah
->IOleAdviseHolder_iface
;
525 /**************************************************************************
526 * DataAdviseHolder Implementation
530 IDataAdviseHolder IDataAdviseHolder_iface
;
534 STATDATA
* connections
;
535 DWORD
* remote_connections
;
536 IDataObject
* delegate
;
539 /* this connection has also has been advised to the delegate data object */
540 #define WINE_ADVF_REMOTE 0x80000000
542 static inline DataAdviseHolder
*impl_from_IDataAdviseHolder(IDataAdviseHolder
*iface
)
544 return CONTAINING_RECORD(iface
, DataAdviseHolder
, IDataAdviseHolder_iface
);
547 /******************************************************************************
548 * DataAdviseHolder_Destructor
550 static void DataAdviseHolder_Destructor(DataAdviseHolder
* ptrToDestroy
)
553 TRACE("%p\n", ptrToDestroy
);
555 for (index
= 0; index
< ptrToDestroy
->maxCons
; index
++)
557 if (ptrToDestroy
->connections
[index
].pAdvSink
!= NULL
)
559 if (ptrToDestroy
->delegate
&&
560 (ptrToDestroy
->connections
[index
].advf
& WINE_ADVF_REMOTE
))
561 IDataObject_DUnadvise(ptrToDestroy
->delegate
,
562 ptrToDestroy
->remote_connections
[index
]);
564 release_statdata(ptrToDestroy
->connections
+ index
);
568 HeapFree(GetProcessHeap(), 0, ptrToDestroy
->remote_connections
);
569 HeapFree(GetProcessHeap(), 0, ptrToDestroy
->connections
);
570 HeapFree(GetProcessHeap(), 0, ptrToDestroy
);
573 /************************************************************************
574 * DataAdviseHolder_QueryInterface (IUnknown)
576 static HRESULT WINAPI
DataAdviseHolder_QueryInterface(IDataAdviseHolder
*iface
,
577 REFIID riid
, void **ppvObject
)
579 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
580 TRACE("(%p)->(%s,%p)\n",This
,debugstr_guid(riid
),ppvObject
);
582 if ( (This
==0) || (ppvObject
==0) )
587 if ( IsEqualIID(&IID_IUnknown
, riid
) ||
588 IsEqualIID(&IID_IDataAdviseHolder
, riid
) )
595 return E_NOINTERFACE
;
598 IUnknown_AddRef((IUnknown
*)*ppvObject
);
602 /************************************************************************
603 * DataAdviseHolder_AddRef (IUnknown)
605 static ULONG WINAPI
DataAdviseHolder_AddRef(IDataAdviseHolder
*iface
)
607 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
608 TRACE("(%p) (ref=%d)\n", This
, This
->ref
);
609 return InterlockedIncrement(&This
->ref
);
612 /************************************************************************
613 * DataAdviseHolder_Release (IUnknown)
615 static ULONG WINAPI
DataAdviseHolder_Release(IDataAdviseHolder
*iface
)
617 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
619 TRACE("(%p) (ref=%d)\n", This
, This
->ref
);
621 ref
= InterlockedDecrement(&This
->ref
);
622 if (ref
==0) DataAdviseHolder_Destructor(This
);
627 /************************************************************************
628 * DataAdviseHolder_Advise
631 static HRESULT WINAPI
DataAdviseHolder_Advise(IDataAdviseHolder
*iface
,
632 IDataObject
*pDataObject
, FORMATETC
*pFetc
,
633 DWORD advf
, IAdviseSink
*pAdvise
,
634 DWORD
*pdwConnection
)
638 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
640 TRACE("(%p)->(%p, %p, %08x, %p, %p)\n", This
, pDataObject
, pFetc
, advf
,
641 pAdvise
, pdwConnection
);
643 if (pdwConnection
==NULL
)
648 for (index
= 0; index
< This
->maxCons
; index
++)
650 if (This
->connections
[index
].pAdvSink
== NULL
)
654 if (index
== This
->maxCons
)
656 This
->maxCons
+=INITIAL_SINKS
;
657 This
->connections
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
659 This
->maxCons
* sizeof(*This
->connections
));
660 This
->remote_connections
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
661 This
->remote_connections
,
662 This
->maxCons
* sizeof(*This
->remote_connections
));
665 new_conn
.pAdvSink
= pAdvise
;
666 new_conn
.advf
= advf
& ~WINE_ADVF_REMOTE
;
667 new_conn
.formatetc
= *pFetc
;
668 new_conn
.dwConnection
= index
+ 1; /* 0 is not a valid cookie, so increment the index */
670 copy_statdata(This
->connections
+ index
, &new_conn
);
672 if (This
->connections
[index
].pAdvSink
!= NULL
)
674 /* if we are already connected advise the remote object */
679 hr
= IDataObject_DAdvise(This
->delegate
, &new_conn
.formatetc
,
680 new_conn
.advf
, new_conn
.pAdvSink
,
681 &This
->remote_connections
[index
]);
684 IDataAdviseHolder_Unadvise(iface
, new_conn
.dwConnection
);
687 This
->connections
[index
].advf
|= WINE_ADVF_REMOTE
;
689 else if(advf
& ADVF_PRIMEFIRST
)
690 /* only do this if we have no delegate, since in the above case the
691 * delegate will do the priming for us */
692 IDataAdviseHolder_SendOnDataChange(iface
, pDataObject
, 0, advf
);
695 *pdwConnection
= new_conn
.dwConnection
;
700 /******************************************************************************
701 * DataAdviseHolder_Unadvise
703 static HRESULT WINAPI
DataAdviseHolder_Unadvise(IDataAdviseHolder
*iface
,
706 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
708 TRACE("(%p)->(%u)\n", This
, dwConnection
);
710 /* The connection number is 1 more than the index, see DataAdviseHolder_Advise */
711 index
= dwConnection
- 1;
713 if (index
>= This
->maxCons
|| This
->connections
[index
].pAdvSink
== NULL
)
714 return OLE_E_NOCONNECTION
;
716 if (This
->delegate
&& This
->connections
[index
].advf
& WINE_ADVF_REMOTE
)
718 IDataObject_DUnadvise(This
->delegate
, This
->remote_connections
[index
]);
719 This
->remote_connections
[index
] = 0;
722 release_statdata(This
->connections
+ index
);
727 /******************************************************************************
728 * DataAdviseHolder_EnumAdvise
730 static HRESULT WINAPI
DataAdviseHolder_EnumAdvise(IDataAdviseHolder
*iface
,
731 IEnumSTATDATA
**enum_advise
)
733 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
737 TRACE("(%p)->(%p)\n", This
, enum_advise
);
739 IDataAdviseHolder_QueryInterface(iface
, &IID_IUnknown
, (void**)&unk
);
740 hr
= EnumSTATDATA_Construct(unk
, 0, This
->maxCons
, This
->connections
, enum_advise
);
741 IUnknown_Release(unk
);
745 /******************************************************************************
746 * DataAdviseHolder_SendOnDataChange
748 static HRESULT WINAPI
DataAdviseHolder_SendOnDataChange(IDataAdviseHolder
*iface
,
749 IDataObject
*data_obj
,
750 DWORD dwReserved
, DWORD advf
)
752 IEnumSTATDATA
*pEnum
;
755 TRACE("(%p)->(%p, %08x, %08x)\n", iface
, data_obj
, dwReserved
, advf
);
757 hr
= IDataAdviseHolder_EnumAdvise(iface
, &pEnum
);
761 while (IEnumSTATDATA_Next(pEnum
, 1, &statdata
, NULL
) == S_OK
)
764 stg
.tymed
= TYMED_NULL
;
766 stg
.pUnkForRelease
= NULL
;
768 if(!(statdata
.advf
& ADVF_NODATA
))
770 hr
= IDataObject_GetData(data_obj
, &statdata
.formatetc
, &stg
);
773 IAdviseSink_OnDataChange(statdata
.pAdvSink
, &statdata
.formatetc
, &stg
);
775 if(statdata
.advf
& ADVF_ONLYONCE
)
777 IDataAdviseHolder_Unadvise(iface
, statdata
.dwConnection
);
780 release_statdata(&statdata
);
782 IEnumSTATDATA_Release(pEnum
);
788 /**************************************************************************
789 * DataAdviseHolderImpl_VTable
791 static const IDataAdviseHolderVtbl DataAdviseHolderImpl_VTable
=
793 DataAdviseHolder_QueryInterface
,
794 DataAdviseHolder_AddRef
,
795 DataAdviseHolder_Release
,
796 DataAdviseHolder_Advise
,
797 DataAdviseHolder_Unadvise
,
798 DataAdviseHolder_EnumAdvise
,
799 DataAdviseHolder_SendOnDataChange
802 HRESULT
DataAdviseHolder_OnConnect(IDataAdviseHolder
*iface
, IDataObject
*pDelegate
)
804 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
808 for(index
= 0; index
< This
->maxCons
; index
++)
810 if(This
->connections
[index
].pAdvSink
!= NULL
)
812 hr
= IDataObject_DAdvise(pDelegate
, &This
->connections
[index
].formatetc
,
813 This
->connections
[index
].advf
,
814 This
->connections
[index
].pAdvSink
,
815 &This
->remote_connections
[index
]);
816 if (FAILED(hr
)) break;
817 This
->connections
[index
].advf
|= WINE_ADVF_REMOTE
;
820 This
->delegate
= pDelegate
;
824 void DataAdviseHolder_OnDisconnect(IDataAdviseHolder
*iface
)
826 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
829 for(index
= 0; index
< This
->maxCons
; index
++)
831 if((This
->connections
[index
].pAdvSink
!= NULL
) &&
832 (This
->connections
[index
].advf
& WINE_ADVF_REMOTE
))
834 IDataObject_DUnadvise(This
->delegate
, This
->remote_connections
[index
]);
835 This
->remote_connections
[index
] = 0;
836 This
->connections
[index
].advf
&= ~WINE_ADVF_REMOTE
;
839 This
->delegate
= NULL
;
842 /******************************************************************************
843 * DataAdviseHolder_Constructor
845 static IDataAdviseHolder
*DataAdviseHolder_Constructor(void)
847 DataAdviseHolder
* newHolder
;
849 newHolder
= HeapAlloc(GetProcessHeap(), 0, sizeof(DataAdviseHolder
));
851 newHolder
->IDataAdviseHolder_iface
.lpVtbl
= &DataAdviseHolderImpl_VTable
;
853 newHolder
->maxCons
= INITIAL_SINKS
;
854 newHolder
->connections
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
855 newHolder
->maxCons
* sizeof(*newHolder
->connections
));
856 newHolder
->remote_connections
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
857 newHolder
->maxCons
* sizeof(*newHolder
->remote_connections
));
858 newHolder
->delegate
= NULL
;
860 TRACE("returning %p\n", &newHolder
->IDataAdviseHolder_iface
);
861 return &newHolder
->IDataAdviseHolder_iface
;
864 /***********************************************************************
868 /***********************************************************************
869 * CreateOleAdviseHolder [OLE32.@]
871 HRESULT WINAPI
CreateOleAdviseHolder(IOleAdviseHolder
**ppOAHolder
)
873 TRACE("(%p)\n", ppOAHolder
);
875 if (ppOAHolder
==NULL
)
878 *ppOAHolder
= OleAdviseHolderImpl_Constructor ();
880 if (*ppOAHolder
!= NULL
)
883 return E_OUTOFMEMORY
;
886 /******************************************************************************
887 * CreateDataAdviseHolder [OLE32.@]
889 HRESULT WINAPI
CreateDataAdviseHolder(IDataAdviseHolder
**ppDAHolder
)
891 TRACE("(%p)\n", ppDAHolder
);
893 if (ppDAHolder
==NULL
)
896 *ppDAHolder
= DataAdviseHolder_Constructor();
898 if (*ppDAHolder
!= NULL
)
901 return E_OUTOFMEMORY
;