Robert Shearman : OLE: Move the dispinterface return value handling to functions that

Alexandre Julliard julliard at wine.codeweavers.com
Sat Dec 3 12:31:15 CST 2005


Module: wine
Branch: refs/heads/master
Commit: d48f6f36827dc12fd194fce6bc2c7b786fcb7b69
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=d48f6f36827dc12fd194fce6bc2c7b786fcb7b69

Author: Robert Shearman <rob at codeweavers.com>
Date:   Sat Dec  3 18:10:30 2005 +0100

OLE: Move the dispinterface return value handling to functions that
return the FUNCDESC to the user.

---

 dlls/oleaut32/typelib.c |   76 +++++++++++++++++++++++++----------------------
 1 files changed, 41 insertions(+), 35 deletions(-)

diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c
index 32c2780..8e37ea9 100644
--- a/dlls/oleaut32/typelib.c
+++ b/dlls/oleaut32/typelib.c
@@ -1863,38 +1863,6 @@ MSFT_DoFuncs(TLBContext*     pcx,
             }
         }
 
-        /* special treatment for dispinterfaces: this makes functions appear
-         * to return their [retval] value when it is really returning an
-         * HRESULT */
-        if ((pTI->TypeAttr.typekind == TKIND_DISPATCH) &&
-            (*pptfd)->funcdesc.elemdescFunc.tdesc.vt == VT_HRESULT)
-        {
-            if (pFuncRec->nrargs &&
-                ((*pptfd)->funcdesc.lprgelemdescParam[pFuncRec->nrargs - 1].u.paramdesc.wParamFlags & PARAMFLAG_FRETVAL))
-            {
-                ELEMDESC *elemdesc = &(*pptfd)->funcdesc.lprgelemdescParam[pFuncRec->nrargs - 1];
-                if (elemdesc->tdesc.vt != VT_PTR)
-                {
-                    ERR_(typelib)("elemdesc should have started with VT_PTR instead of:\n");
-                    if (ERR_ON(typelib))
-                        dump_ELEMDESC(elemdesc);
-                    /* FIXME: return error */
-                    break;
-                }
- 
-                (*pptfd)->funcdesc.elemdescFunc = *elemdesc;
- 
-                /* dereference parameter */
-                (*pptfd)->funcdesc.elemdescFunc.tdesc = *elemdesc->tdesc.u.lptdesc;
- 
-                pFuncRec->nrargs--;
-                (*pptfd)->funcdesc.cParams = pFuncRec->nrargs;
-            }
-            else
-                (*pptfd)->funcdesc.elemdescFunc.tdesc.vt = VT_VOID;
-
-        }
-
         /* scode is not used: archaic win16 stuff FIXME: right? */
         (*pptfd)->funcdesc.cScodes   = 0 ;
         (*pptfd)->funcdesc.lprgscode = NULL ;
@@ -4403,7 +4371,7 @@ static void TLB_FreeElemDesc( ELEMDESC *
         VariantClear(&elemdesc->u.paramdesc.pparamdescex->varDefaultValue);
 }
 
-static HRESULT TLB_AllocAndInitFuncDesc( const FUNCDESC *src, FUNCDESC **dest_ptr )
+static HRESULT TLB_AllocAndInitFuncDesc( const FUNCDESC *src, FUNCDESC **dest_ptr, BOOL dispinterface )
 {
     FUNCDESC *dest;
     char *buffer;
@@ -4454,6 +4422,38 @@ static HRESULT TLB_AllocAndInitFuncDesc(
         return hr;
     }
 
+    /* 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)
+    {
+        if (dest->cParams &&
+            (dest->lprgelemdescParam[dest->cParams - 1].u.paramdesc.wParamFlags & PARAMFLAG_FRETVAL))
+        {
+            ELEMDESC *elemdesc = &dest->lprgelemdescParam[dest->cParams - 1];
+            if (elemdesc->tdesc.vt != VT_PTR)
+            {
+                ERR("elemdesc should have started with VT_PTR instead of:\n");
+                if (ERR_ON(ole))
+                    dump_ELEMDESC(elemdesc);
+                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 */
+            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 */
+            dest->elemdescFunc.tdesc.vt = VT_VOID;
+
+    }
+
     *dest_ptr = dest;
     return S_OK;
 }
@@ -4477,7 +4477,10 @@ static HRESULT WINAPI ITypeInfo_fnGetFun
         ;
 
     if(pFDesc)
-        return TLB_AllocAndInitFuncDesc(&pFDesc->funcdesc, ppFuncDesc);
+        return TLB_AllocAndInitFuncDesc(
+            &pFDesc->funcdesc,
+            ppFuncDesc,
+            This->TypeAttr.typekind == TKIND_DISPATCH);
 
     return E_INVALIDARG;
 }
@@ -6362,7 +6365,10 @@ static HRESULT WINAPI ITypeComp_fnBind(
 
     if (pFDesc)
     {
-        HRESULT hr = TLB_AllocAndInitFuncDesc(&pFDesc->funcdesc, &pBindPtr->lpfuncdesc);
+        HRESULT hr = TLB_AllocAndInitFuncDesc(
+            &pFDesc->funcdesc,
+            &pBindPtr->lpfuncdesc,
+            This->TypeAttr.typekind == TKIND_DISPATCH);
         if (FAILED(hr))
             return hr;
         *pDescKind = DESCKIND_FUNCDESC;




More information about the wine-cvs mailing list