| /* |
| * OLE2 COM objects |
| * |
| * Copyright 1998 Eric Kohl |
| * Copyright 1999 Francis Beaudet |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| */ |
| |
| |
| #include <string.h> |
| #include "winbase.h" |
| #include "winerror.h" |
| #include "wine/debug.h" |
| #include "oleidl.h" |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(ole); |
| |
| #define INITIAL_SINKS 10 |
| |
| /************************************************************************** |
| * OleAdviseHolderImpl Implementation |
| */ |
| typedef struct OleAdviseHolderImpl |
| { |
| ICOM_VFIELD(IOleAdviseHolder); |
| |
| DWORD ref; |
| |
| DWORD maxSinks; |
| IAdviseSink** arrayOfSinks; |
| |
| } OleAdviseHolderImpl; |
| |
| static LPOLEADVISEHOLDER OleAdviseHolderImpl_Constructor(); |
| static void OleAdviseHolderImpl_Destructor(OleAdviseHolderImpl* ptrToDestroy); |
| static HRESULT WINAPI OleAdviseHolderImpl_QueryInterface(LPOLEADVISEHOLDER,REFIID,LPVOID*); |
| static ULONG WINAPI OleAdviseHolderImpl_AddRef(LPOLEADVISEHOLDER); |
| static ULONG WINAPI OleAdviseHolderImpl_Release(LPOLEADVISEHOLDER); |
| static HRESULT WINAPI OleAdviseHolderImpl_Advise(LPOLEADVISEHOLDER, IAdviseSink*, DWORD*); |
| static HRESULT WINAPI OleAdviseHolderImpl_Unadvise (LPOLEADVISEHOLDER, DWORD); |
| static HRESULT WINAPI OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER, IEnumSTATDATA **); |
| static HRESULT WINAPI OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER, IMoniker *); |
| static HRESULT WINAPI OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER); |
| static HRESULT WINAPI OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER); |
| |
| |
| /************************************************************************** |
| * OleAdviseHolderImpl_VTable |
| */ |
| static struct ICOM_VTABLE(IOleAdviseHolder) oahvt = |
| { |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE |
| OleAdviseHolderImpl_QueryInterface, |
| OleAdviseHolderImpl_AddRef, |
| OleAdviseHolderImpl_Release, |
| OleAdviseHolderImpl_Advise, |
| OleAdviseHolderImpl_Unadvise, |
| OleAdviseHolderImpl_EnumAdvise, |
| OleAdviseHolderImpl_SendOnRename, |
| OleAdviseHolderImpl_SendOnSave, |
| OleAdviseHolderImpl_SendOnClose |
| }; |
| |
| /************************************************************************** |
| * OleAdviseHolderImpl_Constructor |
| */ |
| |
| static LPOLEADVISEHOLDER OleAdviseHolderImpl_Constructor() |
| { |
| OleAdviseHolderImpl* lpoah; |
| DWORD index; |
| |
| lpoah= (OleAdviseHolderImpl*)HeapAlloc(GetProcessHeap(), |
| 0, |
| sizeof(OleAdviseHolderImpl)); |
| |
| ICOM_VTBL(lpoah) = &oahvt; |
| lpoah->ref = 1; |
| lpoah->maxSinks = INITIAL_SINKS; |
| lpoah->arrayOfSinks = HeapAlloc(GetProcessHeap(), |
| 0, |
| lpoah->maxSinks * sizeof(IAdviseSink*)); |
| |
| for (index = 0; index < lpoah->maxSinks; index++) |
| lpoah->arrayOfSinks[index]=0; |
| |
| TRACE("returning %p\n", lpoah); |
| return (LPOLEADVISEHOLDER)lpoah; |
| } |
| |
| /************************************************************************** |
| * OleAdviseHolderImpl_Destructor |
| */ |
| static void OleAdviseHolderImpl_Destructor( |
| OleAdviseHolderImpl* ptrToDestroy) |
| { |
| DWORD index; |
| TRACE("%p\n", ptrToDestroy); |
| |
| for (index = 0; index < ptrToDestroy->maxSinks; index++) |
| { |
| if (ptrToDestroy->arrayOfSinks[index]!=0) |
| { |
| IAdviseSink_Release(ptrToDestroy->arrayOfSinks[index]); |
| ptrToDestroy->arrayOfSinks[index] = NULL; |
| } |
| } |
| |
| HeapFree(GetProcessHeap(), |
| 0, |
| ptrToDestroy->arrayOfSinks); |
| |
| |
| HeapFree(GetProcessHeap(), |
| 0, |
| ptrToDestroy); |
| } |
| |
| /************************************************************************** |
| * OleAdviseHolderImpl_QueryInterface |
| */ |
| static HRESULT WINAPI OleAdviseHolderImpl_QueryInterface( |
| LPOLEADVISEHOLDER iface, |
| REFIID riid, |
| LPVOID* ppvObj) |
| { |
| ICOM_THIS(OleAdviseHolderImpl, iface); |
| TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppvObj); |
| /* |
| * Sanity check |
| */ |
| if (ppvObj==NULL) |
| return E_POINTER; |
| |
| *ppvObj = NULL; |
| |
| if (IsEqualIID(riid, &IID_IUnknown)) |
| { |
| /* IUnknown */ |
| *ppvObj = This; |
| } |
| else if(IsEqualIID(riid, &IID_IOleAdviseHolder)) |
| { |
| /* IOleAdviseHolder */ |
| *ppvObj = (IOleAdviseHolder*) This; |
| } |
| |
| if(*ppvObj == NULL) |
| return E_NOINTERFACE; |
| |
| /* |
| * A successful QI always increments the reference count. |
| */ |
| IUnknown_AddRef((IUnknown*)*ppvObj); |
| |
| return S_OK; |
| } |
| |
| /****************************************************************************** |
| * OleAdviseHolderImpl_AddRef |
| */ |
| static ULONG WINAPI OleAdviseHolderImpl_AddRef( |
| LPOLEADVISEHOLDER iface) |
| { |
| ICOM_THIS(OleAdviseHolderImpl, iface); |
| TRACE("(%p)->(ref=%ld)\n", This, This->ref); |
| return ++(This->ref); |
| } |
| |
| /****************************************************************************** |
| * OleAdviseHolderImpl_Release |
| */ |
| static ULONG WINAPI OleAdviseHolderImpl_Release( |
| LPOLEADVISEHOLDER iface) |
| { |
| ICOM_THIS(OleAdviseHolderImpl, iface); |
| TRACE("(%p)->(ref=%ld)\n", This, This->ref); |
| This->ref--; |
| |
| if (This->ref == 0) |
| { |
| OleAdviseHolderImpl_Destructor(This); |
| |
| return 0; |
| } |
| |
| return This->ref; |
| } |
| |
| /****************************************************************************** |
| * OleAdviseHolderImpl_Advise |
| */ |
| static HRESULT WINAPI OleAdviseHolderImpl_Advise( |
| LPOLEADVISEHOLDER iface, |
| IAdviseSink* pAdvise, |
| DWORD* pdwConnection) |
| { |
| DWORD index; |
| |
| ICOM_THIS(OleAdviseHolderImpl, iface); |
| |
| TRACE("(%p)->(%p, %p)\n", This, pAdvise, pdwConnection); |
| |
| /* |
| * Sanity check |
| */ |
| if (pdwConnection==NULL) |
| return E_POINTER; |
| |
| *pdwConnection = 0; |
| |
| /* |
| * Find a free spot in the array. |
| */ |
| for (index = 0; index < This->maxSinks; index++) |
| { |
| if (This->arrayOfSinks[index]==NULL) |
| break; |
| } |
| |
| /* |
| * If the array is full, we need to grow it. |
| */ |
| if (index == This->maxSinks) |
| { |
| DWORD i; |
| |
| This->maxSinks+=INITIAL_SINKS; |
| |
| This->arrayOfSinks = HeapReAlloc(GetProcessHeap(), |
| 0, |
| This->arrayOfSinks, |
| This->maxSinks*sizeof(IAdviseSink*)); |
| |
| for (i=index;i < This->maxSinks; i++) |
| This->arrayOfSinks[i]=0; |
| } |
| |
| /* |
| * Store the new sink |
| */ |
| This->arrayOfSinks[index] = pAdvise; |
| |
| if (This->arrayOfSinks[index]!=NULL) |
| IAdviseSink_AddRef(This->arrayOfSinks[index]); |
| |
| /* |
| * Return the index as the cookie. |
| * Since 0 is not a valid cookie, we will increment by |
| * 1 the index in the table. |
| */ |
| *pdwConnection = index+1; |
| |
| return S_OK; |
| } |
| |
| /****************************************************************************** |
| * OleAdviseHolderImpl_Unadvise |
| */ |
| static HRESULT WINAPI OleAdviseHolderImpl_Unadvise( |
| LPOLEADVISEHOLDER iface, |
| DWORD dwConnection) |
| { |
| ICOM_THIS(OleAdviseHolderImpl, iface); |
| |
| TRACE("(%p)->(%lu)\n", This, dwConnection); |
| |
| /* |
| * So we don't return 0 as a cookie, the index was |
| * incremented by 1 in OleAdviseHolderImpl_Advise |
| * we have to compensate. |
| */ |
| dwConnection--; |
| |
| /* |
| * Check for invalid cookies. |
| */ |
| if ( (dwConnection < 0) || |
| (dwConnection >= This->maxSinks) ) |
| return OLE_E_NOCONNECTION; |
| |
| if (This->arrayOfSinks[dwConnection] == NULL) |
| return OLE_E_NOCONNECTION; |
| |
| /* |
| * Release the sink and mark the spot in the list as free. |
| */ |
| IAdviseSink_Release(This->arrayOfSinks[dwConnection]); |
| This->arrayOfSinks[dwConnection] = NULL; |
| |
| return S_OK; |
| } |
| |
| /****************************************************************************** |
| * OleAdviseHolderImpl_EnumAdvise |
| */ |
| static HRESULT WINAPI |
| OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER iface, IEnumSTATDATA **ppenumAdvise) |
| { |
| ICOM_THIS(OleAdviseHolderImpl, iface); |
| FIXME("(%p)->(%p)\n", This, ppenumAdvise); |
| |
| *ppenumAdvise = NULL; |
| |
| return S_OK; |
| } |
| |
| /****************************************************************************** |
| * OleAdviseHolderImpl_SendOnRename |
| */ |
| static HRESULT WINAPI |
| OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER iface, IMoniker *pmk) |
| { |
| ICOM_THIS(OleAdviseHolderImpl, iface); |
| FIXME("(%p)->(%p)\n", This, pmk); |
| |
| |
| return S_OK; |
| } |
| |
| /****************************************************************************** |
| * OleAdviseHolderImpl_SendOnSave |
| */ |
| static HRESULT WINAPI |
| OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER iface) |
| { |
| ICOM_THIS(OleAdviseHolderImpl, iface); |
| FIXME("(%p)\n", This); |
| |
| return S_OK; |
| } |
| |
| /****************************************************************************** |
| * OleAdviseHolderImpl_SendOnClose |
| */ |
| static HRESULT WINAPI |
| OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER iface) |
| { |
| ICOM_THIS(OleAdviseHolderImpl, iface); |
| FIXME("(%p)\n", This); |
| |
| |
| return S_OK; |
| } |
| |
| /************************************************************************** |
| * DataAdviseHolder Implementation |
| */ |
| typedef struct DataAdviseConnection { |
| IAdviseSink *sink; |
| FORMATETC fmat; |
| DWORD advf; |
| } DataAdviseConnection; |
| |
| typedef struct DataAdviseHolder |
| { |
| ICOM_VFIELD(IDataAdviseHolder); |
| |
| DWORD ref; |
| DWORD maxCons; |
| DataAdviseConnection* Connections; |
| } DataAdviseHolder; |
| |
| /************************************************************************** |
| * DataAdviseHolder method prototypes |
| */ |
| static IDataAdviseHolder* DataAdviseHolder_Constructor(); |
| static void DataAdviseHolder_Destructor(DataAdviseHolder* ptrToDestroy); |
| static HRESULT WINAPI DataAdviseHolder_QueryInterface( |
| IDataAdviseHolder* iface, |
| REFIID riid, |
| void** ppvObject); |
| static ULONG WINAPI DataAdviseHolder_AddRef( |
| IDataAdviseHolder* iface); |
| static ULONG WINAPI DataAdviseHolder_Release( |
| IDataAdviseHolder* iface); |
| static HRESULT WINAPI DataAdviseHolder_Advise( |
| IDataAdviseHolder* iface, |
| IDataObject* pDataObject, |
| FORMATETC* pFetc, |
| DWORD advf, |
| IAdviseSink* pAdvise, |
| DWORD* pdwConnection); |
| static HRESULT WINAPI DataAdviseHolder_Unadvise( |
| IDataAdviseHolder* iface, |
| DWORD dwConnection); |
| static HRESULT WINAPI DataAdviseHolder_EnumAdvise( |
| IDataAdviseHolder* iface, |
| IEnumSTATDATA** ppenumAdvise); |
| static HRESULT WINAPI DataAdviseHolder_SendOnDataChange( |
| IDataAdviseHolder* iface, |
| IDataObject* pDataObject, |
| DWORD dwReserved, |
| DWORD advf); |
| |
| /************************************************************************** |
| * DataAdviseHolderImpl_VTable |
| */ |
| static struct ICOM_VTABLE(IDataAdviseHolder) DataAdviseHolderImpl_VTable = |
| { |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE |
| DataAdviseHolder_QueryInterface, |
| DataAdviseHolder_AddRef, |
| DataAdviseHolder_Release, |
| DataAdviseHolder_Advise, |
| DataAdviseHolder_Unadvise, |
| DataAdviseHolder_EnumAdvise, |
| DataAdviseHolder_SendOnDataChange |
| }; |
| |
| /****************************************************************************** |
| * DataAdviseHolder_Constructor |
| */ |
| static IDataAdviseHolder* DataAdviseHolder_Constructor() |
| { |
| DataAdviseHolder* newHolder; |
| |
| newHolder = (DataAdviseHolder*)HeapAlloc(GetProcessHeap(), |
| 0, |
| sizeof(DataAdviseHolder)); |
| |
| ICOM_VTBL(newHolder) = &DataAdviseHolderImpl_VTable; |
| newHolder->ref = 1; |
| newHolder->maxCons = INITIAL_SINKS; |
| newHolder->Connections = HeapAlloc(GetProcessHeap(), |
| HEAP_ZERO_MEMORY, |
| newHolder->maxCons * |
| sizeof(DataAdviseConnection)); |
| |
| TRACE("returning %p\n", newHolder); |
| return (IDataAdviseHolder*)newHolder; |
| } |
| |
| /****************************************************************************** |
| * DataAdviseHolder_Destructor |
| */ |
| static void DataAdviseHolder_Destructor(DataAdviseHolder* ptrToDestroy) |
| { |
| DWORD index; |
| TRACE("%p\n", ptrToDestroy); |
| |
| for (index = 0; index < ptrToDestroy->maxCons; index++) |
| { |
| if (ptrToDestroy->Connections[index].sink != NULL) |
| { |
| IAdviseSink_Release(ptrToDestroy->Connections[index].sink); |
| ptrToDestroy->Connections[index].sink = NULL; |
| } |
| } |
| |
| HeapFree(GetProcessHeap(), 0, ptrToDestroy->Connections); |
| HeapFree(GetProcessHeap(), 0, ptrToDestroy); |
| } |
| |
| /************************************************************************ |
| * DataAdviseHolder_QueryInterface (IUnknown) |
| * |
| * See Windows documentation for more details on IUnknown methods. |
| */ |
| static HRESULT WINAPI DataAdviseHolder_QueryInterface( |
| IDataAdviseHolder* iface, |
| REFIID riid, |
| void** ppvObject) |
| { |
| ICOM_THIS(DataAdviseHolder, iface); |
| TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppvObject); |
| /* |
| * Perform a sanity check on the parameters. |
| */ |
| if ( (This==0) || (ppvObject==0) ) |
| return E_INVALIDARG; |
| |
| /* |
| * Initialize the return parameter. |
| */ |
| *ppvObject = 0; |
| |
| /* |
| * Compare the riid with the interface IDs implemented by this object. |
| */ |
| if ( (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) || |
| (memcmp(&IID_IDataAdviseHolder, riid, sizeof(IID_IDataAdviseHolder)) == 0) ) |
| { |
| *ppvObject = iface; |
| } |
| |
| /* |
| * Check that we obtained an interface. |
| */ |
| if ((*ppvObject)==0) |
| { |
| return E_NOINTERFACE; |
| } |
| |
| /* |
| * Query Interface always increases the reference count by one when it is |
| * successful. |
| */ |
| IUnknown_AddRef((IUnknown*)*ppvObject); |
| |
| return S_OK; |
| } |
| |
| /************************************************************************ |
| * DataAdviseHolder_AddRef (IUnknown) |
| * |
| * See Windows documentation for more details on IUnknown methods. |
| */ |
| static ULONG WINAPI DataAdviseHolder_AddRef( |
| IDataAdviseHolder* iface) |
| { |
| ICOM_THIS(DataAdviseHolder, iface); |
| TRACE("(%p) (ref=%ld)\n", This, This->ref); |
| This->ref++; |
| |
| return This->ref; |
| } |
| |
| /************************************************************************ |
| * DataAdviseHolder_Release (IUnknown) |
| * |
| * See Windows documentation for more details on IUnknown methods. |
| */ |
| static ULONG WINAPI DataAdviseHolder_Release( |
| IDataAdviseHolder* iface) |
| { |
| ICOM_THIS(DataAdviseHolder, iface); |
| TRACE("(%p) (ref=%ld)\n", This, This->ref); |
| |
| /* |
| * Decrease the reference count on this object. |
| */ |
| This->ref--; |
| |
| /* |
| * If the reference count goes down to 0, perform suicide. |
| */ |
| if (This->ref==0) |
| { |
| DataAdviseHolder_Destructor(This); |
| |
| return 0; |
| } |
| |
| return This->ref; |
| } |
| |
| /************************************************************************ |
| * DataAdviseHolder_Advise |
| * |
| */ |
| static HRESULT WINAPI DataAdviseHolder_Advise( |
| IDataAdviseHolder* iface, |
| IDataObject* pDataObject, |
| FORMATETC* pFetc, |
| DWORD advf, |
| IAdviseSink* pAdvise, |
| DWORD* pdwConnection) |
| { |
| DWORD index; |
| |
| ICOM_THIS(DataAdviseHolder, iface); |
| |
| TRACE("(%p)->(%p, %p, %08lx, %p, %p)\n", This, pDataObject, pFetc, advf, |
| pAdvise, pdwConnection); |
| /* |
| * Sanity check |
| */ |
| if (pdwConnection==NULL) |
| return E_POINTER; |
| |
| *pdwConnection = 0; |
| |
| /* |
| * Find a free spot in the array. |
| */ |
| for (index = 0; index < This->maxCons; index++) |
| { |
| if (This->Connections[index].sink == NULL) |
| break; |
| } |
| |
| /* |
| * If the array is full, we need to grow it. |
| */ |
| if (index == This->maxCons) |
| { |
| This->maxCons+=INITIAL_SINKS; |
| This->Connections = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, |
| This->Connections, |
| This->maxCons*sizeof(DataAdviseConnection)); |
| } |
| /* |
| * Store the new sink |
| */ |
| This->Connections[index].sink = pAdvise; |
| memcpy(&(This->Connections[index].fmat), pFetc, sizeof(FORMATETC)); |
| This->Connections[index].advf = advf; |
| |
| if (This->Connections[index].sink != NULL) { |
| IAdviseSink_AddRef(This->Connections[index].sink); |
| if(advf & ADVF_PRIMEFIRST) { |
| DataAdviseHolder_SendOnDataChange(iface, pDataObject, 0, advf); |
| } |
| } |
| /* |
| * Return the index as the cookie. |
| * Since 0 is not a valid cookie, we will increment by |
| * 1 the index in the table. |
| */ |
| *pdwConnection = index+1; |
| |
| return S_OK; |
| } |
| |
| /****************************************************************************** |
| * DataAdviseHolder_Unadvise |
| */ |
| static HRESULT WINAPI DataAdviseHolder_Unadvise( |
| IDataAdviseHolder* iface, |
| DWORD dwConnection) |
| { |
| ICOM_THIS(DataAdviseHolder, iface); |
| |
| TRACE("(%p)->(%lu)\n", This, dwConnection); |
| |
| /* |
| * So we don't return 0 as a cookie, the index was |
| * incremented by 1 in OleAdviseHolderImpl_Advise |
| * we have to compensate. |
| */ |
| dwConnection--; |
| |
| /* |
| * Check for invalid cookies. |
| */ |
| if ( (dwConnection < 0) || |
| (dwConnection >= This->maxCons) ) |
| return OLE_E_NOCONNECTION; |
| |
| if (This->Connections[dwConnection].sink == NULL) |
| return OLE_E_NOCONNECTION; |
| |
| /* |
| * Release the sink and mark the spot in the list as free. |
| */ |
| IAdviseSink_Release(This->Connections[dwConnection].sink); |
| memset(&(This->Connections[dwConnection]), 0, sizeof(DataAdviseConnection)); |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI DataAdviseHolder_EnumAdvise( |
| IDataAdviseHolder* iface, |
| IEnumSTATDATA** ppenumAdvise) |
| { |
| ICOM_THIS(DataAdviseHolder, iface); |
| |
| FIXME("(%p)->(%p)\n", This, ppenumAdvise); |
| return E_NOTIMPL; |
| } |
| |
| /****************************************************************************** |
| * DataAdviseHolder_SendOnDataChange |
| */ |
| static HRESULT WINAPI DataAdviseHolder_SendOnDataChange( |
| IDataAdviseHolder* iface, |
| IDataObject* pDataObject, |
| DWORD dwReserved, |
| DWORD advf) |
| { |
| ICOM_THIS(DataAdviseHolder, iface); |
| DWORD index; |
| STGMEDIUM stg; |
| HRESULT res; |
| |
| TRACE("(%p)->(%p,%08lx,%08lx)\n", This, pDataObject, dwReserved, advf); |
| |
| for(index = 0; index < This->maxCons; index++) { |
| if(This->Connections[index].sink != NULL) { |
| if(!(This->Connections[index].advf & ADVF_NODATA)) { |
| TRACE("Calling IDataObject_GetData\n"); |
| res = IDataObject_GetData(pDataObject, |
| &(This->Connections[index].fmat), |
| &stg); |
| TRACE("returns %08lx\n", res); |
| } |
| TRACE("Calling IAdviseSink_OnDataChange\n"); |
| IAdviseSink_OnDataChange(This->Connections[index].sink, |
| &(This->Connections[index].fmat), |
| &stg); |
| TRACE("Done IAdviseSink_OnDataChange\n"); |
| if(This->Connections[index].advf & ADVF_ONLYONCE) { |
| TRACE("Removing connection\n"); |
| DataAdviseHolder_Unadvise(iface, index+1); |
| } |
| } |
| } |
| return S_OK; |
| } |
| |
| /*********************************************************************** |
| * API functions |
| */ |
| |
| /*********************************************************************** |
| * CreateOleAdviseHolder [OLE32.59] |
| */ |
| HRESULT WINAPI CreateOleAdviseHolder( |
| LPOLEADVISEHOLDER *ppOAHolder) |
| { |
| TRACE("(%p)\n", ppOAHolder); |
| |
| /* |
| * Sanity check, |
| */ |
| if (ppOAHolder==NULL) |
| return E_POINTER; |
| |
| *ppOAHolder = OleAdviseHolderImpl_Constructor (); |
| |
| if (*ppOAHolder != NULL) |
| return S_OK; |
| |
| return E_OUTOFMEMORY; |
| } |
| |
| /****************************************************************************** |
| * CreateDataAdviseHolder [OLE32.53] |
| */ |
| HRESULT WINAPI CreateDataAdviseHolder( |
| LPDATAADVISEHOLDER* ppDAHolder) |
| { |
| TRACE("(%p)\n", ppDAHolder); |
| |
| /* |
| * Sanity check, |
| */ |
| if (ppDAHolder==NULL) |
| return E_POINTER; |
| |
| *ppDAHolder = DataAdviseHolder_Constructor(); |
| |
| if (*ppDAHolder != NULL) |
| return S_OK; |
| |
| return E_OUTOFMEMORY; |
| } |
| |