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
32 #include "wine/debug.h"
35 #include "compobj_private.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(ole);
39 #define INITIAL_SINKS 10
41 /**************************************************************************
42 * OleAdviseHolderImpl Implementation
44 typedef struct OleAdviseHolderImpl
46 const IOleAdviseHolderVtbl *lpVtbl;
51 IAdviseSink** arrayOfSinks;
53 } OleAdviseHolderImpl;
55 static HRESULT EnumOleSTATDATA_Construct(OleAdviseHolderImpl *pOleAdviseHolder, ULONG index, IEnumSTATDATA **ppenum);
59 IEnumSTATDATA IEnumSTATDATA_iface;
63 OleAdviseHolderImpl *pOleAdviseHolder;
66 static inline EnumOleSTATDATA *impl_from_IEnumSTATDATA(IEnumSTATDATA *iface)
68 return CONTAINING_RECORD(iface, EnumOleSTATDATA, IEnumSTATDATA_iface);
71 static HRESULT WINAPI EnumOleSTATDATA_QueryInterface(
72 IEnumSTATDATA *iface, REFIID riid, void **ppv)
74 TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
75 if (IsEqualIID(riid, &IID_IUnknown) ||
76 IsEqualIID(riid, &IID_IEnumSTATDATA))
78 IUnknown_AddRef(iface);
85 static ULONG WINAPI EnumOleSTATDATA_AddRef(
88 EnumOleSTATDATA *This = impl_from_IEnumSTATDATA(iface);
90 return InterlockedIncrement(&This->ref);
93 static ULONG WINAPI EnumOleSTATDATA_Release(
96 EnumOleSTATDATA *This = impl_from_IEnumSTATDATA(iface);
97 LONG refs = InterlockedDecrement(&This->ref);
101 IOleAdviseHolder_Release((IOleAdviseHolder *)This->pOleAdviseHolder);
102 HeapFree(GetProcessHeap(), 0, This);
107 static HRESULT WINAPI EnumOleSTATDATA_Next(
108 IEnumSTATDATA *iface, ULONG celt, LPSTATDATA rgelt,
111 EnumOleSTATDATA *This = impl_from_IEnumSTATDATA(iface);
114 TRACE("(%d, %p, %p)\n", celt, rgelt, pceltFetched);
119 for (; celt; celt--, rgelt++)
121 while ((This->index < This->pOleAdviseHolder->maxSinks) &&
122 !This->pOleAdviseHolder->arrayOfSinks[This->index])
126 if (This->index >= This->pOleAdviseHolder->maxSinks)
132 memset(&rgelt->formatetc, 0, sizeof(rgelt->formatetc));
134 rgelt->pAdvSink = This->pOleAdviseHolder->arrayOfSinks[This->index];
135 IAdviseSink_AddRef(rgelt->pAdvSink);
136 rgelt->dwConnection = This->index;
145 static HRESULT WINAPI EnumOleSTATDATA_Skip(
146 IEnumSTATDATA *iface, ULONG celt)
148 EnumOleSTATDATA *This = impl_from_IEnumSTATDATA(iface);
150 TRACE("(%d)\n", celt);
154 while ((This->index < This->pOleAdviseHolder->maxSinks) &&
155 !This->pOleAdviseHolder->arrayOfSinks[This->index])
159 if (This->index >= This->pOleAdviseHolder->maxSinks)
166 static HRESULT WINAPI EnumOleSTATDATA_Reset(
167 IEnumSTATDATA *iface)
169 EnumOleSTATDATA *This = impl_from_IEnumSTATDATA(iface);
177 static HRESULT WINAPI EnumOleSTATDATA_Clone(
178 IEnumSTATDATA *iface,
179 IEnumSTATDATA **ppenum)
181 EnumOleSTATDATA *This = impl_from_IEnumSTATDATA(iface);
182 return EnumOleSTATDATA_Construct(This->pOleAdviseHolder, This->index, ppenum);
185 static const IEnumSTATDATAVtbl EnumOleSTATDATA_VTable =
187 EnumOleSTATDATA_QueryInterface,
188 EnumOleSTATDATA_AddRef,
189 EnumOleSTATDATA_Release,
190 EnumOleSTATDATA_Next,
191 EnumOleSTATDATA_Skip,
192 EnumOleSTATDATA_Reset,
193 EnumOleSTATDATA_Clone
196 static HRESULT EnumOleSTATDATA_Construct(OleAdviseHolderImpl *pOleAdviseHolder, ULONG index, IEnumSTATDATA **ppenum)
198 EnumOleSTATDATA *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
200 return E_OUTOFMEMORY;
201 This->IEnumSTATDATA_iface.lpVtbl = &EnumOleSTATDATA_VTable;
204 This->pOleAdviseHolder = pOleAdviseHolder;
205 IOleAdviseHolder_AddRef((IOleAdviseHolder *)pOleAdviseHolder);
206 *ppenum = &This->IEnumSTATDATA_iface;
210 /**************************************************************************
211 * OleAdviseHolderImpl_Destructor
213 static void OleAdviseHolderImpl_Destructor(
214 OleAdviseHolderImpl* ptrToDestroy)
217 TRACE("%p\n", ptrToDestroy);
219 for (index = 0; index < ptrToDestroy->maxSinks; index++)
221 if (ptrToDestroy->arrayOfSinks[index]!=0)
223 IAdviseSink_Release(ptrToDestroy->arrayOfSinks[index]);
224 ptrToDestroy->arrayOfSinks[index] = NULL;
228 HeapFree(GetProcessHeap(),
230 ptrToDestroy->arrayOfSinks);
233 HeapFree(GetProcessHeap(),
238 /**************************************************************************
239 * OleAdviseHolderImpl_QueryInterface
241 static HRESULT WINAPI OleAdviseHolderImpl_QueryInterface(
242 LPOLEADVISEHOLDER iface,
246 OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
247 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppvObj);
256 if (IsEqualIID(riid, &IID_IUnknown))
261 else if(IsEqualIID(riid, &IID_IOleAdviseHolder))
263 /* IOleAdviseHolder */
268 return E_NOINTERFACE;
271 * A successful QI always increments the reference count.
273 IUnknown_AddRef((IUnknown*)*ppvObj);
278 /******************************************************************************
279 * OleAdviseHolderImpl_AddRef
281 static ULONG WINAPI OleAdviseHolderImpl_AddRef(
282 LPOLEADVISEHOLDER iface)
284 OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
285 ULONG ref = InterlockedIncrement(&This->ref);
287 TRACE("(%p)->(ref=%d)\n", This, ref - 1);
292 /******************************************************************************
293 * OleAdviseHolderImpl_Release
295 static ULONG WINAPI OleAdviseHolderImpl_Release(
296 LPOLEADVISEHOLDER iface)
298 OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
300 TRACE("(%p)->(ref=%d)\n", This, This->ref);
301 ref = InterlockedDecrement(&This->ref);
303 if (ref == 0) OleAdviseHolderImpl_Destructor(This);
308 /******************************************************************************
309 * OleAdviseHolderImpl_Advise
311 static HRESULT WINAPI OleAdviseHolderImpl_Advise(
312 LPOLEADVISEHOLDER iface,
313 IAdviseSink* pAdvise,
314 DWORD* pdwConnection)
318 OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
320 TRACE("(%p)->(%p, %p)\n", This, pAdvise, pdwConnection);
325 if (pdwConnection==NULL)
331 * Find a free spot in the array.
333 for (index = 0; index < This->maxSinks; index++)
335 if (This->arrayOfSinks[index]==NULL)
340 * If the array is full, we need to grow it.
342 if (index == This->maxSinks)
346 This->maxSinks+=INITIAL_SINKS;
348 This->arrayOfSinks = HeapReAlloc(GetProcessHeap(),
351 This->maxSinks*sizeof(IAdviseSink*));
353 for (i=index;i < This->maxSinks; i++)
354 This->arrayOfSinks[i]=0;
360 This->arrayOfSinks[index] = pAdvise;
362 if (This->arrayOfSinks[index]!=NULL)
363 IAdviseSink_AddRef(This->arrayOfSinks[index]);
366 * Return the index as the cookie.
367 * Since 0 is not a valid cookie, we will increment by
368 * 1 the index in the table.
370 *pdwConnection = index+1;
375 /******************************************************************************
376 * OleAdviseHolderImpl_Unadvise
378 static HRESULT WINAPI OleAdviseHolderImpl_Unadvise(
379 LPOLEADVISEHOLDER iface,
382 OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
384 TRACE("(%p)->(%u)\n", This, dwConnection);
387 * So we don't return 0 as a cookie, the index was
388 * incremented by 1 in OleAdviseHolderImpl_Advise
389 * we have to compensate.
394 * Check for invalid cookies.
396 if (dwConnection >= This->maxSinks)
397 return OLE_E_NOCONNECTION;
399 if (This->arrayOfSinks[dwConnection] == NULL)
400 return OLE_E_NOCONNECTION;
403 * Release the sink and mark the spot in the list as free.
405 IAdviseSink_Release(This->arrayOfSinks[dwConnection]);
406 This->arrayOfSinks[dwConnection] = NULL;
411 /******************************************************************************
412 * OleAdviseHolderImpl_EnumAdvise
414 static HRESULT WINAPI
415 OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER iface, IEnumSTATDATA **ppenumAdvise)
417 OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
419 TRACE("(%p)->(%p)\n", This, ppenumAdvise);
421 *ppenumAdvise = NULL;
423 return EnumOleSTATDATA_Construct(This, 0, ppenumAdvise);
426 /******************************************************************************
427 * OleAdviseHolderImpl_SendOnRename
429 static HRESULT WINAPI
430 OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER iface, IMoniker *pmk)
432 IEnumSTATDATA *pEnum;
435 TRACE("(%p)->(%p)\n", iface, pmk);
437 hr = IOleAdviseHolder_EnumAdvise(iface, &pEnum);
441 while (IEnumSTATDATA_Next(pEnum, 1, &statdata, NULL) == S_OK)
443 IAdviseSink_OnRename(statdata.pAdvSink, pmk);
445 IAdviseSink_Release(statdata.pAdvSink);
447 IEnumSTATDATA_Release(pEnum);
453 /******************************************************************************
454 * OleAdviseHolderImpl_SendOnSave
456 static HRESULT WINAPI
457 OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER iface)
459 IEnumSTATDATA *pEnum;
462 TRACE("(%p)->()\n", iface);
464 hr = IOleAdviseHolder_EnumAdvise(iface, &pEnum);
468 while (IEnumSTATDATA_Next(pEnum, 1, &statdata, NULL) == S_OK)
470 IAdviseSink_OnSave(statdata.pAdvSink);
472 IAdviseSink_Release(statdata.pAdvSink);
474 IEnumSTATDATA_Release(pEnum);
480 /******************************************************************************
481 * OleAdviseHolderImpl_SendOnClose
483 static HRESULT WINAPI
484 OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER iface)
486 IEnumSTATDATA *pEnum;
489 TRACE("(%p)->()\n", iface);
491 hr = IOleAdviseHolder_EnumAdvise(iface, &pEnum);
495 while (IEnumSTATDATA_Next(pEnum, 1, &statdata, NULL) == S_OK)
497 IAdviseSink_OnClose(statdata.pAdvSink);
499 IAdviseSink_Release(statdata.pAdvSink);
501 IEnumSTATDATA_Release(pEnum);
507 /**************************************************************************
508 * OleAdviseHolderImpl_VTable
510 static const IOleAdviseHolderVtbl oahvt =
512 OleAdviseHolderImpl_QueryInterface,
513 OleAdviseHolderImpl_AddRef,
514 OleAdviseHolderImpl_Release,
515 OleAdviseHolderImpl_Advise,
516 OleAdviseHolderImpl_Unadvise,
517 OleAdviseHolderImpl_EnumAdvise,
518 OleAdviseHolderImpl_SendOnRename,
519 OleAdviseHolderImpl_SendOnSave,
520 OleAdviseHolderImpl_SendOnClose
523 /**************************************************************************
524 * OleAdviseHolderImpl_Constructor
527 static LPOLEADVISEHOLDER OleAdviseHolderImpl_Constructor(void)
529 OleAdviseHolderImpl* lpoah;
532 lpoah = HeapAlloc(GetProcessHeap(), 0, sizeof(OleAdviseHolderImpl));
534 lpoah->lpVtbl = &oahvt;
536 lpoah->maxSinks = INITIAL_SINKS;
537 lpoah->arrayOfSinks = HeapAlloc(GetProcessHeap(),
539 lpoah->maxSinks * sizeof(IAdviseSink*));
541 for (index = 0; index < lpoah->maxSinks; index++)
542 lpoah->arrayOfSinks[index]=0;
544 TRACE("returning %p\n", lpoah);
545 return (LPOLEADVISEHOLDER)lpoah;
548 /**************************************************************************
549 * DataAdviseHolder Implementation
551 typedef struct DataAdviseConnection {
555 DWORD remote_connection;
556 } DataAdviseConnection;
558 typedef struct DataAdviseHolder
560 const IDataAdviseHolderVtbl *lpVtbl;
564 DataAdviseConnection* Connections;
565 IDataObject* delegate;
568 /* this connection has also has been advised to the delegate data object */
569 #define WINE_ADVF_REMOTE 0x80000000
571 /******************************************************************************
572 * DataAdviseHolder_Destructor
574 static void DataAdviseHolder_Destructor(DataAdviseHolder* ptrToDestroy)
577 TRACE("%p\n", ptrToDestroy);
579 for (index = 0; index < ptrToDestroy->maxCons; index++)
581 if (ptrToDestroy->Connections[index].sink != NULL)
583 if (ptrToDestroy->delegate &&
584 (ptrToDestroy->Connections[index].advf & WINE_ADVF_REMOTE))
585 IDataObject_DUnadvise(ptrToDestroy->delegate,
586 ptrToDestroy->Connections[index].remote_connection);
588 IAdviseSink_Release(ptrToDestroy->Connections[index].sink);
589 ptrToDestroy->Connections[index].sink = NULL;
593 HeapFree(GetProcessHeap(), 0, ptrToDestroy->Connections);
594 HeapFree(GetProcessHeap(), 0, ptrToDestroy);
597 /************************************************************************
598 * DataAdviseHolder_QueryInterface (IUnknown)
600 * See Windows documentation for more details on IUnknown methods.
602 static HRESULT WINAPI DataAdviseHolder_QueryInterface(
603 IDataAdviseHolder* iface,
607 DataAdviseHolder *This = (DataAdviseHolder *)iface;
608 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppvObject);
610 * Perform a sanity check on the parameters.
612 if ( (This==0) || (ppvObject==0) )
616 * Initialize the return parameter.
621 * Compare the riid with the interface IDs implemented by this object.
623 if ( IsEqualIID(&IID_IUnknown, riid) ||
624 IsEqualIID(&IID_IDataAdviseHolder, riid) )
630 * Check that we obtained an interface.
634 return E_NOINTERFACE;
638 * Query Interface always increases the reference count by one when it is
641 IUnknown_AddRef((IUnknown*)*ppvObject);
646 /************************************************************************
647 * DataAdviseHolder_AddRef (IUnknown)
649 * See Windows documentation for more details on IUnknown methods.
651 static ULONG WINAPI DataAdviseHolder_AddRef(
652 IDataAdviseHolder* iface)
654 DataAdviseHolder *This = (DataAdviseHolder *)iface;
655 TRACE("(%p) (ref=%d)\n", This, This->ref);
656 return InterlockedIncrement(&This->ref);
659 /************************************************************************
660 * DataAdviseHolder_Release (IUnknown)
662 * See Windows documentation for more details on IUnknown methods.
664 static ULONG WINAPI DataAdviseHolder_Release(
665 IDataAdviseHolder* iface)
667 DataAdviseHolder *This = (DataAdviseHolder *)iface;
669 TRACE("(%p) (ref=%d)\n", This, This->ref);
672 * Decrease the reference count on this object.
674 ref = InterlockedDecrement(&This->ref);
677 * If the reference count goes down to 0, perform suicide.
679 if (ref==0) DataAdviseHolder_Destructor(This);
684 /************************************************************************
685 * DataAdviseHolder_Advise
688 static HRESULT WINAPI DataAdviseHolder_Advise(
689 IDataAdviseHolder* iface,
690 IDataObject* pDataObject,
693 IAdviseSink* pAdvise,
694 DWORD* pdwConnection)
698 DataAdviseHolder *This = (DataAdviseHolder *)iface;
700 TRACE("(%p)->(%p, %p, %08x, %p, %p)\n", This, pDataObject, pFetc, advf,
701 pAdvise, pdwConnection);
705 if (pdwConnection==NULL)
711 * Find a free spot in the array.
713 for (index = 0; index < This->maxCons; index++)
715 if (This->Connections[index].sink == NULL)
720 * If the array is full, we need to grow it.
722 if (index == This->maxCons)
724 This->maxCons+=INITIAL_SINKS;
725 This->Connections = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
727 This->maxCons*sizeof(DataAdviseConnection));
732 This->Connections[index].sink = pAdvise;
733 This->Connections[index].advf = advf & ~WINE_ADVF_REMOTE;
734 This->Connections[index].fmat = *pFetc;
737 This->Connections[index].fmat.ptd = CoTaskMemAlloc(pFetc->ptd->tdSize);
738 if (!This->Connections[index].fmat.ptd)
740 IDataAdviseHolder_Unadvise(iface, index + 1);
741 return E_OUTOFMEMORY;
743 memcpy(This->Connections[index].fmat.ptd, pFetc->ptd, pFetc->ptd->tdSize);
746 if (This->Connections[index].sink != NULL) {
747 IAdviseSink_AddRef(This->Connections[index].sink);
749 /* if we are already connected advise the remote object */
754 hr = IDataObject_DAdvise(This->delegate, &This->Connections[index].fmat,
755 This->Connections[index].advf,
756 This->Connections[index].sink,
757 &This->Connections[index].remote_connection);
760 IDataAdviseHolder_Unadvise(iface, index + 1);
763 This->Connections[index].advf |= WINE_ADVF_REMOTE;
765 else if(advf & ADVF_PRIMEFIRST)
766 /* only do this if we have no delegate, since in the above case the
767 * delegate will do the priming for us */
768 IDataAdviseHolder_SendOnDataChange(iface, pDataObject, 0, advf);
771 * Return the index as the cookie.
772 * Since 0 is not a valid cookie, we will increment by
773 * 1 the index in the table.
775 *pdwConnection = index+1;
780 /******************************************************************************
781 * DataAdviseHolder_Unadvise
783 static HRESULT WINAPI DataAdviseHolder_Unadvise(
784 IDataAdviseHolder* iface,
787 DataAdviseHolder *This = (DataAdviseHolder *)iface;
789 TRACE("(%p)->(%u)\n", This, dwConnection);
792 * So we don't return 0 as a cookie, the index was
793 * incremented by 1 in OleAdviseHolderImpl_Advise
794 * we have to compensate.
799 * Check for invalid cookies.
801 if (dwConnection >= This->maxCons)
802 return OLE_E_NOCONNECTION;
804 if (This->Connections[dwConnection].sink == NULL)
805 return OLE_E_NOCONNECTION;
807 if (This->delegate && This->Connections[dwConnection].advf & WINE_ADVF_REMOTE)
808 IDataObject_DUnadvise(This->delegate,
809 This->Connections[dwConnection].remote_connection);
812 * Release the sink and mark the spot in the list as free.
814 IAdviseSink_Release(This->Connections[dwConnection].sink);
815 memset(&(This->Connections[dwConnection]), 0, sizeof(DataAdviseConnection));
820 static HRESULT WINAPI DataAdviseHolder_EnumAdvise(
821 IDataAdviseHolder* iface,
822 IEnumSTATDATA** ppenumAdvise)
824 DataAdviseHolder *This = (DataAdviseHolder *)iface;
826 FIXME("(%p)->(%p)\n", This, ppenumAdvise);
830 /******************************************************************************
831 * DataAdviseHolder_SendOnDataChange
833 static HRESULT WINAPI DataAdviseHolder_SendOnDataChange(
834 IDataAdviseHolder* iface,
835 IDataObject* pDataObject,
839 DataAdviseHolder *This = (DataAdviseHolder *)iface;
844 TRACE("(%p)->(%p,%08x,%08x)\n", This, pDataObject, dwReserved, advf);
846 for(index = 0; index < This->maxCons; index++) {
847 if(This->Connections[index].sink != NULL) {
848 memset(&stg, 0, sizeof(stg));
849 if(!(This->Connections[index].advf & ADVF_NODATA)) {
850 TRACE("Calling IDataObject_GetData\n");
851 res = IDataObject_GetData(pDataObject,
852 &(This->Connections[index].fmat),
854 TRACE("returns %08x\n", res);
856 TRACE("Calling IAdviseSink_OnDataChange\n");
857 IAdviseSink_OnDataChange(This->Connections[index].sink,
858 &(This->Connections[index].fmat),
860 TRACE("Done IAdviseSink_OnDataChange\n");
861 if(This->Connections[index].advf & ADVF_ONLYONCE) {
862 TRACE("Removing connection\n");
863 DataAdviseHolder_Unadvise(iface, index+1);
870 /**************************************************************************
871 * DataAdviseHolderImpl_VTable
873 static const IDataAdviseHolderVtbl DataAdviseHolderImpl_VTable =
875 DataAdviseHolder_QueryInterface,
876 DataAdviseHolder_AddRef,
877 DataAdviseHolder_Release,
878 DataAdviseHolder_Advise,
879 DataAdviseHolder_Unadvise,
880 DataAdviseHolder_EnumAdvise,
881 DataAdviseHolder_SendOnDataChange
884 HRESULT DataAdviseHolder_OnConnect(IDataAdviseHolder *iface, IDataObject *pDelegate)
886 DataAdviseHolder *This = (DataAdviseHolder *)iface;
890 for(index = 0; index < This->maxCons; index++)
892 if(This->Connections[index].sink != NULL)
894 hr = IDataObject_DAdvise(pDelegate, &This->Connections[index].fmat,
895 This->Connections[index].advf,
896 This->Connections[index].sink,
897 &This->Connections[index].remote_connection);
898 if (FAILED(hr)) break;
899 This->Connections[index].advf |= WINE_ADVF_REMOTE;
902 This->delegate = pDelegate;
906 void DataAdviseHolder_OnDisconnect(IDataAdviseHolder *iface)
908 DataAdviseHolder *This = (DataAdviseHolder *)iface;
911 for(index = 0; index < This->maxCons; index++)
913 if((This->Connections[index].sink != NULL) &&
914 (This->Connections[index].advf & WINE_ADVF_REMOTE))
916 IDataObject_DUnadvise(This->delegate,
917 This->Connections[index].remote_connection);
918 This->Connections[index].advf &= ~WINE_ADVF_REMOTE;
921 This->delegate = NULL;
924 /******************************************************************************
925 * DataAdviseHolder_Constructor
927 static IDataAdviseHolder* DataAdviseHolder_Constructor(void)
929 DataAdviseHolder* newHolder;
931 newHolder = HeapAlloc(GetProcessHeap(), 0, sizeof(DataAdviseHolder));
933 newHolder->lpVtbl = &DataAdviseHolderImpl_VTable;
935 newHolder->maxCons = INITIAL_SINKS;
936 newHolder->Connections = HeapAlloc(GetProcessHeap(),
939 sizeof(DataAdviseConnection));
940 newHolder->delegate = NULL;
942 TRACE("returning %p\n", newHolder);
943 return (IDataAdviseHolder*)newHolder;
946 /***********************************************************************
950 /***********************************************************************
951 * CreateOleAdviseHolder [OLE32.@]
953 HRESULT WINAPI CreateOleAdviseHolder(
954 LPOLEADVISEHOLDER *ppOAHolder)
956 TRACE("(%p)\n", ppOAHolder);
961 if (ppOAHolder==NULL)
964 *ppOAHolder = OleAdviseHolderImpl_Constructor ();
966 if (*ppOAHolder != NULL)
969 return E_OUTOFMEMORY;
972 /******************************************************************************
973 * CreateDataAdviseHolder [OLE32.@]
975 HRESULT WINAPI CreateDataAdviseHolder(
976 LPDATAADVISEHOLDER* ppDAHolder)
978 TRACE("(%p)\n", ppDAHolder);
983 if (ppDAHolder==NULL)
986 *ppDAHolder = DataAdviseHolder_Constructor();
988 if (*ppDAHolder != NULL)
991 return E_OUTOFMEMORY;