Robert Shearman : OLE: Implement undocumented behaviour in DispCallFunc.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Dec 6 14:27:20 CST 2005


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

Author: Robert Shearman <rob at codeweavers.com>
Date:   Tue Dec  6 21:25:51 2005 +0100

OLE: Implement undocumented behaviour in DispCallFunc.
Fix DispCallFunc to work with MSDN-undocumented behaviour used by
Office 2003 and document the function.

---

 dlls/oleaut32/typelib.c |   68 ++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 61 insertions(+), 7 deletions(-)

diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c
index 5ed9a82..a6e2495 100644
--- a/dlls/oleaut32/typelib.c
+++ b/dlls/oleaut32/typelib.c
@@ -5173,6 +5173,45 @@ static HRESULT typedescvt_to_variantvt(I
 
 /***********************************************************************
  *		DispCallFunc (OLEAUT32.@)
+ *
+ * Invokes a function of the specifed calling convention, passing the
+ * specified arguments and returns the result.
+ *
+ * PARAMS
+ *  pvInstance  [I] Optional pointer to the instance whose function to invoke.
+ *  oVft        [I] The offset in the vtable. See notes.
+ *  cc          [I] Calling convention of the function to call.
+ *  vtReturn    [I] The return type of the function.
+ *  cActuals    [I] Number of parameters.
+ *  prgvt       [I] The types of the parameters to pass. This is used for sizing only.
+ *  prgpvarg    [I] The arguments to pass.
+ *  pvargResult [O] The return value of the function. Can be NULL.
+ *
+ * RETURNS
+ *  Success: S_OK.
+ *  Failure: HRESULT code.
+ *
+ * NOTES
+ *  The HRESULT return value of this function is not affected by the return
+ *  value of the user supplied function, which is returned in pvargResult.
+ *
+ *  If pvInstance is NULL then a non-object function is to be called and oVft
+ *  is the address of the function to call.
+ *
+ * The cc parameter can be one of the following values:
+ *|CC_FASTCALL
+ *|CC_CDECL
+ *|CC_PASCAL
+ *|CC_STDCALL
+ *|CC_FPFASTCALL
+ *|CC_SYSCALL
+ *|CC_MPWCDECL
+ *|CC_MPWPASCAL
+ *
+ * BUGS
+ *  Native accepts arguments in the reverse order. I.e. the first item in the
+ *  prgpvarg array is the last argument in the C/C++ declaration of the
+ *  function to be called.
  */
 HRESULT WINAPI
 DispCallFunc(
@@ -5187,10 +5226,10 @@ DispCallFunc(
         pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg,
         pvargResult, V_VT(pvargResult));
 
-    /* DispCallFunc is only used to invoke methods belonging to an
-     * IDispatch-derived COM interface. So we need to add a first parameter
-     * to the list of arguments, to supply the interface pointer */
-    argsize = 1;
+    argsize = 0;
+    if (pvInstance)
+        argsize++; /* for This pointer */
+
     for (i=0;i<cActuals;i++)
     {
         TRACE("arg %d: type %d, size %d\n",i,prgvt[i],_argsize(prgvt[i]));
@@ -5198,8 +5237,14 @@ DispCallFunc(
         argsize += _argsize(prgvt[i]);
     }
     args = HeapAlloc(GetProcessHeap(),0,sizeof(DWORD)*argsize);
-    args[0] = (DWORD)pvInstance;      /* this is the fake IDispatch interface pointer */
-    argspos = 1;
+
+    argspos = 0;
+    if (pvInstance)
+    {
+        args[0] = (DWORD)pvInstance; /* the This pointer is always the first parameter */
+        argspos++;
+    }
+
     for (i=0;i<cActuals;i++)
     {
         VARIANT *arg = prgpvarg[i];
@@ -5208,7 +5253,16 @@ DispCallFunc(
         argspos += _argsize(prgvt[i]);
     }
 
-    hres = _invoke((*(FARPROC**)pvInstance)[oVft/sizeof(void *)],cc,argsize,args);
+    if (pvInstance)
+    {
+        FARPROC *vtable = *(FARPROC**)pvInstance;
+        hres = _invoke(vtable[oVft/sizeof(void *)], cc, argsize, args);
+    }
+    else
+        /* if we aren't invoking an object then the function pointer is stored
+         * in oVft */
+        hres = _invoke((FARPROC)oVft, cc, argsize, args);
+
     if (pvargResult && (vtReturn != VT_EMPTY))
     {
         TRACE("Method returned 0x%08lx\n",hres);




More information about the wine-cvs mailing list