Commit 5b6312f2 authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

ole32: Implement the WdtpInterfacePointer marshal functions.

parent affe9a1e
......@@ -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);
......
......@@ -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);
}
/******************************************************************************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment