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

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

#define HANDLE_ERROR(err) do { hr = err; TRACE("(HRESULT=%x)\n", (HRESULT)err); goto CLEANUP; } while (0)

/* 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 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};

static const WCHAR wine_marshal_dataobject[] = {'W','i','n','e',' ','m','a','r','s','h','a','l',' ','d','a','t','a','o','b','j','e','c','t',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 char *dump_fmtetc(FORMATETC *fmt)
{
    static char buf[100];

    snprintf(buf, sizeof(buf), "cf %04x ptd %p aspect %x lindex %d tymed %x",
             fmt->cfFormat, fmt->ptd, fmt->dwAspect, fmt->lindex, fmt->tymed);
    return buf;
}

/*---------------------------------------------------------------------*
 *  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);
    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 );
            OLECONVERT_CreateOleStream(std.u.pstg);
            OLECONVERT_CreateCompObjStream(std.u.pstg, strOleTypeName);
        }
    }

    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)
    {
        ole_clipbrd *clipbrd;
        HRESULT hr = get_ole_clipbrd(&clipbrd);

        if(This->data) IDataObject_Release(This->data);

        if(SUCCEEDED(hr) && clipbrd->latest_snapshot == This)
            clipbrd->latest_snapshot = NULL;
        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) == 0) 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;
    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++)
        {
            char buf[100];
            GetClipboardFormatNameA(cf, buf, sizeof(buf));
            TRACE("cf %04x %s\n", cf, buf);
        }
        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;
}

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
    {
        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 visibile 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, 0);

    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 = clipbrd->cached_enum->entries;

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

        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,
                         CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                         NULL, 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;

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

    seq_no = GetClipboardSequenceNumber();
    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) return E_OUTOFMEMORY;
    }

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

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