2007-11-29 12:54:54 +00:00
|
|
|
/*
|
|
|
|
* User Marshaling Tests
|
|
|
|
*
|
|
|
|
* Copyright 2004-2006 Robert Shearman for CodeWeavers
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define COBJMACROS
|
|
|
|
#define CONST_VTABLE
|
|
|
|
#include <stdarg.h>
|
|
|
|
|
|
|
|
#include "windef.h"
|
|
|
|
#include "winbase.h"
|
|
|
|
#include "objbase.h"
|
|
|
|
#include "objidl.h"
|
|
|
|
|
|
|
|
#include "wine/test.h"
|
|
|
|
|
2010-03-10 21:52:40 +00:00
|
|
|
ULONG __RPC_USER HMETAFILE_UserSize(ULONG *, ULONG, HMETAFILE *);
|
2007-11-29 12:54:54 +00:00
|
|
|
unsigned char * __RPC_USER HMETAFILE_UserMarshal(ULONG *, unsigned char *, HMETAFILE *);
|
|
|
|
unsigned char * __RPC_USER HMETAFILE_UserUnmarshal(ULONG *, unsigned char *, HMETAFILE *);
|
|
|
|
void __RPC_USER HMETAFILE_UserFree(ULONG *, HMETAFILE *);
|
|
|
|
|
2009-01-18 19:23:06 +00:00
|
|
|
ULONG __RPC_USER HENHMETAFILE_UserSize(ULONG *, ULONG, HENHMETAFILE *);
|
|
|
|
unsigned char * __RPC_USER HENHMETAFILE_UserMarshal (ULONG *, unsigned char *, HENHMETAFILE *);
|
|
|
|
unsigned char * __RPC_USER HENHMETAFILE_UserUnmarshal(ULONG *, unsigned char *, HENHMETAFILE *);
|
|
|
|
void __RPC_USER HENHMETAFILE_UserFree(ULONG *, HENHMETAFILE *);
|
|
|
|
|
|
|
|
ULONG __RPC_USER HMETAFILEPICT_UserSize(ULONG *, ULONG, HMETAFILEPICT *);
|
|
|
|
unsigned char * __RPC_USER HMETAFILEPICT_UserMarshal (ULONG *, unsigned char *, HMETAFILEPICT *);
|
|
|
|
unsigned char * __RPC_USER HMETAFILEPICT_UserUnmarshal(ULONG *, unsigned char *, HMETAFILEPICT *);
|
|
|
|
void __RPC_USER HMETAFILEPICT_UserFree(ULONG *, HMETAFILEPICT *);
|
|
|
|
|
2009-05-17 07:05:22 +00:00
|
|
|
static void * WINAPI user_allocate(SIZE_T size)
|
|
|
|
{
|
|
|
|
return CoTaskMemAlloc(size);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void WINAPI user_free(void *p)
|
|
|
|
{
|
|
|
|
CoTaskMemFree(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void init_user_marshal_cb(USER_MARSHAL_CB *umcb,
|
|
|
|
PMIDL_STUB_MESSAGE stub_msg,
|
|
|
|
PRPC_MESSAGE rpc_msg, unsigned char *buffer,
|
|
|
|
unsigned int size, MSHCTX context)
|
|
|
|
{
|
|
|
|
memset(rpc_msg, 0, sizeof(*rpc_msg));
|
|
|
|
rpc_msg->Buffer = buffer;
|
|
|
|
rpc_msg->BufferLength = size;
|
|
|
|
|
|
|
|
memset(stub_msg, 0, sizeof(*stub_msg));
|
|
|
|
stub_msg->RpcMsg = rpc_msg;
|
|
|
|
stub_msg->Buffer = buffer;
|
|
|
|
stub_msg->pfnAllocate = user_allocate;
|
|
|
|
stub_msg->pfnFree = user_free;
|
|
|
|
|
|
|
|
memset(umcb, 0, sizeof(*umcb));
|
|
|
|
umcb->Flags = MAKELONG(context, NDR_LOCAL_DATA_REPRESENTATION);
|
|
|
|
umcb->pStubMsg = stub_msg;
|
|
|
|
umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
|
|
|
|
umcb->CBType = buffer ? USER_MARSHAL_CB_UNMARSHALL : USER_MARSHAL_CB_BUFFER_SIZE;
|
|
|
|
}
|
2009-01-18 19:23:06 +00:00
|
|
|
|
2007-11-29 12:54:54 +00:00
|
|
|
static const char cf_marshaled[] =
|
|
|
|
{
|
|
|
|
0x9, 0x0, 0x0, 0x0,
|
|
|
|
0x0, 0x0, 0x0, 0x0,
|
|
|
|
0x9, 0x0, 0x0, 0x0,
|
|
|
|
'M', 0x0, 'y', 0x0,
|
|
|
|
'F', 0x0, 'o', 0x0,
|
|
|
|
'r', 0x0, 'm', 0x0,
|
|
|
|
'a', 0x0, 't', 0x0,
|
|
|
|
0x0, 0x0
|
|
|
|
};
|
|
|
|
|
|
|
|
static void test_marshal_CLIPFORMAT(void)
|
|
|
|
{
|
2009-05-17 07:05:22 +00:00
|
|
|
USER_MARSHAL_CB umcb;
|
|
|
|
MIDL_STUB_MESSAGE stub_msg;
|
|
|
|
RPC_MESSAGE rpc_msg;
|
2007-11-29 12:54:54 +00:00
|
|
|
unsigned char *buffer;
|
2009-05-17 07:05:22 +00:00
|
|
|
ULONG i, size;
|
2007-11-29 12:54:54 +00:00
|
|
|
CLIPFORMAT cf = RegisterClipboardFormatA("MyFormat");
|
|
|
|
CLIPFORMAT cf2;
|
|
|
|
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
size = CLIPFORMAT_UserSize(&umcb.Flags, 0, &cf);
|
|
|
|
ok(size == 8 + sizeof(cf_marshaled) ||
|
|
|
|
broken(size == 12 + sizeof(cf_marshaled)) || /* win64 adds 4 extra (unused) bytes */
|
|
|
|
broken(size == 8 + sizeof(cf_marshaled) - 2), /* win9x and winnt don't include the '\0' */
|
|
|
|
"CLIPFORMAT: Wrong size %d\n", size);
|
2007-11-29 12:54:54 +00:00
|
|
|
|
|
|
|
buffer = HeapAlloc(GetProcessHeap(), 0, size);
|
2009-05-17 07:05:22 +00:00
|
|
|
memset( buffer, 0xcc, size );
|
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
CLIPFORMAT_UserMarshal(&umcb.Flags, buffer, &cf);
|
|
|
|
ok(*(LONG *)(buffer + 0) == WDT_REMOTE_CALL, "CLIPFORMAT: Context should be WDT_REMOTE_CALL instead of 0x%08x\n", *(LONG *)(buffer + 0));
|
|
|
|
ok(*(DWORD *)(buffer + 4) == cf, "CLIPFORMAT: Marshaled value should be 0x%04x instead of 0x%04x\n", cf, *(DWORD *)(buffer + 4));
|
|
|
|
ok(!memcmp(buffer + 8, cf_marshaled, min( sizeof(cf_marshaled), size-8 )), "Marshaled data differs\n");
|
|
|
|
if (size > sizeof(cf_marshaled) + 8) /* make sure the extra bytes are not used */
|
|
|
|
for (i = sizeof(cf_marshaled) + 8; i < size; i++)
|
|
|
|
ok( buffer[i] == 0xcc, "buffer offset %u has been set to %x\n", i, buffer[i] );
|
|
|
|
|
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
CLIPFORMAT_UserUnmarshal(&umcb.Flags, buffer, &cf2);
|
|
|
|
ok(cf == cf2, "CLIPFORMAT: Didn't unmarshal properly\n");
|
2007-11-29 12:54:54 +00:00
|
|
|
HeapFree(GetProcessHeap(), 0, buffer);
|
|
|
|
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
CLIPFORMAT_UserFree(&umcb.Flags, &cf2);
|
2007-11-29 12:54:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void test_marshal_HWND(void)
|
|
|
|
{
|
2009-05-17 07:05:22 +00:00
|
|
|
USER_MARSHAL_CB umcb;
|
|
|
|
MIDL_STUB_MESSAGE stub_msg;
|
|
|
|
RPC_MESSAGE rpc_msg;
|
2007-11-29 12:54:54 +00:00
|
|
|
unsigned char *buffer;
|
|
|
|
ULONG size;
|
|
|
|
HWND hwnd = GetDesktopWindow();
|
|
|
|
HWND hwnd2;
|
|
|
|
wireHWND wirehwnd;
|
|
|
|
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
|
|
|
|
size = HWND_UserSize(&umcb.Flags, 0, &hwnd);
|
2007-11-29 12:54:54 +00:00
|
|
|
ok(size == sizeof(*wirehwnd), "Wrong size %d\n", size);
|
|
|
|
|
|
|
|
buffer = HeapAlloc(GetProcessHeap(), 0, size);
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
|
|
|
|
HWND_UserMarshal(&umcb.Flags, buffer, &hwnd);
|
2007-11-29 12:54:54 +00:00
|
|
|
wirehwnd = (wireHWND)buffer;
|
2009-05-17 07:05:22 +00:00
|
|
|
ok(wirehwnd->fContext == WDT_INPROC_CALL, "Context should be WDT_INPROC_CALL instead of 0x%08x\n", wirehwnd->fContext);
|
2010-03-10 21:52:40 +00:00
|
|
|
ok(wirehwnd->u.hInproc == (LONG_PTR)hwnd, "Marshaled value should be %p instead of %x\n", hwnd, wirehwnd->u.hRemote);
|
2007-11-29 12:54:54 +00:00
|
|
|
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
|
|
|
|
HWND_UserUnmarshal(&umcb.Flags, buffer, &hwnd2);
|
2007-11-29 12:54:54 +00:00
|
|
|
ok(hwnd == hwnd2, "Didn't unmarshal properly\n");
|
|
|
|
HeapFree(GetProcessHeap(), 0, buffer);
|
|
|
|
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
|
|
|
|
HWND_UserFree(&umcb.Flags, &hwnd2);
|
2007-11-29 12:54:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void test_marshal_HGLOBAL(void)
|
|
|
|
{
|
2009-05-17 07:05:22 +00:00
|
|
|
USER_MARSHAL_CB umcb;
|
|
|
|
MIDL_STUB_MESSAGE stub_msg;
|
|
|
|
RPC_MESSAGE rpc_msg;
|
2007-11-29 12:54:54 +00:00
|
|
|
unsigned char *buffer;
|
2010-03-10 21:52:40 +00:00
|
|
|
ULONG size, block_size;
|
2007-11-29 12:54:54 +00:00
|
|
|
HGLOBAL hglobal;
|
|
|
|
HGLOBAL hglobal2;
|
|
|
|
unsigned char *wirehglobal;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
hglobal = NULL;
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
|
|
|
|
size = HGLOBAL_UserSize(&umcb.Flags, 0, &hglobal);
|
|
|
|
/* native is poorly programmed and allocates 4/8 bytes more than it needs to
|
2007-11-29 12:54:54 +00:00
|
|
|
* here - Wine doesn't have to emulate that */
|
2009-05-17 07:05:22 +00:00
|
|
|
ok((size == 8) || broken(size == 12) || broken(size == 16), "Size should be 8, instead of %d\n", size);
|
2007-11-29 12:54:54 +00:00
|
|
|
buffer = HeapAlloc(GetProcessHeap(), 0, size);
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
|
|
|
|
HGLOBAL_UserMarshal(&umcb.Flags, buffer, &hglobal);
|
2007-11-29 12:54:54 +00:00
|
|
|
wirehglobal = buffer;
|
|
|
|
ok(*(ULONG *)wirehglobal == WDT_REMOTE_CALL, "Context should be WDT_REMOTE_CALL instead of 0x%08x\n", *(ULONG *)wirehglobal);
|
|
|
|
wirehglobal += sizeof(ULONG);
|
2009-05-17 07:05:22 +00:00
|
|
|
ok(*(ULONG *)wirehglobal == 0, "buffer+4 should be HGLOBAL\n");
|
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
|
2012-05-17 15:17:09 +00:00
|
|
|
hglobal2 = NULL;
|
2009-05-17 07:05:22 +00:00
|
|
|
HGLOBAL_UserUnmarshal(&umcb.Flags, buffer, &hglobal2);
|
2007-11-29 12:54:54 +00:00
|
|
|
ok(hglobal2 == hglobal, "Didn't unmarshal properly\n");
|
|
|
|
HeapFree(GetProcessHeap(), 0, buffer);
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
|
|
|
|
HGLOBAL_UserFree(&umcb.Flags, &hglobal2);
|
2007-11-29 12:54:54 +00:00
|
|
|
|
2010-03-10 21:52:40 +00:00
|
|
|
|
|
|
|
for(block_size = 0; block_size <= 17; block_size++)
|
|
|
|
{
|
|
|
|
ULONG actual_size, expected_size;
|
|
|
|
|
|
|
|
hglobal = GlobalAlloc(0, block_size);
|
|
|
|
buffer = GlobalLock(hglobal);
|
|
|
|
for (i = 0; i < block_size; i++)
|
|
|
|
buffer[i] = i;
|
|
|
|
GlobalUnlock(hglobal);
|
|
|
|
actual_size = GlobalSize(hglobal);
|
|
|
|
expected_size = actual_size + 5 * sizeof(DWORD);
|
|
|
|
trace("%d: actual size %d\n", block_size, actual_size);
|
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
|
|
|
|
size = HGLOBAL_UserSize(&umcb.Flags, 0, &hglobal);
|
|
|
|
/* native is poorly programmed and allocates 4/8 bytes more than it needs to
|
|
|
|
* here - Wine doesn't have to emulate that */
|
|
|
|
ok(size == expected_size ||
|
|
|
|
broken(size == expected_size + 4) ||
|
|
|
|
broken(size == expected_size + 8),
|
|
|
|
"%d: got size %d\n", block_size, size);
|
|
|
|
buffer = HeapAlloc(GetProcessHeap(), 0, size);
|
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
|
|
|
|
HGLOBAL_UserMarshal(&umcb.Flags, buffer, &hglobal);
|
|
|
|
wirehglobal = buffer;
|
|
|
|
ok(*(ULONG *)wirehglobal == WDT_REMOTE_CALL, "Context should be WDT_REMOTE_CALL instead of 0x%08x\n", *(ULONG *)wirehglobal);
|
|
|
|
wirehglobal += sizeof(ULONG);
|
|
|
|
ok(*(ULONG *)wirehglobal == (ULONG)(ULONG_PTR)hglobal, "buffer+0x4 should be HGLOBAL\n");
|
|
|
|
wirehglobal += sizeof(ULONG);
|
|
|
|
ok(*(ULONG *)wirehglobal == actual_size, "%d: buffer+0x8 %08x\n", block_size, *(ULONG *)wirehglobal);
|
|
|
|
wirehglobal += sizeof(ULONG);
|
|
|
|
ok(*(ULONG *)wirehglobal == (ULONG)(ULONG_PTR)hglobal, "buffer+0xc should be HGLOBAL\n");
|
|
|
|
wirehglobal += sizeof(ULONG);
|
|
|
|
ok(*(ULONG *)wirehglobal == actual_size, "%d: buffer+0x10 %08x\n", block_size, *(ULONG *)wirehglobal);
|
|
|
|
wirehglobal += sizeof(ULONG);
|
|
|
|
for (i = 0; i < block_size; i++)
|
|
|
|
ok(wirehglobal[i] == i, "buffer+0x%x should be %d\n", 0x10 + i, i);
|
|
|
|
|
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
|
2012-05-17 15:17:09 +00:00
|
|
|
hglobal2 = NULL;
|
2010-03-10 21:52:40 +00:00
|
|
|
HGLOBAL_UserUnmarshal(&umcb.Flags, buffer, &hglobal2);
|
|
|
|
ok(hglobal2 != NULL, "Didn't unmarshal properly\n");
|
|
|
|
HeapFree(GetProcessHeap(), 0, buffer);
|
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
|
|
|
|
HGLOBAL_UserFree(&umcb.Flags, &hglobal2);
|
|
|
|
GlobalFree(hglobal);
|
|
|
|
}
|
2007-11-29 12:54:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static HENHMETAFILE create_emf(void)
|
|
|
|
{
|
2009-01-04 17:52:22 +00:00
|
|
|
const RECT rect = {0, 0, 100, 100};
|
2007-11-29 12:54:54 +00:00
|
|
|
HDC hdc = CreateEnhMetaFile(NULL, NULL, &rect, "HENHMETAFILE Marshaling Test\0Test\0\0");
|
2009-01-04 17:52:22 +00:00
|
|
|
ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rect, "Test String", strlen("Test String"), NULL);
|
2007-11-29 12:54:54 +00:00
|
|
|
return CloseEnhMetaFile(hdc);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void test_marshal_HENHMETAFILE(void)
|
|
|
|
{
|
2009-05-17 07:05:22 +00:00
|
|
|
USER_MARSHAL_CB umcb;
|
|
|
|
MIDL_STUB_MESSAGE stub_msg;
|
|
|
|
RPC_MESSAGE rpc_msg;
|
2007-11-29 12:54:54 +00:00
|
|
|
unsigned char *buffer;
|
|
|
|
ULONG size;
|
|
|
|
HENHMETAFILE hemf;
|
|
|
|
HENHMETAFILE hemf2 = NULL;
|
|
|
|
unsigned char *wirehemf;
|
|
|
|
|
|
|
|
hemf = create_emf();
|
|
|
|
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
size = HENHMETAFILE_UserSize(&umcb.Flags, 0, &hemf);
|
2007-11-29 12:54:54 +00:00
|
|
|
ok(size > 20, "size should be at least 20 bytes, not %d\n", size);
|
|
|
|
buffer = HeapAlloc(GetProcessHeap(), 0, size);
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
HENHMETAFILE_UserMarshal(&umcb.Flags, buffer, &hemf);
|
2007-11-29 12:54:54 +00:00
|
|
|
wirehemf = buffer;
|
|
|
|
ok(*(DWORD *)wirehemf == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehemf);
|
|
|
|
wirehemf += sizeof(DWORD);
|
|
|
|
ok(*(DWORD *)wirehemf == (DWORD)(DWORD_PTR)hemf, "wirestgm + 0x4 should be hemf instead of 0x%08x\n", *(DWORD *)wirehemf);
|
|
|
|
wirehemf += sizeof(DWORD);
|
|
|
|
ok(*(DWORD *)wirehemf == (size - 0x10), "wirestgm + 0x8 should be size - 0x10 instead of 0x%08x\n", *(DWORD *)wirehemf);
|
|
|
|
wirehemf += sizeof(DWORD);
|
|
|
|
ok(*(DWORD *)wirehemf == (size - 0x10), "wirestgm + 0xc should be size - 0x10 instead of 0x%08x\n", *(DWORD *)wirehemf);
|
|
|
|
wirehemf += sizeof(DWORD);
|
|
|
|
ok(*(DWORD *)wirehemf == EMR_HEADER, "wirestgm + 0x10 should be EMR_HEADER instead of %d\n", *(DWORD *)wirehemf);
|
|
|
|
wirehemf += sizeof(DWORD);
|
|
|
|
/* ... rest of data not tested - refer to tests for GetEnhMetaFileBits
|
|
|
|
* at this point */
|
|
|
|
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
HENHMETAFILE_UserUnmarshal(&umcb.Flags, buffer, &hemf2);
|
2007-11-29 12:54:54 +00:00
|
|
|
ok(hemf2 != NULL, "HENHMETAFILE didn't unmarshal\n");
|
|
|
|
HeapFree(GetProcessHeap(), 0, buffer);
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
HENHMETAFILE_UserFree(&umcb.Flags, &hemf2);
|
2007-11-29 12:54:54 +00:00
|
|
|
DeleteEnhMetaFile(hemf);
|
|
|
|
|
|
|
|
/* test NULL emf */
|
|
|
|
hemf = NULL;
|
|
|
|
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
size = HENHMETAFILE_UserSize(&umcb.Flags, 0, &hemf);
|
2007-11-29 12:54:54 +00:00
|
|
|
ok(size == 8, "size should be 8 bytes, not %d\n", size);
|
|
|
|
buffer = HeapAlloc(GetProcessHeap(), 0, size);
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
HENHMETAFILE_UserMarshal(&umcb.Flags, buffer, &hemf);
|
2007-11-29 12:54:54 +00:00
|
|
|
wirehemf = buffer;
|
|
|
|
ok(*(DWORD *)wirehemf == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehemf);
|
|
|
|
wirehemf += sizeof(DWORD);
|
|
|
|
ok(*(DWORD *)wirehemf == (DWORD)(DWORD_PTR)hemf, "wirestgm + 0x4 should be hemf instead of 0x%08x\n", *(DWORD *)wirehemf);
|
|
|
|
wirehemf += sizeof(DWORD);
|
|
|
|
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
HENHMETAFILE_UserUnmarshal(&umcb.Flags, buffer, &hemf2);
|
2007-11-29 12:54:54 +00:00
|
|
|
ok(hemf2 == NULL, "NULL HENHMETAFILE didn't unmarshal\n");
|
|
|
|
HeapFree(GetProcessHeap(), 0, buffer);
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
HENHMETAFILE_UserFree(&umcb.Flags, &hemf2);
|
2007-11-29 12:54:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static HMETAFILE create_mf(void)
|
|
|
|
{
|
|
|
|
RECT rect = {0, 0, 100, 100};
|
|
|
|
HDC hdc = CreateMetaFile(NULL);
|
|
|
|
ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rect, "Test String", strlen("Test String"), NULL);
|
|
|
|
return CloseMetaFile(hdc);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void test_marshal_HMETAFILE(void)
|
|
|
|
{
|
2009-05-17 07:05:22 +00:00
|
|
|
USER_MARSHAL_CB umcb;
|
|
|
|
MIDL_STUB_MESSAGE stub_msg;
|
|
|
|
RPC_MESSAGE rpc_msg;
|
2007-11-29 12:54:54 +00:00
|
|
|
unsigned char *buffer;
|
|
|
|
ULONG size;
|
|
|
|
HMETAFILE hmf;
|
|
|
|
HMETAFILE hmf2 = NULL;
|
|
|
|
unsigned char *wirehmf;
|
|
|
|
|
|
|
|
hmf = create_mf();
|
|
|
|
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
size = HMETAFILE_UserSize(&umcb.Flags, 0, &hmf);
|
2007-11-29 12:54:54 +00:00
|
|
|
ok(size > 20, "size should be at least 20 bytes, not %d\n", size);
|
|
|
|
buffer = HeapAlloc(GetProcessHeap(), 0, size);
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
HMETAFILE_UserMarshal(&umcb.Flags, buffer, &hmf);
|
2007-11-29 12:54:54 +00:00
|
|
|
wirehmf = buffer;
|
|
|
|
ok(*(DWORD *)wirehmf == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehmf);
|
|
|
|
wirehmf += sizeof(DWORD);
|
|
|
|
ok(*(DWORD *)wirehmf == (DWORD)(DWORD_PTR)hmf, "wirestgm + 0x4 should be hmf instead of 0x%08x\n", *(DWORD *)wirehmf);
|
|
|
|
wirehmf += sizeof(DWORD);
|
|
|
|
ok(*(DWORD *)wirehmf == (size - 0x10), "wirestgm + 0x8 should be size - 0x10 instead of 0x%08x\n", *(DWORD *)wirehmf);
|
|
|
|
wirehmf += sizeof(DWORD);
|
|
|
|
ok(*(DWORD *)wirehmf == (size - 0x10), "wirestgm + 0xc should be size - 0x10 instead of 0x%08x\n", *(DWORD *)wirehmf);
|
|
|
|
wirehmf += sizeof(DWORD);
|
|
|
|
ok(*(WORD *)wirehmf == 1, "wirestgm + 0x10 should be 1 instead of 0x%08x\n", *(DWORD *)wirehmf);
|
|
|
|
wirehmf += sizeof(DWORD);
|
|
|
|
/* ... rest of data not tested - refer to tests for GetMetaFileBits
|
|
|
|
* at this point */
|
|
|
|
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
HMETAFILE_UserUnmarshal(&umcb.Flags, buffer, &hmf2);
|
2007-11-29 12:54:54 +00:00
|
|
|
ok(hmf2 != NULL, "HMETAFILE didn't unmarshal\n");
|
|
|
|
HeapFree(GetProcessHeap(), 0, buffer);
|
2009-05-17 07:05:22 +00:00
|
|
|
HMETAFILE_UserFree(&umcb.Flags, &hmf2);
|
2007-11-29 12:54:54 +00:00
|
|
|
DeleteMetaFile(hmf);
|
|
|
|
|
|
|
|
/* test NULL emf */
|
|
|
|
hmf = NULL;
|
|
|
|
|
2009-05-17 07:05:22 +00:00
|
|
|
size = HMETAFILE_UserSize(&umcb.Flags, 0, &hmf);
|
2007-11-29 12:54:54 +00:00
|
|
|
ok(size == 8, "size should be 8 bytes, not %d\n", size);
|
|
|
|
buffer = HeapAlloc(GetProcessHeap(), 0, size);
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
HMETAFILE_UserMarshal(&umcb.Flags, buffer, &hmf);
|
2007-11-29 12:54:54 +00:00
|
|
|
wirehmf = buffer;
|
|
|
|
ok(*(DWORD *)wirehmf == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehmf);
|
|
|
|
wirehmf += sizeof(DWORD);
|
|
|
|
ok(*(DWORD *)wirehmf == (DWORD)(DWORD_PTR)hmf, "wirestgm + 0x4 should be hmf instead of 0x%08x\n", *(DWORD *)wirehmf);
|
|
|
|
wirehmf += sizeof(DWORD);
|
|
|
|
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
HMETAFILE_UserUnmarshal(&umcb.Flags, buffer, &hmf2);
|
2007-11-29 12:54:54 +00:00
|
|
|
ok(hmf2 == NULL, "NULL HMETAFILE didn't unmarshal\n");
|
|
|
|
HeapFree(GetProcessHeap(), 0, buffer);
|
2009-05-17 07:05:22 +00:00
|
|
|
HMETAFILE_UserFree(&umcb.Flags, &hmf2);
|
2007-11-29 12:54:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#define USER_MARSHAL_PTR_PREFIX \
|
|
|
|
( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
|
|
|
|
( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
|
|
|
|
|
|
|
|
static void test_marshal_HMETAFILEPICT(void)
|
|
|
|
{
|
2009-05-17 07:05:22 +00:00
|
|
|
USER_MARSHAL_CB umcb;
|
|
|
|
MIDL_STUB_MESSAGE stub_msg;
|
|
|
|
RPC_MESSAGE rpc_msg;
|
2007-11-29 12:54:54 +00:00
|
|
|
unsigned char *buffer, *buffer_end;
|
|
|
|
ULONG size;
|
|
|
|
HMETAFILEPICT hmfp;
|
|
|
|
HMETAFILEPICT hmfp2 = NULL;
|
|
|
|
METAFILEPICT *pmfp;
|
|
|
|
unsigned char *wirehmfp;
|
|
|
|
|
|
|
|
hmfp = GlobalAlloc(GMEM_MOVEABLE, sizeof(*pmfp));
|
|
|
|
pmfp = GlobalLock(hmfp);
|
|
|
|
pmfp->mm = MM_ISOTROPIC;
|
|
|
|
pmfp->xExt = 1;
|
|
|
|
pmfp->yExt = 2;
|
|
|
|
pmfp->hMF = create_mf();
|
|
|
|
GlobalUnlock(hmfp);
|
|
|
|
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
size = HMETAFILEPICT_UserSize(&umcb.Flags, 0, &hmfp);
|
2007-11-29 12:54:54 +00:00
|
|
|
ok(size > 20, "size should be at least 20 bytes, not %d\n", size);
|
|
|
|
trace("size is %d\n", size);
|
|
|
|
buffer = HeapAlloc(GetProcessHeap(), 0, size);
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
buffer_end = HMETAFILEPICT_UserMarshal(&umcb.Flags, buffer, &hmfp);
|
2007-11-29 12:54:54 +00:00
|
|
|
wirehmfp = buffer;
|
|
|
|
ok(*(DWORD *)wirehmfp == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehmfp);
|
|
|
|
wirehmfp += sizeof(DWORD);
|
|
|
|
ok(*(DWORD *)wirehmfp == (DWORD)(DWORD_PTR)hmfp, "wirestgm + 0x4 should be hmf instead of 0x%08x\n", *(DWORD *)wirehmfp);
|
|
|
|
wirehmfp += sizeof(DWORD);
|
|
|
|
ok(*(DWORD *)wirehmfp == MM_ISOTROPIC, "wirestgm + 0x8 should be MM_ISOTROPIC instead of 0x%08x\n", *(DWORD *)wirehmfp);
|
|
|
|
wirehmfp += sizeof(DWORD);
|
|
|
|
ok(*(DWORD *)wirehmfp == 1, "wirestgm + 0xc should be 1 instead of 0x%08x\n", *(DWORD *)wirehmfp);
|
|
|
|
wirehmfp += sizeof(DWORD);
|
|
|
|
ok(*(DWORD *)wirehmfp == 2, "wirestgm + 0x10 should be 2 instead of 0x%08x\n", *(DWORD *)wirehmfp);
|
|
|
|
wirehmfp += sizeof(DWORD);
|
|
|
|
ok(*(DWORD *)wirehmfp == USER_MARSHAL_PTR_PREFIX, "wirestgm + 0x14 should be \"User\" instead of 0x%08x\n", *(DWORD *)wirehmfp);
|
|
|
|
wirehmfp += sizeof(DWORD);
|
|
|
|
ok(*(DWORD *)wirehmfp == WDT_REMOTE_CALL, "wirestgm + 0x18 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehmfp);
|
|
|
|
wirehmfp += sizeof(DWORD);
|
|
|
|
pmfp = GlobalLock(hmfp);
|
|
|
|
ok(*(DWORD *)wirehmfp == (DWORD)(DWORD_PTR)pmfp->hMF, "wirestgm + 0x1c should be pmfp->hMF instead of 0x%08x\n", *(DWORD *)wirehmfp);
|
|
|
|
GlobalUnlock(hmfp);
|
|
|
|
wirehmfp += sizeof(DWORD);
|
|
|
|
/* Note use (buffer_end - buffer) instead of size here, because size is an
|
|
|
|
* overestimate with native */
|
|
|
|
ok(*(DWORD *)wirehmfp == (buffer_end - buffer - 0x28), "wirestgm + 0x20 should be size - 0x34 instead of 0x%08x\n", *(DWORD *)wirehmfp);
|
|
|
|
wirehmfp += sizeof(DWORD);
|
|
|
|
ok(*(DWORD *)wirehmfp == (buffer_end - buffer - 0x28), "wirestgm + 0x24 should be size - 0x34 instead of 0x%08x\n", *(DWORD *)wirehmfp);
|
|
|
|
wirehmfp += sizeof(DWORD);
|
|
|
|
ok(*(WORD *)wirehmfp == 1, "wirehmfp + 0x28 should be 1 instead of 0x%08x\n", *(DWORD *)wirehmfp);
|
|
|
|
wirehmfp += sizeof(DWORD);
|
|
|
|
/* ... rest of data not tested - refer to tests for GetMetaFileBits
|
|
|
|
* at this point */
|
|
|
|
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
HMETAFILEPICT_UserUnmarshal(&umcb.Flags, buffer, &hmfp2);
|
2007-11-29 12:54:54 +00:00
|
|
|
ok(hmfp2 != NULL, "HMETAFILEPICT didn't unmarshal\n");
|
|
|
|
HeapFree(GetProcessHeap(), 0, buffer);
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
HMETAFILEPICT_UserFree(&umcb.Flags, &hmfp2);
|
2007-11-29 12:54:54 +00:00
|
|
|
pmfp = GlobalLock(hmfp);
|
|
|
|
DeleteMetaFile(pmfp->hMF);
|
|
|
|
GlobalUnlock(hmfp);
|
|
|
|
GlobalFree(hmfp);
|
|
|
|
|
|
|
|
/* test NULL emf */
|
|
|
|
hmfp = NULL;
|
|
|
|
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
size = HMETAFILEPICT_UserSize(&umcb.Flags, 0, &hmfp);
|
2007-11-29 12:54:54 +00:00
|
|
|
ok(size == 8, "size should be 8 bytes, not %d\n", size);
|
|
|
|
buffer = HeapAlloc(GetProcessHeap(), 0, size);
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
HMETAFILEPICT_UserMarshal(&umcb.Flags, buffer, &hmfp);
|
2007-11-29 12:54:54 +00:00
|
|
|
wirehmfp = buffer;
|
|
|
|
ok(*(DWORD *)wirehmfp == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehmfp);
|
|
|
|
wirehmfp += sizeof(DWORD);
|
|
|
|
ok(*(DWORD *)wirehmfp == (DWORD)(DWORD_PTR)hmfp, "wirestgm + 0x4 should be hmf instead of 0x%08x\n", *(DWORD *)wirehmfp);
|
|
|
|
wirehmfp += sizeof(DWORD);
|
|
|
|
|
|
|
|
hmfp2 = NULL;
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
HMETAFILEPICT_UserUnmarshal(&umcb.Flags, buffer, &hmfp2);
|
2007-11-29 12:54:54 +00:00
|
|
|
ok(hmfp2 == NULL, "NULL HMETAFILE didn't unmarshal\n");
|
|
|
|
HeapFree(GetProcessHeap(), 0, buffer);
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
HMETAFILEPICT_UserFree(&umcb.Flags, &hmfp2);
|
2007-11-29 12:54:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI Test_IUnknown_QueryInterface(
|
|
|
|
LPUNKNOWN iface,
|
|
|
|
REFIID riid,
|
|
|
|
LPVOID *ppvObj)
|
|
|
|
{
|
|
|
|
if (ppvObj == NULL) return E_POINTER;
|
|
|
|
|
|
|
|
if (IsEqualGUID(riid, &IID_IUnknown))
|
|
|
|
{
|
2009-02-08 08:56:01 +00:00
|
|
|
*ppvObj = iface;
|
2007-11-29 12:54:54 +00:00
|
|
|
IUnknown_AddRef(iface);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
*ppvObj = NULL;
|
|
|
|
return E_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI Test_IUnknown_AddRef(LPUNKNOWN iface)
|
|
|
|
{
|
|
|
|
return 2; /* non-heap-based object */
|
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI Test_IUnknown_Release(LPUNKNOWN iface)
|
|
|
|
{
|
|
|
|
return 1; /* non-heap-based object */
|
|
|
|
}
|
|
|
|
|
|
|
|
static const IUnknownVtbl TestUnknown_Vtbl =
|
|
|
|
{
|
|
|
|
Test_IUnknown_QueryInterface,
|
|
|
|
Test_IUnknown_AddRef,
|
|
|
|
Test_IUnknown_Release,
|
|
|
|
};
|
|
|
|
|
2010-03-10 21:52:40 +00:00
|
|
|
static HRESULT WINAPI Test_IStream_QueryInterface(IStream *iface,
|
|
|
|
REFIID riid, LPVOID *ppvObj)
|
|
|
|
{
|
|
|
|
if (ppvObj == NULL) return E_POINTER;
|
|
|
|
|
|
|
|
if (IsEqualIID(riid, &IID_IUnknown) ||
|
|
|
|
IsEqualIID(riid, &IID_IStream))
|
|
|
|
{
|
|
|
|
*ppvObj = iface;
|
|
|
|
IStream_AddRef(iface);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
*ppvObj = NULL;
|
|
|
|
return E_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI Test_IStream_AddRef(IStream *iface)
|
|
|
|
{
|
|
|
|
return 2; /* non-heap-based object */
|
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI Test_IStream_Release(IStream *iface)
|
|
|
|
{
|
|
|
|
return 1; /* non-heap-based object */
|
|
|
|
}
|
|
|
|
|
|
|
|
static const IStreamVtbl TestStream_Vtbl =
|
|
|
|
{
|
|
|
|
Test_IStream_QueryInterface,
|
|
|
|
Test_IStream_AddRef,
|
|
|
|
Test_IStream_Release
|
|
|
|
/* the rest can be NULLs */
|
|
|
|
};
|
|
|
|
|
2007-11-29 12:54:54 +00:00
|
|
|
static IUnknown Test_Unknown = { &TestUnknown_Vtbl };
|
2010-03-10 21:52:40 +00:00
|
|
|
static IStream Test_Stream = { &TestStream_Vtbl };
|
2007-11-29 12:54:54 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2010-03-10 21:52:40 +00:00
|
|
|
static void marshal_WdtpInterfacePointer(DWORD umcb_ctx, DWORD ctx)
|
2007-11-29 12:54:54 +00:00
|
|
|
{
|
2009-05-17 07:05:22 +00:00
|
|
|
USER_MARSHAL_CB umcb;
|
|
|
|
MIDL_STUB_MESSAGE stub_msg;
|
|
|
|
RPC_MESSAGE rpc_msg;
|
2007-11-29 12:54:54 +00:00
|
|
|
unsigned char *buffer, *buffer_end;
|
|
|
|
ULONG size;
|
|
|
|
IUnknown *unk;
|
|
|
|
IUnknown *unk2;
|
|
|
|
unsigned char *wireip;
|
2010-03-10 21:52:40 +00:00
|
|
|
HGLOBAL h = GlobalAlloc(GMEM_MOVEABLE, 0);
|
|
|
|
IStream *stm;
|
|
|
|
void *marshal_data;
|
|
|
|
LARGE_INTEGER zero;
|
|
|
|
ULARGE_INTEGER pos;
|
|
|
|
DWORD marshal_size;
|
2007-11-29 12:54:54 +00:00
|
|
|
|
|
|
|
/* shows that the WdtpInterfacePointer functions don't marshal anything for
|
|
|
|
* NULL pointers, so code using these functions must handle that case
|
|
|
|
* itself */
|
2010-03-10 21:52:40 +00:00
|
|
|
|
2007-11-29 12:54:54 +00:00
|
|
|
unk = NULL;
|
2010-03-10 21:52:40 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, umcb_ctx);
|
|
|
|
size = WdtpInterfacePointer_UserSize(&umcb.Flags, ctx, 0, unk, &IID_IUnknown);
|
2007-11-29 12:54:54 +00:00
|
|
|
ok(size == 0, "size should be 0 bytes, not %d\n", size);
|
|
|
|
buffer = HeapAlloc(GetProcessHeap(), 0, size);
|
2010-03-10 21:52:40 +00:00
|
|
|
buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, ctx, buffer, unk, &IID_IUnknown);
|
2007-11-29 12:54:54 +00:00
|
|
|
HeapFree(GetProcessHeap(), 0, buffer);
|
|
|
|
|
2010-03-10 21:52:40 +00:00
|
|
|
/* Now for a non-NULL pointer. The marshalled data are two size DWORDS and then
|
|
|
|
the result of CoMarshalInterface called with the LOWORD of the ctx */
|
|
|
|
|
2007-11-29 12:54:54 +00:00
|
|
|
unk = &Test_Unknown;
|
2010-03-10 21:52:40 +00:00
|
|
|
|
|
|
|
CreateStreamOnHGlobal(h, TRUE, &stm);
|
|
|
|
CoMarshalInterface(stm, &IID_IUnknown, unk, LOWORD(ctx), NULL, MSHLFLAGS_NORMAL);
|
|
|
|
zero.QuadPart = 0;
|
|
|
|
IStream_Seek(stm, zero, STREAM_SEEK_CUR, &pos);
|
|
|
|
marshal_size = pos.u.LowPart;
|
|
|
|
marshal_data = GlobalLock(h);
|
|
|
|
trace("marshal_size %x\n", marshal_size);
|
|
|
|
|
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, umcb_ctx);
|
|
|
|
size = WdtpInterfacePointer_UserSize(&umcb.Flags, ctx, 0, unk, &IID_IUnknown);
|
|
|
|
ok(size >= marshal_size + 2 * sizeof(DWORD), "marshal size %x got %x\n", marshal_size, size);
|
|
|
|
trace("WdtpInterfacePointer_UserSize returned %x\n", size);
|
2007-11-29 12:54:54 +00:00
|
|
|
buffer = HeapAlloc(GetProcessHeap(), 0, size);
|
2010-03-10 21:52:40 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, umcb_ctx);
|
|
|
|
buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, ctx, buffer, unk, &IID_IUnknown);
|
2007-11-29 12:54:54 +00:00
|
|
|
wireip = buffer;
|
2010-03-10 21:52:40 +00:00
|
|
|
|
Sync advapi32, comctl32, crypt32, cryptui, cryptnet, fusion, gdi32, gdiplus, hlink, imm32, jscript, kernel32, localspl, msacm32, mscms, msi, mstask, msvcrtd, msxml3, ntdll, ole32, pdh, psapi, quartz, rasapi32, riched20 AND rsaenh Winetests.
TBD mshtml, shell32, oleaut32 which still fail to build here
svn path=/trunk/; revision=47931
2010-07-03 12:45:23 +00:00
|
|
|
ok(buffer_end == buffer + marshal_size + 2 * sizeof(DWORD), "buffer_end %p buffer %p\n", buffer_end, buffer);
|
2010-03-10 21:52:40 +00:00
|
|
|
|
|
|
|
ok(*(DWORD *)wireip == marshal_size, "wireip + 0x0 should be %x instead of %x\n", marshal_size, *(DWORD *)wireip);
|
|
|
|
wireip += sizeof(DWORD);
|
|
|
|
ok(*(DWORD *)wireip == marshal_size, "wireip + 0x4 should be %x instead of %x\n", marshal_size, *(DWORD *)wireip);
|
|
|
|
wireip += sizeof(DWORD);
|
|
|
|
|
|
|
|
ok(!memcmp(marshal_data, wireip, marshal_size), "buffer mismatch\n");
|
|
|
|
GlobalUnlock(h);
|
|
|
|
zero.QuadPart = 0;
|
|
|
|
IStream_Seek(stm, zero, STREAM_SEEK_SET, NULL);
|
|
|
|
CoReleaseMarshalData(stm);
|
|
|
|
IStream_Release(stm);
|
2007-11-29 12:54:54 +00:00
|
|
|
|
|
|
|
unk2 = NULL;
|
2010-03-10 21:52:40 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, umcb_ctx);
|
2007-11-29 12:54:54 +00:00
|
|
|
WdtpInterfacePointer_UserUnmarshal(&umcb.Flags, buffer, &unk2, &IID_IUnknown);
|
|
|
|
ok(unk2 != NULL, "IUnknown object didn't unmarshal properly\n");
|
|
|
|
HeapFree(GetProcessHeap(), 0, buffer);
|
2009-05-17 07:05:22 +00:00
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_INPROC);
|
2012-12-12 21:02:09 +00:00
|
|
|
IUnknown_Release(unk2);
|
2007-11-29 12:54:54 +00:00
|
|
|
}
|
|
|
|
|
2010-03-10 21:52:40 +00:00
|
|
|
static void test_marshal_WdtpInterfacePointer(void)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* There are two places where we can pass the marshalling ctx: as
|
|
|
|
* part of the umcb and as a separate flag. The loword of that
|
|
|
|
* separate flag field is what matters.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* 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));
|
|
|
|
|
|
|
|
/* 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));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void test_marshal_STGMEDIUM(void)
|
|
|
|
{
|
|
|
|
USER_MARSHAL_CB umcb;
|
|
|
|
MIDL_STUB_MESSAGE stub_msg;
|
|
|
|
RPC_MESSAGE rpc_msg;
|
|
|
|
unsigned char *buffer, *buffer_end, *expect_buffer, *expect_buffer_end;
|
|
|
|
ULONG size, expect_size;
|
|
|
|
STGMEDIUM med, med2;
|
|
|
|
IUnknown *unk = &Test_Unknown;
|
|
|
|
IStream *stm = &Test_Stream;
|
|
|
|
|
|
|
|
/* TYMED_NULL with pUnkForRelease */
|
|
|
|
|
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
expect_size = WdtpInterfacePointer_UserSize(&umcb.Flags, umcb.Flags, 2 * sizeof(DWORD), unk, &IID_IUnknown);
|
|
|
|
expect_buffer = HeapAlloc(GetProcessHeap(), 0, expect_size);
|
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, expect_buffer, expect_size, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
expect_buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, umcb.Flags, expect_buffer + 2 * sizeof(DWORD), unk, &IID_IUnknown);
|
|
|
|
|
|
|
|
med.tymed = TYMED_NULL;
|
|
|
|
U(med).pstg = NULL;
|
|
|
|
med.pUnkForRelease = unk;
|
|
|
|
|
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
size = STGMEDIUM_UserSize(&umcb.Flags, 0, &med);
|
|
|
|
ok(size == expect_size, "size %d should be %d bytes\n", size, expect_size);
|
|
|
|
|
|
|
|
buffer = HeapAlloc(GetProcessHeap(), 0, size);
|
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
buffer_end = STGMEDIUM_UserMarshal(&umcb.Flags, buffer, &med);
|
|
|
|
ok(buffer_end - buffer == expect_buffer_end - expect_buffer, "buffer size mismatch\n");
|
|
|
|
ok(*(DWORD*)buffer == TYMED_NULL, "got %08x\n", *(DWORD*)buffer);
|
|
|
|
ok(*((DWORD*)buffer+1) != 0, "got %08x\n", *((DWORD*)buffer+1));
|
|
|
|
ok(!memcmp(buffer+8, expect_buffer + 8, expect_buffer_end - expect_buffer - 8), "buffer mismatch\n");
|
|
|
|
|
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
|
|
|
|
/* native crashes if this is uninitialised, presumably because it
|
|
|
|
tries to release it */
|
|
|
|
med2.tymed = TYMED_NULL;
|
|
|
|
U(med2).pstm = NULL;
|
|
|
|
med2.pUnkForRelease = NULL;
|
|
|
|
|
|
|
|
STGMEDIUM_UserUnmarshal(&umcb.Flags, buffer, &med2);
|
|
|
|
|
|
|
|
ok(med2.tymed == TYMED_NULL, "got tymed %x\n", med2.tymed);
|
|
|
|
ok(med2.pUnkForRelease != NULL, "Incorrectly unmarshalled\n");
|
|
|
|
|
|
|
|
HeapFree(GetProcessHeap(), 0, buffer);
|
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
STGMEDIUM_UserFree(&umcb.Flags, &med2);
|
|
|
|
|
|
|
|
HeapFree(GetProcessHeap(), 0, expect_buffer);
|
|
|
|
|
|
|
|
/* TYMED_ISTREAM with pUnkForRelease */
|
|
|
|
|
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
expect_size = WdtpInterfacePointer_UserSize(&umcb.Flags, umcb.Flags, 3 * sizeof(DWORD), (IUnknown*)stm, &IID_IStream);
|
|
|
|
expect_size = WdtpInterfacePointer_UserSize(&umcb.Flags, umcb.Flags, expect_size, unk, &IID_IUnknown);
|
|
|
|
|
|
|
|
expect_buffer = HeapAlloc(GetProcessHeap(), 0, expect_size);
|
|
|
|
/* There may be a hole between the two interfaces so init the buffer to something */
|
|
|
|
memset(expect_buffer, 0xcc, expect_size);
|
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, expect_buffer, expect_size, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
expect_buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, umcb.Flags, expect_buffer + 3 * sizeof(DWORD), (IUnknown*)stm, &IID_IStream);
|
|
|
|
expect_buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, umcb.Flags, expect_buffer_end, unk, &IID_IUnknown);
|
|
|
|
|
|
|
|
med.tymed = TYMED_ISTREAM;
|
|
|
|
U(med).pstm = stm;
|
|
|
|
med.pUnkForRelease = unk;
|
|
|
|
|
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
size = STGMEDIUM_UserSize(&umcb.Flags, 0, &med);
|
|
|
|
ok(size == expect_size, "size %d should be %d bytes\n", size, expect_size);
|
|
|
|
|
|
|
|
buffer = HeapAlloc(GetProcessHeap(), 0, size);
|
|
|
|
memset(buffer, 0xcc, size);
|
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
buffer_end = STGMEDIUM_UserMarshal(&umcb.Flags, buffer, &med);
|
|
|
|
ok(buffer_end - buffer == expect_buffer_end - expect_buffer, "buffer size mismatch\n");
|
|
|
|
ok(*(DWORD*)buffer == TYMED_ISTREAM, "got %08x\n", *(DWORD*)buffer);
|
|
|
|
ok(*((DWORD*)buffer+1) != 0, "got %08x\n", *((DWORD*)buffer+1));
|
|
|
|
ok(*((DWORD*)buffer+2) != 0, "got %08x\n", *((DWORD*)buffer+2));
|
|
|
|
ok(!memcmp(buffer + 12, expect_buffer + 12, (buffer_end - buffer) - 12), "buffer mismatch\n");
|
|
|
|
|
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
|
|
|
|
/* native crashes if this is uninitialised, presumably because it
|
|
|
|
tries to release it */
|
|
|
|
med2.tymed = TYMED_NULL;
|
|
|
|
U(med2).pstm = NULL;
|
|
|
|
med2.pUnkForRelease = NULL;
|
|
|
|
|
|
|
|
STGMEDIUM_UserUnmarshal(&umcb.Flags, buffer, &med2);
|
|
|
|
|
|
|
|
ok(med2.tymed == TYMED_ISTREAM, "got tymed %x\n", med2.tymed);
|
|
|
|
ok(U(med2).pstm != NULL, "Incorrectly unmarshalled\n");
|
|
|
|
ok(med2.pUnkForRelease != NULL, "Incorrectly unmarshalled\n");
|
|
|
|
|
|
|
|
HeapFree(GetProcessHeap(), 0, buffer);
|
|
|
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
|
|
|
|
STGMEDIUM_UserFree(&umcb.Flags, &med2);
|
|
|
|
|
|
|
|
HeapFree(GetProcessHeap(), 0, expect_buffer);
|
|
|
|
}
|
|
|
|
|
2007-11-29 12:54:54 +00:00
|
|
|
START_TEST(usrmarshal)
|
|
|
|
{
|
|
|
|
CoInitialize(NULL);
|
|
|
|
|
|
|
|
test_marshal_CLIPFORMAT();
|
|
|
|
test_marshal_HWND();
|
|
|
|
test_marshal_HGLOBAL();
|
|
|
|
test_marshal_HENHMETAFILE();
|
|
|
|
test_marshal_HMETAFILE();
|
|
|
|
test_marshal_HMETAFILEPICT();
|
|
|
|
test_marshal_WdtpInterfacePointer();
|
2010-03-10 21:52:40 +00:00
|
|
|
test_marshal_STGMEDIUM();
|
2007-11-29 12:54:54 +00:00
|
|
|
|
|
|
|
CoUninitialize();
|
|
|
|
}
|