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

oldstable
Mike McCormack 2005-05-13 13:58:43 +00:00 committed by Alexandre Julliard
parent 3f5990eb9a
commit e3b43fa458
3 changed files with 68 additions and 1 deletions

View File

@ -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);
@ -334,6 +335,16 @@ HRESULT WINAPI StorageBaseImpl_OpenStream(
goto end;
}
/*
* 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
*/
@ -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,
@ -453,6 +465,16 @@ HRESULT WINAPI StorageBaseImpl_OpenStorage(
goto end;
}
/*
* 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
*/
@ -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,
@ -837,6 +861,13 @@ HRESULT WINAPI StorageBaseImpl_CreateStream(
(grfMode & STGM_TRANSACTED))
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
*/
@ -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,
@ -1026,6 +1058,13 @@ HRESULT WINAPI StorageImpl_CreateStorage(
(grfMode & STGM_DELETEONRELEASE) )
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
*/
@ -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.

View File

@ -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(

View File

@ -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");
}