[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