Alexandre Julliard : oleaut32: Fix argument order with instance and VARIANT return type.

Alexandre Julliard julliard at winehq.org
Sun Mar 3 13:21:31 CST 2019


Module: wine
Branch: oldstable
Commit: b141e816d73b80c330d625aaa572ccbac87f564e
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=b141e816d73b80c330d625aaa572ccbac87f564e

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Nov 13 19:08:10 2018 +0100

oleaut32: Fix argument order with instance and VARIANT return type.

Spotted by Dmitry Timoshkov.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>
(cherry picked from commit b73972b9df0e26ebfe07c0d7fbc5b2b9583c556c)
Signed-off-by: Michael Stefaniuc <mstefani at winehq.org>

---

 dlls/oleaut32/typelib.c | 84 ++++++++++++++++++++++++++++---------------------
 1 file changed, 48 insertions(+), 36 deletions(-)

diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c
index 49366ae..4a57162 100644
--- a/dlls/oleaut32/typelib.c
+++ b/dlls/oleaut32/typelib.c
@@ -6676,7 +6676,7 @@ DispCallFunc(
     VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult)
 {
 #ifdef __i386__
-    int argspos, stack_offset;
+    int argspos = 0, stack_offset;
     void *func;
     UINT i;
     DWORD *args;
@@ -6694,8 +6694,6 @@ DispCallFunc(
     /* maximum size for an argument is sizeof(VARIANT) */
     args = heap_alloc(sizeof(VARIANT) * cActuals + sizeof(DWORD) * 2 );
 
-    /* start at 1 in case we need to pass a pointer to the return value as arg 0 */
-    argspos = 1;
     if (pvInstance)
     {
         const FARPROC *vtable = *(FARPROC **)pvInstance;
@@ -6704,6 +6702,20 @@ DispCallFunc(
     }
     else func = (void *)oVft;
 
+    switch (vtReturn)
+    {
+    case VT_DECIMAL:
+    case VT_VARIANT:
+        args[argspos++] = (DWORD)pvargResult;  /* arg 0 is a pointer to the result */
+        break;
+    case VT_HRESULT:
+        WARN("invalid return type %u\n", vtReturn);
+        heap_free( args );
+        return E_INVALIDARG;
+    default:
+        break;
+    }
+
     for (i = 0; i < cActuals; i++)
     {
         VARIANT *arg = prgpvarg[i];
@@ -6738,31 +6750,24 @@ DispCallFunc(
     switch (vtReturn)
     {
     case VT_EMPTY:
-        call_method( func, argspos - 1, args + 1, &stack_offset );
+    case VT_DECIMAL:
+    case VT_VARIANT:
+        call_method( func, argspos, args, &stack_offset );
         break;
     case VT_R4:
-        V_R4(pvargResult) = call_double_method( func, argspos - 1, args + 1, &stack_offset );
+        V_R4(pvargResult) = call_double_method( func, argspos, args, &stack_offset );
         break;
     case VT_R8:
     case VT_DATE:
-        V_R8(pvargResult) = call_double_method( func, argspos - 1, args + 1, &stack_offset );
-        break;
-    case VT_DECIMAL:
-    case VT_VARIANT:
-        args[0] = (DWORD)pvargResult;  /* arg 0 is a pointer to the result */
-        call_method( func, argspos, args, &stack_offset );
+        V_R8(pvargResult) = call_double_method( func, argspos, args, &stack_offset );
         break;
     case VT_I8:
     case VT_UI8:
     case VT_CY:
-        V_UI8(pvargResult) = call_method( func, argspos - 1, args + 1, &stack_offset );
+        V_UI8(pvargResult) = call_method( func, argspos, args, &stack_offset );
         break;
-    case VT_HRESULT:
-        WARN("invalid return type %u\n", vtReturn);
-        heap_free( args );
-        return E_INVALIDARG;
     default:
-        V_UI4(pvargResult) = call_method( func, argspos - 1, args + 1, &stack_offset );
+        V_UI4(pvargResult) = call_method( func, argspos, args, &stack_offset );
         break;
     }
     heap_free( args );
@@ -6776,7 +6781,7 @@ DispCallFunc(
     return S_OK;
 
 #elif defined(__x86_64__)
-    int argspos;
+    int argspos = 0;
     UINT i;
     DWORD_PTR *args;
     void *func;
@@ -6794,8 +6799,6 @@ DispCallFunc(
     /* maximum size for an argument is sizeof(DWORD_PTR) */
     args = heap_alloc( sizeof(DWORD_PTR) * (cActuals + 2) );
 
-    /* start at 1 in case we need to pass a pointer to the return value as arg 0 */
-    argspos = 1;
     if (pvInstance)
     {
         const FARPROC *vtable = *(FARPROC **)pvInstance;
@@ -6804,6 +6807,20 @@ DispCallFunc(
     }
     else func = (void *)oVft;
 
+    switch (vtReturn)
+    {
+    case VT_DECIMAL:
+    case VT_VARIANT:
+        args[argspos++] = (DWORD_PTR)pvargResult;  /* arg 0 is a pointer to the result */
+        break;
+    case VT_HRESULT:
+        WARN("invalid return type %u\n", vtReturn);
+        heap_free( args );
+        return E_INVALIDARG;
+    default:
+        break;
+    }
+
     for (i = 0; i < cActuals; i++)
     {
         VARIANT *arg = prgpvarg[i];
@@ -6827,23 +6844,18 @@ DispCallFunc(
     switch (vtReturn)
     {
     case VT_R4:
-        V_R4(pvargResult) = call_double_method( func, argspos - 1, args + 1 );
+        V_R4(pvargResult) = call_double_method( func, argspos, args );
         break;
     case VT_R8:
     case VT_DATE:
-        V_R8(pvargResult) = call_double_method( func, argspos - 1, args + 1 );
+        V_R8(pvargResult) = call_double_method( func, argspos, args );
         break;
     case VT_DECIMAL:
     case VT_VARIANT:
-        args[0] = (DWORD_PTR)pvargResult;  /* arg 0 is a pointer to the result */
         call_method( func, argspos, args );
         break;
-    case VT_HRESULT:
-        WARN("invalid return type %u\n", vtReturn);
-        heap_free( args );
-        return E_INVALIDARG;
     default:
-        V_UI8(pvargResult) = call_method( func, argspos - 1, args + 1 );
+        V_UI8(pvargResult) = call_method( func, argspos, args );
         break;
     }
     heap_free( args );
@@ -6883,6 +6895,14 @@ DispCallFunc(
     argspos = 0;
     rcount = 0;
 
+    if (pvInstance)
+    {
+        const FARPROC *vtable = *(FARPROC **)pvInstance;
+        func = vtable[oVft/sizeof(void *)];
+        regs.r[rcount++] = (DWORD)pvInstance; /* the This pointer is always the first parameter */
+    }
+    else func = (void *)oVft;
+
     /* Determine if we need to pass a pointer for the return value as arg 0.  If so, do that */
     /*  first as it will need to be in the 'r' registers:                                    */
     switch (vtReturn)
@@ -6898,14 +6918,6 @@ DispCallFunc(
         break;
     }
 
-    if (pvInstance)
-    {
-        const FARPROC *vtable = *(FARPROC **)pvInstance;
-        func = vtable[oVft/sizeof(void *)];
-        regs.r[rcount++] = (DWORD)pvInstance; /* the This pointer is always the first parameter */
-    }
-    else func = (void *)oVft;
-
     /* maximum size for an argument is sizeof(VARIANT).  Also allow for return pointer and stack alignment. */
     args = heap_alloc( sizeof(VARIANT) * cActuals + sizeof(DWORD) * 4 );
 




More information about the wine-cvs mailing list