2005-07-31 12:11:56 +00:00
|
|
|
/*
|
|
|
|
* 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
|
2007-04-20 12:23:52 +00:00
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
2005-07-31 12:11:56 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#define COBJMACROS
|
|
|
|
|
|
|
|
#include "windef.h"
|
|
|
|
#include "winbase.h"
|
|
|
|
#include "winuser.h"
|
|
|
|
#include "winerror.h"
|
|
|
|
#include "wine/debug.h"
|
|
|
|
#include "ole2.h"
|
|
|
|
|
2008-07-10 09:14:19 +00:00
|
|
|
#include "compobj_private.h"
|
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
|
|
|
|
|
|
|
#define INITIAL_SINKS 10
|
|
|
|
|
|
|
|
/**************************************************************************
|
|
|
|
* OleAdviseHolderImpl Implementation
|
|
|
|
*/
|
|
|
|
typedef struct OleAdviseHolderImpl
|
|
|
|
{
|
2005-08-03 22:31:39 +00:00
|
|
|
const IOleAdviseHolderVtbl *lpVtbl;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2005-08-12 17:19:46 +00:00
|
|
|
LONG ref;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
DWORD maxSinks;
|
|
|
|
IAdviseSink** arrayOfSinks;
|
|
|
|
|
|
|
|
} OleAdviseHolderImpl;
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
static HRESULT EnumOleSTATDATA_Construct(OleAdviseHolderImpl *pOleAdviseHolder, ULONG index, IEnumSTATDATA **ppenum);
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
const IEnumSTATDATAVtbl *lpvtbl;
|
|
|
|
LONG ref;
|
|
|
|
|
|
|
|
ULONG index;
|
|
|
|
OleAdviseHolderImpl *pOleAdviseHolder;
|
|
|
|
} EnumOleSTATDATA;
|
|
|
|
|
|
|
|
static HRESULT WINAPI EnumOleSTATDATA_QueryInterface(
|
|
|
|
IEnumSTATDATA *iface, REFIID riid, void **ppv)
|
|
|
|
{
|
|
|
|
TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
|
|
|
|
if (IsEqualIID(riid, &IID_IUnknown) ||
|
|
|
|
IsEqualIID(riid, &IID_IEnumSTATDATA))
|
|
|
|
{
|
|
|
|
IUnknown_AddRef(iface);
|
|
|
|
*ppv = iface;
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
return E_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI EnumOleSTATDATA_AddRef(
|
|
|
|
IEnumSTATDATA *iface)
|
|
|
|
{
|
|
|
|
EnumOleSTATDATA *This = (EnumOleSTATDATA *)iface;
|
|
|
|
TRACE("()\n");
|
|
|
|
return InterlockedIncrement(&This->ref);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI EnumOleSTATDATA_Release(
|
|
|
|
IEnumSTATDATA *iface)
|
|
|
|
{
|
|
|
|
EnumOleSTATDATA *This = (EnumOleSTATDATA *)iface;
|
|
|
|
LONG refs = InterlockedDecrement(&This->ref);
|
|
|
|
TRACE("()\n");
|
|
|
|
if (!refs)
|
|
|
|
{
|
|
|
|
IOleAdviseHolder_Release((IOleAdviseHolder *)This->pOleAdviseHolder);
|
|
|
|
HeapFree(GetProcessHeap(), 0, This);
|
|
|
|
}
|
|
|
|
return refs;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI EnumOleSTATDATA_Next(
|
|
|
|
IEnumSTATDATA *iface, ULONG celt, LPSTATDATA rgelt,
|
|
|
|
ULONG *pceltFetched)
|
|
|
|
{
|
|
|
|
EnumOleSTATDATA *This = (EnumOleSTATDATA *)iface;
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
|
|
|
|
TRACE("(%d, %p, %p)\n", celt, rgelt, pceltFetched);
|
|
|
|
|
|
|
|
if (pceltFetched)
|
|
|
|
*pceltFetched = 0;
|
|
|
|
|
|
|
|
for (; celt; celt--, rgelt++)
|
|
|
|
{
|
2008-01-14 15:45:45 +00:00
|
|
|
while ((This->index < This->pOleAdviseHolder->maxSinks) &&
|
2007-04-20 12:23:52 +00:00
|
|
|
!This->pOleAdviseHolder->arrayOfSinks[This->index])
|
|
|
|
{
|
|
|
|
This->index++;
|
|
|
|
}
|
|
|
|
if (This->index >= This->pOleAdviseHolder->maxSinks)
|
|
|
|
{
|
|
|
|
hr = S_FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(&rgelt->formatetc, 0, sizeof(rgelt->formatetc));
|
|
|
|
rgelt->advf = 0;
|
|
|
|
rgelt->pAdvSink = This->pOleAdviseHolder->arrayOfSinks[This->index];
|
|
|
|
IAdviseSink_AddRef(rgelt->pAdvSink);
|
|
|
|
rgelt->dwConnection = This->index;
|
|
|
|
|
|
|
|
if (pceltFetched)
|
|
|
|
(*pceltFetched)++;
|
|
|
|
This->index++;
|
|
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI EnumOleSTATDATA_Skip(
|
|
|
|
IEnumSTATDATA *iface, ULONG celt)
|
|
|
|
{
|
|
|
|
EnumOleSTATDATA *This = (EnumOleSTATDATA *)iface;
|
|
|
|
|
|
|
|
TRACE("(%d)\n", celt);
|
|
|
|
|
|
|
|
for (; celt; celt--)
|
|
|
|
{
|
2008-01-14 15:45:45 +00:00
|
|
|
while ((This->index < This->pOleAdviseHolder->maxSinks) &&
|
2007-04-20 12:23:52 +00:00
|
|
|
!This->pOleAdviseHolder->arrayOfSinks[This->index])
|
|
|
|
{
|
|
|
|
This->index++;
|
|
|
|
}
|
|
|
|
if (This->index >= This->pOleAdviseHolder->maxSinks)
|
|
|
|
return S_FALSE;
|
|
|
|
This->index++;
|
|
|
|
}
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI EnumOleSTATDATA_Reset(
|
|
|
|
IEnumSTATDATA *iface)
|
|
|
|
{
|
|
|
|
EnumOleSTATDATA *This = (EnumOleSTATDATA *)iface;
|
|
|
|
|
|
|
|
TRACE("()\n");
|
|
|
|
|
|
|
|
This->index = 0;
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI EnumOleSTATDATA_Clone(
|
|
|
|
IEnumSTATDATA *iface,
|
|
|
|
IEnumSTATDATA **ppenum)
|
|
|
|
{
|
|
|
|
EnumOleSTATDATA *This = (EnumOleSTATDATA *)iface;
|
|
|
|
return EnumOleSTATDATA_Construct(This->pOleAdviseHolder, This->index, ppenum);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const IEnumSTATDATAVtbl EnumOleSTATDATA_VTable =
|
|
|
|
{
|
|
|
|
EnumOleSTATDATA_QueryInterface,
|
|
|
|
EnumOleSTATDATA_AddRef,
|
|
|
|
EnumOleSTATDATA_Release,
|
|
|
|
EnumOleSTATDATA_Next,
|
|
|
|
EnumOleSTATDATA_Skip,
|
|
|
|
EnumOleSTATDATA_Reset,
|
|
|
|
EnumOleSTATDATA_Clone
|
|
|
|
};
|
|
|
|
|
|
|
|
static HRESULT EnumOleSTATDATA_Construct(OleAdviseHolderImpl *pOleAdviseHolder, ULONG index, IEnumSTATDATA **ppenum)
|
|
|
|
{
|
|
|
|
EnumOleSTATDATA *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
|
|
|
|
if (!This)
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
This->lpvtbl = &EnumOleSTATDATA_VTable;
|
|
|
|
This->ref = 1;
|
|
|
|
This->index = index;
|
|
|
|
This->pOleAdviseHolder = pOleAdviseHolder;
|
|
|
|
IOleAdviseHolder_AddRef((IOleAdviseHolder *)pOleAdviseHolder);
|
|
|
|
*ppenum = (IEnumSTATDATA *)&This->lpvtbl;
|
2008-01-14 15:45:45 +00:00
|
|
|
return S_OK;
|
2007-04-20 12:23:52 +00:00
|
|
|
}
|
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
/**************************************************************************
|
|
|
|
* 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)
|
|
|
|
{
|
|
|
|
OleAdviseHolderImpl *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 */
|
2009-03-03 09:12:43 +00:00
|
|
|
*ppvObj = This;
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
|
|
|
|
ULONG ref = InterlockedIncrement(&This->ref);
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p)->(ref=%d)\n", This, ref - 1);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
return ref;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* OleAdviseHolderImpl_Release
|
|
|
|
*/
|
|
|
|
static ULONG WINAPI OleAdviseHolderImpl_Release(
|
|
|
|
LPOLEADVISEHOLDER iface)
|
|
|
|
{
|
|
|
|
OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
|
|
|
|
ULONG ref;
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p)->(ref=%d)\n", This, This->ref);
|
2005-07-31 12:11:56 +00:00
|
|
|
ref = InterlockedDecrement(&This->ref);
|
|
|
|
|
|
|
|
if (ref == 0) OleAdviseHolderImpl_Destructor(This);
|
|
|
|
|
|
|
|
return ref;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* OleAdviseHolderImpl_Advise
|
|
|
|
*/
|
|
|
|
static HRESULT WINAPI OleAdviseHolderImpl_Advise(
|
|
|
|
LPOLEADVISEHOLDER iface,
|
|
|
|
IAdviseSink* pAdvise,
|
|
|
|
DWORD* pdwConnection)
|
|
|
|
{
|
|
|
|
DWORD index;
|
|
|
|
|
|
|
|
OleAdviseHolderImpl *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)
|
|
|
|
{
|
|
|
|
OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p)->(%u)\n", This, dwConnection);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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 >= 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)
|
|
|
|
{
|
|
|
|
OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
|
2007-04-20 12:23:52 +00:00
|
|
|
|
|
|
|
TRACE("(%p)->(%p)\n", This, ppenumAdvise);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
*ppenumAdvise = NULL;
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
return EnumOleSTATDATA_Construct(This, 0, ppenumAdvise);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* OleAdviseHolderImpl_SendOnRename
|
|
|
|
*/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER iface, IMoniker *pmk)
|
|
|
|
{
|
2007-04-20 12:23:52 +00:00
|
|
|
IEnumSTATDATA *pEnum;
|
|
|
|
HRESULT hr;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p)->(%p)\n", iface, pmk);
|
2007-04-20 02:30:53 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
hr = IOleAdviseHolder_EnumAdvise(iface, &pEnum);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
STATDATA statdata;
|
|
|
|
while (IEnumSTATDATA_Next(pEnum, 1, &statdata, NULL) == S_OK)
|
|
|
|
{
|
|
|
|
IAdviseSink_OnRename(statdata.pAdvSink, pmk);
|
|
|
|
|
|
|
|
IAdviseSink_Release(statdata.pAdvSink);
|
|
|
|
}
|
|
|
|
IEnumSTATDATA_Release(pEnum);
|
|
|
|
}
|
|
|
|
|
|
|
|
return hr;
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* OleAdviseHolderImpl_SendOnSave
|
|
|
|
*/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER iface)
|
|
|
|
{
|
2007-04-20 12:23:52 +00:00
|
|
|
IEnumSTATDATA *pEnum;
|
|
|
|
HRESULT hr;
|
2007-04-20 02:30:53 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p)->()\n", iface);
|
|
|
|
|
|
|
|
hr = IOleAdviseHolder_EnumAdvise(iface, &pEnum);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
STATDATA statdata;
|
|
|
|
while (IEnumSTATDATA_Next(pEnum, 1, &statdata, NULL) == S_OK)
|
|
|
|
{
|
|
|
|
IAdviseSink_OnSave(statdata.pAdvSink);
|
|
|
|
|
|
|
|
IAdviseSink_Release(statdata.pAdvSink);
|
|
|
|
}
|
|
|
|
IEnumSTATDATA_Release(pEnum);
|
|
|
|
}
|
|
|
|
|
|
|
|
return hr;
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* OleAdviseHolderImpl_SendOnClose
|
|
|
|
*/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER iface)
|
|
|
|
{
|
2007-04-20 12:23:52 +00:00
|
|
|
IEnumSTATDATA *pEnum;
|
|
|
|
HRESULT hr;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p)->()\n", iface);
|
2007-04-20 02:30:53 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
hr = IOleAdviseHolder_EnumAdvise(iface, &pEnum);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
STATDATA statdata;
|
|
|
|
while (IEnumSTATDATA_Next(pEnum, 1, &statdata, NULL) == S_OK)
|
|
|
|
{
|
|
|
|
IAdviseSink_OnClose(statdata.pAdvSink);
|
|
|
|
|
|
|
|
IAdviseSink_Release(statdata.pAdvSink);
|
|
|
|
}
|
|
|
|
IEnumSTATDATA_Release(pEnum);
|
|
|
|
}
|
|
|
|
|
|
|
|
return hr;
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**************************************************************************
|
|
|
|
* OleAdviseHolderImpl_VTable
|
|
|
|
*/
|
2005-08-03 22:31:39 +00:00
|
|
|
static const IOleAdviseHolderVtbl oahvt =
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
|
|
|
OleAdviseHolderImpl_QueryInterface,
|
|
|
|
OleAdviseHolderImpl_AddRef,
|
|
|
|
OleAdviseHolderImpl_Release,
|
|
|
|
OleAdviseHolderImpl_Advise,
|
|
|
|
OleAdviseHolderImpl_Unadvise,
|
|
|
|
OleAdviseHolderImpl_EnumAdvise,
|
|
|
|
OleAdviseHolderImpl_SendOnRename,
|
|
|
|
OleAdviseHolderImpl_SendOnSave,
|
|
|
|
OleAdviseHolderImpl_SendOnClose
|
|
|
|
};
|
|
|
|
|
|
|
|
/**************************************************************************
|
|
|
|
* OleAdviseHolderImpl_Constructor
|
|
|
|
*/
|
|
|
|
|
2005-08-03 22:31:39 +00:00
|
|
|
static LPOLEADVISEHOLDER OleAdviseHolderImpl_Constructor(void)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
|
|
|
OleAdviseHolderImpl* lpoah;
|
|
|
|
DWORD index;
|
|
|
|
|
|
|
|
lpoah = HeapAlloc(GetProcessHeap(), 0, sizeof(OleAdviseHolderImpl));
|
|
|
|
|
|
|
|
lpoah->lpVtbl = &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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**************************************************************************
|
|
|
|
* DataAdviseHolder Implementation
|
|
|
|
*/
|
|
|
|
typedef struct DataAdviseConnection {
|
|
|
|
IAdviseSink *sink;
|
|
|
|
FORMATETC fmat;
|
|
|
|
DWORD advf;
|
2005-12-12 23:53:06 +00:00
|
|
|
DWORD remote_connection;
|
2005-07-31 12:11:56 +00:00
|
|
|
} DataAdviseConnection;
|
|
|
|
|
|
|
|
typedef struct DataAdviseHolder
|
|
|
|
{
|
2005-08-03 22:31:39 +00:00
|
|
|
const IDataAdviseHolderVtbl *lpVtbl;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2005-08-12 17:19:46 +00:00
|
|
|
LONG ref;
|
2005-07-31 12:11:56 +00:00
|
|
|
DWORD maxCons;
|
|
|
|
DataAdviseConnection* Connections;
|
2007-04-20 12:23:52 +00:00
|
|
|
IDataObject* delegate;
|
2005-07-31 12:11:56 +00:00
|
|
|
} DataAdviseHolder;
|
|
|
|
|
2005-12-12 23:53:06 +00:00
|
|
|
/* this connection has also has been advised to the delegate data object */
|
|
|
|
#define WINE_ADVF_REMOTE 0x80000000
|
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
/******************************************************************************
|
|
|
|
* 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)
|
|
|
|
{
|
2008-01-14 15:45:45 +00:00
|
|
|
if (ptrToDestroy->delegate &&
|
2007-04-20 12:23:52 +00:00
|
|
|
(ptrToDestroy->Connections[index].advf & WINE_ADVF_REMOTE))
|
|
|
|
IDataObject_DUnadvise(ptrToDestroy->delegate,
|
|
|
|
ptrToDestroy->Connections[index].remote_connection);
|
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
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)
|
|
|
|
{
|
|
|
|
DataAdviseHolder *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.
|
|
|
|
*/
|
Finish the Wine sync. These components are not just rc file changes
atl, comctl32, comdlg32, dwmapi, fusion, gdiplus, jscript, mpr, mshtml, msi, msimtf, msxml3, ole32, oleaut32, riched20, shdocvw, shlwapi, urlmon, usp10, version and windowscodecs
Seems to build and boot. /me hides
svn path=/trunk/; revision=48273
2010-07-26 02:26:04 +00:00
|
|
|
if ( IsEqualIID(&IID_IUnknown, riid) ||
|
|
|
|
IsEqualIID(&IID_IDataAdviseHolder, riid) )
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
|
|
|
*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)
|
|
|
|
{
|
|
|
|
DataAdviseHolder *This = (DataAdviseHolder *)iface;
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p) (ref=%d)\n", This, This->ref);
|
2005-07-31 12:11:56 +00:00
|
|
|
return InterlockedIncrement(&This->ref);
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* DataAdviseHolder_Release (IUnknown)
|
|
|
|
*
|
|
|
|
* See Windows documentation for more details on IUnknown methods.
|
|
|
|
*/
|
|
|
|
static ULONG WINAPI DataAdviseHolder_Release(
|
|
|
|
IDataAdviseHolder* iface)
|
|
|
|
{
|
|
|
|
DataAdviseHolder *This = (DataAdviseHolder *)iface;
|
|
|
|
ULONG ref;
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p) (ref=%d)\n", This, This->ref);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Decrease the reference count on this object.
|
|
|
|
*/
|
|
|
|
ref = InterlockedDecrement(&This->ref);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If the reference count goes down to 0, perform suicide.
|
|
|
|
*/
|
|
|
|
if (ref==0) DataAdviseHolder_Destructor(This);
|
|
|
|
|
|
|
|
return ref;
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* DataAdviseHolder_Advise
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
static HRESULT WINAPI DataAdviseHolder_Advise(
|
|
|
|
IDataAdviseHolder* iface,
|
|
|
|
IDataObject* pDataObject,
|
|
|
|
FORMATETC* pFetc,
|
|
|
|
DWORD advf,
|
|
|
|
IAdviseSink* pAdvise,
|
|
|
|
DWORD* pdwConnection)
|
|
|
|
{
|
|
|
|
DWORD index;
|
|
|
|
|
|
|
|
DataAdviseHolder *This = (DataAdviseHolder *)iface;
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p)->(%p, %p, %08x, %p, %p)\n", This, pDataObject, pFetc, advf,
|
2005-07-31 12:11:56 +00:00
|
|
|
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;
|
2007-04-20 10:28:01 +00:00
|
|
|
This->Connections[index].advf = advf & ~WINE_ADVF_REMOTE;
|
2008-07-10 09:14:19 +00:00
|
|
|
This->Connections[index].fmat = *pFetc;
|
2007-04-20 12:23:52 +00:00
|
|
|
if (pFetc->ptd)
|
|
|
|
{
|
|
|
|
This->Connections[index].fmat.ptd = CoTaskMemAlloc(pFetc->ptd->tdSize);
|
|
|
|
if (!This->Connections[index].fmat.ptd)
|
|
|
|
{
|
|
|
|
IDataAdviseHolder_Unadvise(iface, index + 1);
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
}
|
|
|
|
memcpy(This->Connections[index].fmat.ptd, pFetc->ptd, pFetc->ptd->tdSize);
|
|
|
|
}
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
if (This->Connections[index].sink != NULL) {
|
|
|
|
IAdviseSink_AddRef(This->Connections[index].sink);
|
2007-04-20 12:23:52 +00:00
|
|
|
|
|
|
|
/* if we are already connected advise the remote object */
|
|
|
|
if (This->delegate)
|
|
|
|
{
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
hr = IDataObject_DAdvise(This->delegate, &This->Connections[index].fmat,
|
|
|
|
This->Connections[index].advf,
|
|
|
|
This->Connections[index].sink,
|
|
|
|
&This->Connections[index].remote_connection);
|
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
IDataAdviseHolder_Unadvise(iface, index + 1);
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
This->Connections[index].advf |= WINE_ADVF_REMOTE;
|
2007-04-20 10:28:01 +00:00
|
|
|
}
|
2007-04-20 12:23:52 +00:00
|
|
|
else if(advf & ADVF_PRIMEFIRST)
|
|
|
|
/* only do this if we have no delegate, since in the above case the
|
|
|
|
* delegate will do the priming for us */
|
|
|
|
IDataAdviseHolder_SendOnDataChange(iface, pDataObject, 0, advf);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
/*
|
|
|
|
* 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)
|
|
|
|
{
|
|
|
|
DataAdviseHolder *This = (DataAdviseHolder *)iface;
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p)->(%u)\n", This, dwConnection);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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 >= This->maxCons)
|
|
|
|
return OLE_E_NOCONNECTION;
|
|
|
|
|
|
|
|
if (This->Connections[dwConnection].sink == NULL)
|
|
|
|
return OLE_E_NOCONNECTION;
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
if (This->delegate && This->Connections[dwConnection].advf & WINE_ADVF_REMOTE)
|
|
|
|
IDataObject_DUnadvise(This->delegate,
|
|
|
|
This->Connections[dwConnection].remote_connection);
|
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
/*
|
|
|
|
* 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));
|
2007-04-20 12:23:52 +00:00
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI DataAdviseHolder_EnumAdvise(
|
|
|
|
IDataAdviseHolder* iface,
|
|
|
|
IEnumSTATDATA** ppenumAdvise)
|
|
|
|
{
|
|
|
|
DataAdviseHolder *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)
|
|
|
|
{
|
|
|
|
DataAdviseHolder *This = (DataAdviseHolder *)iface;
|
|
|
|
DWORD index;
|
|
|
|
STGMEDIUM stg;
|
|
|
|
HRESULT res;
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p)->(%p,%08x,%08x)\n", This, pDataObject, dwReserved, advf);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
for(index = 0; index < This->maxCons; index++) {
|
|
|
|
if(This->Connections[index].sink != NULL) {
|
2007-04-20 12:23:52 +00:00
|
|
|
memset(&stg, 0, sizeof(stg));
|
2005-07-31 12:11:56 +00:00
|
|
|
if(!(This->Connections[index].advf & ADVF_NODATA)) {
|
|
|
|
TRACE("Calling IDataObject_GetData\n");
|
|
|
|
res = IDataObject_GetData(pDataObject,
|
|
|
|
&(This->Connections[index].fmat),
|
|
|
|
&stg);
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("returns %08x\n", res);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**************************************************************************
|
|
|
|
* DataAdviseHolderImpl_VTable
|
|
|
|
*/
|
2005-08-03 22:31:39 +00:00
|
|
|
static const IDataAdviseHolderVtbl DataAdviseHolderImpl_VTable =
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
|
|
|
DataAdviseHolder_QueryInterface,
|
|
|
|
DataAdviseHolder_AddRef,
|
|
|
|
DataAdviseHolder_Release,
|
|
|
|
DataAdviseHolder_Advise,
|
|
|
|
DataAdviseHolder_Unadvise,
|
|
|
|
DataAdviseHolder_EnumAdvise,
|
|
|
|
DataAdviseHolder_SendOnDataChange
|
|
|
|
};
|
|
|
|
|
2005-12-12 23:53:06 +00:00
|
|
|
HRESULT DataAdviseHolder_OnConnect(IDataAdviseHolder *iface, IDataObject *pDelegate)
|
|
|
|
{
|
|
|
|
DataAdviseHolder *This = (DataAdviseHolder *)iface;
|
|
|
|
DWORD index;
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
|
|
|
|
for(index = 0; index < This->maxCons; index++)
|
|
|
|
{
|
|
|
|
if(This->Connections[index].sink != NULL)
|
|
|
|
{
|
|
|
|
hr = IDataObject_DAdvise(pDelegate, &This->Connections[index].fmat,
|
|
|
|
This->Connections[index].advf,
|
|
|
|
This->Connections[index].sink,
|
|
|
|
&This->Connections[index].remote_connection);
|
|
|
|
if (FAILED(hr)) break;
|
|
|
|
This->Connections[index].advf |= WINE_ADVF_REMOTE;
|
|
|
|
}
|
|
|
|
}
|
2007-04-20 12:23:52 +00:00
|
|
|
This->delegate = pDelegate;
|
2005-12-12 23:53:06 +00:00
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DataAdviseHolder_OnDisconnect(IDataAdviseHolder *iface)
|
|
|
|
{
|
2007-04-20 12:23:52 +00:00
|
|
|
DataAdviseHolder *This = (DataAdviseHolder *)iface;
|
|
|
|
DWORD index;
|
|
|
|
|
|
|
|
for(index = 0; index < This->maxCons; index++)
|
|
|
|
{
|
|
|
|
if((This->Connections[index].sink != NULL) &&
|
|
|
|
(This->Connections[index].advf & WINE_ADVF_REMOTE))
|
|
|
|
{
|
|
|
|
IDataObject_DUnadvise(This->delegate,
|
|
|
|
This->Connections[index].remote_connection);
|
|
|
|
This->Connections[index].advf &= ~WINE_ADVF_REMOTE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
This->delegate = NULL;
|
2005-12-12 23:53:06 +00:00
|
|
|
}
|
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
/******************************************************************************
|
|
|
|
* DataAdviseHolder_Constructor
|
|
|
|
*/
|
2005-08-03 22:31:39 +00:00
|
|
|
static IDataAdviseHolder* DataAdviseHolder_Constructor(void)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
|
|
|
DataAdviseHolder* newHolder;
|
|
|
|
|
|
|
|
newHolder = HeapAlloc(GetProcessHeap(), 0, sizeof(DataAdviseHolder));
|
|
|
|
|
|
|
|
newHolder->lpVtbl = &DataAdviseHolderImpl_VTable;
|
|
|
|
newHolder->ref = 1;
|
|
|
|
newHolder->maxCons = INITIAL_SINKS;
|
|
|
|
newHolder->Connections = HeapAlloc(GetProcessHeap(),
|
|
|
|
HEAP_ZERO_MEMORY,
|
|
|
|
newHolder->maxCons *
|
|
|
|
sizeof(DataAdviseConnection));
|
2007-04-20 12:23:52 +00:00
|
|
|
newHolder->delegate = NULL;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
TRACE("returning %p\n", newHolder);
|
|
|
|
return (IDataAdviseHolder*)newHolder;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* API functions
|
|
|
|
*/
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* CreateOleAdviseHolder [OLE32.@]
|
|
|
|
*/
|
|
|
|
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.@]
|
|
|
|
*/
|
|
|
|
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;
|
|
|
|
}
|