reactos/dll/win32/ole32/oleobj.c

907 lines
25 KiB
C
Raw Normal View History

/*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <string.h>
#define COBJMACROS
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winerror.h"
#include "wine/debug.h"
#include "ole2.h"
#include "compobj_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
#define INITIAL_SINKS 10
static void release_statdata(STATDATA *data)
{
CoTaskMemFree(data->formatetc.ptd);
data->formatetc.ptd = NULL;
if(data->pAdvSink)
{
IAdviseSink_Release(data->pAdvSink);
data->pAdvSink = NULL;
}
}
static HRESULT copy_statdata(STATDATA *dst, const STATDATA *src)
{
[OLE32] Sync with Wine Staging 2.9. CORE-13362 9cc976a ole32: Fix compilation with recent versions of gcc. 2e36326 ole32: Synthesize dibs or bitmaps as appropriate. e27708f ole32: Create CF_DIB and CF_BITMAP entries when either is cached. 20a8f1a ole32: Implement IOleCache_EnumCache(). f9b0f60 ole32: Check the cache entry's stgmedium for the unloaded state. 8fc1a4c ole32: OleUninitialize() does not release the reference to the clipboard's source dataobject. 1d2860e ole32: Fix up the dib's resolution on loading. e7bb4ba ole32: Don't cache the BITMAPFILEHEADER. fc49d98 ole32: Set the advise flags in CreateEntry(). 77d1eba ole32: Use the helper function to copy the clipboard's FORMATETC. 9ee30d7 ole32: Use the helper function to copy the datacache's FORMATETC. 11db491 ole32: Add a helper to copy FORMATETC structures. b399baf ole32: Add CoRegisterSurrogate/Ex stubs. 87dba2b ole32: Zero STGMEDIUM before calling IDataObject::GetData. c7e6fe6 ole32: Added GlobalOptions object stub implementation. fd09c37 ole32: Use generic class factory for StdComponentCategoriesMgr object. 076c782 ole32: Use generic class factory for pointer moniker. 961c3dc ole32: Use generic class factory for class moniker. 947c9ba ole32: Use generic class factory for composite moniker. b05fd46 ole32: Use generic class factory for anti moniker. dee6463 ole32: Use generic class factory for item moniker. cf7883f ole32: Added generic class factory implementation and use it for file moniker. svn path=/trunk/; revision=74829
2017-06-03 22:33:33 +00:00
HRESULT hr;
hr = copy_formatetc( &dst->formatetc, &src->formatetc );
if (FAILED(hr)) return hr;
dst->advf = src->advf;
dst->pAdvSink = src->pAdvSink;
if (dst->pAdvSink) IAdviseSink_AddRef( dst->pAdvSink );
dst->dwConnection = src->dwConnection;
return S_OK;
}
/**************************************************************************
* EnumSTATDATA Implementation
*/
typedef struct
{
IEnumSTATDATA IEnumSTATDATA_iface;
LONG ref;
ULONG index;
DWORD num_of_elems;
STATDATA *statdata;
IUnknown *holder;
} EnumSTATDATA;
static inline EnumSTATDATA *impl_from_IEnumSTATDATA(IEnumSTATDATA *iface)
{
return CONTAINING_RECORD(iface, EnumSTATDATA, IEnumSTATDATA_iface);
}
static HRESULT WINAPI EnumSTATDATA_QueryInterface(IEnumSTATDATA *iface, REFIID riid, void **ppv)
{
TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
if (IsEqualIID(riid, &IID_IUnknown) ||
IsEqualIID(riid, &IID_IEnumSTATDATA))
{
IEnumSTATDATA_AddRef(iface);
*ppv = iface;
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG WINAPI EnumSTATDATA_AddRef(IEnumSTATDATA *iface)
{
EnumSTATDATA *This = impl_from_IEnumSTATDATA(iface);
TRACE("()\n");
return InterlockedIncrement(&This->ref);
}
static ULONG WINAPI EnumSTATDATA_Release(IEnumSTATDATA *iface)
{
EnumSTATDATA *This = impl_from_IEnumSTATDATA(iface);
LONG refs = InterlockedDecrement(&This->ref);
TRACE("()\n");
if (!refs)
{
DWORD i;
for(i = 0; i < This->num_of_elems; i++)
release_statdata(This->statdata + i);
HeapFree(GetProcessHeap(), 0, This->statdata);
[OLE32] Sync with Wine Staging 2.9. CORE-13362 9cc976a ole32: Fix compilation with recent versions of gcc. 2e36326 ole32: Synthesize dibs or bitmaps as appropriate. e27708f ole32: Create CF_DIB and CF_BITMAP entries when either is cached. 20a8f1a ole32: Implement IOleCache_EnumCache(). f9b0f60 ole32: Check the cache entry's stgmedium for the unloaded state. 8fc1a4c ole32: OleUninitialize() does not release the reference to the clipboard's source dataobject. 1d2860e ole32: Fix up the dib's resolution on loading. e7bb4ba ole32: Don't cache the BITMAPFILEHEADER. fc49d98 ole32: Set the advise flags in CreateEntry(). 77d1eba ole32: Use the helper function to copy the clipboard's FORMATETC. 9ee30d7 ole32: Use the helper function to copy the datacache's FORMATETC. 11db491 ole32: Add a helper to copy FORMATETC structures. b399baf ole32: Add CoRegisterSurrogate/Ex stubs. 87dba2b ole32: Zero STGMEDIUM before calling IDataObject::GetData. c7e6fe6 ole32: Added GlobalOptions object stub implementation. fd09c37 ole32: Use generic class factory for StdComponentCategoriesMgr object. 076c782 ole32: Use generic class factory for pointer moniker. 961c3dc ole32: Use generic class factory for class moniker. 947c9ba ole32: Use generic class factory for composite moniker. b05fd46 ole32: Use generic class factory for anti moniker. dee6463 ole32: Use generic class factory for item moniker. cf7883f ole32: Added generic class factory implementation and use it for file moniker. svn path=/trunk/; revision=74829
2017-06-03 22:33:33 +00:00
if (This->holder) IUnknown_Release(This->holder);
HeapFree(GetProcessHeap(), 0, This);
}
return refs;
}
static HRESULT WINAPI EnumSTATDATA_Next(IEnumSTATDATA *iface, ULONG num, LPSTATDATA data,
ULONG *fetched)
{
EnumSTATDATA *This = impl_from_IEnumSTATDATA(iface);
DWORD count = 0;
HRESULT hr = S_OK;
TRACE("(%d, %p, %p)\n", num, data, fetched);
while(num--)
{
if (This->index >= This->num_of_elems)
{
hr = S_FALSE;
break;
}
copy_statdata(data + count, This->statdata + This->index);
count++;
This->index++;
}
if (fetched) *fetched = count;
return hr;
}
static HRESULT WINAPI EnumSTATDATA_Skip(IEnumSTATDATA *iface, ULONG num)
{
EnumSTATDATA *This = impl_from_IEnumSTATDATA(iface);
TRACE("(%d)\n", num);
if(This->index + num >= This->num_of_elems)
{
This->index = This->num_of_elems;
return S_FALSE;
}
This->index += num;
return S_OK;
}
static HRESULT WINAPI EnumSTATDATA_Reset(IEnumSTATDATA *iface)
{
EnumSTATDATA *This = impl_from_IEnumSTATDATA(iface);
TRACE("()\n");
This->index = 0;
return S_OK;
}
static HRESULT WINAPI EnumSTATDATA_Clone(IEnumSTATDATA *iface, IEnumSTATDATA **ppenum)
{
EnumSTATDATA *This = impl_from_IEnumSTATDATA(iface);
[OLE32] Sync with Wine Staging 2.9. CORE-13362 9cc976a ole32: Fix compilation with recent versions of gcc. 2e36326 ole32: Synthesize dibs or bitmaps as appropriate. e27708f ole32: Create CF_DIB and CF_BITMAP entries when either is cached. 20a8f1a ole32: Implement IOleCache_EnumCache(). f9b0f60 ole32: Check the cache entry's stgmedium for the unloaded state. 8fc1a4c ole32: OleUninitialize() does not release the reference to the clipboard's source dataobject. 1d2860e ole32: Fix up the dib's resolution on loading. e7bb4ba ole32: Don't cache the BITMAPFILEHEADER. fc49d98 ole32: Set the advise flags in CreateEntry(). 77d1eba ole32: Use the helper function to copy the clipboard's FORMATETC. 9ee30d7 ole32: Use the helper function to copy the datacache's FORMATETC. 11db491 ole32: Add a helper to copy FORMATETC structures. b399baf ole32: Add CoRegisterSurrogate/Ex stubs. 87dba2b ole32: Zero STGMEDIUM before calling IDataObject::GetData. c7e6fe6 ole32: Added GlobalOptions object stub implementation. fd09c37 ole32: Use generic class factory for StdComponentCategoriesMgr object. 076c782 ole32: Use generic class factory for pointer moniker. 961c3dc ole32: Use generic class factory for class moniker. 947c9ba ole32: Use generic class factory for composite moniker. b05fd46 ole32: Use generic class factory for anti moniker. dee6463 ole32: Use generic class factory for item moniker. cf7883f ole32: Added generic class factory implementation and use it for file moniker. svn path=/trunk/; revision=74829
2017-06-03 22:33:33 +00:00
return EnumSTATDATA_Construct(This->holder, This->index, This->num_of_elems, This->statdata,
TRUE, ppenum);
}
static const IEnumSTATDATAVtbl EnumSTATDATA_VTable =
{
EnumSTATDATA_QueryInterface,
EnumSTATDATA_AddRef,
EnumSTATDATA_Release,
EnumSTATDATA_Next,
EnumSTATDATA_Skip,
EnumSTATDATA_Reset,
EnumSTATDATA_Clone
};
[OLE32] Sync with Wine Staging 2.9. CORE-13362 9cc976a ole32: Fix compilation with recent versions of gcc. 2e36326 ole32: Synthesize dibs or bitmaps as appropriate. e27708f ole32: Create CF_DIB and CF_BITMAP entries when either is cached. 20a8f1a ole32: Implement IOleCache_EnumCache(). f9b0f60 ole32: Check the cache entry's stgmedium for the unloaded state. 8fc1a4c ole32: OleUninitialize() does not release the reference to the clipboard's source dataobject. 1d2860e ole32: Fix up the dib's resolution on loading. e7bb4ba ole32: Don't cache the BITMAPFILEHEADER. fc49d98 ole32: Set the advise flags in CreateEntry(). 77d1eba ole32: Use the helper function to copy the clipboard's FORMATETC. 9ee30d7 ole32: Use the helper function to copy the datacache's FORMATETC. 11db491 ole32: Add a helper to copy FORMATETC structures. b399baf ole32: Add CoRegisterSurrogate/Ex stubs. 87dba2b ole32: Zero STGMEDIUM before calling IDataObject::GetData. c7e6fe6 ole32: Added GlobalOptions object stub implementation. fd09c37 ole32: Use generic class factory for StdComponentCategoriesMgr object. 076c782 ole32: Use generic class factory for pointer moniker. 961c3dc ole32: Use generic class factory for class moniker. 947c9ba ole32: Use generic class factory for composite moniker. b05fd46 ole32: Use generic class factory for anti moniker. dee6463 ole32: Use generic class factory for item moniker. cf7883f ole32: Added generic class factory implementation and use it for file moniker. svn path=/trunk/; revision=74829
2017-06-03 22:33:33 +00:00
HRESULT EnumSTATDATA_Construct(IUnknown *holder, ULONG index, DWORD array_len, STATDATA *data,
BOOL copy, IEnumSTATDATA **ppenum)
{
EnumSTATDATA *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
DWORD i, count;
if (!This) return E_OUTOFMEMORY;
This->IEnumSTATDATA_iface.lpVtbl = &EnumSTATDATA_VTable;
This->ref = 1;
This->index = index;
[OLE32] Sync with Wine Staging 2.9. CORE-13362 9cc976a ole32: Fix compilation with recent versions of gcc. 2e36326 ole32: Synthesize dibs or bitmaps as appropriate. e27708f ole32: Create CF_DIB and CF_BITMAP entries when either is cached. 20a8f1a ole32: Implement IOleCache_EnumCache(). f9b0f60 ole32: Check the cache entry's stgmedium for the unloaded state. 8fc1a4c ole32: OleUninitialize() does not release the reference to the clipboard's source dataobject. 1d2860e ole32: Fix up the dib's resolution on loading. e7bb4ba ole32: Don't cache the BITMAPFILEHEADER. fc49d98 ole32: Set the advise flags in CreateEntry(). 77d1eba ole32: Use the helper function to copy the clipboard's FORMATETC. 9ee30d7 ole32: Use the helper function to copy the datacache's FORMATETC. 11db491 ole32: Add a helper to copy FORMATETC structures. b399baf ole32: Add CoRegisterSurrogate/Ex stubs. 87dba2b ole32: Zero STGMEDIUM before calling IDataObject::GetData. c7e6fe6 ole32: Added GlobalOptions object stub implementation. fd09c37 ole32: Use generic class factory for StdComponentCategoriesMgr object. 076c782 ole32: Use generic class factory for pointer moniker. 961c3dc ole32: Use generic class factory for class moniker. 947c9ba ole32: Use generic class factory for composite moniker. b05fd46 ole32: Use generic class factory for anti moniker. dee6463 ole32: Use generic class factory for item moniker. cf7883f ole32: Added generic class factory implementation and use it for file moniker. svn path=/trunk/; revision=74829
2017-06-03 22:33:33 +00:00
if (copy)
{
[OLE32] Sync with Wine Staging 2.9. CORE-13362 9cc976a ole32: Fix compilation with recent versions of gcc. 2e36326 ole32: Synthesize dibs or bitmaps as appropriate. e27708f ole32: Create CF_DIB and CF_BITMAP entries when either is cached. 20a8f1a ole32: Implement IOleCache_EnumCache(). f9b0f60 ole32: Check the cache entry's stgmedium for the unloaded state. 8fc1a4c ole32: OleUninitialize() does not release the reference to the clipboard's source dataobject. 1d2860e ole32: Fix up the dib's resolution on loading. e7bb4ba ole32: Don't cache the BITMAPFILEHEADER. fc49d98 ole32: Set the advise flags in CreateEntry(). 77d1eba ole32: Use the helper function to copy the clipboard's FORMATETC. 9ee30d7 ole32: Use the helper function to copy the datacache's FORMATETC. 11db491 ole32: Add a helper to copy FORMATETC structures. b399baf ole32: Add CoRegisterSurrogate/Ex stubs. 87dba2b ole32: Zero STGMEDIUM before calling IDataObject::GetData. c7e6fe6 ole32: Added GlobalOptions object stub implementation. fd09c37 ole32: Use generic class factory for StdComponentCategoriesMgr object. 076c782 ole32: Use generic class factory for pointer moniker. 961c3dc ole32: Use generic class factory for class moniker. 947c9ba ole32: Use generic class factory for composite moniker. b05fd46 ole32: Use generic class factory for anti moniker. dee6463 ole32: Use generic class factory for item moniker. cf7883f ole32: Added generic class factory implementation and use it for file moniker. svn path=/trunk/; revision=74829
2017-06-03 22:33:33 +00:00
This->statdata = HeapAlloc(GetProcessHeap(), 0, array_len * sizeof(*This->statdata));
if(!This->statdata)
{
HeapFree(GetProcessHeap(), 0, This);
return E_OUTOFMEMORY;
}
[OLE32] Sync with Wine Staging 2.9. CORE-13362 9cc976a ole32: Fix compilation with recent versions of gcc. 2e36326 ole32: Synthesize dibs or bitmaps as appropriate. e27708f ole32: Create CF_DIB and CF_BITMAP entries when either is cached. 20a8f1a ole32: Implement IOleCache_EnumCache(). f9b0f60 ole32: Check the cache entry's stgmedium for the unloaded state. 8fc1a4c ole32: OleUninitialize() does not release the reference to the clipboard's source dataobject. 1d2860e ole32: Fix up the dib's resolution on loading. e7bb4ba ole32: Don't cache the BITMAPFILEHEADER. fc49d98 ole32: Set the advise flags in CreateEntry(). 77d1eba ole32: Use the helper function to copy the clipboard's FORMATETC. 9ee30d7 ole32: Use the helper function to copy the datacache's FORMATETC. 11db491 ole32: Add a helper to copy FORMATETC structures. b399baf ole32: Add CoRegisterSurrogate/Ex stubs. 87dba2b ole32: Zero STGMEDIUM before calling IDataObject::GetData. c7e6fe6 ole32: Added GlobalOptions object stub implementation. fd09c37 ole32: Use generic class factory for StdComponentCategoriesMgr object. 076c782 ole32: Use generic class factory for pointer moniker. 961c3dc ole32: Use generic class factory for class moniker. 947c9ba ole32: Use generic class factory for composite moniker. b05fd46 ole32: Use generic class factory for anti moniker. dee6463 ole32: Use generic class factory for item moniker. cf7883f ole32: Added generic class factory implementation and use it for file moniker. svn path=/trunk/; revision=74829
2017-06-03 22:33:33 +00:00
for(i = 0, count = 0; i < array_len; i++)
{
[OLE32] Sync with Wine Staging 2.9. CORE-13362 9cc976a ole32: Fix compilation with recent versions of gcc. 2e36326 ole32: Synthesize dibs or bitmaps as appropriate. e27708f ole32: Create CF_DIB and CF_BITMAP entries when either is cached. 20a8f1a ole32: Implement IOleCache_EnumCache(). f9b0f60 ole32: Check the cache entry's stgmedium for the unloaded state. 8fc1a4c ole32: OleUninitialize() does not release the reference to the clipboard's source dataobject. 1d2860e ole32: Fix up the dib's resolution on loading. e7bb4ba ole32: Don't cache the BITMAPFILEHEADER. fc49d98 ole32: Set the advise flags in CreateEntry(). 77d1eba ole32: Use the helper function to copy the clipboard's FORMATETC. 9ee30d7 ole32: Use the helper function to copy the datacache's FORMATETC. 11db491 ole32: Add a helper to copy FORMATETC structures. b399baf ole32: Add CoRegisterSurrogate/Ex stubs. 87dba2b ole32: Zero STGMEDIUM before calling IDataObject::GetData. c7e6fe6 ole32: Added GlobalOptions object stub implementation. fd09c37 ole32: Use generic class factory for StdComponentCategoriesMgr object. 076c782 ole32: Use generic class factory for pointer moniker. 961c3dc ole32: Use generic class factory for class moniker. 947c9ba ole32: Use generic class factory for composite moniker. b05fd46 ole32: Use generic class factory for anti moniker. dee6463 ole32: Use generic class factory for item moniker. cf7883f ole32: Added generic class factory implementation and use it for file moniker. svn path=/trunk/; revision=74829
2017-06-03 22:33:33 +00:00
if(data[i].pAdvSink)
{
copy_statdata(This->statdata + count, data + i);
count++;
}
}
}
[OLE32] Sync with Wine Staging 2.9. CORE-13362 9cc976a ole32: Fix compilation with recent versions of gcc. 2e36326 ole32: Synthesize dibs or bitmaps as appropriate. e27708f ole32: Create CF_DIB and CF_BITMAP entries when either is cached. 20a8f1a ole32: Implement IOleCache_EnumCache(). f9b0f60 ole32: Check the cache entry's stgmedium for the unloaded state. 8fc1a4c ole32: OleUninitialize() does not release the reference to the clipboard's source dataobject. 1d2860e ole32: Fix up the dib's resolution on loading. e7bb4ba ole32: Don't cache the BITMAPFILEHEADER. fc49d98 ole32: Set the advise flags in CreateEntry(). 77d1eba ole32: Use the helper function to copy the clipboard's FORMATETC. 9ee30d7 ole32: Use the helper function to copy the datacache's FORMATETC. 11db491 ole32: Add a helper to copy FORMATETC structures. b399baf ole32: Add CoRegisterSurrogate/Ex stubs. 87dba2b ole32: Zero STGMEDIUM before calling IDataObject::GetData. c7e6fe6 ole32: Added GlobalOptions object stub implementation. fd09c37 ole32: Use generic class factory for StdComponentCategoriesMgr object. 076c782 ole32: Use generic class factory for pointer moniker. 961c3dc ole32: Use generic class factory for class moniker. 947c9ba ole32: Use generic class factory for composite moniker. b05fd46 ole32: Use generic class factory for anti moniker. dee6463 ole32: Use generic class factory for item moniker. cf7883f ole32: Added generic class factory implementation and use it for file moniker. svn path=/trunk/; revision=74829
2017-06-03 22:33:33 +00:00
else
{
This->statdata = data;
count = array_len;
}
This->num_of_elems = count;
This->holder = holder;
[OLE32] Sync with Wine Staging 2.9. CORE-13362 9cc976a ole32: Fix compilation with recent versions of gcc. 2e36326 ole32: Synthesize dibs or bitmaps as appropriate. e27708f ole32: Create CF_DIB and CF_BITMAP entries when either is cached. 20a8f1a ole32: Implement IOleCache_EnumCache(). f9b0f60 ole32: Check the cache entry's stgmedium for the unloaded state. 8fc1a4c ole32: OleUninitialize() does not release the reference to the clipboard's source dataobject. 1d2860e ole32: Fix up the dib's resolution on loading. e7bb4ba ole32: Don't cache the BITMAPFILEHEADER. fc49d98 ole32: Set the advise flags in CreateEntry(). 77d1eba ole32: Use the helper function to copy the clipboard's FORMATETC. 9ee30d7 ole32: Use the helper function to copy the datacache's FORMATETC. 11db491 ole32: Add a helper to copy FORMATETC structures. b399baf ole32: Add CoRegisterSurrogate/Ex stubs. 87dba2b ole32: Zero STGMEDIUM before calling IDataObject::GetData. c7e6fe6 ole32: Added GlobalOptions object stub implementation. fd09c37 ole32: Use generic class factory for StdComponentCategoriesMgr object. 076c782 ole32: Use generic class factory for pointer moniker. 961c3dc ole32: Use generic class factory for class moniker. 947c9ba ole32: Use generic class factory for composite moniker. b05fd46 ole32: Use generic class factory for anti moniker. dee6463 ole32: Use generic class factory for item moniker. cf7883f ole32: Added generic class factory implementation and use it for file moniker. svn path=/trunk/; revision=74829
2017-06-03 22:33:33 +00:00
if (holder) IUnknown_AddRef(holder);
*ppenum = &This->IEnumSTATDATA_iface;
return S_OK;
}
/**************************************************************************
* OleAdviseHolder Implementation
*/
typedef struct
{
IOleAdviseHolder IOleAdviseHolder_iface;
LONG ref;
DWORD max_cons;
STATDATA *connections;
} OleAdviseHolderImpl;
static inline OleAdviseHolderImpl *impl_from_IOleAdviseHolder(IOleAdviseHolder *iface)
{
return CONTAINING_RECORD(iface, OleAdviseHolderImpl, IOleAdviseHolder_iface);
}
/**************************************************************************
* OleAdviseHolderImpl_Destructor
*/
static void OleAdviseHolderImpl_Destructor(OleAdviseHolderImpl *This)
{
DWORD index;
TRACE("%p\n", This);
for (index = 0; index < This->max_cons; index++)
{
if (This->connections[index].pAdvSink != NULL)
release_statdata(This->connections + index);
}
HeapFree(GetProcessHeap(), 0, This->connections);
HeapFree(GetProcessHeap(), 0, This);
}
/**************************************************************************
* OleAdviseHolderImpl_QueryInterface
*/
static HRESULT WINAPI OleAdviseHolderImpl_QueryInterface(IOleAdviseHolder *iface,
REFIID iid, void **obj)
{
OleAdviseHolderImpl *This = impl_from_IOleAdviseHolder(iface);
TRACE("(%p)->(%s,%p)\n",This, debugstr_guid(iid), obj);
if (obj == NULL)
return E_POINTER;
*obj = NULL;
if (IsEqualIID(iid, &IID_IUnknown) ||
IsEqualIID(iid, &IID_IOleAdviseHolder))
{
*obj = &This->IOleAdviseHolder_iface;
}
if(*obj == NULL)
return E_NOINTERFACE;
IUnknown_AddRef((IUnknown*)*obj);
return S_OK;
}
/******************************************************************************
* OleAdviseHolderImpl_AddRef
*/
static ULONG WINAPI OleAdviseHolderImpl_AddRef(IOleAdviseHolder *iface)
{
OleAdviseHolderImpl *This = impl_from_IOleAdviseHolder(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p)->(ref=%d)\n", This, ref - 1);
return ref;
}
/******************************************************************************
* OleAdviseHolderImpl_Release
*/
static ULONG WINAPI OleAdviseHolderImpl_Release(IOleAdviseHolder *iface)
{
OleAdviseHolderImpl *This = impl_from_IOleAdviseHolder(iface);
ULONG ref;
TRACE("(%p)->(ref=%d)\n", This, This->ref);
ref = InterlockedDecrement(&This->ref);
if (ref == 0) OleAdviseHolderImpl_Destructor(This);
return ref;
}
/******************************************************************************
* OleAdviseHolderImpl_Advise
*/
static HRESULT WINAPI OleAdviseHolderImpl_Advise(IOleAdviseHolder *iface,
IAdviseSink *pAdvise,
DWORD *pdwConnection)
{
DWORD index;
OleAdviseHolderImpl *This = impl_from_IOleAdviseHolder(iface);
STATDATA new_conn;
static const FORMATETC empty_fmtetc = {0, NULL, 0, -1, 0};
TRACE("(%p)->(%p, %p)\n", This, pAdvise, pdwConnection);
if (pdwConnection==NULL)
return E_POINTER;
*pdwConnection = 0;
for (index = 0; index < This->max_cons; index++)
{
if (This->connections[index].pAdvSink == NULL)
break;
}
if (index == This->max_cons)
{
This->max_cons += INITIAL_SINKS;
This->connections = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->connections,
This->max_cons * sizeof(*This->connections));
}
new_conn.pAdvSink = pAdvise;
new_conn.advf = 0;
new_conn.formatetc = empty_fmtetc;
new_conn.dwConnection = index + 1; /* 0 is not a valid cookie, so increment the index */
copy_statdata(This->connections + index, &new_conn);
*pdwConnection = new_conn.dwConnection;
return S_OK;
}
/******************************************************************************
* OleAdviseHolderImpl_Unadvise
*/
static HRESULT WINAPI OleAdviseHolderImpl_Unadvise(IOleAdviseHolder *iface,
DWORD dwConnection)
{
OleAdviseHolderImpl *This = impl_from_IOleAdviseHolder(iface);
DWORD index;
TRACE("(%p)->(%u)\n", This, dwConnection);
/* The connection number is 1 more than the index, see OleAdviseHolder_Advise */
index = dwConnection - 1;
if (index >= This->max_cons || This->connections[index].pAdvSink == NULL)
return OLE_E_NOCONNECTION;
release_statdata(This->connections + index);
return S_OK;
}
/******************************************************************************
* OleAdviseHolderImpl_EnumAdvise
*/
static HRESULT WINAPI OleAdviseHolderImpl_EnumAdvise(IOleAdviseHolder *iface, IEnumSTATDATA **enum_advise)
{
OleAdviseHolderImpl *This = impl_from_IOleAdviseHolder(iface);
IUnknown *unk;
HRESULT hr;
TRACE("(%p)->(%p)\n", This, enum_advise);
IOleAdviseHolder_QueryInterface(iface, &IID_IUnknown, (void**)&unk);
[OLE32] Sync with Wine Staging 2.9. CORE-13362 9cc976a ole32: Fix compilation with recent versions of gcc. 2e36326 ole32: Synthesize dibs or bitmaps as appropriate. e27708f ole32: Create CF_DIB and CF_BITMAP entries when either is cached. 20a8f1a ole32: Implement IOleCache_EnumCache(). f9b0f60 ole32: Check the cache entry's stgmedium for the unloaded state. 8fc1a4c ole32: OleUninitialize() does not release the reference to the clipboard's source dataobject. 1d2860e ole32: Fix up the dib's resolution on loading. e7bb4ba ole32: Don't cache the BITMAPFILEHEADER. fc49d98 ole32: Set the advise flags in CreateEntry(). 77d1eba ole32: Use the helper function to copy the clipboard's FORMATETC. 9ee30d7 ole32: Use the helper function to copy the datacache's FORMATETC. 11db491 ole32: Add a helper to copy FORMATETC structures. b399baf ole32: Add CoRegisterSurrogate/Ex stubs. 87dba2b ole32: Zero STGMEDIUM before calling IDataObject::GetData. c7e6fe6 ole32: Added GlobalOptions object stub implementation. fd09c37 ole32: Use generic class factory for StdComponentCategoriesMgr object. 076c782 ole32: Use generic class factory for pointer moniker. 961c3dc ole32: Use generic class factory for class moniker. 947c9ba ole32: Use generic class factory for composite moniker. b05fd46 ole32: Use generic class factory for anti moniker. dee6463 ole32: Use generic class factory for item moniker. cf7883f ole32: Added generic class factory implementation and use it for file moniker. svn path=/trunk/; revision=74829
2017-06-03 22:33:33 +00:00
hr = EnumSTATDATA_Construct(unk, 0, This->max_cons, This->connections, TRUE, enum_advise);
IUnknown_Release(unk);
return hr;
}
/******************************************************************************
* OleAdviseHolderImpl_SendOnRename
*/
static HRESULT WINAPI OleAdviseHolderImpl_SendOnRename(IOleAdviseHolder *iface, IMoniker *pmk)
{
IEnumSTATDATA *pEnum;
HRESULT hr;
TRACE("(%p)->(%p)\n", iface, pmk);
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;
}
/******************************************************************************
* OleAdviseHolderImpl_SendOnSave
*/
static HRESULT WINAPI OleAdviseHolderImpl_SendOnSave(IOleAdviseHolder *iface)
{
IEnumSTATDATA *pEnum;
HRESULT hr;
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;
}
/******************************************************************************
* OleAdviseHolderImpl_SendOnClose
*/
static HRESULT WINAPI OleAdviseHolderImpl_SendOnClose(IOleAdviseHolder *iface)
{
IEnumSTATDATA *pEnum;
HRESULT hr;
TRACE("(%p)->()\n", iface);
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;
}
/**************************************************************************
* OleAdviseHolderImpl_VTable
*/
Sync to Wine-20050628: Robert Shearman <rob@codeweavers.com> - Convert some registry helper functions to use unicode versions of CLSID & registry functions (untested). - Add registry entries for local-only OLE interfaces. - Change IUnknown to local interface. - IUnknown isn't a remotable interface so the stub manager shouldn't need a marshaller for it. - Change the RPC code to use the unicode versions of the CLSID & registry functions. - Don't disconnect proxies flagged with SORFP_NOLIFETIMEMGMT. It makes no sense and only causes trouble for proxies that depend on these proxies being available. - Change some of the registry helper functions to use the unicode versions of the CLSID & registry functions. - Reindent CoGetClassObject and output an error message if the class isn't registered. - Add tests for the touched functions. Dmitry Timoshkov <dmitry@codeweavers.com> - Make remaining OLE interface vtables const. Richard Cohen <richard@daijobu.co.uk> - Base FileMonikerImpl_Save() on XP. - Correct handling of Unicode strings & multibyte locales. - More error checking. - Change ERR to WARN. - Match Windows quick & dirty estimate for GetSizeMax(). Stefan Huehner <stefan@huehner.org> - Fix some more -Wstrict-prototypes warnings. Mike Hearn <mike@navi.cx> - Add some tracing to the IRemUnknown RpcProxyBuffer implementation. Eric Pouech <pouech-eric@wanadoo.fr> - Const correctness fixes. Richard Cohen <richard@daijobu.co.uk> - IEnum::Clone shouldn't do a Reset. Marcus Meissner <marcus@jet.franken.de> - Removed CLSID_CompositeMoniker (conflicting with static definition). Alexandre Julliard <julliard@winehq.org> - Sort entry points alphabetically. svn path=/trunk/; revision=17036
2005-08-03 22:31:39 +00:00
static const IOleAdviseHolderVtbl oahvt =
{
OleAdviseHolderImpl_QueryInterface,
OleAdviseHolderImpl_AddRef,
OleAdviseHolderImpl_Release,
OleAdviseHolderImpl_Advise,
OleAdviseHolderImpl_Unadvise,
OleAdviseHolderImpl_EnumAdvise,
OleAdviseHolderImpl_SendOnRename,
OleAdviseHolderImpl_SendOnSave,
OleAdviseHolderImpl_SendOnClose
};
/**************************************************************************
* OleAdviseHolderImpl_Constructor
*/
static IOleAdviseHolder *OleAdviseHolderImpl_Constructor(void)
{
OleAdviseHolderImpl* lpoah;
lpoah = HeapAlloc(GetProcessHeap(), 0, sizeof(OleAdviseHolderImpl));
lpoah->IOleAdviseHolder_iface.lpVtbl = &oahvt;
lpoah->ref = 1;
lpoah->max_cons = INITIAL_SINKS;
lpoah->connections = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
lpoah->max_cons * sizeof(*lpoah->connections));
TRACE("returning %p\n", &lpoah->IOleAdviseHolder_iface);
return &lpoah->IOleAdviseHolder_iface;
}
/**************************************************************************
* DataAdviseHolder Implementation
*/
typedef struct
{
IDataAdviseHolder IDataAdviseHolder_iface;
Sync to Wine-20050725: Robert Shearman <rob@codeweavers.com> - Marshal return value from IRemUnknown_RemQueryInterface. - We should be starting with 1 reference. - IRpcStubBuffer_Disconnect can be called more than once. - Silence now noisy error messages caused by changes in the way we call ipid_to_stubmanager. Move the error message to the one place it is needed. - By-pass the RPC runtime if possible when calling an STA by posting a message directly to the apartment window for it to process. Fixes a deadlock in InstallShield caused by having to create a thread when freeing an object that comes from an STA apartment. Added tests that fail without this fix. - Hack around broken state management so InstallShield works. - Delete the stub manager outside of the apartment critical section because the deletion may require the object to re-enter the apartment. - Always query for the correct stub interface, otherwise we will be pointing to the completely wrong object when a proxy does a queryinterface. - Remove assumption that the stub buffer will handle the lifetime of the object. Alex Villacis Lasso <a_villacis@palosanto.com> - Initialize RegisteredClass properly in CoRegisterClassObject to prevent crash in CoRevokeClassObject when accessing (uninitialized) pMarshalledData. Mike McCormack <mike@codeweavers.com> - Fix gcc 4.0 -Wpointer-sign warnings. Vitaly Lipatov <lav@etersoft.ru> - Added some documentation. Stefan Huehner <stefan@huehner.org> - Fix some missing-declarations warnings. Marcus Meissner <meissner@suse.de> - 16bit interfaces are cdecl, so drop the WINAPI. - 16bit COM interfaces are cdecl, not WINAPI. - OleInitializeWOW gets 2 arguments. - Added OleSetMenuDescriptor16 stub. Marcus Meissner <marcus@jet.franken.de> - Implemented IsValidInterface16, CoMemAlloc. Added debug to HGLOBALLockBytes16_QueryInterface. svn path=/trunk/; revision=17332
2005-08-12 17:19:46 +00:00
LONG ref;
DWORD maxCons;
STATDATA* connections;
DWORD* remote_connections;
IDataObject* delegate;
} DataAdviseHolder;
/* this connection has also has been advised to the delegate data object */
#define WINE_ADVF_REMOTE 0x80000000
static inline DataAdviseHolder *impl_from_IDataAdviseHolder(IDataAdviseHolder *iface)
{
return CONTAINING_RECORD(iface, DataAdviseHolder, IDataAdviseHolder_iface);
}
/******************************************************************************
* 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].pAdvSink != NULL)
{
if (ptrToDestroy->delegate &&
(ptrToDestroy->connections[index].advf & WINE_ADVF_REMOTE))
IDataObject_DUnadvise(ptrToDestroy->delegate,
ptrToDestroy->remote_connections[index]);
release_statdata(ptrToDestroy->connections + index);
}
}
HeapFree(GetProcessHeap(), 0, ptrToDestroy->remote_connections);
HeapFree(GetProcessHeap(), 0, ptrToDestroy->connections);
HeapFree(GetProcessHeap(), 0, ptrToDestroy);
}
/************************************************************************
* DataAdviseHolder_QueryInterface (IUnknown)
*/
static HRESULT WINAPI DataAdviseHolder_QueryInterface(IDataAdviseHolder *iface,
REFIID riid, void **ppvObject)
{
DataAdviseHolder *This = impl_from_IDataAdviseHolder(iface);
TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppvObject);
if ( (This==0) || (ppvObject==0) )
return E_INVALIDARG;
*ppvObject = 0;
if ( IsEqualIID(&IID_IUnknown, riid) ||
IsEqualIID(&IID_IDataAdviseHolder, riid) )
{
*ppvObject = iface;
}
if ((*ppvObject)==0)
{
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppvObject);
return S_OK;
}
/************************************************************************
* DataAdviseHolder_AddRef (IUnknown)
*/
static ULONG WINAPI DataAdviseHolder_AddRef(IDataAdviseHolder *iface)
{
DataAdviseHolder *This = impl_from_IDataAdviseHolder(iface);
TRACE("(%p) (ref=%d)\n", This, This->ref);
return InterlockedIncrement(&This->ref);
}
/************************************************************************
* DataAdviseHolder_Release (IUnknown)
*/
static ULONG WINAPI DataAdviseHolder_Release(IDataAdviseHolder *iface)
{
DataAdviseHolder *This = impl_from_IDataAdviseHolder(iface);
ULONG ref;
TRACE("(%p) (ref=%d)\n", This, This->ref);
ref = InterlockedDecrement(&This->ref);
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;
STATDATA new_conn;
DataAdviseHolder *This = impl_from_IDataAdviseHolder(iface);
TRACE("(%p)->(%p, %p, %08x, %p, %p)\n", This, pDataObject, pFetc, advf,
pAdvise, pdwConnection);
if (pdwConnection==NULL)
return E_POINTER;
*pdwConnection = 0;
for (index = 0; index < This->maxCons; index++)
{
if (This->connections[index].pAdvSink == NULL)
break;
}
if (index == This->maxCons)
{
This->maxCons+=INITIAL_SINKS;
This->connections = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
This->connections,
This->maxCons * sizeof(*This->connections));
This->remote_connections = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
This->remote_connections,
This->maxCons * sizeof(*This->remote_connections));
}
new_conn.pAdvSink = pAdvise;
new_conn.advf = advf & ~WINE_ADVF_REMOTE;
new_conn.formatetc = *pFetc;
new_conn.dwConnection = index + 1; /* 0 is not a valid cookie, so increment the index */
copy_statdata(This->connections + index, &new_conn);
if (This->connections[index].pAdvSink != NULL)
{
/* if we are already connected advise the remote object */
if (This->delegate)
{
HRESULT hr;
hr = IDataObject_DAdvise(This->delegate, &new_conn.formatetc,
new_conn.advf, new_conn.pAdvSink,
&This->remote_connections[index]);
if (FAILED(hr))
{
IDataAdviseHolder_Unadvise(iface, new_conn.dwConnection);
return hr;
}
This->connections[index].advf |= WINE_ADVF_REMOTE;
}
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);
}
*pdwConnection = new_conn.dwConnection;
return S_OK;
}
/******************************************************************************
* DataAdviseHolder_Unadvise
*/
static HRESULT WINAPI DataAdviseHolder_Unadvise(IDataAdviseHolder *iface,
DWORD dwConnection)
{
DataAdviseHolder *This = impl_from_IDataAdviseHolder(iface);
DWORD index;
TRACE("(%p)->(%u)\n", This, dwConnection);
/* The connection number is 1 more than the index, see DataAdviseHolder_Advise */
index = dwConnection - 1;
if (index >= This->maxCons || This->connections[index].pAdvSink == NULL)
return OLE_E_NOCONNECTION;
if (This->delegate && This->connections[index].advf & WINE_ADVF_REMOTE)
{
IDataObject_DUnadvise(This->delegate, This->remote_connections[index]);
This->remote_connections[index] = 0;
}
release_statdata(This->connections + index);
return S_OK;
}
/******************************************************************************
* DataAdviseHolder_EnumAdvise
*/
static HRESULT WINAPI DataAdviseHolder_EnumAdvise(IDataAdviseHolder *iface,
IEnumSTATDATA **enum_advise)
{
DataAdviseHolder *This = impl_from_IDataAdviseHolder(iface);
IUnknown *unk;
HRESULT hr;
TRACE("(%p)->(%p)\n", This, enum_advise);
IDataAdviseHolder_QueryInterface(iface, &IID_IUnknown, (void**)&unk);
[OLE32] Sync with Wine Staging 2.9. CORE-13362 9cc976a ole32: Fix compilation with recent versions of gcc. 2e36326 ole32: Synthesize dibs or bitmaps as appropriate. e27708f ole32: Create CF_DIB and CF_BITMAP entries when either is cached. 20a8f1a ole32: Implement IOleCache_EnumCache(). f9b0f60 ole32: Check the cache entry's stgmedium for the unloaded state. 8fc1a4c ole32: OleUninitialize() does not release the reference to the clipboard's source dataobject. 1d2860e ole32: Fix up the dib's resolution on loading. e7bb4ba ole32: Don't cache the BITMAPFILEHEADER. fc49d98 ole32: Set the advise flags in CreateEntry(). 77d1eba ole32: Use the helper function to copy the clipboard's FORMATETC. 9ee30d7 ole32: Use the helper function to copy the datacache's FORMATETC. 11db491 ole32: Add a helper to copy FORMATETC structures. b399baf ole32: Add CoRegisterSurrogate/Ex stubs. 87dba2b ole32: Zero STGMEDIUM before calling IDataObject::GetData. c7e6fe6 ole32: Added GlobalOptions object stub implementation. fd09c37 ole32: Use generic class factory for StdComponentCategoriesMgr object. 076c782 ole32: Use generic class factory for pointer moniker. 961c3dc ole32: Use generic class factory for class moniker. 947c9ba ole32: Use generic class factory for composite moniker. b05fd46 ole32: Use generic class factory for anti moniker. dee6463 ole32: Use generic class factory for item moniker. cf7883f ole32: Added generic class factory implementation and use it for file moniker. svn path=/trunk/; revision=74829
2017-06-03 22:33:33 +00:00
hr = EnumSTATDATA_Construct(unk, 0, This->maxCons, This->connections, TRUE, enum_advise);
IUnknown_Release(unk);
return hr;
}
/******************************************************************************
* DataAdviseHolder_SendOnDataChange
*/
static HRESULT WINAPI DataAdviseHolder_SendOnDataChange(IDataAdviseHolder *iface,
IDataObject *data_obj,
DWORD dwReserved, DWORD advf)
{
IEnumSTATDATA *pEnum;
HRESULT hr;
TRACE("(%p)->(%p, %08x, %08x)\n", iface, data_obj, dwReserved, advf);
hr = IDataAdviseHolder_EnumAdvise(iface, &pEnum);
if (SUCCEEDED(hr))
{
STATDATA statdata;
while (IEnumSTATDATA_Next(pEnum, 1, &statdata, NULL) == S_OK)
{
STGMEDIUM stg;
stg.tymed = TYMED_NULL;
stg.u.pstg = NULL;
stg.pUnkForRelease = NULL;
if(!(statdata.advf & ADVF_NODATA))
{
hr = IDataObject_GetData(data_obj, &statdata.formatetc, &stg);
}
IAdviseSink_OnDataChange(statdata.pAdvSink, &statdata.formatetc, &stg);
if(statdata.advf & ADVF_ONLYONCE)
{
IDataAdviseHolder_Unadvise(iface, statdata.dwConnection);
}
release_statdata(&statdata);
}
IEnumSTATDATA_Release(pEnum);
}
return S_OK;
}
/**************************************************************************
* DataAdviseHolderImpl_VTable
*/
Sync to Wine-20050628: Robert Shearman <rob@codeweavers.com> - Convert some registry helper functions to use unicode versions of CLSID & registry functions (untested). - Add registry entries for local-only OLE interfaces. - Change IUnknown to local interface. - IUnknown isn't a remotable interface so the stub manager shouldn't need a marshaller for it. - Change the RPC code to use the unicode versions of the CLSID & registry functions. - Don't disconnect proxies flagged with SORFP_NOLIFETIMEMGMT. It makes no sense and only causes trouble for proxies that depend on these proxies being available. - Change some of the registry helper functions to use the unicode versions of the CLSID & registry functions. - Reindent CoGetClassObject and output an error message if the class isn't registered. - Add tests for the touched functions. Dmitry Timoshkov <dmitry@codeweavers.com> - Make remaining OLE interface vtables const. Richard Cohen <richard@daijobu.co.uk> - Base FileMonikerImpl_Save() on XP. - Correct handling of Unicode strings & multibyte locales. - More error checking. - Change ERR to WARN. - Match Windows quick & dirty estimate for GetSizeMax(). Stefan Huehner <stefan@huehner.org> - Fix some more -Wstrict-prototypes warnings. Mike Hearn <mike@navi.cx> - Add some tracing to the IRemUnknown RpcProxyBuffer implementation. Eric Pouech <pouech-eric@wanadoo.fr> - Const correctness fixes. Richard Cohen <richard@daijobu.co.uk> - IEnum::Clone shouldn't do a Reset. Marcus Meissner <marcus@jet.franken.de> - Removed CLSID_CompositeMoniker (conflicting with static definition). Alexandre Julliard <julliard@winehq.org> - Sort entry points alphabetically. svn path=/trunk/; revision=17036
2005-08-03 22:31:39 +00:00
static const IDataAdviseHolderVtbl DataAdviseHolderImpl_VTable =
{
DataAdviseHolder_QueryInterface,
DataAdviseHolder_AddRef,
DataAdviseHolder_Release,
DataAdviseHolder_Advise,
DataAdviseHolder_Unadvise,
DataAdviseHolder_EnumAdvise,
DataAdviseHolder_SendOnDataChange
};
HRESULT DataAdviseHolder_OnConnect(IDataAdviseHolder *iface, IDataObject *pDelegate)
{
DataAdviseHolder *This = impl_from_IDataAdviseHolder(iface);
DWORD index;
HRESULT hr = S_OK;
for(index = 0; index < This->maxCons; index++)
{
if(This->connections[index].pAdvSink != NULL)
{
hr = IDataObject_DAdvise(pDelegate, &This->connections[index].formatetc,
This->connections[index].advf,
This->connections[index].pAdvSink,
&This->remote_connections[index]);
if (FAILED(hr)) break;
This->connections[index].advf |= WINE_ADVF_REMOTE;
}
}
This->delegate = pDelegate;
return hr;
}
void DataAdviseHolder_OnDisconnect(IDataAdviseHolder *iface)
{
DataAdviseHolder *This = impl_from_IDataAdviseHolder(iface);
DWORD index;
for(index = 0; index < This->maxCons; index++)
{
if((This->connections[index].pAdvSink != NULL) &&
(This->connections[index].advf & WINE_ADVF_REMOTE))
{
IDataObject_DUnadvise(This->delegate, This->remote_connections[index]);
This->remote_connections[index] = 0;
This->connections[index].advf &= ~WINE_ADVF_REMOTE;
}
}
This->delegate = NULL;
}
/******************************************************************************
* DataAdviseHolder_Constructor
*/
static IDataAdviseHolder *DataAdviseHolder_Constructor(void)
{
DataAdviseHolder* newHolder;
newHolder = HeapAlloc(GetProcessHeap(), 0, sizeof(DataAdviseHolder));
newHolder->IDataAdviseHolder_iface.lpVtbl = &DataAdviseHolderImpl_VTable;
newHolder->ref = 1;
newHolder->maxCons = INITIAL_SINKS;
newHolder->connections = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
newHolder->maxCons * sizeof(*newHolder->connections));
newHolder->remote_connections = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
newHolder->maxCons * sizeof(*newHolder->remote_connections));
newHolder->delegate = NULL;
TRACE("returning %p\n", &newHolder->IDataAdviseHolder_iface);
return &newHolder->IDataAdviseHolder_iface;
}
/***********************************************************************
* API functions
*/
/***********************************************************************
* CreateOleAdviseHolder [OLE32.@]
*/
HRESULT WINAPI CreateOleAdviseHolder(IOleAdviseHolder **ppOAHolder)
{
TRACE("(%p)\n", ppOAHolder);
if (ppOAHolder==NULL)
return E_POINTER;
*ppOAHolder = OleAdviseHolderImpl_Constructor ();
if (*ppOAHolder != NULL)
return S_OK;
return E_OUTOFMEMORY;
}
/******************************************************************************
* CreateDataAdviseHolder [OLE32.@]
*/
HRESULT WINAPI CreateDataAdviseHolder(IDataAdviseHolder **ppDAHolder)
{
TRACE("(%p)\n", ppDAHolder);
if (ppDAHolder==NULL)
return E_POINTER;
*ppDAHolder = DataAdviseHolder_Constructor();
if (*ppDAHolder != NULL)
return S_OK;
return E_OUTOFMEMORY;
}