Commit e3b43fa4 authored by Mike McCormack's avatar Mike McCormack Committed by Alexandre Julliard

Make sure a stream can't be created in read only storage.

parent 3f5990eb
...@@ -296,6 +296,7 @@ HRESULT WINAPI StorageBaseImpl_OpenStream( ...@@ -296,6 +296,7 @@ HRESULT WINAPI StorageBaseImpl_OpenStream(
StgProperty currentProperty; StgProperty currentProperty;
ULONG foundPropertyIndex; ULONG foundPropertyIndex;
HRESULT res = STG_E_UNKNOWN; HRESULT res = STG_E_UNKNOWN;
DWORD parent_grfMode;
TRACE("(%p, %s, %p, %lx, %ld, %p)\n", TRACE("(%p, %s, %p, %lx, %ld, %p)\n",
iface, debugstr_w(pwcsName), reserved1, grfMode, reserved2, ppstm); iface, debugstr_w(pwcsName), reserved1, grfMode, reserved2, ppstm);
...@@ -335,6 +336,16 @@ HRESULT WINAPI StorageBaseImpl_OpenStream( ...@@ -335,6 +336,16 @@ HRESULT WINAPI StorageBaseImpl_OpenStream(
} }
/* /*
* 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 * Create a property enumeration to search the properties
*/ */
propertyEnumeration = IEnumSTATSTGImpl_Construct( propertyEnumeration = IEnumSTATSTGImpl_Construct(
...@@ -412,6 +423,7 @@ HRESULT WINAPI StorageBaseImpl_OpenStorage( ...@@ -412,6 +423,7 @@ HRESULT WINAPI StorageBaseImpl_OpenStorage(
StgProperty currentProperty; StgProperty currentProperty;
ULONG foundPropertyIndex; ULONG foundPropertyIndex;
HRESULT res = STG_E_UNKNOWN; HRESULT res = STG_E_UNKNOWN;
DWORD parent_grfMode;
TRACE("(%p, %s, %p, %lx, %p, %ld, %p)\n", TRACE("(%p, %s, %p, %lx, %p, %ld, %p)\n",
iface, debugstr_w(pwcsName), pstgPriority, iface, debugstr_w(pwcsName), pstgPriority,
...@@ -454,6 +466,16 @@ HRESULT WINAPI StorageBaseImpl_OpenStorage( ...@@ -454,6 +466,16 @@ HRESULT WINAPI StorageBaseImpl_OpenStorage(
} }
/* /*
* 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 * Initialize the out parameter
*/ */
*ppstg = NULL; *ppstg = NULL;
...@@ -489,6 +511,7 @@ HRESULT WINAPI StorageBaseImpl_OpenStorage( ...@@ -489,6 +511,7 @@ HRESULT WINAPI StorageBaseImpl_OpenStorage(
*/ */
newStorage = StorageInternalImpl_Construct( newStorage = StorageInternalImpl_Construct(
This->ancestorStorage, This->ancestorStorage,
grfMode,
foundPropertyIndex); foundPropertyIndex);
if (newStorage != 0) if (newStorage != 0)
...@@ -804,6 +827,7 @@ HRESULT WINAPI StorageBaseImpl_CreateStream( ...@@ -804,6 +827,7 @@ HRESULT WINAPI StorageBaseImpl_CreateStream(
StgStreamImpl* newStream; StgStreamImpl* newStream;
StgProperty currentProperty, newStreamProperty; StgProperty currentProperty, newStreamProperty;
ULONG foundPropertyIndex, newPropertyIndex; ULONG foundPropertyIndex, newPropertyIndex;
DWORD parent_grfMode;
TRACE("(%p, %s, %lx, %ld, %ld, %p)\n", TRACE("(%p, %s, %lx, %ld, %ld, %p)\n",
iface, debugstr_w(pwcsName), grfMode, iface, debugstr_w(pwcsName), grfMode,
...@@ -838,6 +862,13 @@ HRESULT WINAPI StorageBaseImpl_CreateStream( ...@@ -838,6 +862,13 @@ HRESULT WINAPI StorageBaseImpl_CreateStream(
return STG_E_INVALIDFUNCTION; 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 * Initialize the out parameter
*/ */
*ppstm = 0; *ppstm = 0;
...@@ -1005,6 +1036,7 @@ HRESULT WINAPI StorageImpl_CreateStorage( ...@@ -1005,6 +1036,7 @@ HRESULT WINAPI StorageImpl_CreateStorage(
ULONG foundPropertyIndex; ULONG foundPropertyIndex;
ULONG newPropertyIndex; ULONG newPropertyIndex;
HRESULT hr; HRESULT hr;
DWORD parent_grfMode;
TRACE("(%p, %s, %lx, %ld, %ld, %p)\n", TRACE("(%p, %s, %lx, %ld, %ld, %p)\n",
iface, debugstr_w(pwcsName), grfMode, iface, debugstr_w(pwcsName), grfMode,
...@@ -1027,6 +1059,13 @@ HRESULT WINAPI StorageImpl_CreateStorage( ...@@ -1027,6 +1059,13 @@ HRESULT WINAPI StorageImpl_CreateStorage(
return STG_E_INVALIDFLAG; 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 * Initialize the out parameter
*/ */
*ppstg = 0; *ppstg = 0;
...@@ -2186,6 +2225,7 @@ HRESULT StorageImpl_Construct( ...@@ -2186,6 +2225,7 @@ HRESULT StorageImpl_Construct(
This->base.lpVtbl = &Storage32Impl_Vtbl; This->base.lpVtbl = &Storage32Impl_Vtbl;
This->base.pssVtbl = &IPropertySetStorage_Vtbl; This->base.pssVtbl = &IPropertySetStorage_Vtbl;
This->base.v_destructor = &StorageImpl_Destroy; This->base.v_destructor = &StorageImpl_Destroy;
This->base.openFlags = openFlags;
/* /*
* This is the top-level storage so initialize the ancestor pointer * This is the top-level storage so initialize the ancestor pointer
...@@ -4013,7 +4053,8 @@ static IStorageVtbl Storage32InternalImpl_Vtbl = ...@@ -4013,7 +4053,8 @@ static IStorageVtbl Storage32InternalImpl_Vtbl =
StorageInternalImpl* StorageInternalImpl_Construct( StorageInternalImpl* StorageInternalImpl_Construct(
StorageImpl* ancestorStorage, StorageImpl* ancestorStorage,
ULONG rootPropertyIndex) DWORD openFlags,
ULONG rootPropertyIndex)
{ {
StorageInternalImpl* newStorage; StorageInternalImpl* newStorage;
...@@ -4031,6 +4072,7 @@ StorageInternalImpl* StorageInternalImpl_Construct( ...@@ -4031,6 +4072,7 @@ StorageInternalImpl* StorageInternalImpl_Construct(
*/ */
newStorage->base.lpVtbl = &Storage32InternalImpl_Vtbl; newStorage->base.lpVtbl = &Storage32InternalImpl_Vtbl;
newStorage->base.v_destructor = &StorageInternalImpl_Destroy; newStorage->base.v_destructor = &StorageInternalImpl_Destroy;
newStorage->base.openFlags = openFlags;
/* /*
* Keep the ancestor storage pointer and nail a reference to it. * Keep the ancestor storage pointer and nail a reference to it.
......
...@@ -239,6 +239,11 @@ struct StorageBaseImpl ...@@ -239,6 +239,11 @@ struct StorageBaseImpl
* virtual Destructor method. * virtual Destructor method.
*/ */
void (*v_destructor)(StorageBaseImpl*); void (*v_destructor)(StorageBaseImpl*);
/*
* flags that this storage was opened or created with
*/
DWORD openFlags;
}; };
...@@ -399,6 +404,7 @@ struct StorageInternalImpl ...@@ -399,6 +404,7 @@ struct StorageInternalImpl
*/ */
StorageInternalImpl* StorageInternalImpl_Construct( StorageInternalImpl* StorageInternalImpl_Construct(
StorageImpl* ancestorStorage, StorageImpl* ancestorStorage,
DWORD openFlags,
ULONG rootTropertyIndex); ULONG rootTropertyIndex);
void StorageInternalImpl_Destroy( void StorageInternalImpl_Destroy(
......
...@@ -421,6 +421,25 @@ void test_open_storage(void) ...@@ -421,6 +421,25 @@ void test_open_storage(void)
ok(r == 0, "wrong ref count\n"); 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); r = DeleteFileW(filename);
ok(r, "file didn't exist\n"); ok(r, "file didn't exist\n");
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment