typelib: Invoke cleanup
Huw D M Davies
h.davies1 at physics.ox.ac.uk
Mon Dec 6 10:35:42 CST 2004
Requires my earlier patch to GetFuncIndexOfMemId
Huw Davies <huw at codeweavers.com>
Remove Invoke's dependence on the internal TLBFuncDesc structure.
Fix memory leaks in some failure cases.
--
Huw Davies
huw at codeweavers.com
Index: dlls/oleaut32/typelib.c
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/typelib.c,v
retrieving revision 1.129
diff -u -p -p -r1.129 typelib.c
--- dlls/oleaut32/typelib.c 2 Dec 2004 19:58:07 -0000 1.129
+++ dlls/oleaut32/typelib.c 6 Dec 2004 17:28:36 -0000
@@ -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) {
More information about the wine-patches
mailing list