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 CoTaskMemFree(data
->formatetc
.ptd
);
45 data
->formatetc
.ptd
= NULL
;
49 IAdviseSink_Release(data
->pAdvSink
);
50 data
->pAdvSink
= NULL
;
54 static HRESULT
copy_statdata(STATDATA
*dst
, const STATDATA
*src
)
58 hr
= copy_formatetc( &dst
->formatetc
, &src
->formatetc
);
59 if (FAILED(hr
)) return hr
;
60 dst
->advf
= src
->advf
;
61 dst
->pAdvSink
= src
->pAdvSink
;
62 if (dst
->pAdvSink
) IAdviseSink_AddRef( dst
->pAdvSink
);
63 dst
->dwConnection
= src
->dwConnection
;
67 /**************************************************************************
68 * EnumSTATDATA Implementation
73 IEnumSTATDATA IEnumSTATDATA_iface
;
82 static inline EnumSTATDATA
*impl_from_IEnumSTATDATA(IEnumSTATDATA
*iface
)
84 return CONTAINING_RECORD(iface
, EnumSTATDATA
, IEnumSTATDATA_iface
);
87 static HRESULT WINAPI
EnumSTATDATA_QueryInterface(IEnumSTATDATA
*iface
, REFIID riid
, void **ppv
)
89 TRACE("(%s, %p)\n", debugstr_guid(riid
), ppv
);
90 if (IsEqualIID(riid
, &IID_IUnknown
) ||
91 IsEqualIID(riid
, &IID_IEnumSTATDATA
))
93 IEnumSTATDATA_AddRef(iface
);
100 static ULONG WINAPI
EnumSTATDATA_AddRef(IEnumSTATDATA
*iface
)
102 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
104 return InterlockedIncrement(&This
->ref
);
107 static ULONG WINAPI
EnumSTATDATA_Release(IEnumSTATDATA
*iface
)
109 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
110 LONG refs
= InterlockedDecrement(&This
->ref
);
115 for(i
= 0; i
< This
->num_of_elems
; i
++)
116 release_statdata(This
->statdata
+ i
);
117 HeapFree(GetProcessHeap(), 0, This
->statdata
);
118 if (This
->holder
) IUnknown_Release(This
->holder
);
119 HeapFree(GetProcessHeap(), 0, This
);
124 static HRESULT WINAPI
EnumSTATDATA_Next(IEnumSTATDATA
*iface
, ULONG num
, LPSTATDATA data
,
127 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
131 TRACE("(%d, %p, %p)\n", num
, data
, fetched
);
135 if (This
->index
>= This
->num_of_elems
)
141 copy_statdata(data
+ count
, This
->statdata
+ This
->index
);
147 if (fetched
) *fetched
= count
;
152 static HRESULT WINAPI
EnumSTATDATA_Skip(IEnumSTATDATA
*iface
, ULONG num
)
154 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
156 TRACE("(%d)\n", num
);
158 if(This
->index
+ num
>= This
->num_of_elems
)
160 This
->index
= This
->num_of_elems
;
168 static HRESULT WINAPI
EnumSTATDATA_Reset(IEnumSTATDATA
*iface
)
170 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
178 static HRESULT WINAPI
EnumSTATDATA_Clone(IEnumSTATDATA
*iface
, IEnumSTATDATA
**ppenum
)
180 EnumSTATDATA
*This
= impl_from_IEnumSTATDATA(iface
);
182 return EnumSTATDATA_Construct(This
->holder
, This
->index
, This
->num_of_elems
, This
->statdata
,
186 static const IEnumSTATDATAVtbl EnumSTATDATA_VTable
=
188 EnumSTATDATA_QueryInterface
,
190 EnumSTATDATA_Release
,
197 HRESULT
EnumSTATDATA_Construct(IUnknown
*holder
, ULONG index
, DWORD array_len
, STATDATA
*data
,
198 BOOL copy
, IEnumSTATDATA
**ppenum
)
200 EnumSTATDATA
*This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
203 if (!This
) return E_OUTOFMEMORY
;
205 This
->IEnumSTATDATA_iface
.lpVtbl
= &EnumSTATDATA_VTable
;
211 This
->statdata
= HeapAlloc(GetProcessHeap(), 0, array_len
* sizeof(*This
->statdata
));
214 HeapFree(GetProcessHeap(), 0, This
);
215 return E_OUTOFMEMORY
;
218 for(i
= 0, count
= 0; i
< array_len
; i
++)
222 copy_statdata(This
->statdata
+ count
, data
+ i
);
229 This
->statdata
= data
;
233 This
->num_of_elems
= count
;
234 This
->holder
= holder
;
235 if (holder
) IUnknown_AddRef(holder
);
236 *ppenum
= &This
->IEnumSTATDATA_iface
;
240 /**************************************************************************
241 * OleAdviseHolder Implementation
245 IOleAdviseHolder IOleAdviseHolder_iface
;
250 STATDATA
*connections
;
251 } OleAdviseHolderImpl
;
253 static inline OleAdviseHolderImpl
*impl_from_IOleAdviseHolder(IOleAdviseHolder
*iface
)
255 return CONTAINING_RECORD(iface
, OleAdviseHolderImpl
, IOleAdviseHolder_iface
);
258 /**************************************************************************
259 * OleAdviseHolderImpl_Destructor
261 static void OleAdviseHolderImpl_Destructor(OleAdviseHolderImpl
*This
)
266 for (index
= 0; index
< This
->max_cons
; index
++)
268 if (This
->connections
[index
].pAdvSink
!= NULL
)
269 release_statdata(This
->connections
+ index
);
272 HeapFree(GetProcessHeap(), 0, This
->connections
);
273 HeapFree(GetProcessHeap(), 0, This
);
276 /**************************************************************************
277 * OleAdviseHolderImpl_QueryInterface
279 static HRESULT WINAPI
OleAdviseHolderImpl_QueryInterface(IOleAdviseHolder
*iface
,
280 REFIID iid
, void **obj
)
282 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
283 TRACE("(%p)->(%s,%p)\n",This
, debugstr_guid(iid
), obj
);
290 if (IsEqualIID(iid
, &IID_IUnknown
) ||
291 IsEqualIID(iid
, &IID_IOleAdviseHolder
))
293 *obj
= &This
->IOleAdviseHolder_iface
;
297 return E_NOINTERFACE
;
299 IUnknown_AddRef((IUnknown
*)*obj
);
304 /******************************************************************************
305 * OleAdviseHolderImpl_AddRef
307 static ULONG WINAPI
OleAdviseHolderImpl_AddRef(IOleAdviseHolder
*iface
)
309 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
310 ULONG ref
= InterlockedIncrement(&This
->ref
);
312 TRACE("(%p)->(ref=%d)\n", This
, ref
- 1);
317 /******************************************************************************
318 * OleAdviseHolderImpl_Release
320 static ULONG WINAPI
OleAdviseHolderImpl_Release(IOleAdviseHolder
*iface
)
322 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
324 TRACE("(%p)->(ref=%d)\n", This
, This
->ref
);
325 ref
= InterlockedDecrement(&This
->ref
);
327 if (ref
== 0) OleAdviseHolderImpl_Destructor(This
);
332 /******************************************************************************
333 * OleAdviseHolderImpl_Advise
335 static HRESULT WINAPI
OleAdviseHolderImpl_Advise(IOleAdviseHolder
*iface
,
336 IAdviseSink
*pAdvise
,
337 DWORD
*pdwConnection
)
340 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
342 static const FORMATETC empty_fmtetc
= {0, NULL
, 0, -1, 0};
344 TRACE("(%p)->(%p, %p)\n", This
, pAdvise
, pdwConnection
);
346 if (pdwConnection
==NULL
)
351 for (index
= 0; index
< This
->max_cons
; index
++)
353 if (This
->connections
[index
].pAdvSink
== NULL
)
357 if (index
== This
->max_cons
)
359 This
->max_cons
+= INITIAL_SINKS
;
360 This
->connections
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, This
->connections
,
361 This
->max_cons
* sizeof(*This
->connections
));
364 new_conn
.pAdvSink
= pAdvise
;
366 new_conn
.formatetc
= empty_fmtetc
;
367 new_conn
.dwConnection
= index
+ 1; /* 0 is not a valid cookie, so increment the index */
369 copy_statdata(This
->connections
+ index
, &new_conn
);
371 *pdwConnection
= new_conn
.dwConnection
;
376 /******************************************************************************
377 * OleAdviseHolderImpl_Unadvise
379 static HRESULT WINAPI
OleAdviseHolderImpl_Unadvise(IOleAdviseHolder
*iface
,
382 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
385 TRACE("(%p)->(%u)\n", This
, dwConnection
);
387 /* The connection number is 1 more than the index, see OleAdviseHolder_Advise */
388 index
= dwConnection
- 1;
390 if (index
>= This
->max_cons
|| This
->connections
[index
].pAdvSink
== NULL
)
391 return OLE_E_NOCONNECTION
;
393 release_statdata(This
->connections
+ index
);
398 /******************************************************************************
399 * OleAdviseHolderImpl_EnumAdvise
401 static HRESULT WINAPI
OleAdviseHolderImpl_EnumAdvise(IOleAdviseHolder
*iface
, IEnumSTATDATA
**enum_advise
)
403 OleAdviseHolderImpl
*This
= impl_from_IOleAdviseHolder(iface
);
407 TRACE("(%p)->(%p)\n", This
, enum_advise
);
409 IOleAdviseHolder_QueryInterface(iface
, &IID_IUnknown
, (void**)&unk
);
410 hr
= EnumSTATDATA_Construct(unk
, 0, This
->max_cons
, This
->connections
, TRUE
, enum_advise
);
411 IUnknown_Release(unk
);
415 /******************************************************************************
416 * OleAdviseHolderImpl_SendOnRename
418 static HRESULT WINAPI
OleAdviseHolderImpl_SendOnRename(IOleAdviseHolder
*iface
, IMoniker
*pmk
)
420 IEnumSTATDATA
*pEnum
;
423 TRACE("(%p)->(%p)\n", iface
, pmk
);
425 hr
= IOleAdviseHolder_EnumAdvise(iface
, &pEnum
);
429 while (IEnumSTATDATA_Next(pEnum
, 1, &statdata
, NULL
) == S_OK
)
431 IAdviseSink_OnRename(statdata
.pAdvSink
, pmk
);
433 IAdviseSink_Release(statdata
.pAdvSink
);
435 IEnumSTATDATA_Release(pEnum
);
441 /******************************************************************************
442 * OleAdviseHolderImpl_SendOnSave
444 static HRESULT WINAPI
OleAdviseHolderImpl_SendOnSave(IOleAdviseHolder
*iface
)
446 IEnumSTATDATA
*pEnum
;
449 TRACE("(%p)->()\n", iface
);
451 hr
= IOleAdviseHolder_EnumAdvise(iface
, &pEnum
);
455 while (IEnumSTATDATA_Next(pEnum
, 1, &statdata
, NULL
) == S_OK
)
457 IAdviseSink_OnSave(statdata
.pAdvSink
);
459 IAdviseSink_Release(statdata
.pAdvSink
);
461 IEnumSTATDATA_Release(pEnum
);
467 /******************************************************************************
468 * OleAdviseHolderImpl_SendOnClose
470 static HRESULT WINAPI
OleAdviseHolderImpl_SendOnClose(IOleAdviseHolder
*iface
)
472 IEnumSTATDATA
*pEnum
;
475 TRACE("(%p)->()\n", iface
);
477 hr
= IOleAdviseHolder_EnumAdvise(iface
, &pEnum
);
481 while (IEnumSTATDATA_Next(pEnum
, 1, &statdata
, NULL
) == S_OK
)
483 IAdviseSink_OnClose(statdata
.pAdvSink
);
485 IAdviseSink_Release(statdata
.pAdvSink
);
487 IEnumSTATDATA_Release(pEnum
);
493 /**************************************************************************
494 * OleAdviseHolderImpl_VTable
496 static const IOleAdviseHolderVtbl oahvt
=
498 OleAdviseHolderImpl_QueryInterface
,
499 OleAdviseHolderImpl_AddRef
,
500 OleAdviseHolderImpl_Release
,
501 OleAdviseHolderImpl_Advise
,
502 OleAdviseHolderImpl_Unadvise
,
503 OleAdviseHolderImpl_EnumAdvise
,
504 OleAdviseHolderImpl_SendOnRename
,
505 OleAdviseHolderImpl_SendOnSave
,
506 OleAdviseHolderImpl_SendOnClose
509 /**************************************************************************
510 * OleAdviseHolderImpl_Constructor
513 static IOleAdviseHolder
*OleAdviseHolderImpl_Constructor(void)
515 OleAdviseHolderImpl
* lpoah
;
517 lpoah
= HeapAlloc(GetProcessHeap(), 0, sizeof(OleAdviseHolderImpl
));
519 lpoah
->IOleAdviseHolder_iface
.lpVtbl
= &oahvt
;
521 lpoah
->max_cons
= INITIAL_SINKS
;
522 lpoah
->connections
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
523 lpoah
->max_cons
* sizeof(*lpoah
->connections
));
525 TRACE("returning %p\n", &lpoah
->IOleAdviseHolder_iface
);
526 return &lpoah
->IOleAdviseHolder_iface
;
529 /**************************************************************************
530 * DataAdviseHolder Implementation
534 IDataAdviseHolder IDataAdviseHolder_iface
;
538 STATDATA
* connections
;
539 DWORD
* remote_connections
;
540 IDataObject
* delegate
;
543 /* this connection has also has been advised to the delegate data object */
544 #define WINE_ADVF_REMOTE 0x80000000
546 static inline DataAdviseHolder
*impl_from_IDataAdviseHolder(IDataAdviseHolder
*iface
)
548 return CONTAINING_RECORD(iface
, DataAdviseHolder
, IDataAdviseHolder_iface
);
551 /******************************************************************************
552 * DataAdviseHolder_Destructor
554 static void DataAdviseHolder_Destructor(DataAdviseHolder
* ptrToDestroy
)
557 TRACE("%p\n", ptrToDestroy
);
559 for (index
= 0; index
< ptrToDestroy
->maxCons
; index
++)
561 if (ptrToDestroy
->connections
[index
].pAdvSink
!= NULL
)
563 if (ptrToDestroy
->delegate
&&
564 (ptrToDestroy
->connections
[index
].advf
& WINE_ADVF_REMOTE
))
565 IDataObject_DUnadvise(ptrToDestroy
->delegate
,
566 ptrToDestroy
->remote_connections
[index
]);
568 release_statdata(ptrToDestroy
->connections
+ index
);
572 HeapFree(GetProcessHeap(), 0, ptrToDestroy
->remote_connections
);
573 HeapFree(GetProcessHeap(), 0, ptrToDestroy
->connections
);
574 HeapFree(GetProcessHeap(), 0, ptrToDestroy
);
577 /************************************************************************
578 * DataAdviseHolder_QueryInterface (IUnknown)
580 static HRESULT WINAPI
DataAdviseHolder_QueryInterface(IDataAdviseHolder
*iface
,
581 REFIID riid
, void **ppvObject
)
583 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
584 TRACE("(%p)->(%s,%p)\n",This
,debugstr_guid(riid
),ppvObject
);
586 if ( (This
==0) || (ppvObject
==0) )
591 if ( IsEqualIID(&IID_IUnknown
, riid
) ||
592 IsEqualIID(&IID_IDataAdviseHolder
, riid
) )
599 return E_NOINTERFACE
;
602 IUnknown_AddRef((IUnknown
*)*ppvObject
);
606 /************************************************************************
607 * DataAdviseHolder_AddRef (IUnknown)
609 static ULONG WINAPI
DataAdviseHolder_AddRef(IDataAdviseHolder
*iface
)
611 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
612 TRACE("(%p) (ref=%d)\n", This
, This
->ref
);
613 return InterlockedIncrement(&This
->ref
);
616 /************************************************************************
617 * DataAdviseHolder_Release (IUnknown)
619 static ULONG WINAPI
DataAdviseHolder_Release(IDataAdviseHolder
*iface
)
621 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
623 TRACE("(%p) (ref=%d)\n", This
, This
->ref
);
625 ref
= InterlockedDecrement(&This
->ref
);
626 if (ref
==0) DataAdviseHolder_Destructor(This
);
631 /************************************************************************
632 * DataAdviseHolder_Advise
635 static HRESULT WINAPI
DataAdviseHolder_Advise(IDataAdviseHolder
*iface
,
636 IDataObject
*pDataObject
, FORMATETC
*pFetc
,
637 DWORD advf
, IAdviseSink
*pAdvise
,
638 DWORD
*pdwConnection
)
642 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
644 TRACE("(%p)->(%p, %p, %08x, %p, %p)\n", This
, pDataObject
, pFetc
, advf
,
645 pAdvise
, pdwConnection
);
647 if (pdwConnection
==NULL
)
652 for (index
= 0; index
< This
->maxCons
; index
++)
654 if (This
->connections
[index
].pAdvSink
== NULL
)
658 if (index
== This
->maxCons
)
660 This
->maxCons
+=INITIAL_SINKS
;
661 This
->connections
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
663 This
->maxCons
* sizeof(*This
->connections
));
664 This
->remote_connections
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
665 This
->remote_connections
,
666 This
->maxCons
* sizeof(*This
->remote_connections
));
669 new_conn
.pAdvSink
= pAdvise
;
670 new_conn
.advf
= advf
& ~WINE_ADVF_REMOTE
;
671 new_conn
.formatetc
= *pFetc
;
672 new_conn
.dwConnection
= index
+ 1; /* 0 is not a valid cookie, so increment the index */
674 copy_statdata(This
->connections
+ index
, &new_conn
);
676 if (This
->connections
[index
].pAdvSink
!= NULL
)
678 /* if we are already connected advise the remote object */
683 hr
= IDataObject_DAdvise(This
->delegate
, &new_conn
.formatetc
,
684 new_conn
.advf
, new_conn
.pAdvSink
,
685 &This
->remote_connections
[index
]);
688 IDataAdviseHolder_Unadvise(iface
, new_conn
.dwConnection
);
691 This
->connections
[index
].advf
|= WINE_ADVF_REMOTE
;
693 else if(advf
& ADVF_PRIMEFIRST
)
694 /* only do this if we have no delegate, since in the above case the
695 * delegate will do the priming for us */
696 IDataAdviseHolder_SendOnDataChange(iface
, pDataObject
, 0, advf
);
699 *pdwConnection
= new_conn
.dwConnection
;
704 /******************************************************************************
705 * DataAdviseHolder_Unadvise
707 static HRESULT WINAPI
DataAdviseHolder_Unadvise(IDataAdviseHolder
*iface
,
710 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
712 TRACE("(%p)->(%u)\n", This
, dwConnection
);
714 /* The connection number is 1 more than the index, see DataAdviseHolder_Advise */
715 index
= dwConnection
- 1;
717 if (index
>= This
->maxCons
|| This
->connections
[index
].pAdvSink
== NULL
)
718 return OLE_E_NOCONNECTION
;
720 if (This
->delegate
&& This
->connections
[index
].advf
& WINE_ADVF_REMOTE
)
722 IDataObject_DUnadvise(This
->delegate
, This
->remote_connections
[index
]);
723 This
->remote_connections
[index
] = 0;
726 release_statdata(This
->connections
+ index
);
731 /******************************************************************************
732 * DataAdviseHolder_EnumAdvise
734 static HRESULT WINAPI
DataAdviseHolder_EnumAdvise(IDataAdviseHolder
*iface
,
735 IEnumSTATDATA
**enum_advise
)
737 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
741 TRACE("(%p)->(%p)\n", This
, enum_advise
);
743 IDataAdviseHolder_QueryInterface(iface
, &IID_IUnknown
, (void**)&unk
);
744 hr
= EnumSTATDATA_Construct(unk
, 0, This
->maxCons
, This
->connections
, TRUE
, enum_advise
);
745 IUnknown_Release(unk
);
749 /******************************************************************************
750 * DataAdviseHolder_SendOnDataChange
752 static HRESULT WINAPI
DataAdviseHolder_SendOnDataChange(IDataAdviseHolder
*iface
,
753 IDataObject
*data_obj
,
754 DWORD dwReserved
, DWORD advf
)
756 IEnumSTATDATA
*pEnum
;
759 TRACE("(%p)->(%p, %08x, %08x)\n", iface
, data_obj
, dwReserved
, advf
);
761 hr
= IDataAdviseHolder_EnumAdvise(iface
, &pEnum
);
765 while (IEnumSTATDATA_Next(pEnum
, 1, &statdata
, NULL
) == S_OK
)
768 stg
.tymed
= TYMED_NULL
;
770 stg
.pUnkForRelease
= NULL
;
772 if(!(statdata
.advf
& ADVF_NODATA
))
774 hr
= IDataObject_GetData(data_obj
, &statdata
.formatetc
, &stg
);
777 IAdviseSink_OnDataChange(statdata
.pAdvSink
, &statdata
.formatetc
, &stg
);
779 if(statdata
.advf
& ADVF_ONLYONCE
)
781 IDataAdviseHolder_Unadvise(iface
, statdata
.dwConnection
);
784 release_statdata(&statdata
);
786 IEnumSTATDATA_Release(pEnum
);
792 /**************************************************************************
793 * DataAdviseHolderImpl_VTable
795 static const IDataAdviseHolderVtbl DataAdviseHolderImpl_VTable
=
797 DataAdviseHolder_QueryInterface
,
798 DataAdviseHolder_AddRef
,
799 DataAdviseHolder_Release
,
800 DataAdviseHolder_Advise
,
801 DataAdviseHolder_Unadvise
,
802 DataAdviseHolder_EnumAdvise
,
803 DataAdviseHolder_SendOnDataChange
806 HRESULT
DataAdviseHolder_OnConnect(IDataAdviseHolder
*iface
, IDataObject
*pDelegate
)
808 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
812 for(index
= 0; index
< This
->maxCons
; index
++)
814 if(This
->connections
[index
].pAdvSink
!= NULL
)
816 hr
= IDataObject_DAdvise(pDelegate
, &This
->connections
[index
].formatetc
,
817 This
->connections
[index
].advf
,
818 This
->connections
[index
].pAdvSink
,
819 &This
->remote_connections
[index
]);
820 if (FAILED(hr
)) break;
821 This
->connections
[index
].advf
|= WINE_ADVF_REMOTE
;
824 This
->delegate
= pDelegate
;
828 void DataAdviseHolder_OnDisconnect(IDataAdviseHolder
*iface
)
830 DataAdviseHolder
*This
= impl_from_IDataAdviseHolder(iface
);
833 for(index
= 0; index
< This
->maxCons
; index
++)
835 if((This
->connections
[index
].pAdvSink
!= NULL
) &&
836 (This
->connections
[index
].advf
& WINE_ADVF_REMOTE
))
838 IDataObject_DUnadvise(This
->delegate
, This
->remote_connections
[index
]);
839 This
->remote_connections
[index
] = 0;
840 This
->connections
[index
].advf
&= ~WINE_ADVF_REMOTE
;
843 This
->delegate
= NULL
;
846 /******************************************************************************
847 * DataAdviseHolder_Constructor
849 static IDataAdviseHolder
*DataAdviseHolder_Constructor(void)
851 DataAdviseHolder
* newHolder
;
853 newHolder
= HeapAlloc(GetProcessHeap(), 0, sizeof(DataAdviseHolder
));
855 newHolder
->IDataAdviseHolder_iface
.lpVtbl
= &DataAdviseHolderImpl_VTable
;
857 newHolder
->maxCons
= INITIAL_SINKS
;
858 newHolder
->connections
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
859 newHolder
->maxCons
* sizeof(*newHolder
->connections
));
860 newHolder
->remote_connections
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
861 newHolder
->maxCons
* sizeof(*newHolder
->remote_connections
));
862 newHolder
->delegate
= NULL
;
864 TRACE("returning %p\n", &newHolder
->IDataAdviseHolder_iface
);
865 return &newHolder
->IDataAdviseHolder_iface
;
868 /***********************************************************************
872 /***********************************************************************
873 * CreateOleAdviseHolder [OLE32.@]
875 HRESULT WINAPI
CreateOleAdviseHolder(IOleAdviseHolder
**ppOAHolder
)
877 TRACE("(%p)\n", ppOAHolder
);
879 if (ppOAHolder
==NULL
)
882 *ppOAHolder
= OleAdviseHolderImpl_Constructor ();
884 if (*ppOAHolder
!= NULL
)
887 return E_OUTOFMEMORY
;
890 /******************************************************************************
891 * CreateDataAdviseHolder [OLE32.@]
893 HRESULT WINAPI
CreateDataAdviseHolder(IDataAdviseHolder
**ppDAHolder
)
895 TRACE("(%p)\n", ppDAHolder
);
897 if (ppDAHolder
==NULL
)
900 *ppDAHolder
= DataAdviseHolder_Constructor();
902 if (*ppDAHolder
!= NULL
)
905 return E_OUTOFMEMORY
;