Misha Koshelev : oleaut32: Add support for vararg functions in
ITypeInfo:: Invoke.
Alexandre Julliard
julliard at wine.codeweavers.com
Thu Jun 7 07:20:23 CDT 2007
Module: wine
Branch: master
Commit: 428ed94fa9f75c2036953352b50c217aa925479a
URL: http://source.winehq.org/git/wine.git/?a=commit;h=428ed94fa9f75c2036953352b50c217aa925479a
Author: Misha Koshelev <mk144210 at bcm.edu>
Date: Wed Jun 6 15:50:32 2007 -0500
oleaut32: Add support for vararg functions in ITypeInfo::Invoke.
---
dlls/oleaut32/tests/tmarshal.c | 4 +-
dlls/oleaut32/typelib.c | 71 ++++++++++++++++++++++++++++++++++++---
2 files changed, 67 insertions(+), 8 deletions(-)
diff --git a/dlls/oleaut32/tests/tmarshal.c b/dlls/oleaut32/tests/tmarshal.c
index 05624e9..cc2632f 100644
--- a/dlls/oleaut32/tests/tmarshal.c
+++ b/dlls/oleaut32/tests/tmarshal.c
@@ -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 */
diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c
index 6bf9dfd..1558593 100644
--- a/dlls/oleaut32/typelib.c
+++ b/dlls/oleaut32/typelib.c
@@ -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)
More information about the wine-cvs
mailing list