oleaut32: Add support for vararg functions in ITypeInfo::Invoke.
This commit is contained in:
parent
127385e718
commit
428ed94fa9
|
@ -1007,14 +1007,14 @@ static void test_typelibmarshal(void)
|
|||
dispparams.rgdispidNamedArgs = NULL;
|
||||
dispparams.rgvarg = vararg;
|
||||
hr = IDispatch_Invoke(pDispatch, DISPID_TM_VARARG, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
|
||||
todo_wine ok_ole_success(hr, ITypeInfo_Invoke);
|
||||
ok_ole_success(hr, ITypeInfo_Invoke);
|
||||
|
||||
/* call VarArg, even one (non-optional, non-safearray) named argument is not allowed */
|
||||
dispidNamed = 0;
|
||||
dispparams.cNamedArgs = 1;
|
||||
dispparams.rgdispidNamedArgs = &dispidNamed;
|
||||
hr = IDispatch_Invoke(pDispatch, DISPID_TM_VARARG, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
|
||||
todo_wine ok(hr == DISP_E_NONAMEDARGS, "IDispatch_Invoke should have returned DISP_E_NONAMEDARGS instead of 0x%08x\n", hr);
|
||||
ok(hr == DISP_E_NONAMEDARGS, "IDispatch_Invoke should have returned DISP_E_NONAMEDARGS instead of 0x%08x\n", hr);
|
||||
dispidNamed = DISPID_PROPERTYPUT;
|
||||
|
||||
/* call Error */
|
||||
|
|
|
@ -5594,6 +5594,13 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
|
|||
rgdispidNamedArgs++;
|
||||
}
|
||||
|
||||
if (func_desc->cParamsOpt < 0 && cNamedArgs)
|
||||
{
|
||||
ERR("functions with the vararg attribute do not support named arguments\n");
|
||||
hres = DISP_E_NONAMEDARGS;
|
||||
goto func_fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < func_desc->cParams; i++)
|
||||
{
|
||||
TYPEDESC *tdesc = &func_desc->lprgelemdescParam[i].tdesc;
|
||||
|
@ -5674,6 +5681,36 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
|
|||
}
|
||||
V_VT(&rgvarg[i]) = rgvt[i];
|
||||
}
|
||||
else if (rgvt[i] == (VT_VARIANT | VT_ARRAY) && func_desc->cParamsOpt < 0 && i == func_desc->cParams-1)
|
||||
{
|
||||
SAFEARRAY *a;
|
||||
SAFEARRAYBOUND bound;
|
||||
VARIANT *v;
|
||||
LONG j;
|
||||
bound.lLbound = 0;
|
||||
bound.cElements = pDispParams->cArgs-i;
|
||||
if (!(a = SafeArrayCreate(VT_VARIANT, 1, &bound)))
|
||||
{
|
||||
ERR("SafeArrayCreate failed\n");
|
||||
break;
|
||||
}
|
||||
hres = SafeArrayAccessData(a, (LPVOID)&v);
|
||||
if (hres != S_OK)
|
||||
{
|
||||
ERR("SafeArrayAccessData failed with %x\n", hres);
|
||||
break;
|
||||
}
|
||||
for (j = 0; j < bound.cElements; j++)
|
||||
VariantCopy(&v[j], &pDispParams->rgvarg[pDispParams->cArgs - 1 - i - j]);
|
||||
hres = SafeArrayUnaccessData(a);
|
||||
if (hres != S_OK)
|
||||
{
|
||||
ERR("SafeArrayUnaccessData failed with %x\n", hres);
|
||||
break;
|
||||
}
|
||||
V_ARRAY(&rgvarg[i]) = a;
|
||||
V_VT(&rgvarg[i]) = rgvt[i];
|
||||
}
|
||||
else if ((rgvt[i] & VT_BYREF) && !V_ISBYREF(src_arg))
|
||||
{
|
||||
VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams);
|
||||
|
@ -5740,12 +5777,6 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
|
|||
}
|
||||
}
|
||||
if (FAILED(hres)) goto func_fail; /* FIXME: we don't free changed types here */
|
||||
if (func_desc->cParamsOpt < 0)
|
||||
{
|
||||
FIXME("Does not support safearray optional parameters\n");
|
||||
hres = DISP_E_BADPARAMCOUNT;
|
||||
goto func_fail; /* FIXME: we don't free changed types here */
|
||||
}
|
||||
|
||||
/* VT_VOID is a special case for return types, so it is not
|
||||
* handled in the general function */
|
||||
|
@ -5809,6 +5840,34 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
|
|||
break;
|
||||
}
|
||||
}
|
||||
else if (V_VT(prgpvarg[i]) == (VT_VARIANT | VT_ARRAY) &&
|
||||
func_desc->cParamsOpt < 0 &&
|
||||
i == func_desc->cParams-1)
|
||||
{
|
||||
SAFEARRAY *a = V_ARRAY(prgpvarg[i]);
|
||||
LONG j, ubound;
|
||||
VARIANT *v;
|
||||
hres = SafeArrayGetUBound(a, 1, &ubound);
|
||||
if (hres != S_OK)
|
||||
{
|
||||
ERR("SafeArrayGetUBound failed with %x\n", hres);
|
||||
break;
|
||||
}
|
||||
hres = SafeArrayAccessData(a, (LPVOID)&v);
|
||||
if (hres != S_OK)
|
||||
{
|
||||
ERR("SafeArrayAccessData failed with %x\n", hres);
|
||||
break;
|
||||
}
|
||||
for (j = 0; j <= ubound; j++)
|
||||
VariantClear(&v[j]);
|
||||
hres = SafeArrayUnaccessData(a);
|
||||
if (hres != S_OK)
|
||||
{
|
||||
ERR("SafeArrayUnaccessData failed with %x\n", hres);
|
||||
break;
|
||||
}
|
||||
}
|
||||
VariantClear(&rgvarg[i]);
|
||||
}
|
||||
else if (wParamFlags & PARAMFLAG_FOPT)
|
||||
|
|
Loading…
Reference in New Issue