/*
 *	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
#define NONAMELESSSTRUCT

#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)
{
    if(data->formatetc.ptd)
    {
        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)
{
    *dst = *src;
    if(src->formatetc.ptd)
    {
        dst->formatetc.ptd = CoTaskMemAlloc(src->formatetc.ptd->tdSize);
        if(!dst->formatetc.ptd) return E_OUTOFMEMORY;
        memcpy(dst->formatetc.ptd, src->formatetc.ptd, src->formatetc.ptd->tdSize);
    }
    if(dst->pAdvSink) IAdviseSink_AddRef(dst->pAdvSink);
    return S_OK;
}

/**************************************************************************
 *  EnumSTATDATA Implementation
 */

static HRESULT EnumSTATDATA_Construct(IUnknown *holder, ULONG index, DWORD array_len, STATDATA *data, IEnumSTATDATA **ppenum);

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);
        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);

    return EnumSTATDATA_Construct(This->holder, This->index, This->num_of_elems, This->statdata, ppenum);
}

static const IEnumSTATDATAVtbl EnumSTATDATA_VTable =
{
    EnumSTATDATA_QueryInterface,
    EnumSTATDATA_AddRef,
    EnumSTATDATA_Release,
    EnumSTATDATA_Next,
    EnumSTATDATA_Skip,
    EnumSTATDATA_Reset,
    EnumSTATDATA_Clone
};

static HRESULT EnumSTATDATA_Construct(IUnknown *holder, ULONG index, DWORD array_len, STATDATA *data,
                                      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;

    This->statdata = HeapAlloc(GetProcessHeap(), 0, array_len * sizeof(*This->statdata));
    if(!This->statdata)
    {
        HeapFree(GetProcessHeap(), 0, This);
        return E_OUTOFMEMORY;
    }

    for(i = 0, count = 0; i < array_len; i++)
    {
        if(data[i].pAdvSink)
        {
            copy_statdata(This->statdata + count, data + i);
            count++;
        }
    }

    This->num_of_elems = count;
    This->holder = 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);
    hr = EnumSTATDATA_Construct(unk, 0, This->max_cons, This->connections, 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
 */
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;

  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);
    hr = EnumSTATDATA_Construct(unk, 0, This->maxCons, This->connections, 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
 */
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;
}
