Huw Davies : oleaut32: Correctly marshal NULL interface ptrs.

Alexandre Julliard julliard at winehq.org
Thu Feb 25 11:36:22 CST 2010


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

Author: Huw Davies <huw at codeweavers.com>
Date:   Thu Feb 25 13:48:22 2010 +0000

oleaut32: Correctly marshal NULL interface ptrs.

---

 dlls/oleaut32/tests/usrmarshal.c |   24 ++++++++++++++++++++++
 dlls/oleaut32/usrmarshal.c       |   41 +++++++++++++++++++++++++-------------
 2 files changed, 51 insertions(+), 14 deletions(-)

diff --git a/dlls/oleaut32/tests/usrmarshal.c b/dlls/oleaut32/tests/usrmarshal.c
index b5cdc1e..9275837 100644
--- a/dlls/oleaut32/tests/usrmarshal.c
+++ b/dlls/oleaut32/tests/usrmarshal.c
@@ -1427,6 +1427,30 @@ static void test_marshal_VARIANT(void)
     }
     HeapFree(GetProcessHeap(), 0, oldbuffer);
 
+    /*** NULL UNKNOWN ***/
+    VariantInit(&v);
+    V_VT(&v) = VT_UNKNOWN;
+    V_UNKNOWN(&v) = NULL;
+
+    rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
+    ok(stubMsg.BufferLength >= 24, "size %d\n", stubMsg.BufferLength);
+    buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer);
+    stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength;
+    memset(buffer, 0xcc, stubMsg.BufferLength);
+    next = VARIANT_UserMarshal(&umcb.Flags, buffer, &v);
+    wirev = (DWORD*)buffer;
+    check_variant_header(wirev, &v, next - buffer);
+    wirev += 5;
+    ok(*wirev == 0, "wv[5] %08x\n", *wirev);
+
+    VariantInit(&v2);
+    stubMsg.Buffer = buffer;
+    next = VARIANT_UserUnmarshal(&umcb.Flags, buffer, &v2);
+    ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
+    ok(V_UNKNOWN(&v2) == NULL, "got %p expect NULL\n", V_UNKNOWN(&v2));
+    VARIANT_UserFree(&umcb.Flags, &v2);
+    HeapFree(GetProcessHeap(), 0, oldbuffer);
+
     /*** UNKNOWN BYREF ***/
     heap_unknown = HeapAlloc(GetProcessHeap(), 0, sizeof(*heap_unknown));
     heap_unknown->lpVtbl = &HeapUnknown_Vtbl;
diff --git a/dlls/oleaut32/usrmarshal.c b/dlls/oleaut32/usrmarshal.c
index 202cf84..402794c 100644
--- a/dlls/oleaut32/usrmarshal.c
+++ b/dlls/oleaut32/usrmarshal.c
@@ -256,20 +256,21 @@ static unsigned int get_type_alignment(ULONG *pFlags, VARTYPE vt)
 
 static unsigned interface_variant_size(const ULONG *pFlags, REFIID riid, IUnknown *punk)
 {
-  ULONG size;
-  HRESULT hr;
-  /* find the buffer size of the marshalled dispatch interface */
-  hr = CoGetMarshalSizeMax(&size, riid, punk, LOWORD(*pFlags), NULL, MSHLFLAGS_NORMAL);
-  if (FAILED(hr)) {
-    if (!punk)
-      WARN("NULL dispatch pointer\n");
-    else
-      ERR("Dispatch variant buffer size calculation failed, HRESULT=0x%x\n", hr);
-    return 0;
-  }
-  size += sizeof(ULONG); /* we have to store the buffersize in the stream */
-  TRACE("wire-size extra of dispatch variant is %d\n", size);
-  return size;
+    ULONG size = 0;
+    HRESULT hr;
+
+    if (punk)
+    {
+        hr = CoGetMarshalSizeMax(&size, riid, punk, LOWORD(*pFlags), NULL, MSHLFLAGS_NORMAL);
+        if (FAILED(hr))
+        {
+            ERR("interface variant buffer size calculation failed, HRESULT=0x%x\n", hr);
+            return 0;
+        }
+    }
+    size += sizeof(ULONG); /* we have to store the buffersize in the stream */
+    TRACE("wire-size extra of interface variant is %d\n", size);
+    return size;
 }
 
 static ULONG wire_extra_user_size(ULONG *pFlags, ULONG Start, VARIANT *pvar)
@@ -322,6 +323,12 @@ static unsigned char* interface_variant_marshal(const ULONG *pFlags, unsigned ch
   
   TRACE("pFlags=%d, Buffer=%p, pUnk=%p\n", *pFlags, Buffer, punk);
 
+  if(!punk)
+  {
+      memset(Buffer, 0, sizeof(ULONG));
+      return Buffer + sizeof(ULONG);
+  }
+
   oldpos = Buffer;
   
   /* CoMarshalInterface needs a stream, whereas at this level we are operating in terms of buffers.
@@ -378,6 +385,12 @@ static unsigned char *interface_variant_unmarshal(const ULONG *pFlags, unsigned
   memcpy(&size, Buffer, sizeof(ULONG));
   TRACE("buffersize=%d\n", size);
 
+  if(!size)
+  {
+      *ppunk = NULL;
+      return Buffer + sizeof(ULONG);
+  }
+
   working_mem = GlobalAlloc(0, size);
   if (!working_mem) return oldpos;
 




More information about the wine-cvs mailing list