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