Rob Shearman : oleaut32: Unmarshall byref types correctly in IDispatch_Invoke_Proxy.

Alexandre Julliard julliard at winehq.org
Wed Nov 18 09:40:41 CST 2009


Module: wine
Branch: master
Commit: 6d7572c0e75227e51022f81b32479421a46a6c9c
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=6d7572c0e75227e51022f81b32479421a46a6c9c

Author: Rob Shearman <robertshearman at gmail.com>
Date:   Wed Nov 18 00:16:51 2009 +0000

oleaut32: Unmarshall byref types correctly in IDispatch_Invoke_Proxy.

Byref arguments should only be passed in the rgVarRef array, not in
arg array. Copy the value into the rgVarRef array before calling the
remote function to ensure that memory isn't allocated for the byref
pointers during unmarshalling.

---

 dlls/oleaut32/tests/tmarshal.c |    1 -
 dlls/oleaut32/usrmarshal.c     |   14 +++++++++-----
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/dlls/oleaut32/tests/tmarshal.c b/dlls/oleaut32/tests/tmarshal.c
index ba28892..7a6c49e 100644
--- a/dlls/oleaut32/tests/tmarshal.c
+++ b/dlls/oleaut32/tests/tmarshal.c
@@ -1364,7 +1364,6 @@ static void test_typelibmarshal(void)
     ok_ole_success(hr, ITypeInfo_Invoke);
     ok(V_VT(&varresult) == VT_EMPTY, "varresult should be VT_EMPTY\n");
     ok(V_VT(&vararg[0]) == (VT_UI4|VT_BYREF), "arg VT not unmarshalled correctly: %x\n", V_VT(&vararg[0]));
-    todo_wine
     ok(V_UI4REF(&vararg[0]) == &uval, "Byref pointer not preserved: %p/%p\n", &uval, V_UI4REF(&vararg[0]));
     ok(*V_UI4REF(&vararg[0]) == 42, "Expected 42 to be returned instead of %u\n", *V_UI4REF(&vararg[0]));
     VariantClear(&varresult);
diff --git a/dlls/oleaut32/usrmarshal.c b/dlls/oleaut32/usrmarshal.c
index 3172eba..6ad9bd6 100644
--- a/dlls/oleaut32/usrmarshal.c
+++ b/dlls/oleaut32/usrmarshal.c
@@ -1180,6 +1180,8 @@ HRESULT CALLBACK IDispatch_Invoke_Proxy(
       if (V_ISBYREF(arg)) {
 	rgVarRefIdx[cVarRef] = u;
 	VariantInit(&rgVarRef[cVarRef]);
+	VariantCopy(&rgVarRef[cVarRef], arg);
+	VariantClear(arg);
 	cVarRef++;
       }
     }
@@ -1265,6 +1267,12 @@ HRESULT __RPC_STUB IDispatch_Invoke_Stub(
   }
 
   if (SUCCEEDED(hr)) {
+    /* copy ref args to arg array */
+    for (u=0; u<cVarRef; u++) {
+      unsigned i = rgVarRefIdx[u];
+      VariantCopy(&arg[i], &rgVarRef[u]);
+    }
+
     pDispParams->rgvarg = arg;
 
     hr = IDispatch_Invoke(This,
@@ -1277,14 +1285,10 @@ HRESULT __RPC_STUB IDispatch_Invoke_Stub(
 			  pExcepInfo,
 			  pArgErr);
 
-    /* copy ref args to out list */
+    /* copy ref args from arg array */
     for (u=0; u<cVarRef; u++) {
       unsigned i = rgVarRefIdx[u];
-      VariantInit(&rgVarRef[u]);
       VariantCopy(&rgVarRef[u], &arg[i]);
-      /* clear original if equal, to avoid double-free */
-      if (V_BYREF(&rgVarRef[u]) == V_BYREF(&rgvarg[i]))
-        VariantClear(&rgvarg[i]);
     }
   }
 




More information about the wine-cvs mailing list