Make sure a stream can't be created in read only storage.
This commit is contained in:
parent
3f5990eb9a
commit
e3b43fa458
|
@ -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.
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue