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(
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_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
*/
propertyEnumeration = IEnumSTATSTGImpl_Construct(
......@@ -412,6 +423,7 @@ HRESULT WINAPI StorageBaseImpl_OpenStorage(
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_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
*/
*ppstg = NULL;
......@@ -489,6 +511,7 @@ HRESULT WINAPI StorageBaseImpl_OpenStorage(
*/
newStorage = StorageInternalImpl_Construct(
This->ancestorStorage,
grfMode,
foundPropertyIndex);
if (newStorage != 0)
......@@ -804,6 +827,7 @@ HRESULT WINAPI StorageBaseImpl_CreateStream(
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_CreateStream(
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 Storage32InternalImpl_Vtbl =
StorageInternalImpl* StorageInternalImpl_Construct(
StorageImpl* ancestorStorage,
ULONG rootPropertyIndex)
DWORD openFlags,
ULONG rootPropertyIndex)
{
StorageInternalImpl* newStorage;
......@@ -4031,6 +4072,7 @@ StorageInternalImpl* StorageInternalImpl_Construct(
*/
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.
......
......@@ -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(
......
......@@ -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");
}
......
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