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