oleaut32: Add support for vararg functions in ITypeInfo::Invoke.

This commit is contained in:
Misha Koshelev 2007-06-06 15:50:32 -05:00 committed by Alexandre Julliard
parent 127385e718
commit 428ed94fa9
2 changed files with 67 additions and 8 deletions

View File

@ -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 */

View File

@ -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)