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
)
61 hr
= copy_formatetc( &dst
->formatetc
, &src
->formatetc
);
62 if (FAILED(hr
)) return hr
;
63 dst
->advf
= src
->advf
;
64 dst
->pAdvSink
= src
->pAdvSink
;
65 if (dst
->pAdvSink
) IAdviseSink_AddRef( dst
->pAdvSink
);
66 dst
->dwConnection
= src
->dwConnection
;
70 /**************************************************************************
71 * EnumSTATDATA Implementation
76 IEnumSTATDATA IEnumSTATDATA_iface
;
85 static inline EnumSTATDATA
*impl_from_IEnumSTATDATA(IEnumSTATDATA
*iface
)
87 return CONTAINING_RECORD(iface
, EnumSTATDATA
, IEnumSTATDATA_iface
);
90 static HRESULT WINAPI
EnumSTATDATA_QueryInterface(IEnumSTATDATA
*iface
, REFIID riid
, void **ppv
)
92 TRACE("(%s, %p)\n", debugstr_guid(riid
), ppv
);
93 if (IsEqualIID(riid
, &IID_IUnknown
) ||
94 IsEqualIID(riid
, &IID_IEnumSTATDATA
))
96 IEnumSTATDATA_AddRef(iface
);
100 return E_NOINTERFACE
;
103 static ULONG WINAPI
EnumSTATDATA_AddRef(IEnumSTATDATA
*iface
)
105 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
107 return InterlockedIncrement(&This
->ref
);
110 static ULONG WINAPI
EnumSTATDATA_Release(IEnumSTATDATA
*iface
)
112 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
113 LONG refs
= InterlockedDecrement(&This
->ref
);
118 for(i
= 0; i
< This
->num_of_elems
; i
++)
119 release_statdata(This
->statdata
+ i
);
120 HeapFree(GetProcessHeap(), 0, This
->statdata
);
121 if (This
->holder
) IUnknown_Release(This
->holder
);
122 HeapFree(GetProcessHeap(), 0, This
);
127 static HRESULT WINAPI
EnumSTATDATA_Next(IEnumSTATDATA
*iface
, ULONG num
, LPSTATDATA data
,
130 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
134 TRACE("(%d, %p, %p)\n", num
, data
, fetched
);
138 if (This
->index
>= This
->num_of_elems
)
144 copy_statdata(data
+ count
, This
->statdata
+ This
->index
);
150 if (fetched
) *fetched
= count
;
155 static HRESULT WINAPI
EnumSTATDATA_Skip(IEnumSTATDATA
*iface
, ULONG num
)
157 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
159 TRACE("(%d)\n", num
);
161 if(This
->index
+ num
>= This
->num_of_elems
)
163 This
->index
= This
->num_of_elems
;
171 static HRESULT WINAPI
EnumSTATDATA_Reset(IEnumSTATDATA
*iface
)
173 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
181 static HRESULT WINAPI
EnumSTATDATA_Clone(IEnumSTATDATA
*iface
, IEnumSTATDATA
**ppenum
)
183 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
185 return EnumSTATDATA_Construct(This
->holder
, This
->index
, This
->num_of_elems
, This
->statdata
,
189 static const IEnumSTATDATAVtbl EnumSTATDATA_VTable
=
191 EnumSTATDATA_QueryInterface
,
193 EnumSTATDATA_Release
,
200 HRESULT
EnumSTATDATA_Construct(IUnknown
*holder
, ULONG index
, DWORD array_len
, STATDATA
*data
,
201 BOOL copy
, IEnumSTATDATA
**ppenum
)
203 EnumSTATDATA
*This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
206 if (!This
) return E_OUTOFMEMORY
;
208 This
->IEnumSTATDATA_iface
.lpVtbl
= &EnumSTATDATA_VTable
;
214 This
->statdata
= HeapAlloc(GetProcessHeap(), 0, array_len
* sizeof(*This
->statdata
));
217 HeapFree(GetProcessHeap(), 0, This
);
218 return E_OUTOFMEMORY
;
221 for(i
= 0, count
= 0; i
< array_len
; i
++)
225 copy_statdata(This
->statdata
+ count
, data
+ i
);
232 This
->statdata
= data
;
236 This
->num_of_elems
= count
;
237 This
->holder
= holder
;
238 if (holder
) IUnknown_AddRef(holder
);
239 *ppenum
= &This
->IEnumSTATDATA_iface
;
243 /**************************************************************************
244 * OleAdviseHolder Implementation
248 IOleAdviseHolder IOleAdviseHolder_iface
;
253 STATDATA
*connections
;
254 } OleAdviseHolderImpl
;
256 static inline OleAdviseHolderImpl
*impl_from_IOleAdviseHolder(IOleAdviseHolder
*iface
)
258 return CONTAINING_RECORD(iface
, OleAdviseHolderImpl
, IOleAdviseHolder_iface
);
261 /**************************************************************************
262 * OleAdviseHolderImpl_Destructor
264 static void OleAdviseHolderImpl_Destructor(OleAdviseHolderImpl
*This
)
269 for (index
= 0; index
< This
->max_cons
; index
++)
271 if (This
->connections
[index
].pAdvSink
!= NULL
)
272 release_statdata(This
->connections
+ index
);
275 HeapFree(GetProcessHeap(), 0, This
->connections
);
276 HeapFree(GetProcessHeap(), 0, This
);
279 /**************************************************************************
280 * OleAdviseHolderImpl_QueryInterface
282 static HRESULT WINAPI
OleAdviseHolderImpl_QueryInterface(IOleAdviseHolder
*iface
,
283 REFIID iid
, void **obj
)
285 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
286 TRACE("(%p)->(%s,%p)\n",This
, debugstr_guid(iid
), obj
);
293 if (IsEqualIID(iid
, &IID_IUnknown
) ||
294 IsEqualIID(iid
, &IID_IOleAdviseHolder
))
296 *obj
= &This
->IOleAdviseHolder_iface
;
300 return E_NOINTERFACE
;
302 IUnknown_AddRef((IUnknown
*)*obj
);
307 /******************************************************************************
308 * OleAdviseHolderImpl_AddRef
310 static ULONG WINAPI
OleAdviseHolderImpl_AddRef(IOleAdviseHolder
*iface
)
312 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
313 ULONG ref
= InterlockedIncrement(&This
->ref
);
315 TRACE("(%p)->(ref=%d)\n", This
, ref
- 1);
320 /******************************************************************************
321 * OleAdviseHolderImpl_Release
323 static ULONG WINAPI
OleAdviseHolderImpl_Release(IOleAdviseHolder
*iface
)
325 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
327 TRACE("(%p)->(ref=%d)\n", This
, This
->ref
);
328 ref
= InterlockedDecrement(&This
->ref
);
330 if (ref
== 0) OleAdviseHolderImpl_Destructor(This
);
335 /******************************************************************************
336 * OleAdviseHolderImpl_Advise
338 static HRESULT WINAPI
OleAdviseHolderImpl_Advise(IOleAdviseHolder
*iface
,
339 IAdviseSink
*pAdvise
,
340 DWORD
*pdwConnection
)
343 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
345 static const FORMATETC empty_fmtetc
= {0, NULL
, 0, -1, 0};
347 TRACE("(%p)->(%p, %p)\n", This
, pAdvise
, pdwConnection
);
349 if (pdwConnection
==NULL
)
354 for (index
= 0; index
< This
->max_cons
; index
++)
356 if (This
->connections
[index
].pAdvSink
== NULL
)
360 if (index
== This
->max_cons
)
362 This
->max_cons
+= INITIAL_SINKS
;
363 This
->connections
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, This
->connections
,
364 This
->max_cons
* sizeof(*This
->connections
));
367 new_conn
.pAdvSink
= pAdvise
;
369 new_conn
.formatetc
= empty_fmtetc
;
370 new_conn
.dwConnection
= index
+ 1; /* 0 is not a valid cookie, so increment the index */
372 copy_statdata(This
->connections
+ index
, &new_conn
);
374 *pdwConnection
= new_conn
.dwConnection
;
379 /******************************************************************************
380 * OleAdviseHolderImpl_Unadvise
382 static HRESULT WINAPI
OleAdviseHolderImpl_Unadvise(IOleAdviseHolder
*iface
,
385 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
388 TRACE("(%p)->(%u)\n", This
, dwConnection
);
390 /* The connection number is 1 more than the index, see OleAdviseHolder_Advise */
391 index
= dwConnection
- 1;
393 if (index
>= This
->max_cons
|| This
->connections
[index
].pAdvSink
== NULL
)
394 return OLE_E_NOCONNECTION
;
396 release_statdata(This
->connections
+ index
);
401 /******************************************************************************
402 * OleAdviseHolderImpl_EnumAdvise
404 static HRESULT WINAPI
OleAdviseHolderImpl_EnumAdvise(IOleAdviseHolder
*iface
, IEnumSTATDATA
**enum_advise
)
406 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
410 TRACE("(%p)->(%p)\n", This
, enum_advise
);
412 IOleAdviseHolder_QueryInterface(iface
, &IID_IUnknown
, (void**)&unk
);
413 hr
= EnumSTATDATA_Construct(unk
, 0, This
->max_cons
, This
->connections
, TRUE
, enum_advise
);
414 IUnknown_Release(unk
);
418 /******************************************************************************
419 * OleAdviseHolderImpl_SendOnRename
421 static HRESULT WINAPI
OleAdviseHolderImpl_SendOnRename(IOleAdviseHolder
*iface
, IMoniker
*pmk
)
423 IEnumSTATDATA
*pEnum
;
426 TRACE("(%p)->(%p)\n", iface
, pmk
);
428 hr
= IOleAdviseHolder_EnumAdvise(iface
, &pEnum
);
432 while (IEnumSTATDATA_Next(pEnum
, 1, &statdata
, NULL
) == S_OK
)
434 IAdviseSink_OnRename(statdata
.pAdvSink
, pmk
);
436 IAdviseSink_Release(statdata
.pAdvSink
);
438 IEnumSTATDATA_Release(pEnum
);
444 /******************************************************************************
445 * OleAdviseHolderImpl_SendOnSave
447 static HRESULT WINAPI
OleAdviseHolderImpl_SendOnSave(IOleAdviseHolder
*iface
)
449 IEnumSTATDATA
*pEnum
;
452 TRACE("(%p)->()\n", iface
);
454 hr
= IOleAdviseHolder_EnumAdvise(iface
, &pEnum
);
458 while (IEnumSTATDATA_Next(pEnum
, 1, &statdata
, NULL
) == S_OK
)
460 IAdviseSink_OnSave(statdata
.pAdvSink
);
462 IAdviseSink_Release(statdata
.pAdvSink
);
464 IEnumSTATDATA_Release(pEnum
);
470 /******************************************************************************
471 * OleAdviseHolderImpl_SendOnClose
473 static HRESULT WINAPI
OleAdviseHolderImpl_SendOnClose(IOleAdviseHolder
*iface
)
475 IEnumSTATDATA
*pEnum
;
478 TRACE("(%p)->()\n", iface
);
480 hr
= IOleAdviseHolder_EnumAdvise(iface
, &pEnum
);
484 while (IEnumSTATDATA_Next(pEnum
, 1, &statdata
, NULL
) == S_OK
)
486 IAdviseSink_OnClose(statdata
.pAdvSink
);
488 IAdviseSink_Release(statdata
.pAdvSink
);
490 IEnumSTATDATA_Release(pEnum
);
496 /**************************************************************************
497 * OleAdviseHolderImpl_VTable
499 static const IOleAdviseHolderVtbl oahvt
=
501 OleAdviseHolderImpl_QueryInterface
,
502 OleAdviseHolderImpl_AddRef
,
503 OleAdviseHolderImpl_Release
,
504 OleAdviseHolderImpl_Advise
,
505 OleAdviseHolderImpl_Unadvise
,
506 OleAdviseHolderImpl_EnumAdvise
,
507 OleAdviseHolderImpl_SendOnRename
,
508 OleAdviseHolderImpl_SendOnSave
,
509 OleAdviseHolderImpl_SendOnClose
512 /**************************************************************************
513 * OleAdviseHolderImpl_Constructor
516 static IOleAdviseHolder
*OleAdviseHolderImpl_Constructor(void)
518 OleAdviseHolderImpl
* lpoah
;
520 lpoah
= HeapAlloc(GetProcessHeap(), 0, sizeof(OleAdviseHolderImpl
));
522 lpoah
->IOleAdviseHolder_iface
.lpVtbl
= &oahvt
;
524 lpoah
->max_cons
= INITIAL_SINKS
;
525 lpoah
->connections
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
526 lpoah
->max_cons
* sizeof(*lpoah
->connections
));
528 TRACE("returning %p\n", &lpoah
->IOleAdviseHolder_iface
);
529 return &lpoah
->IOleAdviseHolder_iface
;
532 /**************************************************************************
533 * DataAdviseHolder Implementation
537 IDataAdviseHolder IDataAdviseHolder_iface
;
541 STATDATA
* connections
;
542 DWORD
* remote_connections
;
543 IDataObject
* delegate
;
546 /* this connection has also has been advised to the delegate data object */
547 #define WINE_ADVF_REMOTE 0x80000000
549 static inline DataAdviseHolder
*impl_from_IDataAdviseHolder(IDataAdviseHolder
*iface
)
551 return CONTAINING_RECORD(iface
, DataAdviseHolder
, IDataAdviseHolder_iface
);
554 /******************************************************************************
555 * DataAdviseHolder_Destructor
557 static void DataAdviseHolder_Destructor(DataAdviseHolder
* ptrToDestroy
)
560 TRACE("%p\n", ptrToDestroy
);
562 for (index
= 0; index
< ptrToDestroy
->maxCons
; index
++)
564 if (ptrToDestroy
->connections
[index
].pAdvSink
!= NULL
)
566 if (ptrToDestroy
->delegate
&&
567 (ptrToDestroy
->connections
[index
].advf
& WINE_ADVF_REMOTE
))
568 IDataObject_DUnadvise(ptrToDestroy
->delegate
,
569 ptrToDestroy
->remote_connections
[index
]);
571 release_statdata(ptrToDestroy
->connections
+ index
);
575 HeapFree(GetProcessHeap(), 0, ptrToDestroy
->remote_connections
);
576 HeapFree(GetProcessHeap(), 0, ptrToDestroy
->connections
);
577 HeapFree(GetProcessHeap(), 0, ptrToDestroy
);
580 /************************************************************************
581 * DataAdviseHolder_QueryInterface (IUnknown)
583 static HRESULT WINAPI
DataAdviseHolder_QueryInterface(IDataAdviseHolder
*iface
,
584 REFIID riid
, void **ppvObject
)
586 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
587 TRACE("(%p)->(%s,%p)\n",This
,debugstr_guid(riid
),ppvObject
);
589 if ( (This
==0) || (ppvObject
==0) )
594 if ( IsEqualIID(&IID_IUnknown
, riid
) ||
595 IsEqualIID(&IID_IDataAdviseHolder
, riid
) )
602 return E_NOINTERFACE
;
605 IUnknown_AddRef((IUnknown
*)*ppvObject
);
609 /************************************************************************
610 * DataAdviseHolder_AddRef (IUnknown)
612 static ULONG WINAPI
DataAdviseHolder_AddRef(IDataAdviseHolder
*iface
)
614 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
615 TRACE("(%p) (ref=%d)\n", This
, This
->ref
);
616 return InterlockedIncrement(&This
->ref
);
619 /************************************************************************
620 * DataAdviseHolder_Release (IUnknown)
622 static ULONG WINAPI
DataAdviseHolder_Release(IDataAdviseHolder
*iface
)
624 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
626 TRACE("(%p) (ref=%d)\n", This
, This
->ref
);
628 ref
= InterlockedDecrement(&This
->ref
);
629 if (ref
==0) DataAdviseHolder_Destructor(This
);
634 /************************************************************************
635 * DataAdviseHolder_Advise
638 static HRESULT WINAPI
DataAdviseHolder_Advise(IDataAdviseHolder
*iface
,
639 IDataObject
*pDataObject
, FORMATETC
*pFetc
,
640 DWORD advf
, IAdviseSink
*pAdvise
,
641 DWORD
*pdwConnection
)
645 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
647 TRACE("(%p)->(%p, %p, %08x, %p, %p)\n", This
, pDataObject
, pFetc
, advf
,
648 pAdvise
, pdwConnection
);
650 if (pdwConnection
==NULL
)
655 for (index
= 0; index
< This
->maxCons
; index
++)
657 if (This
->connections
[index
].pAdvSink
== NULL
)
661 if (index
== This
->maxCons
)
663 This
->maxCons
+=INITIAL_SINKS
;
664 This
->connections
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
666 This
->maxCons
* sizeof(*This
->connections
));
667 This
->remote_connections
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
668 This
->remote_connections
,
669 This
->maxCons
* sizeof(*This
->remote_connections
));
672 new_conn
.pAdvSink
= pAdvise
;
673 new_conn
.advf
= advf
& ~WINE_ADVF_REMOTE
;
674 new_conn
.formatetc
= *pFetc
;
675 new_conn
.dwConnection
= index
+ 1; /* 0 is not a valid cookie, so increment the index */
677 copy_statdata(This
->connections
+ index
, &new_conn
);
679 if (This
->connections
[index
].pAdvSink
!= NULL
)
681 /* if we are already connected advise the remote object */
686 hr
= IDataObject_DAdvise(This
->delegate
, &new_conn
.formatetc
,
687 new_conn
.advf
, new_conn
.pAdvSink
,
688 &This
->remote_connections
[index
]);
691 IDataAdviseHolder_Unadvise(iface
, new_conn
.dwConnection
);
694 This
->connections
[index
].advf
|= WINE_ADVF_REMOTE
;
696 else if(advf
& ADVF_PRIMEFIRST
)
697 /* only do this if we have no delegate, since in the above case the
698 * delegate will do the priming for us */
699 IDataAdviseHolder_SendOnDataChange(iface
, pDataObject
, 0, advf
);
702 *pdwConnection
= new_conn
.dwConnection
;
707 /******************************************************************************
708 * DataAdviseHolder_Unadvise
710 static HRESULT WINAPI
DataAdviseHolder_Unadvise(IDataAdviseHolder
*iface
,
713 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
715 TRACE("(%p)->(%u)\n", This
, dwConnection
);
717 /* The connection number is 1 more than the index, see DataAdviseHolder_Advise */
718 index
= dwConnection
- 1;
720 if (index
>= This
->maxCons
|| This
->connections
[index
].pAdvSink
== NULL
)
721 return OLE_E_NOCONNECTION
;
723 if (This
->delegate
&& This
->connections
[index
].advf
& WINE_ADVF_REMOTE
)
725 IDataObject_DUnadvise(This
->delegate
, This
->remote_connections
[index
]);
726 This
->remote_connections
[index
] = 0;
729 release_statdata(This
->connections
+ index
);
734 /******************************************************************************
735 * DataAdviseHolder_EnumAdvise
737 static HRESULT WINAPI
DataAdviseHolder_EnumAdvise(IDataAdviseHolder
*iface
,
738 IEnumSTATDATA
**enum_advise
)
740 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
744 TRACE("(%p)->(%p)\n", This
, enum_advise
);
746 IDataAdviseHolder_QueryInterface(iface
, &IID_IUnknown
, (void**)&unk
);
747 hr
= EnumSTATDATA_Construct(unk
, 0, This
->maxCons
, This
->connections
, TRUE
, enum_advise
);
748 IUnknown_Release(unk
);
752 /******************************************************************************
753 * DataAdviseHolder_SendOnDataChange
755 static HRESULT WINAPI
DataAdviseHolder_SendOnDataChange(IDataAdviseHolder
*iface
,
756 IDataObject
*data_obj
,
757 DWORD dwReserved
, DWORD advf
)
759 IEnumSTATDATA
*pEnum
;
762 TRACE("(%p)->(%p, %08x, %08x)\n", iface
, data_obj
, dwReserved
, advf
);
764 hr
= IDataAdviseHolder_EnumAdvise(iface
, &pEnum
);
768 while (IEnumSTATDATA_Next(pEnum
, 1, &statdata
, NULL
) == S_OK
)
771 stg
.tymed
= TYMED_NULL
;
773 stg
.pUnkForRelease
= NULL
;
775 if(!(statdata
.advf
& ADVF_NODATA
))
777 hr
= IDataObject_GetData(data_obj
, &statdata
.formatetc
, &stg
);
780 IAdviseSink_OnDataChange(statdata
.pAdvSink
, &statdata
.formatetc
, &stg
);
782 if(statdata
.advf
& ADVF_ONLYONCE
)
784 IDataAdviseHolder_Unadvise(iface
, statdata
.dwConnection
);
787 release_statdata(&statdata
);
789 IEnumSTATDATA_Release(pEnum
);
795 /**************************************************************************
796 * DataAdviseHolderImpl_VTable
798 static const IDataAdviseHolderVtbl DataAdviseHolderImpl_VTable
=
800 DataAdviseHolder_QueryInterface
,
801 DataAdviseHolder_AddRef
,
802 DataAdviseHolder_Release
,
803 DataAdviseHolder_Advise
,
804 DataAdviseHolder_Unadvise
,
805 DataAdviseHolder_EnumAdvise
,
806 DataAdviseHolder_SendOnDataChange
809 HRESULT
DataAdviseHolder_OnConnect(IDataAdviseHolder
*iface
, IDataObject
*pDelegate
)
811 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
815 for(index
= 0; index
< This
->maxCons
; index
++)
817 if(This
->connections
[index
].pAdvSink
!= NULL
)
819 hr
= IDataObject_DAdvise(pDelegate
, &This
->connections
[index
].formatetc
,
820 This
->connections
[index
].advf
,
821 This
->connections
[index
].pAdvSink
,
822 &This
->remote_connections
[index
]);
823 if (FAILED(hr
)) break;
824 This
->connections
[index
].advf
|= WINE_ADVF_REMOTE
;
827 This
->delegate
= pDelegate
;
831 void DataAdviseHolder_OnDisconnect(IDataAdviseHolder
*iface
)
833 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
836 for(index
= 0; index
< This
->maxCons
; index
++)
838 if((This
->connections
[index
].pAdvSink
!= NULL
) &&
839 (This
->connections
[index
].advf
& WINE_ADVF_REMOTE
))
841 IDataObject_DUnadvise(This
->delegate
, This
->remote_connections
[index
]);
842 This
->remote_connections
[index
] = 0;
843 This
->connections
[index
].advf
&= ~WINE_ADVF_REMOTE
;
846 This
->delegate
= NULL
;
849 /******************************************************************************
850 * DataAdviseHolder_Constructor
852 static IDataAdviseHolder
*DataAdviseHolder_Constructor(void)
854 DataAdviseHolder
* newHolder
;
856 newHolder
= HeapAlloc(GetProcessHeap(), 0, sizeof(DataAdviseHolder
));
858 newHolder
->IDataAdviseHolder_iface
.lpVtbl
= &DataAdviseHolderImpl_VTable
;
860 newHolder
->maxCons
= INITIAL_SINKS
;
861 newHolder
->connections
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
862 newHolder
->maxCons
* sizeof(*newHolder
->connections
));
863 newHolder
->remote_connections
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
864 newHolder
->maxCons
* sizeof(*newHolder
->remote_connections
));
865 newHolder
->delegate
= NULL
;
867 TRACE("returning %p\n", &newHolder
->IDataAdviseHolder_iface
);
868 return &newHolder
->IDataAdviseHolder_iface
;
871 /***********************************************************************
875 /***********************************************************************
876 * CreateOleAdviseHolder [OLE32.@]
878 HRESULT WINAPI
CreateOleAdviseHolder(IOleAdviseHolder
**ppOAHolder
)
880 TRACE("(%p)\n", ppOAHolder
);
882 if (ppOAHolder
==NULL
)
885 *ppOAHolder
= OleAdviseHolderImpl_Constructor ();
887 if (*ppOAHolder
!= NULL
)
890 return E_OUTOFMEMORY
;
893 /******************************************************************************
894 * CreateDataAdviseHolder [OLE32.@]
896 HRESULT WINAPI
CreateDataAdviseHolder(IDataAdviseHolder
**ppDAHolder
)
898 TRACE("(%p)\n", ppDAHolder
);
900 if (ppDAHolder
==NULL
)
903 *ppDAHolder
= DataAdviseHolder_Constructor();
905 if (*ppDAHolder
!= NULL
)
908 return E_OUTOFMEMORY
;