ole32: Fix CLIPFORMAT marshalling on 64-bit platforms by not using the wireCLIPFORMAT...
[wine/multimedia.git] / dlls / ole32 / tests / usrmarshal.c
blobef588ee8f0800ba31f0bb28235cafcaf1eefe9f2
1 /*
2 * User Marshaling Tests
4 * Copyright 2004-2006 Robert Shearman for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
22 #define CONST_VTABLE
23 #include <stdarg.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "objbase.h"
28 #include "objidl.h"
30 #include "wine/test.h"
32 ULONG __RPC_USER HMETAFILE_UserSize(ULONG *, unsigned long, HMETAFILE *);
33 unsigned char * __RPC_USER HMETAFILE_UserMarshal(ULONG *, unsigned char *, HMETAFILE *);
34 unsigned char * __RPC_USER HMETAFILE_UserUnmarshal(ULONG *, unsigned char *, HMETAFILE *);
35 void __RPC_USER HMETAFILE_UserFree(ULONG *, HMETAFILE *);
37 ULONG __RPC_USER HENHMETAFILE_UserSize(ULONG *, ULONG, HENHMETAFILE *);
38 unsigned char * __RPC_USER HENHMETAFILE_UserMarshal (ULONG *, unsigned char *, HENHMETAFILE *);
39 unsigned char * __RPC_USER HENHMETAFILE_UserUnmarshal(ULONG *, unsigned char *, HENHMETAFILE *);
40 void __RPC_USER HENHMETAFILE_UserFree(ULONG *, HENHMETAFILE *);
42 ULONG __RPC_USER HMETAFILEPICT_UserSize(ULONG *, ULONG, HMETAFILEPICT *);
43 unsigned char * __RPC_USER HMETAFILEPICT_UserMarshal (ULONG *, unsigned char *, HMETAFILEPICT *);
44 unsigned char * __RPC_USER HMETAFILEPICT_UserUnmarshal(ULONG *, unsigned char *, HMETAFILEPICT *);
45 void __RPC_USER HMETAFILEPICT_UserFree(ULONG *, HMETAFILEPICT *);
47 static void * WINAPI user_allocate(SIZE_T size)
49 return CoTaskMemAlloc(size);
52 static void WINAPI user_free(void *p)
54 CoTaskMemFree(p);
57 static void init_user_marshal_cb(USER_MARSHAL_CB *umcb,
58 PMIDL_STUB_MESSAGE stub_msg,
59 PRPC_MESSAGE rpc_msg, unsigned char *buffer,
60 unsigned int size, MSHCTX context)
62 memset(rpc_msg, 0, sizeof(*rpc_msg));
63 rpc_msg->Buffer = buffer;
64 rpc_msg->BufferLength = size;
66 memset(stub_msg, 0, sizeof(*stub_msg));
67 stub_msg->RpcMsg = rpc_msg;
68 stub_msg->Buffer = buffer;
69 stub_msg->pfnAllocate = user_allocate;
70 stub_msg->pfnFree = user_free;
72 memset(umcb, 0, sizeof(*umcb));
73 umcb->Flags = MAKELONG(context, NDR_LOCAL_DATA_REPRESENTATION);
74 umcb->pStubMsg = stub_msg;
75 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
76 umcb->CBType = buffer ? USER_MARSHAL_CB_UNMARSHALL : USER_MARSHAL_CB_BUFFER_SIZE;
79 static const char cf_marshaled[] =
81 0x9, 0x0, 0x0, 0x0,
82 0x0, 0x0, 0x0, 0x0,
83 0x9, 0x0, 0x0, 0x0,
84 'M', 0x0, 'y', 0x0,
85 'F', 0x0, 'o', 0x0,
86 'r', 0x0, 'm', 0x0,
87 'a', 0x0, 't', 0x0,
88 0x0, 0x0
91 static void test_marshal_CLIPFORMAT(void)
93 USER_MARSHAL_CB umcb;
94 MIDL_STUB_MESSAGE stub_msg;
95 RPC_MESSAGE rpc_msg;
96 unsigned char *buffer;
97 ULONG size;
98 CLIPFORMAT cf = RegisterClipboardFormatA("MyFormat");
99 CLIPFORMAT cf2;
101 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
102 size = CLIPFORMAT_UserSize(&umcb.Flags, 0, &cf);
103 ok(size == 8 + sizeof(cf_marshaled), "CLIPFORMAT: Wrong size %d\n", size);
105 buffer = HeapAlloc(GetProcessHeap(), 0, size);
106 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
107 CLIPFORMAT_UserMarshal(&umcb.Flags, buffer, &cf);
108 ok(*(LONG *)(buffer + 0) == WDT_REMOTE_CALL, "CLIPFORMAT: Context should be WDT_REMOTE_CALL instead of 0x%08x\n", *(LONG *)(buffer + 0));
109 ok(*(DWORD *)(buffer + 4) == cf, "CLIPFORMAT: Marshaled value should be 0x%04x instead of 0x%04x\n", cf, *(DWORD *)(buffer + 4));
110 ok(!memcmp(buffer + 8, cf_marshaled, sizeof(cf_marshaled)), "Marshaled data differs\n");
112 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
113 CLIPFORMAT_UserUnmarshal(&umcb.Flags, buffer, &cf2);
114 ok(cf == cf2, "CLIPFORMAT: Didn't unmarshal properly\n");
115 HeapFree(GetProcessHeap(), 0, buffer);
117 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
118 CLIPFORMAT_UserFree(&umcb.Flags, &cf2);
121 static void test_marshal_HWND(void)
123 USER_MARSHAL_CB umcb;
124 MIDL_STUB_MESSAGE stub_msg;
125 RPC_MESSAGE rpc_msg;
126 unsigned char *buffer;
127 ULONG size;
128 HWND hwnd = GetDesktopWindow();
129 HWND hwnd2;
130 wireHWND wirehwnd;
132 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
133 size = HWND_UserSize(&umcb.Flags, 0, &hwnd);
134 ok(size == sizeof(*wirehwnd), "Wrong size %d\n", size);
136 buffer = HeapAlloc(GetProcessHeap(), 0, size);
137 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
138 HWND_UserMarshal(&umcb.Flags, buffer, &hwnd);
139 wirehwnd = (wireHWND)buffer;
140 ok(wirehwnd->fContext == WDT_INPROC_CALL, "Context should be WDT_INPROC_CALL instead of 0x%08lx\n", wirehwnd->fContext);
141 ok(wirehwnd->u.hInproc == (LONG_PTR)hwnd, "Marshaled value should be %p instead of %p\n", hwnd, (HANDLE)wirehwnd->u.hRemote);
143 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
144 HWND_UserUnmarshal(&umcb.Flags, buffer, &hwnd2);
145 ok(hwnd == hwnd2, "Didn't unmarshal properly\n");
146 HeapFree(GetProcessHeap(), 0, buffer);
148 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
149 HWND_UserFree(&umcb.Flags, &hwnd2);
152 static void test_marshal_HGLOBAL(void)
154 USER_MARSHAL_CB umcb;
155 MIDL_STUB_MESSAGE stub_msg;
156 RPC_MESSAGE rpc_msg;
157 unsigned char *buffer;
158 ULONG size;
159 HGLOBAL hglobal;
160 HGLOBAL hglobal2;
161 unsigned char *wirehglobal;
162 int i;
164 hglobal = NULL;
165 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
166 size = HGLOBAL_UserSize(&umcb.Flags, 0, &hglobal);
167 /* native is poorly programmed and allocates 4 bytes more than it needs to
168 * here - Wine doesn't have to emulate that */
169 ok((size == 8) || (size == 12), "Size should be 12, instead of %d\n", size);
170 buffer = HeapAlloc(GetProcessHeap(), 0, size);
171 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
172 HGLOBAL_UserMarshal(&umcb.Flags, buffer, &hglobal);
173 wirehglobal = buffer;
174 ok(*(ULONG *)wirehglobal == WDT_REMOTE_CALL, "Context should be WDT_REMOTE_CALL instead of 0x%08x\n", *(ULONG *)wirehglobal);
175 wirehglobal += sizeof(ULONG);
176 ok(*(ULONG *)wirehglobal == (ULONG)hglobal, "buffer+4 should be HGLOBAL\n");
177 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
178 HGLOBAL_UserUnmarshal(&umcb.Flags, buffer, &hglobal2);
179 ok(hglobal2 == hglobal, "Didn't unmarshal properly\n");
180 HeapFree(GetProcessHeap(), 0, buffer);
181 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
182 HGLOBAL_UserFree(&umcb.Flags, &hglobal2);
184 hglobal = GlobalAlloc(0, 4);
185 buffer = GlobalLock(hglobal);
186 for (i = 0; i < 4; i++)
187 buffer[i] = i;
188 GlobalUnlock(hglobal);
189 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
190 size = HGLOBAL_UserSize(&umcb.Flags, 0, &hglobal);
191 /* native is poorly programmed and allocates 4 bytes more than it needs to
192 * here - Wine doesn't have to emulate that */
193 ok((size == 24) || (size == 28), "Size should be 24 or 28, instead of %d\n", size);
194 buffer = HeapAlloc(GetProcessHeap(), 0, size);
195 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
196 HGLOBAL_UserMarshal(&umcb.Flags, buffer, &hglobal);
197 wirehglobal = buffer;
198 ok(*(ULONG *)wirehglobal == WDT_REMOTE_CALL, "Context should be WDT_REMOTE_CALL instead of 0x%08x\n", *(ULONG *)wirehglobal);
199 wirehglobal += sizeof(ULONG);
200 ok(*(ULONG *)wirehglobal == (ULONG)hglobal, "buffer+0x4 should be HGLOBAL\n");
201 wirehglobal += sizeof(ULONG);
202 ok(*(ULONG *)wirehglobal == 4, "buffer+0x8 should be size of HGLOBAL\n");
203 wirehglobal += sizeof(ULONG);
204 ok(*(ULONG *)wirehglobal == (ULONG)hglobal, "buffer+0xc should be HGLOBAL\n");
205 wirehglobal += sizeof(ULONG);
206 ok(*(ULONG *)wirehglobal == 4, "buffer+0x10 should be size of HGLOBAL\n");
207 wirehglobal += sizeof(ULONG);
208 for (i = 0; i < 4; i++)
209 ok(wirehglobal[i] == i, "buffer+0x%x should be %d\n", 0x10 + i, i);
210 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
211 HGLOBAL_UserUnmarshal(&umcb.Flags, buffer, &hglobal2);
212 ok(hglobal2 != NULL, "Didn't unmarshal properly\n");
213 HeapFree(GetProcessHeap(), 0, buffer);
214 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
215 HGLOBAL_UserFree(&umcb.Flags, &hglobal2);
216 GlobalFree(hglobal);
219 static HENHMETAFILE create_emf(void)
221 const RECT rect = {0, 0, 100, 100};
222 HDC hdc = CreateEnhMetaFile(NULL, NULL, &rect, "HENHMETAFILE Marshaling Test\0Test\0\0");
223 ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rect, "Test String", strlen("Test String"), NULL);
224 return CloseEnhMetaFile(hdc);
227 static void test_marshal_HENHMETAFILE(void)
229 USER_MARSHAL_CB umcb;
230 MIDL_STUB_MESSAGE stub_msg;
231 RPC_MESSAGE rpc_msg;
232 unsigned char *buffer;
233 ULONG size;
234 HENHMETAFILE hemf;
235 HENHMETAFILE hemf2 = NULL;
236 unsigned char *wirehemf;
238 hemf = create_emf();
240 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
241 size = HENHMETAFILE_UserSize(&umcb.Flags, 0, &hemf);
242 ok(size > 20, "size should be at least 20 bytes, not %d\n", size);
243 buffer = HeapAlloc(GetProcessHeap(), 0, size);
244 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
245 HENHMETAFILE_UserMarshal(&umcb.Flags, buffer, &hemf);
246 wirehemf = buffer;
247 ok(*(DWORD *)wirehemf == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehemf);
248 wirehemf += sizeof(DWORD);
249 ok(*(DWORD *)wirehemf == (DWORD)(DWORD_PTR)hemf, "wirestgm + 0x4 should be hemf instead of 0x%08x\n", *(DWORD *)wirehemf);
250 wirehemf += sizeof(DWORD);
251 ok(*(DWORD *)wirehemf == (size - 0x10), "wirestgm + 0x8 should be size - 0x10 instead of 0x%08x\n", *(DWORD *)wirehemf);
252 wirehemf += sizeof(DWORD);
253 ok(*(DWORD *)wirehemf == (size - 0x10), "wirestgm + 0xc should be size - 0x10 instead of 0x%08x\n", *(DWORD *)wirehemf);
254 wirehemf += sizeof(DWORD);
255 ok(*(DWORD *)wirehemf == EMR_HEADER, "wirestgm + 0x10 should be EMR_HEADER instead of %d\n", *(DWORD *)wirehemf);
256 wirehemf += sizeof(DWORD);
257 /* ... rest of data not tested - refer to tests for GetEnhMetaFileBits
258 * at this point */
260 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
261 HENHMETAFILE_UserUnmarshal(&umcb.Flags, buffer, &hemf2);
262 ok(hemf2 != NULL, "HENHMETAFILE didn't unmarshal\n");
263 HeapFree(GetProcessHeap(), 0, buffer);
264 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
265 HENHMETAFILE_UserFree(&umcb.Flags, &hemf2);
266 DeleteEnhMetaFile(hemf);
268 /* test NULL emf */
269 hemf = NULL;
271 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
272 size = HENHMETAFILE_UserSize(&umcb.Flags, 0, &hemf);
273 ok(size == 8, "size should be 8 bytes, not %d\n", size);
274 buffer = HeapAlloc(GetProcessHeap(), 0, size);
275 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
276 HENHMETAFILE_UserMarshal(&umcb.Flags, buffer, &hemf);
277 wirehemf = buffer;
278 ok(*(DWORD *)wirehemf == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehemf);
279 wirehemf += sizeof(DWORD);
280 ok(*(DWORD *)wirehemf == (DWORD)(DWORD_PTR)hemf, "wirestgm + 0x4 should be hemf instead of 0x%08x\n", *(DWORD *)wirehemf);
281 wirehemf += sizeof(DWORD);
283 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
284 HENHMETAFILE_UserUnmarshal(&umcb.Flags, buffer, &hemf2);
285 ok(hemf2 == NULL, "NULL HENHMETAFILE didn't unmarshal\n");
286 HeapFree(GetProcessHeap(), 0, buffer);
287 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
288 HENHMETAFILE_UserFree(&umcb.Flags, &hemf2);
291 static HMETAFILE create_mf(void)
293 RECT rect = {0, 0, 100, 100};
294 HDC hdc = CreateMetaFile(NULL);
295 ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rect, "Test String", strlen("Test String"), NULL);
296 return CloseMetaFile(hdc);
299 static void test_marshal_HMETAFILE(void)
301 USER_MARSHAL_CB umcb;
302 MIDL_STUB_MESSAGE stub_msg;
303 RPC_MESSAGE rpc_msg;
304 unsigned char *buffer;
305 ULONG size;
306 HMETAFILE hmf;
307 HMETAFILE hmf2 = NULL;
308 unsigned char *wirehmf;
310 hmf = create_mf();
312 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
313 size = HMETAFILE_UserSize(&umcb.Flags, 0, &hmf);
314 ok(size > 20, "size should be at least 20 bytes, not %d\n", size);
315 buffer = HeapAlloc(GetProcessHeap(), 0, size);
316 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
317 HMETAFILE_UserMarshal(&umcb.Flags, buffer, &hmf);
318 wirehmf = buffer;
319 ok(*(DWORD *)wirehmf == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehmf);
320 wirehmf += sizeof(DWORD);
321 ok(*(DWORD *)wirehmf == (DWORD)(DWORD_PTR)hmf, "wirestgm + 0x4 should be hmf instead of 0x%08x\n", *(DWORD *)wirehmf);
322 wirehmf += sizeof(DWORD);
323 ok(*(DWORD *)wirehmf == (size - 0x10), "wirestgm + 0x8 should be size - 0x10 instead of 0x%08x\n", *(DWORD *)wirehmf);
324 wirehmf += sizeof(DWORD);
325 ok(*(DWORD *)wirehmf == (size - 0x10), "wirestgm + 0xc should be size - 0x10 instead of 0x%08x\n", *(DWORD *)wirehmf);
326 wirehmf += sizeof(DWORD);
327 ok(*(WORD *)wirehmf == 1, "wirestgm + 0x10 should be 1 instead of 0x%08x\n", *(DWORD *)wirehmf);
328 wirehmf += sizeof(DWORD);
329 /* ... rest of data not tested - refer to tests for GetMetaFileBits
330 * at this point */
332 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
333 HMETAFILE_UserUnmarshal(&umcb.Flags, buffer, &hmf2);
334 ok(hmf2 != NULL, "HMETAFILE didn't unmarshal\n");
335 HeapFree(GetProcessHeap(), 0, buffer);
336 HMETAFILE_UserFree(&umcb.Flags, &hmf2);
337 DeleteMetaFile(hmf);
339 /* test NULL emf */
340 hmf = NULL;
342 size = HMETAFILE_UserSize(&umcb.Flags, 0, &hmf);
343 ok(size == 8, "size should be 8 bytes, not %d\n", size);
344 buffer = HeapAlloc(GetProcessHeap(), 0, size);
345 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
346 HMETAFILE_UserMarshal(&umcb.Flags, buffer, &hmf);
347 wirehmf = buffer;
348 ok(*(DWORD *)wirehmf == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehmf);
349 wirehmf += sizeof(DWORD);
350 ok(*(DWORD *)wirehmf == (DWORD)(DWORD_PTR)hmf, "wirestgm + 0x4 should be hmf instead of 0x%08x\n", *(DWORD *)wirehmf);
351 wirehmf += sizeof(DWORD);
353 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
354 HMETAFILE_UserUnmarshal(&umcb.Flags, buffer, &hmf2);
355 ok(hmf2 == NULL, "NULL HMETAFILE didn't unmarshal\n");
356 HeapFree(GetProcessHeap(), 0, buffer);
357 HMETAFILE_UserFree(&umcb.Flags, &hmf2);
360 #define USER_MARSHAL_PTR_PREFIX \
361 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
362 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
364 static void test_marshal_HMETAFILEPICT(void)
366 USER_MARSHAL_CB umcb;
367 MIDL_STUB_MESSAGE stub_msg;
368 RPC_MESSAGE rpc_msg;
369 unsigned char *buffer, *buffer_end;
370 ULONG size;
371 HMETAFILEPICT hmfp;
372 HMETAFILEPICT hmfp2 = NULL;
373 METAFILEPICT *pmfp;
374 unsigned char *wirehmfp;
376 hmfp = GlobalAlloc(GMEM_MOVEABLE, sizeof(*pmfp));
377 pmfp = GlobalLock(hmfp);
378 pmfp->mm = MM_ISOTROPIC;
379 pmfp->xExt = 1;
380 pmfp->yExt = 2;
381 pmfp->hMF = create_mf();
382 GlobalUnlock(hmfp);
384 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
385 size = HMETAFILEPICT_UserSize(&umcb.Flags, 0, &hmfp);
386 ok(size > 20, "size should be at least 20 bytes, not %d\n", size);
387 trace("size is %d\n", size);
388 buffer = HeapAlloc(GetProcessHeap(), 0, size);
389 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
390 buffer_end = HMETAFILEPICT_UserMarshal(&umcb.Flags, buffer, &hmfp);
391 wirehmfp = buffer;
392 ok(*(DWORD *)wirehmfp == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehmfp);
393 wirehmfp += sizeof(DWORD);
394 ok(*(DWORD *)wirehmfp == (DWORD)(DWORD_PTR)hmfp, "wirestgm + 0x4 should be hmf instead of 0x%08x\n", *(DWORD *)wirehmfp);
395 wirehmfp += sizeof(DWORD);
396 ok(*(DWORD *)wirehmfp == MM_ISOTROPIC, "wirestgm + 0x8 should be MM_ISOTROPIC instead of 0x%08x\n", *(DWORD *)wirehmfp);
397 wirehmfp += sizeof(DWORD);
398 ok(*(DWORD *)wirehmfp == 1, "wirestgm + 0xc should be 1 instead of 0x%08x\n", *(DWORD *)wirehmfp);
399 wirehmfp += sizeof(DWORD);
400 ok(*(DWORD *)wirehmfp == 2, "wirestgm + 0x10 should be 2 instead of 0x%08x\n", *(DWORD *)wirehmfp);
401 wirehmfp += sizeof(DWORD);
402 ok(*(DWORD *)wirehmfp == USER_MARSHAL_PTR_PREFIX, "wirestgm + 0x14 should be \"User\" instead of 0x%08x\n", *(DWORD *)wirehmfp);
403 wirehmfp += sizeof(DWORD);
404 ok(*(DWORD *)wirehmfp == WDT_REMOTE_CALL, "wirestgm + 0x18 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehmfp);
405 wirehmfp += sizeof(DWORD);
406 pmfp = GlobalLock(hmfp);
407 ok(*(DWORD *)wirehmfp == (DWORD)(DWORD_PTR)pmfp->hMF, "wirestgm + 0x1c should be pmfp->hMF instead of 0x%08x\n", *(DWORD *)wirehmfp);
408 GlobalUnlock(hmfp);
409 wirehmfp += sizeof(DWORD);
410 /* Note use (buffer_end - buffer) instead of size here, because size is an
411 * overestimate with native */
412 ok(*(DWORD *)wirehmfp == (buffer_end - buffer - 0x28), "wirestgm + 0x20 should be size - 0x34 instead of 0x%08x\n", *(DWORD *)wirehmfp);
413 wirehmfp += sizeof(DWORD);
414 ok(*(DWORD *)wirehmfp == (buffer_end - buffer - 0x28), "wirestgm + 0x24 should be size - 0x34 instead of 0x%08x\n", *(DWORD *)wirehmfp);
415 wirehmfp += sizeof(DWORD);
416 ok(*(WORD *)wirehmfp == 1, "wirehmfp + 0x28 should be 1 instead of 0x%08x\n", *(DWORD *)wirehmfp);
417 wirehmfp += sizeof(DWORD);
418 /* ... rest of data not tested - refer to tests for GetMetaFileBits
419 * at this point */
421 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
422 HMETAFILEPICT_UserUnmarshal(&umcb.Flags, buffer, &hmfp2);
423 ok(hmfp2 != NULL, "HMETAFILEPICT didn't unmarshal\n");
424 HeapFree(GetProcessHeap(), 0, buffer);
425 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
426 HMETAFILEPICT_UserFree(&umcb.Flags, &hmfp2);
427 pmfp = GlobalLock(hmfp);
428 DeleteMetaFile(pmfp->hMF);
429 GlobalUnlock(hmfp);
430 GlobalFree(hmfp);
432 /* test NULL emf */
433 hmfp = NULL;
435 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
436 size = HMETAFILEPICT_UserSize(&umcb.Flags, 0, &hmfp);
437 ok(size == 8, "size should be 8 bytes, not %d\n", size);
438 buffer = HeapAlloc(GetProcessHeap(), 0, size);
439 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
440 HMETAFILEPICT_UserMarshal(&umcb.Flags, buffer, &hmfp);
441 wirehmfp = buffer;
442 ok(*(DWORD *)wirehmfp == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehmfp);
443 wirehmfp += sizeof(DWORD);
444 ok(*(DWORD *)wirehmfp == (DWORD)(DWORD_PTR)hmfp, "wirestgm + 0x4 should be hmf instead of 0x%08x\n", *(DWORD *)wirehmfp);
445 wirehmfp += sizeof(DWORD);
447 hmfp2 = NULL;
448 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
449 HMETAFILEPICT_UserUnmarshal(&umcb.Flags, buffer, &hmfp2);
450 ok(hmfp2 == NULL, "NULL HMETAFILE didn't unmarshal\n");
451 HeapFree(GetProcessHeap(), 0, buffer);
452 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
453 HMETAFILEPICT_UserFree(&umcb.Flags, &hmfp2);
456 static HRESULT WINAPI Test_IUnknown_QueryInterface(
457 LPUNKNOWN iface,
458 REFIID riid,
459 LPVOID *ppvObj)
461 if (ppvObj == NULL) return E_POINTER;
463 if (IsEqualGUID(riid, &IID_IUnknown))
465 *ppvObj = iface;
466 IUnknown_AddRef(iface);
467 return S_OK;
470 *ppvObj = NULL;
471 return E_NOINTERFACE;
474 static ULONG WINAPI Test_IUnknown_AddRef(LPUNKNOWN iface)
476 return 2; /* non-heap-based object */
479 static ULONG WINAPI Test_IUnknown_Release(LPUNKNOWN iface)
481 return 1; /* non-heap-based object */
484 static const IUnknownVtbl TestUnknown_Vtbl =
486 Test_IUnknown_QueryInterface,
487 Test_IUnknown_AddRef,
488 Test_IUnknown_Release,
491 static IUnknown Test_Unknown = { &TestUnknown_Vtbl };
493 ULONG __RPC_USER WdtpInterfacePointer_UserSize(ULONG *, ULONG, ULONG, IUnknown *, REFIID);
494 unsigned char * __RPC_USER WdtpInterfacePointer_UserMarshal(ULONG *, ULONG, unsigned char *, IUnknown *, REFIID);
495 unsigned char * __RPC_USER WdtpInterfacePointer_UserUnmarshal(ULONG *, unsigned char *, IUnknown **, REFIID);
496 void __RPC_USER WdtpInterfacePointer_UserFree(IUnknown *);
498 static void test_marshal_WdtpInterfacePointer(void)
500 USER_MARSHAL_CB umcb;
501 MIDL_STUB_MESSAGE stub_msg;
502 RPC_MESSAGE rpc_msg;
503 unsigned char *buffer, *buffer_end;
504 ULONG size;
505 IUnknown *unk;
506 IUnknown *unk2;
507 unsigned char *wireip;
508 const IID *iid;
510 /* shows that the WdtpInterfacePointer functions don't marshal anything for
511 * NULL pointers, so code using these functions must handle that case
512 * itself */
513 unk = NULL;
514 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_INPROC);
515 size = WdtpInterfacePointer_UserSize(&umcb.Flags, umcb.Flags, 0, unk, &IID_IUnknown);
516 ok(size == 0, "size should be 0 bytes, not %d\n", size);
517 buffer = HeapAlloc(GetProcessHeap(), 0, size);
518 buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, umcb.Flags, buffer, unk, &IID_IUnknown);
519 wireip = buffer;
520 HeapFree(GetProcessHeap(), 0, buffer);
522 unk = &Test_Unknown;
523 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_INPROC);
524 size = WdtpInterfacePointer_UserSize(&umcb.Flags, umcb.Flags, 0, unk, &IID_IUnknown);
525 todo_wine
526 ok(size > 28, "size should be > 28 bytes, not %d\n", size);
527 trace("WdtpInterfacePointer_UserSize returned %d\n", size);
528 buffer = HeapAlloc(GetProcessHeap(), 0, size);
529 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_INPROC);
530 buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, umcb.Flags, buffer, unk, &IID_IUnknown);
531 wireip = buffer;
532 if (size >= 28)
534 ok(*(DWORD *)wireip == 0x44, "wireip + 0x0 should be 0x44 instead of 0x%08x\n", *(DWORD *)wireip);
535 wireip += sizeof(DWORD);
536 ok(*(DWORD *)wireip == 0x44, "wireip + 0x4 should be 0x44 instead of 0x%08x\n", *(DWORD *)wireip);
537 wireip += sizeof(DWORD);
538 ok(*(DWORD *)wireip == 0x574f454d /* 'MEOW' */, "wireip + 0x8 should be 0x574f454d instead of 0x%08x\n", *(DWORD *)wireip);
539 wireip += sizeof(DWORD);
540 ok(*(DWORD *)wireip == 0x1, "wireip + 0xc should be 0x1 instead of 0x%08x\n", *(DWORD *)wireip);
541 wireip += sizeof(DWORD);
542 iid = (const IID *)wireip;
543 ok(IsEqualIID(iid, &IID_IUnknown),
544 "wireip + 0x10 should be IID_IUnknown instead of {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
545 iid->Data1, iid->Data2, iid->Data3,
546 iid->Data4[0], iid->Data4[1], iid->Data4[2], iid->Data4[3],
547 iid->Data4[4], iid->Data4[5], iid->Data4[6], iid->Data4[7]);
548 wireip += sizeof(IID);
549 ok(*(DWORD *)wireip == 0, "wireip + 0x1c should be 0 instead of 0x%08x\n", *(DWORD *)wireip);
550 wireip += sizeof(DWORD);
551 ok(*(DWORD *)wireip == 5, "wireip + 0x20 should be 5 instead of %d\n", *(DWORD *)wireip);
552 wireip += sizeof(DWORD);
553 /* the rest is dynamic so can't really be tested */
556 unk2 = NULL;
557 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_INPROC);
558 WdtpInterfacePointer_UserUnmarshal(&umcb.Flags, buffer, &unk2, &IID_IUnknown);
559 todo_wine
560 ok(unk2 != NULL, "IUnknown object didn't unmarshal properly\n");
561 HeapFree(GetProcessHeap(), 0, buffer);
562 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_INPROC);
563 WdtpInterfacePointer_UserFree(unk2);
566 START_TEST(usrmarshal)
568 CoInitialize(NULL);
570 test_marshal_CLIPFORMAT();
571 test_marshal_HWND();
572 test_marshal_HGLOBAL();
573 test_marshal_HENHMETAFILE();
574 test_marshal_HMETAFILE();
575 test_marshal_HMETAFILEPICT();
576 test_marshal_WdtpInterfacePointer();
578 CoUninitialize();