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
|
|
|
*/
|
|
|
|
|
2018-03-20 11:38:17 +00:00
|
|
|
|
|
|
|
#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"
|
2008-07-10 09:14:19 +00:00
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
|
|
|
|
|
|
|
#define INITIAL_SINKS 10
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
static void release_statdata(STATDATA *data)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
2019-11-10 13:10:55 +00:00
|
|
|
CoTaskMemFree(data->formatetc.ptd);
|
|
|
|
data->formatetc.ptd = NULL;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
if(data->pAdvSink)
|
|
|
|
{
|
|
|
|
IAdviseSink_Release(data->pAdvSink);
|
|
|
|
data->pAdvSink = NULL;
|
|
|
|
}
|
|
|
|
}
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
static HRESULT copy_statdata(STATDATA *dst, const STATDATA *src)
|
|
|
|
{
|
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;
|
2012-05-17 15:16:51 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
/**************************************************************************
|
|
|
|
* EnumSTATDATA Implementation
|
|
|
|
*/
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
IEnumSTATDATA IEnumSTATDATA_iface;
|
2007-04-20 12:23:52 +00:00
|
|
|
LONG ref;
|
|
|
|
|
|
|
|
ULONG index;
|
2012-05-17 15:16:51 +00:00
|
|
|
DWORD num_of_elems;
|
|
|
|
STATDATA *statdata;
|
|
|
|
IUnknown *holder;
|
|
|
|
} EnumSTATDATA;
|
|
|
|
|
|
|
|
static inline EnumSTATDATA *impl_from_IEnumSTATDATA(IEnumSTATDATA *iface)
|
|
|
|
{
|
|
|
|
return CONTAINING_RECORD(iface, EnumSTATDATA, IEnumSTATDATA_iface);
|
|
|
|
}
|
2007-04-20 12:23:52 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
static HRESULT WINAPI EnumSTATDATA_QueryInterface(IEnumSTATDATA *iface, REFIID riid, void **ppv)
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
|
|
|
TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
|
|
|
|
if (IsEqualIID(riid, &IID_IUnknown) ||
|
|
|
|
IsEqualIID(riid, &IID_IEnumSTATDATA))
|
|
|
|
{
|
2012-12-12 21:01:41 +00:00
|
|
|
IEnumSTATDATA_AddRef(iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
*ppv = iface;
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
return E_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
static ULONG WINAPI EnumSTATDATA_AddRef(IEnumSTATDATA *iface)
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
EnumSTATDATA *This = impl_from_IEnumSTATDATA(iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("()\n");
|
|
|
|
return InterlockedIncrement(&This->ref);
|
|
|
|
}
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
static ULONG WINAPI EnumSTATDATA_Release(IEnumSTATDATA *iface)
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
EnumSTATDATA *This = impl_from_IEnumSTATDATA(iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
LONG refs = InterlockedDecrement(&This->ref);
|
|
|
|
TRACE("()\n");
|
|
|
|
if (!refs)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
DWORD i;
|
|
|
|
for(i = 0; i < This->num_of_elems; i++)
|
|
|
|
release_statdata(This->statdata + i);
|
|
|
|
HeapFree(GetProcessHeap(), 0, This->statdata);
|
2017-06-03 22:33:33 +00:00
|
|
|
if (This->holder) IUnknown_Release(This->holder);
|
2007-04-20 12:23:52 +00:00
|
|
|
HeapFree(GetProcessHeap(), 0, This);
|
|
|
|
}
|
|
|
|
return refs;
|
|
|
|
}
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
static HRESULT WINAPI EnumSTATDATA_Next(IEnumSTATDATA *iface, ULONG num, LPSTATDATA data,
|
|
|
|
ULONG *fetched)
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
EnumSTATDATA *This = impl_from_IEnumSTATDATA(iface);
|
|
|
|
DWORD count = 0;
|
2007-04-20 12:23:52 +00:00
|
|
|
HRESULT hr = S_OK;
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
TRACE("(%d, %p, %p)\n", num, data, fetched);
|
2007-04-20 12:23:52 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
while(num--)
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
if (This->index >= This->num_of_elems)
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
|
|
|
hr = S_FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
copy_statdata(data + count, This->statdata + This->index);
|
2007-04-20 12:23:52 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
count++;
|
2007-04-20 12:23:52 +00:00
|
|
|
This->index++;
|
|
|
|
}
|
2012-05-17 15:16:51 +00:00
|
|
|
|
|
|
|
if (fetched) *fetched = count;
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
static HRESULT WINAPI EnumSTATDATA_Skip(IEnumSTATDATA *iface, ULONG num)
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
EnumSTATDATA *This = impl_from_IEnumSTATDATA(iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
TRACE("(%d)\n", num);
|
2007-04-20 12:23:52 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
if(This->index + num >= This->num_of_elems)
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
This->index = This->num_of_elems;
|
|
|
|
return S_FALSE;
|
2007-04-20 12:23:52 +00:00
|
|
|
}
|
2012-05-17 15:16:51 +00:00
|
|
|
|
|
|
|
This->index += num;
|
2007-04-20 12:23:52 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
static HRESULT WINAPI EnumSTATDATA_Reset(IEnumSTATDATA *iface)
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
EnumSTATDATA *This = impl_from_IEnumSTATDATA(iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
|
|
|
|
TRACE("()\n");
|
|
|
|
|
|
|
|
This->index = 0;
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
static HRESULT WINAPI EnumSTATDATA_Clone(IEnumSTATDATA *iface, IEnumSTATDATA **ppenum)
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
EnumSTATDATA *This = impl_from_IEnumSTATDATA(iface);
|
|
|
|
|
2017-06-03 22:33:33 +00:00
|
|
|
return EnumSTATDATA_Construct(This->holder, This->index, This->num_of_elems, This->statdata,
|
|
|
|
TRUE, ppenum);
|
2007-04-20 12:23:52 +00:00
|
|
|
}
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
static const IEnumSTATDATAVtbl EnumSTATDATA_VTable =
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
EnumSTATDATA_QueryInterface,
|
|
|
|
EnumSTATDATA_AddRef,
|
|
|
|
EnumSTATDATA_Release,
|
|
|
|
EnumSTATDATA_Next,
|
|
|
|
EnumSTATDATA_Skip,
|
|
|
|
EnumSTATDATA_Reset,
|
|
|
|
EnumSTATDATA_Clone
|
2007-04-20 12:23:52 +00:00
|
|
|
};
|
|
|
|
|
2017-06-03 22:33:33 +00:00
|
|
|
HRESULT EnumSTATDATA_Construct(IUnknown *holder, ULONG index, DWORD array_len, STATDATA *data,
|
|
|
|
BOOL copy, IEnumSTATDATA **ppenum)
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
EnumSTATDATA *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
|
|
|
|
DWORD i, count;
|
|
|
|
|
|
|
|
if (!This) return E_OUTOFMEMORY;
|
|
|
|
|
|
|
|
This->IEnumSTATDATA_iface.lpVtbl = &EnumSTATDATA_VTable;
|
2007-04-20 12:23:52 +00:00
|
|
|
This->ref = 1;
|
|
|
|
This->index = index;
|
2012-05-17 15:16:51 +00:00
|
|
|
|
2017-06-03 22:33:33 +00:00
|
|
|
if (copy)
|
2012-05-17 15:16:51 +00:00
|
|
|
{
|
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;
|
|
|
|
}
|
2012-05-17 15:16:51 +00:00
|
|
|
|
2017-06-03 22:33:33 +00:00
|
|
|
for(i = 0, count = 0; i < array_len; i++)
|
2012-05-17 15:16:51 +00:00
|
|
|
{
|
2017-06-03 22:33:33 +00:00
|
|
|
if(data[i].pAdvSink)
|
|
|
|
{
|
|
|
|
copy_statdata(This->statdata + count, data + i);
|
|
|
|
count++;
|
|
|
|
}
|
2012-05-17 15:16:51 +00:00
|
|
|
}
|
|
|
|
}
|
2017-06-03 22:33:33 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
This->statdata = data;
|
|
|
|
count = array_len;
|
|
|
|
}
|
2012-05-17 15:16:51 +00:00
|
|
|
|
|
|
|
This->num_of_elems = count;
|
|
|
|
This->holder = holder;
|
2017-06-03 22:33:33 +00:00
|
|
|
if (holder) IUnknown_AddRef(holder);
|
2012-05-17 15:16:51 +00:00
|
|
|
*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);
|
2007-04-20 12:23:52 +00:00
|
|
|
}
|
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
/**************************************************************************
|
|
|
|
* OleAdviseHolderImpl_Destructor
|
|
|
|
*/
|
2012-05-17 15:16:51 +00:00
|
|
|
static void OleAdviseHolderImpl_Destructor(OleAdviseHolderImpl *This)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
DWORD index;
|
|
|
|
TRACE("%p\n", This);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
for (index = 0; index < This->max_cons; index++)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
if (This->connections[index].pAdvSink != NULL)
|
|
|
|
release_statdata(This->connections + index);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
HeapFree(GetProcessHeap(), 0, This->connections);
|
|
|
|
HeapFree(GetProcessHeap(), 0, This);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**************************************************************************
|
|
|
|
* OleAdviseHolderImpl_QueryInterface
|
|
|
|
*/
|
2012-05-17 15:16:51 +00:00
|
|
|
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)
|
2005-07-31 12:11:56 +00:00
|
|
|
return E_POINTER;
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
*obj = NULL;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
if (IsEqualIID(iid, &IID_IUnknown) ||
|
|
|
|
IsEqualIID(iid, &IID_IOleAdviseHolder))
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
*obj = &This->IOleAdviseHolder_iface;
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
if(*obj == NULL)
|
2005-07-31 12:11:56 +00:00
|
|
|
return E_NOINTERFACE;
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
IUnknown_AddRef((IUnknown*)*obj);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* OleAdviseHolderImpl_AddRef
|
|
|
|
*/
|
2012-05-17 15:16:51 +00:00
|
|
|
static ULONG WINAPI OleAdviseHolderImpl_AddRef(IOleAdviseHolder *iface)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
OleAdviseHolderImpl *This = impl_from_IOleAdviseHolder(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
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
|
|
|
|
*/
|
2012-05-17 15:16:51 +00:00
|
|
|
static ULONG WINAPI OleAdviseHolderImpl_Release(IOleAdviseHolder *iface)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
OleAdviseHolderImpl *This = impl_from_IOleAdviseHolder(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
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
|
|
|
|
*/
|
2012-05-17 15:16:51 +00:00
|
|
|
static HRESULT WINAPI OleAdviseHolderImpl_Advise(IOleAdviseHolder *iface,
|
|
|
|
IAdviseSink *pAdvise,
|
|
|
|
DWORD *pdwConnection)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
|
|
|
DWORD index;
|
2012-05-17 15:16:51 +00:00
|
|
|
OleAdviseHolderImpl *This = impl_from_IOleAdviseHolder(iface);
|
|
|
|
STATDATA new_conn;
|
|
|
|
static const FORMATETC empty_fmtetc = {0, NULL, 0, -1, 0};
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
TRACE("(%p)->(%p, %p)\n", This, pAdvise, pdwConnection);
|
|
|
|
|
|
|
|
if (pdwConnection==NULL)
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
*pdwConnection = 0;
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
for (index = 0; index < This->max_cons; index++)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
if (This->connections[index].pAdvSink == NULL)
|
2005-07-31 12:11:56 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
if (index == This->max_cons)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
This->max_cons += INITIAL_SINKS;
|
|
|
|
This->connections = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->connections,
|
|
|
|
This->max_cons * sizeof(*This->connections));
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
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 */
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
copy_statdata(This->connections + index, &new_conn);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
*pdwConnection = new_conn.dwConnection;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* OleAdviseHolderImpl_Unadvise
|
|
|
|
*/
|
2012-05-17 15:16:51 +00:00
|
|
|
static HRESULT WINAPI OleAdviseHolderImpl_Unadvise(IOleAdviseHolder *iface,
|
|
|
|
DWORD dwConnection)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
OleAdviseHolderImpl *This = impl_from_IOleAdviseHolder(iface);
|
|
|
|
DWORD index;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p)->(%u)\n", This, dwConnection);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
/* The connection number is 1 more than the index, see OleAdviseHolder_Advise */
|
|
|
|
index = dwConnection - 1;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
if (index >= This->max_cons || This->connections[index].pAdvSink == NULL)
|
|
|
|
return OLE_E_NOCONNECTION;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
release_statdata(This->connections + index);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* OleAdviseHolderImpl_EnumAdvise
|
|
|
|
*/
|
2012-05-17 15:16:51 +00:00
|
|
|
static HRESULT WINAPI OleAdviseHolderImpl_EnumAdvise(IOleAdviseHolder *iface, IEnumSTATDATA **enum_advise)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
OleAdviseHolderImpl *This = impl_from_IOleAdviseHolder(iface);
|
|
|
|
IUnknown *unk;
|
|
|
|
HRESULT hr;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
TRACE("(%p)->(%p)\n", This, enum_advise);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
IOleAdviseHolder_QueryInterface(iface, &IID_IUnknown, (void**)&unk);
|
2017-06-03 22:33:33 +00:00
|
|
|
hr = EnumSTATDATA_Construct(unk, 0, This->max_cons, This->connections, TRUE, enum_advise);
|
2012-05-17 15:16:51 +00:00
|
|
|
IUnknown_Release(unk);
|
|
|
|
return hr;
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* OleAdviseHolderImpl_SendOnRename
|
|
|
|
*/
|
2012-05-17 15:16:51 +00:00
|
|
|
static HRESULT WINAPI OleAdviseHolderImpl_SendOnRename(IOleAdviseHolder *iface, IMoniker *pmk)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
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
|
|
|
|
*/
|
2012-05-17 15:16:51 +00:00
|
|
|
static HRESULT WINAPI OleAdviseHolderImpl_SendOnSave(IOleAdviseHolder *iface)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
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
|
|
|
|
*/
|
2012-05-17 15:16:51 +00:00
|
|
|
static HRESULT WINAPI OleAdviseHolderImpl_SendOnClose(IOleAdviseHolder *iface)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
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
|
|
|
|
*/
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
static IOleAdviseHolder *OleAdviseHolderImpl_Constructor(void)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
|
|
|
OleAdviseHolderImpl* lpoah;
|
|
|
|
|
|
|
|
lpoah = HeapAlloc(GetProcessHeap(), 0, sizeof(OleAdviseHolderImpl));
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
lpoah->IOleAdviseHolder_iface.lpVtbl = &oahvt;
|
2005-07-31 12:11:56 +00:00
|
|
|
lpoah->ref = 1;
|
2012-05-17 15:16:51 +00:00
|
|
|
lpoah->max_cons = INITIAL_SINKS;
|
|
|
|
lpoah->connections = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
|
|
|
lpoah->max_cons * sizeof(*lpoah->connections));
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
TRACE("returning %p\n", &lpoah->IOleAdviseHolder_iface);
|
|
|
|
return &lpoah->IOleAdviseHolder_iface;
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**************************************************************************
|
|
|
|
* DataAdviseHolder Implementation
|
|
|
|
*/
|
2012-05-17 15:16:51 +00:00
|
|
|
typedef struct
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
IDataAdviseHolder IDataAdviseHolder_iface;
|
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;
|
2012-05-17 15:16:51 +00:00
|
|
|
STATDATA* connections;
|
|
|
|
DWORD* remote_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
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
static inline DataAdviseHolder *impl_from_IDataAdviseHolder(IDataAdviseHolder *iface)
|
|
|
|
{
|
|
|
|
return CONTAINING_RECORD(iface, DataAdviseHolder, IDataAdviseHolder_iface);
|
|
|
|
}
|
|
|
|
|
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++)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
if (ptrToDestroy->connections[index].pAdvSink != NULL)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
2008-01-14 15:45:45 +00:00
|
|
|
if (ptrToDestroy->delegate &&
|
2012-05-17 15:16:51 +00:00
|
|
|
(ptrToDestroy->connections[index].advf & WINE_ADVF_REMOTE))
|
2007-04-20 12:23:52 +00:00
|
|
|
IDataObject_DUnadvise(ptrToDestroy->delegate,
|
2012-05-17 15:16:51 +00:00
|
|
|
ptrToDestroy->remote_connections[index]);
|
2007-04-20 12:23:52 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
release_statdata(ptrToDestroy->connections + index);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
HeapFree(GetProcessHeap(), 0, ptrToDestroy->remote_connections);
|
|
|
|
HeapFree(GetProcessHeap(), 0, ptrToDestroy->connections);
|
2005-07-31 12:11:56 +00:00
|
|
|
HeapFree(GetProcessHeap(), 0, ptrToDestroy);
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* DataAdviseHolder_QueryInterface (IUnknown)
|
|
|
|
*/
|
2012-05-17 15:16:51 +00:00
|
|
|
static HRESULT WINAPI DataAdviseHolder_QueryInterface(IDataAdviseHolder *iface,
|
|
|
|
REFIID riid, void **ppvObject)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
DataAdviseHolder *This = impl_from_IDataAdviseHolder(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppvObject);
|
2012-05-17 15:16:51 +00:00
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
if ( (This==0) || (ppvObject==0) )
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
|
|
|
*ppvObject = 0;
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((*ppvObject)==0)
|
|
|
|
{
|
|
|
|
return E_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
IUnknown_AddRef((IUnknown*)*ppvObject);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* DataAdviseHolder_AddRef (IUnknown)
|
|
|
|
*/
|
2012-05-17 15:16:51 +00:00
|
|
|
static ULONG WINAPI DataAdviseHolder_AddRef(IDataAdviseHolder *iface)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
DataAdviseHolder *This = impl_from_IDataAdviseHolder(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)
|
|
|
|
*/
|
2012-05-17 15:16:51 +00:00
|
|
|
static ULONG WINAPI DataAdviseHolder_Release(IDataAdviseHolder *iface)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
DataAdviseHolder *This = impl_from_IDataAdviseHolder(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
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) DataAdviseHolder_Destructor(This);
|
|
|
|
|
|
|
|
return ref;
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* DataAdviseHolder_Advise
|
|
|
|
*
|
|
|
|
*/
|
2012-05-17 15:16:51 +00:00
|
|
|
static HRESULT WINAPI DataAdviseHolder_Advise(IDataAdviseHolder *iface,
|
|
|
|
IDataObject *pDataObject, FORMATETC *pFetc,
|
|
|
|
DWORD advf, IAdviseSink *pAdvise,
|
|
|
|
DWORD *pdwConnection)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
|
|
|
DWORD index;
|
2012-05-17 15:16:51 +00:00
|
|
|
STATDATA new_conn;
|
|
|
|
DataAdviseHolder *This = impl_from_IDataAdviseHolder(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
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);
|
2012-05-17 15:16:51 +00:00
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
if (pdwConnection==NULL)
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
*pdwConnection = 0;
|
|
|
|
|
|
|
|
for (index = 0; index < This->maxCons; index++)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
if (This->connections[index].pAdvSink == NULL)
|
2005-07-31 12:11:56 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (index == This->maxCons)
|
|
|
|
{
|
|
|
|
This->maxCons+=INITIAL_SINKS;
|
2012-05-17 15:16:51 +00:00
|
|
|
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));
|
2007-04-20 12:23:52 +00:00
|
|
|
}
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
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);
|
2007-04-20 12:23:52 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
if (This->connections[index].pAdvSink != NULL)
|
|
|
|
{
|
2007-04-20 12:23:52 +00:00
|
|
|
/* if we are already connected advise the remote object */
|
|
|
|
if (This->delegate)
|
|
|
|
{
|
|
|
|
HRESULT hr;
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
hr = IDataObject_DAdvise(This->delegate, &new_conn.formatetc,
|
|
|
|
new_conn.advf, new_conn.pAdvSink,
|
|
|
|
&This->remote_connections[index]);
|
2007-04-20 12:23:52 +00:00
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
IDataAdviseHolder_Unadvise(iface, new_conn.dwConnection);
|
2007-04-20 12:23:52 +00:00
|
|
|
return hr;
|
|
|
|
}
|
2012-05-17 15:16:51 +00:00
|
|
|
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
|
|
|
}
|
2012-05-17 15:16:51 +00:00
|
|
|
|
|
|
|
*pdwConnection = new_conn.dwConnection;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* DataAdviseHolder_Unadvise
|
|
|
|
*/
|
2012-05-17 15:16:51 +00:00
|
|
|
static HRESULT WINAPI DataAdviseHolder_Unadvise(IDataAdviseHolder *iface,
|
|
|
|
DWORD dwConnection)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
DataAdviseHolder *This = impl_from_IDataAdviseHolder(iface);
|
|
|
|
DWORD index;
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p)->(%u)\n", This, dwConnection);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
/* The connection number is 1 more than the index, see DataAdviseHolder_Advise */
|
|
|
|
index = dwConnection - 1;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
if (index >= This->maxCons || This->connections[index].pAdvSink == NULL)
|
|
|
|
return OLE_E_NOCONNECTION;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
if (This->delegate && This->connections[index].advf & WINE_ADVF_REMOTE)
|
|
|
|
{
|
|
|
|
IDataObject_DUnadvise(This->delegate, This->remote_connections[index]);
|
|
|
|
This->remote_connections[index] = 0;
|
|
|
|
}
|
2007-04-20 12:23:52 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
release_statdata(This->connections + index);
|
2007-04-20 12:23:52 +00:00
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
/******************************************************************************
|
|
|
|
* DataAdviseHolder_EnumAdvise
|
|
|
|
*/
|
|
|
|
static HRESULT WINAPI DataAdviseHolder_EnumAdvise(IDataAdviseHolder *iface,
|
|
|
|
IEnumSTATDATA **enum_advise)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
DataAdviseHolder *This = impl_from_IDataAdviseHolder(iface);
|
|
|
|
IUnknown *unk;
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
TRACE("(%p)->(%p)\n", This, enum_advise);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
IDataAdviseHolder_QueryInterface(iface, &IID_IUnknown, (void**)&unk);
|
2017-06-03 22:33:33 +00:00
|
|
|
hr = EnumSTATDATA_Construct(unk, 0, This->maxCons, This->connections, TRUE, enum_advise);
|
2012-05-17 15:16:51 +00:00
|
|
|
IUnknown_Release(unk);
|
|
|
|
return hr;
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* DataAdviseHolder_SendOnDataChange
|
|
|
|
*/
|
2012-05-17 15:16:51 +00:00
|
|
|
static HRESULT WINAPI DataAdviseHolder_SendOnDataChange(IDataAdviseHolder *iface,
|
|
|
|
IDataObject *data_obj,
|
|
|
|
DWORD dwReserved, DWORD advf)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
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);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
2012-05-17 15:16:51 +00:00
|
|
|
|
|
|
|
return S_OK;
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**************************************************************************
|
|
|
|
* 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)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
DataAdviseHolder *This = impl_from_IDataAdviseHolder(iface);
|
2005-12-12 23:53:06 +00:00
|
|
|
DWORD index;
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
|
|
|
|
for(index = 0; index < This->maxCons; index++)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
if(This->connections[index].pAdvSink != NULL)
|
2005-12-12 23:53:06 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
hr = IDataObject_DAdvise(pDelegate, &This->connections[index].formatetc,
|
|
|
|
This->connections[index].advf,
|
|
|
|
This->connections[index].pAdvSink,
|
|
|
|
&This->remote_connections[index]);
|
2005-12-12 23:53:06 +00:00
|
|
|
if (FAILED(hr)) break;
|
2012-05-17 15:16:51 +00:00
|
|
|
This->connections[index].advf |= WINE_ADVF_REMOTE;
|
2005-12-12 23:53:06 +00:00
|
|
|
}
|
|
|
|
}
|
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)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
DataAdviseHolder *This = impl_from_IDataAdviseHolder(iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
DWORD index;
|
|
|
|
|
|
|
|
for(index = 0; index < This->maxCons; index++)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
if((This->connections[index].pAdvSink != NULL) &&
|
|
|
|
(This->connections[index].advf & WINE_ADVF_REMOTE))
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
IDataObject_DUnadvise(This->delegate, This->remote_connections[index]);
|
|
|
|
This->remote_connections[index] = 0;
|
|
|
|
This->connections[index].advf &= ~WINE_ADVF_REMOTE;
|
2007-04-20 12:23:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
This->delegate = NULL;
|
2005-12-12 23:53:06 +00:00
|
|
|
}
|
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
/******************************************************************************
|
|
|
|
* DataAdviseHolder_Constructor
|
|
|
|
*/
|
2012-05-17 15:16:51 +00:00
|
|
|
static IDataAdviseHolder *DataAdviseHolder_Constructor(void)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
|
|
|
DataAdviseHolder* newHolder;
|
|
|
|
|
|
|
|
newHolder = HeapAlloc(GetProcessHeap(), 0, sizeof(DataAdviseHolder));
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
newHolder->IDataAdviseHolder_iface.lpVtbl = &DataAdviseHolderImpl_VTable;
|
2005-07-31 12:11:56 +00:00
|
|
|
newHolder->ref = 1;
|
|
|
|
newHolder->maxCons = INITIAL_SINKS;
|
2012-05-17 15:16:51 +00:00
|
|
|
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));
|
2007-04-20 12:23:52 +00:00
|
|
|
newHolder->delegate = NULL;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
TRACE("returning %p\n", &newHolder->IDataAdviseHolder_iface);
|
|
|
|
return &newHolder->IDataAdviseHolder_iface;
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* API functions
|
|
|
|
*/
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* CreateOleAdviseHolder [OLE32.@]
|
|
|
|
*/
|
2012-05-17 15:16:51 +00:00
|
|
|
HRESULT WINAPI CreateOleAdviseHolder(IOleAdviseHolder **ppOAHolder)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
|
|
|
TRACE("(%p)\n", ppOAHolder);
|
|
|
|
|
|
|
|
if (ppOAHolder==NULL)
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
*ppOAHolder = OleAdviseHolderImpl_Constructor ();
|
|
|
|
|
|
|
|
if (*ppOAHolder != NULL)
|
|
|
|
return S_OK;
|
|
|
|
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* CreateDataAdviseHolder [OLE32.@]
|
|
|
|
*/
|
2012-05-17 15:16:51 +00:00
|
|
|
HRESULT WINAPI CreateDataAdviseHolder(IDataAdviseHolder **ppDAHolder)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
|
|
|
TRACE("(%p)\n", ppDAHolder);
|
|
|
|
|
|
|
|
if (ppDAHolder==NULL)
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
*ppDAHolder = DataAdviseHolder_Constructor();
|
|
|
|
|
|
|
|
if (*ppDAHolder != NULL)
|
|
|
|
return S_OK;
|
|
|
|
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
}
|