[PATCH v3 3/6] oleaut32: Overwrite return type when rewriting FUNCDESC to FUNC_DISPATCH.

Huw Davies huw at codeweavers.com
Mon Sep 28 04:52:52 CDT 2020


From: Kevin Puetz <PuetzKevinA at 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 <PuetzKevinA at JohnDeere.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
---
 dlls/oleaut32/typelib.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c
index 540d91f2eb8..eaff9be77f1 100644
--- a/dlls/oleaut32/typelib.c
+++ b/dlls/oleaut32/typelib.c
@@ -5855,11 +5855,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 separate 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))
         {
@@ -5872,17 +5874,17 @@ 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. the function signature's return type.
+             * 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 HRESULT is returned in pExcepInfo->scode,
+             * not pVarResult.  So the function signature should show no return value. */
             dest->elemdescFunc.tdesc.vt = VT_VOID;
 
     }
-- 
2.23.0




More information about the wine-devel mailing list