From c40429f3c9e6fbde1349f1c94ea91322068cc009 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sat, 21 Jan 2017 19:24:12 +0100 Subject: [PATCH] Added patch with multiple fixes for ole32 property storage. --- ...parse-unicode-property-storage-dicti.patch | 37 +++++ ...ading-VT_BOOL-VT_R8-and-VT_I8-into-p.patch | 46 ++++++ ...returning-a-name-in-IEnumSTATPROPSTG.patch | 146 ++++++++++++++++++ patches/ole32-STGPROP/definition | 1 + patches/patchinstall.sh | 25 ++- 5 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 patches/ole32-STGPROP/0001-ole32-Correctly-parse-unicode-property-storage-dicti.patch create mode 100644 patches/ole32-STGPROP/0002-ole32-Support-reading-VT_BOOL-VT_R8-and-VT_I8-into-p.patch create mode 100644 patches/ole32-STGPROP/0003-ole32-Implement-returning-a-name-in-IEnumSTATPROPSTG.patch create mode 100644 patches/ole32-STGPROP/definition diff --git a/patches/ole32-STGPROP/0001-ole32-Correctly-parse-unicode-property-storage-dicti.patch b/patches/ole32-STGPROP/0001-ole32-Correctly-parse-unicode-property-storage-dicti.patch new file mode 100644 index 00000000..ecae05cd --- /dev/null +++ b/patches/ole32-STGPROP/0001-ole32-Correctly-parse-unicode-property-storage-dicti.patch @@ -0,0 +1,37 @@ +From 9a73838c005c3bdb74a449bb7afb269112d6ae34 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Fri, 20 Jan 2017 01:35:05 +0100 +Subject: ole32: Correctly parse unicode property storage dictionaries. + +--- + dlls/ole32/stg_prop.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/dlls/ole32/stg_prop.c b/dlls/ole32/stg_prop.c +index a2598832bf1..f952704c7cd 100644 +--- a/dlls/ole32/stg_prop.c ++++ b/dlls/ole32/stg_prop.c +@@ -1020,15 +1020,18 @@ static HRESULT PropertyStorage_ReadDictionary(PropertyStorage_impl *This, + if (This->codePage != CP_UNICODE) + ptr[cbEntry - 1] = '\0'; + else +- *((LPWSTR)ptr + cbEntry / sizeof(WCHAR)) = '\0'; ++ ((LPWSTR)ptr)[cbEntry - 1] = 0; + hr = PropertyStorage_StoreNameWithId(This, (char*)ptr, This->codePage, propid); + if (This->codePage == CP_UNICODE) + { ++ /* cbEntry is the number of characters */ ++ cbEntry *= 2; ++ + /* Unicode entries are padded to DWORD boundaries */ + if (cbEntry % sizeof(DWORD)) + ptr += sizeof(DWORD) - (cbEntry % sizeof(DWORD)); + } +- ptr += sizeof(DWORD) + cbEntry; ++ ptr += cbEntry; + } + return hr; + } +-- +2.11.0 + diff --git a/patches/ole32-STGPROP/0002-ole32-Support-reading-VT_BOOL-VT_R8-and-VT_I8-into-p.patch b/patches/ole32-STGPROP/0002-ole32-Support-reading-VT_BOOL-VT_R8-and-VT_I8-into-p.patch new file mode 100644 index 00000000..7d3736e1 --- /dev/null +++ b/patches/ole32-STGPROP/0002-ole32-Support-reading-VT_BOOL-VT_R8-and-VT_I8-into-p.patch @@ -0,0 +1,46 @@ +From fe0714a56f0b6b69336446c6f68abafba29f57bd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Fri, 20 Jan 2017 01:39:01 +0100 +Subject: ole32: Support reading VT_BOOL, VT_R8 and VT_I8 into propery storage. + +--- + dlls/ole32/stg_prop.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/dlls/ole32/stg_prop.c b/dlls/ole32/stg_prop.c +index f952704c7cd..e90e1ed4eda 100644 +--- a/dlls/ole32/stg_prop.c ++++ b/dlls/ole32/stg_prop.c +@@ -1066,6 +1066,10 @@ static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const BYTE *data, + prop->u.bVal = *data; + TRACE("Read byte 0x%x\n", prop->u.bVal); + break; ++ case VT_BOOL: ++ StorageUtl_ReadWord(data, 0, (WORD*)&prop->u.boolVal); ++ TRACE("Read bool %d\n", prop->u.boolVal); ++ break; + case VT_I2: + StorageUtl_ReadWord(data, 0, (WORD*)&prop->u.iVal); + TRACE("Read short %d\n", prop->u.iVal); +@@ -1084,6 +1088,18 @@ static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const BYTE *data, + StorageUtl_ReadDWord(data, 0, &prop->u.ulVal); + TRACE("Read ulong %d\n", prop->u.ulVal); + break; ++ case VT_I8: ++ StorageUtl_ReadULargeInteger(data, 0, (ULARGE_INTEGER *)&prop->u.hVal); ++ TRACE("Read long long %s\n", wine_dbgstr_longlong(prop->u.hVal.QuadPart)); ++ break; ++ case VT_UI8: ++ StorageUtl_ReadULargeInteger(data, 0, &prop->u.uhVal); ++ TRACE("Read ulong long %s\n", wine_dbgstr_longlong(prop->u.uhVal.QuadPart)); ++ break; ++ case VT_R8: ++ memcpy(&prop->u.dblVal, data, sizeof(double)); ++ TRACE("Read double %f\n", prop->u.dblVal); ++ break; + case VT_LPSTR: + { + DWORD count; +-- +2.11.0 + diff --git a/patches/ole32-STGPROP/0003-ole32-Implement-returning-a-name-in-IEnumSTATPROPSTG.patch b/patches/ole32-STGPROP/0003-ole32-Implement-returning-a-name-in-IEnumSTATPROPSTG.patch new file mode 100644 index 00000000..4e2e5419 --- /dev/null +++ b/patches/ole32-STGPROP/0003-ole32-Implement-returning-a-name-in-IEnumSTATPROPSTG.patch @@ -0,0 +1,146 @@ +From 78ca8c020c1fefe80de805b096b02a4418f062a8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Fri, 20 Jan 2017 01:42:07 +0100 +Subject: ole32: Implement returning a name in IEnumSTATPROPSTG. + +--- + dlls/ole32/enumx.c | 16 ++++++++++++++-- + dlls/ole32/enumx.h | 5 ++++- + dlls/ole32/stg_prop.c | 29 +++++++++++++++++++++++++++-- + 3 files changed, 45 insertions(+), 5 deletions(-) + +diff --git a/dlls/ole32/enumx.c b/dlls/ole32/enumx.c +index 4279ca81fa9..2b53810dad9 100644 +--- a/dlls/ole32/enumx.c ++++ b/dlls/ole32/enumx.c +@@ -41,6 +41,8 @@ struct tagEnumSTATPROPSETSTG_impl + struct list *current; + ULONG elem_size; + GUID riid; ++ IUnknown *parent; ++ enumx_copy_cb copy_cb; + }; + + /************************************************************************ +@@ -91,6 +93,7 @@ ULONG WINAPI enumx_Release(enumx_impl *This) + list_remove(x); + HeapFree(GetProcessHeap(), 0, x); + } ++ IUnknown_Release(This->parent); + HeapFree(GetProcessHeap(), 0, This); + } + return ref; +@@ -112,7 +115,10 @@ HRESULT WINAPI enumx_Next(enumx_impl *This, ULONG celt, + p = rgelt; + while (count < celt && This->current && This->current != &This->elements) + { +- memcpy(p, &This->current[1], This->elem_size); ++ if (This->copy_cb) ++ This->copy_cb(This->parent, &This->current[1], p); ++ else ++ memcpy(p, &This->current[1], This->elem_size); + p += This->elem_size; + This->current = This->current->next; + count++; +@@ -169,7 +175,8 @@ HRESULT WINAPI enumx_Clone( + * + * Allocate a generic enumerator + */ +-enumx_impl *enumx_allocate(REFIID riid, const void *vtbl, ULONG elem_size) ++enumx_impl *enumx_allocate(REFIID riid, const void *vtbl, ULONG elem_size, ++ IUnknown *parent, enumx_copy_cb copy_cb) + { + enumx_impl *enumx; + +@@ -181,6 +188,11 @@ enumx_impl *enumx_allocate(REFIID riid, const void *vtbl, ULONG elem_size) + enumx->current = NULL; + enumx->elem_size = elem_size; + enumx->riid = *riid; ++ enumx->parent = parent; ++ enumx->copy_cb = copy_cb; ++ ++ IUnknown_AddRef(parent); ++ + list_init(&enumx->elements); + } + +diff --git a/dlls/ole32/enumx.h b/dlls/ole32/enumx.h +index da76e13769b..8a2a2b354d8 100644 +--- a/dlls/ole32/enumx.h ++++ b/dlls/ole32/enumx.h +@@ -21,6 +21,8 @@ + + typedef struct tagEnumSTATPROPSETSTG_impl enumx_impl; + ++typedef void (*enumx_copy_cb)(IUnknown *parent, void *orig, void *dest); ++ + extern HRESULT WINAPI enumx_QueryInterface(enumx_impl *, REFIID, void**) DECLSPEC_HIDDEN; + extern ULONG WINAPI enumx_AddRef(enumx_impl *) DECLSPEC_HIDDEN; + extern ULONG WINAPI enumx_Release(enumx_impl *) DECLSPEC_HIDDEN; +@@ -28,7 +30,8 @@ extern HRESULT WINAPI enumx_Next(enumx_impl *, ULONG, void *, ULONG *) DECLSPEC_ + extern HRESULT WINAPI enumx_Skip(enumx_impl *, ULONG) DECLSPEC_HIDDEN; + extern HRESULT WINAPI enumx_Reset(enumx_impl *) DECLSPEC_HIDDEN; + extern HRESULT WINAPI enumx_Clone(enumx_impl *, enumx_impl **) DECLSPEC_HIDDEN; +-extern enumx_impl *enumx_allocate(REFIID, const void *, ULONG) DECLSPEC_HIDDEN; ++extern enumx_impl *enumx_allocate(REFIID, const void *, ULONG, ++ IUnknown *, enumx_copy_cb) DECLSPEC_HIDDEN; + extern void *enumx_add_element(enumx_impl *, const void *) DECLSPEC_HIDDEN; + + #endif +diff --git a/dlls/ole32/stg_prop.c b/dlls/ole32/stg_prop.c +index e90e1ed4eda..bfc052966ab 100644 +--- a/dlls/ole32/stg_prop.c ++++ b/dlls/ole32/stg_prop.c +@@ -2393,7 +2393,9 @@ static HRESULT create_EnumSTATPROPSETSTG( + + enumx = enumx_allocate(&IID_IEnumSTATPROPSETSTG, + &IEnumSTATPROPSETSTG_Vtbl, +- sizeof (STATPROPSETSTG)); ++ sizeof (STATPROPSETSTG), ++ (IUnknown*)&This->base.IStorage_iface, ++ NULL); + + /* add all the property set elements into a list */ + r = IStorage_EnumElements(stg, 0, NULL, 0, &penum); +@@ -2486,6 +2488,27 @@ static HRESULT WINAPI IEnumSTATPROPSTG_fnClone( + return enumx_Clone((enumx_impl*)iface, (enumx_impl**)ppenum); + } + ++static void prop_enum_copy_cb(IUnknown *parent, void *orig, void *dest) ++{ ++ PropertyStorage_impl *storage = impl_from_IPropertyStorage((IPropertyStorage*)parent); ++ STATPROPSTG *src_prop = orig; ++ STATPROPSTG *dest_prop = dest; ++ LPWSTR name; ++ ++ dest_prop->propid = src_prop->propid; ++ dest_prop->vt = src_prop->vt; ++ dest_prop->lpwstrName = NULL; ++ ++ if (dictionary_find(storage->propid_to_name, UlongToPtr(src_prop->propid), (void**)&name)) ++ { ++ DWORD size = (strlenW(name) + 1) * sizeof(WCHAR); ++ ++ dest_prop->lpwstrName = CoTaskMemAlloc(size); ++ if (!dest_prop->lpwstrName) return; ++ memcpy(dest_prop->lpwstrName, name, size); ++ } ++} ++ + static BOOL prop_enum_stat(const void *k, const void *v, void *extra, void *arg) + { + enumx_impl *enumx = arg; +@@ -2512,7 +2535,9 @@ static HRESULT create_EnumSTATPROPSTG( + + enumx = enumx_allocate(&IID_IEnumSTATPROPSTG, + &IEnumSTATPROPSTG_Vtbl, +- sizeof (STATPROPSTG)); ++ sizeof (STATPROPSTG), ++ (IUnknown*)&This->IPropertyStorage_iface, ++ prop_enum_copy_cb); + + dictionary_enumerate(This->propid_to_prop, prop_enum_stat, enumx); + +-- +2.11.0 + diff --git a/patches/ole32-STGPROP/definition b/patches/ole32-STGPROP/definition new file mode 100644 index 00000000..6f388456 --- /dev/null +++ b/patches/ole32-STGPROP/definition @@ -0,0 +1 @@ +Fixes: [42046] Multiple fixes for ole32 property storage diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 2a8e6a71..daf243a7 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -52,7 +52,7 @@ usage() # Get the upstream commit sha upstream_commit() { - echo "3ba2b5898cf9c78f81afc1fd620e5046a3392be0" + echo "199e30663efadfb1539f240e6fa29204440e9974" } # Show version information @@ -276,6 +276,7 @@ patch_enable_all () enable_nvencodeapi_Video_Encoder="$1" enable_ole32_HGLOBALStream="$1" enable_ole32_OleGetIconOfFile="$1" + enable_ole32_STGPROP="$1" enable_oleaut32_CreateTypeLib="$1" enable_oleaut32_DispCallFunc="$1" enable_oleaut32_ITypeInfo_fnInvoke="$1" @@ -1044,6 +1045,9 @@ patch_enable () ole32-OleGetIconOfFile) enable_ole32_OleGetIconOfFile="$2" ;; + ole32-STGPROP) + enable_ole32_STGPROP="$2" + ;; oleaut32-CreateTypeLib) enable_oleaut32_CreateTypeLib="$2" ;; @@ -6275,6 +6279,25 @@ if test "$enable_ole32_OleGetIconOfFile" -eq 1; then ) >> "$patchlist" fi +# Patchset ole32-STGPROP +# | +# | This patchset fixes the following Wine bugs: +# | * [#42046] Multiple fixes for ole32 property storage +# | +# | Modified files: +# | * dlls/ole32/enumx.c, dlls/ole32/enumx.h, dlls/ole32/stg_prop.c +# | +if test "$enable_ole32_STGPROP" -eq 1; then + patch_apply ole32-STGPROP/0001-ole32-Correctly-parse-unicode-property-storage-dicti.patch + patch_apply ole32-STGPROP/0002-ole32-Support-reading-VT_BOOL-VT_R8-and-VT_I8-into-p.patch + patch_apply ole32-STGPROP/0003-ole32-Implement-returning-a-name-in-IEnumSTATPROPSTG.patch + ( + printf '%s\n' '+ { "Michael Müller", "ole32: Correctly parse unicode property storage dictionaries.", 1 },'; + printf '%s\n' '+ { "Michael Müller", "ole32: Support reading VT_BOOL, VT_R8 and VT_I8 into propery storage.", 1 },'; + printf '%s\n' '+ { "Michael Müller", "ole32: Implement returning a name in IEnumSTATPROPSTG.", 1 },'; + ) >> "$patchlist" +fi + # Patchset oleaut32-CreateTypeLib # | # | This patchset fixes the following Wine bugs: