Module: wine Branch: master Commit: 03a590017e901b9473cc40afbc851eca218c96c4 URL: https://source.winehq.org/git/wine.git/?a=commit;h=03a590017e901b9473cc40afb...
Author: Alexandre Julliard julliard@winehq.org Date: Tue Oct 29 14:10:45 2019 +0100
oleaut32: Fix handling of VARIANT parameters in DispCallFunc() on ARM64.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/oleaut32/tests/typelib.c | 27 ++++++++++++++++++++++++--- dlls/oleaut32/typelib.c | 33 +++++++++++---------------------- 2 files changed, 35 insertions(+), 25 deletions(-)
diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c index a706481042..47faad7763 100644 --- a/dlls/oleaut32/tests/typelib.c +++ b/dlls/oleaut32/tests/typelib.c @@ -1201,17 +1201,37 @@ static HRESULT WINAPI ret_false_func(void)
static const WCHAR testW[] = { 'T','e','s','t',0 };
-static void WINAPI variant_func2(VARIANT *ret, VARIANT v1, VARIANT v2) +static VARIANT WINAPI variant_func2(VARIANT v1, VARIANT v2) { + VARIANT 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; + V_VT(&ret) = VT_UI4; + V_I4(&ret) = 4321; + return ret; }
+#ifdef __aarch64__ +static VARIANT WINAPI inst_func2(void *inst, VARIANT v1, VARIANT v2) +{ + VARIANT ret; + + ok( (*(void ***)inst)[3] == inst_func2, "wrong ptr %p\n", inst ); + + 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; + return ret; +} +#else static void WINAPI inst_func2(void *inst, VARIANT *ret, VARIANT v1, VARIANT v2) { ok( (*(void ***)inst)[3] == inst_func2, "wrong ptr %p\n", inst ); @@ -1227,6 +1247,7 @@ static void WINAPI inst_func2(void *inst, VARIANT *ret, VARIANT v1, VARIANT v2) V_VT(ret) = VT_UI4; V_I4(ret) = 4321; } +#endif
static void *vtable[] = { NULL, NULL, NULL, inst_func }; static void *vtable2[] = { NULL, NULL, NULL, inst_func2 }; diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c index 7ad92837da..d652edc7ee 100644 --- a/dlls/oleaut32/typelib.c +++ b/dlls/oleaut32/typelib.c @@ -6882,23 +6882,8 @@ HRESULT WINAPI DispCallFunc( void *instance, ULONG_PTR offset, CALLCONV cc, VART } else func = (void *)offset;
- /* Determine if we need to pass a pointer for the return value as arg 0. If so, do that */ - /* first as it will need to be in the 'x' registers: */ - switch (ret_type) - { - case VT_DECIMAL: - case VT_VARIANT: - regs.x[8] = (DWORD_PTR)result; /* x8 is a pointer to the result */ - break; - case VT_HRESULT: - WARN("invalid return type %u\n", ret_type); - return E_INVALIDARG; - default: - break; - } - - /* maximum size for an argument is sizeof(VARIANT). Also allow for return pointer and stack alignment. */ - args = heap_alloc( sizeof(VARIANT) * count + sizeof(DWORD_PTR) * 4 ); + /* maximum size for an argument is 16 */ + args = heap_alloc( 16 * count );
for (i = 0; i < count; i++) { @@ -6906,8 +6891,6 @@ HRESULT WINAPI DispCallFunc( void *instance, ULONG_PTR offset, CALLCONV cc, VART
switch (types[i]) { - case VT_EMPTY: - break; case VT_R4: if (fpcount < 8) regs.fp[fpcount++].f = V_R4(arg); else *(float *)&args[argspos++] = V_R4(arg); @@ -6918,7 +6901,6 @@ HRESULT WINAPI DispCallFunc( void *instance, ULONG_PTR offset, CALLCONV cc, VART else *(double *)&args[argspos++] = V_R8(arg); break; case VT_DECIMAL: - case VT_VARIANT: if (rcount < 7) { memcpy( ®s.x[rcount], arg, sizeof(*arg) ); @@ -6930,6 +6912,10 @@ HRESULT WINAPI DispCallFunc( void *instance, ULONG_PTR offset, CALLCONV cc, VART argspos += 2; } break; + case VT_VARIANT: + if (rcount < 8) regs.x[rcount++] = (DWORD_PTR)arg; + else args[argspos++] = (DWORD_PTR)arg; + break; case VT_BOOL: /* VT_BOOL is 16-bit but BOOL is 32-bit, needs to be extended */ if (rcount < 8) regs.x[rcount++] = V_BOOL(arg); else args[argspos++] = V_BOOL(arg); @@ -6946,9 +6932,12 @@ HRESULT WINAPI DispCallFunc( void *instance, ULONG_PTR offset, CALLCONV cc, VART
switch (ret_type) { - case VT_EMPTY: /* EMPTY = no return value */ - case VT_DECIMAL: /* DECIMAL and VARIANT already have a pointer argument passed (see above) */ + case VT_HRESULT: + heap_free( args ); + return E_INVALIDARG; + case VT_DECIMAL: case VT_VARIANT: + regs.x[8] = (DWORD_PTR)result; /* x8 is a pointer to the result */ call_method( func, argspos, args, (DWORD_PTR *)®s ); break; case VT_R4: