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
28 #define NONAMELESSSTRUCT
34 #include "wine/debug.h"
37 #include "compobj_private.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
41 #define INITIAL_SINKS 10
43 static void release_statdata(STATDATA
*data
)
45 if(data
->formatetc
.ptd
)
47 CoTaskMemFree(data
->formatetc
.ptd
);
48 data
->formatetc
.ptd
= NULL
;
53 IAdviseSink_Release(data
->pAdvSink
);
54 data
->pAdvSink
= NULL
;
58 static HRESULT
copy_statdata(STATDATA
*dst
, const STATDATA
*src
)
61 if(src
->formatetc
.ptd
)
63 dst
->formatetc
.ptd
= CoTaskMemAlloc(src
->formatetc
.ptd
->tdSize
);
64 if(!dst
->formatetc
.ptd
) return E_OUTOFMEMORY
;
65 memcpy(dst
->formatetc
.ptd
, src
->formatetc
.ptd
, src
->formatetc
.ptd
->tdSize
);
67 if(dst
->pAdvSink
) IAdviseSink_AddRef(dst
->pAdvSink
);
71 /**************************************************************************
72 * EnumSTATDATA Implementation
75 static HRESULT
EnumSTATDATA_Construct(IUnknown
*holder
, ULONG index
, DWORD array_len
, STATDATA
*data
, IEnumSTATDATA
**ppenum
);
79 IEnumSTATDATA IEnumSTATDATA_iface
;
88 static inline EnumSTATDATA
*impl_from_IEnumSTATDATA(IEnumSTATDATA
*iface
)
90 return CONTAINING_RECORD(iface
, EnumSTATDATA
, IEnumSTATDATA_iface
);
93 static HRESULT WINAPI
EnumSTATDATA_QueryInterface(IEnumSTATDATA
*iface
, REFIID riid
, void **ppv
)
95 TRACE("(%s, %p)\n", debugstr_guid(riid
), ppv
);
96 if (IsEqualIID(riid
, &IID_IUnknown
) ||
97 IsEqualIID(riid
, &IID_IEnumSTATDATA
))
99 IUnknown_AddRef(iface
);
103 return E_NOINTERFACE
;
106 static ULONG WINAPI
EnumSTATDATA_AddRef(IEnumSTATDATA
*iface
)
108 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
110 return InterlockedIncrement(&This
->ref
);
113 static ULONG WINAPI
EnumSTATDATA_Release(IEnumSTATDATA
*iface
)
115 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
116 LONG refs
= InterlockedDecrement(&This
->ref
);
121 for(i
= 0; i
< This
->num_of_elems
; i
++)
122 release_statdata(This
->statdata
+ i
);
123 HeapFree(GetProcessHeap(), 0, This
->statdata
);
124 IUnknown_Release(This
->holder
);
125 HeapFree(GetProcessHeap(), 0, This
);
130 static HRESULT WINAPI
EnumSTATDATA_Next(IEnumSTATDATA
*iface
, ULONG num
, LPSTATDATA data
,
133 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
137 TRACE("(%d, %p, %p)\n", num
, data
, fetched
);
141 if (This
->index
>= This
->num_of_elems
)
147 copy_statdata(data
+ count
, This
->statdata
+ This
->index
);
153 if (fetched
) *fetched
= count
;
158 static HRESULT WINAPI
EnumSTATDATA_Skip(IEnumSTATDATA
*iface
, ULONG num
)
160 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
162 TRACE("(%d)\n", num
);
164 if(This
->index
+ num
>= This
->num_of_elems
)
166 This
->index
= This
->num_of_elems
;
174 static HRESULT WINAPI
EnumSTATDATA_Reset(IEnumSTATDATA
*iface
)
176 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
184 static HRESULT WINAPI
EnumSTATDATA_Clone(IEnumSTATDATA
*iface
, IEnumSTATDATA
**ppenum
)
186 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
188 return EnumSTATDATA_Construct(This
->holder
, This
->index
, This
->num_of_elems
, This
->statdata
, ppenum
);
191 static const IEnumSTATDATAVtbl EnumSTATDATA_VTable
=
193 EnumSTATDATA_QueryInterface
,
195 EnumSTATDATA_Release
,
202 static HRESULT
EnumSTATDATA_Construct(IUnknown
*holder
, ULONG index
, DWORD array_len
, STATDATA
*data
,
203 IEnumSTATDATA
**ppenum
)
205 EnumSTATDATA
*This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
208 if (!This
) return E_OUTOFMEMORY
;
210 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
);
230 This
->num_of_elems
= count
;
231 This
->holder
= holder
;
232 IUnknown_AddRef(holder
);
233 *ppenum
= &This
->IEnumSTATDATA_iface
;
237 /**************************************************************************
238 * OleAdviseHolder Implementation
242 IOleAdviseHolder IOleAdviseHolder_iface
;
247 STATDATA
*connections
;
248 } OleAdviseHolderImpl
;
250 static inline OleAdviseHolderImpl
*impl_from_IOleAdviseHolder(IOleAdviseHolder
*iface
)
252 return CONTAINING_RECORD(iface
, OleAdviseHolderImpl
, IOleAdviseHolder_iface
);
255 /**************************************************************************
256 * OleAdviseHolderImpl_Destructor
258 static void OleAdviseHolderImpl_Destructor(OleAdviseHolderImpl
*This
)
263 for (index
= 0; index
< This
->max_cons
; index
++)
265 if (This
->connections
[index
].pAdvSink
!= NULL
)
266 release_statdata(This
->connections
+ index
);
269 HeapFree(GetProcessHeap(), 0, This
->connections
);
270 HeapFree(GetProcessHeap(), 0, This
);
273 /**************************************************************************
274 * OleAdviseHolderImpl_QueryInterface
276 static HRESULT WINAPI
OleAdviseHolderImpl_QueryInterface(IOleAdviseHolder
*iface
,
277 REFIID iid
, void **obj
)
279 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
280 TRACE("(%p)->(%s,%p)\n",This
, debugstr_guid(iid
), obj
);
287 if (IsEqualIID(iid
, &IID_IUnknown
) ||
288 IsEqualIID(iid
, &IID_IOleAdviseHolder
))
290 *obj
= &This
->IOleAdviseHolder_iface
;
294 return E_NOINTERFACE
;
296 IUnknown_AddRef((IUnknown
*)*obj
);
301 /******************************************************************************
302 * OleAdviseHolderImpl_AddRef
304 static ULONG WINAPI
OleAdviseHolderImpl_AddRef(IOleAdviseHolder
*iface
)
306 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
307 ULONG ref
= InterlockedIncrement(&This
->ref
);
309 TRACE("(%p)->(ref=%d)\n", This
, ref
- 1);
314 /******************************************************************************
315 * OleAdviseHolderImpl_Release
317 static ULONG WINAPI
OleAdviseHolderImpl_Release(IOleAdviseHolder
*iface
)
319 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
321 TRACE("(%p)->(ref=%d)\n", This
, This
->ref
);
322 ref
= InterlockedDecrement(&This
->ref
);
324 if (ref
== 0) OleAdviseHolderImpl_Destructor(This
);
329 /******************************************************************************
330 * OleAdviseHolderImpl_Advise
332 static HRESULT WINAPI
OleAdviseHolderImpl_Advise(IOleAdviseHolder
*iface
,
333 IAdviseSink
*pAdvise
,
334 DWORD
*pdwConnection
)
337 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
339 static const FORMATETC empty_fmtetc
= {0, NULL
, 0, -1, 0};
341 TRACE("(%p)->(%p, %p)\n", This
, pAdvise
, pdwConnection
);
343 if (pdwConnection
==NULL
)
348 for (index
= 0; index
< This
->max_cons
; index
++)
350 if (This
->connections
[index
].pAdvSink
== NULL
)
354 if (index
== This
->max_cons
)
356 This
->max_cons
+= INITIAL_SINKS
;
357 This
->connections
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, This
->connections
,
358 This
->max_cons
* sizeof(*This
->connections
));
361 new_conn
.pAdvSink
= pAdvise
;
363 new_conn
.formatetc
= empty_fmtetc
;
364 new_conn
.dwConnection
= index
+ 1; /* 0 is not a valid cookie, so increment the index */
366 copy_statdata(This
->connections
+ index
, &new_conn
);
368 *pdwConnection
= new_conn
.dwConnection
;
373 /******************************************************************************
374 * OleAdviseHolderImpl_Unadvise
376 static HRESULT WINAPI
OleAdviseHolderImpl_Unadvise(IOleAdviseHolder
*iface
,
379 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
382 TRACE("(%p)->(%u)\n", This
, dwConnection
);
384 /* The connection number is 1 more than the index, see OleAdviseHolder_Advise */
385 index
= dwConnection
- 1;
387 if (index
>= This
->max_cons
|| This
->connections
[index
].pAdvSink
== NULL
)
388 return OLE_E_NOCONNECTION
;
390 release_statdata(This
->connections
+ index
);
395 /******************************************************************************
396 * OleAdviseHolderImpl_EnumAdvise
398 static HRESULT WINAPI
OleAdviseHolderImpl_EnumAdvise(IOleAdviseHolder
*iface
, IEnumSTATDATA
**enum_advise
)
400 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
404 TRACE("(%p)->(%p)\n", This
, enum_advise
);
406 IOleAdviseHolder_QueryInterface(iface
, &IID_IUnknown
, (void**)&unk
);
407 hr
= EnumSTATDATA_Construct(unk
, 0, This
->max_cons
, This
->connections
, enum_advise
);
408 IUnknown_Release(unk
);
412 /******************************************************************************
413 * OleAdviseHolderImpl_SendOnRename
415 static HRESULT WINAPI
OleAdviseHolderImpl_SendOnRename(IOleAdviseHolder
*iface
, IMoniker
*pmk
)
417 IEnumSTATDATA
*pEnum
;
420 TRACE("(%p)->(%p)\n", iface
, pmk
);
422 hr
= IOleAdviseHolder_EnumAdvise(iface
, &pEnum
);
426 while (IEnumSTATDATA_Next(pEnum
, 1, &statdata
, NULL
) == S_OK
)
428 IAdviseSink_OnRename(statdata
.pAdvSink
, pmk
);
430 IAdviseSink_Release(statdata
.pAdvSink
);
432 IEnumSTATDATA_Release(pEnum
);
438 /******************************************************************************
439 * OleAdviseHolderImpl_SendOnSave
441 static HRESULT WINAPI
OleAdviseHolderImpl_SendOnSave(IOleAdviseHolder
*iface
)
443 IEnumSTATDATA
*pEnum
;
446 TRACE("(%p)->()\n", iface
);
448 hr
= IOleAdviseHolder_EnumAdvise(iface
, &pEnum
);
452 while (IEnumSTATDATA_Next(pEnum
, 1, &statdata
, NULL
) == S_OK
)
454 IAdviseSink_OnSave(statdata
.pAdvSink
);
456 IAdviseSink_Release(statdata
.pAdvSink
);
458 IEnumSTATDATA_Release(pEnum
);
464 /******************************************************************************
465 * OleAdviseHolderImpl_SendOnClose
467 static HRESULT WINAPI
OleAdviseHolderImpl_SendOnClose(IOleAdviseHolder
*iface
)
469 IEnumSTATDATA
*pEnum
;
472 TRACE("(%p)->()\n", iface
);
474 hr
= IOleAdviseHolder_EnumAdvise(iface
, &pEnum
);
478 while (IEnumSTATDATA_Next(pEnum
, 1, &statdata
, NULL
) == S_OK
)
480 IAdviseSink_OnClose(statdata
.pAdvSink
);
482 IAdviseSink_Release(statdata
.pAdvSink
);
484 IEnumSTATDATA_Release(pEnum
);
490 /**************************************************************************
491 * OleAdviseHolderImpl_VTable
493 static const IOleAdviseHolderVtbl oahvt
=
495 OleAdviseHolderImpl_QueryInterface
,
496 OleAdviseHolderImpl_AddRef
,
497 OleAdviseHolderImpl_Release
,
498 OleAdviseHolderImpl_Advise
,
499 OleAdviseHolderImpl_Unadvise
,
500 OleAdviseHolderImpl_EnumAdvise
,
501 OleAdviseHolderImpl_SendOnRename
,
502 OleAdviseHolderImpl_SendOnSave
,
503 OleAdviseHolderImpl_SendOnClose
506 /**************************************************************************
507 * OleAdviseHolderImpl_Constructor
510 static IOleAdviseHolder
*OleAdviseHolderImpl_Constructor(void)
512 OleAdviseHolderImpl
* lpoah
;
514 lpoah
= HeapAlloc(GetProcessHeap(), 0, sizeof(OleAdviseHolderImpl
));
516 lpoah
->IOleAdviseHolder_iface
.lpVtbl
= &oahvt
;
518 lpoah
->max_cons
= INITIAL_SINKS
;
519 lpoah
->connections
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
520 lpoah
->max_cons
* sizeof(*lpoah
->connections
));
522 TRACE("returning %p\n", &lpoah
->IOleAdviseHolder_iface
);
523 return &lpoah
->IOleAdviseHolder_iface
;
526 /**************************************************************************
527 * DataAdviseHolder Implementation
531 IDataAdviseHolder IDataAdviseHolder_iface
;
535 STATDATA
* connections
;
536 DWORD
* remote_connections
;
537 IDataObject
* delegate
;
540 /* this connection has also has been advised to the delegate data object */
541 #define WINE_ADVF_REMOTE 0x80000000
543 static inline DataAdviseHolder
*impl_from_IDataAdviseHolder(IDataAdviseHolder
*iface
)
545 return CONTAINING_RECORD(iface
, DataAdviseHolder
, IDataAdviseHolder_iface
);
548 /******************************************************************************
549 * DataAdviseHolder_Destructor
551 static void DataAdviseHolder_Destructor(DataAdviseHolder
* ptrToDestroy
)
554 TRACE("%p\n", ptrToDestroy
);
556 for (index
= 0; index
< ptrToDestroy
->maxCons
; index
++)
558 if (ptrToDestroy
->connections
[index
].pAdvSink
!= NULL
)
560 if (ptrToDestroy
->delegate
&&
561 (ptrToDestroy
->connections
[index
].advf
& WINE_ADVF_REMOTE
))
562 IDataObject_DUnadvise(ptrToDestroy
->delegate
,
563 ptrToDestroy
->remote_connections
[index
]);
565 release_statdata(ptrToDestroy
->connections
+ index
);
569 HeapFree(GetProcessHeap(), 0, ptrToDestroy
->remote_connections
);
570 HeapFree(GetProcessHeap(), 0, ptrToDestroy
->connections
);
571 HeapFree(GetProcessHeap(), 0, ptrToDestroy
);
574 /************************************************************************
575 * DataAdviseHolder_QueryInterface (IUnknown)
577 static HRESULT WINAPI
DataAdviseHolder_QueryInterface(IDataAdviseHolder
*iface
,
578 REFIID riid
, void **ppvObject
)
580 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
581 TRACE("(%p)->(%s,%p)\n",This
,debugstr_guid(riid
),ppvObject
);
583 if ( (This
==0) || (ppvObject
==0) )
588 if ( IsEqualIID(&IID_IUnknown
, riid
) ||
589 IsEqualIID(&IID_IDataAdviseHolder
, riid
) )
596 return E_NOINTERFACE
;
599 IUnknown_AddRef((IUnknown
*)*ppvObject
);
603 /************************************************************************
604 * DataAdviseHolder_AddRef (IUnknown)
606 static ULONG WINAPI
DataAdviseHolder_AddRef(IDataAdviseHolder
*iface
)
608 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
609 TRACE("(%p) (ref=%d)\n", This
, This
->ref
);
610 return InterlockedIncrement(&This
->ref
);
613 /************************************************************************
614 * DataAdviseHolder_Release (IUnknown)
616 static ULONG WINAPI
DataAdviseHolder_Release(IDataAdviseHolder
*iface
)
618 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
620 TRACE("(%p) (ref=%d)\n", This
, This
->ref
);
622 ref
= InterlockedDecrement(&This
->ref
);
623 if (ref
==0) DataAdviseHolder_Destructor(This
);
628 /************************************************************************
629 * DataAdviseHolder_Advise
632 static HRESULT WINAPI
DataAdviseHolder_Advise(IDataAdviseHolder
*iface
,
633 IDataObject
*pDataObject
, FORMATETC
*pFetc
,
634 DWORD advf
, IAdviseSink
*pAdvise
,
635 DWORD
*pdwConnection
)
639 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
641 TRACE("(%p)->(%p, %p, %08x, %p, %p)\n", This
, pDataObject
, pFetc
, advf
,
642 pAdvise
, pdwConnection
);
644 if (pdwConnection
==NULL
)
649 for (index
= 0; index
< This
->maxCons
; index
++)
651 if (This
->connections
[index
].pAdvSink
== NULL
)
655 if (index
== This
->maxCons
)
657 This
->maxCons
+=INITIAL_SINKS
;
658 This
->connections
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
660 This
->maxCons
* sizeof(*This
->connections
));
661 This
->remote_connections
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
662 This
->remote_connections
,
663 This
->maxCons
* sizeof(*This
->remote_connections
));
666 new_conn
.pAdvSink
= pAdvise
;
667 new_conn
.advf
= advf
& ~WINE_ADVF_REMOTE
;
668 new_conn
.formatetc
= *pFetc
;
669 new_conn
.dwConnection
= index
+ 1; /* 0 is not a valid cookie, so increment the index */
671 copy_statdata(This
->connections
+ index
, &new_conn
);
673 if (This
->connections
[index
].pAdvSink
!= NULL
)
675 /* if we are already connected advise the remote object */
680 hr
= IDataObject_DAdvise(This
->delegate
, &new_conn
.formatetc
,
681 new_conn
.advf
, new_conn
.pAdvSink
,
682 &This
->remote_connections
[index
]);
685 IDataAdviseHolder_Unadvise(iface
, new_conn
.dwConnection
);
688 This
->connections
[index
].advf
|= WINE_ADVF_REMOTE
;
690 else if(advf
& ADVF_PRIMEFIRST
)
691 /* only do this if we have no delegate, since in the above case the
692 * delegate will do the priming for us */
693 IDataAdviseHolder_SendOnDataChange(iface
, pDataObject
, 0, advf
);
696 *pdwConnection
= new_conn
.dwConnection
;
701 /******************************************************************************
702 * DataAdviseHolder_Unadvise
704 static HRESULT WINAPI
DataAdviseHolder_Unadvise(IDataAdviseHolder
*iface
,
707 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
709 TRACE("(%p)->(%u)\n", This
, dwConnection
);
711 /* The connection number is 1 more than the index, see DataAdviseHolder_Advise */
712 index
= dwConnection
- 1;
714 if (index
>= This
->maxCons
|| This
->connections
[index
].pAdvSink
== NULL
)
715 return OLE_E_NOCONNECTION
;
717 if (This
->delegate
&& This
->connections
[index
].advf
& WINE_ADVF_REMOTE
)
719 IDataObject_DUnadvise(This
->delegate
, This
->remote_connections
[index
]);
720 This
->remote_connections
[index
] = 0;
723 release_statdata(This
->connections
+ index
);
728 /******************************************************************************
729 * DataAdviseHolder_EnumAdvise
731 static HRESULT WINAPI
DataAdviseHolder_EnumAdvise(IDataAdviseHolder
*iface
,
732 IEnumSTATDATA
**enum_advise
)
734 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
738 TRACE("(%p)->(%p)\n", This
, enum_advise
);
740 IDataAdviseHolder_QueryInterface(iface
, &IID_IUnknown
, (void**)&unk
);
741 hr
= EnumSTATDATA_Construct(unk
, 0, This
->maxCons
, This
->connections
, enum_advise
);
742 IUnknown_Release(unk
);
746 /******************************************************************************
747 * DataAdviseHolder_SendOnDataChange
749 static HRESULT WINAPI
DataAdviseHolder_SendOnDataChange(IDataAdviseHolder
*iface
,
750 IDataObject
*data_obj
,
751 DWORD dwReserved
, DWORD advf
)
753 IEnumSTATDATA
*pEnum
;
756 TRACE("(%p)->(%p, %08x, %08x)\n", iface
, data_obj
, dwReserved
, advf
);
758 hr
= IDataAdviseHolder_EnumAdvise(iface
, &pEnum
);
762 while (IEnumSTATDATA_Next(pEnum
, 1, &statdata
, NULL
) == S_OK
)
765 stg
.tymed
= TYMED_NULL
;
767 stg
.pUnkForRelease
= NULL
;
769 if(!(statdata
.advf
& ADVF_NODATA
))
771 hr
= IDataObject_GetData(data_obj
, &statdata
.formatetc
, &stg
);
774 IAdviseSink_OnDataChange(statdata
.pAdvSink
, &statdata
.formatetc
, &stg
);
776 if(statdata
.advf
& ADVF_ONLYONCE
)
778 IDataAdviseHolder_Unadvise(iface
, statdata
.dwConnection
);
781 release_statdata(&statdata
);
783 IEnumSTATDATA_Release(pEnum
);
789 /**************************************************************************
790 * DataAdviseHolderImpl_VTable
792 static const IDataAdviseHolderVtbl DataAdviseHolderImpl_VTable
=
794 DataAdviseHolder_QueryInterface
,
795 DataAdviseHolder_AddRef
,
796 DataAdviseHolder_Release
,
797 DataAdviseHolder_Advise
,
798 DataAdviseHolder_Unadvise
,
799 DataAdviseHolder_EnumAdvise
,
800 DataAdviseHolder_SendOnDataChange
803 HRESULT
DataAdviseHolder_OnConnect(IDataAdviseHolder
*iface
, IDataObject
*pDelegate
)
805 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
809 for(index
= 0; index
< This
->maxCons
; index
++)
811 if(This
->connections
[index
].pAdvSink
!= NULL
)
813 hr
= IDataObject_DAdvise(pDelegate
, &This
->connections
[index
].formatetc
,
814 This
->connections
[index
].advf
,
815 This
->connections
[index
].pAdvSink
,
816 &This
->remote_connections
[index
]);
817 if (FAILED(hr
)) break;
818 This
->connections
[index
].advf
|= WINE_ADVF_REMOTE
;
821 This
->delegate
= pDelegate
;
825 void DataAdviseHolder_OnDisconnect(IDataAdviseHolder
*iface
)
827 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
830 for(index
= 0; index
< This
->maxCons
; index
++)
832 if((This
->connections
[index
].pAdvSink
!= NULL
) &&
833 (This
->connections
[index
].advf
& WINE_ADVF_REMOTE
))
835 IDataObject_DUnadvise(This
->delegate
, This
->remote_connections
[index
]);
836 This
->remote_connections
[index
] = 0;
837 This
->connections
[index
].advf
&= ~WINE_ADVF_REMOTE
;
840 This
->delegate
= NULL
;
843 /******************************************************************************
844 * DataAdviseHolder_Constructor
846 static IDataAdviseHolder
*DataAdviseHolder_Constructor(void)
848 DataAdviseHolder
* newHolder
;
850 newHolder
= HeapAlloc(GetProcessHeap(), 0, sizeof(DataAdviseHolder
));
852 newHolder
->IDataAdviseHolder_iface
.lpVtbl
= &DataAdviseHolderImpl_VTable
;
854 newHolder
->maxCons
= INITIAL_SINKS
;
855 newHolder
->connections
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
856 newHolder
->maxCons
* sizeof(*newHolder
->connections
));
857 newHolder
->remote_connections
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
858 newHolder
->maxCons
* sizeof(*newHolder
->remote_connections
));
859 newHolder
->delegate
= NULL
;
861 TRACE("returning %p\n", &newHolder
->IDataAdviseHolder_iface
);
862 return &newHolder
->IDataAdviseHolder_iface
;
865 /***********************************************************************
869 /***********************************************************************
870 * CreateOleAdviseHolder [OLE32.@]
872 HRESULT WINAPI
CreateOleAdviseHolder(IOleAdviseHolder
**ppOAHolder
)
874 TRACE("(%p)\n", ppOAHolder
);
876 if (ppOAHolder
==NULL
)
879 *ppOAHolder
= OleAdviseHolderImpl_Constructor ();
881 if (*ppOAHolder
!= NULL
)
884 return E_OUTOFMEMORY
;
887 /******************************************************************************
888 * CreateDataAdviseHolder [OLE32.@]
890 HRESULT WINAPI
CreateDataAdviseHolder(IDataAdviseHolder
**ppDAHolder
)
892 TRACE("(%p)\n", ppDAHolder
);
894 if (ppDAHolder
==NULL
)
897 *ppDAHolder
= DataAdviseHolder_Constructor();
899 if (*ppDAHolder
!= NULL
)
902 return E_OUTOFMEMORY
;