From a6a91a440b5d41362193ad8f531d039cf0f4acde Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 21 Feb 2005 20:58:09 +0000 Subject: [PATCH] Implement and test IPropertySetStorage. --- dlls/ole32/Makefile.in | 1 + dlls/ole32/stg_prop.c | 591 +++++++++++++++++++++++++++++++++++ dlls/ole32/storage32.c | 7 +- dlls/ole32/storage32.h | 4 + dlls/ole32/tests/storage32.c | 116 +++++++ 5 files changed, 718 insertions(+), 1 deletion(-) create mode 100644 dlls/ole32/stg_prop.c diff --git a/dlls/ole32/Makefile.in b/dlls/ole32/Makefile.in index 7b6dc578241..34e77bb0784 100644 --- a/dlls/ole32/Makefile.in +++ b/dlls/ole32/Makefile.in @@ -34,6 +34,7 @@ C_SRCS = \ regsvr.c \ rpc.c \ stg_bigblockfile.c \ + stg_prop.c \ stg_stream.c \ storage32.c \ stubmanager.c diff --git a/dlls/ole32/stg_prop.c b/dlls/ole32/stg_prop.c new file mode 100644 index 00000000000..95a48e53b20 --- /dev/null +++ b/dlls/ole32/stg_prop.c @@ -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 +#include +#include +#include +#include + +#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; +} diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c index 7f3e2b2a4fb..cf6a97dc7f2 100644 --- a/dlls/ole32/storage32.c +++ b/dlls/ole32/storage32.c @@ -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; /* diff --git a/dlls/ole32/storage32.h b/dlls/ole32/storage32.h index 05ceaed9727..28f96fd2767 100644 --- a/dlls/ole32/storage32.h +++ b/dlls/ole32/storage32.h @@ -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 diff --git a/dlls/ole32/tests/storage32.c b/dlls/ole32/tests/storage32.c index 2c9bf8b0503..a95534b9d09 100644 --- a/dlls/ole32/tests/storage32.c +++ b/dlls/ole32/tests/storage32.c @@ -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(); }