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