From 30f9da4b58b74573b511734bc74e2b78e0e20947 Mon Sep 17 00:00:00 2001 From: Marcus Meissner Date: Thu, 20 Jun 2002 22:45:08 +0000 Subject: [PATCH] ITypelib::Invoke: Handle different length arguments better, we also return 1 VARIANT only. --- dlls/oleaut32/tmarshal.c | 2 +- dlls/oleaut32/typelib.c | 74 ++++++++++++++++++++++++++++++++++-------------- 2 files changed, 54 insertions(+), 22 deletions(-) diff --git a/dlls/oleaut32/tmarshal.c b/dlls/oleaut32/tmarshal.c index 5d32e800528..a8c3e641a90 100644 --- a/dlls/oleaut32/tmarshal.c +++ b/dlls/oleaut32/tmarshal.c @@ -360,7 +360,7 @@ static ICOM_VTABLE(IRpcProxyBuffer) tmproxyvtable = { }; /* how much space do we use on stack in DWORD steps. */ -static int const +int const _argsize(DWORD vt) { switch (vt) { case VT_DATE: diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c index 9f3968cbc12..bf643652d08 100644 --- a/dlls/oleaut32/typelib.c +++ b/dlls/oleaut32/typelib.c @@ -4087,6 +4087,8 @@ _invoke(LPVOID func,CALLCONV callconv, int nrargs, DWORD *args) { return res; } +extern int const _argsize(DWORD vt); + static HRESULT WINAPI ITypeInfo_fnInvoke( ITypeInfo2 *iface, VOID *pIUnk, @@ -4114,35 +4116,62 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( } if (pFDesc) { dump_TLBFuncDescOne(pFDesc); + /* dump_FUNCDESC(&pFDesc->funcdesc);*/ switch (pFDesc->funcdesc.funckind) { case FUNC_PUREVIRTUAL: case FUNC_VIRTUAL: { DWORD res; - DWORD *args = (DWORD*)HeapAlloc(GetProcessHeap(),0,sizeof(DWORD)*(pFDesc->funcdesc.cParams+1)); - DWORD *args2 = (DWORD*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD)*(pFDesc->funcdesc.cParams)); - args[0] = (DWORD)pIUnk; + int numargs, numargs2, argspos, args2pos; + DWORD *args , *args2; + + + numargs = 1; numargs2 = 0; + for (i=0;ifuncdesc.cParams;i++) { + if (icArgs) + numargs += _argsize(pFDesc->funcdesc.lprgelemdescParam[i].tdesc.vt); + else { + numargs += 1; /* sizeof(lpvoid) */ + numargs2 += _argsize(pFDesc->funcdesc.lprgelemdescParam[i].tdesc.vt); + } + } + + args = (DWORD*)HeapAlloc(GetProcessHeap(),0,sizeof(DWORD)*numargs); + args2 = (DWORD*)HeapAlloc(GetProcessHeap(),0,sizeof(DWORD)*numargs2); + args[0] = (DWORD)pIUnk; + argspos = 1; args2pos = 0; for (i=0;ifuncdesc.cParams;i++) { + int arglen = _argsize(pFDesc->funcdesc.lprgelemdescParam[i].tdesc.vt); if (icArgs) { - TRACE("set %d to disparg type %d vs %d\n",i, - V_VT(&pDispParams->rgvarg[pDispParams->cArgs-i-1]), - pFDesc->funcdesc.lprgelemdescParam[i].tdesc.vt - ); - args[i+1] = V_UNION(&pDispParams->rgvarg[pDispParams->cArgs-i-1],lVal); + VARIANT *arg = &pDispParams->rgvarg[pDispParams->cArgs-i-1]; + TYPEDESC *tdesc = &pFDesc->funcdesc.lprgelemdescParam[i].tdesc; + + if (V_VT(arg) == tdesc->vt) { + memcpy(&args[argspos],&V_UNION(arg,lVal), arglen*sizeof(DWORD)); + } else { + if (tdesc->vt == VT_VARIANT) { + memcpy(&args[argspos],arg, arglen*sizeof(DWORD)); + } else { + ERR("Set arg %d to disparg type %d vs %d\n",i, + V_VT(arg),tdesc->vt + ); + } + } + argspos += arglen; } else { TYPEDESC *tdesc = &(pFDesc->funcdesc.lprgelemdescParam[i].tdesc); - TRACE("set %d to pointer for get (type is %d)\n",i,tdesc->vt); + FIXME("set %d to pointer for get (type is %d)\n",i,tdesc->vt); /*FIXME: give pointers for the rest, so propertyget works*/ - args[i+1] = (DWORD)&args2[i]; + args[argspos] = (DWORD)&args2[args2pos]; - /* If pointer to variant, pass reference to variant - * in result variant array. - */ + /* If pointer to variant, pass reference it. */ if ((tdesc->vt == VT_PTR) && (tdesc->u.lptdesc->vt == VT_VARIANT) && pVarResult ) - args[i+1] = (DWORD)(pVarResult+(i-pDispParams->cArgs)); + args[argspos]= (DWORD)pVarResult; + argspos += 1; + args2pos += arglen; } } if (pFDesc->funcdesc.cParamsOpt) @@ -4152,22 +4181,24 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( res = _invoke((*(DWORD***)pIUnk)[pFDesc->funcdesc.oVft/4], pFDesc->funcdesc.callconv, - pFDesc->funcdesc.cParams+1, + numargs, args ); if (pVarResult && (dwFlags & (DISPATCH_PROPERTYGET))) { + args2pos = 0; for (i=0;ifuncdesc.cParams-pDispParams->cArgs;i++) { + int arglen = _argsize(pFDesc->funcdesc.lprgelemdescParam[i].tdesc.vt); TYPEDESC *tdesc = &(pFDesc->funcdesc.lprgelemdescParam[i+pDispParams->cArgs].tdesc); /* If we are a pointer to a variant, we are done already */ if ((tdesc->vt==VT_PTR)&&(tdesc->u.lptdesc->vt==VT_VARIANT)) continue; - VariantInit(&pVarResult[i]); - V_UNION(pVarResult+i,intVal) = args2[i+pDispParams->cArgs]; + VariantInit(pVarResult); + memcpy(&V_UNION(pVarResult,intVal),&args2[args2pos],arglen*sizeof(DWORD)); if (tdesc->vt == VT_PTR) tdesc = tdesc->u.lptdesc; - V_VT(pVarResult+i) = tdesc->vt; + V_VT(pVarResult) = tdesc->vt; /* HACK: VB5 likes this. * I do not know why. There is 1 example in MSDN which uses @@ -4175,9 +4206,10 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( * IDispatch*.). */ if ((tdesc->vt == VT_PTR) && (dwFlags & DISPATCH_METHOD)) - V_VT(pVarResult+i) = VT_DISPATCH; - TRACE("storing into variant: [%d]\n", i); - dump_Variant(pVarResult+i); + V_VT(pVarResult) = VT_DISPATCH; + TRACE("storing into variant:\n"); + dump_Variant(pVarResult); + args2pos += arglen; } } HeapFree(GetProcessHeap(),0,args2); -- 2.11.4.GIT