[PATCH v2 3/6] oleaut32: return type when rewriting FUNCDESC to FUNC_DISPATCH.
Kevin Puetz
PuetzKevinA at JohnDeere.com
Mon Sep 21 09:17:19 CDT 2020
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 at 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;
}
More information about the wine-devel
mailing list