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 PuetzKevinA@JohnDeere.com --- 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;
}