Huw Davies : ole32: Implement the WdtpInterfacePointer marshal functions.

Alexandre Julliard julliard at winehq.org
Mon May 18 08:13:15 CDT 2009


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

Author: Huw Davies <huw at codeweavers.com>
Date:   Thu May 14 12:23:37 2009 +0100

ole32: Implement the WdtpInterfacePointer marshal functions.

---

 dlls/ole32/tests/usrmarshal.c |   63 ++++++++++++--------------
 dlls/ole32/usrmarshal.c       |   98 ++++++++++++++++++++++++++++++++++++----
 2 files changed, 118 insertions(+), 43 deletions(-)

diff --git a/dlls/ole32/tests/usrmarshal.c b/dlls/ole32/tests/usrmarshal.c
index e597b21..f1c0e34 100644
--- a/dlls/ole32/tests/usrmarshal.c
+++ b/dlls/ole32/tests/usrmarshal.c
@@ -512,7 +512,11 @@ static void marshal_WdtpInterfacePointer(DWORD umcb_ctx, DWORD ctx)
     IUnknown *unk;
     IUnknown *unk2;
     unsigned char *wireip;
-    DWORD expected_size;
+    HGLOBAL h = GlobalAlloc(GMEM_MOVEABLE, 0);
+    IStream *stm;
+    void *ptr;
+    LARGE_INTEGER pos;
+    DWORD h_size, marshal_size, expected_size;
 
     /* The marshalled data depends on the LOWORD of the ctx */
 
@@ -541,42 +545,35 @@ static void marshal_WdtpInterfacePointer(DWORD umcb_ctx, DWORD ctx)
     init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, umcb_ctx);
     buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, ctx, buffer, unk, &IID_IUnknown);
     wireip = buffer;
-    if(size)
-    {
-        HGLOBAL h = GlobalAlloc(GMEM_MOVEABLE, 0);
-        IStream *stm;
-        void *ptr;
-        LARGE_INTEGER pos;
-        DWORD h_size, marshal_size;
-
-        ok(buffer_end == buffer + expected_size, "buffer_end %p buffer %p (diff %x)\n", buffer_end, buffer, buffer_end - buffer);
-
-        marshal_size = buffer_end - buffer - 2 * sizeof(DWORD);
-        ok(*(DWORD *)wireip == marshal_size, "wireip + 0x0 should be 0x44 instead of 0x%08x\n", *(DWORD *)wireip);
-        wireip += sizeof(DWORD);
-        ok(*(DWORD *)wireip == marshal_size, "wireip + 0x4 should be 0x44 instead of 0x%08x\n", *(DWORD *)wireip);
-        wireip += sizeof(DWORD);
-
-        /* The remaining 0x44/0xac bytes are the result of CoMarshalInterface */
-
-        CreateStreamOnHGlobal(h, TRUE, &stm);
-        CoMarshalInterface(stm, &IID_IUnknown, unk, LOWORD(ctx), NULL, MSHLFLAGS_NORMAL);
-        h_size = GlobalSize(h);
-        ok(h_size == marshal_size, "size %x\n", h_size);
-
-        ptr = GlobalLock(h);
-        ok(!memcmp(ptr, wireip, h_size), "buffer mismatch\n");
-        GlobalUnlock(h);
-        pos.QuadPart = 0;
-        IStream_Seek(stm, pos, STREAM_SEEK_SET, NULL);
-        CoReleaseMarshalData(stm);
-        IStream_Release(stm);
-    }
+
+    /* Wine's standard marshalling appears to be a DWORD short */
+    todo_wine
+    ok(buffer_end == buffer + expected_size, "buffer_end %p buffer %p (diff %x)\n", buffer_end, buffer, buffer_end - buffer);
+
+    marshal_size = buffer_end - buffer - 2 * sizeof(DWORD);
+    ok(*(DWORD *)wireip == marshal_size, "wireip + 0x0 should be 0x44 instead of 0x%08x\n", *(DWORD *)wireip);
+    wireip += sizeof(DWORD);
+    ok(*(DWORD *)wireip == marshal_size, "wireip + 0x4 should be 0x44 instead of 0x%08x\n", *(DWORD *)wireip);
+    wireip += sizeof(DWORD);
+
+    /* The remaining 0x44/0xac bytes are the result of CoMarshalInterface */
+
+    CreateStreamOnHGlobal(h, TRUE, &stm);
+    CoMarshalInterface(stm, &IID_IUnknown, unk, LOWORD(ctx), NULL, MSHLFLAGS_NORMAL);
+    h_size = GlobalSize(h);
+    ok(h_size == marshal_size, "size %x\n", h_size);
+
+    ptr = GlobalLock(h);
+    ok(!memcmp(ptr, wireip, h_size), "buffer mismatch\n");
+    GlobalUnlock(h);
+    pos.QuadPart = 0;
+    IStream_Seek(stm, pos, STREAM_SEEK_SET, NULL);
+    CoReleaseMarshalData(stm);
+    IStream_Release(stm);
 
     unk2 = NULL;
     init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, umcb_ctx);
     WdtpInterfacePointer_UserUnmarshal(&umcb.Flags, buffer, &unk2, &IID_IUnknown);
-    todo_wine
     ok(unk2 != NULL, "IUnknown object didn't unmarshal properly\n");
     HeapFree(GetProcessHeap(), 0, buffer);
     init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_INPROC);
diff --git a/dlls/ole32/usrmarshal.c b/dlls/ole32/usrmarshal.c
index 57a048e..07a4aed 100644
--- a/dlls/ole32/usrmarshal.c
+++ b/dlls/ole32/usrmarshal.c
@@ -1570,10 +1570,19 @@ void __RPC_USER HMETAFILEPICT_UserFree(ULONG *pFlags, HMETAFILEPICT *phMfp)
  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
  *  the first parameter is a ULONG.
  */
-ULONG __RPC_USER WdtpInterfacePointer_UserSize(ULONG *pFlags, ULONG RealFlags, IUnknown *punk, ULONG StartingSize, REFIID riid)
+ULONG __RPC_USER WdtpInterfacePointer_UserSize(ULONG *pFlags, ULONG RealFlags, ULONG StartingSize, IUnknown *punk, REFIID riid)
 {
-    FIXME("(%s, 0%x, %p, %d, %s): stub\n", debugstr_user_flags(pFlags), RealFlags, punk, StartingSize, debugstr_guid(riid));
-    return 0;
+    DWORD marshal_size = 0;
+    HRESULT hr;
+
+    TRACE("(%s, 0%x, %d, %p, %s)\n", debugstr_user_flags(pFlags), RealFlags, StartingSize, punk, debugstr_guid(riid));
+
+    hr = CoGetMarshalSizeMax(&marshal_size, riid, punk, LOWORD(RealFlags), NULL, MSHLFLAGS_NORMAL);
+    if(FAILED(hr)) return StartingSize;
+
+    ALIGN_LENGTH(StartingSize, 3);
+    StartingSize += 2 * sizeof(DWORD);
+    return StartingSize + marshal_size;
 }
 
 /******************************************************************************
@@ -1598,8 +1607,40 @@ ULONG __RPC_USER WdtpInterfacePointer_UserSize(ULONG *pFlags, ULONG RealFlags, I
  */
 unsigned char * WINAPI WdtpInterfacePointer_UserMarshal(ULONG *pFlags, ULONG RealFlags, unsigned char *pBuffer, IUnknown *punk, REFIID riid)
 {
-    FIXME("(%s, 0x%x, %p, &%p, %s): stub\n", debugstr_user_flags(pFlags), RealFlags, pBuffer, punk, debugstr_guid(riid));
-    return NULL;
+    HGLOBAL h = GlobalAlloc(GMEM_MOVEABLE, 0);
+    IStream *stm;
+    DWORD size;
+    void *ptr;
+
+    TRACE("(%s, 0x%x, %p, &%p, %s)\n", debugstr_user_flags(pFlags), RealFlags, pBuffer, punk, debugstr_guid(riid));
+
+    if(!h) return NULL;
+    if(CreateStreamOnHGlobal(h, TRUE, &stm) != S_OK)
+    {
+        GlobalFree(h);
+        return NULL;
+    }
+
+    if(CoMarshalInterface(stm, riid, punk, LOWORD(RealFlags), NULL, MSHLFLAGS_NORMAL) != S_OK)
+    {
+        IStream_Release(stm);
+        return NULL;
+    }
+
+    ALIGN_POINTER(pBuffer, 3);
+    size = GlobalSize(h);
+
+    *(DWORD *)pBuffer = size;
+    pBuffer += sizeof(DWORD);
+    *(DWORD *)pBuffer = size;
+    pBuffer += sizeof(DWORD);
+
+    ptr = GlobalLock(h);
+    memcpy(pBuffer, ptr, size);
+    GlobalUnlock(h);
+
+    IStream_Release(stm);
+    return pBuffer + size;
 }
 
 /******************************************************************************
@@ -1623,24 +1664,61 @@ unsigned char * WINAPI WdtpInterfacePointer_UserMarshal(ULONG *pFlags, ULONG Rea
  */
 unsigned char * WINAPI WdtpInterfacePointer_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, IUnknown **ppunk, REFIID riid)
 {
-    FIXME("(%s, %p, %p, %s): stub\n", debugstr_user_flags(pFlags), pBuffer, ppunk, debugstr_guid(riid));
-    return NULL;
+    HRESULT hr;
+    HGLOBAL h;
+    IStream *stm;
+    DWORD size;
+    void *ptr;
+
+    TRACE("(%s, %p, %p, %s)\n", debugstr_user_flags(pFlags), pBuffer, ppunk, debugstr_guid(riid));
+
+    ALIGN_POINTER(pBuffer, 3);
+
+    size = *(DWORD *)pBuffer;
+    pBuffer += sizeof(DWORD);
+    if(size != *(DWORD *)pBuffer)
+        RaiseException(RPC_X_BAD_STUB_DATA, 0, 0, NULL);
+
+    pBuffer += sizeof(DWORD);
+
+    /* FIXME: sanity check on size */
+
+    h = GlobalAlloc(GMEM_MOVEABLE, size);
+    if(!h) RaiseException(RPC_X_NO_MEMORY, 0, 0, NULL);
+
+    if(CreateStreamOnHGlobal(h, TRUE, &stm) != S_OK)
+    {
+        GlobalFree(h);
+        RaiseException(RPC_X_NO_MEMORY, 0, 0, NULL);
+    }
+
+    ptr = GlobalLock(h);
+    memcpy(ptr, pBuffer, size);
+    GlobalUnlock(h);
+
+    hr = CoUnmarshalInterface(stm, riid, (void**)ppunk);
+    IStream_Release(stm);
+
+    if(hr != S_OK) RaiseException(hr, 0, 0, NULL);
+
+    return pBuffer + size;
 }
 
 /******************************************************************************
  *           WdtpInterfacePointer_UserFree [OLE32.@]
  *
- * Frees an unmarshaled interface pointer.
+ * Releases an unmarshaled interface pointer.
  *
  * PARAMS
- *  punk    [I] Interface pointer to free.
+ *  punk    [I] Interface pointer to release.
  *
  * RETURNS
  *  Nothing.
  */
 void WINAPI WdtpInterfacePointer_UserFree(IUnknown *punk)
 {
-    FIXME("(%p): stub\n", punk);
+    TRACE("(%p)\n", punk);
+    if(punk) IUnknown_Release(punk);
 }
 
 /******************************************************************************




More information about the wine-cvs mailing list