Andrey Turkin : ole32: StgOpenStorage on non-existent file should create it (with test).

Alexandre Julliard julliard at wine.codeweavers.com
Thu Sep 28 07:35:50 CDT 2006


Module: wine
Branch: master
Commit: 63f88b3d57a2d3453dd77852ce4ae31a73d084ad
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=63f88b3d57a2d3453dd77852ce4ae31a73d084ad

Author: Andrey Turkin <pancha at mail.nnov.ru>
Date:   Fri Sep 22 06:40:49 2006 +0400

ole32: StgOpenStorage on non-existent file should create it (with test).

---

 dlls/ole32/storage32.c       |   48 +++++++++++++++++++++++++-----------------
 dlls/ole32/tests/storage32.c |   20 ++++++++++++++++++
 2 files changed, 49 insertions(+), 19 deletions(-)

diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c
index 187ba0b..0293073 100644
--- a/dlls/ole32/storage32.c
+++ b/dlls/ole32/storage32.c
@@ -5935,18 +5935,18 @@ HRESULT WINAPI StgOpenStorageEx(const WC
 HRESULT WINAPI StgOpenStorage(
   const OLECHAR *pwcsName,
   IStorage      *pstgPriority,
-  DWORD           grfMode,
-  SNB           snbExclude,
-  DWORD           reserved,
-  IStorage      **ppstgOpen)
+  DWORD          grfMode,
+  SNB            snbExclude,
+  DWORD          reserved,
+  IStorage     **ppstgOpen)
 {
-  StorageImpl* newStorage = 0;
+  StorageImpl*   newStorage = 0;
   HRESULT        hr = S_OK;
-  HANDLE       hFile = 0;
+  HANDLE         hFile = 0;
   DWORD          shareMode;
   DWORD          accessMode;
   WCHAR          fullname[MAX_PATH];
-  DWORD          length;
+  BOOL           newFile;
 
   TRACE("(%s, %p, %lx, %p, %ld, %p)\n",
 	debugstr_w(pwcsName), pstgPriority, grfMode,
@@ -6036,13 +6036,24 @@ HRESULT WINAPI StgOpenStorage(
    */
   *ppstgOpen = 0;
 
-  hFile = CreateFileW( pwcsName,
-                       accessMode,
-                       shareMode,
-                       NULL,
-                       OPEN_EXISTING,
-                       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
-                       0);
+  if ((accessMode & GENERIC_WRITE) && /* try to create a file if no yet exists */
+      ((hFile = CreateFileW( pwcsName, accessMode, shareMode, NULL, CREATE_NEW,
+                             FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, 0))
+          != INVALID_HANDLE_VALUE))
+  {
+      newFile = TRUE;
+  }
+  else
+  {
+      newFile = FALSE;
+      hFile = CreateFileW( pwcsName,
+                           accessMode,
+                           shareMode,
+                           NULL,
+                           OPEN_EXISTING,
+                           FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
+                           0);
+  }
 
   if (hFile==INVALID_HANDLE_VALUE)
   {
@@ -6080,8 +6091,7 @@ HRESULT WINAPI StgOpenStorage(
    * 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)
+  if (!newFile && GetFileSize(hFile, NULL) < 0x100)
   {
     CloseHandle(hFile);
     hr = STG_E_FILEALREADYEXISTS;
@@ -6099,15 +6109,15 @@ HRESULT WINAPI StgOpenStorage(
     goto end;
   }
 
-  /* if the file's length was zero, initialize the storage */
+  /* if we created new file, initialize the storage */
   hr = StorageImpl_Construct(
          newStorage,
          hFile,
-        pwcsName,
+         pwcsName,
          NULL,
          grfMode,
          TRUE,
-	 FALSE );
+         newFile );
 
   if (FAILED(hr))
   {
diff --git a/dlls/ole32/tests/storage32.c b/dlls/ole32/tests/storage32.c
index 437387f..469e53a 100644
--- a/dlls/ole32/tests/storage32.c
+++ b/dlls/ole32/tests/storage32.c
@@ -349,6 +349,18 @@ static BOOL is_zero_length(LPCWSTR filen
     return len == 0;
 }
 
+static BOOL is_existing_file(LPCWSTR filename)
+{
+    HANDLE file;
+
+    file = CreateFileW(filename, GENERIC_READ, 0, NULL,
+                       OPEN_EXISTING, 0, NULL);
+    if (file==INVALID_HANDLE_VALUE)
+        return FALSE;
+    CloseHandle(file);
+    return TRUE;
+}
+
 static void test_open_storage(void)
 {
     static const WCHAR szPrefix[] = { 's','t','g',0 };
@@ -376,6 +388,14 @@ static void test_open_storage(void)
 
     DeleteFileW(filename);
 
+    /* try opening a non-existant file - it should create it */
+    stgm = STGM_DIRECT | STGM_SHARE_EXCLUSIVE | STGM_READWRITE;
+    r = StgOpenStorage( filename, NULL, stgm, NULL, 0, &stg);
+    ok(r==S_OK, "StgOpenStorage failed: 0x%08lx\n", r);
+    if (r==S_OK) IStorage_Release(stg);
+    ok(is_existing_file(filename), "StgOpenStorage didn't create a file\n");
+    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");




More information about the wine-cvs mailing list