Commit 968126c2 authored by Andrew Eikum's avatar Andrew Eikum Committed by Alexandre Julliard

ole32: Don't fail when constants are 'incorrect'.

parent 95105c01
......@@ -198,9 +198,9 @@ FileMonikerImpl_Load(IMoniker* iface, IStream* pStm)
TRACE("(%p,%p)\n",iface,pStm);
/* first WORD must be 0 */
/* first WORD */
res=IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread);
if (bread!=sizeof(WORD) || wbuffer!=0)
if (bread!=sizeof(WORD))
{
WARN("Couldn't read 0 word\n");
goto fail;
......@@ -229,18 +229,26 @@ FileMonikerImpl_Load(IMoniker* iface, IStream* pStm)
goto fail;
}
/* read the first constant */
IStream_Read(pStm,&dwbuffer,sizeof(DWORD),&bread);
if (bread != sizeof(DWORD) || dwbuffer != 0xDEADFFFF)
/* read the unknown value */
IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread);
if (bread != sizeof(WORD))
{
WARN("Couldn't read 0xDEADFFFF constant\n");
WARN("Couldn't read unknown value\n");
goto fail;
}
/* read the DEAD constant */
IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread);
if (bread != sizeof(WORD))
{
WARN("Couldn't read DEAD constant\n");
goto fail;
}
for(i=0;i<5;i++)
{
res=IStream_Read(pStm,&dwbuffer,sizeof(DWORD),&bread);
if (bread!=sizeof(DWORD) || dwbuffer!=0)
if (bread!=sizeof(DWORD))
{
WARN("Couldn't read 0 padding\n");
goto fail;
......@@ -320,18 +328,20 @@ FileMonikerImpl_Load(IMoniker* iface, IStream* pStm)
* of Windows have minor variations.
*
* Data which must be written on stream is:
* 1) WORD constant:zero
* 1) WORD constant: zero (not validated by Windows)
* 2) length of the path string ("\0" included)
* 3) path string type A
* 4) DWORD constant : 0xDEADFFFF
* 5) five DWORD constant: zero
* 6) If we're only writing the multibyte version,
* 4) Unknown WORD value: Frequently 0xFFFF, but not always. If set very large,
* Windows returns E_OUTOFMEMORY
* 5) WORD Constant: 0xDEAD (not validated by Windows)
* 6) five DWORD constant: zero (not validated by Windows)
* 7) If we're only writing the multibyte version,
* write a zero DWORD and finish.
*
* 7) DWORD: double-length of the path string type W ("\0" not
* 8) DWORD: double-length of the path string type W ("\0" not
* included)
* 8) WORD constant: 0x3
* 9) filePath unicode string.
* 9) WORD constant: 0x3
* 10) filePath unicode string.
*
*/
static HRESULT WINAPI
......@@ -344,7 +354,8 @@ FileMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty)
CHAR* filePathA;
DWORD bytesA, bytesW, len;
static const DWORD DEADFFFF = 0xDEADFFFF; /* Constants */
static const WORD FFFF = 0xFFFF; /* Constants */
static const WORD DEAD = 0xDEAD;
static const DWORD ZERO = 0;
static const WORD THREE = 0x3;
......@@ -374,8 +385,12 @@ FileMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty)
HeapFree(GetProcessHeap(),0,filePathA);
if (FAILED(res)) return res;
/* write a DWORD 0xDEADFFFF */
res=IStream_Write(pStm,&DEADFFFF,sizeof(DWORD),NULL);
/* write a WORD 0xFFFF */
res=IStream_Write(pStm,&FFFF,sizeof(WORD),NULL);
if (FAILED(res)) return res;
/* write a WORD 0xDEAD */
res=IStream_Write(pStm,&DEAD,sizeof(WORD),NULL);
if (FAILED(res)) return res;
/* write 5 zero DWORDs */
......
......@@ -1867,6 +1867,75 @@ static void test_bind_context(void)
ok(!refs, "bound object should have been destroyed, instead of having %d refs\n", refs);
}
static void test_save_load_filemoniker(void)
{
IMoniker* pMk;
IStream* pStm;
HRESULT hr;
ULARGE_INTEGER size;
LARGE_INTEGER zero_pos, dead_pos, nulls_pos;
DWORD some_val = 0xFEDCBA98;
int i;
/* see FileMonikerImpl_Save docs */
zero_pos.u.LowPart = 0;
dead_pos.u.LowPart = sizeof(WORD) + sizeof(DWORD) + (lstrlenW(wszFileName1) + 1) + sizeof(WORD);
nulls_pos.u.LowPart = dead_pos.u.LowPart + sizeof(WORD);
/* create the stream we're going to write to */
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStm);
ok_ole_success(hr, "CreateStreamOnHGlobal");
size.u.LowPart = 128;
hr = IStream_SetSize(pStm, size);
ok_ole_success(hr, "IStream_SetSize");
/* create and save a moniker */
hr = CreateFileMoniker(wszFileName1, &pMk);
ok_ole_success(hr, "CreateFileMoniker");
hr = IMoniker_Save(pMk, pStm, TRUE);
ok_ole_success(hr, "IMoniker_Save");
hr = IMoniker_Release(pMk);
ok_ole_success(hr, "IMoniker_Release");
/* overwrite the constants with various values */
hr = IStream_Seek(pStm, zero_pos, STREAM_SEEK_SET, NULL);
ok_ole_success(hr, "IStream_Seek");
hr = IStream_Write(pStm, &some_val, sizeof(WORD), NULL);
ok_ole_success(hr, "IStream_Write");
hr = IStream_Seek(pStm, dead_pos, STREAM_SEEK_SET, NULL);
ok_ole_success(hr, "IStream_Seek");
hr = IStream_Write(pStm, &some_val, sizeof(WORD), NULL);
ok_ole_success(hr, "IStream_Write");
hr = IStream_Seek(pStm, nulls_pos, STREAM_SEEK_SET, NULL);
ok_ole_success(hr, "IStream_Seek");
for(i = 0; i < 5; ++i){
hr = IStream_Write(pStm, &some_val, sizeof(DWORD), NULL);
ok_ole_success(hr, "IStream_Write");
}
/* go back to the start of the stream */
hr = IStream_Seek(pStm, zero_pos, STREAM_SEEK_SET, NULL);
ok_ole_success(hr, "IStream_Seek");
/* create a new moniker and load into it */
hr = CreateFileMoniker(wszFileName1, &pMk);
ok_ole_success(hr, "CreateFileMoniker");
hr = IMoniker_Load(pMk, pStm);
ok_ole_success(hr, "IMoniker_Load");
hr = IMoniker_Release(pMk);
ok_ole_success(hr, "IMoniker_Release");
hr = IStream_Release(pStm);
ok_ole_success(hr, "IStream_Release");
}
START_TEST(moniker)
{
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
......@@ -1880,6 +1949,7 @@ START_TEST(moniker)
test_anti_moniker();
test_generic_composite_moniker();
test_pointer_moniker();
test_save_load_filemoniker();
/* FIXME: test moniker creation funcs and parsing other moniker formats */
......
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