Huw Davies : ole32: WdtpInterfacePointer_UserUnmarshal() should release an interface if one is passed in.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Oct 27 11:06:37 CDT 2015


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

Author: Huw Davies <huw at codeweavers.com>
Date:   Tue Oct 27 14:42:31 2015 +0000

ole32: WdtpInterfacePointer_UserUnmarshal() should release an interface if one is passed in.

Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ole32/tests/usrmarshal.c | 32 ++++++++++++++++++++++++--------
 dlls/ole32/usrmarshal.c       |  4 ++++
 2 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/dlls/ole32/tests/usrmarshal.c b/dlls/ole32/tests/usrmarshal.c
index 23cb910..756e820 100644
--- a/dlls/ole32/tests/usrmarshal.c
+++ b/dlls/ole32/tests/usrmarshal.c
@@ -563,13 +563,14 @@ static const IStreamVtbl TestStream_Vtbl =
 };
 
 static TestUnknown Test_Unknown = { {&TestUnknown_Vtbl}, 1 };
+static TestUnknown Test_Unknown2 = { {&TestUnknown_Vtbl}, 1 };
 static IStream Test_Stream = { &TestStream_Vtbl };
 
 ULONG __RPC_USER WdtpInterfacePointer_UserSize(ULONG *, ULONG, ULONG, IUnknown *, REFIID);
 unsigned char * __RPC_USER WdtpInterfacePointer_UserMarshal(ULONG *, ULONG, unsigned char *, IUnknown *, REFIID);
 unsigned char * __RPC_USER WdtpInterfacePointer_UserUnmarshal(ULONG *, unsigned char *, IUnknown **, REFIID);
 
-static void marshal_WdtpInterfacePointer(DWORD umcb_ctx, DWORD ctx)
+static void marshal_WdtpInterfacePointer(DWORD umcb_ctx, DWORD ctx, BOOL client, BOOL in, BOOL out)
 {
     USER_MARSHAL_CB umcb;
     MIDL_STUB_MESSAGE stub_msg;
@@ -638,11 +639,17 @@ todo_wine
     CoReleaseMarshalData(stm);
     IStream_Release(stm);
 
-    unk2 = NULL;
+    Test_Unknown2.refs = 1;
+    unk2 = &Test_Unknown2.IUnknown_iface;
     init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, umcb_ctx);
+    umcb.pStubMsg->IsClient = client;
+    umcb.pStubMsg->fIsIn = in;
+    umcb.pStubMsg->fIsOut = out;
+
     WdtpInterfacePointer_UserUnmarshal(&umcb.Flags, buffer, &unk2, &IID_IUnknown);
     ok(unk2 != NULL, "IUnknown object didn't unmarshal properly\n");
     ok(Test_Unknown.refs == 2, "got %d\n", Test_Unknown.refs);
+    ok(Test_Unknown2.refs == 0, "got %d\n", Test_Unknown2.refs);
     HeapFree(GetProcessHeap(), 0, buffer);
     init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_INPROC);
     IUnknown_Release(unk2);
@@ -657,14 +664,23 @@ static void test_marshal_WdtpInterfacePointer(void)
      */
 
     /* All three are marshalled as inproc */
-    marshal_WdtpInterfacePointer(MSHCTX_INPROC, MSHCTX_INPROC);
-    marshal_WdtpInterfacePointer(MSHCTX_DIFFERENTMACHINE, MSHCTX_INPROC);
-    marshal_WdtpInterfacePointer(MSHCTX_INPROC, MAKELONG(MSHCTX_INPROC, 0xffff));
+    marshal_WdtpInterfacePointer(MSHCTX_INPROC, MSHCTX_INPROC, 0,0,0);
+    marshal_WdtpInterfacePointer(MSHCTX_DIFFERENTMACHINE, MSHCTX_INPROC,0,0,0);
+    marshal_WdtpInterfacePointer(MSHCTX_INPROC, MAKELONG(MSHCTX_INPROC, 0xffff),0,0,0);
 
     /* All three are marshalled as remote */
-    marshal_WdtpInterfacePointer(MSHCTX_INPROC, MSHCTX_DIFFERENTMACHINE);
-    marshal_WdtpInterfacePointer(MSHCTX_DIFFERENTMACHINE, MSHCTX_DIFFERENTMACHINE);
-    marshal_WdtpInterfacePointer(MSHCTX_INPROC, MAKELONG(MSHCTX_DIFFERENTMACHINE, 0xffff));
+    marshal_WdtpInterfacePointer(MSHCTX_INPROC, MSHCTX_DIFFERENTMACHINE,0,0,0);
+    marshal_WdtpInterfacePointer(MSHCTX_DIFFERENTMACHINE, MSHCTX_DIFFERENTMACHINE,0,0,0);
+    marshal_WdtpInterfacePointer(MSHCTX_INPROC, MAKELONG(MSHCTX_DIFFERENTMACHINE, 0xffff),0,0,0);
+
+    /* Test different combinations of client, in and out */
+    marshal_WdtpInterfacePointer(MSHCTX_INPROC, MSHCTX_DIFFERENTMACHINE,0,0,1);
+    marshal_WdtpInterfacePointer(MSHCTX_INPROC, MSHCTX_DIFFERENTMACHINE,0,1,0);
+    marshal_WdtpInterfacePointer(MSHCTX_INPROC, MSHCTX_DIFFERENTMACHINE,0,1,1);
+    marshal_WdtpInterfacePointer(MSHCTX_INPROC, MSHCTX_DIFFERENTMACHINE,1,0,0);
+    marshal_WdtpInterfacePointer(MSHCTX_INPROC, MSHCTX_DIFFERENTMACHINE,1,0,1);
+    marshal_WdtpInterfacePointer(MSHCTX_INPROC, MSHCTX_DIFFERENTMACHINE,1,1,0);
+    marshal_WdtpInterfacePointer(MSHCTX_INPROC, MSHCTX_DIFFERENTMACHINE,1,1,1);
 }
 
 static void test_marshal_STGMEDIUM(void)
diff --git a/dlls/ole32/usrmarshal.c b/dlls/ole32/usrmarshal.c
index fe8ff4f..3184be6 100644
--- a/dlls/ole32/usrmarshal.c
+++ b/dlls/ole32/usrmarshal.c
@@ -1490,6 +1490,7 @@ unsigned char * WINAPI WdtpInterfacePointer_UserUnmarshal(ULONG *pFlags, unsigne
     IStream *stm;
     DWORD size;
     void *ptr;
+    IUnknown *orig;
 
     TRACE("(%s, %p, %p, %s)\n", debugstr_user_flags(pFlags), pBuffer, ppunk, debugstr_guid(riid));
 
@@ -1517,11 +1518,14 @@ unsigned char * WINAPI WdtpInterfacePointer_UserUnmarshal(ULONG *pFlags, unsigne
     memcpy(ptr, pBuffer, size);
     GlobalUnlock(h);
 
+    orig = *ppunk;
     hr = CoUnmarshalInterface(stm, riid, (void**)ppunk);
     IStream_Release(stm);
 
     if(hr != S_OK) RaiseException(hr, 0, 0, NULL);
 
+    if(orig) IUnknown_Release(orig);
+
     return pBuffer + size;
 }
 




More information about the wine-cvs mailing list