Remove Invoke's dependence on the internal TLBFuncDesc structure.
Fix memory leaks in some failure cases.
This commit is contained in:
parent
38964fd852
commit
23ded07e63
|
@ -4689,9 +4689,9 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
|
|||
UINT *pArgErr)
|
||||
{
|
||||
ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
|
||||
TLBFuncDesc * pFDesc;
|
||||
TLBVarDesc * pVDesc;
|
||||
int i;
|
||||
unsigned int func_index;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p)(%p,id=%ld,flags=0x%08x,%p,%p,%p,%p) partial stub!\n",
|
||||
|
@ -4699,31 +4699,30 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
|
|||
);
|
||||
dump_DispParms(pDispParams);
|
||||
|
||||
for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
|
||||
if (pFDesc->funcdesc.memid == memid) {
|
||||
if (pFDesc->funcdesc.invkind & dwFlags)
|
||||
break;
|
||||
}
|
||||
|
||||
if (pFDesc) {
|
||||
if (TRACE_ON(typelib)) dump_TLBFuncDescOne(pFDesc);
|
||||
/* dump_FUNCDESC(&pFDesc->funcdesc);*/
|
||||
switch (pFDesc->funcdesc.funckind) {
|
||||
hres = ITypeInfo2_GetFuncIndexOfMemId(iface, memid, dwFlags, &func_index);
|
||||
if (SUCCEEDED(hres)) {
|
||||
FUNCDESC *func_desc;
|
||||
|
||||
hres = ITypeInfo2_GetFuncDesc(iface, func_index, &func_desc);
|
||||
if(FAILED(hres)) return hres;
|
||||
|
||||
switch (func_desc->funckind) {
|
||||
case FUNC_PUREVIRTUAL:
|
||||
case FUNC_VIRTUAL: {
|
||||
DWORD res;
|
||||
int numargs, numargs2, argspos, args2pos;
|
||||
DWORD *args , *args2;
|
||||
VARIANT *rgvarg = HeapAlloc(GetProcessHeap(),0,sizeof(VARIANT)*pFDesc->funcdesc.cParams);
|
||||
VARIANT *rgvarg = HeapAlloc(GetProcessHeap(), 0, sizeof(VARIANT) * func_desc->cParams);
|
||||
memcpy(rgvarg,pDispParams->rgvarg,sizeof(VARIANT)*pDispParams->cArgs);
|
||||
|
||||
hres = S_OK;
|
||||
numargs = 1; numargs2 = 0;
|
||||
for (i=0;i<pFDesc->funcdesc.cParams;i++) {
|
||||
for (i = 0; i < func_desc->cParams; i++) {
|
||||
if (i<pDispParams->cArgs)
|
||||
numargs += _argsize(pFDesc->funcdesc.lprgelemdescParam[i].tdesc.vt);
|
||||
numargs += _argsize(func_desc->lprgelemdescParam[i].tdesc.vt);
|
||||
else {
|
||||
numargs += 1; /* sizeof(lpvoid) */
|
||||
numargs2 += _argsize(pFDesc->funcdesc.lprgelemdescParam[i].tdesc.vt);
|
||||
numargs2 += _argsize(func_desc->lprgelemdescParam[i].tdesc.vt);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4732,14 +4731,14 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
|
|||
|
||||
args[0] = (DWORD)pIUnk;
|
||||
argspos = 1; args2pos = 0;
|
||||
for (i=0;i<pFDesc->funcdesc.cParams;i++) {
|
||||
int arglen = _argsize(pFDesc->funcdesc.lprgelemdescParam[i].tdesc.vt);
|
||||
for (i = 0; i < func_desc->cParams; i++) {
|
||||
int arglen = _argsize(func_desc->lprgelemdescParam[i].tdesc.vt);
|
||||
if (i<pDispParams->cArgs) {
|
||||
VARIANT *arg = &rgvarg[pDispParams->cArgs-i-1];
|
||||
TYPEDESC *tdesc = &pFDesc->funcdesc.lprgelemdescParam[i].tdesc;
|
||||
USHORT paramFlags = pFDesc->funcdesc.lprgelemdescParam[i].u.paramdesc.wParamFlags;
|
||||
TYPEDESC *tdesc = &func_desc->lprgelemdescParam[i].tdesc;
|
||||
USHORT paramFlags = func_desc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
|
||||
if (paramFlags & PARAMFLAG_FOPT) {
|
||||
if(i < pFDesc->funcdesc.cParams-pFDesc->funcdesc.cParamsOpt)
|
||||
if(i < func_desc->cParams - func_desc->cParamsOpt)
|
||||
ERR("Parameter has PARAMFLAG_FOPT flag but is not one of last cParamOpt parameters\n");
|
||||
if(V_VT(arg) == VT_EMPTY
|
||||
|| ((V_VT(arg) & VT_BYREF) && !V_BYREF(arg))) {
|
||||
|
@ -4754,23 +4753,23 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
|
|||
}
|
||||
}
|
||||
hres = _copy_arg(iface, tdesc, &args[argspos], arg, tdesc->vt);
|
||||
if (FAILED(hres)) return hres;
|
||||
if (FAILED(hres)) goto func_fail;
|
||||
argspos += arglen;
|
||||
} else if(pFDesc->funcdesc.lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FOPT) {
|
||||
} else if(func_desc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FOPT) {
|
||||
VARIANT *arg = &rgvarg[i];
|
||||
TYPEDESC *tdesc = &pFDesc->funcdesc.lprgelemdescParam[i].tdesc;
|
||||
if(i < pFDesc->funcdesc.cParams-pFDesc->funcdesc.cParamsOpt)
|
||||
TYPEDESC *tdesc = &func_desc->lprgelemdescParam[i].tdesc;
|
||||
if(i < func_desc->cParams - func_desc->cParamsOpt)
|
||||
ERR("Parameter has PARAMFLAG_FOPT flag but is not one of last cParamOpt parameters\n");
|
||||
if(pFDesc->funcdesc.lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
|
||||
if(func_desc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
|
||||
FIXME("PARAMFLAG_FHASDEFAULT flag not supported\n");
|
||||
V_VT(arg) = VT_ERROR;
|
||||
V_ERROR(arg) = DISP_E_PARAMNOTFOUND;
|
||||
arglen = _argsize(VT_ERROR);
|
||||
hres = _copy_arg(iface, tdesc, &args[argspos], arg, tdesc->vt);
|
||||
if (FAILED(hres)) return hres;
|
||||
if (FAILED(hres)) goto func_fail;
|
||||
argspos += arglen;
|
||||
} else {
|
||||
TYPEDESC *tdesc = &(pFDesc->funcdesc.lprgelemdescParam[i].tdesc);
|
||||
TYPEDESC *tdesc = &(func_desc->lprgelemdescParam[i].tdesc);
|
||||
if (tdesc->vt != VT_PTR)
|
||||
FIXME("set %d to pointer for get (type is %d)\n",i,tdesc->vt);
|
||||
/*FIXME: give pointers for the rest, so propertyget works*/
|
||||
|
@ -4780,32 +4779,28 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
|
|||
if ((tdesc->vt == VT_PTR) &&
|
||||
(tdesc->u.lptdesc->vt == VT_VARIANT) &&
|
||||
pVarResult
|
||||
)
|
||||
args[argspos]= (DWORD)pVarResult;
|
||||
)
|
||||
args[argspos]= (DWORD)pVarResult;
|
||||
argspos += 1;
|
||||
args2pos += arglen;
|
||||
}
|
||||
}
|
||||
if (pFDesc->funcdesc.cParamsOpt < 0)
|
||||
FIXME("Does not support optional parameters (%d)\n",
|
||||
pFDesc->funcdesc.cParamsOpt
|
||||
);
|
||||
if (func_desc->cParamsOpt < 0)
|
||||
FIXME("Does not support optional parameters (%d)\n", func_desc->cParamsOpt);
|
||||
|
||||
res = _invoke((*(FARPROC**)pIUnk)[pFDesc->funcdesc.oVft/4],
|
||||
pFDesc->funcdesc.callconv,
|
||||
res = _invoke((*(FARPROC**)pIUnk)[func_desc->oVft/4],
|
||||
func_desc->callconv,
|
||||
numargs,
|
||||
args
|
||||
);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, rgvarg);
|
||||
|
||||
if (pVarResult && (dwFlags & (DISPATCH_PROPERTYGET))) {
|
||||
args2pos = 0;
|
||||
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 i4_tdesc;
|
||||
i4_tdesc.vt = VT_I4;
|
||||
for (i = 0; i < func_desc->cParams - pDispParams->cArgs; i++) {
|
||||
int arglen = _argsize(func_desc->lprgelemdescParam[i].tdesc.vt);
|
||||
TYPEDESC *tdesc = &(func_desc->lprgelemdescParam[i + pDispParams->cArgs].tdesc);
|
||||
TYPEDESC i4_tdesc;
|
||||
i4_tdesc.vt = VT_I4;
|
||||
|
||||
/* If we are a pointer to a variant, we are done already */
|
||||
if ((tdesc->vt==VT_PTR)&&(tdesc->u.lptdesc->vt==VT_VARIANT))
|
||||
|
@ -4821,16 +4816,16 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
|
|||
TYPEATTR *tattr;
|
||||
|
||||
hres = ITypeInfo_GetRefTypeInfo(iface,tdesc->u.hreftype,&tinfo2);
|
||||
if (hres) {
|
||||
if (FAILED(hres)) {
|
||||
FIXME("Could not get typeinfo of hreftype %lx for VT_USERDEFINED, while coercing. Copying 4 byte.\n",tdesc->u.hreftype);
|
||||
return E_FAIL;
|
||||
goto func_fail;
|
||||
}
|
||||
ITypeInfo_GetTypeAttr(tinfo2,&tattr);
|
||||
switch (tattr->typekind) {
|
||||
case TKIND_ENUM:
|
||||
/* force the return type to be VT_I4 */
|
||||
tdesc = &i4_tdesc;
|
||||
break;
|
||||
/* force the return type to be VT_I4 */
|
||||
tdesc = &i4_tdesc;
|
||||
break;
|
||||
case TKIND_ALIAS:
|
||||
TRACE("TKIND_ALIAS to vt 0x%x\n",tattr->tdescAlias.vt);
|
||||
tdesc = &(tattr->tdescAlias);
|
||||
|
@ -4865,33 +4860,38 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
|
|||
args2pos += arglen;
|
||||
}
|
||||
}
|
||||
func_fail:
|
||||
HeapFree(GetProcessHeap(), 0, rgvarg);
|
||||
HeapFree(GetProcessHeap(),0,args2);
|
||||
HeapFree(GetProcessHeap(),0,args);
|
||||
return S_OK;
|
||||
break;
|
||||
}
|
||||
case FUNC_DISPATCH: {
|
||||
IDispatch *disp;
|
||||
HRESULT hr;
|
||||
|
||||
hr = IUnknown_QueryInterface((LPUNKNOWN)pIUnk,&IID_IDispatch,(LPVOID*)&disp);
|
||||
if (hr) {
|
||||
hres = IUnknown_QueryInterface((LPUNKNOWN)pIUnk,&IID_IDispatch,(LPVOID*)&disp);
|
||||
if (SUCCEEDED(hres)) {
|
||||
FIXME("Calling Invoke in IDispatch iface. untested!\n");
|
||||
hres = IDispatch_Invoke(
|
||||
disp,memid,&IID_NULL,LOCALE_USER_DEFAULT,dwFlags,pDispParams,
|
||||
pVarResult,pExcepInfo,pArgErr
|
||||
);
|
||||
if (FAILED(hres))
|
||||
FIXME("IDispatch::Invoke failed with %08lx. (Could be not a real error?)\n", hres);
|
||||
IDispatch_Release(disp);
|
||||
} else
|
||||
FIXME("FUNC_DISPATCH used on object without IDispatch iface?\n");
|
||||
return hr;
|
||||
}
|
||||
FIXME("Calling Invoke in IDispatch iface. untested!\n");
|
||||
hr = IDispatch_Invoke(
|
||||
disp,memid,&IID_NULL,LOCALE_USER_DEFAULT,dwFlags,pDispParams,
|
||||
pVarResult,pExcepInfo,pArgErr
|
||||
);
|
||||
if (hr)
|
||||
FIXME("IDispatch::Invoke failed with %08lx. (Could be not a real error?)\n",hr);
|
||||
IDispatch_Release(disp);
|
||||
return hr;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
FIXME("Unknown function invocation type %d\n",pFDesc->funcdesc.funckind);
|
||||
return E_FAIL;
|
||||
}
|
||||
FIXME("Unknown function invocation type %d\n", func_desc->funckind);
|
||||
hres = E_FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
ITypeInfo2_ReleaseFuncDesc(iface, func_desc);
|
||||
return hres;
|
||||
|
||||
} else {
|
||||
for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next) {
|
||||
if (pVDesc->vardesc.memid == memid) {
|
||||
|
|
Loading…
Reference in New Issue