/*
 *	OLE 2 Data cache
 *
 *      Copyright 1999  Francis Beaudet
 *      Copyright 2000  Abey George
 *
 * 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:
 *    The OLE2 data cache supports a whole whack of
 *    interfaces including:
 *       IDataObject, IPersistStorage, IViewObject2,
 *       IOleCache2 and IOleCacheControl.
 *
 *    Most of the implementation details are taken from: Inside OLE
 *    second edition by Kraig Brockschmidt,
 *
 * NOTES
 *  -  This implementation of the datacache will let your application
 *     load documents that have embedded OLE objects in them and it will
 *     also retrieve the metafile representation of those objects.
 *  -  This implementation of the datacache will also allow your
 *     application to save new documents with OLE objects in them.
 *  -  The main thing that it doesn't do is allow you to activate
 *     or modify the OLE objects in any way.
 *  -  I haven't found any good documentation on the real usage of
 *     the streams created by the data cache. In particular, How to
 *     determine what the XXX stands for in the stream name
 *     "\002OlePresXXX". It appears to just be a counter.
 *  -  Also, I don't know the real content of the presentation stream
 *     header. I was able to figure-out where the extent of the object
 *     was stored and the aspect, but that's about it.
 */

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

#define COBJMACROS
#define NONAMELESSUNION

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "ole2.h"
#include "compobj_private.h"
#include "wine/unicode.h"
#include "wine/list.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(ole);

/****************************************************************************
 * PresentationDataHeader
 *
 * This structure represents the header of the \002OlePresXXX stream in
 * the OLE object storage.
 */
typedef struct PresentationDataHeader
{
  /* clipformat:
   *  - standard clipformat:
   *  DWORD length = 0xffffffff;
   *  DWORD cfFormat;
   *  - or custom clipformat:
   *  DWORD length;
   *  CHAR format_name[length]; (null-terminated)
   */
  DWORD unknown3;	/* 4, possibly TYMED_ISTREAM */
  DVASPECT dvAspect;
  DWORD lindex;
  DWORD advf;
  DWORD unknown7;	/* 0 */
  DWORD dwObjectExtentX;
  DWORD dwObjectExtentY;
  DWORD dwSize;
} PresentationDataHeader;

enum stream_type
{
    no_stream,
    pres_stream,
    contents_stream
};

typedef struct DataCacheEntry
{
  struct list entry;
  /* format of this entry */
  FORMATETC fmtetc;
  /* the clipboard format of the data */
  CLIPFORMAT data_cf;
  /* cached data */
  STGMEDIUM stgmedium;
  /*
   * This stream pointer is set through a call to
   * IPersistStorage_Load. This is where the visual
   * representation of the object is stored.
   */
  IStream *stream;
  enum stream_type stream_type;
  /* connection ID */
  DWORD id;
  /* dirty flag */
  BOOL dirty;
  /* stream number (-1 if not set ) */
  unsigned short stream_number;
  /* sink id set when object is running */
  DWORD sink_id;
  /* Advise sink flags */
  DWORD advise_flags;
} DataCacheEntry;

/****************************************************************************
 * DataCache
 */
struct DataCache
{
  /*
   * List all interface here
   */
  IUnknown          IUnknown_inner;
  IDataObject       IDataObject_iface;
  IPersistStorage   IPersistStorage_iface;
  IViewObject2      IViewObject2_iface;
  IOleCache2        IOleCache2_iface;
  IOleCacheControl  IOleCacheControl_iface;

  /* The sink that is connected to a remote object.
     The other interfaces are not available by QI'ing the sink and vice-versa */
  IAdviseSink       IAdviseSink_iface;

  /*
   * Reference count of this object
   */
  LONG ref;

  /*
   * IUnknown implementation of the outer object.
   */
  IUnknown *outer_unk;

  /*
   * The user of this object can setup ONE advise sink
   * connection with the object. These parameters describe
   * that connection.
   */
  DWORD        sinkAspects;
  DWORD        sinkAdviseFlag;
  IAdviseSink *sinkInterface;

  CLSID clsid;
  IStorage *presentationStorage;

  /* list of cache entries */
  struct list cache_list;
  /* last id assigned to an entry */
  DWORD last_cache_id;
  /* dirty flag */
  BOOL dirty;
  /* running object set by OnRun */
  IDataObject *running_object;
};

typedef struct DataCache DataCache;

/*
 * Here, I define utility macros to help with the casting of the
 * "this" parameter.
 * There is a version to accommodate all of the VTables implemented
 * by this object.
 */

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

static inline DataCache *impl_from_IUnknown( IUnknown *iface )
{
    return CONTAINING_RECORD(iface, DataCache, IUnknown_inner);
}

static inline DataCache *impl_from_IPersistStorage( IPersistStorage *iface )
{
    return CONTAINING_RECORD(iface, DataCache, IPersistStorage_iface);
}

static inline DataCache *impl_from_IViewObject2( IViewObject2 *iface )
{
    return CONTAINING_RECORD(iface, DataCache, IViewObject2_iface);
}

static inline DataCache *impl_from_IOleCache2( IOleCache2 *iface )
{
    return CONTAINING_RECORD(iface, DataCache, IOleCache2_iface);
}

static inline DataCache *impl_from_IOleCacheControl( IOleCacheControl *iface )
{
    return CONTAINING_RECORD(iface, DataCache, IOleCacheControl_iface);
}

static inline DataCache *impl_from_IAdviseSink( IAdviseSink *iface )
{
    return CONTAINING_RECORD(iface, DataCache, IAdviseSink_iface);
}

const char *debugstr_formatetc(const FORMATETC *formatetc)
{
    return wine_dbg_sprintf("{ cfFormat = 0x%x, ptd = %p, dwAspect = %d, lindex = %d, tymed = %d }",
        formatetc->cfFormat, formatetc->ptd, formatetc->dwAspect,
        formatetc->lindex, formatetc->tymed);
}

/***********************************************************************
 *           bitmap_info_size
 *
 * Return the size of the bitmap info structure including color table.
 */
static int bitmap_info_size( const BITMAPINFO * info, WORD coloruse )
{
    unsigned int colors, size, masks = 0;

    if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
    {
        const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
        colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
        return sizeof(BITMAPCOREHEADER) + colors *
            ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
    }
    else  /* assume BITMAPINFOHEADER */
    {
        colors = info->bmiHeader.biClrUsed;
        if (colors > 256) /* buffer overflow otherwise */
            colors = 256;
        if (!colors && (info->bmiHeader.biBitCount <= 8))
            colors = 1 << info->bmiHeader.biBitCount;
        if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
        size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
        return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
    }
}

static void DataCacheEntry_Destroy(DataCache *cache, DataCacheEntry *cache_entry)
{
    list_remove(&cache_entry->entry);
    if (cache_entry->stream)
        IStream_Release(cache_entry->stream);
    CoTaskMemFree(cache_entry->fmtetc.ptd);
    ReleaseStgMedium(&cache_entry->stgmedium);
    if(cache_entry->sink_id)
        IDataObject_DUnadvise(cache->running_object, cache_entry->sink_id);

    HeapFree(GetProcessHeap(), 0, cache_entry);
}

static void DataCache_Destroy(
  DataCache* ptrToDestroy)
{
  DataCacheEntry *cache_entry, *next_cache_entry;

  TRACE("()\n");

  if (ptrToDestroy->sinkInterface != NULL)
  {
    IAdviseSink_Release(ptrToDestroy->sinkInterface);
    ptrToDestroy->sinkInterface = NULL;
  }

  LIST_FOR_EACH_ENTRY_SAFE(cache_entry, next_cache_entry, &ptrToDestroy->cache_list, DataCacheEntry, entry)
    DataCacheEntry_Destroy(ptrToDestroy, cache_entry);

  if (ptrToDestroy->presentationStorage != NULL)
  {
    IStorage_Release(ptrToDestroy->presentationStorage);
    ptrToDestroy->presentationStorage = NULL;
  }

  /*
   * Free the datacache pointer.
   */
  HeapFree(GetProcessHeap(), 0, ptrToDestroy);
}

static DataCacheEntry *DataCache_GetEntryForFormatEtc(DataCache *This, const FORMATETC *formatetc)
{
    DataCacheEntry *cache_entry;
    FORMATETC fmt = *formatetc;

    if (fmt.cfFormat == CF_BITMAP)
    {
        fmt.cfFormat = CF_DIB;
        fmt.tymed = TYMED_HGLOBAL;
    }

    LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry)
    {
        /* FIXME: also compare DVTARGETDEVICEs */
        if ((!cache_entry->fmtetc.cfFormat || !fmt.cfFormat || (fmt.cfFormat == cache_entry->fmtetc.cfFormat)) &&
            (fmt.dwAspect == cache_entry->fmtetc.dwAspect) &&
            (fmt.lindex == cache_entry->fmtetc.lindex) &&
            (!cache_entry->fmtetc.tymed || !fmt.tymed || (fmt.tymed == cache_entry->fmtetc.tymed)))
            return cache_entry;
    }
    return NULL;
}

/* checks that the clipformat and tymed are valid and returns an error if they
* aren't and CACHE_S_NOTSUPPORTED if they are valid, but can't be rendered by
* DataCache_Draw */
static HRESULT check_valid_clipformat_and_tymed(CLIPFORMAT cfFormat, DWORD tymed)
{
    if (!cfFormat || !tymed ||
        (cfFormat == CF_METAFILEPICT && tymed == TYMED_MFPICT) ||
        (cfFormat == CF_BITMAP && tymed == TYMED_GDI) ||
        (cfFormat == CF_DIB && tymed == TYMED_HGLOBAL) ||
        (cfFormat == CF_ENHMETAFILE && tymed == TYMED_ENHMF))
        return S_OK;
    else if (tymed == TYMED_HGLOBAL)
        return CACHE_S_FORMATETC_NOTSUPPORTED;
    else
    {
        WARN("invalid clipformat/tymed combination: %d/%d\n", cfFormat, tymed);
        return DV_E_TYMED;
    }
}

static BOOL init_cache_entry(DataCacheEntry *entry, const FORMATETC *fmt, DWORD advf,
                             DWORD id)
{
    HRESULT hr;

    hr = copy_formatetc(&entry->fmtetc, fmt);
    if (FAILED(hr)) return FALSE;

    entry->data_cf = 0;
    entry->stgmedium.tymed = TYMED_NULL;
    entry->stgmedium.pUnkForRelease = NULL;
    entry->stream = NULL;
    entry->stream_type = no_stream;
    entry->id = id;
    entry->dirty = TRUE;
    entry->stream_number = -1;
    entry->sink_id = 0;
    entry->advise_flags = advf;

    return TRUE;
}

static HRESULT DataCache_CreateEntry(DataCache *This, const FORMATETC *formatetc, DWORD advf,
                                     BOOL automatic, DataCacheEntry **cache_entry)
{
    HRESULT hr;
    DWORD id = automatic ? 1 : This->last_cache_id;
    DataCacheEntry *entry;

    hr = check_valid_clipformat_and_tymed(formatetc->cfFormat, formatetc->tymed);
    if (FAILED(hr))
        return hr;
    if (hr == CACHE_S_FORMATETC_NOTSUPPORTED)
        TRACE("creating unsupported format %d\n", formatetc->cfFormat);

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

    if (!init_cache_entry(entry, formatetc, advf, id))
        goto fail;

    if (automatic)
        list_add_head(&This->cache_list, &entry->entry);
    else
    {
        list_add_tail(&This->cache_list, &entry->entry);
        This->last_cache_id++;
    }

    if (cache_entry) *cache_entry = entry;
    return hr;

fail:
    HeapFree(GetProcessHeap(), 0, entry);
    return E_OUTOFMEMORY;
}

/************************************************************************
 * DataCache_FireOnViewChange
 *
 * This method will fire an OnViewChange notification to the advise
 * sink registered with the datacache.
 *
 * See IAdviseSink::OnViewChange for more details.
 */
static void DataCache_FireOnViewChange(
  DataCache* this,
  DWORD      aspect,
  LONG       lindex)
{
  TRACE("(%p, %x, %d)\n", this, aspect, lindex);

  /*
   * The sink supplies a filter when it registers
   * we make sure we only send the notifications when that
   * filter matches.
   */
  if ((this->sinkAspects & aspect) != 0)
  {
    if (this->sinkInterface != NULL)
    {
      IAdviseSink_OnViewChange(this->sinkInterface,
			       aspect,
			       lindex);

      /*
       * Some sinks want to be unregistered automatically when
       * the first notification goes out.
       */
      if ( (this->sinkAdviseFlag & ADVF_ONLYONCE) != 0)
      {
	IAdviseSink_Release(this->sinkInterface);

	this->sinkInterface  = NULL;
	this->sinkAspects    = 0;
	this->sinkAdviseFlag = 0;
      }
    }
  }
}

/* Helper for DataCacheEntry_OpenPresStream */
static BOOL DataCache_IsPresentationStream(const STATSTG *elem)
{
    /* The presentation streams have names of the form "\002OlePresXXX",
     * where XXX goes from 000 to 999. */
    static const WCHAR OlePres[] = { 2,'O','l','e','P','r','e','s' };

    LPCWSTR name = elem->pwcsName;

    return (elem->type == STGTY_STREAM)
	&& (strlenW(name) == 11)
	&& (strncmpW(name, OlePres, 8) == 0)
	&& (name[8] >= '0') && (name[8] <= '9')
	&& (name[9] >= '0') && (name[9] <= '9')
	&& (name[10] >= '0') && (name[10] <= '9');
}

static HRESULT read_clipformat(IStream *stream, CLIPFORMAT *clipformat)
{
    DWORD length;
    HRESULT hr;
    ULONG read;

    *clipformat = 0;

    hr = IStream_Read(stream, &length, sizeof(length), &read);
    if (hr != S_OK || read != sizeof(length))
        return DV_E_CLIPFORMAT;
    if (length == -1)
    {
        DWORD cf;
        hr = IStream_Read(stream, &cf, sizeof(cf), &read);
        if (hr != S_OK || read != sizeof(cf))
            return DV_E_CLIPFORMAT;
        *clipformat = cf;
    }
    else
    {
        char *format_name = HeapAlloc(GetProcessHeap(), 0, length);
        if (!format_name)
            return E_OUTOFMEMORY;
        hr = IStream_Read(stream, format_name, length, &read);
        if (hr != S_OK || read != length || format_name[length - 1] != '\0')
        {
            HeapFree(GetProcessHeap(), 0, format_name);
            return DV_E_CLIPFORMAT;
        }
        *clipformat = RegisterClipboardFormatA(format_name);
        HeapFree(GetProcessHeap(), 0, format_name);
    }
    return S_OK;
}

static HRESULT write_clipformat(IStream *stream, CLIPFORMAT clipformat)
{
    DWORD length;
    HRESULT hr;

    if (clipformat < 0xc000)
        length = -1;
    else
        length = GetClipboardFormatNameA(clipformat, NULL, 0);
    hr = IStream_Write(stream, &length, sizeof(length), NULL);
    if (FAILED(hr))
        return hr;
    if (clipformat < 0xc000)
    {
        DWORD cf = clipformat;
        hr = IStream_Write(stream, &cf, sizeof(cf), NULL);
    }
    else
    {
        char *format_name = HeapAlloc(GetProcessHeap(), 0, length);
        if (!format_name)
            return E_OUTOFMEMORY;
        GetClipboardFormatNameA(clipformat, format_name, length);
        hr = IStream_Write(stream, format_name, length, NULL);
        HeapFree(GetProcessHeap(), 0, format_name);
    }
    return hr;
}

/************************************************************************
 * DataCacheEntry_OpenPresStream
 *
 * This method will find the stream for the given presentation. It makes
 * no attempt at fallback.
 *
 * Param:
 *   this       - Pointer to the DataCache object
 *   drawAspect - The aspect of the object that we wish to draw.
 *   pStm       - A returned stream. It points to the beginning of the
 *              - presentation data, including the header.
 *
 * Errors:
 *   S_OK		The requested stream has been opened.
 *   OLE_E_BLANK	The requested stream could not be found.
 *   Quite a few others I'm too lazy to map correctly.
 *
 * Notes:
 *   Algorithm:	Scan the elements of the presentation storage, looking
 *		for presentation streams. For each presentation stream,
 *		load the header and check to see if the aspect matches.
 *
 *   If a fallback is desired, just opening the first presentation stream
 *   is a possibility.
 */
static HRESULT DataCacheEntry_OpenPresStream(DataCacheEntry *cache_entry, IStream **ppStm)
{
    HRESULT hr;
    LARGE_INTEGER offset;

    if (cache_entry->stream)
    {
        /* Rewind the stream before returning it. */
        offset.QuadPart = 0;

        hr = IStream_Seek( cache_entry->stream, offset, STREAM_SEEK_SET, NULL );
        if (SUCCEEDED( hr ))
        {
            *ppStm = cache_entry->stream;
            IStream_AddRef( cache_entry->stream );
        }
    }
    else
        hr = OLE_E_BLANK;

    return hr;
}


static HRESULT load_mf_pict( DataCacheEntry *cache_entry, IStream *stm )
{
    HRESULT hr;
    STATSTG stat;
    ULARGE_INTEGER current_pos;
    void *bits;
    METAFILEPICT *mfpict;
    HGLOBAL hmfpict;
    PresentationDataHeader header;
    CLIPFORMAT clipformat;
    static const LARGE_INTEGER offset_zero;
    ULONG read;

    if (cache_entry->stream_type != pres_stream)
    {
        FIXME( "Unimplemented for stream type %d\n", cache_entry->stream_type );
        return E_FAIL;
    }

    hr = IStream_Stat( stm, &stat, STATFLAG_NONAME );
    if (FAILED( hr )) return hr;

    hr = read_clipformat( stm, &clipformat );
    if (FAILED( hr )) return hr;

    hr = IStream_Read( stm, &header, sizeof(header), &read );
    if (hr != S_OK || read != sizeof(header)) return E_FAIL;

    hr = IStream_Seek( stm, offset_zero, STREAM_SEEK_CUR, &current_pos );
    if (FAILED( hr )) return hr;

    stat.cbSize.QuadPart -= current_pos.QuadPart;

    hmfpict = GlobalAlloc( GMEM_MOVEABLE, sizeof(METAFILEPICT) );
    if (!hmfpict) return E_OUTOFMEMORY;
    mfpict = GlobalLock( hmfpict );

    bits = HeapAlloc( GetProcessHeap(), 0, stat.cbSize.u.LowPart);
    if (!bits)
    {
        GlobalFree( hmfpict );
        return E_OUTOFMEMORY;
    }

    hr = IStream_Read( stm, bits, stat.cbSize.u.LowPart, &read );
    if (hr != S_OK || read != stat.cbSize.u.LowPart) hr = E_FAIL;

    if (SUCCEEDED( hr ))
    {
        /* FIXME: get this from the stream */
        mfpict->mm = MM_ANISOTROPIC;
        mfpict->xExt = header.dwObjectExtentX;
        mfpict->yExt = header.dwObjectExtentY;
        mfpict->hMF = SetMetaFileBitsEx( stat.cbSize.u.LowPart, bits );
        if (!mfpict->hMF)
            hr = E_FAIL;
    }

    GlobalUnlock( hmfpict );
    if (SUCCEEDED( hr ))
    {
        cache_entry->data_cf = cache_entry->fmtetc.cfFormat;
        cache_entry->stgmedium.tymed = TYMED_MFPICT;
        cache_entry->stgmedium.u.hMetaFilePict = hmfpict;
    }
    else
        GlobalFree( hmfpict );

    HeapFree( GetProcessHeap(), 0, bits );

    return hr;
}

static HRESULT load_dib( DataCacheEntry *cache_entry, IStream *stm )
{
    HRESULT hr;
    STATSTG stat;
    void *dib;
    HGLOBAL hglobal;
    ULONG read, info_size, bi_size;
    BITMAPFILEHEADER file;
    BITMAPINFOHEADER *info;

    if (cache_entry->stream_type != contents_stream)
    {
        FIXME( "Unimplemented for stream type %d\n", cache_entry->stream_type );
        return E_FAIL;
    }

    hr = IStream_Stat( stm, &stat, STATFLAG_NONAME );
    if (FAILED( hr )) return hr;

    if (stat.cbSize.QuadPart < sizeof(file) + sizeof(DWORD)) return E_FAIL;
    hr = IStream_Read( stm, &file, sizeof(file), &read );
    if (hr != S_OK || read != sizeof(file)) return E_FAIL;
    stat.cbSize.QuadPart -= sizeof(file);

    hglobal = GlobalAlloc( GMEM_MOVEABLE, stat.cbSize.u.LowPart );
    if (!hglobal) return E_OUTOFMEMORY;
    dib = GlobalLock( hglobal );

    hr = IStream_Read( stm, dib, sizeof(DWORD), &read );
    if (hr != S_OK || read != sizeof(DWORD)) goto fail;
    bi_size = *(DWORD *)dib;
    if (stat.cbSize.QuadPart < bi_size) goto fail;

    hr = IStream_Read( stm, (char *)dib + sizeof(DWORD), bi_size - sizeof(DWORD), &read );
    if (hr != S_OK || read != bi_size - sizeof(DWORD)) goto fail;

    info_size = bitmap_info_size( dib, DIB_RGB_COLORS );
    if (stat.cbSize.QuadPart < info_size) goto fail;
    if (info_size > bi_size)
    {
        hr = IStream_Read( stm, (char *)dib + bi_size, info_size - bi_size, &read );
        if (hr != S_OK || read != info_size - bi_size) goto fail;
    }
    stat.cbSize.QuadPart -= info_size;

    if (file.bfOffBits)
    {
        LARGE_INTEGER skip;

        skip.QuadPart = file.bfOffBits - sizeof(file) - info_size;
        if (stat.cbSize.QuadPart < skip.QuadPart) goto fail;
        hr = IStream_Seek( stm, skip, STREAM_SEEK_CUR, NULL );
        if (hr != S_OK) goto fail;
        stat.cbSize.QuadPart -= skip.QuadPart;
    }

    hr = IStream_Read( stm, (char *)dib + info_size, stat.cbSize.u.LowPart, &read );
    if (hr != S_OK || read != stat.cbSize.QuadPart) goto fail;

    if (bi_size >= sizeof(*info))
    {
        info = (BITMAPINFOHEADER *)dib;
        if (info->biXPelsPerMeter == 0 || info->biYPelsPerMeter == 0)
        {
            HDC hdc = GetDC( 0 );
            info->biXPelsPerMeter = MulDiv( GetDeviceCaps( hdc, LOGPIXELSX ), 10000, 254 );
            info->biYPelsPerMeter = MulDiv( GetDeviceCaps( hdc, LOGPIXELSY ), 10000, 254 );
            ReleaseDC( 0, hdc );
        }
    }

    GlobalUnlock( hglobal );

    cache_entry->data_cf = cache_entry->fmtetc.cfFormat;
    cache_entry->stgmedium.tymed = TYMED_HGLOBAL;
    cache_entry->stgmedium.u.hGlobal = hglobal;

    return S_OK;

fail:
    GlobalUnlock( hglobal );
    GlobalFree( hglobal );
    return E_FAIL;

}

/************************************************************************
 * DataCacheEntry_LoadData
 *
 * This method will read information for the requested presentation
 * into the given structure.
 *
 * Param:
 *   This - The entry to load the data from.
 *
 * Returns:
 *   This method returns a metafile handle if it is successful.
 *   it will return 0 if not.
 */
static HRESULT DataCacheEntry_LoadData(DataCacheEntry *cache_entry)
{
    HRESULT hr;
    IStream *stm;

    hr = DataCacheEntry_OpenPresStream( cache_entry, &stm );
    if (FAILED(hr)) return hr;

    switch (cache_entry->fmtetc.cfFormat)
    {
    case CF_METAFILEPICT:
        hr = load_mf_pict( cache_entry, stm );
        break;

    case CF_DIB:
        hr = load_dib( cache_entry, stm );
        break;

    default:
        FIXME( "Unimplemented clip format %x\n", cache_entry->fmtetc.cfFormat );
        hr = E_NOTIMPL;
    }

    IStream_Release( stm );
    return hr;
}

static HRESULT DataCacheEntry_CreateStream(DataCacheEntry *cache_entry,
                                           IStorage *storage, IStream **stream)
{
    WCHAR wszName[] = {2,'O','l','e','P','r','e','s',
        '0' + (cache_entry->stream_number / 100) % 10,
        '0' + (cache_entry->stream_number / 10) % 10,
        '0' + cache_entry->stream_number % 10, 0};

    /* FIXME: cache the created stream in This? */
    return IStorage_CreateStream(storage, wszName,
                                 STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE,
                                 0, 0, stream);
}

static HRESULT DataCacheEntry_Save(DataCacheEntry *cache_entry, IStorage *storage,
                                   BOOL same_as_load)
{
    PresentationDataHeader header;
    HRESULT hr;
    IStream *pres_stream;
    void *data = NULL;

    TRACE("stream_number = %d, fmtetc = %s\n", cache_entry->stream_number, debugstr_formatetc(&cache_entry->fmtetc));

    hr = DataCacheEntry_CreateStream(cache_entry, storage, &pres_stream);
    if (FAILED(hr))
        return hr;

    hr = write_clipformat(pres_stream, cache_entry->data_cf);
    if (FAILED(hr))
        return hr;

    if (cache_entry->fmtetc.ptd)
        FIXME("ptd not serialized\n");
    header.unknown3 = 4;
    header.dvAspect = cache_entry->fmtetc.dwAspect;
    header.lindex = cache_entry->fmtetc.lindex;
    header.advf = cache_entry->advise_flags;
    header.unknown7 = 0;
    header.dwObjectExtentX = 0;
    header.dwObjectExtentY = 0;
    header.dwSize = 0;

    /* size the data */
    switch (cache_entry->data_cf)
    {
        case CF_METAFILEPICT:
        {
            if (cache_entry->stgmedium.tymed != TYMED_NULL)
            {
                const METAFILEPICT *mfpict = GlobalLock(cache_entry->stgmedium.u.hMetaFilePict);
                if (!mfpict)
                {
                    IStream_Release(pres_stream);
                    return DV_E_STGMEDIUM;
                }
                header.dwObjectExtentX = mfpict->xExt;
                header.dwObjectExtentY = mfpict->yExt;
                header.dwSize = GetMetaFileBitsEx(mfpict->hMF, 0, NULL);
                GlobalUnlock(cache_entry->stgmedium.u.hMetaFilePict);
            }
            break;
        }
        default:
            break;
    }

    /*
     * Write the header.
     */
    hr = IStream_Write(pres_stream, &header, sizeof(PresentationDataHeader),
                       NULL);
    if (FAILED(hr))
    {
        IStream_Release(pres_stream);
        return hr;
    }

    /* get the data */
    switch (cache_entry->data_cf)
    {
        case CF_METAFILEPICT:
        {
            if (cache_entry->stgmedium.tymed != TYMED_NULL)
            {
                const METAFILEPICT *mfpict = GlobalLock(cache_entry->stgmedium.u.hMetaFilePict);
                if (!mfpict)
                {
                    IStream_Release(pres_stream);
                    return DV_E_STGMEDIUM;
                }
                data = HeapAlloc(GetProcessHeap(), 0, header.dwSize);
                GetMetaFileBitsEx(mfpict->hMF, header.dwSize, data);
                GlobalUnlock(cache_entry->stgmedium.u.hMetaFilePict);
            }
            break;
        }
        default:
            break;
    }

    if (data)
        hr = IStream_Write(pres_stream, data, header.dwSize, NULL);
    HeapFree(GetProcessHeap(), 0, data);

    IStream_Release(pres_stream);
    return hr;
}

/* helper for copying STGMEDIUM of type bitmap, MF, EMF or HGLOBAL.
* does no checking of whether src_stgm has a supported tymed, so this should be
* done in the caller */
static HRESULT copy_stg_medium(CLIPFORMAT cf, STGMEDIUM *dest_stgm,
                               const STGMEDIUM *src_stgm)
{
    if (src_stgm->tymed == TYMED_MFPICT)
    {
        const METAFILEPICT *src_mfpict = GlobalLock(src_stgm->u.hMetaFilePict);
        METAFILEPICT *dest_mfpict;

        if (!src_mfpict)
            return DV_E_STGMEDIUM;
        dest_stgm->u.hMetaFilePict = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAFILEPICT));
        dest_mfpict = GlobalLock(dest_stgm->u.hMetaFilePict);
        if (!dest_mfpict)
        {
            GlobalUnlock(src_stgm->u.hMetaFilePict);
            return E_OUTOFMEMORY;
        }
        *dest_mfpict = *src_mfpict;
        dest_mfpict->hMF = CopyMetaFileW(src_mfpict->hMF, NULL);
        GlobalUnlock(src_stgm->u.hMetaFilePict);
        GlobalUnlock(dest_stgm->u.hMetaFilePict);
    }
    else if (src_stgm->tymed != TYMED_NULL)
    {
        dest_stgm->u.hGlobal = OleDuplicateData(src_stgm->u.hGlobal, cf,
                                                GMEM_MOVEABLE);
        if (!dest_stgm->u.hGlobal)
            return E_OUTOFMEMORY;
    }
    dest_stgm->tymed = src_stgm->tymed;
    dest_stgm->pUnkForRelease = src_stgm->pUnkForRelease;
    if (dest_stgm->pUnkForRelease)
        IUnknown_AddRef(dest_stgm->pUnkForRelease);
    return S_OK;
}

static HGLOBAL synthesize_dib( HBITMAP bm )
{
    HDC hdc = GetDC( 0 );
    BITMAPINFOHEADER header;
    BITMAPINFO *bmi;
    HGLOBAL ret = 0;
    DWORD header_size;

    memset( &header, 0, sizeof(header) );
    header.biSize = sizeof(header);
    if (!GetDIBits( hdc, bm, 0, 0, NULL, (BITMAPINFO *)&header, DIB_RGB_COLORS )) goto done;

    header_size = bitmap_info_size( (BITMAPINFO *)&header, DIB_RGB_COLORS );
    if (!(ret = GlobalAlloc( GMEM_MOVEABLE, header_size + header.biSizeImage ))) goto done;
    bmi = GlobalLock( ret );
    memset( bmi, 0, header_size );
    memcpy( bmi, &header, header.biSize );
    GetDIBits( hdc, bm, 0, abs(header.biHeight), (char *)bmi + header_size, bmi, DIB_RGB_COLORS );
    GlobalUnlock( ret );

done:
    ReleaseDC( 0, hdc );
    return ret;
}

static HBITMAP synthesize_bitmap( HGLOBAL dib )
{
    HBITMAP ret = 0;
    BITMAPINFO *bmi;
    HDC hdc = GetDC( 0 );

    if ((bmi = GlobalLock( dib )))
    {
        /* FIXME: validate data size */
        ret = CreateDIBitmap( hdc, &bmi->bmiHeader, CBM_INIT,
                              (char *)bmi + bitmap_info_size( bmi, DIB_RGB_COLORS ),
                              bmi, DIB_RGB_COLORS );
        GlobalUnlock( dib );
    }
    ReleaseDC( 0, hdc );
    return ret;
}

static HRESULT DataCacheEntry_SetData(DataCacheEntry *cache_entry,
                                      const FORMATETC *formatetc,
                                      STGMEDIUM *stgmedium,
                                      BOOL fRelease)
{
    STGMEDIUM dib_copy;

    if ((!cache_entry->fmtetc.cfFormat && !formatetc->cfFormat) ||
        (cache_entry->fmtetc.tymed == TYMED_NULL && formatetc->tymed == TYMED_NULL) ||
        stgmedium->tymed == TYMED_NULL)
    {
        WARN("invalid formatetc\n");
        return DV_E_FORMATETC;
    }

    cache_entry->dirty = TRUE;
    ReleaseStgMedium(&cache_entry->stgmedium);
    cache_entry->data_cf = cache_entry->fmtetc.cfFormat ? cache_entry->fmtetc.cfFormat : formatetc->cfFormat;

    if (formatetc->cfFormat == CF_BITMAP)
    {
        dib_copy.tymed = TYMED_HGLOBAL;
        dib_copy.u.hGlobal = synthesize_dib( stgmedium->u.hBitmap );
        dib_copy.pUnkForRelease = NULL;
        if (fRelease) ReleaseStgMedium(stgmedium);
        stgmedium = &dib_copy;
        fRelease = TRUE;
    }

    if (fRelease)
    {
        cache_entry->stgmedium = *stgmedium;
        return S_OK;
    }
    else
        return copy_stg_medium(cache_entry->data_cf,
                               &cache_entry->stgmedium, stgmedium);
}

static HRESULT DataCacheEntry_GetData(DataCacheEntry *cache_entry, FORMATETC *fmt, STGMEDIUM *stgmedium)
{
    if (cache_entry->stgmedium.tymed == TYMED_NULL && cache_entry->stream)
    {
        HRESULT hr = DataCacheEntry_LoadData(cache_entry);
        if (FAILED(hr))
            return hr;
    }
    if (cache_entry->stgmedium.tymed == TYMED_NULL)
        return OLE_E_BLANK;

    if (fmt->cfFormat == CF_BITMAP)
    {
        stgmedium->tymed = TYMED_GDI;
        stgmedium->u.hBitmap = synthesize_bitmap( cache_entry->stgmedium.u.hGlobal );
        stgmedium->pUnkForRelease = NULL;
        return S_OK;
    }
    return copy_stg_medium(cache_entry->data_cf, stgmedium, &cache_entry->stgmedium);
}

static inline HRESULT DataCacheEntry_DiscardData(DataCacheEntry *cache_entry)
{
    ReleaseStgMedium(&cache_entry->stgmedium);
    cache_entry->data_cf = cache_entry->fmtetc.cfFormat;
    return S_OK;
}

static inline void DataCacheEntry_HandsOffStorage(DataCacheEntry *cache_entry)
{
    if (cache_entry->stream)
    {
        IStream_Release(cache_entry->stream);
        cache_entry->stream = NULL;
    }
}

static inline DWORD tymed_from_cf( DWORD cf )
{
    switch( cf )
    {
    case CF_BITMAP:       return TYMED_GDI;
    case CF_METAFILEPICT: return TYMED_MFPICT;
    case CF_ENHMETAFILE:  return TYMED_ENHMF;
    case CF_DIB:
    default:              return TYMED_HGLOBAL;
    }
}

/****************************************************************
 *  create_automatic_entry
 *
 * Creates an appropriate cache entry for one of the CLSID_Picture_
 * classes.  The connection id of the entry is one.  Any pre-existing
 * automatic entry is re-assigned a new connection id, and moved to
 * the end of the list.
 */
static HRESULT create_automatic_entry(DataCache *cache, const CLSID *clsid)
{
    static const struct data
    {
        const CLSID *clsid;
        FORMATETC fmt;
    } data[] =
    {
        { &CLSID_Picture_Dib,         { CF_DIB,          0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } },
        { &CLSID_Picture_Metafile,    { CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT } },
        { &CLSID_Picture_EnhMetafile, { CF_ENHMETAFILE,  0, DVASPECT_CONTENT, -1, TYMED_ENHMF } },
        { NULL }
    };
    const struct data *ptr = data;
    struct list *head;
    DataCacheEntry *entry;

    if (IsEqualCLSID( &cache->clsid, clsid )) return S_OK;

    /* move and reassign any pre-existing automatic entry */
    if ((head = list_head( &cache->cache_list )))
    {
        entry = LIST_ENTRY( head, DataCacheEntry, entry );
        if (entry->id == 1)
        {
            list_remove( &entry->entry );
            entry->id = cache->last_cache_id++;
            list_add_tail( &cache->cache_list, &entry->entry );
        }
    }

    while (ptr->clsid)
    {
        if (IsEqualCLSID( clsid, ptr->clsid ))
            return DataCache_CreateEntry( cache, &ptr->fmt, 0, TRUE, NULL );
        ptr++;
    }
    return S_OK;
}

/*********************************************************
 * Method implementation for the  non delegating IUnknown
 * part of the DataCache class.
 */

/************************************************************************
 * DataCache_NDIUnknown_QueryInterface (IUnknown)
 *
 * This version of QueryInterface will not delegate its implementation
 * to the outer unknown.
 */
static HRESULT WINAPI DataCache_NDIUnknown_QueryInterface(
            IUnknown*      iface,
            REFIID         riid,
            void**         ppvObject)
{
  DataCache *this = impl_from_IUnknown(iface);

  if ( ppvObject==0 )
    return E_INVALIDARG;

  *ppvObject = 0;

  if (IsEqualIID(&IID_IUnknown, riid))
  {
    if (this->outer_unk == iface) /* non-aggregated, return IUnknown from IOleCache2 */
      *ppvObject = &this->IOleCache2_iface;
    else
      *ppvObject = iface;
  }
  else if (IsEqualIID(&IID_IDataObject, riid))
  {
    *ppvObject = &this->IDataObject_iface;
  }
  else if ( IsEqualIID(&IID_IPersistStorage, riid)  ||
            IsEqualIID(&IID_IPersist, riid) )
  {
    *ppvObject = &this->IPersistStorage_iface;
  }
  else if ( IsEqualIID(&IID_IViewObject, riid) ||
            IsEqualIID(&IID_IViewObject2, riid) )
  {
    *ppvObject = &this->IViewObject2_iface;
  }
  else if ( IsEqualIID(&IID_IOleCache, riid) ||
            IsEqualIID(&IID_IOleCache2, riid) )
  {
    *ppvObject = &this->IOleCache2_iface;
  }
  else if ( IsEqualIID(&IID_IOleCacheControl, riid) )
  {
    *ppvObject = &this->IOleCacheControl_iface;
  }

  if ((*ppvObject)==0)
  {
    WARN( "() : asking for unsupported interface %s\n", debugstr_guid(riid));
    return E_NOINTERFACE;
  }

  IUnknown_AddRef((IUnknown*)*ppvObject);

  return S_OK;
}

/************************************************************************
 * DataCache_NDIUnknown_AddRef (IUnknown)
 *
 * This version of QueryInterface will not delegate its implementation
 * to the outer unknown.
 */
static ULONG WINAPI DataCache_NDIUnknown_AddRef(
            IUnknown*      iface)
{
  DataCache *this = impl_from_IUnknown(iface);
  return InterlockedIncrement(&this->ref);
}

/************************************************************************
 * DataCache_NDIUnknown_Release (IUnknown)
 *
 * This version of QueryInterface will not delegate its implementation
 * to the outer unknown.
 */
static ULONG WINAPI DataCache_NDIUnknown_Release(
            IUnknown*      iface)
{
  DataCache *this = impl_from_IUnknown(iface);
  ULONG ref;

  ref = InterlockedDecrement(&this->ref);

  if (ref == 0) DataCache_Destroy(this);

  return ref;
}

/*********************************************************
 * Method implementation for the IDataObject
 * part of the DataCache class.
 */

/************************************************************************
 * DataCache_IDataObject_QueryInterface (IUnknown)
 */
static HRESULT WINAPI DataCache_IDataObject_QueryInterface(
            IDataObject*     iface,
            REFIID           riid,
            void**           ppvObject)
{
  DataCache *this = impl_from_IDataObject(iface);

  return IUnknown_QueryInterface(this->outer_unk, riid, ppvObject);
}

/************************************************************************
 * DataCache_IDataObject_AddRef (IUnknown)
 */
static ULONG WINAPI DataCache_IDataObject_AddRef(
            IDataObject*     iface)
{
  DataCache *this = impl_from_IDataObject(iface);

  return IUnknown_AddRef(this->outer_unk);
}

/************************************************************************
 * DataCache_IDataObject_Release (IUnknown)
 */
static ULONG WINAPI DataCache_IDataObject_Release(
            IDataObject*     iface)
{
  DataCache *this = impl_from_IDataObject(iface);

  return IUnknown_Release(this->outer_unk);
}

/************************************************************************
 * DataCache_GetData
 *
 * Get Data from a source dataobject using format pformatetcIn->cfFormat
 */
static HRESULT WINAPI DataCache_GetData(
	    IDataObject*     iface,
	    LPFORMATETC      pformatetcIn,
	    STGMEDIUM*       pmedium)
{
    DataCache *This = impl_from_IDataObject(iface);
    DataCacheEntry *cache_entry;

    TRACE("(%p, %s, %p)\n", iface, debugstr_formatetc(pformatetcIn), pmedium);

    memset(pmedium, 0, sizeof(*pmedium));

    cache_entry = DataCache_GetEntryForFormatEtc(This, pformatetcIn);
    if (!cache_entry)
        return OLE_E_BLANK;

    return DataCacheEntry_GetData(cache_entry, pformatetcIn, pmedium);
}

static HRESULT WINAPI DataCache_GetDataHere(
	    IDataObject*     iface,
	    LPFORMATETC      pformatetc,
	    STGMEDIUM*       pmedium)
{
  FIXME("stub\n");
  return E_NOTIMPL;
}

static HRESULT WINAPI DataCache_QueryGetData( IDataObject *iface, FORMATETC *fmt )
{
    DataCache *This = impl_from_IDataObject( iface );
    DataCacheEntry *cache_entry;

    TRACE( "(%p)->(%s)\n", iface, debugstr_formatetc( fmt ) );
    cache_entry = DataCache_GetEntryForFormatEtc( This, fmt );

    return cache_entry ? S_OK : S_FALSE;
}

/************************************************************************
 * DataCache_EnumFormatEtc (IDataObject)
 *
 * The data cache doesn't implement this method.
 */
static HRESULT WINAPI DataCache_GetCanonicalFormatEtc(
	    IDataObject*     iface,
	    LPFORMATETC      pformatectIn,
	    LPFORMATETC      pformatetcOut)
{
  TRACE("()\n");
  return E_NOTIMPL;
}

/************************************************************************
 * DataCache_IDataObject_SetData (IDataObject)
 *
 * This method is delegated to the IOleCache2 implementation.
 */
static HRESULT WINAPI DataCache_IDataObject_SetData(
	    IDataObject*     iface,
	    LPFORMATETC      pformatetc,
	    STGMEDIUM*       pmedium,
	    BOOL             fRelease)
{
  IOleCache2* oleCache = NULL;
  HRESULT     hres;

  TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);

  hres = IDataObject_QueryInterface(iface, &IID_IOleCache2, (void**)&oleCache);

  if (FAILED(hres))
    return E_UNEXPECTED;

  hres = IOleCache2_SetData(oleCache, pformatetc, pmedium, fRelease);

  IOleCache2_Release(oleCache);

  return hres;
}

/************************************************************************
 * DataCache_EnumFormatEtc (IDataObject)
 *
 * The data cache doesn't implement this method.
 */
static HRESULT WINAPI DataCache_EnumFormatEtc(
	    IDataObject*     iface,
	    DWORD            dwDirection,
	    IEnumFORMATETC** ppenumFormatEtc)
{
  TRACE("()\n");
  return E_NOTIMPL;
}

/************************************************************************
 * DataCache_DAdvise (IDataObject)
 *
 * The data cache doesn't support connections.
 */
static HRESULT WINAPI DataCache_DAdvise(
	    IDataObject*     iface,
	    FORMATETC*       pformatetc,
	    DWORD            advf,
	    IAdviseSink*     pAdvSink,
	    DWORD*           pdwConnection)
{
  TRACE("()\n");
  return OLE_E_ADVISENOTSUPPORTED;
}

/************************************************************************
 * DataCache_DUnadvise (IDataObject)
 *
 * The data cache doesn't support connections.
 */
static HRESULT WINAPI DataCache_DUnadvise(
	    IDataObject*     iface,
	    DWORD            dwConnection)
{
  TRACE("()\n");
  return OLE_E_NOCONNECTION;
}

/************************************************************************
 * DataCache_EnumDAdvise (IDataObject)
 *
 * The data cache doesn't support connections.
 */
static HRESULT WINAPI DataCache_EnumDAdvise(
	    IDataObject*     iface,
	    IEnumSTATDATA**  ppenumAdvise)
{
  TRACE("()\n");
  return OLE_E_ADVISENOTSUPPORTED;
}

/*********************************************************
 * Method implementation for the IDataObject
 * part of the DataCache class.
 */

/************************************************************************
 * DataCache_IPersistStorage_QueryInterface (IUnknown)
 */
static HRESULT WINAPI DataCache_IPersistStorage_QueryInterface(
            IPersistStorage* iface,
            REFIID           riid,
            void**           ppvObject)
{
  DataCache *this = impl_from_IPersistStorage(iface);

  return IUnknown_QueryInterface(this->outer_unk, riid, ppvObject);
}

/************************************************************************
 * DataCache_IPersistStorage_AddRef (IUnknown)
 */
static ULONG WINAPI DataCache_IPersistStorage_AddRef(
            IPersistStorage* iface)
{
  DataCache *this = impl_from_IPersistStorage(iface);

  return IUnknown_AddRef(this->outer_unk);
}

/************************************************************************
 * DataCache_IPersistStorage_Release (IUnknown)
 */
static ULONG WINAPI DataCache_IPersistStorage_Release(
            IPersistStorage* iface)
{
  DataCache *this = impl_from_IPersistStorage(iface);

  return IUnknown_Release(this->outer_unk);
}

/************************************************************************
 * DataCache_GetClassID (IPersistStorage)
 *
 */
static HRESULT WINAPI DataCache_GetClassID(IPersistStorage *iface, CLSID *clsid)
{
    DataCache *This = impl_from_IPersistStorage( iface );

    TRACE( "(%p, %p) returning %s\n", iface, clsid, debugstr_guid(&This->clsid) );
    *clsid = This->clsid;

    return S_OK;
}

/************************************************************************
 * DataCache_IsDirty (IPersistStorage)
 */
static HRESULT WINAPI DataCache_IsDirty(
            IPersistStorage* iface)
{
    DataCache *This = impl_from_IPersistStorage(iface);
    DataCacheEntry *cache_entry;

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

    if (This->dirty)
        return S_OK;

    LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry)
        if (cache_entry->dirty)
            return S_OK;

    return S_FALSE;
}

/************************************************************************
 * DataCache_InitNew (IPersistStorage)
 *
 * The data cache implementation of IPersistStorage_InitNew simply stores
 * the storage pointer.
 */
static HRESULT WINAPI DataCache_InitNew(
            IPersistStorage* iface,
	    IStorage*        pStg)
{
    DataCache *This = impl_from_IPersistStorage(iface);
    CLSID clsid;
    HRESULT hr;

    TRACE("(%p, %p)\n", iface, pStg);

    if (This->presentationStorage != NULL)
        return CO_E_ALREADYINITIALIZED;

    This->presentationStorage = pStg;

    IStorage_AddRef(This->presentationStorage);
    This->dirty = TRUE;
    ReadClassStg( pStg, &clsid );
    hr = create_automatic_entry( This, &clsid );
    if (FAILED(hr))
    {
        IStorage_Release( pStg );
        This->presentationStorage = NULL;
        return hr;
    }
    This->clsid = clsid;

    return S_OK;
}


static HRESULT add_cache_entry( DataCache *This, const FORMATETC *fmt, DWORD advf, IStream *stm,
                                enum stream_type type )
{
    DataCacheEntry *cache_entry;
    HRESULT hr = S_OK;

    TRACE( "loading entry with formatetc: %s\n", debugstr_formatetc( fmt ) );

    cache_entry = DataCache_GetEntryForFormatEtc( This, fmt );
    if (!cache_entry)
        hr = DataCache_CreateEntry( This, fmt, advf, FALSE, &cache_entry );
    if (SUCCEEDED( hr ))
    {
        DataCacheEntry_DiscardData( cache_entry );
        if (cache_entry->stream) IStream_Release( cache_entry->stream );
        cache_entry->stream = stm;
        IStream_AddRef( stm );
        cache_entry->stream_type = type;
        cache_entry->dirty = FALSE;
    }
    return hr;
}

static HRESULT parse_pres_streams( DataCache *This, IStorage *stg )
{
    HRESULT hr;
    IEnumSTATSTG *stat_enum;
    STATSTG stat;
    IStream *stm;
    PresentationDataHeader header;
    ULONG actual_read;
    CLIPFORMAT clipformat;
    FORMATETC fmtetc;

    hr = IStorage_EnumElements( stg, 0, NULL, 0, &stat_enum );
    if (FAILED( hr )) return hr;

    while ((hr = IEnumSTATSTG_Next( stat_enum, 1, &stat, NULL )) == S_OK)
    {
        if (DataCache_IsPresentationStream( &stat ))
        {
            hr = IStorage_OpenStream( stg, stat.pwcsName, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE,
                                      0, &stm );
            if (SUCCEEDED( hr ))
            {
                hr = read_clipformat( stm, &clipformat );

                if (hr == S_OK)
                    hr = IStream_Read( stm, &header, sizeof(header), &actual_read );

                if (hr == S_OK && actual_read == sizeof(header))
                {
                    fmtetc.cfFormat = clipformat;
                    fmtetc.ptd = NULL; /* FIXME */
                    fmtetc.dwAspect = header.dvAspect;
                    fmtetc.lindex = header.lindex;
                    fmtetc.tymed = tymed_from_cf( clipformat );

                    add_cache_entry( This, &fmtetc, header.advf, stm, pres_stream );
                }
                IStream_Release( stm );
            }
        }
        CoTaskMemFree( stat.pwcsName );
    }
    IEnumSTATSTG_Release( stat_enum );

    return S_OK;
}

static const FORMATETC static_dib_fmt = { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };

static HRESULT parse_contents_stream( DataCache *This, IStorage *stg, IStream *stm )
{
    HRESULT hr;
    STATSTG stat;
    const FORMATETC *fmt;

    hr = IStorage_Stat( stg, &stat, STATFLAG_NONAME );
    if (FAILED( hr )) return hr;

    if (IsEqualCLSID( &stat.clsid, &CLSID_Picture_Dib ))
        fmt = &static_dib_fmt;
    else
    {
        FIXME("unsupported format %s\n", debugstr_guid( &stat.clsid ));
        return E_FAIL;
    }

    return add_cache_entry( This, fmt, 0, stm, contents_stream );
}

static const WCHAR CONTENTS[] = {'C','O','N','T','E','N','T','S',0};

/************************************************************************
 * DataCache_Load (IPersistStorage)
 *
 * The data cache implementation of IPersistStorage_Load doesn't
 * actually load anything. Instead, it holds on to the storage pointer
 * and it will load the presentation information when the
 * IDataObject_GetData or IViewObject2_Draw methods are called.
 */
static HRESULT WINAPI DataCache_Load( IPersistStorage *iface, IStorage *pStg )
{
    DataCache *This = impl_from_IPersistStorage(iface);
    HRESULT hr;
    IStream *stm;
    CLSID clsid;
    DataCacheEntry *entry, *cursor2;

    TRACE("(%p, %p)\n", iface, pStg);

    IPersistStorage_HandsOffStorage( iface );

    LIST_FOR_EACH_ENTRY_SAFE( entry, cursor2, &This->cache_list, DataCacheEntry, entry )
        DataCacheEntry_Destroy( This, entry );

    ReadClassStg( pStg, &clsid );
    hr = create_automatic_entry( This, &clsid );
    if (FAILED( hr )) return hr;

    This->clsid = clsid;

    hr = IStorage_OpenStream( pStg, CONTENTS, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE,
                              0, &stm );
    if (SUCCEEDED( hr ))
    {
        hr = parse_contents_stream( This, pStg, stm );
        IStream_Release( stm );
    }

    if (FAILED(hr))
        hr = parse_pres_streams( This, pStg );

    if (SUCCEEDED( hr ))
    {
        This->dirty = FALSE;
        This->presentationStorage = pStg;
        IStorage_AddRef( This->presentationStorage );
    }

    return hr;
}

/************************************************************************
 * DataCache_Save (IPersistStorage)
 *
 * Until we actually connect to a running object and retrieve new
 * information to it, we never have to save anything. However, it is
 * our responsibility to copy the information when saving to a new
 * storage.
 */
static HRESULT WINAPI DataCache_Save(
            IPersistStorage* iface,
	    IStorage*        pStg,
	    BOOL             fSameAsLoad)
{
    DataCache *This = impl_from_IPersistStorage(iface);
    DataCacheEntry *cache_entry;
    BOOL dirty = FALSE;
    HRESULT hr = S_OK;
    unsigned short stream_number = 0;

    TRACE("(%p, %p, %d)\n", iface, pStg, fSameAsLoad);

    dirty = This->dirty;
    if (!dirty)
    {
        LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry)
        {
            dirty = cache_entry->dirty;
            if (dirty)
                break;
        }
    }

    /* this is a shortcut if nothing changed */
    if (!dirty && !fSameAsLoad && This->presentationStorage)
    {
        return IStorage_CopyTo(This->presentationStorage, 0, NULL, NULL, pStg);
    }

    /* assign stream numbers to the cache entries */
    LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry)
    {
        if (cache_entry->stream_number != stream_number)
        {
            cache_entry->dirty = TRUE; /* needs to be written out again */
            cache_entry->stream_number = stream_number;
        }
        stream_number++;
    }

    /* write out the cache entries */
    LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry)
    {
        if (!fSameAsLoad || cache_entry->dirty)
        {
            hr = DataCacheEntry_Save(cache_entry, pStg, fSameAsLoad);
            if (FAILED(hr))
                break;

            cache_entry->dirty = FALSE;
        }
    }

    This->dirty = FALSE;
    return hr;
}

/************************************************************************
 * DataCache_SaveCompleted (IPersistStorage)
 *
 * This method is called to tell the cache to release the storage
 * pointer it's currently holding.
 */
static HRESULT WINAPI DataCache_SaveCompleted(
            IPersistStorage* iface,
	    IStorage*        pStgNew)
{
  TRACE("(%p, %p)\n", iface, pStgNew);

  if (pStgNew)
  {
    IPersistStorage_HandsOffStorage(iface);

    DataCache_Load(iface, pStgNew);
  }

  return S_OK;
}

/************************************************************************
 * DataCache_HandsOffStorage (IPersistStorage)
 *
 * This method is called to tell the cache to release the storage
 * pointer it's currently holding.
 */
static HRESULT WINAPI DataCache_HandsOffStorage(
            IPersistStorage* iface)
{
  DataCache *this = impl_from_IPersistStorage(iface);
  DataCacheEntry *cache_entry;

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

  if (this->presentationStorage != NULL)
  {
    IStorage_Release(this->presentationStorage);
    this->presentationStorage = NULL;
  }

  LIST_FOR_EACH_ENTRY(cache_entry, &this->cache_list, DataCacheEntry, entry)
    DataCacheEntry_HandsOffStorage(cache_entry);

  return S_OK;
}

/*********************************************************
 * Method implementation for the IViewObject2
 * part of the DataCache class.
 */

/************************************************************************
 * DataCache_IViewObject2_QueryInterface (IUnknown)
 */
static HRESULT WINAPI DataCache_IViewObject2_QueryInterface(
            IViewObject2* iface,
            REFIID           riid,
            void**           ppvObject)
{
  DataCache *this = impl_from_IViewObject2(iface);

  return IUnknown_QueryInterface(this->outer_unk, riid, ppvObject);
}

/************************************************************************
 * DataCache_IViewObject2_AddRef (IUnknown)
 */
static ULONG WINAPI DataCache_IViewObject2_AddRef(
            IViewObject2* iface)
{
  DataCache *this = impl_from_IViewObject2(iface);

  return IUnknown_AddRef(this->outer_unk);
}

/************************************************************************
 * DataCache_IViewObject2_Release (IUnknown)
 */
static ULONG WINAPI DataCache_IViewObject2_Release(
            IViewObject2* iface)
{
  DataCache *this = impl_from_IViewObject2(iface);

  return IUnknown_Release(this->outer_unk);
}

/************************************************************************
 * DataCache_Draw (IViewObject2)
 *
 * This method will draw the cached representation of the object
 * to the given device context.
 */
static HRESULT WINAPI DataCache_Draw(
            IViewObject2*    iface,
	    DWORD            dwDrawAspect,
	    LONG             lindex,
	    void*            pvAspect,
	    DVTARGETDEVICE*  ptd,
	    HDC              hdcTargetDev,
	    HDC              hdcDraw,
	    LPCRECTL         lprcBounds,
	    LPCRECTL         lprcWBounds,
	    BOOL  (CALLBACK *pfnContinue)(ULONG_PTR dwContinue),
	    ULONG_PTR        dwContinue)
{
  DataCache *This = impl_from_IViewObject2(iface);
  HRESULT                hres;
  DataCacheEntry        *cache_entry;

  TRACE("(%p, %x, %d, %p, %p, %p, %p, %p, %p, %lx)\n",
	iface,
	dwDrawAspect,
	lindex,
	pvAspect,
	hdcTargetDev,
	hdcDraw,
	lprcBounds,
	lprcWBounds,
	pfnContinue,
	dwContinue);

  if (lprcBounds==NULL)
    return E_INVALIDARG;

  LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry)
  {
    /* FIXME: compare ptd too */
    if ((cache_entry->fmtetc.dwAspect != dwDrawAspect) ||
        (cache_entry->fmtetc.lindex != lindex))
      continue;

    /* if the data hasn't been loaded yet, do it now */
    if ((cache_entry->stgmedium.tymed == TYMED_NULL) && cache_entry->stream)
    {
      hres = DataCacheEntry_LoadData(cache_entry);
      if (FAILED(hres))
        continue;
    }

    /* no data */
    if (cache_entry->stgmedium.tymed == TYMED_NULL)
      continue;

    if (pfnContinue && !pfnContinue(dwContinue)) return E_ABORT;

    switch (cache_entry->data_cf)
    {
      case CF_METAFILEPICT:
      {
        /*
         * We have to be careful not to modify the state of the
         * DC.
         */
        INT   prevMapMode;
        SIZE  oldWindowExt;
        SIZE  oldViewportExt;
        POINT oldViewportOrg;
        METAFILEPICT *mfpict;

        if ((cache_entry->stgmedium.tymed != TYMED_MFPICT) ||
            !((mfpict = GlobalLock(cache_entry->stgmedium.u.hMetaFilePict))))
          continue;

        prevMapMode = SetMapMode(hdcDraw, mfpict->mm);

        SetWindowExtEx(hdcDraw,
		       mfpict->xExt,
		       mfpict->yExt,
		       &oldWindowExt);

        SetViewportExtEx(hdcDraw,
		         lprcBounds->right - lprcBounds->left,
		         lprcBounds->bottom - lprcBounds->top,
		         &oldViewportExt);

        SetViewportOrgEx(hdcDraw,
		         lprcBounds->left,
		         lprcBounds->top,
		         &oldViewportOrg);

        PlayMetaFile(hdcDraw, mfpict->hMF);

        SetWindowExtEx(hdcDraw,
		       oldWindowExt.cx,
		       oldWindowExt.cy,
		       NULL);

        SetViewportExtEx(hdcDraw,
		         oldViewportExt.cx,
		         oldViewportExt.cy,
		         NULL);

        SetViewportOrgEx(hdcDraw,
		         oldViewportOrg.x,
		         oldViewportOrg.y,
		         NULL);

        SetMapMode(hdcDraw, prevMapMode);

        GlobalUnlock(cache_entry->stgmedium.u.hMetaFilePict);

        return S_OK;
      }
      case CF_DIB:
      {
          BITMAPINFO *info;
          BYTE *bits;

          if ((cache_entry->stgmedium.tymed != TYMED_HGLOBAL) ||
              !((info = GlobalLock( cache_entry->stgmedium.u.hGlobal ))))
              continue;

          bits = (BYTE *) info + bitmap_info_size( info, DIB_RGB_COLORS );
          StretchDIBits( hdcDraw, lprcBounds->left, lprcBounds->top,
                         lprcBounds->right - lprcBounds->left, lprcBounds->bottom - lprcBounds->top,
                         0, 0, info->bmiHeader.biWidth, info->bmiHeader.biHeight,
                         bits, info, DIB_RGB_COLORS, SRCCOPY );

          GlobalUnlock( cache_entry->stgmedium.u.hGlobal );
          return S_OK;
      }
    }
  }

  WARN("no data could be found to be drawn\n");

  return OLE_E_BLANK;
}

static HRESULT WINAPI DataCache_GetColorSet(
            IViewObject2*   iface,
	    DWORD           dwDrawAspect,
	    LONG            lindex,
	    void*           pvAspect,
	    DVTARGETDEVICE* ptd,
	    HDC             hicTargetDevice,
	    LOGPALETTE**    ppColorSet)
{
  FIXME("stub\n");
  return E_NOTIMPL;
}

static HRESULT WINAPI DataCache_Freeze(
            IViewObject2*   iface,
	    DWORD           dwDrawAspect,
	    LONG            lindex,
	    void*           pvAspect,
	    DWORD*          pdwFreeze)
{
  FIXME("stub\n");
  return E_NOTIMPL;
}

static HRESULT WINAPI DataCache_Unfreeze(
            IViewObject2*   iface,
	    DWORD           dwFreeze)
{
  FIXME("stub\n");
  return E_NOTIMPL;
}

/************************************************************************
 * DataCache_SetAdvise (IViewObject2)
 *
 * This sets-up an advisory sink with the data cache. When the object's
 * view changes, this sink is called.
 */
static HRESULT WINAPI DataCache_SetAdvise(
            IViewObject2*   iface,
	    DWORD           aspects,
	    DWORD           advf,
	    IAdviseSink*    pAdvSink)
{
  DataCache *this = impl_from_IViewObject2(iface);

  TRACE("(%p, %x, %x, %p)\n", iface, aspects, advf, pAdvSink);

  /*
   * A call to this function removes the previous sink
   */
  if (this->sinkInterface != NULL)
  {
    IAdviseSink_Release(this->sinkInterface);
    this->sinkInterface  = NULL;
    this->sinkAspects    = 0;
    this->sinkAdviseFlag = 0;
  }

  /*
   * Now, setup the new one.
   */
  if (pAdvSink!=NULL)
  {
    this->sinkInterface  = pAdvSink;
    this->sinkAspects    = aspects;
    this->sinkAdviseFlag = advf;

    IAdviseSink_AddRef(this->sinkInterface);
  }

  /*
   * When the ADVF_PRIMEFIRST flag is set, we have to advise the
   * sink immediately.
   */
  if (advf & ADVF_PRIMEFIRST)
  {
    DataCache_FireOnViewChange(this, aspects, -1);
  }

  return S_OK;
}

/************************************************************************
 * DataCache_GetAdvise (IViewObject2)
 *
 * This method queries the current state of the advise sink
 * installed on the data cache.
 */
static HRESULT WINAPI DataCache_GetAdvise(
            IViewObject2*   iface,
	    DWORD*          pAspects,
	    DWORD*          pAdvf,
	    IAdviseSink**   ppAdvSink)
{
  DataCache *this = impl_from_IViewObject2(iface);

  TRACE("(%p, %p, %p, %p)\n", iface, pAspects, pAdvf, ppAdvSink);

  /*
   * Just copy all the requested values.
   */
  if (pAspects!=NULL)
    *pAspects = this->sinkAspects;

  if (pAdvf!=NULL)
    *pAdvf = this->sinkAdviseFlag;

  if (ppAdvSink!=NULL)
  {
    if (this->sinkInterface != NULL)
        IAdviseSink_QueryInterface(this->sinkInterface,
			       &IID_IAdviseSink,
			       (void**)ppAdvSink);
    else *ppAdvSink = NULL;
  }

  return S_OK;
}

/************************************************************************
 * DataCache_GetExtent (IViewObject2)
 *
 * This method retrieves the "natural" size of this cached object.
 */
static HRESULT WINAPI DataCache_GetExtent(
            IViewObject2*   iface,
	    DWORD           dwDrawAspect,
	    LONG            lindex,
	    DVTARGETDEVICE* ptd,
	    LPSIZEL         lpsizel)
{
  DataCache *This = impl_from_IViewObject2(iface);
  HRESULT                hres = E_FAIL;
  DataCacheEntry        *cache_entry;

  TRACE("(%p, %x, %d, %p, %p)\n",
	iface, dwDrawAspect, lindex, ptd, lpsizel);

  if (lpsizel==NULL)
    return E_POINTER;

  lpsizel->cx = 0;
  lpsizel->cy = 0;

  if (lindex!=-1)
    FIXME("Unimplemented flag lindex = %d\n", lindex);

  /*
   * Right now, we support only the callback from
   * the default handler.
   */
  if (ptd!=NULL)
    FIXME("Unimplemented ptd = %p\n", ptd);

  LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry)
  {
    /* FIXME: compare ptd too */
    if ((cache_entry->fmtetc.dwAspect != dwDrawAspect) ||
        (cache_entry->fmtetc.lindex != lindex))
      continue;

    /* if the data hasn't been loaded yet, do it now */
    if ((cache_entry->stgmedium.tymed == TYMED_NULL) && cache_entry->stream)
    {
      hres = DataCacheEntry_LoadData(cache_entry);
      if (FAILED(hres))
        continue;
    }

    /* no data */
    if (cache_entry->stgmedium.tymed == TYMED_NULL)
      continue;


    switch (cache_entry->data_cf)
    {
      case CF_METAFILEPICT:
      {
          METAFILEPICT *mfpict;

          if ((cache_entry->stgmedium.tymed != TYMED_MFPICT) ||
              !((mfpict = GlobalLock(cache_entry->stgmedium.u.hMetaFilePict))))
            continue;

        lpsizel->cx = mfpict->xExt;
        lpsizel->cy = mfpict->yExt;

        GlobalUnlock(cache_entry->stgmedium.u.hMetaFilePict);

        return S_OK;
      }
      case CF_DIB:
      {
          BITMAPINFOHEADER *info;
          LONG x_pels_m, y_pels_m;


          if ((cache_entry->stgmedium.tymed != TYMED_HGLOBAL) ||
              !((info = GlobalLock( cache_entry->stgmedium.u.hGlobal ))))
              continue;

          x_pels_m = info->biXPelsPerMeter;
          y_pels_m = info->biYPelsPerMeter;

          /* Size in units of 0.01mm (ie. MM_HIMETRIC) */
          if (x_pels_m != 0 && y_pels_m != 0)
          {
              lpsizel->cx = info->biWidth  * 100000 / x_pels_m;
              lpsizel->cy = info->biHeight * 100000 / y_pels_m;
          }
          else
          {
              HDC hdc = GetDC( 0 );
              lpsizel->cx = info->biWidth  * 2540 / GetDeviceCaps( hdc, LOGPIXELSX );
              lpsizel->cy = info->biHeight * 2540 / GetDeviceCaps( hdc, LOGPIXELSY );

              ReleaseDC( 0, hdc );
          }

          GlobalUnlock( cache_entry->stgmedium.u.hGlobal );

          return S_OK;
      }
    }
  }

  WARN("no data could be found to get the extents from\n");

  /*
   * This method returns OLE_E_BLANK when it fails.
   */
  return OLE_E_BLANK;
}


/*********************************************************
 * Method implementation for the IOleCache2
 * part of the DataCache class.
 */

/************************************************************************
 * DataCache_IOleCache2_QueryInterface (IUnknown)
 */
static HRESULT WINAPI DataCache_IOleCache2_QueryInterface(
            IOleCache2*     iface,
            REFIID          riid,
            void**          ppvObject)
{
  DataCache *this = impl_from_IOleCache2(iface);

  return IUnknown_QueryInterface(this->outer_unk, riid, ppvObject);
}

/************************************************************************
 * DataCache_IOleCache2_AddRef (IUnknown)
 */
static ULONG WINAPI DataCache_IOleCache2_AddRef(
            IOleCache2*     iface)
{
  DataCache *this = impl_from_IOleCache2(iface);

  return IUnknown_AddRef(this->outer_unk);
}

/************************************************************************
 * DataCache_IOleCache2_Release (IUnknown)
 */
static ULONG WINAPI DataCache_IOleCache2_Release(
            IOleCache2*     iface)
{
  DataCache *this = impl_from_IOleCache2(iface);

  return IUnknown_Release(this->outer_unk);
}

/*****************************************************************************
 * setup_sink
 *
 * Set up the sink connection to the running object.
 */
static HRESULT setup_sink(DataCache *This, DataCacheEntry *cache_entry)
{
    HRESULT hr = S_FALSE;
    DWORD flags;

    /* Clear the ADVFCACHE_* bits.  Native also sets the two highest bits for some reason. */
    flags = cache_entry->advise_flags & ~(ADVFCACHE_NOHANDLER | ADVFCACHE_FORCEBUILTIN | ADVFCACHE_ONSAVE);

    if(This->running_object)
        if(!(flags & ADVF_NODATA))
            hr = IDataObject_DAdvise(This->running_object, &cache_entry->fmtetc, flags,
                                     &This->IAdviseSink_iface, &cache_entry->sink_id);
    return hr;
}

static HRESULT WINAPI DataCache_Cache(
            IOleCache2*     iface,
	    FORMATETC*      pformatetc,
	    DWORD           advf,
	    DWORD*          pdwConnection)
{
    DataCache *This = impl_from_IOleCache2(iface);
    DataCacheEntry *cache_entry;
    HRESULT hr;
    FORMATETC fmt_cpy;

    TRACE("(%p, 0x%x, %p)\n", pformatetc, advf, pdwConnection);

    if (!pformatetc || !pdwConnection)
        return E_INVALIDARG;

    TRACE("pformatetc = %s\n", debugstr_formatetc(pformatetc));

    fmt_cpy = *pformatetc; /* No need for a deep copy */
    if (fmt_cpy.cfFormat == CF_BITMAP && fmt_cpy.tymed == TYMED_GDI)
    {
        fmt_cpy.cfFormat = CF_DIB;
        fmt_cpy.tymed = TYMED_HGLOBAL;
    }

    *pdwConnection = 0;

    cache_entry = DataCache_GetEntryForFormatEtc(This, &fmt_cpy);
    if (cache_entry)
    {
        TRACE("found an existing cache entry\n");
        *pdwConnection = cache_entry->id;
        return CACHE_S_SAMECACHE;
    }

    hr = DataCache_CreateEntry(This, &fmt_cpy, advf, FALSE, &cache_entry);

    if (SUCCEEDED(hr))
    {
        *pdwConnection = cache_entry->id;
        setup_sink(This, cache_entry);
    }

    return hr;
}

static HRESULT WINAPI DataCache_Uncache(
	    IOleCache2*     iface,
	    DWORD           dwConnection)
{
    DataCache *This = impl_from_IOleCache2(iface);
    DataCacheEntry *cache_entry;

    TRACE("(%d)\n", dwConnection);

    LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry)
        if (cache_entry->id == dwConnection)
        {
            DataCacheEntry_Destroy(This, cache_entry);
            return S_OK;
        }

    WARN("no connection found for %d\n", dwConnection);

    return OLE_E_NOCONNECTION;
}

static HRESULT WINAPI DataCache_EnumCache(IOleCache2 *iface,
                                          IEnumSTATDATA **enum_stat)
{
    DataCache *This = impl_from_IOleCache2( iface );
    DataCacheEntry *cache_entry;
    int i = 0, count = 0;
    STATDATA *data;
    HRESULT hr;

    TRACE( "(%p, %p)\n", This, enum_stat );

    LIST_FOR_EACH_ENTRY( cache_entry, &This->cache_list, DataCacheEntry, entry )
    {
        count++;
        if (cache_entry->fmtetc.cfFormat == CF_DIB)
            count++;
    }

    data = CoTaskMemAlloc( count * sizeof(*data) );
    if (!data) return E_OUTOFMEMORY;

    LIST_FOR_EACH_ENTRY( cache_entry, &This->cache_list, DataCacheEntry, entry )
    {
        if (i == count) goto fail;
        hr = copy_formatetc( &data[i].formatetc, &cache_entry->fmtetc );
        if (FAILED(hr)) goto fail;
        data[i].advf = cache_entry->advise_flags;
        data[i].pAdvSink = NULL;
        data[i].dwConnection = cache_entry->id;
        i++;

        if (cache_entry->fmtetc.cfFormat == CF_DIB)
        {
            if (i == count) goto fail;
            hr = copy_formatetc( &data[i].formatetc, &cache_entry->fmtetc );
            if (FAILED(hr)) goto fail;
            data[i].formatetc.cfFormat = CF_BITMAP;
            data[i].formatetc.tymed = TYMED_GDI;
            data[i].advf = cache_entry->advise_flags;
            data[i].pAdvSink = NULL;
            data[i].dwConnection = cache_entry->id;
            i++;
        }
    }

    hr = EnumSTATDATA_Construct( NULL, 0, i, data, FALSE, enum_stat );
    if (SUCCEEDED(hr)) return hr;

fail:
    while (i--) CoTaskMemFree( data[i].formatetc.ptd );
    CoTaskMemFree( data );
    return hr;
}

static HRESULT WINAPI DataCache_InitCache(
	    IOleCache2*     iface,
	    IDataObject*    pDataObject)
{
  FIXME("stub\n");
  return E_NOTIMPL;
}

static HRESULT WINAPI DataCache_IOleCache2_SetData(
            IOleCache2*     iface,
	    FORMATETC*      pformatetc,
	    STGMEDIUM*      pmedium,
	    BOOL            fRelease)
{
    DataCache *This = impl_from_IOleCache2(iface);
    DataCacheEntry *cache_entry;
    HRESULT hr;

    TRACE("(%p, %p, %s)\n", pformatetc, pmedium, fRelease ? "TRUE" : "FALSE");
    TRACE("formatetc = %s\n", debugstr_formatetc(pformatetc));

    cache_entry = DataCache_GetEntryForFormatEtc(This, pformatetc);
    if (cache_entry)
    {
        hr = DataCacheEntry_SetData(cache_entry, pformatetc, pmedium, fRelease);

        if (SUCCEEDED(hr))
            DataCache_FireOnViewChange(This, cache_entry->fmtetc.dwAspect,
                                       cache_entry->fmtetc.lindex);

        return hr;
    }
    WARN("cache entry not found\n");

    return OLE_E_BLANK;
}

static HRESULT WINAPI DataCache_UpdateCache(
            IOleCache2*     iface,
	    LPDATAOBJECT    pDataObject,
	    DWORD           grfUpdf,
	    LPVOID          pReserved)
{
  FIXME("(%p, 0x%x, %p): stub\n", pDataObject, grfUpdf, pReserved);
  return E_NOTIMPL;
}

static HRESULT WINAPI DataCache_DiscardCache(
            IOleCache2*     iface,
	    DWORD           dwDiscardOptions)
{
    DataCache *This = impl_from_IOleCache2(iface);
    DataCacheEntry *cache_entry;
    HRESULT hr = S_OK;

    TRACE("(%d)\n", dwDiscardOptions);

    if (dwDiscardOptions == DISCARDCACHE_SAVEIFDIRTY)
        hr = DataCache_Save(&This->IPersistStorage_iface, This->presentationStorage, TRUE);

    LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry)
    {
        hr = DataCacheEntry_DiscardData(cache_entry);
        if (FAILED(hr))
            break;
    }

    return hr;
}


/*********************************************************
 * Method implementation for the IOleCacheControl
 * part of the DataCache class.
 */

/************************************************************************
 * DataCache_IOleCacheControl_QueryInterface (IUnknown)
 */
static HRESULT WINAPI DataCache_IOleCacheControl_QueryInterface(
            IOleCacheControl* iface,
            REFIID            riid,
            void**            ppvObject)
{
  DataCache *this = impl_from_IOleCacheControl(iface);

  return IUnknown_QueryInterface(this->outer_unk, riid, ppvObject);
}

/************************************************************************
 * DataCache_IOleCacheControl_AddRef (IUnknown)
 */
static ULONG WINAPI DataCache_IOleCacheControl_AddRef(
            IOleCacheControl* iface)
{
  DataCache *this = impl_from_IOleCacheControl(iface);

  return IUnknown_AddRef(this->outer_unk);
}

/************************************************************************
 * DataCache_IOleCacheControl_Release (IUnknown)
 */
static ULONG WINAPI DataCache_IOleCacheControl_Release(
            IOleCacheControl* iface)
{
  DataCache *this = impl_from_IOleCacheControl(iface);

  return IUnknown_Release(this->outer_unk);
}

/************************************************************************
 * DataCache_OnRun (IOleCacheControl)
 */
static HRESULT WINAPI DataCache_OnRun(IOleCacheControl* iface, IDataObject *data_obj)
{
    DataCache *This = impl_from_IOleCacheControl(iface);
    DataCacheEntry *cache_entry;

    TRACE("(%p)->(%p)\n", iface, data_obj);

    if(This->running_object) return S_OK;

    /* No reference is taken on the data object */
    This->running_object = data_obj;

    LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry)
    {
        setup_sink(This, cache_entry);
    }

    return S_OK;
}

/************************************************************************
 * DataCache_OnStop (IOleCacheControl)
 */
static HRESULT WINAPI DataCache_OnStop(IOleCacheControl* iface)
{
    DataCache *This = impl_from_IOleCacheControl(iface);
    DataCacheEntry *cache_entry;

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

    if(!This->running_object) return S_OK;

    LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry)
    {
        if(cache_entry->sink_id)
        {
            IDataObject_DUnadvise(This->running_object, cache_entry->sink_id);
            cache_entry->sink_id = 0;
        }
    }

    /* No ref taken in OnRun, so no Release call here */
    This->running_object = NULL;
    return S_OK;
}

/************************************************************************
 *              IAdviseSink methods.
 * This behaves as an internal object to the data cache.  QI'ing its ptr doesn't
 * give access to the cache's other interfaces.  We don't maintain a ref count,
 * the object exists as long as the cache is around.
 */
static HRESULT WINAPI DataCache_IAdviseSink_QueryInterface(IAdviseSink *iface, REFIID iid, void **obj)
{
    *obj = NULL;
    if (IsEqualIID(&IID_IUnknown, iid) ||
        IsEqualIID(&IID_IAdviseSink, iid))
    {
        *obj = iface;
    }

    if(*obj)
    {
        IAdviseSink_AddRef(iface);
        return S_OK;
    }
    return E_NOINTERFACE;
}

static ULONG WINAPI DataCache_IAdviseSink_AddRef(IAdviseSink *iface)
{
    return 2;
}

static ULONG WINAPI DataCache_IAdviseSink_Release(IAdviseSink *iface)
{
    return 1;
}

static void WINAPI DataCache_OnDataChange(IAdviseSink *iface, FORMATETC *fmt, STGMEDIUM *med)
{
    DataCache *This = impl_from_IAdviseSink(iface);
    TRACE("(%p)->(%s, %p)\n", This, debugstr_formatetc(fmt), med);
    IOleCache2_SetData(&This->IOleCache2_iface, fmt, med, FALSE);
}

static void WINAPI DataCache_OnViewChange(IAdviseSink *iface, DWORD aspect, LONG index)
{
    FIXME("stub\n");
}

static void WINAPI DataCache_OnRename(IAdviseSink *iface, IMoniker *mk)
{
    FIXME("stub\n");
}

static void WINAPI DataCache_OnSave(IAdviseSink *iface)
{
    FIXME("stub\n");
}

static void WINAPI DataCache_OnClose(IAdviseSink *iface)
{
    FIXME("stub\n");
}

/*
 * Virtual function tables for the DataCache class.
 */
static const IUnknownVtbl DataCache_NDIUnknown_VTable =
{
  DataCache_NDIUnknown_QueryInterface,
  DataCache_NDIUnknown_AddRef,
  DataCache_NDIUnknown_Release
};

static const IDataObjectVtbl DataCache_IDataObject_VTable =
{
  DataCache_IDataObject_QueryInterface,
  DataCache_IDataObject_AddRef,
  DataCache_IDataObject_Release,
  DataCache_GetData,
  DataCache_GetDataHere,
  DataCache_QueryGetData,
  DataCache_GetCanonicalFormatEtc,
  DataCache_IDataObject_SetData,
  DataCache_EnumFormatEtc,
  DataCache_DAdvise,
  DataCache_DUnadvise,
  DataCache_EnumDAdvise
};

static const IPersistStorageVtbl DataCache_IPersistStorage_VTable =
{
  DataCache_IPersistStorage_QueryInterface,
  DataCache_IPersistStorage_AddRef,
  DataCache_IPersistStorage_Release,
  DataCache_GetClassID,
  DataCache_IsDirty,
  DataCache_InitNew,
  DataCache_Load,
  DataCache_Save,
  DataCache_SaveCompleted,
  DataCache_HandsOffStorage
};

static const IViewObject2Vtbl DataCache_IViewObject2_VTable =
{
  DataCache_IViewObject2_QueryInterface,
  DataCache_IViewObject2_AddRef,
  DataCache_IViewObject2_Release,
  DataCache_Draw,
  DataCache_GetColorSet,
  DataCache_Freeze,
  DataCache_Unfreeze,
  DataCache_SetAdvise,
  DataCache_GetAdvise,
  DataCache_GetExtent
};

static const IOleCache2Vtbl DataCache_IOleCache2_VTable =
{
  DataCache_IOleCache2_QueryInterface,
  DataCache_IOleCache2_AddRef,
  DataCache_IOleCache2_Release,
  DataCache_Cache,
  DataCache_Uncache,
  DataCache_EnumCache,
  DataCache_InitCache,
  DataCache_IOleCache2_SetData,
  DataCache_UpdateCache,
  DataCache_DiscardCache
};

static const IOleCacheControlVtbl DataCache_IOleCacheControl_VTable =
{
  DataCache_IOleCacheControl_QueryInterface,
  DataCache_IOleCacheControl_AddRef,
  DataCache_IOleCacheControl_Release,
  DataCache_OnRun,
  DataCache_OnStop
};

static const IAdviseSinkVtbl DataCache_IAdviseSink_VTable =
{
    DataCache_IAdviseSink_QueryInterface,
    DataCache_IAdviseSink_AddRef,
    DataCache_IAdviseSink_Release,
    DataCache_OnDataChange,
    DataCache_OnViewChange,
    DataCache_OnRename,
    DataCache_OnSave,
    DataCache_OnClose
};

/*********************************************************
 * Method implementation for DataCache class.
 */
static DataCache* DataCache_Construct(
  REFCLSID  clsid,
  LPUNKNOWN pUnkOuter)
{
  DataCache* newObject = 0;

  /*
   * Allocate space for the object.
   */
  newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(DataCache));

  if (newObject==0)
    return newObject;

  /*
   * Initialize the virtual function table.
   */
  newObject->IDataObject_iface.lpVtbl = &DataCache_IDataObject_VTable;
  newObject->IUnknown_inner.lpVtbl = &DataCache_NDIUnknown_VTable;
  newObject->IPersistStorage_iface.lpVtbl = &DataCache_IPersistStorage_VTable;
  newObject->IViewObject2_iface.lpVtbl = &DataCache_IViewObject2_VTable;
  newObject->IOleCache2_iface.lpVtbl = &DataCache_IOleCache2_VTable;
  newObject->IOleCacheControl_iface.lpVtbl = &DataCache_IOleCacheControl_VTable;
  newObject->IAdviseSink_iface.lpVtbl = &DataCache_IAdviseSink_VTable;
  newObject->outer_unk = pUnkOuter ? pUnkOuter : &newObject->IUnknown_inner;
  newObject->ref = 1;

  /*
   * Initialize the other members of the structure.
   */
  newObject->sinkAspects = 0;
  newObject->sinkAdviseFlag = 0;
  newObject->sinkInterface = 0;
  newObject->clsid = CLSID_NULL;
  newObject->presentationStorage = NULL;
  list_init(&newObject->cache_list);
  newObject->last_cache_id = 2;
  newObject->dirty = FALSE;
  newObject->running_object = NULL;

  create_automatic_entry( newObject, clsid );
  newObject->clsid = *clsid;

  return newObject;
}

/******************************************************************************
 *              CreateDataCache        [OLE32.@]
 *
 * Creates a data cache to allow an object to render one or more of its views,
 * whether running or not.
 *
 * PARAMS
 *  pUnkOuter [I] Outer unknown for the object.
 *  rclsid    [I]
 *  riid      [I] IID of interface to return.
 *  ppvObj    [O] Address where the data cache object will be stored on return.
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: HRESULT code.
 *
 * NOTES
 *  The following interfaces are supported by the returned data cache object:
 *  IOleCache, IOleCache2, IOleCacheControl, IPersistStorage, IDataObject,
 *  IViewObject and IViewObject2.
 */
HRESULT WINAPI CreateDataCache(
  LPUNKNOWN pUnkOuter,
  REFCLSID  rclsid,
  REFIID    riid,
  LPVOID*   ppvObj)
{
  DataCache* newCache = NULL;
  HRESULT    hr       = S_OK;

  TRACE("(%s, %p, %s, %p)\n", debugstr_guid(rclsid), pUnkOuter, debugstr_guid(riid), ppvObj);

  /*
   * Sanity check
   */
  if (ppvObj==0)
    return E_POINTER;

  *ppvObj = 0;

  /*
   * If this cache is constructed for aggregation, make sure
   * the caller is requesting the IUnknown interface.
   * This is necessary because it's the only time the non-delegating
   * IUnknown pointer can be returned to the outside.
   */
  if ( pUnkOuter && !IsEqualIID(&IID_IUnknown, riid) )
    return E_INVALIDARG;

  /*
   * Try to construct a new instance of the class.
   */
  newCache = DataCache_Construct(rclsid,
				 pUnkOuter);

  if (newCache == 0)
    return E_OUTOFMEMORY;

  hr = IUnknown_QueryInterface(&newCache->IUnknown_inner, riid, ppvObj);
  IUnknown_Release(&newCache->IUnknown_inner);

  return hr;
}
