OLE32: make sure a stream can't be created in read only storage

Mike McCormack mike at codeweavers.com
Fri May 13 03:53:06 CDT 2005


ChangeLog:
* make sure a stream can't be created in read only storage
-------------- next part --------------
? dlls/ole32/ole32.spec.def
Index: dlls/ole32/storage32.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/storage32.c,v
retrieving revision 1.85
diff -u -p -r1.85 storage32.c
--- dlls/ole32/storage32.c	10 May 2005 15:59:59 -0000	1.85
+++ dlls/ole32/storage32.c	13 May 2005 08:50:27 -0000
@@ -296,6 +296,7 @@ HRESULT WINAPI StorageBaseImpl_OpenStrea
   StgProperty       currentProperty;
   ULONG             foundPropertyIndex;
   HRESULT           res = STG_E_UNKNOWN;
+  DWORD             parent_grfMode;
 
   TRACE("(%p, %s, %p, %lx, %ld, %p)\n",
 	iface, debugstr_w(pwcsName), reserved1, grfMode, reserved2, ppstm);
@@ -335,6 +336,16 @@ HRESULT WINAPI StorageBaseImpl_OpenStrea
   }
 
   /*
+   * Check that we're compatible with the parent's storage mode
+   */
+  parent_grfMode = STGM_ACCESS_MODE( This->ancestorStorage->base.openFlags );
+  if ( STGM_ACCESS_MODE( grfMode ) > STGM_ACCESS_MODE( parent_grfMode ) )
+  {
+    res = STG_E_ACCESSDENIED;
+    goto end;
+  }
+
+  /*
    * Create a property enumeration to search the properties
    */
   propertyEnumeration = IEnumSTATSTGImpl_Construct(
@@ -412,6 +423,7 @@ HRESULT WINAPI StorageBaseImpl_OpenStora
   StgProperty            currentProperty;
   ULONG                  foundPropertyIndex;
   HRESULT                res = STG_E_UNKNOWN;
+  DWORD                  parent_grfMode;
 
   TRACE("(%p, %s, %p, %lx, %p, %ld, %p)\n",
 	iface, debugstr_w(pwcsName), pstgPriority,
@@ -454,6 +466,16 @@ HRESULT WINAPI StorageBaseImpl_OpenStora
   }
 
   /*
+   * Check that we're compatible with the parent's storage mode
+   */
+  parent_grfMode = STGM_ACCESS_MODE( This->ancestorStorage->base.openFlags );
+  if ( STGM_ACCESS_MODE( grfMode ) > STGM_ACCESS_MODE( parent_grfMode ) )
+  {
+    res = STG_E_ACCESSDENIED;
+    goto end;
+  }
+
+  /*
    * Initialize the out parameter
    */
   *ppstg = NULL;
@@ -489,6 +511,7 @@ HRESULT WINAPI StorageBaseImpl_OpenStora
      */
     newStorage = StorageInternalImpl_Construct(
                    This->ancestorStorage,
+                   grfMode,
                    foundPropertyIndex);
 
     if (newStorage != 0)
@@ -804,6 +827,7 @@ HRESULT WINAPI StorageBaseImpl_CreateStr
   StgStreamImpl*    newStream;
   StgProperty       currentProperty, newStreamProperty;
   ULONG             foundPropertyIndex, newPropertyIndex;
+  DWORD             parent_grfMode;
 
   TRACE("(%p, %s, %lx, %ld, %ld, %p)\n",
 	iface, debugstr_w(pwcsName), grfMode,
@@ -838,6 +862,13 @@ HRESULT WINAPI StorageBaseImpl_CreateStr
     return STG_E_INVALIDFUNCTION;
 
   /*
+   * Check that we're compatible with the parent's storage mode
+   */
+  parent_grfMode = STGM_ACCESS_MODE( This->ancestorStorage->base.openFlags );
+  if ( STGM_ACCESS_MODE( grfMode ) > STGM_ACCESS_MODE( parent_grfMode ) )
+    return STG_E_ACCESSDENIED;
+
+  /*
    * Initialize the out parameter
    */
   *ppstm = 0;
@@ -1005,6 +1036,7 @@ HRESULT WINAPI StorageImpl_CreateStorage
   ULONG            foundPropertyIndex;
   ULONG            newPropertyIndex;
   HRESULT          hr;
+  DWORD            parent_grfMode;
 
   TRACE("(%p, %s, %lx, %ld, %ld, %p)\n",
 	iface, debugstr_w(pwcsName), grfMode,
@@ -1027,6 +1059,13 @@ HRESULT WINAPI StorageImpl_CreateStorage
     return STG_E_INVALIDFLAG;
 
   /*
+   * Check that we're compatible with the parent's storage mode
+   */
+  parent_grfMode = STGM_ACCESS_MODE( This->base.ancestorStorage->base.openFlags );
+  if ( STGM_ACCESS_MODE( grfMode ) > STGM_ACCESS_MODE( parent_grfMode ) )
+    return STG_E_ACCESSDENIED;
+
+  /*
    * Initialize the out parameter
    */
   *ppstg = 0;
@@ -2186,6 +2225,7 @@ HRESULT StorageImpl_Construct(
   This->base.lpVtbl = &Storage32Impl_Vtbl;
   This->base.pssVtbl = &IPropertySetStorage_Vtbl;
   This->base.v_destructor = &StorageImpl_Destroy;
+  This->base.openFlags = openFlags;
 
   /*
    * This is the top-level storage so initialize the ancestor pointer
@@ -4013,7 +4053,8 @@ static IStorageVtbl Storage32InternalImp
 
 StorageInternalImpl* StorageInternalImpl_Construct(
   StorageImpl* ancestorStorage,
-  ULONG          rootPropertyIndex)
+  DWORD        openFlags,
+  ULONG        rootPropertyIndex)
 {
   StorageInternalImpl* newStorage;
 
@@ -4031,6 +4072,7 @@ StorageInternalImpl* StorageInternalImpl
      */
     newStorage->base.lpVtbl = &Storage32InternalImpl_Vtbl;
     newStorage->base.v_destructor = &StorageInternalImpl_Destroy;
+    newStorage->base.openFlags = openFlags;
 
     /*
      * Keep the ancestor storage pointer and nail a reference to it.
Index: dlls/ole32/storage32.h
===================================================================
RCS file: /home/wine/wine/dlls/ole32/storage32.h,v
retrieving revision 1.22
diff -u -p -r1.22 storage32.h
--- dlls/ole32/storage32.h	24 Apr 2005 17:22:26 -0000	1.22
+++ dlls/ole32/storage32.h	13 May 2005 08:50:27 -0000
@@ -239,6 +239,11 @@ struct StorageBaseImpl
    * virtual Destructor method.
    */
   void (*v_destructor)(StorageBaseImpl*);
+
+  /*
+   * flags that this storage was opened or created with
+   */
+  DWORD openFlags;
 };
 
 
@@ -399,6 +404,7 @@ struct StorageInternalImpl
  */
 StorageInternalImpl* StorageInternalImpl_Construct(
 	    StorageImpl* ancestorStorage,
+            DWORD          openFlags,
 	    ULONG          rootTropertyIndex);
 
 void StorageInternalImpl_Destroy(
Index: dlls/ole32/tests/storage32.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/tests/storage32.c,v
retrieving revision 1.10
diff -u -p -r1.10 storage32.c
--- dlls/ole32/tests/storage32.c	22 Mar 2005 18:18:43 -0000	1.10
+++ dlls/ole32/tests/storage32.c	13 May 2005 08:50:27 -0000
@@ -421,6 +421,25 @@ void test_open_storage(void)
         ok(r == 0, "wrong ref count\n");
     }
 
+    /* now try write to a storage file we opened read-only */ 
+    r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg);
+    ok(r==S_OK, "StgOpenStorage failed\n");
+    if(stg)
+    { 
+        const static WCHAR stmname[] =  { 'w','i','n','e','t','e','s','t',0};
+        IStream *stm = NULL;
+        IStorage *stg2 = NULL;
+
+        r = IStorage_CreateStream( stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE,
+                                   0, 0, &stm );
+        ok(r == STG_E_ACCESSDENIED, "CreateStream should fail\n");
+        r = IStorage_CreateStorage( stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
+        ok(r == STG_E_ACCESSDENIED, "CreateStream should fail\n");
+
+        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