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