Commit 30f9da4b authored by Marcus Meissner's avatar Marcus Meissner Committed by Alexandre Julliard

ITypelib::Invoke: Handle different length arguments better, we also

return 1 VARIANT only.
parent a0587c4a
...@@ -360,7 +360,7 @@ static ICOM_VTABLE(IRpcProxyBuffer) tmproxyvtable = { ...@@ -360,7 +360,7 @@ static ICOM_VTABLE(IRpcProxyBuffer) tmproxyvtable = {
}; };
/* how much space do we use on stack in DWORD steps. */ /* how much space do we use on stack in DWORD steps. */
static int const int const
_argsize(DWORD vt) { _argsize(DWORD vt) {
switch (vt) { switch (vt) {
case VT_DATE: case VT_DATE:
......
...@@ -4087,6 +4087,8 @@ _invoke(LPVOID func,CALLCONV callconv, int nrargs, DWORD *args) { ...@@ -4087,6 +4087,8 @@ _invoke(LPVOID func,CALLCONV callconv, int nrargs, DWORD *args) {
return res; return res;
} }
extern int const _argsize(DWORD vt);
static HRESULT WINAPI ITypeInfo_fnInvoke( static HRESULT WINAPI ITypeInfo_fnInvoke(
ITypeInfo2 *iface, ITypeInfo2 *iface,
VOID *pIUnk, VOID *pIUnk,
...@@ -4114,35 +4116,62 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( ...@@ -4114,35 +4116,62 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
} }
if (pFDesc) { if (pFDesc) {
dump_TLBFuncDescOne(pFDesc); dump_TLBFuncDescOne(pFDesc);
/* dump_FUNCDESC(&pFDesc->funcdesc);*/
switch (pFDesc->funcdesc.funckind) { switch (pFDesc->funcdesc.funckind) {
case FUNC_PUREVIRTUAL: case FUNC_PUREVIRTUAL:
case FUNC_VIRTUAL: { case FUNC_VIRTUAL: {
DWORD res; DWORD res;
DWORD *args = (DWORD*)HeapAlloc(GetProcessHeap(),0,sizeof(DWORD)*(pFDesc->funcdesc.cParams+1)); int numargs, numargs2, argspos, args2pos;
DWORD *args2 = (DWORD*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD)*(pFDesc->funcdesc.cParams)); DWORD *args , *args2;
args[0] = (DWORD)pIUnk;
numargs = 1; numargs2 = 0;
for (i=0;i<pFDesc->funcdesc.cParams;i++) {
if (i<pDispParams->cArgs)
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;i<pFDesc->funcdesc.cParams;i++) { for (i=0;i<pFDesc->funcdesc.cParams;i++) {
int arglen = _argsize(pFDesc->funcdesc.lprgelemdescParam[i].tdesc.vt);
if (i<pDispParams->cArgs) { if (i<pDispParams->cArgs) {
TRACE("set %d to disparg type %d vs %d\n",i, VARIANT *arg = &pDispParams->rgvarg[pDispParams->cArgs-i-1];
V_VT(&pDispParams->rgvarg[pDispParams->cArgs-i-1]), TYPEDESC *tdesc = &pFDesc->funcdesc.lprgelemdescParam[i].tdesc;
pFDesc->funcdesc.lprgelemdescParam[i].tdesc.vt
); if (V_VT(arg) == tdesc->vt) {
args[i+1] = V_UNION(&pDispParams->rgvarg[pDispParams->cArgs-i-1],lVal); 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 { } else {
TYPEDESC *tdesc = &(pFDesc->funcdesc.lprgelemdescParam[i].tdesc); 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*/ /*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 /* If pointer to variant, pass reference it. */
* in result variant array.
*/
if ((tdesc->vt == VT_PTR) && if ((tdesc->vt == VT_PTR) &&
(tdesc->u.lptdesc->vt == VT_VARIANT) && (tdesc->u.lptdesc->vt == VT_VARIANT) &&
pVarResult pVarResult
) )
args[i+1] = (DWORD)(pVarResult+(i-pDispParams->cArgs)); args[argspos]= (DWORD)pVarResult;
argspos += 1;
args2pos += arglen;
} }
} }
if (pFDesc->funcdesc.cParamsOpt) if (pFDesc->funcdesc.cParamsOpt)
...@@ -4152,22 +4181,24 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( ...@@ -4152,22 +4181,24 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
res = _invoke((*(DWORD***)pIUnk)[pFDesc->funcdesc.oVft/4], res = _invoke((*(DWORD***)pIUnk)[pFDesc->funcdesc.oVft/4],
pFDesc->funcdesc.callconv, pFDesc->funcdesc.callconv,
pFDesc->funcdesc.cParams+1, numargs,
args args
); );
if (pVarResult && (dwFlags & (DISPATCH_PROPERTYGET))) { if (pVarResult && (dwFlags & (DISPATCH_PROPERTYGET))) {
args2pos = 0;
for (i=0;i<pFDesc->funcdesc.cParams-pDispParams->cArgs;i++) { for (i=0;i<pFDesc->funcdesc.cParams-pDispParams->cArgs;i++) {
int arglen = _argsize(pFDesc->funcdesc.lprgelemdescParam[i].tdesc.vt);
TYPEDESC *tdesc = &(pFDesc->funcdesc.lprgelemdescParam[i+pDispParams->cArgs].tdesc); TYPEDESC *tdesc = &(pFDesc->funcdesc.lprgelemdescParam[i+pDispParams->cArgs].tdesc);
/* If we are a pointer to a variant, we are done already */ /* If we are a pointer to a variant, we are done already */
if ((tdesc->vt==VT_PTR)&&(tdesc->u.lptdesc->vt==VT_VARIANT)) if ((tdesc->vt==VT_PTR)&&(tdesc->u.lptdesc->vt==VT_VARIANT))
continue; continue;
VariantInit(&pVarResult[i]); VariantInit(pVarResult);
V_UNION(pVarResult+i,intVal) = args2[i+pDispParams->cArgs]; memcpy(&V_UNION(pVarResult,intVal),&args2[args2pos],arglen*sizeof(DWORD));
if (tdesc->vt == VT_PTR) if (tdesc->vt == VT_PTR)
tdesc = tdesc->u.lptdesc; tdesc = tdesc->u.lptdesc;
V_VT(pVarResult+i) = tdesc->vt; V_VT(pVarResult) = tdesc->vt;
/* HACK: VB5 likes this. /* HACK: VB5 likes this.
* I do not know why. There is 1 example in MSDN which uses * I do not know why. There is 1 example in MSDN which uses
...@@ -4175,9 +4206,10 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( ...@@ -4175,9 +4206,10 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
* IDispatch*.). * IDispatch*.).
*/ */
if ((tdesc->vt == VT_PTR) && (dwFlags & DISPATCH_METHOD)) if ((tdesc->vt == VT_PTR) && (dwFlags & DISPATCH_METHOD))
V_VT(pVarResult+i) = VT_DISPATCH; V_VT(pVarResult) = VT_DISPATCH;
TRACE("storing into variant: [%d]\n", i); TRACE("storing into variant:\n");
dump_Variant(pVarResult+i); dump_Variant(pVarResult);
args2pos += arglen;
} }
} }
HeapFree(GetProcessHeap(),0,args2); HeapFree(GetProcessHeap(),0,args2);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment