From: Kevin Puetz Subject: [PATCH v2 3/6] oleaut32: return type when rewriting FUNCDESC to FUNC_DISPATCH. Message-Id: <20200921141722.2300-3-PuetzKevinA@JohnDeere.com> Date: Mon, 21 Sep 2020 09:17:19 -0500 In-Reply-To: <20200921141722.2300-1-PuetzKevinA@JohnDeere.com> References: <20200921141722.2300-1-PuetzKevinA@JohnDeere.com> A [retval] parameter overwrites any return type, not just HRESULT. But HRESULT is special even without a [retval] to replace it; it's translated into pExcepInfo and so the return type becomes void. This rewriting should occur only for functions not originally defined as FUNC_DISPACH (e.g. inherited or [dual]). A FUNCDESC originally declared as a dispinterface is left as-is, and might e.g. return HRESULT. Signed-off-by: Kevin Puetz --- dlls/oleaut32/typelib.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c index ecc754145f..2c9b4ac5eb 100644 --- a/dlls/oleaut32/typelib.c +++ b/dlls/oleaut32/typelib.c @@ -5857,11 +5857,13 @@ static HRESULT TLB_AllocAndInitFuncDesc( const FUNCDESC *src, FUNCDESC **dest_pt } else dest->lprgelemdescParam = NULL; - /* special treatment for dispinterfaces: this makes functions appear - * to return their [retval] value when it is really returning an - * HRESULT */ - if (dispinterface && dest->elemdescFunc.tdesc.vt == VT_HRESULT) + /* special treatment for dispinterface FUNCDESC based on an interface FUNCDESC. + * This accounts for several arguments that are seperate in the signature of + * IDispatch::Invoke, rather than passed in DISPPARAMS::rgvarg[] */ + if (dispinterface && (src->funckind != FUNC_DISPATCH)) { + /* functions that have a [retval] parameter return this value into pVarResult. + * [retval] is always the last parameter (if present) */ if (dest->cParams && (dest->lprgelemdescParam[dest->cParams - 1].u.paramdesc.wParamFlags & PARAMFLAG_FRETVAL)) { @@ -5874,17 +5876,18 @@ static HRESULT TLB_AllocAndInitFuncDesc( const FUNCDESC *src, FUNCDESC **dest_pt return E_UNEXPECTED; } - /* copy last parameter to the return value. we are using a flat - * buffer so there is no danger of leaking memory in - * elemdescFunc */ + /* the type pointed to by this [retval] becomes elemdescFunc, + * i.e. functions signature's return type (replacing HRESULT/void/anything else) + * We are using a flat buffer so there is no danger of leaking memory */ dest->elemdescFunc.tdesc = *elemdesc->tdesc.u.lptdesc; /* remove the last parameter */ dest->cParams--; } - else - /* otherwise this function is made to appear to have no return - * value */ + else if (dest->elemdescFunc.tdesc.vt == VT_HRESULT) + /* Even if not otherwise replaced (by [retval], + * HRESULT is returned in pExcepInfo->scode, not pVarResult. + * So the function signature should show no return value. */ dest->elemdescFunc.tdesc.vt = VT_VOID; }