OLE32: StgOpenStorage shouldn't open zero length storage files

Mike McCormack mike at codeweavers.com
Fri Mar 11 04:29:55 CST 2005


This fixes the Word 2000 "custom dictionary is not available" message 
with builtin ole32.

Mike


ChangeLog:
* StgOpenStorage shouldn't open zero length storage files
-------------- next part --------------
Index: dlls/ole32/storage32.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/storage32.c,v
retrieving revision 1.75
diff -u -p -r1.75 storage32.c
--- dlls/ole32/storage32.c	9 Mar 2005 11:44:59 -0000	1.75
+++ dlls/ole32/storage32.c	11 Mar 2005 10:26:49 -0000
@@ -5677,6 +5677,15 @@ HRESULT WINAPI StgOpenStorage(
     goto end;
   }
 
+  /* shared reading requires transacted mode */
+  if( STGM_SHARE_MODE(grfMode) == STGM_SHARE_DENY_WRITE &&
+      STGM_ACCESS_MODE(grfMode) == STGM_READWRITE &&
+     !(grfMode&STGM_TRANSACTED) )
+  {
+    hr = STG_E_INVALIDFLAG;
+    goto end;
+  }
+
   /*
    * Interpret the STGM value grfMode
    */
@@ -5728,7 +5737,17 @@ HRESULT WINAPI StgOpenStorage(
     goto end;
   }
 
+  /*
+   * Refuse to open the file if it's too small to be a structured storage file
+   * FIXME: verify the file when reading instead of here
+   */
   length = GetFileSize(hFile, NULL);
+  if (length < 0x100)
+  {
+    CloseHandle(hFile);
+    hr = STG_E_FILEALREADYEXISTS;
+    goto end;
+  }
 
   /*
    * Allocate and initialize the new IStorage32object.
@@ -5749,7 +5768,7 @@ HRESULT WINAPI StgOpenStorage(
          NULL,
          grfMode,
          TRUE,
-	 !length );
+	 FALSE );
 
   if (FAILED(hr))
   {
@@ -6134,7 +6153,7 @@ static HRESULT validateSTGM(DWORD stgm)
   /*
    * STGM_NOSCRATCH requires STGM_TRANSACTED
    */
-  if ( (stgm & STGM_NOSCRATCH) && (stgm & STGM_TRANSACTED) )
+  if ( (stgm & STGM_NOSCRATCH) && !(stgm & STGM_TRANSACTED) )
     return E_FAIL;
 
   /*
Index: dlls/ole32/tests/storage32.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/tests/storage32.c,v
retrieving revision 1.8
diff -u -p -r1.8 storage32.c
--- dlls/ole32/tests/storage32.c	9 Mar 2005 11:44:59 -0000	1.8
+++ dlls/ole32/tests/storage32.c	11 Mar 2005 10:26:49 -0000
@@ -315,6 +315,32 @@ void test_storage_stream(void)
     ok(r == TRUE, "file should exist\n");
 }
 
+static BOOL touch_file(LPCWSTR filename)
+{
+    HANDLE file;
+
+    file = CreateFileW(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, 
+                CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+    if (file==INVALID_HANDLE_VALUE)
+        return FALSE;
+    CloseHandle(file);
+    return TRUE;
+}
+
+static BOOL is_zero_length(LPCWSTR filename)
+{
+    HANDLE file;
+    DWORD len;
+
+    file = CreateFileW(filename, GENERIC_READ, 0, NULL, 
+                OPEN_EXISTING, 0, NULL);
+    if (file==INVALID_HANDLE_VALUE)
+        return FALSE;
+    len = GetFileSize(file, NULL);
+    CloseHandle(file);
+    return len == 0;
+}
+
 void test_open_storage(void)
 {
     static const WCHAR szPrefix[] = { 's','t','g',0 };
@@ -323,10 +349,23 @@ void test_open_storage(void)
     WCHAR filename[MAX_PATH];
     IStorage *stg = NULL, *stg2 = NULL;
     HRESULT r;
+    DWORD stgm;
 
     if(!GetTempFileNameW(szDot, szPrefix, 0, filename))
         return;
 
+    /* try opening a zero length file - it should stay zero length */
+    DeleteFileW(filename);
+    touch_file(filename);
+    stgm = STGM_NOSCRATCH | STGM_TRANSACTED | STGM_SHARE_DENY_WRITE | STGM_READWRITE;
+    r = StgOpenStorage( filename, NULL, stgm, NULL, 0, &stg);
+    ok(r==STG_E_FILEALREADYEXISTS, "StgOpenStorage didn't fail\n");
+
+    stgm = STGM_SHARE_EXCLUSIVE | STGM_READWRITE;
+    r = StgOpenStorage( filename, NULL, stgm, NULL, 0, &stg);
+    ok(r==STG_E_FILEALREADYEXISTS, "StgOpenStorage didn't fail\n");
+    ok(is_zero_length(filename), "file length changed\n");
+
     DeleteFileW(filename);
 
     /* create the file */
@@ -350,19 +389,37 @@ void test_open_storage(void)
     ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
     r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_READ | STGM_READ, NULL, 0, &stg);
     ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
+    r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_WRITE | STGM_READWRITE, NULL, 0, &stg);
+    ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
 
     /* open it for real */
     r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_WRITE | STGM_READ, NULL, 0, &stg);
     ok(r==S_OK, "StgOpenStorage failed\n");
-    r = IStorage_Release(stg);
-    ok(r == 0, "wrong ref count\n");
+    if(stg)
+    {
+        r = IStorage_Release(stg);
+        ok(r == 0, "wrong ref count\n");
+    }
+
+    /* test the way word opens its custom dictionary */
+    r = StgOpenStorage( filename, NULL, STGM_NOSCRATCH | STGM_TRANSACTED |
+                        STGM_SHARE_DENY_WRITE | STGM_READWRITE, NULL, 0, &stg);
+    ok(r==S_OK, "StgOpenStorage failed\n");
+    if(stg)
+    {
+        r = IStorage_Release(stg);
+        ok(r == 0, "wrong ref count\n");
+    }
 
     r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg);
     ok(r==S_OK, "StgOpenStorage failed\n");
     r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg2);
     ok(r==STG_E_SHAREVIOLATION, "StgOpenStorage failed\n");
-    r = IStorage_Release(stg);
-    ok(r == 0, "wrong ref count\n");
+    if(stg)
+    {
+        r = IStorage_Release(stg);
+        ok(r == 0, "wrong ref count\n");
+    }
 
     r = DeleteFileW(filename);
     ok(r, "file didn't exist\n");


More information about the wine-patches mailing list