Module: wine Branch: master Commit: fbba581cf2aeeda169f6cc229c1a80da3eb40532 URL: https://gitlab.winehq.org/wine/wine/-/commit/fbba581cf2aeeda169f6cc229c1a80d...
Author: Alexandre Julliard julliard@winehq.org Date: Sun Apr 28 22:06:29 2024 +0200
oleaut32: Fix IDispatch::Invoke for vararg functions with empty varargs.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56598
---
dlls/oleaut32/tests/tmarshal.c | 40 ++++++++++++++++++++++++++++++++++++++++ dlls/oleaut32/typelib.c | 11 +++++++++++ 2 files changed, 51 insertions(+)
diff --git a/dlls/oleaut32/tests/tmarshal.c b/dlls/oleaut32/tests/tmarshal.c index 5ffc103c7eb..4bcc15628f7 100644 --- a/dlls/oleaut32/tests/tmarshal.c +++ b/dlls/oleaut32/tests/tmarshal.c @@ -932,6 +932,10 @@ static HRESULT WINAPI Widget_VarArg(
trace("VarArg(%p)\n", values);
+ ok( values->cDims == 1, "wrong cDims %u\n", values->cDims ); + ok( values->cbElements == (numexpect ? sizeof(VARIANT) : 0), + "wrong cbElements %lu\n", values->cbElements ); + hr = SafeArrayGetLBound(values, 1, &lbound); ok(hr == S_OK, "SafeArrayGetLBound failed with %lx\n", hr); ok(lbound == 0, "SafeArrayGetLBound returned %ld\n", lbound); @@ -1058,6 +1062,16 @@ static HRESULT WINAPI Widget_VarArg_Run(
ok(!lstrcmpW(name, catW), "got %s\n", wine_dbgstr_w(name));
+ if (!params->cbElements) /* no varargs */ + { + hr = SafeArrayGetUBound(params, 1, &bound); + ok(hr == S_OK, "SafeArrayGetUBound error %#lx\n", hr); + ok(bound == -1, "expected -1, got %ld\n", bound); + return S_OK; + } + + ok( params->cbElements == sizeof(VARIANT), "wrong cbElements %lu\n", params->cbElements ); + hr = SafeArrayGetLBound(params, 1, &bound); ok(hr == S_OK, "SafeArrayGetLBound error %#lx\n", hr); ok(bound == 0, "expected 0, got %ld\n", bound); @@ -1093,6 +1107,16 @@ static HRESULT WINAPI Widget_VarArg_Ref_Run(
ok(!lstrcmpW(name, catW), "got %s\n", wine_dbgstr_w(name));
+ if (!(*params)->cbElements) /* no varargs */ + { + hr = SafeArrayGetUBound(*params, 1, &bound); + ok(hr == S_OK, "SafeArrayGetUBound error %#lx\n", hr); + ok(bound == -1, "expected -1, got %ld\n", bound); + return S_OK; + } + + ok( (*params)->cbElements == sizeof(VARIANT), "wrong cbElements %lu\n", (*params)->cbElements ); + hr = SafeArrayGetLBound(*params, 1, &bound); ok(hr == S_OK, "SafeArrayGetLBound error %#lx\n", hr); ok(bound == 0, "expected 0, got %ld\n", bound); @@ -3231,6 +3255,12 @@ static void test_typelibmarshal(void) hr = IDispatch_Invoke(pDispatch, DISPID_TM_VARARG, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL); ok_ole_success(hr, IDispatch_Invoke);
+ /* without any varargs */ + dispparams.cArgs = 1; + V_I4(&vararg[0]) = 0; + hr = IDispatch_Invoke(pDispatch, DISPID_TM_VARARG, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL); + ok_ole_success(hr, IDispatch_Invoke); + /* call VarArg, even one (non-optional, non-safearray) named argument is not allowed */ dispidNamed = 0; dispparams.cNamedArgs = 1; @@ -3252,6 +3282,11 @@ static void test_typelibmarshal(void) dispparams.rgvarg = vararg; hr = IDispatch_Invoke(pDispatch, DISPID_TM_VARARG_RUN, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL); ok_ole_success(hr, IDispatch_Invoke); + /* without any varargs */ + dispparams.cArgs = 1; + dispparams.rgvarg = vararg + 1; + hr = IDispatch_Invoke(pDispatch, DISPID_TM_VARARG_RUN, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL); + ok_ole_success(hr, IDispatch_Invoke); SysFreeString(V_BSTR(&vararg[1])); SysFreeString(V_BSTR(&vararg[0]));
@@ -3268,6 +3303,11 @@ static void test_typelibmarshal(void) dispparams.rgvarg = vararg; hr = IDispatch_Invoke(pDispatch, DISPID_TM_VARARG_REF_RUN, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL); ok_ole_success(hr, IDispatch_Invoke); + /* without any varargs */ + dispparams.cArgs = 1; + dispparams.rgvarg = vararg + 1; + hr = IDispatch_Invoke(pDispatch, DISPID_TM_VARARG_REF_RUN, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL); + ok_ole_success(hr, IDispatch_Invoke); SysFreeString(V_BSTR(&vararg[1])); SysFreeString(V_BSTR(&vararg[0]));
diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c index 670938fb81c..6b4842b7e1a 100644 --- a/dlls/oleaut32/typelib.c +++ b/dlls/oleaut32/typelib.c @@ -7483,6 +7483,17 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( } } } + else if (func_desc->cParamsOpt < 0 && ((rgvt[i] & ~VT_BYREF) == (VT_VARIANT | VT_ARRAY))) + { + hres = SafeArrayAllocDescriptorEx( VT_EMPTY, 1, &a ); + if (FAILED(hres)) break; + if (rgvt[i] & VT_BYREF) + V_BYREF(&rgvarg[i]) = &a; + else + V_ARRAY(&rgvarg[i]) = a; + V_VT(&rgvarg[i]) = rgvt[i]; + prgpvarg[i] = &rgvarg[i]; + } else { hres = DISP_E_BADPARAMCOUNT;