From 80a4e6bdd7ea6e2a350d3b094d0ace0b27c59199 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Thu, 19 Jan 2017 06:09:18 +0100 Subject: [PATCH] Added patch to fix calling function with instance and VARIANT return type in DispCallFunc. --- ...ling-function-with-instance-and-VARI.patch | 145 ++++++++++++++++++ patches/oleaut32-DispCallFunc/definition | 1 + patches/patchinstall.sh | 19 +++ 3 files changed, 165 insertions(+) create mode 100644 patches/oleaut32-DispCallFunc/0001-oleaut32-Fix-calling-function-with-instance-and-VARI.patch create mode 100644 patches/oleaut32-DispCallFunc/definition diff --git a/patches/oleaut32-DispCallFunc/0001-oleaut32-Fix-calling-function-with-instance-and-VARI.patch b/patches/oleaut32-DispCallFunc/0001-oleaut32-Fix-calling-function-with-instance-and-VARI.patch new file mode 100644 index 00000000..4080eaba --- /dev/null +++ b/patches/oleaut32-DispCallFunc/0001-oleaut32-Fix-calling-function-with-instance-and-VARI.patch @@ -0,0 +1,145 @@ +From fcc683802ce5c7dac4127339fb2d3a6675ee87ff Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Thu, 19 Jan 2017 11:48:24 +0800 +Subject: oleaut32: Fix calling function with instance and VARIANT return type. + (v2) + +--- + dlls/oleaut32/tests/typelib.c | 59 +++++++++++++++++++++++++++++++++++++++++-- + dlls/oleaut32/typelib.c | 26 ++++++++++++++++--- + 2 files changed, 79 insertions(+), 6 deletions(-) + +diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c +index 6d0585a9cee..8f1b9d56fd1 100644 +--- a/dlls/oleaut32/tests/typelib.c ++++ b/dlls/oleaut32/tests/typelib.c +@@ -1084,11 +1084,41 @@ static HRESULT WINAPI ret_false_func(void) + return S_FALSE; + } + +-static const void *vtable[] = { NULL, NULL, NULL, inst_func }; ++static const WCHAR testW[] = { 'T','e','s','t',0 }; ++ ++static void WINAPI variant_func2(VARIANT *ret, VARIANT v1, VARIANT v2) ++{ ++ ok(V_VT(&v1) == VT_I4, "unexpected %d\n", V_VT(&v1)); ++ ok(V_I4(&v1) == 2, "unexpected %d\n", V_I4(&v1)); ++ ok(V_VT(&v2) == VT_BSTR, "unexpected %d\n", V_VT(&v2)); ++ ok(lstrcmpW(V_BSTR(&v2), testW) == 0, "unexpected %s\n", wine_dbgstr_w(V_BSTR(&v2))); ++ ++ V_VT(ret) = VT_UI4; ++ V_I4(ret) = 4321; ++} ++ ++static void WINAPI inst_func2(void *inst, VARIANT *ret, VARIANT v1, VARIANT v2) ++{ ++ ok( (*(void ***)inst)[3] == inst_func2, "wrong ptr %p\n", inst ); ++ ++ ok(V_VT(ret) == VT_I4 || broken(V_VT(ret) == VT_VARIANT) /* win64 */, "unexpected %d\n", V_VT(ret)); ++ ok(V_I4(ret) == 1234, "unexpected %d\n", V_I4(ret)); ++ ++ ok(V_VT(&v1) == VT_I4, "unexpected %d\n", V_VT(&v1)); ++ ok(V_I4(&v1) == 2, "unexpected %d\n", V_I4(&v1)); ++ ok(V_VT(&v2) == VT_BSTR, "unexpected %d\n", V_VT(&v2)); ++ ok(lstrcmpW(V_BSTR(&v2), testW) == 0, "unexpected %s\n", wine_dbgstr_w(V_BSTR(&v2))); ++ ++ V_VT(ret) = VT_UI4; ++ V_I4(ret) = 4321; ++} ++ ++static void *vtable[] = { NULL, NULL, NULL, inst_func }; ++static void *vtable2[] = { NULL, NULL, NULL, inst_func2 }; + + static void test_DispCallFunc(void) + { +- const void **inst = vtable; ++ void **inst; + HRESULT res; + VARIANT result, args[5]; + VARIANTARG *pargs[5]; +@@ -1098,6 +1128,30 @@ static void test_DispCallFunc(void) + for (i = 0; i < 5; i++) pargs[i] = &args[i]; + + memset( args, 0x55, sizeof(args) ); ++ ++ types[0] = VT_VARIANT; ++ V_VT(&args[0]) = VT_I4; ++ V_I4(&args[0]) = 2; ++ types[1] = VT_VARIANT; ++ V_VT(&args[1]) = VT_BSTR; ++ V_BSTR(&args[1]) = SysAllocString(testW); ++ memset( &result, 0xcc, sizeof(result) ); ++ res = DispCallFunc(NULL, (ULONG_PTR)variant_func2, CC_STDCALL, VT_VARIANT, 2, types, pargs, &result); ++ ok(res == S_OK, "DispCallFunc error %#x\n", res); ++ ok(V_VT(&result) == VT_UI4, "wrong result type %d\n", V_VT(&result)); ++ ok(V_UI4(&result) == 4321, "wrong result %u\n", V_UI4(&result)); ++ ++ V_VT(&result) = VT_I4; ++ V_UI4(&result) = 1234; ++ inst = vtable2; ++ res = DispCallFunc(&inst, 3 * sizeof(void *), CC_STDCALL, VT_VARIANT, 2, types, pargs, &result); ++ ok(res == S_OK, "DispCallFunc error %#x\n", res); ++ ok(V_VT(&result) == VT_UI4, "wrong result type %d\n", V_VT(&result)); ++ ok(V_UI4(&result) == 4321, "wrong result %u\n", V_UI4(&result)); ++ ++ VariantClear(&args[1]); ++ ++ memset( args, 0x55, sizeof(args) ); + types[0] = VT_UI4; + V_UI4(&args[0]) = 1; + types[1] = VT_I4; +@@ -1195,6 +1249,7 @@ static void test_DispCallFunc(void) + types[0] = VT_I4; + V_I4(&args[0]) = 3; + memset( &result, 0xcc, sizeof(result) ); ++ inst = vtable; + res = DispCallFunc( &inst, 3 * sizeof(void*), CC_STDCALL, VT_I4, 1, types, pargs, &result ); + ok( res == S_OK, "DispCallFunc failed %x\n", res ); + ok( V_VT(&result) == VT_I4, "wrong result type %d\n", V_VT(&result) ); +diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c +index ef2cb04ee3c..f2fd16be718 100644 +--- a/dlls/oleaut32/typelib.c ++++ b/dlls/oleaut32/typelib.c +@@ -6882,8 +6882,17 @@ DispCallFunc( + break; + case VT_DECIMAL: + case VT_VARIANT: +- args[0] = (DWORD)pvargResult; /* arg 0 is a pointer to the result */ +- call_method( func, argspos, args, &stack_offset ); ++ if (pvInstance) ++ { ++ args[0] = (DWORD)pvInstance; /* arg 0 is a pointer to the instance */ ++ args[1] = (DWORD)pvargResult; /* arg 1 is a pointer to the result */ ++ call_method( func, argspos, args, &stack_offset ); ++ } ++ else ++ { ++ args[0] = (DWORD)pvargResult; /* arg 0 is a pointer to the result */ ++ call_method( func, argspos, args, &stack_offset ); ++ } + break; + case VT_I8: + case VT_UI8: +@@ -6968,8 +6977,17 @@ DispCallFunc( + break; + case VT_DECIMAL: + case VT_VARIANT: +- args[0] = (DWORD_PTR)pvargResult; /* arg 0 is a pointer to the result */ +- call_method( func, argspos, args ); ++ if (pvInstance) ++ { ++ args[0] = (DWORD_PTR)pvInstance; /* arg 0 is a pointer to the instance */ ++ args[1] = (DWORD_PTR)pvargResult; /* arg 1 is a pointer to the result */ ++ call_method( func, argspos, args ); ++ } ++ else ++ { ++ args[0] = (DWORD_PTR)pvargResult; /* arg 0 is a pointer to the result */ ++ call_method( func, argspos, args ); ++ } + break; + case VT_HRESULT: + WARN("invalid return type %u\n", vtReturn); +-- +2.11.0 + diff --git a/patches/oleaut32-DispCallFunc/definition b/patches/oleaut32-DispCallFunc/definition new file mode 100644 index 00000000..234c52dd --- /dev/null +++ b/patches/oleaut32-DispCallFunc/definition @@ -0,0 +1 @@ +Fixes: [40160] Fix calling function with instance and VARIANT return type in DispCallFunc diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 764f4729..931e5bc1 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -273,6 +273,7 @@ patch_enable_all () enable_ole32_HGLOBALStream="$1" enable_ole32_OleGetIconOfFile="$1" enable_oleaut32_CreateTypeLib="$1" + enable_oleaut32_DispCallFunc="$1" enable_oleaut32_ITypeInfo_fnInvoke="$1" enable_oleaut32_LoadTypeLibEx="$1" enable_oleaut32_Load_Save_EMF="$1" @@ -1029,6 +1030,9 @@ patch_enable () oleaut32-CreateTypeLib) enable_oleaut32_CreateTypeLib="$2" ;; + oleaut32-DispCallFunc) + enable_oleaut32_DispCallFunc="$2" + ;; oleaut32-ITypeInfo_fnInvoke) enable_oleaut32_ITypeInfo_fnInvoke="$2" ;; @@ -6197,6 +6201,21 @@ if test "$enable_oleaut32_CreateTypeLib" -eq 1; then ) >> "$patchlist" fi +# Patchset oleaut32-DispCallFunc +# | +# | This patchset fixes the following Wine bugs: +# | * [#40160] Fix calling function with instance and VARIANT return type in DispCallFunc +# | +# | Modified files: +# | * dlls/oleaut32/tests/typelib.c, dlls/oleaut32/typelib.c +# | +if test "$enable_oleaut32_DispCallFunc" -eq 1; then + patch_apply oleaut32-DispCallFunc/0001-oleaut32-Fix-calling-function-with-instance-and-VARI.patch + ( + echo '+ { "Dmitry Timoshkov", "oleaut32: Fix calling function with instance and VARIANT return type.", 2 },'; + ) >> "$patchlist" +fi + # Patchset oleaut32-ITypeInfo_fnInvoke # | # | This patchset fixes the following Wine bugs: