OLE32: shared reading of storage files requires STGM_TRANSACTED

Mike McCormack mike at codeweavers.com
Tue Mar 8 22:44:09 CST 2005


This fixes some problems I was seeing with various Office 2000 
applications and builtin OLE32.

Mike


ChangeLog:
* shared reading of storage files requires STGM_TRANSACTED
-------------- next part --------------
Index: dlls/ole32/storage32.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/storage32.c,v
retrieving revision 1.74
diff -u -p -r1.74 storage32.c
--- dlls/ole32/storage32.c	7 Mar 2005 12:24:42 -0000	1.74
+++ dlls/ole32/storage32.c	9 Mar 2005 04:40:53 -0000
@@ -5426,7 +5426,7 @@ HRESULT WINAPI StgCreateDocfile(
 {
   StorageImpl* newStorage = 0;
   HANDLE       hFile      = INVALID_HANDLE_VALUE;
-  HRESULT        hr         = S_OK;
+  HRESULT        hr         = STG_E_INVALIDFLAG;
   DWORD          shareMode;
   DWORD          accessMode;
   DWORD          creationMode;
@@ -5449,7 +5449,7 @@ HRESULT WINAPI StgCreateDocfile(
    * Validate the STGM flags
    */
   if ( FAILED( validateSTGM(grfMode) ))
-    return STG_E_INVALIDFLAG;
+    goto end;
 
   /* StgCreateDocFile always opens for write */
   switch(STGM_ACCESS_MODE(grfMode))
@@ -5458,7 +5458,7 @@ HRESULT WINAPI StgCreateDocfile(
   case STGM_READWRITE:
     break;
   default:
-    return STG_E_INVALIDFLAG;
+    goto end;
   }
 
   /* can't share write */
@@ -5468,22 +5468,13 @@ HRESULT WINAPI StgCreateDocfile(
   case STGM_SHARE_DENY_WRITE:
     break;
   default:
-    return STG_E_INVALIDFLAG;
+    goto end;
   }
 
-  /* 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;
+  /* shared reading requires transacted mode */
+  if( STGM_SHARE_MODE(grfMode) == STGM_SHARE_DENY_WRITE &&
+     !(grfMode&STGM_TRANSACTED) )
+    goto end;
 
   /*
    * Generate a unique name.
@@ -5494,7 +5485,7 @@ HRESULT WINAPI StgCreateDocfile(
     static const WCHAR prefix[] = { 'S', 'T', 'O', 0 };
 
     if (STGM_SHARE_MODE(grfMode) == STGM_SHARE_EXCLUSIVE)
-      return STG_E_INVALIDFLAG;
+      goto end;
 
     memset(tempPath, 0, sizeof(tempPath));
     memset(tempFileName, 0, sizeof(tempFileName));
@@ -5505,7 +5496,10 @@ HRESULT WINAPI StgCreateDocfile(
     if (GetTempFileNameW(tempPath, prefix, 0, tempFileName) != 0)
       pwcsName = tempFileName;
     else
-      return STG_E_INSUFFICIENTMEMORY;
+    {
+      hr = STG_E_INSUFFICIENTMEMORY;
+      goto end;
+    }
 
     creationMode = TRUNCATE_EXISTING;
   }
@@ -5544,8 +5538,10 @@ HRESULT WINAPI StgCreateDocfile(
   if (hFile == INVALID_HANDLE_VALUE)
   {
     if(GetLastError() == ERROR_FILE_EXISTS)
-      return STG_E_FILEALREADYEXISTS;
-    return E_FAIL;
+      hr = STG_E_FILEALREADYEXISTS;
+    else
+      hr = E_FAIL;
+    goto end;
   }
 
   /*
@@ -5554,7 +5550,10 @@ HRESULT WINAPI StgCreateDocfile(
   newStorage = HeapAlloc(GetProcessHeap(), 0, sizeof(StorageImpl));
 
   if (newStorage == 0)
-    return STG_E_INSUFFICIENTMEMORY;
+  {
+    hr = STG_E_INSUFFICIENTMEMORY;
+    goto end;
+  }
 
   hr = StorageImpl_Construct(
          newStorage,
@@ -5568,7 +5567,7 @@ HRESULT WINAPI StgCreateDocfile(
   if (FAILED(hr))
   {
     HeapFree(GetProcessHeap(), 0, newStorage);
-    return hr;
+    goto end;
   }
 
   /*
@@ -5578,6 +5577,8 @@ HRESULT WINAPI StgCreateDocfile(
          (IStorage*)newStorage,
          (REFIID)&IID_IStorage,
          (void**)ppstgOpen);
+end:
+  TRACE("<-- %p  r = %08lx\n", *ppstgOpen, hr);
 
   return hr;
 }
@@ -6186,7 +6187,6 @@ static DWORD GetAccessModeFromSTGM(DWORD
   case STGM_READ:
     return GENERIC_READ;
   case STGM_WRITE:
-    return GENERIC_WRITE;
   case STGM_READWRITE:
     return GENERIC_READ | GENERIC_WRITE;
   }
@@ -6884,7 +6884,7 @@ HRESULT WINAPI ReadFmtUserTypeStg (LPSTO
                     STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm );
     if( FAILED ( r ) )
     {
-        ERR("Failed to open stream\n");
+        WARN("Failed to open stream r = %08lx\n", r);
         return r;
     }
 
Index: dlls/ole32/tests/storage32.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/tests/storage32.c,v
retrieving revision 1.7
diff -u -p -r1.7 storage32.c
--- dlls/ole32/tests/storage32.c	5 Mar 2005 10:48:11 -0000	1.7
+++ dlls/ole32/tests/storage32.c	9 Mar 2005 04:40:53 -0000
@@ -153,8 +153,9 @@ void test_create_storage_modes(void)
    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_DENY_WRITE | STGM_READWRITE, 0, &stg);
+   ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
    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);
@@ -162,7 +163,6 @@ void test_create_storage_modes(void)
 
    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");
@@ -183,6 +183,24 @@ void test_create_storage_modes(void)
       ok(DeleteFileW(filename), "failed to delete file\n");
    }
 
+   r = StgCreateDocfile( filename, STGM_TRANSACTED|STGM_CREATE|STGM_SHARE_DENY_WRITE|STGM_WRITE, 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");
+   }
+
+   r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
+   ok(r==S_OK, "StgCreateDocfile the powerpoint 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");
@@ -454,7 +472,6 @@ void test_storage_suminfo(void)
     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");


More information about the wine-patches mailing list