/*
 * Compound Storage (32 bit version)
 * Storage implementation
 *
 * This file contains the compound file implementation
 * of the storage interface.
 *
 * Copyright 1999 Francis Beaudet
 * Copyright 1999 Sylvain St-Germain
 * Copyright 1999 Thuy Nguyen
 * Copyright 2005 Mike McCormack
 * Copyright 2005 Juan Lang
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * There's a decent overview of property set storage here:
 * http://msdn.microsoft.com/archive/en-us/dnarolegen/html/msdn_propset.asp
 * It's a little bit out of date, and more definitive references are given
 * below, but it gives the best "big picture" that I've found.
 *
 * TODO: There's a lot missing in here.  Biggies:
 * - There are all sorts of restricions I don't honor, like maximum property
 *   set byte size, maximum property name length
 * - Certain bogus files could result in reading past the end of a buffer.
 * - Write support is missing.
 * - This will probably fail on big-endian machines, especially reading and
 *   writing strings.
 * - Mac-generated files won't be read correctly, even if they're little
 *   endian, because I disregard whether the generator was a Mac.  This means
 *   strings will probably be munged (as I don't understand Mac scripts.)
 * - Not all PROPVARIANT types are supported.
 * There are lots more unimplemented features, see FIXMEs below.
 */

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

#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT

#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "winuser.h"
#include "wine/unicode.h"
#include "wine/debug.h"
#include "dictionary.h"
#include "storage32.h"

WINE_DEFAULT_DEBUG_CHANNEL(storage);

#define _IPropertySetStorage_Offset ((int)(&(((StorageImpl*)0)->base.pssVtbl)))
#define _ICOM_THIS_From_IPropertySetStorage(class, name) \
    class* This = (class*)(((char*)name)-_IPropertySetStorage_Offset)

/* These are documented in MSDN, e.g.
 * http://msdn.microsoft.com/library/en-us/stg/stg/property_set_header.asp
 * http://msdn.microsoft.com/library/library/en-us/stg/stg/section.asp
 * but they don't seem to be in any header file.
 */
#define PROPSETHDR_BYTEORDER_MAGIC      0xfffe
#define PROPSETHDR_OSVER_KIND_WIN16     0
#define PROPSETHDR_OSVER_KIND_MAC       1
#define PROPSETHDR_OSVER_KIND_WIN32     2

/* The format version (and what it implies) is described here:
 * http://msdn.microsoft.com/library/en-us/stg/stg/format_version.asp
 */
typedef struct tagPROPERTYSETHEADER
{
    WORD  wByteOrder; /* always 0xfffe */
    WORD  wFormat;    /* can be zero or one */
    DWORD dwOSVer;    /* OS version of originating system */
    CLSID clsid;      /* application CLSID */
    DWORD reserved;   /* always 1 */
} PROPERTYSETHEADER;

typedef struct tagFORMATIDOFFSET
{
    FMTID fmtid;
    DWORD dwOffset; /* from beginning of stream */
} FORMATIDOFFSET;

typedef struct tagPROPERTYSECTIONHEADER
{
    DWORD cbSection;
    DWORD cProperties;
} PROPERTYSECTIONHEADER;

typedef struct tagPROPERTYIDOFFSET
{
    DWORD propid;
    DWORD dwOffset;
} PROPERTYIDOFFSET;

/* Initializes the property storage from the stream (and undoes any uncommitted
 * changes in the process.)  Returns an error if there is an error reading or
 * if the stream format doesn't match what's expected.
 */
static HRESULT PropertyStorage_ReadFromStream(IPropertyStorage *iface);

static HRESULT PropertyStorage_WriteToStream(IPropertyStorage *iface);

static IPropertyStorageVtbl IPropertyStorage_Vtbl;

/***********************************************************************
 * Implementation of IPropertyStorage
 */
typedef struct tagPropertyStorage_impl
{
    IPropertyStorageVtbl *vtbl;
    DWORD ref;
    CRITICAL_SECTION cs;
    IStream *stm;
    BOOL  dirty;
    FMTID fmtid;
    CLSID clsid;
    DWORD originatorOS;
    DWORD grfFlags;
    DWORD grfMode;
    UINT  codePage;
    LCID  locale;
    PROPID highestProp;
    struct dictionary *name_to_propid;
    struct dictionary *propid_to_name;
    struct dictionary *propid_to_prop;
} PropertyStorage_impl;

/************************************************************************
 * IPropertyStorage_fnQueryInterface (IPropertyStorage)
 */
static HRESULT WINAPI IPropertyStorage_fnQueryInterface(
    IPropertyStorage *iface,
    REFIID riid,
    void** ppvObject)
{
    PropertyStorage_impl *This = (PropertyStorage_impl *)iface;

    if ( (This==0) || (ppvObject==0) )
        return E_INVALIDARG;

    *ppvObject = 0;

    if (IsEqualGUID(&IID_IUnknown, riid) ||
        IsEqualGUID(&IID_IPropertyStorage, riid))
    {
        IPropertyStorage_AddRef(iface);
        *ppvObject = (IPropertyStorage*)iface;
        return S_OK;
    }

    return E_NOINTERFACE;
}

/************************************************************************
 * IPropertyStorage_fnAddRef (IPropertyStorage)
 */
static ULONG WINAPI IPropertyStorage_fnAddRef(
    IPropertyStorage *iface)
{
    PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
    return InterlockedIncrement(&This->ref);
}

/************************************************************************
 * IPropertyStorage_fnRelease (IPropertyStorage)
 */
static ULONG WINAPI IPropertyStorage_fnRelease(
    IPropertyStorage *iface)
{
    PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
    ULONG ref;

    ref = InterlockedDecrement(&This->ref);
    if (ref == 0)
    {
        TRACE("Destroying %p\n", This);
        IStream_Release(This->stm);
        DeleteCriticalSection(&This->cs);
        dictionary_destroy(This->name_to_propid);
        dictionary_destroy(This->propid_to_name);
        dictionary_destroy(This->propid_to_prop);
        HeapFree(GetProcessHeap(), 0, This);
    }
    return ref;
}

static PROPVARIANT *PropertyStorage_FindProperty(PropertyStorage_impl *This,
 DWORD propid)
{
    PROPVARIANT *ret = NULL;

    if (!This)
        return NULL;
    dictionary_find(This->propid_to_prop, (void *)propid, (void **)&ret);
    return ret;
}

static PROPVARIANT *PropertyStorage_FindPropertyByName(
 PropertyStorage_impl *This, LPCWSTR name)
{
    PROPVARIANT *ret = NULL;
    PROPID propid;

    if (!This || !name)
        return NULL;
    if (dictionary_find(This->name_to_propid, name, (void **)&propid))
        ret = PropertyStorage_FindProperty(This, (PROPID)propid);
    return ret;
}

static LPWSTR PropertyStorage_FindPropertyNameById(PropertyStorage_impl *This,
 DWORD propid)
{
    LPWSTR ret = NULL;

    if (!This)
        return NULL;
    dictionary_find(This->propid_to_name, (void *)propid, (void **)&ret);
    return ret;
}

/************************************************************************
 * IPropertyStorage_fnReadMultiple (IPropertyStorage)
 */
static HRESULT WINAPI IPropertyStorage_fnReadMultiple(
    IPropertyStorage* iface,
    ULONG cpspec,
    const PROPSPEC rgpspec[],
    PROPVARIANT rgpropvar[])
{
    PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
    HRESULT hr = S_OK;
    ULONG i;

    TRACE("(%p, %ld, %p, %p)\n", iface, cpspec, rgpspec, rgpropvar);
    if (!This)
        return E_INVALIDARG;
    if (cpspec && (!rgpspec || !rgpropvar))
        return E_INVALIDARG;
    EnterCriticalSection(&This->cs);
    for (i = 0; i < cpspec; i++)
    {
        PropVariantInit(&rgpropvar[i]);
        if (rgpspec[i].ulKind == PRSPEC_LPWSTR)
        {
            PROPVARIANT *prop = PropertyStorage_FindPropertyByName(This,
             rgpspec[i].u.lpwstr);

            if (prop)
                PropVariantCopy(&rgpropvar[i], prop);
        }
        else
        {
            PROPVARIANT *prop = PropertyStorage_FindProperty(This,
             rgpspec[i].u.propid);

            if (prop)
                PropVariantCopy(&rgpropvar[i], prop);
        }
    }
    LeaveCriticalSection(&This->cs);
    return hr;
}

static HRESULT PropertyStorage_StorePropWithId(PropertyStorage_impl *This,
 PROPID propid, const PROPVARIANT *propvar)
{
    HRESULT hr = S_OK;
    PROPVARIANT *prop = PropertyStorage_FindProperty(This, propid);

    if (prop)
    {
        PropVariantClear(prop);
        PropVariantCopy(prop, propvar);
    }
    else
    {
        prop = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
         sizeof(PROPVARIANT));
        if (prop)
        {
            PropVariantCopy(prop, propvar);
            dictionary_insert(This->propid_to_prop, (void *)propid, prop);
        }
        else
            hr = STG_E_INSUFFICIENTMEMORY;
    }
    return hr;
}

/************************************************************************
 * IPropertyStorage_fnWriteMultiple (IPropertyStorage)
 */
static HRESULT WINAPI IPropertyStorage_fnWriteMultiple(
    IPropertyStorage* iface,
    ULONG cpspec,
    const PROPSPEC rgpspec[],
    const PROPVARIANT rgpropvar[],
    PROPID propidNameFirst)
{
    PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
    HRESULT hr = S_OK;
    ULONG i;

    TRACE("(%p, %ld, %p, %p)\n", iface, cpspec, rgpspec, rgpropvar);
    if (!This)
        return E_INVALIDARG;
    if (cpspec && (!rgpspec || !rgpropvar))
        return E_INVALIDARG;
    if (!(This->grfMode & STGM_READWRITE))
        return STG_E_ACCESSDENIED;
    EnterCriticalSection(&This->cs);
    This->dirty = TRUE;
    This->originatorOS = (DWORD)MAKELONG(LOWORD(GetVersion()),
     PROPSETHDR_OSVER_KIND_WIN32) ;
    for (i = 0; i < cpspec; i++)
    {
        if (rgpspec[i].ulKind == PRSPEC_LPWSTR)
        {
            PROPVARIANT *prop = PropertyStorage_FindPropertyByName(This,
             rgpspec[i].u.lpwstr);

            if (prop)
                PropVariantCopy(prop, &rgpropvar[i]);
            else
            {
                if (propidNameFirst < PID_FIRST_USABLE ||
                 propidNameFirst >= PID_MIN_READONLY)
                    hr = STG_E_INVALIDPARAMETER;
                else
                {
                    PROPID nextId = max(propidNameFirst, This->highestProp + 1);
                    size_t len = strlenW(rgpspec[i].u.lpwstr) + 1;
                    LPWSTR name = HeapAlloc(GetProcessHeap(), 0,
                     len * sizeof(WCHAR));

                    strcpyW(name, rgpspec[i].u.lpwstr);
                    dictionary_insert(This->name_to_propid, name,
                     (void *)nextId);
                    dictionary_insert(This->propid_to_name, (void *)nextId,
                     name);
                    This->highestProp = nextId;
                    hr = PropertyStorage_StorePropWithId(This, nextId,
                     &rgpropvar[i]);
                }
            }
        }
        else
        {
            /* FIXME: certain propid's have special behavior.  E.g., you can't
             * set propid 0, and setting PID_BEHAVIOR affects the
             * case-sensitivity.
             */
            hr = PropertyStorage_StorePropWithId(This, rgpspec[i].u.propid,
             &rgpropvar[i]);
        }
    }
    LeaveCriticalSection(&This->cs);
    return hr;
}

/************************************************************************
 * IPropertyStorage_fnDeleteMultiple (IPropertyStorage)
 */
static HRESULT WINAPI IPropertyStorage_fnDeleteMultiple(
    IPropertyStorage* iface,
    ULONG cpspec,
    const PROPSPEC rgpspec[])
{
    PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
    ULONG i;
    HRESULT hr;

    TRACE("(%p, %ld, %p)\n", iface, cpspec, rgpspec);
    if (!This)
        return E_INVALIDARG;
    if (!rgpspec)
        return E_INVALIDARG;
    if (!(This->grfMode & STGM_READWRITE))
        return STG_E_ACCESSDENIED;
    hr = S_OK;
    EnterCriticalSection(&This->cs);
    for (i = 0; i < cpspec; i++)
    {
        if (rgpspec[i].ulKind == PRSPEC_LPWSTR)
        {
            PROPID propid;

            if (dictionary_find(This->name_to_propid,
             (void *)rgpspec[i].u.lpwstr, (void **)&propid))
                dictionary_remove(This->propid_to_prop, (void *)propid);
        }
        else
        {
            /* FIXME: certain propid's have special meaning.  For example,
             * removing propid 0 is supposed to remove the dictionary, and
             * removing PID_BEHAVIOR should change this to a case-insensitive
             * property set.  Unknown "read-only" propid's should be ignored.
             */
            dictionary_remove(This->propid_to_prop,
             (void *)rgpspec[i].u.propid);
        }
    }
    LeaveCriticalSection(&This->cs);
    return hr;
}

/************************************************************************
 * IPropertyStorage_fnReadPropertyNames (IPropertyStorage)
 */
static HRESULT WINAPI IPropertyStorage_fnReadPropertyNames(
    IPropertyStorage* iface,
    ULONG cpropid,
    const PROPID rgpropid[],
    LPOLESTR rglpwstrName[])
{
    PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
    ULONG i;
    HRESULT hr;

    TRACE("(%p, %ld, %p, %p)\n", iface, cpropid, rgpropid, rglpwstrName);
    if (!This)
        return E_INVALIDARG;
    if (cpropid && (!rgpropid || !rglpwstrName))
        return E_INVALIDARG;
    /* MSDN says S_FALSE is returned if no strings matching rgpropid are found,
     * default to that
     */
    hr = S_FALSE;
    EnterCriticalSection(&This->cs);
    for (i = 0; i < cpropid && SUCCEEDED(hr); i++)
    {
        LPWSTR name = PropertyStorage_FindPropertyNameById(This, rgpropid[i]);

        if (name)
        {
            size_t len = lstrlenW(name);

            hr = S_OK;
            rglpwstrName[i] = CoTaskMemAlloc((len + 1) * sizeof(WCHAR));
            if (rglpwstrName)
                memcpy(rglpwstrName, name, (len + 1) * sizeof(WCHAR));
            else
                hr = STG_E_INSUFFICIENTMEMORY;
        }
        else
            rglpwstrName[i] = NULL;
    }
    LeaveCriticalSection(&This->cs);
    return hr;
}

/************************************************************************
 * IPropertyStorage_fnWritePropertyNames (IPropertyStorage)
 */
static HRESULT WINAPI IPropertyStorage_fnWritePropertyNames(
    IPropertyStorage* iface,
    ULONG cpropid,
    const PROPID rgpropid[],
    const LPOLESTR rglpwstrName[])
{
    PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
    ULONG i;
    HRESULT hr;

    TRACE("(%p, %ld, %p, %p)\n", iface, cpropid, rgpropid, rglpwstrName);
    if (!This)
        return E_INVALIDARG;
    if (cpropid && (!rgpropid || !rglpwstrName))
        return E_INVALIDARG;
    if (!(This->grfMode & STGM_READWRITE))
        return STG_E_ACCESSDENIED;
    hr = S_OK;
    EnterCriticalSection(&This->cs);
    for (i = 0; i < cpropid; i++)
    {
        if (rgpropid[i] != PID_ILLEGAL)
        {
            size_t len = lstrlenW(rglpwstrName[i] + 1);
            LPWSTR name = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));

            strcpyW(name, rglpwstrName[i]);
            dictionary_insert(This->name_to_propid, name, (void *)rgpropid[i]);
            dictionary_insert(This->propid_to_name, (void *)rgpropid[i], name);
        }
    }
    LeaveCriticalSection(&This->cs);
    return hr;
}

/************************************************************************
 * IPropertyStorage_fnDeletePropertyNames (IPropertyStorage)
 */
static HRESULT WINAPI IPropertyStorage_fnDeletePropertyNames(
    IPropertyStorage* iface,
    ULONG cpropid,
    const PROPID rgpropid[])
{
    PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
    ULONG i;
    HRESULT hr;

    TRACE("(%p, %ld, %p)\n", iface, cpropid, rgpropid);
    if (!This)
        return E_INVALIDARG;
    if (cpropid && !rgpropid)
        return E_INVALIDARG;
    if (!(This->grfMode & STGM_READWRITE))
        return STG_E_ACCESSDENIED;
    hr = S_OK;
    EnterCriticalSection(&This->cs);
    for (i = 0; i < cpropid; i++)
    {
        LPWSTR name = NULL;

        if (dictionary_find(This->propid_to_name, (void *)rgpropid[i],
         (void **)&name))
        {
            dictionary_remove(This->propid_to_name, (void *)rgpropid[i]);
            dictionary_remove(This->name_to_propid, name);
        }
    }
    LeaveCriticalSection(&This->cs);
    return hr;
}

/************************************************************************
 * IPropertyStorage_fnCommit (IPropertyStorage)
 */
static HRESULT WINAPI IPropertyStorage_fnCommit(
    IPropertyStorage* iface,
    DWORD grfCommitFlags)
{
    PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
    HRESULT hr;

    TRACE("(%p, 0x%08lx)\n", iface, grfCommitFlags);
    if (!This)
        return E_INVALIDARG;
    if (!(This->grfMode & STGM_READWRITE))
        return STG_E_ACCESSDENIED;
    EnterCriticalSection(&This->cs);
    if (This->dirty)
        hr = PropertyStorage_WriteToStream(iface);
    else
        hr = S_OK;
    LeaveCriticalSection(&This->cs);
    return hr;
}

/************************************************************************
 * IPropertyStorage_fnRevert (IPropertyStorage)
 */
static HRESULT WINAPI IPropertyStorage_fnRevert(
    IPropertyStorage* iface)
{
    HRESULT hr;
    PropertyStorage_impl *This = (PropertyStorage_impl *)iface;

    TRACE("%p\n", iface);
    if (!This)
        return E_INVALIDARG;

    EnterCriticalSection(&This->cs);
    if (This->dirty)
        hr = PropertyStorage_ReadFromStream(iface);
    else
        hr = S_OK;
    LeaveCriticalSection(&This->cs);
    return hr;
}

/************************************************************************
 * IPropertyStorage_fnEnum (IPropertyStorage)
 */
static HRESULT WINAPI IPropertyStorage_fnEnum(
    IPropertyStorage* iface,
    IEnumSTATPROPSTG** ppenum)
{
    FIXME("\n");
    return E_NOTIMPL;
}

/************************************************************************
 * IPropertyStorage_fnSetTimes (IPropertyStorage)
 */
static HRESULT WINAPI IPropertyStorage_fnSetTimes(
    IPropertyStorage* iface,
    const FILETIME* pctime,
    const FILETIME* patime,
    const FILETIME* pmtime)
{
    FIXME("\n");
    return E_NOTIMPL;
}

/************************************************************************
 * IPropertyStorage_fnSetClass (IPropertyStorage)
 */
static HRESULT WINAPI IPropertyStorage_fnSetClass(
    IPropertyStorage* iface,
    REFCLSID clsid)
{
    PropertyStorage_impl *This = (PropertyStorage_impl *)iface;

    TRACE("%p, %s\n", iface, debugstr_guid(clsid));
    if (!This || !clsid)
        return E_INVALIDARG;
    if (!(This->grfMode & STGM_READWRITE))
        return STG_E_ACCESSDENIED;
    memcpy(&This->clsid, clsid, sizeof(This->clsid));
    This->dirty = TRUE;
    return S_OK;
}

/************************************************************************
 * IPropertyStorage_fnStat (IPropertyStorage)
 */
static HRESULT WINAPI IPropertyStorage_fnStat(
    IPropertyStorage* iface,
    STATPROPSETSTG* statpsstg)
{
    PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
    STATSTG stat;
    HRESULT hr;

    TRACE("%p, %p\n", iface, statpsstg);
    if (!This || !statpsstg)
        return E_INVALIDARG;

    hr = IStream_Stat(This->stm, &stat, STATFLAG_NONAME);
    if (SUCCEEDED(hr))
    {
        memcpy(&statpsstg->fmtid, &This->fmtid, sizeof(statpsstg->fmtid));
        memcpy(&statpsstg->clsid, &This->clsid, sizeof(statpsstg->clsid));
        statpsstg->grfFlags = This->grfFlags;
        memcpy(&statpsstg->mtime, &stat.mtime, sizeof(statpsstg->mtime));
        memcpy(&statpsstg->ctime, &stat.ctime, sizeof(statpsstg->ctime));
        memcpy(&statpsstg->atime, &stat.atime, sizeof(statpsstg->atime));
        statpsstg->dwOSVersion = This->originatorOS;
    }
    return hr;
}

static int PropertyStorage_PropNameCompare(const void *a, const void *b,
 void *extra)
{
    PropertyStorage_impl *This = (PropertyStorage_impl *)extra;

    if (This->grfFlags & PROPSETFLAG_CASE_SENSITIVE)
        return strcmpW((LPCWSTR)a, (LPCWSTR)b);
    else
        return strcmpiW((LPCWSTR)a, (LPCWSTR)b);
}

static void PropertyStorage_PropNameDestroy(void *k, void *d, void *extra)
{
    HeapFree(GetProcessHeap(), 0, k);
}

static int PropertyStorage_PropCompare(const void *a, const void *b,
 void *extra)
{
    return (PROPID)a - (PROPID)b;
}

static void PropertyStorage_PropertyDestroy(void *k, void *d, void *extra)
{
    PropVariantClear((PROPVARIANT *)d);
    HeapFree(GetProcessHeap(), 0, d);
}

/* Reads the dictionary from the memory buffer beginning at ptr.  Interprets
 * the entries according to the values of This->codePage and This->locale.
 * FIXME: there isn't any checking whether the read property extends past the
 * end of the buffer.
 */
static HRESULT PropertyStorage_ReadDictionary(PropertyStorage_impl *This,
 BYTE *ptr)
{
    DWORD numEntries = *(DWORD *)ptr;
    HRESULT hr = S_OK;

    ptr += sizeof(DWORD);
    This->name_to_propid = dictionary_create(PropertyStorage_PropNameCompare,
     PropertyStorage_PropNameDestroy, This);
    This->propid_to_name = dictionary_create(PropertyStorage_PropCompare, NULL,
     This);
    if (This->name_to_propid && This->propid_to_name)
    {
        DWORD i;

        for (i = 0; SUCCEEDED(hr) && i < numEntries; i++)
        {
            PROPID propid;
            DWORD cbEntry;
            int len;

            StorageUtl_ReadDWord(ptr, 0, &propid);
            ptr += sizeof(PROPID);
            StorageUtl_ReadDWord(ptr, 0, &cbEntry);
            ptr += sizeof(DWORD);
            /* FIXME: if host is big-endian, this'll suck to convert */
            len = MultiByteToWideChar(This->codePage, 0, ptr, cbEntry, NULL, 0);
            if (!len)
                hr = HRESULT_FROM_WIN32(GetLastError());
            else
            {
                LPWSTR name = HeapAlloc(GetProcessHeap(), 0,
                 len * sizeof(WCHAR));

                if (name)
                {
                    MultiByteToWideChar(This->codePage, 0, ptr + sizeof(DWORD),
                     cbEntry, name, len);
                    dictionary_insert(This->name_to_propid, name,
                     (void *)propid);
                    dictionary_insert(This->propid_to_name, (void *)propid,
                     name);
                    TRACE("Property %s maps to id %ld\n", debugstr_w(name),
                     propid);
                }
                else
                    hr = STG_E_INSUFFICIENTMEMORY;
            }
            ptr += sizeof(DWORD) + cbEntry;
            /* Unicode entries are padded to DWORD boundaries */
            if (This->codePage == 1200 && cbEntry % sizeof(DWORD))
                ptr += sizeof(DWORD) - (cbEntry % sizeof(DWORD));
        }
    }
    else
    {
        /* one or the other failed, free the other */
        if (This->name_to_propid)
        {
            dictionary_destroy(This->name_to_propid);
            This->name_to_propid = NULL;
        }
        if (This->propid_to_name)
        {
            dictionary_destroy(This->propid_to_name);
            This->propid_to_name = NULL;
        }
        hr = STG_E_INSUFFICIENTMEMORY;
    }
    return hr;
}

/* FIXME: there isn't any checking whether the read property extends past the
 * end of the buffer.
 */
static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, DWORD type,
 const BYTE *data)
{
    HRESULT hr = S_OK;

    prop->vt = VT_EMPTY;
    switch (type)
    {
    case VT_NULL:
        prop->vt = VT_NULL;
        break;
    case VT_I1:
        prop->vt = VT_I1;
        prop->u.cVal = *(const char *)data;
        TRACE("Read char 0x%x ('%c')\n", prop->u.cVal, prop->u.cVal);
        break;
    case VT_UI1:
        prop->vt = VT_UI1;
        prop->u.bVal = *(const UCHAR *)data;
        TRACE("Read byte 0x%x\n", prop->u.bVal);
        break;
    case VT_I2:
        prop->vt = VT_I2;
        StorageUtl_ReadWord(data, 0, &prop->u.iVal);
        TRACE("Read short %d\n", prop->u.iVal);
        break;
    case VT_UI2:
        prop->vt = VT_UI2;
        StorageUtl_ReadWord(data, 0, &prop->u.uiVal);
        TRACE("Read ushort %d\n", prop->u.uiVal);
        break;
    case VT_I4:
        prop->vt = VT_I4;
        StorageUtl_ReadDWord(data, 0, &prop->u.lVal);
        TRACE("Read long %ld\n", prop->u.lVal);
        break;
    case VT_UI4:
        prop->vt = VT_UI4;
        StorageUtl_ReadDWord(data, 0, &prop->u.ulVal);
        TRACE("Read ulong %ld\n", prop->u.ulVal);
        break;
    case VT_LPSTR:
    {
        DWORD count = *(const DWORD *)data;

        prop->u.pszVal = CoTaskMemAlloc(count);
        if (prop->u.pszVal)
        {
            /* FIXME: if the host is big-endian, this'll suck */
            memcpy(prop->u.pszVal, data + sizeof(DWORD), count);
            prop->vt = VT_LPSTR;
            /* FIXME: so far so good, but this may be Unicode or DBCS depending
             * on This->codePage.
             */
            TRACE("Read string value %s\n", debugstr_a(prop->u.pszVal));
        }
        else
            hr = STG_E_INSUFFICIENTMEMORY;
        break;
    }
    case VT_LPWSTR:
    {
        DWORD count = *(DWORD *)data;

        prop->u.pwszVal = CoTaskMemAlloc(count * sizeof(WCHAR));
        if (prop->u.pwszVal)
        {
            /* FIXME: if the host is big-endian, gotta swap every char */
            memcpy(prop->u.pwszVal, data + sizeof(DWORD),
             count * sizeof(WCHAR));
            prop->vt = VT_LPWSTR;
            TRACE("Read string value %s\n", debugstr_w(prop->u.pwszVal));
        }
        else
            hr = STG_E_INSUFFICIENTMEMORY;
        break;
    }
    case VT_FILETIME:
        /* FIXME: endianness */
        prop->vt = VT_FILETIME;
        memcpy(&prop->u.filetime, data, sizeof(FILETIME));
        break;
    default:
        FIXME("unsupported type %ld\n", type);
        hr = STG_E_INVALIDPARAMETER;
    }
    return hr;
}

static HRESULT PropertyStorage_ReadHeaderFromStream(IStream *stm,
 PROPERTYSETHEADER *hdr)
{
    BYTE buf[sizeof(PROPERTYSETHEADER)];
    ULONG count = 0;
    HRESULT hr;

    hr = IStream_Read(stm, buf, sizeof(buf), &count);
    if (SUCCEEDED(hr))
    {
        if (count != sizeof(buf))
        {
            WARN("read %ld, expected %d\n", count, sizeof(buf));
            hr = STG_E_INVALIDHEADER;
        }
        else
        {
            StorageUtl_ReadWord(buf, offsetof(PROPERTYSETHEADER, wByteOrder),
             &hdr->wByteOrder);
            StorageUtl_ReadWord(buf, offsetof(PROPERTYSETHEADER, wFormat),
             &hdr->wFormat);
            StorageUtl_ReadDWord(buf, offsetof(PROPERTYSETHEADER, dwOSVer),
             &hdr->dwOSVer);
            StorageUtl_ReadGUID(buf, offsetof(PROPERTYSETHEADER, clsid),
             &hdr->clsid);
            StorageUtl_ReadDWord(buf, offsetof(PROPERTYSETHEADER, reserved),
             &hdr->reserved);
        }
    }
    TRACE("returning 0x%08lx\n", hr);
    return hr;
}

static HRESULT PropertyStorage_ReadFmtIdOffsetFromStream(IStream *stm,
 FORMATIDOFFSET *fmt)
{
    BYTE buf[sizeof(FORMATIDOFFSET)];
    ULONG count = 0;
    HRESULT hr;

    hr = IStream_Read(stm, buf, sizeof(buf), &count);
    if (SUCCEEDED(hr))
    {
        if (count != sizeof(buf))
        {
            WARN("read %ld, expected %d\n", count, sizeof(buf));
            hr = STG_E_INVALIDHEADER;
        }
        else
        {
            StorageUtl_ReadGUID(buf, offsetof(FORMATIDOFFSET, fmtid),
             &fmt->fmtid);
            StorageUtl_ReadDWord(buf, offsetof(FORMATIDOFFSET, dwOffset),
             &fmt->dwOffset);
        }
    }
    TRACE("returning 0x%08lx\n", hr);
    return hr;
}

static HRESULT PropertyStorage_ReadSectionHeaderFromStream(IStream *stm,
 PROPERTYSECTIONHEADER *hdr)
{
    BYTE buf[sizeof(PROPERTYSECTIONHEADER)];
    ULONG count = 0;
    HRESULT hr;

    hr = IStream_Read(stm, buf, sizeof(buf), &count);
    if (SUCCEEDED(hr))
    {
        if (count != sizeof(buf))
        {
            WARN("read %ld, expected %d\n", count, sizeof(buf));
            hr = STG_E_INVALIDHEADER;
        }
        else
        {
            StorageUtl_ReadDWord(buf, offsetof(PROPERTYSECTIONHEADER,
             cbSection), &hdr->cbSection);
            StorageUtl_ReadDWord(buf, offsetof(PROPERTYSECTIONHEADER,
             cProperties), &hdr->cProperties);
        }
    }
    TRACE("returning 0x%08lx\n", hr);
    return hr;
}

static HRESULT PropertyStorage_ReadFromStream(IPropertyStorage *iface)
{
    PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
    PROPERTYSETHEADER hdr;
    FORMATIDOFFSET fmtOffset;
    PROPERTYSECTIONHEADER sectionHdr;
    ULONG i;
    STATSTG stat;
    HRESULT hr;
    BYTE *buf = NULL;
    ULONG count = 0;
    DWORD dictOffset = 0;

    if (!This)
        return E_INVALIDARG;

    This->dirty = FALSE;
    This->highestProp = 0;
    dictionary_destroy(This->name_to_propid);
    This->name_to_propid = NULL;
    dictionary_destroy(This->propid_to_name);
    This->propid_to_name = NULL;
    hr = IStream_Stat(This->stm, &stat, STATFLAG_NONAME);
    if (FAILED(hr))
        goto end;
    if (stat.cbSize.u.HighPart)
    {
        WARN("stream too big\n");
        /* maximum size varies, but it can't be this big */
        hr = STG_E_INVALIDHEADER;
        goto end;
    }
    if (stat.cbSize.u.LowPart == 0)
    {
        /* empty stream is okay, we might be being called from Create */
        hr = S_OK;
        goto end;
    }
    else if (stat.cbSize.u.LowPart < sizeof(PROPERTYSETHEADER) +
     sizeof(FORMATIDOFFSET))
    {
        WARN("stream too small\n");
        hr = STG_E_INVALIDHEADER;
        goto end;
    }
    hr = PropertyStorage_ReadHeaderFromStream(This->stm, &hdr);
    /* I've only seen reserved == 1, but the article says I shouldn't disallow
     * higher values.
     */
    if (hdr.wByteOrder != PROPSETHDR_BYTEORDER_MAGIC || hdr.reserved < 1)
    {
        WARN("bad magic in prop set header\n");
        hr = STG_E_INVALIDHEADER;
        goto end;
    }
    if (hdr.wFormat != 0 && hdr.wFormat != 1)
    {
        WARN("bad format version %d\n", hdr.wFormat);
        hr = STG_E_INVALIDHEADER;
        goto end;
    }
    memcpy(&This->clsid, &hdr.clsid, sizeof(This->clsid));
    This->originatorOS = hdr.dwOSVer;
    if (PROPSETHDR_OSVER_KIND(hdr.dwOSVer) == PROPSETHDR_OSVER_KIND_MAC)
        WARN("File comes from a Mac, strings will probably be screwed up\n");
    hr = PropertyStorage_ReadFmtIdOffsetFromStream(This->stm, &fmtOffset);
    if (FAILED(hr))
        goto end;
    if (fmtOffset.dwOffset > stat.cbSize.u.LowPart)
    {
        WARN("invalid offset %ld (stream length is %ld)\n", fmtOffset.dwOffset,
         stat.cbSize.u.LowPart);
        hr = STG_E_INVALIDHEADER;
        goto end;
    }
    /* wackiness alert: if the format ID is FMTID_DocSummaryInformation, there
     * follow not one, but two sections.  The first is the standard properties
     * for the document summary information, and the second is user-defined
     * properties.  This is the only case in which multiple sections are
     * allowed.
     * Reading the second stream isn't implemented yet.
     */
    hr = PropertyStorage_ReadSectionHeaderFromStream(This->stm, &sectionHdr);
    if (FAILED(hr))
        goto end;
    /* The section size includes the section header, so check it */
    if (sectionHdr.cbSection < sizeof(PROPERTYSECTIONHEADER))
    {
        WARN("section header too small, got %ld, expected at least %d\n",
         sectionHdr.cbSection, sizeof(PROPERTYSECTIONHEADER));
        hr = STG_E_INVALIDHEADER;
        goto end;
    }
    buf = HeapAlloc(GetProcessHeap(), 0, sectionHdr.cbSection -
     sizeof(PROPERTYSECTIONHEADER));
    if (!buf)
    {
        hr = STG_E_INSUFFICIENTMEMORY;
        goto end;
    }
    hr = IStream_Read(This->stm, buf, sectionHdr.cbSection -
     sizeof(PROPERTYSECTIONHEADER), &count);
    if (FAILED(hr))
        goto end;
    dictionary_destroy(This->propid_to_prop);
    This->propid_to_prop = dictionary_create(PropertyStorage_PropCompare,
     PropertyStorage_PropertyDestroy, This);
    for (i = 0; SUCCEEDED(hr) && i < sectionHdr.cProperties; i++)
    {
        PROPERTYIDOFFSET *idOffset = (PROPERTYIDOFFSET *)(buf +
         i * sizeof(PROPERTYIDOFFSET));

        if (idOffset->dwOffset < sizeof(PROPERTYSECTIONHEADER) ||
         idOffset->dwOffset >= sectionHdr.cbSection - sizeof(DWORD))
            hr = STG_E_INVALIDPOINTER;
        else
        {
            if (idOffset->propid >= PID_FIRST_USABLE &&
             idOffset->propid < PID_MIN_READONLY && idOffset->propid >
             This->highestProp)
                This->highestProp = idOffset->propid;
            if (idOffset->propid == 0)
            {
                /* Don't read the dictionary yet, its entries depend on the
                 * code page.  Just store the offset so we know to read it
                 * later.
                 */
                dictOffset = idOffset->dwOffset;
            }
            else
            {
                DWORD type;
                PROPVARIANT prop;

                StorageUtl_ReadDWord(buf,
                 idOffset->dwOffset - sizeof(PROPERTYSECTIONHEADER), &type);
                if (SUCCEEDED(PropertyStorage_ReadProperty(&prop, type,
                 buf + idOffset->dwOffset - sizeof(PROPERTYSECTIONHEADER) +
                 sizeof(DWORD))))
                {
                    /* FIXME: the PID_CODEPAGE and PID_LOCALE special cases
                     * aren't really needed, just look them up in
                     * propid_to_prop when needed
                     */
                    switch(idOffset->propid)
                    {
                    case PID_CODEPAGE:
                        if (prop.vt == VT_I2)
                            This->codePage = (UINT)prop.u.iVal;
                        break;
                    case PID_LOCALE:
                        if (prop.vt == VT_I4)
                            This->locale = (LCID)prop.u.lVal;
                        break;
                    case PID_BEHAVIOR:
                        if (prop.vt == VT_I4 && prop.u.lVal)
                            This->grfFlags |= PROPSETFLAG_CASE_SENSITIVE;
                        break;
                    default:
                        hr = PropertyStorage_StorePropWithId(This,
                         idOffset->propid, &prop);
                    }
                }
            }
        }
    }
    if (!This->codePage)
    {
        /* default to Unicode unless told not to, as specified here:
         * http://msdn.microsoft.com/library/en-us/stg/stg/names_in_istorage.asp
         */
        if (This->grfFlags & PROPSETFLAG_ANSI)
            This->codePage = GetACP();
        else
            This->codePage = 1200;
    }
    if (!This->locale)
        This->locale = LOCALE_SYSTEM_DEFAULT;
    TRACE("Code page is %d, locale is %ld\n", This->codePage, This->locale);
    if (dictOffset)
        PropertyStorage_ReadDictionary(This,
         buf + dictOffset - sizeof(PROPERTYSECTIONHEADER));

end:
    HeapFree(GetProcessHeap(), 0, buf);
    return hr;
}


static HRESULT PropertyStorage_WriteToStream(IPropertyStorage *iface)
{
    FIXME("\n");
    return E_NOTIMPL;
}

/***********************************************************************
 * PropertyStorage_Construct
 */
static HRESULT PropertyStorage_Construct(IStream *stm, REFFMTID rfmtid,
 DWORD grfFlags, DWORD grfMode, IPropertyStorage** pps)
{
    PropertyStorage_impl *ps;
    HRESULT hr;

    ps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof *ps);
    if (!ps)
        return E_OUTOFMEMORY;

    ps->vtbl = &IPropertyStorage_Vtbl;
    ps->ref = 1;
    InitializeCriticalSection(&ps->cs);
    ps->stm = stm;
    memcpy(&ps->fmtid, rfmtid, sizeof(ps->fmtid));
    ps->grfFlags = grfFlags;
    ps->grfMode = grfMode;

    hr = PropertyStorage_ReadFromStream((IPropertyStorage *)ps);
    if (SUCCEEDED(hr))
    {
        *pps = (IPropertyStorage *)ps;
        TRACE("PropertyStorage %p constructed\n", ps);
        hr = S_OK;
    }
    else
        HeapFree(GetProcessHeap(), 0, ps);
    return hr;
}


/***********************************************************************
 * Implementation of IPropertySetStorage
 */

#define BITS_PER_BYTE    8
#define CHARMASK         0x1f
#define BITS_IN_CHARMASK 5

/* Converts rfmtid to a string and returns the resulting string.  If rfmtid
 * is a well-known FMTID, it just returns a static string.  Otherwise it
 * creates the appropriate string name in str, which must be 27 characters
 * in length, and returns str.
 * Based on the algorithm described here:
 * http://msdn.microsoft.com/library/en-us/stg/stg/names_in_istorage.asp
 */
static LPCWSTR format_id_to_name(REFFMTID rfmtid, LPWSTR str)
{
    static const char fmtMap[] = "abcdefghijklmnopqrstuvwxyz012345";
    static const WCHAR szSummaryInfo[] = { 5,'S','u','m','m','a','r','y',
        'I','n','f','o','r','m','a','t','i','o','n',0 };
    static const WCHAR szDocSummaryInfo[] = { 5,'D','o','c','u','m','e','n','t',
        'S','u','m','m','a','r','y','I','n','f','o','r','m','a','t','i','o','n',
        0 };
    LPCWSTR ret;

    if (IsEqualGUID(&FMTID_SummaryInformation, rfmtid))
        ret = szSummaryInfo;
    else if (IsEqualGUID(&FMTID_DocSummaryInformation, rfmtid))
        ret = szDocSummaryInfo;
    else
    {
        BYTE *fmtptr;
        WCHAR *pstr = str;
        ULONG bitsRemaining = BITS_PER_BYTE;

        *pstr++ = 5;
        for (fmtptr = (BYTE *)rfmtid; fmtptr < (BYTE *)rfmtid + sizeof(FMTID); )
        {
            ULONG i = *fmtptr >> (BITS_PER_BYTE - bitsRemaining);

            if (bitsRemaining >= BITS_IN_CHARMASK)
            {
                *pstr = (WCHAR)(fmtMap[i & CHARMASK]);
                if (bitsRemaining == BITS_PER_BYTE && *pstr >= 'a' &&
                 *pstr <= 'z')
                    *pstr += 'A' - 'a';
                pstr++;
                bitsRemaining -= BITS_IN_CHARMASK;
                if (bitsRemaining == 0)
                {
                    fmtptr++;
                    bitsRemaining = BITS_PER_BYTE;
                }
            }
            else
            {
                if (++fmtptr < (BYTE *)rfmtid + sizeof(FMTID))
                    i |= *fmtptr << bitsRemaining;
                *pstr++ = (WCHAR)(fmtMap[i & CHARMASK]);
            }
        }
        *pstr = 0;
        ret = str;
    }
    TRACE("returning %s\n", debugstr_w(ret));
    return ret;
}

/************************************************************************
 * IPropertySetStorage_fnQueryInterface (IUnknown)
 *
 *  This method forwards to the common QueryInterface implementation
 */
static HRESULT WINAPI IPropertySetStorage_fnQueryInterface(
    IPropertySetStorage *ppstg,
    REFIID riid,
    void** ppvObject)
{
    _ICOM_THIS_From_IPropertySetStorage(StorageImpl, ppstg);
    return StorageBaseImpl_QueryInterface( (IStorage*)This, riid, ppvObject );
}

/************************************************************************
 * IPropertySetStorage_fnAddRef (IUnknown)
 *
 *  This method forwards to the common AddRef implementation
 */
static ULONG WINAPI IPropertySetStorage_fnAddRef(
    IPropertySetStorage *ppstg)
{
    _ICOM_THIS_From_IPropertySetStorage(StorageImpl, ppstg);
    return StorageBaseImpl_AddRef( (IStorage*)This );
}

/************************************************************************
 * IPropertySetStorage_fnRelease (IUnknown)
 *
 *  This method forwards to the common Release implementation
 */
static ULONG WINAPI IPropertySetStorage_fnRelease(
    IPropertySetStorage *ppstg)
{
    _ICOM_THIS_From_IPropertySetStorage(StorageImpl, ppstg);
    return StorageBaseImpl_Release( (IStorage*)This );
}

/************************************************************************
 * IPropertySetStorage_fnCreate (IPropertySetStorage)
 */
static HRESULT WINAPI IPropertySetStorage_fnCreate(
    IPropertySetStorage *ppstg,
    REFFMTID rfmtid,
    const CLSID* pclsid,
    DWORD grfFlags,
    DWORD grfMode,
    IPropertyStorage** ppprstg)
{
    _ICOM_THIS_From_IPropertySetStorage(StorageImpl, ppstg);
    WCHAR nameBuf[27];
    LPCWSTR name = NULL;
    IStream *stm = NULL;
    HRESULT r;

    TRACE("%p %s %08lx %08lx %p\n", This, debugstr_guid(rfmtid), grfFlags,
     grfMode, ppprstg);

    /* be picky */
    if (grfMode != (STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE))
    {
        r = STG_E_INVALIDFLAG;
        goto end;
    }

    if (!rfmtid)
    {
        r = E_INVALIDARG;
        goto end;
    }

    /* FIXME: if (grfFlags & PROPSETFLAG_NONSIMPLE), we need to create a
     * storage, not a stream.  For now, disallow it.
     */
    if (grfFlags & PROPSETFLAG_NONSIMPLE)
    {
        FIXME("PROPSETFLAG_NONSIMPLE not supported\n");
        r = STG_E_INVALIDFLAG;
        goto end;
    }

    name = format_id_to_name(rfmtid, nameBuf);

    r = IStorage_CreateStream( (IStorage*)This, name, grfMode, 0, 0, &stm );
    if (FAILED(r))
        goto end;

    r = PropertyStorage_Construct(stm, rfmtid, grfFlags, grfMode, ppprstg);

end:
    TRACE("returning 0x%08lx\n", r);
    return r;
}

/************************************************************************
 * IPropertySetStorage_fnOpen (IPropertySetStorage)
 */
static HRESULT WINAPI IPropertySetStorage_fnOpen(
    IPropertySetStorage *ppstg,
    REFFMTID rfmtid,
    DWORD grfMode,
    IPropertyStorage** ppprstg)
{
    _ICOM_THIS_From_IPropertySetStorage(StorageImpl, ppstg);
    IStream *stm = NULL;
    WCHAR nameBuf[27];
    LPCWSTR name = NULL;
    HRESULT r;

    TRACE("%p %s %08lx %p\n", This, debugstr_guid(rfmtid), grfMode, ppprstg);

    /* be picky */
    if (grfMode != (STGM_READWRITE|STGM_SHARE_EXCLUSIVE) &&
        grfMode != (STGM_READ|STGM_SHARE_EXCLUSIVE))
    {
        r = STG_E_INVALIDFLAG;
        goto end;
    }

    if (!rfmtid)
    {
        r = E_INVALIDARG;
        goto end;
    }

    name = format_id_to_name(rfmtid, nameBuf);

    r = IStorage_OpenStream((IStorage*) This, name, 0, grfMode, 0, &stm );
    if (FAILED(r))
        goto end;

    r = PropertyStorage_Construct(stm, rfmtid, PROPSETFLAG_DEFAULT, grfMode,
     ppprstg);

end:
    TRACE("returning 0x%08lx\n", r);
    return r;
}

/************************************************************************
 * IPropertySetStorage_fnDelete (IPropertySetStorage)
 */
static HRESULT WINAPI IPropertySetStorage_fnDelete(
    IPropertySetStorage *ppstg,
    REFFMTID rfmtid)
{
    _ICOM_THIS_From_IPropertySetStorage(StorageImpl, ppstg);
    IStorage *stg = NULL;
    WCHAR nameBuf[27];
    LPCWSTR name = NULL;

    TRACE("%p %s\n", This, debugstr_guid(rfmtid));

    if (!rfmtid)
        return E_INVALIDARG;

    name = format_id_to_name(rfmtid, nameBuf);
    if (!name)
        return STG_E_FILENOTFOUND;

    stg = (IStorage*) This;
    return IStorage_DestroyElement(stg, name);
}

/************************************************************************
 * IPropertySetStorage_fnEnum (IPropertySetStorage)
 */
static HRESULT WINAPI IPropertySetStorage_fnEnum(
    IPropertySetStorage *ppstg,
    IEnumSTATPROPSETSTG** ppenum)
{
    _ICOM_THIS_From_IPropertySetStorage(StorageImpl, ppstg);
    FIXME("%p\n", This);
    return E_NOTIMPL;
}


/***********************************************************************
 * vtables
 */
IPropertySetStorageVtbl IPropertySetStorage_Vtbl =
{
    IPropertySetStorage_fnQueryInterface,
    IPropertySetStorage_fnAddRef,
    IPropertySetStorage_fnRelease,
    IPropertySetStorage_fnCreate,
    IPropertySetStorage_fnOpen,
    IPropertySetStorage_fnDelete,
    IPropertySetStorage_fnEnum
};

static IPropertyStorageVtbl IPropertyStorage_Vtbl =
{
    IPropertyStorage_fnQueryInterface,
    IPropertyStorage_fnAddRef,
    IPropertyStorage_fnRelease,
    IPropertyStorage_fnReadMultiple,
    IPropertyStorage_fnWriteMultiple,
    IPropertyStorage_fnDeleteMultiple,
    IPropertyStorage_fnReadPropertyNames,
    IPropertyStorage_fnWritePropertyNames,
    IPropertyStorage_fnDeletePropertyNames,
    IPropertyStorage_fnCommit,
    IPropertyStorage_fnRevert,
    IPropertyStorage_fnEnum,
    IPropertyStorage_fnSetTimes,
    IPropertyStorage_fnSetClass,
    IPropertyStorage_fnStat,
};
