/*
 *  OLE 2 clipboard support
 *
 *      Copyright 1999  Noel Borthwick <noel@macadamian.com>
 *      Copyright 2000  Abey George <abey@macadamian.com>
 *
 * 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
 *
 * NOTES:
 *    This file contains the implementation for the OLE Clipboard and its
 *    internal interfaces. The OLE clipboard interacts with an IDataObject
 *    interface via the OleSetClipboard, OleGetClipboard and
 *    OleIsCurrentClipboard API's. An internal IDataObject delegates
 *    to a client supplied IDataObject or the WIN32 clipboard API depending
 *    on whether OleSetClipboard has been invoked.
 *    Here are some operating scenarios:
 *
 *    1. OleSetClipboard called: In this case the internal IDataObject
 *       delegates to the client supplied IDataObject. Additionally OLE takes
 *       ownership of the Windows clipboard and any HGLOCBAL IDataObject
 *       items are placed on the Windows clipboard. This allows non OLE aware
 *       applications to access these. A local WinProc fields WM_RENDERFORMAT
 *       and WM_RENDERALLFORMATS messages in this case.
 *
 *    2. OleGetClipboard called without previous OleSetClipboard. Here the internal
 *       IDataObject functionality wraps around the WIN32 clipboard API.
 *
 *    3. OleGetClipboard called after previous OleSetClipboard. Here the internal
 *       IDataObject delegates to the source IDataObjects functionality directly,
 *       thereby bypassing the Windows clipboard.
 *
 *    Implementation references : Inside OLE 2'nd  edition by Kraig Brockschmidt
 *
 * TODO:
 *    - Support for pasting between different processes. OLE clipboard support
 *      currently works only for in process copy and paste. Since we internally
 *      store a pointer to the source's IDataObject and delegate to that, this
 *      will fail if the IDataObject client belongs to a different process.
 *    - IDataObject::GetDataHere is not implemented
 *    - OleFlushClipboard needs to additionally handle TYMED_IStorage media
 *      by copying the storage into global memory. Subsequently the default
 *      data object exposed through OleGetClipboard must convert this TYMED_HGLOBAL
 *      back to TYMED_IStorage.
 *    - OLE1 compatibility formats to be synthesized from OLE2 formats and put on
 *      clipboard in OleSetClipboard.
 *
 */

#include <assert.h>
#include <stdarg.h>
#include <string.h>
#include <stdio.h>

#define COBJMACROS
#define NONAMELESSUNION

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "winnls.h"
#include "ole2.h"
#include "wine/debug.h"
#include "olestd.h"

#include "storage32.h"

#include "compobj_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(ole);

/* Structure of 'Ole Private Data' clipboard format */
typedef struct
{
    FORMATETC fmtetc;
    DWORD first_use;  /* Has this cf been added to the list already */
    DWORD unk[2];
} ole_priv_data_entry;

typedef struct
{
    DWORD unk1;
    DWORD size; /* in bytes of the entire structure */
    DWORD unk2;
    DWORD count; /* no. of format entries */
    DWORD unk3[2];
    ole_priv_data_entry entries[1]; /* array of size count */
    /* then follows any DVTARGETDEVICE structures referenced in the FORMATETCs */
} ole_priv_data;

/*****************************************************************************
 *           td_offs_to_ptr
 *
 * Returns a ptr to a target device at a given offset from the
 * start of the ole_priv_data.
 *
 * Used when unpacking ole private data from the clipboard.
 */
static inline DVTARGETDEVICE *td_offs_to_ptr(ole_priv_data *data, DWORD_PTR off)
{
    if(off == 0) return NULL;
    return (DVTARGETDEVICE*)((char*)data + off);
}

/*****************************************************************************
 *           td_get_offs
 *
 * Get the offset from the start of the ole_priv_data of the idx'th
 * target device.
 *
 * Used when packing ole private data to the clipboard.
 */
static inline DWORD_PTR td_get_offs(ole_priv_data *data, DWORD idx)
{
    if(data->entries[idx].fmtetc.ptd == NULL) return 0;
    return (char*)data->entries[idx].fmtetc.ptd - (char*)data;
}

/****************************************************************************
 * Consumer snapshot.  Represents the state of the ole clipboard
 * returned by OleGetClipboard().
 */
typedef struct snapshot
{
    IDataObject IDataObject_iface;
    LONG ref;

    DWORD seq_no;                   /* Clipboard sequence number corresponding to this snapshot */

    IDataObject *data;              /* If we unmarshal a remote data object we hold a ref here */
} snapshot;

/****************************************************************************
 * ole_clipbrd
 */
typedef struct ole_clipbrd
{
    snapshot *latest_snapshot;       /* Latest consumer snapshot */

    HWND window;                     /* Hidden clipboard window */
    IDataObject *src_data;           /* Source object passed to OleSetClipboard */
    ole_priv_data *cached_enum;      /* Cached result from the enumeration of src data object */
    IStream *marshal_data;           /* Stream onto which to marshal src_data */
} ole_clipbrd;

static inline snapshot *impl_from_IDataObject(IDataObject *iface)
{
    return CONTAINING_RECORD(iface, snapshot, IDataObject_iface);
}

typedef struct PresentationDataHeader
{
  BYTE unknown1[28];
  DWORD dwObjectExtentX;
  DWORD dwObjectExtentY;
  DWORD dwSize;
} PresentationDataHeader;

/*
 * The one and only ole_clipbrd object which is created by OLEClipbrd_Initialize()
 */
static ole_clipbrd* theOleClipboard;

static CRITICAL_SECTION latest_snapshot_cs;
static CRITICAL_SECTION_DEBUG latest_snapshot_cs_debug =
{
        0, 0, &latest_snapshot_cs,
        { &latest_snapshot_cs_debug.ProcessLocksList, &latest_snapshot_cs_debug.ProcessLocksList },
        0, 0, { (DWORD_PTR)(__FILE__ ": clipboard last snapshot") }
};
static CRITICAL_SECTION latest_snapshot_cs = { &latest_snapshot_cs_debug, -1, 0, 0, 0, 0 };

static inline HRESULT get_ole_clipbrd(ole_clipbrd **clipbrd)
{
    struct oletls *info = COM_CurrentInfo();
    *clipbrd = NULL;

    if(!info->ole_inits)
        return CO_E_NOTINITIALIZED;
    *clipbrd = theOleClipboard;

    return S_OK;
}

/*
 * Name of our registered OLE clipboard window class
 */
static const WCHAR clipbrd_wndclass[] = {'C','L','I','P','B','R','D','W','N','D','C','L','A','S','S',0};

UINT ownerlink_clipboard_format = 0;
UINT filename_clipboard_format = 0;
UINT filenameW_clipboard_format = 0;
UINT dataobject_clipboard_format = 0;
UINT embedded_object_clipboard_format = 0;
UINT embed_source_clipboard_format = 0;
UINT custom_link_source_clipboard_format = 0;
UINT link_source_clipboard_format = 0;
UINT object_descriptor_clipboard_format = 0;
UINT link_source_descriptor_clipboard_format = 0;
UINT ole_private_data_clipboard_format = 0;

static UINT wine_marshal_clipboard_format;

static inline const char *dump_fmtetc(FORMATETC *fmt)
{
    if (!fmt) return "(null)";
    return wine_dbg_sprintf("cf %04x ptd %p aspect %x lindex %d tymed %x",
                            fmt->cfFormat, fmt->ptd, fmt->dwAspect, fmt->lindex, fmt->tymed);
}

/*---------------------------------------------------------------------*
 *  Implementation of the internal IEnumFORMATETC interface returned by
 *  the OLE clipboard's IDataObject.
 *---------------------------------------------------------------------*/

typedef struct enum_fmtetc
{
    IEnumFORMATETC IEnumFORMATETC_iface;
    LONG ref;

    UINT pos;    /* current enumerator position */
    ole_priv_data *data;
} enum_fmtetc;

static inline enum_fmtetc *impl_from_IEnumFORMATETC(IEnumFORMATETC *iface)
{
    return CONTAINING_RECORD(iface, enum_fmtetc, IEnumFORMATETC_iface);
}

/************************************************************************
 * OLEClipbrd_IEnumFORMATETC_QueryInterface (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 */
static HRESULT WINAPI OLEClipbrd_IEnumFORMATETC_QueryInterface
  (LPENUMFORMATETC iface, REFIID riid, LPVOID* ppvObj)
{
  enum_fmtetc *This = impl_from_IEnumFORMATETC(iface);

  TRACE("(%p)->(IID: %s, %p)\n", This, debugstr_guid(riid), ppvObj);

  *ppvObj = NULL;

  if(IsEqualIID(riid, &IID_IUnknown) ||
     IsEqualIID(riid, &IID_IEnumFORMATETC))
  {
    *ppvObj = iface;
  }

  if(*ppvObj)
  {
    IEnumFORMATETC_AddRef((IEnumFORMATETC*)*ppvObj);
    TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
    return S_OK;
  }

  TRACE("-- Interface: E_NOINTERFACE\n");
  return E_NOINTERFACE;
}

/************************************************************************
 * OLEClipbrd_IEnumFORMATETC_AddRef (IUnknown)
 *
 */
static ULONG WINAPI OLEClipbrd_IEnumFORMATETC_AddRef(LPENUMFORMATETC iface)
{
  enum_fmtetc *This = impl_from_IEnumFORMATETC(iface);
  TRACE("(%p)->(count=%u)\n",This, This->ref);

  return InterlockedIncrement(&This->ref);
}

/************************************************************************
 * OLEClipbrd_IEnumFORMATETC_Release (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 */
static ULONG WINAPI OLEClipbrd_IEnumFORMATETC_Release(LPENUMFORMATETC iface)
{
  enum_fmtetc *This = impl_from_IEnumFORMATETC(iface);
  ULONG ref;

  TRACE("(%p)->(count=%u)\n",This, This->ref);

  ref = InterlockedDecrement(&This->ref);
  if (!ref)
  {
    TRACE("() - destroying IEnumFORMATETC(%p)\n",This);
    HeapFree(GetProcessHeap(), 0, This->data);
    HeapFree(GetProcessHeap(), 0, This);
  }
  return ref;
}

/************************************************************************
 * OLEClipbrd_IEnumFORMATETC_Next (IEnumFORMATETC)
 *
 * Standard enumerator members for IEnumFORMATETC
 */
static HRESULT WINAPI OLEClipbrd_IEnumFORMATETC_Next
  (LPENUMFORMATETC iface, ULONG celt, FORMATETC *rgelt, ULONG *pceltFethed)
{
  enum_fmtetc *This = impl_from_IEnumFORMATETC(iface);
  UINT cfetch, i;
  HRESULT hres = S_FALSE;

  TRACE("(%p)->(pos=%u)\n", This, This->pos);

  if (This->pos < This->data->count)
  {
    cfetch = This->data->count - This->pos;
    if (cfetch >= celt)
    {
      cfetch = celt;
      hres = S_OK;
    }

    for(i = 0; i < cfetch; i++)
    {
      rgelt[i] = This->data->entries[This->pos++].fmtetc;
      if(rgelt[i].ptd)
      {
        DVTARGETDEVICE *target = rgelt[i].ptd;
        rgelt[i].ptd = CoTaskMemAlloc(target->tdSize);
        if(!rgelt[i].ptd) return E_OUTOFMEMORY;
        memcpy(rgelt[i].ptd, target, target->tdSize);
      }
    }
  }
  else
  {
    cfetch = 0;
  }

  if (pceltFethed)
  {
    *pceltFethed = cfetch;
  }

  return hres;
}

/************************************************************************
 * OLEClipbrd_IEnumFORMATETC_Skip (IEnumFORMATETC)
 *
 * Standard enumerator members for IEnumFORMATETC
 */
static HRESULT WINAPI OLEClipbrd_IEnumFORMATETC_Skip(LPENUMFORMATETC iface, ULONG celt)
{
  enum_fmtetc *This = impl_from_IEnumFORMATETC(iface);
  TRACE("(%p)->(num=%u)\n", This, celt);

  This->pos += celt;
  if (This->pos > This->data->count)
  {
    This->pos = This->data->count;
    return S_FALSE;
  }
  return S_OK;
}

/************************************************************************
 * OLEClipbrd_IEnumFORMATETC_Reset (IEnumFORMATETC)
 *
 * Standard enumerator members for IEnumFORMATETC
 */
static HRESULT WINAPI OLEClipbrd_IEnumFORMATETC_Reset(LPENUMFORMATETC iface)
{
  enum_fmtetc *This = impl_from_IEnumFORMATETC(iface);
  TRACE("(%p)->()\n", This);

  This->pos = 0;
  return S_OK;
}

static HRESULT enum_fmtetc_construct(ole_priv_data *data, UINT pos, IEnumFORMATETC **obj);

/************************************************************************
 * OLEClipbrd_IEnumFORMATETC_Clone (IEnumFORMATETC)
 *
 * Standard enumerator members for IEnumFORMATETC
 */
static HRESULT WINAPI OLEClipbrd_IEnumFORMATETC_Clone
  (LPENUMFORMATETC iface, LPENUMFORMATETC* obj)
{
  enum_fmtetc *This = impl_from_IEnumFORMATETC(iface);
  ole_priv_data *new_data;
  DWORD i;

  TRACE("(%p)->(%p)\n", This, obj);

  if ( !obj ) return E_INVALIDARG;
  *obj = NULL;

  new_data = HeapAlloc(GetProcessHeap(), 0, This->data->size);
  if(!new_data) return E_OUTOFMEMORY;
  memcpy(new_data, This->data, This->data->size);

  /* Fixup any target device ptrs */
  for(i = 0; i < This->data->count; i++)
      new_data->entries[i].fmtetc.ptd =
          td_offs_to_ptr(new_data, td_get_offs(This->data, i));

  return enum_fmtetc_construct(new_data, This->pos, obj);
}

static const IEnumFORMATETCVtbl efvt =
{
  OLEClipbrd_IEnumFORMATETC_QueryInterface,
  OLEClipbrd_IEnumFORMATETC_AddRef,
  OLEClipbrd_IEnumFORMATETC_Release,
  OLEClipbrd_IEnumFORMATETC_Next,
  OLEClipbrd_IEnumFORMATETC_Skip,
  OLEClipbrd_IEnumFORMATETC_Reset,
  OLEClipbrd_IEnumFORMATETC_Clone
};

/************************************************************************
 * enum_fmtetc_construct
 *
 * Creates an IEnumFORMATETC enumerator from ole_priv_data which it then owns.
 */
static HRESULT enum_fmtetc_construct(ole_priv_data *data, UINT pos, IEnumFORMATETC **obj)
{
  enum_fmtetc* ef;

  *obj = NULL;
  ef = HeapAlloc(GetProcessHeap(), 0, sizeof(*ef));
  if (!ef) return E_OUTOFMEMORY;

  ef->ref = 1;
  ef->IEnumFORMATETC_iface.lpVtbl = &efvt;
  ef->data = data;
  ef->pos = pos;

  TRACE("(%p)->()\n", ef);
  *obj = &ef->IEnumFORMATETC_iface;
  return S_OK;
}

/***********************************************************************
 *                    dup_global_mem
 *
 * Helper method to duplicate an HGLOBAL chunk of memory
 */
static HRESULT dup_global_mem( HGLOBAL src, DWORD flags, HGLOBAL *dst )
{
    void *src_ptr, *dst_ptr;
    DWORD size;

    *dst = NULL;
    if ( !src ) return S_FALSE;

    size = GlobalSize(src);

    *dst = GlobalAlloc( flags, size );
    if ( !*dst ) return E_OUTOFMEMORY;

    src_ptr = GlobalLock(src);
    dst_ptr = GlobalLock(*dst);

    memcpy(dst_ptr, src_ptr, size);

    GlobalUnlock(*dst);
    GlobalUnlock(src);

    return S_OK;
}

/***********************************************************************
 *                    dup_metafilepict
 *
 * Helper function to duplicate a handle to a METAFILEPICT, and the
 * contained HMETAFILE.
 */
static HRESULT dup_metafilepict(HGLOBAL src, HGLOBAL *pdest)
{
    HRESULT hr;
    HGLOBAL dest;
    METAFILEPICT *dest_ptr;

    *pdest = NULL;

    /* Copy the METAFILEPICT structure. */
    hr = dup_global_mem(src, GMEM_DDESHARE|GMEM_MOVEABLE, &dest);
    if (FAILED(hr)) return hr;

    dest_ptr = GlobalLock(dest);
    if (!dest_ptr) return E_FAIL;

    /* Give the new METAFILEPICT a separate HMETAFILE. */
    dest_ptr->hMF = CopyMetaFileW(dest_ptr->hMF, NULL);
    if (dest_ptr->hMF)
    {
       GlobalUnlock(dest);
       *pdest = dest;
       return S_OK;
    }
    else
    {
       GlobalUnlock(dest);
       GlobalFree(dest);
       return E_FAIL;
    }
}

/***********************************************************************
 *                    free_metafilepict
 *
 * Helper function to GlobalFree a handle to a METAFILEPICT, and also
 * free the contained HMETAFILE.
 */
static void free_metafilepict(HGLOBAL src)
{
    METAFILEPICT *src_ptr;

    src_ptr = GlobalLock(src);
    if (src_ptr)
    {
        DeleteMetaFile(src_ptr->hMF);
        GlobalUnlock(src);
    }
    GlobalFree(src);
}

/***********************************************************************
 *                    dup_bitmap
 *
 * Helper function to duplicate an HBITMAP.
 */
static HRESULT dup_bitmap(HBITMAP src, HBITMAP *pdest)
{
    HDC src_dc;
    HGDIOBJ orig_src_bitmap;
    BITMAP bm;
    HBITMAP dest;

    src_dc = CreateCompatibleDC(NULL);
    orig_src_bitmap = SelectObject(src_dc, src);
    GetObjectW(src, sizeof bm, &bm);
    dest = CreateCompatibleBitmap(src_dc, bm.bmWidth, bm.bmHeight);
    if (dest)
    {
        HDC dest_dc = CreateCompatibleDC(NULL);
        HGDIOBJ orig_dest_bitmap = SelectObject(dest_dc, dest);
        BitBlt(dest_dc, 0, 0, bm.bmWidth, bm.bmHeight, src_dc, 0, 0, SRCCOPY);
        SelectObject(dest_dc, orig_dest_bitmap);
        DeleteDC(dest_dc);
    }
    SelectObject(src_dc, orig_src_bitmap);
    DeleteDC(src_dc);
    *pdest = dest;
    return dest ? S_OK : E_FAIL;
}

/************************************************************
 *              render_embed_source_hack
 *
 * This is clearly a hack and has no place in the clipboard code.
 *
 */
static HRESULT render_embed_source_hack(IDataObject *data, LPFORMATETC fmt)
{
    STGMEDIUM std;
    HGLOBAL hStorage = 0;
    HRESULT hr = S_OK;
    ILockBytes *ptrILockBytes;

    memset(&std, 0, sizeof(STGMEDIUM));
    std.tymed = fmt->tymed = TYMED_ISTORAGE;

    hStorage = GlobalAlloc(GMEM_SHARE|GMEM_MOVEABLE, 0);
    if (hStorage == NULL) return E_OUTOFMEMORY;
    hr = CreateILockBytesOnHGlobal(hStorage, FALSE, &ptrILockBytes);
    if (FAILED(hr))
    {
        GlobalFree(hStorage);
        return hr;
    }

    hr = StgCreateDocfileOnILockBytes(ptrILockBytes, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &std.u.pstg);
    ILockBytes_Release(ptrILockBytes);

    if (FAILED(hr = IDataObject_GetDataHere(theOleClipboard->src_data, fmt, &std)))
    {
        WARN("() : IDataObject_GetDataHere failed to render clipboard data! (%x)\n", hr);
        GlobalFree(hStorage);
        return hr;
    }

    if (1) /* check whether the presentation data is already -not- present */
    {
        FORMATETC fmt2;
        STGMEDIUM std2;
        METAFILEPICT *mfp = 0;

        fmt2.cfFormat = CF_METAFILEPICT;
        fmt2.ptd = 0;
        fmt2.dwAspect = DVASPECT_CONTENT;
        fmt2.lindex = -1;
        fmt2.tymed = TYMED_MFPICT;

        memset(&std2, 0, sizeof(STGMEDIUM));
        std2.tymed = TYMED_MFPICT;

        /* Get the metafile picture out of it */

        if (SUCCEEDED(hr = IDataObject_GetData(theOleClipboard->src_data, &fmt2, &std2)))
        {
            mfp = GlobalLock(std2.u.hGlobal);
        }

        if (mfp)
        {
            OLECHAR name[]={ 2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0};
            IStream *pStream = 0;
            void *mfBits;
            PresentationDataHeader pdh;
            INT nSize;
            CLSID clsID;
            LPOLESTR strProgID;
            CHAR strOleTypeName[51];
            BYTE OlePresStreamHeader [] =
            {
                0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
                0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00
            };

            nSize = GetMetaFileBitsEx(mfp->hMF, 0, NULL);

            memset(&pdh, 0, sizeof(PresentationDataHeader));
            memcpy(&pdh, OlePresStreamHeader, sizeof(OlePresStreamHeader));

            pdh.dwObjectExtentX = mfp->xExt;
            pdh.dwObjectExtentY = mfp->yExt;
            pdh.dwSize = nSize;

            hr = IStorage_CreateStream(std.u.pstg, name, STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, 0, &pStream);

            hr = IStream_Write(pStream, &pdh, sizeof(PresentationDataHeader), NULL);

            mfBits = HeapAlloc(GetProcessHeap(), 0, nSize);
            nSize = GetMetaFileBitsEx(mfp->hMF, nSize, mfBits);

            hr = IStream_Write(pStream, mfBits, nSize, NULL);

            IStream_Release(pStream);

            HeapFree(GetProcessHeap(), 0, mfBits);

            GlobalUnlock(std2.u.hGlobal);
            ReleaseStgMedium(&std2);

            ReadClassStg(std.u.pstg, &clsID);
            ProgIDFromCLSID(&clsID, &strProgID);

            WideCharToMultiByte( CP_ACP, 0, strProgID, -1, strOleTypeName, sizeof(strOleTypeName), NULL, NULL );
            STORAGE_CreateOleStream(std.u.pstg, 0);
            OLECONVERT_CreateCompObjStream(std.u.pstg, strOleTypeName);
            CoTaskMemFree(strProgID);
        }
    }

    if ( !SetClipboardData( fmt->cfFormat, hStorage ) )
    {
        WARN("() : Failed to set rendered clipboard data into clipboard!\n");
        GlobalFree(hStorage);
        hr = CLIPBRD_E_CANT_SET;
    }

    ReleaseStgMedium(&std);
    return hr;
}

/************************************************************************
 *           find_format_in_list
 *
 * Returns the first entry that matches the provided clipboard format.
 */
static inline ole_priv_data_entry *find_format_in_list(ole_priv_data_entry *entries, DWORD num, UINT cf)
{
    DWORD i;
    for(i = 0; i < num; i++)
        if(entries[i].fmtetc.cfFormat == cf)
            return &entries[i];

    return NULL;
}

/***************************************************************************
 *         get_data_from_storage
 *
 * Returns storage data in an HGLOBAL.
 */
static HRESULT get_data_from_storage(IDataObject *data, FORMATETC *fmt, HGLOBAL *mem)
{
    HGLOBAL h;
    IStorage *stg;
    HRESULT hr;
    FORMATETC stg_fmt;
    STGMEDIUM med;
    ILockBytes *lbs;

    *mem = NULL;

    h = GlobalAlloc( GMEM_DDESHARE|GMEM_MOVEABLE, 0 );
    if(!h) return E_OUTOFMEMORY;

    hr = CreateILockBytesOnHGlobal(h, FALSE, &lbs);
    if(SUCCEEDED(hr))
    {
        hr = StgCreateDocfileOnILockBytes(lbs, STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stg);
        ILockBytes_Release(lbs);
    }
    if(FAILED(hr))
    {
        GlobalFree(h);
        return hr;
    }

    stg_fmt = *fmt;
    med.tymed = stg_fmt.tymed = TYMED_ISTORAGE;
    med.u.pstg = stg;
    med.pUnkForRelease = NULL;

    hr = IDataObject_GetDataHere(data, &stg_fmt, &med);
    if(FAILED(hr))
    {
        med.u.pstg = NULL;
        hr = IDataObject_GetData(data, &stg_fmt, &med);
        if(FAILED(hr)) goto end;

        hr = IStorage_CopyTo(med.u.pstg, 0, NULL, NULL, stg);
        ReleaseStgMedium(&med);
        if(FAILED(hr)) goto end;
    }
    *mem = h;

end:
    IStorage_Release(stg);
    if(FAILED(hr)) GlobalFree(h);
    return hr;
}

/***************************************************************************
 *         get_data_from_stream
 *
 * Returns stream data in an HGLOBAL.
 */
static HRESULT get_data_from_stream(IDataObject *data, FORMATETC *fmt, HGLOBAL *mem)
{
    HGLOBAL h;
    IStream *stm = NULL;
    HRESULT hr;
    FORMATETC stm_fmt;
    STGMEDIUM med;

    *mem = NULL;

    h = GlobalAlloc( GMEM_DDESHARE|GMEM_MOVEABLE, 0 );
    if(!h) return E_OUTOFMEMORY;

    hr = CreateStreamOnHGlobal(h, FALSE, &stm);
    if(FAILED(hr)) goto error;

    stm_fmt = *fmt;
    med.tymed = stm_fmt.tymed = TYMED_ISTREAM;
    med.u.pstm = stm;
    med.pUnkForRelease = NULL;

    hr = IDataObject_GetDataHere(data, &stm_fmt, &med);
    if(FAILED(hr))
    {
        LARGE_INTEGER offs;
        ULARGE_INTEGER pos;

        med.u.pstm = NULL;
        hr = IDataObject_GetData(data, &stm_fmt, &med);
        if(FAILED(hr)) goto error;

        offs.QuadPart = 0;
        IStream_Seek(med.u.pstm, offs, STREAM_SEEK_CUR, &pos);
        IStream_Seek(med.u.pstm, offs, STREAM_SEEK_SET, NULL);
        hr = IStream_CopyTo(med.u.pstm, stm, pos, NULL, NULL);
        ReleaseStgMedium(&med);
        if(FAILED(hr)) goto error;
    }
    *mem = h;
    IStream_Release(stm);
    return S_OK;

error:
    if(stm) IStream_Release(stm);
    GlobalFree(h);
    return hr;
}

/***************************************************************************
 *         get_data_from_global
 *
 * Returns global data in an HGLOBAL.
 */
static HRESULT get_data_from_global(IDataObject *data, FORMATETC *fmt, HGLOBAL *mem)
{
    HGLOBAL h;
    HRESULT hr;
    FORMATETC mem_fmt;
    STGMEDIUM med;

    *mem = NULL;

    mem_fmt = *fmt;
    mem_fmt.tymed = TYMED_HGLOBAL;

    hr = IDataObject_GetData(data, &mem_fmt, &med);
    if(FAILED(hr)) return hr;

    hr = dup_global_mem(med.u.hGlobal, GMEM_DDESHARE|GMEM_MOVEABLE, &h);

    if(SUCCEEDED(hr)) *mem = h;

    ReleaseStgMedium(&med);

    return hr;
}

/***************************************************************************
 *         get_data_from_enhmetafile
 */
static HRESULT get_data_from_enhmetafile(IDataObject *data, FORMATETC *fmt, HGLOBAL *mem)
{
    HENHMETAFILE copy;
    HRESULT hr;
    FORMATETC mem_fmt;
    STGMEDIUM med;

    *mem = NULL;

    mem_fmt = *fmt;
    mem_fmt.tymed = TYMED_ENHMF;

    hr = IDataObject_GetData(data, &mem_fmt, &med);
    if(FAILED(hr)) return hr;

    copy = CopyEnhMetaFileW(med.u.hEnhMetaFile, NULL);
    if(copy) *mem = (HGLOBAL)copy;
    else hr = E_FAIL;

    ReleaseStgMedium(&med);

    return hr;
}

/***************************************************************************
 *         get_data_from_metafilepict
 */
static HRESULT get_data_from_metafilepict(IDataObject *data, FORMATETC *fmt, HGLOBAL *mem)
{
    HGLOBAL copy;
    HRESULT hr;
    FORMATETC mem_fmt;
    STGMEDIUM med;

    *mem = NULL;

    mem_fmt = *fmt;
    mem_fmt.tymed = TYMED_MFPICT;

    hr = IDataObject_GetData(data, &mem_fmt, &med);
    if(FAILED(hr)) return hr;

    hr = dup_metafilepict(med.u.hMetaFilePict, &copy);

    if(SUCCEEDED(hr)) *mem = copy;

    ReleaseStgMedium(&med);

    return hr;
}

/***************************************************************************
 *         get_data_from_bitmap
 *
 * Returns bitmap in an HBITMAP.
 */
static HRESULT get_data_from_bitmap(IDataObject *data, FORMATETC *fmt, HBITMAP *hbm)
{
    HBITMAP copy;
    HRESULT hr;
    FORMATETC mem_fmt;
    STGMEDIUM med;

    *hbm = NULL;

    mem_fmt = *fmt;
    mem_fmt.tymed = TYMED_GDI;

    hr = IDataObject_GetData(data, &mem_fmt, &med);
    if(FAILED(hr)) return hr;

    hr = dup_bitmap(med.u.hBitmap, &copy);

    if(SUCCEEDED(hr)) *hbm = copy;

    ReleaseStgMedium(&med);

    return hr;
}

/***********************************************************************
 *                render_format
 *
 * Render the clipboard data. Note that this call will delegate to the
 * source data object.
 */
static HRESULT render_format(IDataObject *data, LPFORMATETC fmt)
{
    HANDLE clip_data = NULL;  /* HGLOBAL unless otherwise specified */
    HRESULT hr;

    /* Embed source hack */
    if(fmt->cfFormat == embed_source_clipboard_format)
    {
        return render_embed_source_hack(data, fmt);
    }

    if(fmt->tymed & TYMED_ISTORAGE)
    {
        hr = get_data_from_storage(data, fmt, &clip_data);
    }
    else if(fmt->tymed & TYMED_ISTREAM)
    {
        hr = get_data_from_stream(data, fmt, &clip_data);
    }
    else if(fmt->tymed & TYMED_HGLOBAL)
    {
        hr = get_data_from_global(data, fmt, &clip_data);
    }
    else if(fmt->tymed & TYMED_ENHMF)
    {
        hr = get_data_from_enhmetafile(data, fmt, &clip_data);
    }
    else if(fmt->tymed & TYMED_MFPICT)
    {
        /* Returns global handle to METAFILEPICT, containing a copied HMETAFILE */
        hr = get_data_from_metafilepict(data, fmt, &clip_data);
    }
    else if(fmt->tymed & TYMED_GDI)
    {
        /* Returns HBITMAP not HGLOBAL */
        hr = get_data_from_bitmap(data, fmt, (HBITMAP *)&clip_data);
    }
    else
    {
        FIXME("Unhandled tymed %x\n", fmt->tymed);
        hr = DV_E_FORMATETC;
    }

    if(SUCCEEDED(hr))
    {
        if ( !SetClipboardData(fmt->cfFormat, clip_data) )
        {
            WARN("() : Failed to set rendered clipboard data into clipboard!\n");
            if(fmt->tymed & TYMED_MFPICT)
                free_metafilepict(clip_data);
            else if(fmt->tymed & TYMED_GDI)
                DeleteObject(clip_data);
            else
                GlobalFree(clip_data);
            hr = CLIPBRD_E_CANT_SET;
        }
    }

    return hr;
}

/*---------------------------------------------------------------------*
 *  Implementation of the internal IDataObject interface exposed by
 *  the OLE clipboard.
 *---------------------------------------------------------------------*/


/************************************************************************
 *           snapshot_QueryInterface
 */
static HRESULT WINAPI snapshot_QueryInterface(IDataObject *iface,
                                              REFIID riid, void **ppvObject)
{
  snapshot *This = impl_from_IDataObject(iface);
  TRACE("(%p)->(IID:%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_IDataObject, riid))
  {
    *ppvObject = iface;
  }
  else
  {
    WARN( "() : asking for unsupported interface %s\n", debugstr_guid(riid));
    return E_NOINTERFACE;
  }

  IUnknown_AddRef((IUnknown*)*ppvObject);

  return S_OK;
}

/************************************************************************
 *              snapshot_AddRef
 */
static ULONG WINAPI snapshot_AddRef(IDataObject *iface)
{
    snapshot *This = impl_from_IDataObject(iface);

    TRACE("(%p)->(count=%u)\n", This, This->ref);

    return InterlockedIncrement(&This->ref);
}

/************************************************************************
 *      snapshot_Release
 */
static ULONG WINAPI snapshot_Release(IDataObject *iface)
{
    snapshot *This = impl_from_IDataObject(iface);
    ULONG ref;

    TRACE("(%p)->(count=%u)\n", This, This->ref);

    ref = InterlockedDecrement(&This->ref);

    if (ref == 0)
    {
        EnterCriticalSection(&latest_snapshot_cs);
        if (This->ref)
        {
            LeaveCriticalSection(&latest_snapshot_cs);
            return ref;
        }
        if (theOleClipboard->latest_snapshot == This)
            theOleClipboard->latest_snapshot = NULL;
        LeaveCriticalSection(&latest_snapshot_cs);

        if(This->data) IDataObject_Release(This->data);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

/************************************************************
 *              get_current_ole_clip_window
 *
 * Return the window that owns the ole clipboard.
 *
 * If the clipboard is flushed or not owned by ole this will
 * return NULL.
 */
static HWND get_current_ole_clip_window(void)
{
    HGLOBAL h;
    HWND *ptr, wnd;

    h = GetClipboardData(dataobject_clipboard_format);
    if(!h) return NULL;
    ptr = GlobalLock(h);
    if(!ptr) return NULL;
    wnd = *ptr;
    GlobalUnlock(h);
    return wnd;
}

/************************************************************
 *              get_current_dataobject
 *
 * Return an unmarshalled IDataObject if there is a current
 * (ie non-flushed) object on the ole clipboard.
 */
static HRESULT get_current_dataobject(IDataObject **data)
{
    HRESULT hr = S_FALSE;
    HWND wnd = get_current_ole_clip_window();
    HGLOBAL h;
    void *ptr;
    IStream *stm;
    LARGE_INTEGER pos;

    *data = NULL;
    if(!wnd) return S_FALSE;

    h = GetClipboardData(wine_marshal_clipboard_format);
    if(!h) return S_FALSE;
    if(GlobalSize(h) <= 1) return S_FALSE;
    ptr = GlobalLock(h);
    if(!ptr) return S_FALSE;

    hr = CreateStreamOnHGlobal(NULL, TRUE, &stm);
    if(FAILED(hr)) goto end;

    hr = IStream_Write(stm, ptr, GlobalSize(h), NULL);
    if(SUCCEEDED(hr))
    {
        pos.QuadPart = 0;
        IStream_Seek(stm, pos, STREAM_SEEK_SET, NULL);
        hr = CoUnmarshalInterface(stm, &IID_IDataObject, (void**)data);
    }
    IStream_Release(stm);

end:
    GlobalUnlock(h);
    return hr;
}

static DWORD get_tymed_from_nonole_cf(UINT cf)
{
    if(cf >= 0xc000) return TYMED_ISTREAM | TYMED_HGLOBAL;

    switch(cf)
    {
    case CF_TEXT:
    case CF_OEMTEXT:
    case CF_UNICODETEXT:
        return TYMED_ISTREAM | TYMED_HGLOBAL;
    case CF_ENHMETAFILE:
        return TYMED_ENHMF;
    case CF_METAFILEPICT:
        return TYMED_MFPICT;
    case CF_BITMAP:
        return TYMED_GDI;
    default:
        FIXME("returning TYMED_NULL for cf %04x\n", cf);
        return TYMED_NULL;
    }
}

/***********************************************************
 *     get_priv_data
 *
 * Returns a copy of the Ole Private Data
 */
static HRESULT get_priv_data(ole_priv_data **data)
{
    HGLOBAL handle;
    HRESULT hr = S_OK;
    ole_priv_data *ret = NULL;

    *data = NULL;

    handle = GetClipboardData( ole_private_data_clipboard_format );
    if(handle)
    {
        ole_priv_data *src = GlobalLock(handle);
        if(src)
        {
            DWORD i;

            /* FIXME: sanity check on size */
            ret = HeapAlloc(GetProcessHeap(), 0, src->size);
            if(!ret)
            {
                GlobalUnlock(handle);
                return E_OUTOFMEMORY;
            }
            memcpy(ret, src, src->size);
            GlobalUnlock(handle);

            /* Fixup any target device offsets to ptrs */
            for(i = 0; i < ret->count; i++)
                ret->entries[i].fmtetc.ptd =
                    td_offs_to_ptr(ret, (DWORD_PTR) ret->entries[i].fmtetc.ptd);
        }
    }

    if(!ret) /* Non-ole data */
    {
        UINT cf;
        DWORD count = 0, idx, size = FIELD_OFFSET(ole_priv_data, entries);

        for(cf = 0; (cf = EnumClipboardFormats(cf)) != 0; count++)
        {
            WCHAR buf[256];
            if (GetClipboardFormatNameW(cf, buf, sizeof(buf) / sizeof(WCHAR)))
                TRACE("cf %04x %s\n", cf, debugstr_w(buf));
            else
                TRACE("cf %04x\n", cf);
        }
        TRACE("count %d\n", count);
        size += count * sizeof(ret->entries[0]);

        /* There are holes in fmtetc so zero init */
        ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
        if(!ret) return E_OUTOFMEMORY;
        ret->size = size;
        ret->count = count;

        for(cf = 0, idx = 0; (cf = EnumClipboardFormats(cf)) != 0; idx++)
        {
            ret->entries[idx].fmtetc.cfFormat = cf;
            ret->entries[idx].fmtetc.ptd = NULL;
            ret->entries[idx].fmtetc.dwAspect = DVASPECT_CONTENT;
            ret->entries[idx].fmtetc.lindex = -1;
            ret->entries[idx].fmtetc.tymed = get_tymed_from_nonole_cf(cf);
            ret->entries[idx].first_use = 1;
        }
    }

    *data = ret;
    return hr;
}

/************************************************************************
 *                    get_stgmed_for_global
 *
 * Returns a stg medium with a copy of the global handle
 */
static HRESULT get_stgmed_for_global(HGLOBAL h, STGMEDIUM *med)
{
    HRESULT hr;

    med->pUnkForRelease = NULL;
    med->tymed = TYMED_NULL;

    hr = dup_global_mem(h, GMEM_MOVEABLE, &med->u.hGlobal);

    if(SUCCEEDED(hr)) med->tymed = TYMED_HGLOBAL;

    return hr;
}

/************************************************************************
 *                    get_stgmed_for_stream
 *
 * Returns a stg medium with a stream based on the handle
 */
static HRESULT get_stgmed_for_stream(HGLOBAL h, STGMEDIUM *med)
{
    HRESULT hr;
    HGLOBAL dst;

    med->pUnkForRelease = NULL;
    med->tymed = TYMED_NULL;

    hr = dup_global_mem(h, GMEM_MOVEABLE, &dst);
    if(FAILED(hr)) return hr;

    hr = CreateStreamOnHGlobal(dst, TRUE, &med->u.pstm);
    if(FAILED(hr))
    {
        GlobalFree(dst);
        return hr;
    }

    med->tymed = TYMED_ISTREAM;
    return hr;
}

/************************************************************************
 *                    get_stgmed_for_storage
 *
 * Returns a stg medium with a storage based on the handle
 */
static HRESULT get_stgmed_for_storage(HGLOBAL h, STGMEDIUM *med)
{
    HRESULT hr;
    HGLOBAL dst;
    ILockBytes *lbs;

    med->pUnkForRelease = NULL;
    med->tymed = TYMED_NULL;

    hr = dup_global_mem(h, GMEM_MOVEABLE, &dst);
    if(FAILED(hr)) return hr;

    hr = CreateILockBytesOnHGlobal(dst, TRUE, &lbs);
    if(FAILED(hr))
    {
        GlobalFree(dst);
        return hr;
    }

    hr = StgOpenStorageOnILockBytes(lbs, NULL,  STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &med->u.pstg);
    ILockBytes_Release(lbs);
    if(FAILED(hr))
    {
        GlobalFree(dst);
        return hr;
    }

    med->tymed = TYMED_ISTORAGE;
    return hr;
}

/************************************************************************
 *                    get_stgmed_for_emf
 *
 * Returns a stg medium with an enhanced metafile based on the handle
 */
static HRESULT get_stgmed_for_emf(HENHMETAFILE hemf, STGMEDIUM *med)
{
    med->pUnkForRelease = NULL;
    med->tymed = TYMED_NULL;

    med->u.hEnhMetaFile = CopyEnhMetaFileW(hemf, NULL);
    if(!med->u.hEnhMetaFile) return E_OUTOFMEMORY;
    med->tymed = TYMED_ENHMF;
    return S_OK;
}

/************************************************************************
 *                    get_stgmed_for_bitmap
 *
 * Returns a stg medium with a bitmap based on the handle
 */
static HRESULT get_stgmed_for_bitmap(HBITMAP hbmp, STGMEDIUM *med)
{
    HRESULT hr;

    med->pUnkForRelease = NULL;
    med->tymed = TYMED_NULL;

    hr = dup_bitmap(hbmp, &med->u.hBitmap);

    if (FAILED(hr))
        return hr;

    med->tymed = TYMED_GDI;
    return S_OK;
}

static inline BOOL string_off_equal(const DVTARGETDEVICE *t1, WORD off1, const DVTARGETDEVICE *t2, WORD off2)
{
    const WCHAR *str1, *str2;

    if(off1 == 0 && off2 == 0) return TRUE;
    if(off1 == 0 || off2 == 0) return FALSE;

    str1 = (const WCHAR*)((const char*)t1 + off1);
    str2 = (const WCHAR*)((const char*)t2 + off2);

    return !lstrcmpW(str1, str2);
}

static inline BOOL td_equal(const DVTARGETDEVICE *t1, const DVTARGETDEVICE *t2)
{
    if(t1 == NULL && t2 == NULL) return TRUE;
    if(t1 == NULL || t2 == NULL) return FALSE;

    if(!string_off_equal(t1, t1->tdDriverNameOffset, t2, t2->tdDriverNameOffset))
        return FALSE;
    if(!string_off_equal(t1, t1->tdDeviceNameOffset, t2, t2->tdDeviceNameOffset))
        return FALSE;
    if(!string_off_equal(t1, t1->tdPortNameOffset, t2, t2->tdPortNameOffset))
        return FALSE;

    /* FIXME check devmode? */

    return TRUE;
}

/************************************************************************
 *         snapshot_GetData
 */
static HRESULT WINAPI snapshot_GetData(IDataObject *iface, FORMATETC *fmt,
                                       STGMEDIUM *med)
{
    snapshot *This = impl_from_IDataObject(iface);
    HANDLE h;
    HRESULT hr;
    ole_priv_data *enum_data = NULL;
    ole_priv_data_entry *entry;
    DWORD mask;

    TRACE("(%p, %p {%s}, %p)\n", iface, fmt, dump_fmtetc(fmt), med);

    if ( !fmt || !med ) return E_INVALIDARG;

    if ( !OpenClipboard(NULL)) return CLIPBRD_E_CANT_OPEN;

    if(!This->data)
        hr = get_current_dataobject(&This->data);

    if(This->data)
    {
        hr = IDataObject_GetData(This->data, fmt, med);
        CloseClipboard();
        return hr;
    }

    h = GetClipboardData(fmt->cfFormat);
    if(!h)
    {
        hr = DV_E_FORMATETC;
        goto end;
    }

    hr = get_priv_data(&enum_data);
    if(FAILED(hr)) goto end;

    entry = find_format_in_list(enum_data->entries, enum_data->count, fmt->cfFormat);
    if(entry)
    {
        if(!td_equal(fmt->ptd, entry->fmtetc.ptd))
        {
            hr = DV_E_FORMATETC;
            goto end;
        }
        mask = fmt->tymed & entry->fmtetc.tymed;
        if(!mask) mask = fmt->tymed & (TYMED_ISTREAM | TYMED_HGLOBAL);
    }
    else /* non-Ole format */
        mask = fmt->tymed & TYMED_HGLOBAL;

    if(mask & TYMED_ISTORAGE)
        hr = get_stgmed_for_storage(h, med);
    else if(mask & TYMED_HGLOBAL)
        hr = get_stgmed_for_global(h, med);
    else if(mask & TYMED_ISTREAM)
        hr = get_stgmed_for_stream(h, med);
    else if(mask & TYMED_ENHMF)
        hr = get_stgmed_for_emf((HENHMETAFILE)h, med);
    else if(mask & TYMED_GDI)
        hr = get_stgmed_for_bitmap((HBITMAP)h, med);
    else
    {
        FIXME("Unhandled tymed - mask %x req tymed %x\n", mask, fmt->tymed);
        hr = E_FAIL;
        goto end;
    }

end:
    HeapFree(GetProcessHeap(), 0, enum_data);
    if ( !CloseClipboard() ) hr = CLIPBRD_E_CANT_CLOSE;
    return hr;
}

/************************************************************************
 *          snapshot_GetDataHere
 */
static HRESULT WINAPI snapshot_GetDataHere(IDataObject *iface, FORMATETC *fmt,
                                           STGMEDIUM *med)
{
    snapshot *This = impl_from_IDataObject(iface);
    HANDLE h;
    HRESULT hr;
    ole_priv_data *enum_data = NULL;
    ole_priv_data_entry *entry;
    TYMED supported;

    if ( !fmt || !med ) return E_INVALIDARG;

    TRACE("(%p, %p {%s}, %p (tymed %x)\n", iface, fmt, dump_fmtetc(fmt), med, med->tymed);

    if ( !OpenClipboard(NULL)) return CLIPBRD_E_CANT_OPEN;

    if(!This->data)
        hr = get_current_dataobject(&This->data);

    if(This->data)
    {
        hr = IDataObject_GetDataHere(This->data, fmt, med);
        if(SUCCEEDED(hr))
        {
            CloseClipboard();
            return hr;
        }
    }

    h = GetClipboardData(fmt->cfFormat);
    if(!h)
    {
        hr = DV_E_FORMATETC;
        goto end;
    }

    hr = get_priv_data(&enum_data);
    if(FAILED(hr)) goto end;

    entry = find_format_in_list(enum_data->entries, enum_data->count, fmt->cfFormat);
    if(entry)
    {
        if(!td_equal(fmt->ptd, entry->fmtetc.ptd))
        {
            hr = DV_E_FORMATETC;
            goto end;
        }
        supported = entry->fmtetc.tymed;
    }
    else /* non-Ole format */
        supported = TYMED_HGLOBAL;

    switch(med->tymed)
    {
    case TYMED_HGLOBAL:
    {
        DWORD src_size = GlobalSize(h);
        DWORD dst_size = GlobalSize(med->u.hGlobal);
        hr = E_FAIL;
        if(dst_size >= src_size)
        {
            void *src = GlobalLock(h);
            void *dst = GlobalLock(med->u.hGlobal);

            memcpy(dst, src, src_size);
            GlobalUnlock(med->u.hGlobal);
            GlobalUnlock(h);
            hr = S_OK;
        }
        break;
    }
    case TYMED_ISTREAM:
    {
        DWORD src_size = GlobalSize(h);
        void *src = GlobalLock(h);
        hr = IStream_Write(med->u.pstm, src, src_size, NULL);
        GlobalUnlock(h);
        break;
    }
    case TYMED_ISTORAGE:
    {
        STGMEDIUM copy;
        if(!(supported & TYMED_ISTORAGE))
        {
            hr = E_FAIL;
            goto end;
        }
        hr = get_stgmed_for_storage(h, &copy);
        if(SUCCEEDED(hr))
        {
            hr = IStorage_CopyTo(copy.u.pstg, 0, NULL, NULL, med->u.pstg);
            ReleaseStgMedium(&copy);
        }
        break;
    }
    default:
        FIXME("Unhandled tymed - supported %x req tymed %x\n", supported, med->tymed);
        hr = E_FAIL;
        goto end;
    }

end:
    HeapFree(GetProcessHeap(), 0, enum_data);
    if ( !CloseClipboard() ) hr = CLIPBRD_E_CANT_CLOSE;
    return hr;
}

/************************************************************************
 *           snapshot_QueryGetData
 *
 * The OLE Clipboard's implementation of this method delegates to
 * a data source if there is one or wraps around the windows clipboard
 * function IsClipboardFormatAvailable() otherwise.
 *
 */
static HRESULT WINAPI snapshot_QueryGetData(IDataObject *iface, FORMATETC *fmt)
{
    FIXME("(%p, %p {%s})\n", iface, fmt, dump_fmtetc(fmt));

    if (!fmt) return E_INVALIDARG;

    if ( fmt->dwAspect != DVASPECT_CONTENT ) return DV_E_FORMATETC;

    if ( fmt->lindex != -1 ) return DV_E_FORMATETC;

    return (IsClipboardFormatAvailable(fmt->cfFormat)) ? S_OK : DV_E_CLIPFORMAT;
}

/************************************************************************
 *              snapshot_GetCanonicalFormatEtc
 */
static HRESULT WINAPI snapshot_GetCanonicalFormatEtc(IDataObject *iface, FORMATETC *fmt_in,
                                                     FORMATETC *fmt_out)
{
    TRACE("(%p, %p, %p)\n", iface, fmt_in, fmt_out);

    if ( !fmt_in || !fmt_out ) return E_INVALIDARG;

    *fmt_out = *fmt_in;
    return DATA_S_SAMEFORMATETC;
}

/************************************************************************
 *              snapshot_SetData
 *
 * The OLE Clipboard does not implement this method
 */
static HRESULT WINAPI snapshot_SetData(IDataObject *iface, FORMATETC *fmt,
                                       STGMEDIUM *med, BOOL release)
{
    TRACE("(%p, %p, %p, %d): not implemented\n", iface, fmt, med, release);
    return E_NOTIMPL;
}

/************************************************************************
 *             snapshot_EnumFormatEtc
 *
 */
static HRESULT WINAPI snapshot_EnumFormatEtc(IDataObject *iface, DWORD dir,
                                             IEnumFORMATETC **enum_fmt)
{
    HRESULT hr;
    ole_priv_data *data = NULL;

    TRACE("(%p, %x, %p)\n", iface, dir, enum_fmt);

    *enum_fmt = NULL;

    if ( dir != DATADIR_GET ) return E_NOTIMPL;
    if ( !OpenClipboard(NULL) ) return CLIPBRD_E_CANT_OPEN;

    hr = get_priv_data(&data);

    if(FAILED(hr)) goto end;

    hr = enum_fmtetc_construct( data, 0, enum_fmt );

end:
    if ( !CloseClipboard() ) hr = CLIPBRD_E_CANT_CLOSE;
    return hr;
}

/************************************************************************
 *               snapshot_DAdvise
 *
 * The OLE Clipboard does not implement this method
 */
static HRESULT WINAPI snapshot_DAdvise(IDataObject *iface, FORMATETC *fmt,
                                       DWORD flags, IAdviseSink *sink,
                                       DWORD *conn)
{
    TRACE("(%p, %p, %x, %p, %p): not implemented\n", iface, fmt, flags, sink, conn);
    return E_NOTIMPL;
}

/************************************************************************
 *              snapshot_DUnadvise
 *
 * The OLE Clipboard does not implement this method
 */
static HRESULT WINAPI snapshot_DUnadvise(IDataObject* iface, DWORD conn)
{
    TRACE("(%p, %d): not implemented\n", iface, conn);
    return E_NOTIMPL;
}

/************************************************************************
 *             snapshot_EnumDAdvise
 *
 * The OLE Clipboard does not implement this method
 */
static HRESULT WINAPI snapshot_EnumDAdvise(IDataObject* iface,
                                           IEnumSTATDATA** enum_advise)
{
    TRACE("(%p, %p): not implemented\n", iface, enum_advise);
    return E_NOTIMPL;
}

static const IDataObjectVtbl snapshot_vtable =
{
    snapshot_QueryInterface,
    snapshot_AddRef,
    snapshot_Release,
    snapshot_GetData,
    snapshot_GetDataHere,
    snapshot_QueryGetData,
    snapshot_GetCanonicalFormatEtc,
    snapshot_SetData,
    snapshot_EnumFormatEtc,
    snapshot_DAdvise,
    snapshot_DUnadvise,
    snapshot_EnumDAdvise
};

/*---------------------------------------------------------------------*
 *           Internal implementation methods for the OLE clipboard
 *---------------------------------------------------------------------*/

static snapshot *snapshot_construct(DWORD seq_no)
{
    snapshot *This;

    This = HeapAlloc( GetProcessHeap(), 0, sizeof(*This) );
    if (!This) return NULL;

    This->IDataObject_iface.lpVtbl = &snapshot_vtable;
    This->ref = 0;
    This->seq_no = seq_no;
    This->data = NULL;

    return This;
}

/*********************************************************
 *               register_clipboard_formats
 */
static void register_clipboard_formats(void)
{
    static const WCHAR OwnerLink[] = {'O','w','n','e','r','L','i','n','k',0};
    static const WCHAR FileName[] = {'F','i','l','e','N','a','m','e',0};
    static const WCHAR FileNameW[] = {'F','i','l','e','N','a','m','e','W',0};
    static const WCHAR DataObject[] = {'D','a','t','a','O','b','j','e','c','t',0};
    static const WCHAR EmbeddedObject[] = {'E','m','b','e','d','d','e','d',' ','O','b','j','e','c','t',0};
    static const WCHAR EmbedSource[] = {'E','m','b','e','d',' ','S','o','u','r','c','e',0};
    static const WCHAR CustomLinkSource[] = {'C','u','s','t','o','m',' ','L','i','n','k',' ','S','o','u','r','c','e',0};
    static const WCHAR LinkSource[] = {'L','i','n','k',' ','S','o','u','r','c','e',0};
    static const WCHAR ObjectDescriptor[] = {'O','b','j','e','c','t',' ','D','e','s','c','r','i','p','t','o','r',0};
    static const WCHAR LinkSourceDescriptor[] = {'L','i','n','k',' ','S','o','u','r','c','e',' ',
                                                 'D','e','s','c','r','i','p','t','o','r',0};
    static const WCHAR OlePrivateData[] = {'O','l','e',' ','P','r','i','v','a','t','e',' ','D','a','t','a',0};

    static const WCHAR WineMarshalledDataObject[] = {'W','i','n','e',' ','M','a','r','s','h','a','l','l','e','d',' ',
                                                     'D','a','t','a','O','b','j','e','c','t',0};

    ownerlink_clipboard_format = RegisterClipboardFormatW(OwnerLink);
    filename_clipboard_format = RegisterClipboardFormatW(FileName);
    filenameW_clipboard_format = RegisterClipboardFormatW(FileNameW);
    dataobject_clipboard_format = RegisterClipboardFormatW(DataObject);
    embedded_object_clipboard_format = RegisterClipboardFormatW(EmbeddedObject);
    embed_source_clipboard_format = RegisterClipboardFormatW(EmbedSource);
    custom_link_source_clipboard_format = RegisterClipboardFormatW(CustomLinkSource);
    link_source_clipboard_format = RegisterClipboardFormatW(LinkSource);
    object_descriptor_clipboard_format = RegisterClipboardFormatW(ObjectDescriptor);
    link_source_descriptor_clipboard_format = RegisterClipboardFormatW(LinkSourceDescriptor);
    ole_private_data_clipboard_format = RegisterClipboardFormatW(OlePrivateData);

    wine_marshal_clipboard_format = RegisterClipboardFormatW(WineMarshalledDataObject);
}

/***********************************************************************
 * OLEClipbrd_Initialize()
 * Initializes the OLE clipboard.
 */
void OLEClipbrd_Initialize(void)
{
    register_clipboard_formats();

    if ( !theOleClipboard )
    {
        ole_clipbrd* clipbrd;
        HGLOBAL h;

        TRACE("()\n");

        clipbrd = HeapAlloc( GetProcessHeap(), 0, sizeof(*clipbrd) );
        if (!clipbrd) return;

        clipbrd->latest_snapshot = NULL;
        clipbrd->window = NULL;
        clipbrd->src_data = NULL;
        clipbrd->cached_enum = NULL;

        h = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, 0);
        if(!h)
        {
            HeapFree(GetProcessHeap(), 0, clipbrd);
            return;
        }

        if(FAILED(CreateStreamOnHGlobal(h, TRUE, &clipbrd->marshal_data)))
        {
            GlobalFree(h);
            HeapFree(GetProcessHeap(), 0, clipbrd);
            return;
        }

        theOleClipboard = clipbrd;
    }
}

/***********************************************************************
 * OLEClipbrd_UnInitialize()
 * Un-Initializes the OLE clipboard
 */
void OLEClipbrd_UnInitialize(void)
{
    ole_clipbrd *clipbrd = theOleClipboard;

    TRACE("()\n");

    if ( clipbrd )
    {
        static const WCHAR ole32W[] = {'o','l','e','3','2',0};
        HINSTANCE hinst = GetModuleHandleW(ole32W);

        if ( clipbrd->window )
        {
            DestroyWindow(clipbrd->window);
            UnregisterClassW( clipbrd_wndclass, hinst );
        }

        IStream_Release(clipbrd->marshal_data);
        if (clipbrd->src_data) IDataObject_Release(clipbrd->src_data);
        HeapFree(GetProcessHeap(), 0, clipbrd->cached_enum);
        HeapFree(GetProcessHeap(), 0, clipbrd);
        theOleClipboard = NULL;
    }
}

/*********************************************************************
 *          set_clipboard_formats
 *
 * Enumerate all formats supported by the source and make
 * those formats available using delayed rendering using SetClipboardData.
 * Cache the enumeration list and make that list visible as the
 * 'Ole Private Data' format on the clipboard.
 *
 */
static HRESULT set_clipboard_formats(ole_clipbrd *clipbrd, IDataObject *data)
{
    HRESULT hr;
    FORMATETC fmt;
    IEnumFORMATETC *enum_fmt;
    HGLOBAL priv_data_handle;
    DWORD_PTR target_offset;
    ole_priv_data *priv_data;
    DWORD count = 0, needed = sizeof(*priv_data), idx;

    hr = IDataObject_EnumFormatEtc(data, DATADIR_GET, &enum_fmt);
    if(FAILED(hr)) return hr;

    while(IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL) == S_OK)
    {
        count++;
        needed += sizeof(priv_data->entries[0]);
        if(fmt.ptd)
        {
            needed += fmt.ptd->tdSize;
            CoTaskMemFree(fmt.ptd);
        }
    }

    /* Windows pads the list with two empty ole_priv_data_entries, one
     * after the entries array and one after the target device data.
     * Allocating with zero init to zero these pads. */

    needed += sizeof(priv_data->entries[0]); /* initialisation of needed includes one of these. */
    priv_data_handle = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE | GMEM_ZEROINIT, needed);
    priv_data = GlobalLock(priv_data_handle);

    priv_data->unk1 = 0;
    priv_data->size = needed;
    priv_data->unk2 = 1;
    priv_data->count = count;
    priv_data->unk3[0] = 0;
    priv_data->unk3[1] = 0;

    IEnumFORMATETC_Reset(enum_fmt);

    idx = 0;
    target_offset = FIELD_OFFSET(ole_priv_data, entries[count + 1]); /* count entries + one pad. */

    while(IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL) == S_OK)
    {
        TRACE("%s\n", dump_fmtetc(&fmt));

        priv_data->entries[idx].fmtetc = fmt;
        if(fmt.ptd)
        {
            memcpy((char*)priv_data + target_offset, fmt.ptd, fmt.ptd->tdSize);
            priv_data->entries[idx].fmtetc.ptd = (DVTARGETDEVICE*)target_offset;
            target_offset += fmt.ptd->tdSize;
            CoTaskMemFree(fmt.ptd);
        }

        priv_data->entries[idx].first_use = !find_format_in_list(priv_data->entries, idx, fmt.cfFormat);
        priv_data->entries[idx].unk[0] = 0;
        priv_data->entries[idx].unk[1] = 0;

        if (priv_data->entries[idx].first_use)
            SetClipboardData(fmt.cfFormat, NULL);

        idx++;
    }

    IEnumFORMATETC_Release(enum_fmt);

    /* Cache the list and fixup any target device offsets to ptrs */
    clipbrd->cached_enum = HeapAlloc(GetProcessHeap(), 0, needed);
    memcpy(clipbrd->cached_enum, priv_data, needed);
    for(idx = 0; idx < clipbrd->cached_enum->count; idx++)
        clipbrd->cached_enum->entries[idx].fmtetc.ptd =
            td_offs_to_ptr(clipbrd->cached_enum, (DWORD_PTR)clipbrd->cached_enum->entries[idx].fmtetc.ptd);

    GlobalUnlock(priv_data_handle);
    if(!SetClipboardData(ole_private_data_clipboard_format, priv_data_handle))
    {
        GlobalFree(priv_data_handle);
        return CLIPBRD_E_CANT_SET;
    }

    return S_OK;
}

static HWND create_clipbrd_window(void);

/***********************************************************************
 *                 get_clipbrd_window
 */
static inline HRESULT get_clipbrd_window(ole_clipbrd *clipbrd, HWND *wnd)
{
    if ( !clipbrd->window )
        clipbrd->window = create_clipbrd_window();

    *wnd = clipbrd->window;
    return *wnd ? S_OK : E_FAIL;
}


/**********************************************************************
 *                  release_marshal_data
 *
 * Releases the data and sets the stream back to zero size.
 */
static inline void release_marshal_data(IStream *stm)
{
    LARGE_INTEGER pos;
    ULARGE_INTEGER size;
    pos.QuadPart = size.QuadPart = 0;

    IStream_Seek(stm, pos, STREAM_SEEK_SET, NULL);
    CoReleaseMarshalData(stm);
    IStream_Seek(stm, pos, STREAM_SEEK_SET, NULL);
    IStream_SetSize(stm, size);
}

/***********************************************************************
 *   expose_marshalled_dataobject
 *
 * Sets the marshalled dataobject to the clipboard.  In the flushed case
 * we set a zero sized HGLOBAL to clear the old marshalled data.
 */
static HRESULT expose_marshalled_dataobject(ole_clipbrd *clipbrd, IDataObject *data)
{
    HGLOBAL h;

    if(data)
    {
        HGLOBAL h_stm;
        GetHGlobalFromStream(clipbrd->marshal_data, &h_stm);
        dup_global_mem(h_stm, GMEM_DDESHARE|GMEM_MOVEABLE, &h);
    }
    else /* flushed */
        h = GlobalAlloc(GMEM_DDESHARE|GMEM_MOVEABLE, 1);

    if(!h) return E_OUTOFMEMORY;

    if(!SetClipboardData(wine_marshal_clipboard_format, h))
    {
        GlobalFree(h);
        return CLIPBRD_E_CANT_SET;
    }
    return S_OK;
}

/***********************************************************************
 *                   set_src_dataobject
 *
 * Clears and sets the clipboard's src IDataObject.
 *
 * To marshal the source dataobject we do something rather different from Windows.
 * We set a clipboard format which contains the marshalled data.
 * Windows sets two window props one of which is an IID, the other is an endpoint number.
 */
static HRESULT set_src_dataobject(ole_clipbrd *clipbrd, IDataObject *data)
{
    HRESULT hr;
    HWND wnd;

    if(FAILED(hr = get_clipbrd_window(clipbrd, &wnd))) return hr;

    if(clipbrd->src_data)
    {
        release_marshal_data(clipbrd->marshal_data);

        IDataObject_Release(clipbrd->src_data);
        clipbrd->src_data = NULL;
        HeapFree(GetProcessHeap(), 0, clipbrd->cached_enum);
        clipbrd->cached_enum = NULL;
    }

    if(data)
    {
        IUnknown *unk;

        IDataObject_AddRef(data);
        clipbrd->src_data = data;

        IDataObject_QueryInterface(data, &IID_IUnknown, (void**)&unk);
        hr = CoMarshalInterface(clipbrd->marshal_data, &IID_IDataObject, unk,
                                MSHCTX_LOCAL, NULL, MSHLFLAGS_TABLESTRONG);
        IUnknown_Release(unk); /* Don't hold a ref on IUnknown, we have one on IDataObject. */
        if(FAILED(hr)) return hr;
        hr = set_clipboard_formats(clipbrd, data);
    }
    return hr;
}

/***********************************************************************
 *                   clipbrd_wndproc
 */
static LRESULT CALLBACK clipbrd_wndproc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
    ole_clipbrd *clipbrd;

    get_ole_clipbrd(&clipbrd);

    switch (message)
    {
    case WM_RENDERFORMAT:
    {
        UINT cf = wparam;
        ole_priv_data_entry *entry;

        TRACE("(): WM_RENDERFORMAT(cfFormat=%x)\n", cf);
        entry = find_format_in_list(clipbrd->cached_enum->entries, clipbrd->cached_enum->count, cf);

        if(entry)
            render_format(clipbrd->src_data, &entry->fmtetc);

        break;
    }

    case WM_RENDERALLFORMATS:
    {
        DWORD i;
        ole_priv_data_entry *entries;

        TRACE("(): WM_RENDERALLFORMATS\n");

        if (!clipbrd || !clipbrd->cached_enum) break;
        entries = clipbrd->cached_enum->entries;
        for(i = 0; i < clipbrd->cached_enum->count; i++)
        {
            if(entries[i].first_use)
                render_format(clipbrd->src_data, &entries[i].fmtetc);
        }
        break;
    }

    case WM_DESTROYCLIPBOARD:
    {
        TRACE("(): WM_DESTROYCLIPBOARD\n");

        set_src_dataobject(clipbrd, NULL);
        break;
    }

    default:
        return DefWindowProcW(hwnd, message, wparam, lparam);
    }

    return 0;
}


/***********************************************************************
 *                 create_clipbrd_window
 */
static HWND create_clipbrd_window(void)
{
    WNDCLASSEXW class;
    static const WCHAR ole32W[] = {'o','l','e','3','2',0};
    static const WCHAR title[] = {'C','l','i','p','b','o','a','r','d','W','i','n','d','o','w',0};
    HINSTANCE hinst = GetModuleHandleW(ole32W);

    class.cbSize         = sizeof(class);
    class.style          = 0;
    class.lpfnWndProc    = clipbrd_wndproc;
    class.cbClsExtra     = 0;
    class.cbWndExtra     = 0;
    class.hInstance      = hinst;
    class.hIcon          = 0;
    class.hCursor        = 0;
    class.hbrBackground  = 0;
    class.lpszMenuName   = NULL;
    class.lpszClassName  = clipbrd_wndclass;
    class.hIconSm        = NULL;

    RegisterClassExW(&class);

    return CreateWindowW(clipbrd_wndclass, title, WS_POPUP | WS_CLIPSIBLINGS | WS_OVERLAPPED,
                         0, 0, 0, 0, HWND_MESSAGE, NULL, hinst, 0);
}

/*********************************************************************
 *          set_dataobject_format
 *
 * Windows creates a 'DataObject' clipboard format that contains the
 * clipboard window's HWND or NULL if the Ole clipboard has been flushed.
 */
static HRESULT set_dataobject_format(HWND hwnd)
{
    HGLOBAL h = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, sizeof(hwnd));
    HWND *data;

    if(!h) return E_OUTOFMEMORY;

    data = GlobalLock(h);
    *data = hwnd;
    GlobalUnlock(h);

    if(!SetClipboardData(dataobject_clipboard_format, h))
    {
        GlobalFree(h);
        return CLIPBRD_E_CANT_SET;
    }

    return S_OK;
}

/*---------------------------------------------------------------------*
 *           Win32 OLE clipboard API
 *---------------------------------------------------------------------*/

/***********************************************************************
 *           OleSetClipboard     [OLE32.@]
 *  Places a pointer to the specified data object onto the clipboard,
 *  making the data object accessible to the OleGetClipboard function.
 *
 * RETURNS
 *
 *    S_OK                  IDataObject pointer placed on the clipboard
 *    CLIPBRD_E_CANT_OPEN   OpenClipboard failed
 *    CLIPBRD_E_CANT_EMPTY  EmptyClipboard failed
 *    CLIPBRD_E_CANT_CLOSE  CloseClipboard failed
 *    CLIPBRD_E_CANT_SET    SetClipboard failed
 */

HRESULT WINAPI OleSetClipboard(IDataObject* data)
{
  HRESULT hr;
  ole_clipbrd *clipbrd;
  HWND wnd;

  TRACE("(%p)\n", data);

  if(FAILED(hr = get_ole_clipbrd(&clipbrd))) return hr;

  if(FAILED(hr = get_clipbrd_window(clipbrd, &wnd))) return hr;

  if ( !OpenClipboard(wnd) ) return CLIPBRD_E_CANT_OPEN;

  if ( !EmptyClipboard() )
  {
    hr = CLIPBRD_E_CANT_EMPTY;
    goto end;
  }

  hr = set_src_dataobject(clipbrd, data);
  if(FAILED(hr)) goto end;

  if(data)
  {
    hr = expose_marshalled_dataobject(clipbrd, data);
    if(FAILED(hr)) goto end;
    hr = set_dataobject_format(wnd);
  }

end:

  if ( !CloseClipboard() ) hr = CLIPBRD_E_CANT_CLOSE;

  if ( FAILED(hr) )
  {
    expose_marshalled_dataobject(clipbrd, NULL);
    set_src_dataobject(clipbrd, NULL);
  }

  return hr;
}


/***********************************************************************
 * OleGetClipboard [OLE32.@]
 * Returns a pointer to our internal IDataObject which represents the conceptual
 * state of the Windows clipboard. If the current clipboard already contains
 * an IDataObject, our internal IDataObject will delegate to this object.
 */
HRESULT WINAPI OleGetClipboard(IDataObject **obj)
{
    HRESULT hr;
    ole_clipbrd *clipbrd;
    DWORD seq_no;

    TRACE("(%p)\n", obj);

    if(!obj) return E_INVALIDARG;
    *obj = NULL;

    if(FAILED(hr = get_ole_clipbrd(&clipbrd))) return hr;

    seq_no = GetClipboardSequenceNumber();
    EnterCriticalSection(&latest_snapshot_cs);
    if(clipbrd->latest_snapshot && clipbrd->latest_snapshot->seq_no != seq_no)
        clipbrd->latest_snapshot = NULL;

    if(!clipbrd->latest_snapshot)
    {
        clipbrd->latest_snapshot = snapshot_construct(seq_no);
        if(!clipbrd->latest_snapshot)
        {
            LeaveCriticalSection(&latest_snapshot_cs);
            return E_OUTOFMEMORY;
        }
    }

    *obj = &clipbrd->latest_snapshot->IDataObject_iface;
    IDataObject_AddRef(*obj);
    LeaveCriticalSection(&latest_snapshot_cs);

    return S_OK;
}

/******************************************************************************
 *              OleFlushClipboard        [OLE32.@]
 *  Renders the data from the source IDataObject into the windows clipboard
 *
 *  TODO: OleFlushClipboard needs to additionally handle TYMED_IStorage media
 *  by copying the storage into global memory. Subsequently the default
 *  data object exposed through OleGetClipboard must convert this TYMED_HGLOBAL
 *  back to TYMED_IStorage.
 */
HRESULT WINAPI OleFlushClipboard(void)
{
  HRESULT hr;
  ole_clipbrd *clipbrd;
  HWND wnd;

  TRACE("()\n");

  if(FAILED(hr = get_ole_clipbrd(&clipbrd))) return hr;

  if(FAILED(hr = get_clipbrd_window(clipbrd, &wnd))) return hr;

  /*
   * Already flushed or no source DataObject? Nothing to do.
   */
  if (!clipbrd->src_data) return S_OK;

  if (!OpenClipboard(wnd)) return CLIPBRD_E_CANT_OPEN;

  SendMessageW(wnd, WM_RENDERALLFORMATS, 0, 0);

  hr = set_dataobject_format(NULL);

  expose_marshalled_dataobject(clipbrd, NULL);
  set_src_dataobject(clipbrd, NULL);

  if ( !CloseClipboard() ) hr = CLIPBRD_E_CANT_CLOSE;

  return hr;
}


/***********************************************************************
 *           OleIsCurrentClipboard [OLE32.@]
 */
HRESULT WINAPI OleIsCurrentClipboard(IDataObject *data)
{
    HRESULT hr;
    ole_clipbrd *clipbrd;
    TRACE("()\n");

    if(FAILED(hr = get_ole_clipbrd(&clipbrd))) return hr;

    if (data == NULL) return S_FALSE;

    return (data == clipbrd->src_data) ? S_OK : S_FALSE;
}
