Implement and test IPropertySetStorage.

This commit is contained in:
Mike McCormack 2005-02-21 20:58:09 +00:00 committed by Alexandre Julliard
parent 2f2546040d
commit a6a91a440b
5 changed files with 718 additions and 1 deletions

View File

@ -34,6 +34,7 @@ C_SRCS = \
regsvr.c \
rpc.c \
stg_bigblockfile.c \
stg_prop.c \
stg_stream.c \
storage32.c \
stubmanager.c

591
dlls/ole32/stg_prop.c Normal file
View File

@ -0,0 +1,591 @@
/*
* 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
*
* 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
*/
#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 "storage32.h"
WINE_DEFAULT_DEBUG_CHANNEL(storage);
#define _IPropertySetStorage_Offset ((int)(&(((StorageImpl*)0)->pssVtbl)))
#define _ICOM_THIS_From_IPropertySetStorage(class, name) \
class* This = (class*)(((char*)name)-_IPropertySetStorage_Offset)
/***********************************************************************
* Declaration of the functions used in IPropertySetStorage
*/
static HRESULT WINAPI IPropertySetStorage_fnQueryInterface(
IPropertySetStorage *ppstg,
REFIID riid,
void** ppvObject);
static ULONG WINAPI IPropertySetStorage_fnAddRef(
IPropertySetStorage *ppstg);
static ULONG WINAPI IPropertySetStorage_fnRelease(
IPropertySetStorage *ppstg);
static HRESULT WINAPI IPropertySetStorage_fnCreate(
IPropertySetStorage *ppstg,
REFFMTID rfmtid,
const CLSID* pclsid,
DWORD grfFlags,
DWORD grfMode,
IPropertyStorage** ppprstg);
static HRESULT WINAPI IPropertySetStorage_fnOpen(
IPropertySetStorage *ppstg,
REFFMTID rfmtid,
DWORD grfMode,
IPropertyStorage** ppprstg);
static HRESULT WINAPI IPropertySetStorage_fnDelete(
IPropertySetStorage *ppstg,
REFFMTID rfmtid);
static HRESULT WINAPI IPropertySetStorage_fnEnum(
IPropertySetStorage *ppstg,
IEnumSTATPROPSETSTG** ppenum);
/***********************************************************************
* Declaration of the functions used in IPropertyStorage
*/
static HRESULT WINAPI IPropertyStorage_fnQueryInterface(
IPropertyStorage *ppstg,
REFIID riid,
void** ppvObject);
static ULONG WINAPI IPropertyStorage_fnAddRef(
IPropertyStorage *ppstg);
static ULONG WINAPI IPropertyStorage_fnRelease(
IPropertyStorage *ppstg);
static HRESULT WINAPI IPropertyStorage_fnReadMultiple(
IPropertyStorage* This,
ULONG cpspec,
const PROPSPEC rgpspec[],
PROPVARIANT rgpropvar[]);
static HRESULT WINAPI IPropertyStorage_fnWriteMultiple(
IPropertyStorage* This,
ULONG cpspec,
const PROPSPEC rgpspec[],
const PROPVARIANT rgpropvar[],
PROPID propidNameFirst);
static HRESULT WINAPI IPropertyStorage_fnDeleteMultiple(
IPropertyStorage* This,
ULONG cpspec,
const PROPSPEC rgpspec[]);
static HRESULT WINAPI IPropertyStorage_fnReadPropertyNames(
IPropertyStorage* This,
ULONG cpropid,
const PROPID rgpropid[],
LPOLESTR rglpwstrName[]);
static HRESULT WINAPI IPropertyStorage_fnWritePropertyNames(
IPropertyStorage* This,
ULONG cpropid,
const PROPID rgpropid[],
const LPOLESTR rglpwstrName[]);
static HRESULT WINAPI IPropertyStorage_fnDeletePropertyNames(
IPropertyStorage* This,
ULONG cpropid,
const PROPID rgpropid[]);
static HRESULT WINAPI IPropertyStorage_fnCommit(
IPropertyStorage* This,
DWORD grfCommitFlags);
static HRESULT WINAPI IPropertyStorage_fnRevert(
IPropertyStorage* This);
static HRESULT WINAPI IPropertyStorage_fnEnum(
IPropertyStorage* This,
IEnumSTATPROPSTG** ppenum);
static HRESULT WINAPI IPropertyStorage_fnSetTimes(
IPropertyStorage* This,
const FILETIME* pctime,
const FILETIME* patime,
const FILETIME* pmtime);
static HRESULT WINAPI IPropertyStorage_fnSetClass(
IPropertyStorage* This,
REFCLSID clsid);
static HRESULT WINAPI IPropertyStorage_fnStat(
IPropertyStorage* This,
STATPROPSETSTG* statpsstg);
/***********************************************************************
* 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,
};
/***********************************************************************
* Implementation of IPropertyStorage
*/
typedef struct tagPropertyStorage_impl
{
IPropertyStorageVtbl *vtbl;
DWORD ref;
IStream *stm;
} 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);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
/************************************************************************
* IPropertyStorage_fnReadMultiple (IPropertyStorage)
*/
static HRESULT WINAPI IPropertyStorage_fnReadMultiple(
IPropertyStorage* iface,
ULONG cpspec,
const PROPSPEC rgpspec[],
PROPVARIANT rgpropvar[])
{
FIXME("\n");
return E_NOTIMPL;
}
/************************************************************************
* IPropertyStorage_fnWriteMultiple (IPropertyStorage)
*/
static HRESULT WINAPI IPropertyStorage_fnWriteMultiple(
IPropertyStorage* iface,
ULONG cpspec,
const PROPSPEC rgpspec[],
const PROPVARIANT rgpropvar[],
PROPID propidNameFirst)
{
FIXME("\n");
return E_NOTIMPL;
}
/************************************************************************
* IPropertyStorage_fnDeleteMultiple (IPropertyStorage)
*/
static HRESULT WINAPI IPropertyStorage_fnDeleteMultiple(
IPropertyStorage* iface,
ULONG cpspec,
const PROPSPEC rgpspec[])
{
FIXME("\n");
return E_NOTIMPL;
}
/************************************************************************
* IPropertyStorage_fnReadPropertyNames (IPropertyStorage)
*/
static HRESULT WINAPI IPropertyStorage_fnReadPropertyNames(
IPropertyStorage* iface,
ULONG cpropid,
const PROPID rgpropid[],
LPOLESTR rglpwstrName[])
{
FIXME("\n");
return E_NOTIMPL;
}
/************************************************************************
* IPropertyStorage_fnWritePropertyNames (IPropertyStorage)
*/
static HRESULT WINAPI IPropertyStorage_fnWritePropertyNames(
IPropertyStorage* iface,
ULONG cpropid,
const PROPID rgpropid[],
const LPOLESTR rglpwstrName[])
{
FIXME("\n");
return E_NOTIMPL;
}
/************************************************************************
* IPropertyStorage_fnDeletePropertyNames (IPropertyStorage)
*/
static HRESULT WINAPI IPropertyStorage_fnDeletePropertyNames(
IPropertyStorage* iface,
ULONG cpropid,
const PROPID rgpropid[])
{
FIXME("\n");
return E_NOTIMPL;
}
/************************************************************************
* IPropertyStorage_fnCommit (IPropertyStorage)
*/
static HRESULT WINAPI IPropertyStorage_fnCommit(
IPropertyStorage* iface,
DWORD grfCommitFlags)
{
FIXME("\n");
return E_NOTIMPL;
}
/************************************************************************
* IPropertyStorage_fnRevert (IPropertyStorage)
*/
static HRESULT WINAPI IPropertyStorage_fnRevert(
IPropertyStorage* iface)
{
FIXME("\n");
return E_NOTIMPL;
}
/************************************************************************
* 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)
{
FIXME("\n");
return E_NOTIMPL;
}
/************************************************************************
* IPropertyStorage_fnStat (IPropertyStorage)
*/
static HRESULT WINAPI IPropertyStorage_fnStat(
IPropertyStorage* iface,
STATPROPSETSTG* statpsstg)
{
FIXME("\n");
return E_NOTIMPL;
}
/***********************************************************************
* PropertyStorage_Contruct
*/
static HRESULT PropertyStorage_Contruct(IStream *stm, IPropertyStorage** pps)
{
PropertyStorage_impl *ps;
ps = HeapAlloc(GetProcessHeap(), 0, sizeof *ps);
if (!ps)
return E_OUTOFMEMORY;
ps->vtbl = &IPropertyStorage_Vtbl;
ps->ref = 1;
ps->stm = stm;
*pps = (IPropertyStorage*)ps;
TRACE("PropertyStorage %p constructed\n", ps);
return S_OK;
}
/***********************************************************************
* Implementation of IPropertySetStorage
*/
static LPCWSTR format_id_to_name(REFFMTID rfmtid)
{
static const WCHAR szSummaryInfo[] = { 5,'S','u','m','m','a','r','y',
'I','n','f','o','r','m','a','t','i','o','n',0 };
if (IsEqualGUID(&FMTID_SummaryInformation, rfmtid))
return szSummaryInfo;
ERR("Unknown format id %s\n", debugstr_guid(rfmtid));
return NULL;
}
/************************************************************************
* 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);
LPCWSTR name = NULL;
IStream *stm = NULL;
HRESULT r;
TRACE("%p %s %08lx %p\n", This, debugstr_guid(rfmtid), grfMode, ppprstg);
/* be picky */
if (grfMode != (STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE))
return STG_E_INVALIDFLAG;
if (!rfmtid)
return E_INVALIDARG;
name = format_id_to_name(rfmtid);
if (!name)
return STG_E_FILENOTFOUND;
r = IStorage_CreateStream( (IStorage*)This, name, grfMode, 0, 0, &stm );
if (FAILED(r))
return r;
return PropertyStorage_Contruct(stm, ppprstg);
}
/************************************************************************
* 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;
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))
return STG_E_INVALIDFLAG;
if (!rfmtid)
return E_INVALIDARG;
name = format_id_to_name(rfmtid);
if (!name)
return STG_E_FILENOTFOUND;
r = IStorage_OpenStream((IStorage*) This, name, 0, grfMode, 0, &stm );
if (FAILED(r))
return r;
return PropertyStorage_Contruct(stm, ppprstg);
}
/************************************************************************
* IPropertySetStorage_fnDelete (IPropertySetStorage)
*/
static HRESULT WINAPI IPropertySetStorage_fnDelete(
IPropertySetStorage *ppstg,
REFFMTID rfmtid)
{
_ICOM_THIS_From_IPropertySetStorage(StorageImpl, ppstg);
IStorage *stg = NULL;
LPCWSTR name = NULL;
TRACE("%p %s\n", This, debugstr_guid(rfmtid));
if (!rfmtid)
return E_INVALIDARG;
name = format_id_to_name(rfmtid);
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;
}

View File

@ -222,7 +222,7 @@ static IEnumSTATSTGVtbl IEnumSTATSTGImpl_Vtbl =
IEnumSTATSTGImpl_Clone
};
extern IPropertySetStorageVtbl IPropertySetStorage_Vtbl;
@ -266,6 +266,10 @@ HRESULT WINAPI StorageBaseImpl_QueryInterface(
{
*ppvObject = (IStorage*)This;
}
else if (memcmp(&IID_IPropertySetStorage, riid, sizeof(IID_IPropertySetStorage)) == 0)
{
*ppvObject = (IStorage*)&This->pssVtbl;
}
/*
* Check that we obtained an interface.
@ -2214,6 +2218,7 @@ HRESULT StorageImpl_Construct(
* Initialize the virtual function table.
*/
This->lpVtbl = &Storage32Impl_Vtbl;
This->pssVtbl = &IPropertySetStorage_Vtbl;
This->v_destructor = &StorageImpl_Destroy;
/*

View File

@ -207,6 +207,8 @@ struct StorageBaseImpl
IStorageVtbl *lpVtbl; /* Needs to be the first item in the struct
* since we want to cast this in a Storage32 pointer */
IPropertySetStorageVtbl *pssVtbl; /* interface for adding a properties stream */
/*
* Reference count of this object
*/
@ -301,6 +303,8 @@ struct StorageImpl
IStorageVtbl *lpVtbl; /* Needs to be the first item in the struct
* since we want to cast this in a Storage32 pointer */
IPropertySetStorageVtbl *pssVtbl; /* interface for adding a properties stream */
/*
* Declare the member of the Storage32BaseImpl class to allow
* casting as a Storage32BaseImpl

View File

@ -309,10 +309,126 @@ void test_open_storage(void)
ok(r, "file didn't exist\n");
}
void test_storage_suminfo(void)
{
static const WCHAR szDot[] = { '.',0 };
static const WCHAR szPrefix[] = { 's','t','g',0 };
WCHAR filename[MAX_PATH];
IStorage *stg = NULL;
IPropertySetStorage *propset = NULL;
IPropertyStorage *ps = NULL;
HRESULT r;
if(!GetTempFileNameW(szDot, szPrefix, 0, filename))
return;
DeleteFileW(filename);
/* create the file */
r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
ok(r==S_OK, "StgCreateDocfile failed\n");
r = IStorage_QueryInterface( stg, &IID_IPropertySetStorage, (LPVOID) &propset );
ok(r == S_OK, "query interface failed\n");
/* delete it */
r = IPropertySetStorage_Delete( propset, &FMTID_SummaryInformation );
ok(r == STG_E_FILENOTFOUND, "deleted property set storage\n");
r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation,
STGM_READ | STGM_SHARE_EXCLUSIVE, &ps );
ok(r == STG_E_FILENOTFOUND, "opened property set storage\n");
r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
STGM_READ | STGM_SHARE_EXCLUSIVE, &ps );
ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
STGM_READ, &ps );
ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0, 0, &ps );
ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
STGM_WRITE|STGM_SHARE_EXCLUSIVE, &ps );
ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
STGM_CREATE|STGM_WRITE|STGM_SHARE_EXCLUSIVE, &ps );
ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
/* now try really creating a a property set */
r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps );
ok(r == S_OK, "failed to create property set storage\n");
if( ps )
IPropertyStorage_Release(ps);
/* now try creating the same thing again */
r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps );
ok(r == S_OK, "failed to create property set storage\n");
if( ps )
IPropertyStorage_Release(ps);
/* should be able to open it */
r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation,
STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
ok(r == S_OK, "open failed\n");
if(r == S_OK)
IPropertyStorage_Release(ps);
/* delete it */
r = IPropertySetStorage_Delete( propset, &FMTID_SummaryInformation );
ok(r == S_OK, "failed to delete property set storage\n");
/* try opening with an invalid FMTID */
r = IPropertySetStorage_Open( propset, NULL,
STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
ok(r == E_INVALIDARG, "open succeeded\n");
if(r == S_OK)
IPropertyStorage_Release(ps);
/* try a bad guid */
r = IPropertySetStorage_Open( propset, &IID_IStorage,
STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
ok(r == STG_E_FILENOTFOUND, "open succeeded\n");
if(r == S_OK)
IPropertyStorage_Release(ps);
/* try some invalid flags */
r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation,
STGM_CREATE | STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
ok(r == STG_E_INVALIDFLAG, "open succeeded\n");
if(r == S_OK)
IPropertyStorage_Release(ps);
/* after deleting it, it should be gone */
r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation,
STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
ok(r == STG_E_FILENOTFOUND, "open failed\n");
if(r == S_OK)
IPropertyStorage_Release(ps);
printf("r = %08lx\n",r);
r = IPropertySetStorage_Release( propset );
ok(r == 1, "ref count wrong\n");
r = IStorage_Release(stg);
ok(r == 0, "ref count wrong\n");
DeleteFileW(filename);
}
START_TEST(storage32)
{
test_hglobal_storage_stat();
test_create_storage_modes();
test_storage_stream();
test_open_storage();
test_storage_suminfo();
}