From: Piotr Caban piotr@codeweavers.com
--- dlls/ole32/stg_prop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/ole32/stg_prop.c b/dlls/ole32/stg_prop.c index 7481f0f3480..d988a009355 100644 --- a/dlls/ole32/stg_prop.c +++ b/dlls/ole32/stg_prop.c @@ -1518,7 +1518,7 @@ static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const struct read { DWORD count, i;
- switch (prop->vt & VT_VECTOR) + switch (prop->vt & ~VT_VECTOR) { case VT_BSTR: case VT_VARIANT:
From: Piotr Caban piotr@codeweavers.com
--- dlls/ole32/tests/stg_prop.c | 79 +++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+)
diff --git a/dlls/ole32/tests/stg_prop.c b/dlls/ole32/tests/stg_prop.c index 90e1f6a8f48..8dd6b7c6daf 100644 --- a/dlls/ole32/tests/stg_prop.c +++ b/dlls/ole32/tests/stg_prop.c @@ -628,11 +628,15 @@ static void test_propertyset_storage_enum(void) IPropertyStorage *prop_storage, *prop_storage2; IPropertySetStorage *ps_storage; IEnumSTATPROPSETSTG *ps_enum; + IEnumSTATPROPSTG *prop_enum; WCHAR filename[MAX_PATH]; STATPROPSETSTG psstg; + STATPROPSTG pstg; DWORD ret, fetched; IStorage *storage; FILETIME ftime; + PROPVARIANT pv; + PROPSPEC ps; HRESULT hr;
ret = GetTempFileNameW(L".", L"stg", 0, filename); @@ -733,6 +737,81 @@ todo_wine { IPropertySetStorage_Release(ps_storage); IStorage_Release(storage);
+ /* test FMTID_UserDefinedProperties */ + hr = StgCreateDocfile(filename, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, &storage); + ok(hr == S_OK, "Failed to crate storage, hr %#lx.\n", hr); + + hr = StgCreatePropSetStg(storage, 0, &ps_storage); + ok(hr == S_OK, "Failed to create property set storage, hr %#lx.\n", hr); + + hr = IPropertySetStorage_Create(ps_storage, &FMTID_UserDefinedProperties, &IID_IUnknown, + PROPSETFLAG_ANSI, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE, &prop_storage); + ok(hr == S_OK, "Failed to create property storage, hr %#lx.\n", hr); + ps.ulKind = PRSPEC_PROPID; + ps.propid = 0x10; + pv.vt = VT_I4; + pv.lVal = 10; + hr = IPropertyStorage_WriteMultiple(prop_storage, 1, &ps, &pv, 0x10); + ok(hr == S_OK, "Failed to add property, hr %#lx.\n", hr); + IPropertyStorage_Release(prop_storage); + + hr = IPropertySetStorage_Open(ps_storage, &FMTID_DocSummaryInformation, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, &prop_storage); + ok(hr == S_OK, "Failed to open FMTID_DocSummaryInformation, hr %#lx.\n", hr); + pv.vt = VT_UI4; + pv.lVal = 11; + hr = IPropertyStorage_WriteMultiple(prop_storage, 1, &ps, &pv, 0x10); + ok(hr == S_OK, "Failed to add property, hr %#lx.\n", hr); + IPropertyStorage_Release(prop_storage); + + hr = IPropertySetStorage_Enum(ps_storage, &ps_enum); + ok(hr == S_OK, "Failed to get enum object, hr %#lx.\n", hr); + memset(&psstg, 0, sizeof(psstg)); + hr = IEnumSTATPROPSETSTG_Next(ps_enum, 1, &psstg, &fetched); + ok(hr == S_OK, "Failed to get enum item, hr %#lx.\n", hr); + ok(fetched == 1, "Unexpected fetched count.\n"); + ok(IsEqualCLSID(&psstg.fmtid, &FMTID_DocSummaryInformation), "Unexpected fmtid %s.\n", + wine_dbgstr_guid(&psstg.fmtid)); + memset(&psstg, 0, sizeof(psstg)); + hr = IEnumSTATPROPSETSTG_Next(ps_enum, 1, &psstg, &fetched); + ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr); + IEnumSTATPROPSETSTG_Release(ps_enum); + + hr = IPropertySetStorage_Open(ps_storage, &FMTID_DocSummaryInformation, + STGM_READ | STGM_SHARE_EXCLUSIVE, &prop_storage); + ok(hr == S_OK, "Failed to open FMTID_DocSummaryInformation, hr %#lx.\n", hr); + hr = IPropertyStorage_Enum(prop_storage, &prop_enum); + ok(hr == S_OK, "IPropertyStorage_Enum failed, hr %#lx.\n", hr); + memset(&pstg, 0, sizeof(pstg)); + hr = IEnumSTATPROPSTG_Next(prop_enum, 1, &pstg, &fetched); + ok(hr == S_OK, "IEnumSTATPROPSTG_Next failed, hr %#lx.\n", hr); + ok(pstg.propid == 0x10, "pstg.propid = %lx\n", pstg.propid); + ok(pstg.vt == VT_UI4, "pstg.vt = %d\n", pstg.vt); + memset(&pstg, 0, sizeof(pstg)); + hr = IEnumSTATPROPSTG_Next(prop_enum, 1, &pstg, &fetched); + ok(hr == S_FALSE, "IEnumSTATPROPSTG_Next failed, hr %#lx.\n", hr); + IEnumSTATPROPSTG_Release(prop_enum); + IPropertyStorage_Release(prop_storage); + + hr = IPropertySetStorage_Open(ps_storage, &FMTID_UserDefinedProperties, + STGM_READ | STGM_SHARE_EXCLUSIVE, &prop_storage); + ok(hr == S_OK, "Failed to open FMTID_DocSummaryInformation, hr %#lx.\n", hr); + hr = IPropertyStorage_Enum(prop_storage, &prop_enum); + ok(hr == S_OK, "IPropertyStorage_Enum failed, hr %#lx.\n", hr); + memset(&pstg, 0, sizeof(pstg)); + hr = IEnumSTATPROPSTG_Next(prop_enum, 1, &pstg, &fetched); + ok(hr == S_OK, "IEnumSTATPROPSTG_Next failed, hr %#lx.\n", hr); + ok(pstg.propid == 0x10, "pstg.propid = %lx\n", pstg.propid); + todo_wine ok(pstg.vt == VT_I4, "pstg.vt = %d\n", pstg.vt); + memset(&pstg, 0, sizeof(pstg)); + hr = IEnumSTATPROPSTG_Next(prop_enum, 1, &pstg, &fetched); + ok(hr == S_FALSE, "IEnumSTATPROPSTG_Next failed, hr %#lx.\n", hr); + IEnumSTATPROPSTG_Release(prop_enum); + IPropertyStorage_Release(prop_storage); + + IPropertySetStorage_Release(ps_storage); + IStorage_Release(storage); + ret = DeleteFileW(filename); ok(ret, "Failed to delete storage file.\n"); }
From: Piotr Caban piotr@codeweavers.com
--- dlls/ole32/stg_prop.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/dlls/ole32/stg_prop.c b/dlls/ole32/stg_prop.c index d988a009355..a19ce8ad3d6 100644 --- a/dlls/ole32/stg_prop.c +++ b/dlls/ole32/stg_prop.c @@ -1798,6 +1798,10 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This) hr = STG_E_INVALIDHEADER; goto end; } + seek.QuadPart = fmtOffset.dwOffset; + hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL); + if (FAILED(hr)) + goto end; /* wackiness alert: if the format ID is FMTID_DocSummaryInformation, there * follows not one, but two sections. The first contains the standard properties * for the document summary information, and the second consists of user-defined
From: Piotr Caban piotr@codeweavers.com
--- dlls/ole32/tests/stg_prop.c | 115 ++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+)
diff --git a/dlls/ole32/tests/stg_prop.c b/dlls/ole32/tests/stg_prop.c index 8dd6b7c6daf..128de9fc72e 100644 --- a/dlls/ole32/tests/stg_prop.c +++ b/dlls/ole32/tests/stg_prop.c @@ -623,6 +623,81 @@ static void testFmtId(void) "Got unexpected FMTID, expected IID_IPropertySetStorage\n"); }
+typedef struct +{ + WORD byte_order; + WORD format; + DWORD os_ver; + CLSID clsid; + DWORD reserved; +} PROPERTYSETHEADER; + +typedef struct +{ + FMTID fmtid; + DWORD offset; +} FORMATIDOFFSET; + +typedef struct +{ + DWORD size; + DWORD properties; +} PROPERTYSECTIONHEADER; + +typedef struct +{ + DWORD propid; + DWORD offset; +} PROPERTYIDOFFSET; + +typedef struct +{ + DWORD type; + DWORD data; +} PROPVARIANT_DWORD; + +struct test_prop_data +{ + PROPERTYSETHEADER header; + FORMATIDOFFSET doc_summary; + FORMATIDOFFSET user_def_props; + PROPERTYSECTIONHEADER doc_summary_header; + PROPERTYIDOFFSET prop1; + PROPVARIANT_DWORD prop1_val; + PROPERTYSECTIONHEADER user_def_props_header; + PROPERTYIDOFFSET prop2; + PROPVARIANT_DWORD prop2_val; +} test_prop_data = { + { + 0xfffe, 0, 0x2000a00, + /* IID_IUnknown */ + {0x00000000, 0x0000, 0x0000, {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}, + 2 + }, + { + /* FMTID_DocSummaryInformation */ + {0xd5cdd502, 0x2e9c, 0x101b, {0x93, 0x97, 0x08, 0x00, 0x2b, 0x2c, 0xf9, 0xae}}, + FIELD_OFFSET(struct test_prop_data, doc_summary_header) + }, + { + /* FMTID_UserDefinedProperties */ + {0xd5cdd505, 0x2e9c, 0x101b, {0x93, 0x97, 0x08, 0x00, 0x2b, 0x2c, 0xf9, 0xae}}, + FIELD_OFFSET(struct test_prop_data, user_def_props_header) + }, + { + sizeof(PROPERTYSECTIONHEADER) + sizeof(PROPERTYIDOFFSET) + sizeof(PROPVARIANT_DWORD), + 1 + }, + { 0x10, sizeof(PROPERTYSECTIONHEADER) + sizeof(PROPERTYIDOFFSET) }, + { VT_UI4, 11 }, + { + sizeof(PROPERTYSECTIONHEADER) + sizeof(PROPERTYIDOFFSET) + sizeof(PROPVARIANT_DWORD), + 1 + }, + { 0x10, sizeof(PROPERTYSECTIONHEADER) + sizeof(PROPERTYIDOFFSET) }, + { VT_I4, 10 } +}; + static void test_propertyset_storage_enum(void) { IPropertyStorage *prop_storage, *prop_storage2; @@ -634,6 +709,7 @@ static void test_propertyset_storage_enum(void) STATPROPSTG pstg; DWORD ret, fetched; IStorage *storage; + IStream *stream; FILETIME ftime; PROPVARIANT pv; PROPSPEC ps; @@ -809,6 +885,45 @@ todo_wine { IEnumSTATPROPSTG_Release(prop_enum); IPropertyStorage_Release(prop_storage);
+ hr = IStorage_OpenStream(storage, L"\5DocumentSummaryInformation", NULL, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stream); + ok(hr == S_OK, "IStorage_CreateStream failed, hr %#lx.\n", hr); + hr = IStream_Write(stream, &test_prop_data, sizeof(test_prop_data), NULL); + ok(hr == S_OK, "IStream_Write failed, hr %#lx.\n", hr); + IStream_Release(stream); + + hr = IPropertySetStorage_Open(ps_storage, &FMTID_DocSummaryInformation, + STGM_READ | STGM_SHARE_EXCLUSIVE, &prop_storage); + ok(hr == S_OK, "Failed to open FMTID_DocSummaryInformation, hr %#lx.\n", hr); + hr = IPropertyStorage_Enum(prop_storage, &prop_enum); + ok(hr == S_OK, "IPropertyStorage_Enum failed, hr %#lx.\n", hr); + memset(&pstg, 0, sizeof(pstg)); + hr = IEnumSTATPROPSTG_Next(prop_enum, 1, &pstg, &fetched); + ok(hr == S_OK, "IEnumSTATPROPSTG_Next failed, hr %#lx.\n", hr); + ok(pstg.propid == 0x10, "pstg.propid = %lx\n", pstg.propid); + ok(pstg.vt == VT_UI4, "pstg.vt = %d\n", pstg.vt); + memset(&pstg, 0, sizeof(pstg)); + hr = IEnumSTATPROPSTG_Next(prop_enum, 1, &pstg, &fetched); + ok(hr == S_FALSE, "IEnumSTATPROPSTG_Next failed, hr %#lx.\n", hr); + IEnumSTATPROPSTG_Release(prop_enum); + IPropertyStorage_Release(prop_storage); + + hr = IPropertySetStorage_Open(ps_storage, &FMTID_UserDefinedProperties, + STGM_READ | STGM_SHARE_EXCLUSIVE, &prop_storage); + ok(hr == S_OK, "Failed to open FMTID_DocSummaryInformation, hr %#lx.\n", hr); + hr = IPropertyStorage_Enum(prop_storage, &prop_enum); + ok(hr == S_OK, "IPropertyStorage_Enum failed, hr %#lx.\n", hr); + memset(&pstg, 0, sizeof(pstg)); + hr = IEnumSTATPROPSTG_Next(prop_enum, 1, &pstg, &fetched); + ok(hr == S_OK, "IEnumSTATPROPSTG_Next failed, hr %#lx.\n", hr); + ok(pstg.propid == 0x10, "pstg.propid = %lx\n", pstg.propid); + todo_wine ok(pstg.vt == VT_I4, "pstg.vt = %d\n", pstg.vt); + memset(&pstg, 0, sizeof(pstg)); + hr = IEnumSTATPROPSTG_Next(prop_enum, 1, &pstg, &fetched); + ok(hr == S_FALSE, "IEnumSTATPROPSTG_Next failed, hr %#lx.\n", hr); + IEnumSTATPROPSTG_Release(prop_enum); + IPropertyStorage_Release(prop_storage); + IPropertySetStorage_Release(ps_storage); IStorage_Release(storage);