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
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)
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[] =
91 static void test_marshal_CLIPFORMAT(void)
94 MIDL_STUB_MESSAGE stub_msg;
96 unsigned char *buffer;
98 CLIPFORMAT cf = RegisterClipboardFormatA("MyFormat");
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) ||
104 broken(size == 8 + sizeof(cf_marshaled) - 2), /* win9x and winnt don't include the '\0' */
105 "CLIPFORMAT: Wrong size %d\n", size);
107 buffer = HeapAlloc(GetProcessHeap(), 0, size);
108 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
109 CLIPFORMAT_UserMarshal(&umcb.Flags, buffer, &cf);
110 ok(*(LONG *)(buffer + 0) == WDT_REMOTE_CALL, "CLIPFORMAT: Context should be WDT_REMOTE_CALL instead of 0x%08x\n", *(LONG *)(buffer + 0));
111 ok(*(DWORD *)(buffer + 4) == cf, "CLIPFORMAT: Marshaled value should be 0x%04x instead of 0x%04x\n", cf, *(DWORD *)(buffer + 4));
112 ok(!memcmp(buffer + 8, cf_marshaled, size - 8), "Marshaled data differs\n");
114 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
115 CLIPFORMAT_UserUnmarshal(&umcb.Flags, buffer, &cf2);
116 ok(cf == cf2, "CLIPFORMAT: Didn't unmarshal properly\n");
117 HeapFree(GetProcessHeap(), 0, buffer);
119 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
120 CLIPFORMAT_UserFree(&umcb.Flags, &cf2);
123 static void test_marshal_HWND(void)
125 USER_MARSHAL_CB umcb;
126 MIDL_STUB_MESSAGE stub_msg;
128 unsigned char *buffer;
130 HWND hwnd = GetDesktopWindow();
134 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
135 size = HWND_UserSize(&umcb.Flags, 0, &hwnd);
136 ok(size == sizeof(*wirehwnd), "Wrong size %d\n", size);
138 buffer = HeapAlloc(GetProcessHeap(), 0, size);
139 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
140 HWND_UserMarshal(&umcb.Flags, buffer, &hwnd);
141 wirehwnd = (wireHWND)buffer;
142 ok(wirehwnd->fContext == WDT_INPROC_CALL, "Context should be WDT_INPROC_CALL instead of 0x%08x\n", wirehwnd->fContext);
143 ok(wirehwnd->u.hInproc == (LONG_PTR)hwnd, "Marshaled value should be %p instead of %p\n", hwnd, (HANDLE)wirehwnd->u.hRemote);
145 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
146 HWND_UserUnmarshal(&umcb.Flags, buffer, &hwnd2);
147 ok(hwnd == hwnd2, "Didn't unmarshal properly\n");
148 HeapFree(GetProcessHeap(), 0, buffer);
150 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
151 HWND_UserFree(&umcb.Flags, &hwnd2);
154 static void test_marshal_HGLOBAL(void)
156 USER_MARSHAL_CB umcb;
157 MIDL_STUB_MESSAGE stub_msg;
159 unsigned char *buffer;
163 unsigned char *wirehglobal;
167 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
168 size = HGLOBAL_UserSize(&umcb.Flags, 0, &hglobal);
169 /* native is poorly programmed and allocates 4/8 bytes more than it needs to
170 * here - Wine doesn't have to emulate that */
171 ok((size == 8) || broken(size == 12) || broken(size == 16), "Size should be 8, instead of %d\n", size);
172 buffer = HeapAlloc(GetProcessHeap(), 0, size);
173 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
174 HGLOBAL_UserMarshal(&umcb.Flags, buffer, &hglobal);
175 wirehglobal = buffer;
176 ok(*(ULONG *)wirehglobal == WDT_REMOTE_CALL, "Context should be WDT_REMOTE_CALL instead of 0x%08x\n", *(ULONG *)wirehglobal);
177 wirehglobal += sizeof(ULONG);
178 ok(*(ULONG *)wirehglobal == 0, "buffer+4 should be HGLOBAL\n");
179 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
180 HGLOBAL_UserUnmarshal(&umcb.Flags, buffer, &hglobal2);
181 ok(hglobal2 == hglobal, "Didn't unmarshal properly\n");
182 HeapFree(GetProcessHeap(), 0, buffer);
183 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
184 HGLOBAL_UserFree(&umcb.Flags, &hglobal2);
186 hglobal = GlobalAlloc(0, 4);
187 buffer = GlobalLock(hglobal);
188 for (i = 0; i < 4; i++)
190 GlobalUnlock(hglobal);
191 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
192 size = HGLOBAL_UserSize(&umcb.Flags, 0, &hglobal);
193 /* native is poorly programmed and allocates 4/8 bytes more than it needs to
194 * here - Wine doesn't have to emulate that */
195 ok((size == 24) || broken(size == 28) || broken(size == 32), "Size should be 24, instead of %d\n", size);
196 buffer = HeapAlloc(GetProcessHeap(), 0, size);
197 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
198 HGLOBAL_UserMarshal(&umcb.Flags, buffer, &hglobal);
199 wirehglobal = buffer;
200 ok(*(ULONG *)wirehglobal == WDT_REMOTE_CALL, "Context should be WDT_REMOTE_CALL instead of 0x%08x\n", *(ULONG *)wirehglobal);
201 wirehglobal += sizeof(ULONG);
202 ok(*(ULONG *)wirehglobal == (ULONG)(ULONG_PTR)hglobal, "buffer+0x4 should be HGLOBAL\n");
203 wirehglobal += sizeof(ULONG);
204 ok(*(ULONG *)wirehglobal == 4, "buffer+0x8 should be size of HGLOBAL instead of %d\n", *(ULONG *)wirehglobal);
205 wirehglobal += sizeof(ULONG);
206 ok(*(ULONG *)wirehglobal == (ULONG)(ULONG_PTR)hglobal, "buffer+0xc should be HGLOBAL\n");
207 wirehglobal += sizeof(ULONG);
208 ok(*(ULONG *)wirehglobal == 4, "buffer+0x10 should be size of HGLOBAL instead of %d\n", *(ULONG *)wirehglobal);
209 wirehglobal += sizeof(ULONG);
210 for (i = 0; i < 4; i++)
211 ok(wirehglobal[i] == i, "buffer+0x%x should be %d\n", 0x10 + i, i);
212 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
213 HGLOBAL_UserUnmarshal(&umcb.Flags, buffer, &hglobal2);
214 ok(hglobal2 != NULL, "Didn't unmarshal properly\n");
215 HeapFree(GetProcessHeap(), 0, buffer);
216 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
217 HGLOBAL_UserFree(&umcb.Flags, &hglobal2);
221 static HENHMETAFILE create_emf(void)
223 const RECT rect = {0, 0, 100, 100};
224 HDC hdc = CreateEnhMetaFile(NULL, NULL, &rect, "HENHMETAFILE Marshaling Test\0Test\0\0");
225 ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rect, "Test String", strlen("Test String"), NULL);
226 return CloseEnhMetaFile(hdc);
229 static void test_marshal_HENHMETAFILE(void)
231 USER_MARSHAL_CB umcb;
232 MIDL_STUB_MESSAGE stub_msg;
234 unsigned char *buffer;
237 HENHMETAFILE hemf2 = NULL;
238 unsigned char *wirehemf;
242 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
243 size = HENHMETAFILE_UserSize(&umcb.Flags, 0, &hemf);
244 ok(size > 20, "size should be at least 20 bytes, not %d\n", size);
245 buffer = HeapAlloc(GetProcessHeap(), 0, size);
246 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
247 HENHMETAFILE_UserMarshal(&umcb.Flags, buffer, &hemf);
249 ok(*(DWORD *)wirehemf == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehemf);
250 wirehemf += sizeof(DWORD);
251 ok(*(DWORD *)wirehemf == (DWORD)(DWORD_PTR)hemf, "wirestgm + 0x4 should be hemf instead of 0x%08x\n", *(DWORD *)wirehemf);
252 wirehemf += sizeof(DWORD);
253 ok(*(DWORD *)wirehemf == (size - 0x10), "wirestgm + 0x8 should be size - 0x10 instead of 0x%08x\n", *(DWORD *)wirehemf);
254 wirehemf += sizeof(DWORD);
255 ok(*(DWORD *)wirehemf == (size - 0x10), "wirestgm + 0xc should be size - 0x10 instead of 0x%08x\n", *(DWORD *)wirehemf);
256 wirehemf += sizeof(DWORD);
257 ok(*(DWORD *)wirehemf == EMR_HEADER, "wirestgm + 0x10 should be EMR_HEADER instead of %d\n", *(DWORD *)wirehemf);
258 wirehemf += sizeof(DWORD);
259 /* ... rest of data not tested - refer to tests for GetEnhMetaFileBits
262 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
263 HENHMETAFILE_UserUnmarshal(&umcb.Flags, buffer, &hemf2);
264 ok(hemf2 != NULL, "HENHMETAFILE didn't unmarshal\n");
265 HeapFree(GetProcessHeap(), 0, buffer);
266 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
267 HENHMETAFILE_UserFree(&umcb.Flags, &hemf2);
268 DeleteEnhMetaFile(hemf);
273 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
274 size = HENHMETAFILE_UserSize(&umcb.Flags, 0, &hemf);
275 ok(size == 8, "size should be 8 bytes, not %d\n", size);
276 buffer = HeapAlloc(GetProcessHeap(), 0, size);
277 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
278 HENHMETAFILE_UserMarshal(&umcb.Flags, buffer, &hemf);
280 ok(*(DWORD *)wirehemf == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehemf);
281 wirehemf += sizeof(DWORD);
282 ok(*(DWORD *)wirehemf == (DWORD)(DWORD_PTR)hemf, "wirestgm + 0x4 should be hemf instead of 0x%08x\n", *(DWORD *)wirehemf);
283 wirehemf += sizeof(DWORD);
285 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
286 HENHMETAFILE_UserUnmarshal(&umcb.Flags, buffer, &hemf2);
287 ok(hemf2 == NULL, "NULL HENHMETAFILE didn't unmarshal\n");
288 HeapFree(GetProcessHeap(), 0, buffer);
289 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
290 HENHMETAFILE_UserFree(&umcb.Flags, &hemf2);
293 static HMETAFILE create_mf(void)
295 RECT rect = {0, 0, 100, 100};
296 HDC hdc = CreateMetaFile(NULL);
297 ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rect, "Test String", strlen("Test String"), NULL);
298 return CloseMetaFile(hdc);
301 static void test_marshal_HMETAFILE(void)
303 USER_MARSHAL_CB umcb;
304 MIDL_STUB_MESSAGE stub_msg;
306 unsigned char *buffer;
309 HMETAFILE hmf2 = NULL;
310 unsigned char *wirehmf;
314 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
315 size = HMETAFILE_UserSize(&umcb.Flags, 0, &hmf);
316 ok(size > 20, "size should be at least 20 bytes, not %d\n", size);
317 buffer = HeapAlloc(GetProcessHeap(), 0, size);
318 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
319 HMETAFILE_UserMarshal(&umcb.Flags, buffer, &hmf);
321 ok(*(DWORD *)wirehmf == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehmf);
322 wirehmf += sizeof(DWORD);
323 ok(*(DWORD *)wirehmf == (DWORD)(DWORD_PTR)hmf, "wirestgm + 0x4 should be hmf instead of 0x%08x\n", *(DWORD *)wirehmf);
324 wirehmf += sizeof(DWORD);
325 ok(*(DWORD *)wirehmf == (size - 0x10), "wirestgm + 0x8 should be size - 0x10 instead of 0x%08x\n", *(DWORD *)wirehmf);
326 wirehmf += sizeof(DWORD);
327 ok(*(DWORD *)wirehmf == (size - 0x10), "wirestgm + 0xc should be size - 0x10 instead of 0x%08x\n", *(DWORD *)wirehmf);
328 wirehmf += sizeof(DWORD);
329 ok(*(WORD *)wirehmf == 1, "wirestgm + 0x10 should be 1 instead of 0x%08x\n", *(DWORD *)wirehmf);
330 wirehmf += sizeof(DWORD);
331 /* ... rest of data not tested - refer to tests for GetMetaFileBits
334 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
335 HMETAFILE_UserUnmarshal(&umcb.Flags, buffer, &hmf2);
336 ok(hmf2 != NULL, "HMETAFILE didn't unmarshal\n");
337 HeapFree(GetProcessHeap(), 0, buffer);
338 HMETAFILE_UserFree(&umcb.Flags, &hmf2);
344 size = HMETAFILE_UserSize(&umcb.Flags, 0, &hmf);
345 ok(size == 8, "size should be 8 bytes, not %d\n", size);
346 buffer = HeapAlloc(GetProcessHeap(), 0, size);
347 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
348 HMETAFILE_UserMarshal(&umcb.Flags, buffer, &hmf);
350 ok(*(DWORD *)wirehmf == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehmf);
351 wirehmf += sizeof(DWORD);
352 ok(*(DWORD *)wirehmf == (DWORD)(DWORD_PTR)hmf, "wirestgm + 0x4 should be hmf instead of 0x%08x\n", *(DWORD *)wirehmf);
353 wirehmf += sizeof(DWORD);
355 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
356 HMETAFILE_UserUnmarshal(&umcb.Flags, buffer, &hmf2);
357 ok(hmf2 == NULL, "NULL HMETAFILE didn't unmarshal\n");
358 HeapFree(GetProcessHeap(), 0, buffer);
359 HMETAFILE_UserFree(&umcb.Flags, &hmf2);
362 #define USER_MARSHAL_PTR_PREFIX \
363 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
364 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
366 static void test_marshal_HMETAFILEPICT(void)
368 USER_MARSHAL_CB umcb;
369 MIDL_STUB_MESSAGE stub_msg;
371 unsigned char *buffer, *buffer_end;
374 HMETAFILEPICT hmfp2 = NULL;
376 unsigned char *wirehmfp;
378 hmfp = GlobalAlloc(GMEM_MOVEABLE, sizeof(*pmfp));
379 pmfp = GlobalLock(hmfp);
380 pmfp->mm = MM_ISOTROPIC;
383 pmfp->hMF = create_mf();
386 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
387 size = HMETAFILEPICT_UserSize(&umcb.Flags, 0, &hmfp);
388 ok(size > 20, "size should be at least 20 bytes, not %d\n", size);
389 trace("size is %d\n", size);
390 buffer = HeapAlloc(GetProcessHeap(), 0, size);
391 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
392 buffer_end = HMETAFILEPICT_UserMarshal(&umcb.Flags, buffer, &hmfp);
394 ok(*(DWORD *)wirehmfp == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehmfp);
395 wirehmfp += sizeof(DWORD);
396 ok(*(DWORD *)wirehmfp == (DWORD)(DWORD_PTR)hmfp, "wirestgm + 0x4 should be hmf instead of 0x%08x\n", *(DWORD *)wirehmfp);
397 wirehmfp += sizeof(DWORD);
398 ok(*(DWORD *)wirehmfp == MM_ISOTROPIC, "wirestgm + 0x8 should be MM_ISOTROPIC instead of 0x%08x\n", *(DWORD *)wirehmfp);
399 wirehmfp += sizeof(DWORD);
400 ok(*(DWORD *)wirehmfp == 1, "wirestgm + 0xc should be 1 instead of 0x%08x\n", *(DWORD *)wirehmfp);
401 wirehmfp += sizeof(DWORD);
402 ok(*(DWORD *)wirehmfp == 2, "wirestgm + 0x10 should be 2 instead of 0x%08x\n", *(DWORD *)wirehmfp);
403 wirehmfp += sizeof(DWORD);
404 ok(*(DWORD *)wirehmfp == USER_MARSHAL_PTR_PREFIX, "wirestgm + 0x14 should be \"User\" instead of 0x%08x\n", *(DWORD *)wirehmfp);
405 wirehmfp += sizeof(DWORD);
406 ok(*(DWORD *)wirehmfp == WDT_REMOTE_CALL, "wirestgm + 0x18 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehmfp);
407 wirehmfp += sizeof(DWORD);
408 pmfp = GlobalLock(hmfp);
409 ok(*(DWORD *)wirehmfp == (DWORD)(DWORD_PTR)pmfp->hMF, "wirestgm + 0x1c should be pmfp->hMF instead of 0x%08x\n", *(DWORD *)wirehmfp);
411 wirehmfp += sizeof(DWORD);
412 /* Note use (buffer_end - buffer) instead of size here, because size is an
413 * overestimate with native */
414 ok(*(DWORD *)wirehmfp == (buffer_end - buffer - 0x28), "wirestgm + 0x20 should be size - 0x34 instead of 0x%08x\n", *(DWORD *)wirehmfp);
415 wirehmfp += sizeof(DWORD);
416 ok(*(DWORD *)wirehmfp == (buffer_end - buffer - 0x28), "wirestgm + 0x24 should be size - 0x34 instead of 0x%08x\n", *(DWORD *)wirehmfp);
417 wirehmfp += sizeof(DWORD);
418 ok(*(WORD *)wirehmfp == 1, "wirehmfp + 0x28 should be 1 instead of 0x%08x\n", *(DWORD *)wirehmfp);
419 wirehmfp += sizeof(DWORD);
420 /* ... rest of data not tested - refer to tests for GetMetaFileBits
423 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
424 HMETAFILEPICT_UserUnmarshal(&umcb.Flags, buffer, &hmfp2);
425 ok(hmfp2 != NULL, "HMETAFILEPICT didn't unmarshal\n");
426 HeapFree(GetProcessHeap(), 0, buffer);
427 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
428 HMETAFILEPICT_UserFree(&umcb.Flags, &hmfp2);
429 pmfp = GlobalLock(hmfp);
430 DeleteMetaFile(pmfp->hMF);
437 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
438 size = HMETAFILEPICT_UserSize(&umcb.Flags, 0, &hmfp);
439 ok(size == 8, "size should be 8 bytes, not %d\n", size);
440 buffer = HeapAlloc(GetProcessHeap(), 0, size);
441 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
442 HMETAFILEPICT_UserMarshal(&umcb.Flags, buffer, &hmfp);
444 ok(*(DWORD *)wirehmfp == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehmfp);
445 wirehmfp += sizeof(DWORD);
446 ok(*(DWORD *)wirehmfp == (DWORD)(DWORD_PTR)hmfp, "wirestgm + 0x4 should be hmf instead of 0x%08x\n", *(DWORD *)wirehmfp);
447 wirehmfp += sizeof(DWORD);
450 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
451 HMETAFILEPICT_UserUnmarshal(&umcb.Flags, buffer, &hmfp2);
452 ok(hmfp2 == NULL, "NULL HMETAFILE didn't unmarshal\n");
453 HeapFree(GetProcessHeap(), 0, buffer);
454 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
455 HMETAFILEPICT_UserFree(&umcb.Flags, &hmfp2);
458 static HRESULT WINAPI Test_IUnknown_QueryInterface(
463 if (ppvObj == NULL) return E_POINTER;
465 if (IsEqualGUID(riid, &IID_IUnknown))
468 IUnknown_AddRef(iface);
473 return E_NOINTERFACE;
476 static ULONG WINAPI Test_IUnknown_AddRef(LPUNKNOWN iface)
478 return 2; /* non-heap-based object */
481 static ULONG WINAPI Test_IUnknown_Release(LPUNKNOWN iface)
483 return 1; /* non-heap-based object */
486 static const IUnknownVtbl TestUnknown_Vtbl =
488 Test_IUnknown_QueryInterface,
489 Test_IUnknown_AddRef,
490 Test_IUnknown_Release,
493 static IUnknown Test_Unknown = { &TestUnknown_Vtbl };
495 ULONG __RPC_USER WdtpInterfacePointer_UserSize(ULONG *, ULONG, ULONG, IUnknown *, REFIID);
496 unsigned char * __RPC_USER WdtpInterfacePointer_UserMarshal(ULONG *, ULONG, unsigned char *, IUnknown *, REFIID);
497 unsigned char * __RPC_USER WdtpInterfacePointer_UserUnmarshal(ULONG *, unsigned char *, IUnknown **, REFIID);
498 void __RPC_USER WdtpInterfacePointer_UserFree(IUnknown *);
500 static void test_marshal_WdtpInterfacePointer(void)
502 USER_MARSHAL_CB umcb;
503 MIDL_STUB_MESSAGE stub_msg;
505 unsigned char *buffer, *buffer_end;
509 unsigned char *wireip;
512 /* shows that the WdtpInterfacePointer functions don't marshal anything for
513 * NULL pointers, so code using these functions must handle that case
516 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_INPROC);
517 size = WdtpInterfacePointer_UserSize(&umcb.Flags, umcb.Flags, 0, unk, &IID_IUnknown);
518 ok(size == 0, "size should be 0 bytes, not %d\n", size);
519 buffer = HeapAlloc(GetProcessHeap(), 0, size);
520 buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, umcb.Flags, buffer, unk, &IID_IUnknown);
522 HeapFree(GetProcessHeap(), 0, buffer);
525 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_INPROC);
526 size = WdtpInterfacePointer_UserSize(&umcb.Flags, umcb.Flags, 0, unk, &IID_IUnknown);
528 ok(size > 28, "size should be > 28 bytes, not %d\n", size);
529 trace("WdtpInterfacePointer_UserSize returned %d\n", size);
530 buffer = HeapAlloc(GetProcessHeap(), 0, size);
531 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_INPROC);
532 buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, umcb.Flags, buffer, unk, &IID_IUnknown);
536 ok(*(DWORD *)wireip == 0x44, "wireip + 0x0 should be 0x44 instead of 0x%08x\n", *(DWORD *)wireip);
537 wireip += sizeof(DWORD);
538 ok(*(DWORD *)wireip == 0x44, "wireip + 0x4 should be 0x44 instead of 0x%08x\n", *(DWORD *)wireip);
539 wireip += sizeof(DWORD);
540 ok(*(DWORD *)wireip == 0x574f454d /* 'MEOW' */, "wireip + 0x8 should be 0x574f454d instead of 0x%08x\n", *(DWORD *)wireip);
541 wireip += sizeof(DWORD);
542 ok(*(DWORD *)wireip == 0x1, "wireip + 0xc should be 0x1 instead of 0x%08x\n", *(DWORD *)wireip);
543 wireip += sizeof(DWORD);
544 iid = (const IID *)wireip;
545 ok(IsEqualIID(iid, &IID_IUnknown),
546 "wireip + 0x10 should be IID_IUnknown instead of {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
547 iid->Data1, iid->Data2, iid->Data3,
548 iid->Data4[0], iid->Data4[1], iid->Data4[2], iid->Data4[3],
549 iid->Data4[4], iid->Data4[5], iid->Data4[6], iid->Data4[7]);
550 wireip += sizeof(IID);
551 ok(*(DWORD *)wireip == 0, "wireip + 0x1c should be 0 instead of 0x%08x\n", *(DWORD *)wireip);
552 wireip += sizeof(DWORD);
553 ok(*(DWORD *)wireip == 5, "wireip + 0x20 should be 5 instead of %d\n", *(DWORD *)wireip);
554 wireip += sizeof(DWORD);
555 /* the rest is dynamic so can't really be tested */
559 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_INPROC);
560 WdtpInterfacePointer_UserUnmarshal(&umcb.Flags, buffer, &unk2, &IID_IUnknown);
562 ok(unk2 != NULL, "IUnknown object didn't unmarshal properly\n");
563 HeapFree(GetProcessHeap(), 0, buffer);
564 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_INPROC);
565 WdtpInterfacePointer_UserFree(unk2);
568 START_TEST(usrmarshal)
572 test_marshal_CLIPFORMAT();
574 test_marshal_HGLOBAL();
575 test_marshal_HENHMETAFILE();
576 test_marshal_HMETAFILE();
577 test_marshal_HMETAFILEPICT();
578 test_marshal_WdtpInterfacePointer();