Commit 23ded07e authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

Remove Invoke's dependence on the internal TLBFuncDesc structure.

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