OLE32: fix handling of STGM_ flags again
Mike McCormack
mike at codeweavers.com
Fri Mar 4 23:32:35 CST 2005
The low word of the STGM_ flags is not a bitfield, but a set of four
nybbles. That means they should not be tested with the & operator, but
the value in each nybble should be check with the == operator.
For example, the access mode is determined by setting the 4 lowest bits
of the grfMode to one of the following values.
STGM_READ 0
STGM_WRITE 1
STGM_READWRITE 2
The value 3 (STGM_WRITE|STGM_READWRITE) is not a legal flag, and causes
StgOpenDocfile to return an error. Any value between 3 and 15 causes
the function to return STG_E_INVALIDFLAG. Testing grfMode with bitwise
operators is therefore incorrect.
Mike
ChangeLog:
* test and fix grfMode handling in StgOpenDocfile.
-------------- next part --------------
Index: dlls/ole32/storage32.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/storage32.c,v
retrieving revision 1.71
diff -u -p -r1.71 storage32.c
--- dlls/ole32/storage32.c 4 Mar 2005 10:48:17 -0000 1.71
+++ dlls/ole32/storage32.c 5 Mar 2005 05:20:15 -0000
@@ -8,6 +8,7 @@
* 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
@@ -51,7 +52,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(storage);
#define FILE_BEGIN 0
-#define STGM_SHARE_MODE(stgm) ((stgm)&0xf0)
+#define STGM_ACCESS_MODE(stgm) ((stgm)&0x0000f)
+#define STGM_SHARE_MODE(stgm) ((stgm)&0x000f0)
+#define STGM_CREATE_MODE(stgm) ((stgm)&0x0f000)
+
+#define STGM_KNOWN_FLAGS (0xf0ff | \
+ STGM_TRANSACTED | STGM_CONVERT | STGM_PRIORITY | STGM_NOSCRATCH | \
+ STGM_NOSNAPSHOT | STGM_DIRECT_SWMR | STGM_DELETEONRELEASE | STGM_SIMPLE)
/* Used for OleConvertIStorageToOLESTREAM and OleConvertOLESTREAMToIStorage */
#define OLESTREAM_ID 0x501
@@ -391,7 +398,7 @@ HRESULT WINAPI StorageBaseImpl_OpenStrea
/*
* As documented.
*/
- if ( !(grfMode & STGM_SHARE_EXCLUSIVE) ||
+ if ( STGM_SHARE_MODE(grfMode) != STGM_SHARE_EXCLUSIVE ||
(grfMode & STGM_DELETEONRELEASE) ||
(grfMode & STGM_TRANSACTED) )
{
@@ -510,7 +517,7 @@ HRESULT WINAPI StorageBaseImpl_OpenStora
/*
* As documented.
*/
- if ( !(grfMode & STGM_SHARE_EXCLUSIVE) ||
+ if ( STGM_SHARE_MODE(grfMode) != STGM_SHARE_EXCLUSIVE ||
(grfMode & STGM_DELETEONRELEASE) ||
(grfMode & STGM_PRIORITY) )
{
@@ -892,7 +899,7 @@ HRESULT WINAPI StorageBaseImpl_CreateStr
if ( FAILED( validateSTGM(grfMode) ))
return STG_E_INVALIDFLAG;
- if ( !(grfMode & STGM_SHARE_EXCLUSIVE) )
+ if (STGM_SHARE_MODE(grfMode) != STGM_SHARE_EXCLUSIVE)
return STG_E_INVALIDFLAG;
/*
@@ -924,7 +931,7 @@ HRESULT WINAPI StorageBaseImpl_CreateStr
/*
* An element with this name already exists
*/
- if (grfMode & STGM_CREATE)
+ if (STGM_CREATE_MODE(grfMode) == STGM_CREATE)
{
IStorage_DestroyElement(iface, pwcsName);
}
@@ -1112,7 +1119,7 @@ HRESULT WINAPI StorageImpl_CreateStorage
/*
* An element with this name already exists
*/
- if (grfMode & STGM_CREATE)
+ if (STGM_CREATE_MODE(grfMode) == STGM_CREATE)
IStorage_DestroyElement(iface, pwcsName);
else
return STG_E_FILEALREADYEXISTS;
@@ -5453,13 +5460,39 @@ HRESULT WINAPI StgCreateDocfile(
return STG_E_INVALIDFLAG;
/* StgCreateDocFile always opens for write */
- if (!(grfMode & (STGM_WRITE|STGM_READWRITE)))
+ switch(STGM_ACCESS_MODE(grfMode))
+ {
+ case STGM_WRITE:
+ case STGM_READWRITE:
+ break;
+ default:
return STG_E_INVALIDFLAG;
+ }
- /* always opens non-shared */
- if (!(grfMode & STGM_SHARE_EXCLUSIVE))
+ /* can't share write */
+ switch(STGM_SHARE_MODE(grfMode))
+ {
+ case STGM_SHARE_EXCLUSIVE:
+ case STGM_SHARE_DENY_WRITE:
+ break;
+ default:
return STG_E_INVALIDFLAG;
-
+ }
+
+ /* need to create in transacted mode */
+ if( STGM_CREATE_MODE(grfMode) == STGM_CREATE &&
+ !(grfMode&STGM_TRANSACTED) )
+ return STG_E_INVALIDFLAG;
+
+ /*
+ * Write only access only works in create mode.
+ * I guess we need read access to read in the old file if there is one.
+ */
+ if( STGM_ACCESS_MODE(grfMode) == STGM_WRITE &&
+ STGM_SHARE_MODE(grfMode) == STGM_SHARE_DENY_WRITE &&
+ STGM_CREATE_MODE(grfMode) != STGM_CREATE )
+ return STG_E_INVALIDFLAG;
+
/*
* Generate a unique name.
*/
@@ -5468,9 +5501,7 @@ HRESULT WINAPI StgCreateDocfile(
WCHAR tempPath[MAX_PATH];
static const WCHAR prefix[] = { 'S', 'T', 'O', 0 };
- if (!(grfMode & STGM_SHARE_EXCLUSIVE))
- return STG_E_INVALIDFLAG;
- if (!(grfMode & (STGM_WRITE|STGM_READWRITE)))
+ if (STGM_SHARE_MODE(grfMode) == STGM_SHARE_EXCLUSIVE)
return STG_E_INVALIDFLAG;
memset(tempPath, 0, sizeof(tempPath));
@@ -5513,10 +5544,10 @@ HRESULT WINAPI StgCreateDocfile(
hFile = CreateFileW(pwcsName,
accessMode,
shareMode,
- NULL,
+ NULL,
creationMode,
fileAttributes,
- 0);
+ 0);
if (hFile == INVALID_HANDLE_VALUE)
{
@@ -6009,6 +6040,9 @@ HRESULT WINAPI OleSaveToStream(IPersist
/****************************************************************************
* This method validate a STGM parameter that can contain the values below
*
+ * The stgm modes in 0x0000ffff are not bit masks, but distinct 4 bit values.
+ * The stgm values contained in 0xffff0000 are bitmasks.
+ *
* STGM_DIRECT 0x00000000
* STGM_TRANSACTED 0x00010000
* STGM_SIMPLE 0x08000000
@@ -6034,79 +6068,74 @@ HRESULT WINAPI OleSaveToStream(IPersist
*/
static HRESULT validateSTGM(DWORD stgm)
{
- BOOL bSTGM_TRANSACTED = ((stgm & STGM_TRANSACTED) == STGM_TRANSACTED);
- BOOL bSTGM_SIMPLE = ((stgm & STGM_SIMPLE) == STGM_SIMPLE);
- BOOL bSTGM_DIRECT = ! (bSTGM_TRANSACTED || bSTGM_SIMPLE);
-
- BOOL bSTGM_WRITE = ((stgm & STGM_WRITE) == STGM_WRITE);
- BOOL bSTGM_READWRITE = ((stgm & STGM_READWRITE) == STGM_READWRITE);
- BOOL bSTGM_READ = ! (bSTGM_WRITE || bSTGM_READWRITE);
-
- BOOL bSTGM_SHARE_DENY_NONE =
- ((stgm & STGM_SHARE_DENY_NONE) == STGM_SHARE_DENY_NONE);
+ DWORD access = STGM_ACCESS_MODE(stgm);
+ DWORD share = STGM_SHARE_MODE(stgm);
+ DWORD create = STGM_CREATE_MODE(stgm);
- BOOL bSTGM_SHARE_DENY_READ =
- ((stgm & STGM_SHARE_DENY_READ) == STGM_SHARE_DENY_READ);
-
- BOOL bSTGM_SHARE_DENY_WRITE =
- ((stgm & STGM_SHARE_DENY_WRITE) == STGM_SHARE_DENY_WRITE);
+ if (stgm&~STGM_KNOWN_FLAGS)
+ {
+ ERR("unknown flags %08lx\n", stgm);
+ return E_FAIL;
+ }
- BOOL bSTGM_SHARE_EXCLUSIVE =
- ((stgm & STGM_SHARE_EXCLUSIVE) == STGM_SHARE_EXCLUSIVE);
+ switch (access)
+ {
+ case STGM_READ:
+ case STGM_WRITE:
+ case STGM_READWRITE:
+ break;
+ default:
+ return E_FAIL;
+ }
- BOOL bSTGM_CREATE = ((stgm & STGM_CREATE) == STGM_CREATE);
- BOOL bSTGM_CONVERT = ((stgm & STGM_CONVERT) == STGM_CONVERT);
+ switch (share)
+ {
+ case STGM_SHARE_DENY_NONE:
+ case STGM_SHARE_DENY_READ:
+ case STGM_SHARE_DENY_WRITE:
+ case STGM_SHARE_EXCLUSIVE:
+ break;
+ default:
+ return E_FAIL;
+ }
- BOOL bSTGM_NOSCRATCH = ((stgm & STGM_NOSCRATCH) == STGM_NOSCRATCH);
- BOOL bSTGM_NOSNAPSHOT = ((stgm & STGM_NOSNAPSHOT) == STGM_NOSNAPSHOT);
+ switch (create)
+ {
+ case STGM_CREATE:
+ case STGM_FAILIFTHERE:
+ break;
+ default:
+ return E_FAIL;
+ }
/*
* STGM_DIRECT | STGM_TRANSACTED | STGM_SIMPLE
*/
- if ( ! bSTGM_DIRECT )
- if( bSTGM_TRANSACTED && bSTGM_SIMPLE )
- return E_FAIL;
-
- /*
- * STGM_WRITE | STGM_READWRITE | STGM_READ
- */
- if ( ! bSTGM_READ )
- if( bSTGM_WRITE && bSTGM_READWRITE )
- return E_FAIL;
-
- /*
- * STGM_SHARE_DENY_NONE | others
- * (I assume here that DENY_READ implies DENY_WRITE)
- */
- if ( bSTGM_SHARE_DENY_NONE )
- if ( bSTGM_SHARE_DENY_READ ||
- bSTGM_SHARE_DENY_WRITE ||
- bSTGM_SHARE_EXCLUSIVE)
+ if ( (stgm & STGM_TRANSACTED) && (stgm & STGM_SIMPLE) )
return E_FAIL;
/*
* STGM_CREATE | STGM_CONVERT
* if both are false, STGM_FAILIFTHERE is set to TRUE
*/
- if ( bSTGM_CREATE && bSTGM_CONVERT )
+ if ( create == STGM_CREATE && (stgm & STGM_CONVERT) )
return E_FAIL;
/*
* STGM_NOSCRATCH requires STGM_TRANSACTED
*/
- if ( bSTGM_NOSCRATCH && ! bSTGM_TRANSACTED )
+ if ( (stgm & STGM_NOSCRATCH) && (stgm & STGM_TRANSACTED) )
return E_FAIL;
/*
* STGM_NOSNAPSHOT requires STGM_TRANSACTED and
* not STGM_SHARE_EXCLUSIVE or STGM_SHARE_DENY_WRITE`
*/
- if (bSTGM_NOSNAPSHOT)
- {
- if ( ! ( bSTGM_TRANSACTED &&
- !(bSTGM_SHARE_EXCLUSIVE || bSTGM_SHARE_DENY_WRITE)) )
+ if ( (stgm & STGM_NOSNAPSHOT) &&
+ (!(stgm & STGM_TRANSACTED) ||
+ share == STGM_SHARE_EXCLUSIVE ||
+ share == STGM_SHARE_DENY_WRITE) )
return E_FAIL;
- }
return S_OK;
}
@@ -6119,29 +6148,20 @@ static HRESULT validateSTGM(DWORD stgm)
*/
static DWORD GetShareModeFromSTGM(DWORD stgm)
{
- DWORD dwShareMode = 0;
- BOOL bSTGM_SHARE_DENY_NONE =
- ((stgm & STGM_SHARE_DENY_NONE) == STGM_SHARE_DENY_NONE);
-
- BOOL bSTGM_SHARE_DENY_READ =
- ((stgm & STGM_SHARE_DENY_READ) == STGM_SHARE_DENY_READ);
-
- BOOL bSTGM_SHARE_DENY_WRITE =
- ((stgm & STGM_SHARE_DENY_WRITE) == STGM_SHARE_DENY_WRITE);
-
- BOOL bSTGM_SHARE_EXCLUSIVE =
- ((stgm & STGM_SHARE_EXCLUSIVE) == STGM_SHARE_EXCLUSIVE);
-
- if ((bSTGM_SHARE_EXCLUSIVE) || (bSTGM_SHARE_DENY_READ))
- dwShareMode = 0;
-
- if (bSTGM_SHARE_DENY_NONE)
- dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
-
- if (bSTGM_SHARE_DENY_WRITE)
- dwShareMode = FILE_SHARE_READ;
-
- return dwShareMode;
+ switch (STGM_SHARE_MODE(stgm))
+ {
+ case STGM_SHARE_DENY_NONE:
+ return FILE_SHARE_READ | FILE_SHARE_WRITE;
+ case STGM_SHARE_DENY_READ:
+ return FILE_SHARE_WRITE;
+ case STGM_SHARE_DENY_WRITE:
+ return FILE_SHARE_READ;
+ case STGM_SHARE_EXCLUSIVE:
+ return 0;
+ }
+ ERR("Invalid share mode!\n");
+ assert(0);
+ return 0;
}
/****************************************************************************
@@ -6152,21 +6172,18 @@ static DWORD GetShareModeFromSTGM(DWORD
*/
static DWORD GetAccessModeFromSTGM(DWORD stgm)
{
- DWORD dwDesiredAccess = GENERIC_READ;
- BOOL bSTGM_WRITE = ((stgm & STGM_WRITE) == STGM_WRITE);
- BOOL bSTGM_READWRITE = ((stgm & STGM_READWRITE) == STGM_READWRITE);
- BOOL bSTGM_READ = ! (bSTGM_WRITE || bSTGM_READWRITE);
-
- if (bSTGM_READ)
- dwDesiredAccess = GENERIC_READ;
-
- if (bSTGM_WRITE)
- dwDesiredAccess |= GENERIC_WRITE;
-
- if (bSTGM_READWRITE)
- dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
-
- return dwDesiredAccess;
+ switch (STGM_ACCESS_MODE(stgm))
+ {
+ case STGM_READ:
+ return GENERIC_READ;
+ case STGM_WRITE:
+ return GENERIC_WRITE;
+ case STGM_READWRITE:
+ return GENERIC_READ | GENERIC_WRITE;
+ }
+ ERR("Invalid access mode!\n");
+ assert(0);
+ return 0;
}
/****************************************************************************
@@ -6177,16 +6194,19 @@ static DWORD GetAccessModeFromSTGM(DWORD
*/
static DWORD GetCreationModeFromSTGM(DWORD stgm)
{
- if ( stgm & STGM_CREATE)
+ switch(STGM_CREATE_MODE(stgm))
+ {
+ case STGM_CREATE:
return CREATE_ALWAYS;
- if (stgm & STGM_CONVERT) {
+ case STGM_CONVERT:
FIXME("STGM_CONVERT not implemented!\n");
return CREATE_NEW;
+ case STGM_FAILIFTHERE:
+ return CREATE_NEW;
}
- /* All other cases */
- if (stgm & ~ (STGM_CREATE|STGM_CONVERT))
- FIXME("unhandled storage mode : 0x%08lx\n",stgm & ~ (STGM_CREATE|STGM_CONVERT));
- return CREATE_NEW;
+ ERR("Invalid create mode!\n");
+ assert(0);
+ return 0;
}
Index: dlls/ole32/tests/storage32.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/tests/storage32.c,v
retrieving revision 1.6
diff -u -p -r1.6 storage32.c
--- dlls/ole32/tests/storage32.c 21 Feb 2005 20:58:09 -0000 1.6
+++ dlls/ole32/tests/storage32.c 5 Mar 2005 05:20:15 -0000
@@ -90,16 +90,32 @@ void test_create_storage_modes(void)
ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE, 0, &stg);
ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
- r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
- STGM_READWRITE, 0, NULL);
+ r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, NULL);
ok(r==STG_E_INVALIDPOINTER, "StgCreateDocfile succeeded\n");
- r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
- STGM_READWRITE, 1, &stg);
+ r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 1, &stg);
ok(r==STG_E_INVALIDPARAMETER, "StgCreateDocfile succeeded\n");
+ r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_DENY_WRITE | STGM_READWRITE, 0, &stg);
+ ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READ, 0, &stg);
ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
r = StgCreateDocfile( filename, STGM_PRIORITY, 0, &stg);
ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
+
+ /* StgCreateDocfile seems to be very particular about the flags it accepts */
+ r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | STGM_WRITE, 0, &stg);
+ ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
+ r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 8, 0, &stg);
+ ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
+ r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x80, 0, &stg);
+ ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
+ r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x800, 0, &stg);
+ ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
+ r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x8000, 0, &stg);
+ ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
+ r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x80000, 0, &stg);
+ ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
+ r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x800000, 0, &stg);
+ ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
ok(stg == NULL, "stg was set\n");
/* check what happens if the file already exists */
@@ -107,8 +123,7 @@ void test_create_storage_modes(void)
ok(r==S_OK, "StgCreateDocfile failed\n");
r = IStorage_Release(stg);
ok(r == 0, "storage not released\n");
- r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |
- STGM_TRANSACTED, 0, &stg);
+ r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
ok(r==STG_E_FILEALREADYEXISTS, "StgCreateDocfile wrong error\n");
r = StgCreateDocfile( filename, STGM_READ, 0, &stg);
ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
@@ -130,23 +145,49 @@ void test_create_storage_modes(void)
ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile wrong error\n");
ok(DeleteFileW(filename), "failed to delete file\n");
- r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |
- STGM_TRANSACTED, 0, &stg);
+ r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
ok(r==S_OK, "StgCreateDocfile failed\n");
r = IStorage_Release(stg);
ok(r == 0, "storage not released\n");
- r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |
- STGM_TRANSACTED |STGM_FAILIFTHERE, 0, &stg);
+ r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED |STGM_FAILIFTHERE, 0, &stg);
ok(r==STG_E_FILEALREADYEXISTS, "StgCreateDocfile wrong error\n");
r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_WRITE, 0, &stg);
ok(r==STG_E_FILEALREADYEXISTS, "StgCreateDocfile wrong error\n");
+ //ok(DeleteFileW(filename), "failed to delete file\n");
- r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
- STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
+ r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
ok(r==S_OK, "StgCreateDocfile failed\n");
r = IStorage_Release(stg);
ok(r == 0, "storage not released\n");
+ ok(DeleteFileW(filename), "failed to delete file\n");
+
+
+ /* test the way excel uses StgCreateDocFile */
+ r = StgCreateDocfile( filename, STGM_TRANSACTED|STGM_CREATE|STGM_SHARE_DENY_WRITE|STGM_READWRITE, 0, &stg);
+ ok(r==S_OK, "StgCreateDocfile the excel way failed\n");
+ if(r == S_OK)
+ {
+ r = IStorage_Release(stg);
+ ok(r == 0, "storage not released\n");
+ ok(DeleteFileW(filename), "failed to delete file\n");
+ }
+
+ /* looks like we need STGM_TRANSACTED or STGM_CREATE */
+ r = StgCreateDocfile( filename, STGM_TRANSACTED|STGM_SHARE_DENY_WRITE|STGM_READWRITE, 0, &stg);
+ ok(r==S_OK, "StgCreateDocfile the excel way failed\n");
+ if(r == S_OK)
+ {
+ r = IStorage_Release(stg);
+ ok(r == 0, "storage not released\n");
+ ok(DeleteFileW(filename), "failed to delete file\n");
+ }
+
+ /* test the way msi uses StgCreateDocfile */
+ r = StgCreateDocfile( filename, STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stg);
+ ok(r==S_OK, "StgCreateDocFile failed\n");
+ r = IStorage_Release(stg);
+ ok(r == 0, "storage not released\n");
ok(DeleteFileW(filename), "failed to delete file\n");
}
More information about the wine-patches
mailing list