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 static const char cf_marshaled[] =
49 static void test_marshal_CLIPFORMAT(void)
51 unsigned char *buffer;
53 ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
54 wireCLIPFORMAT wirecf;
55 CLIPFORMAT cf = RegisterClipboardFormatA("MyFormat");
58 size = CLIPFORMAT_UserSize(&flags, 0, &cf);
59 ok(size == sizeof(*wirecf) + sizeof(cf_marshaled), "Wrong size %d\n", size);
61 buffer = HeapAlloc(GetProcessHeap(), 0, size);
62 CLIPFORMAT_UserMarshal(&flags, buffer, &cf);
63 wirecf = (wireCLIPFORMAT)buffer;
64 ok(wirecf->fContext == WDT_REMOTE_CALL, "Context should be WDT_REMOTE_CALL instead of 0x%08lx\n", wirecf->fContext);
65 ok(wirecf->u.dwValue == cf, "Marshaled value should be 0x%04x instead of 0x%04x\n", cf, wirecf->u.dwValue);
66 ok(!memcmp(wirecf+1, cf_marshaled, sizeof(cf_marshaled)), "Marshaled data differs\n");
68 CLIPFORMAT_UserUnmarshal(&flags, buffer, &cf2);
69 ok(cf == cf2, "Didn't unmarshal properly\n");
70 HeapFree(GetProcessHeap(), 0, buffer);
72 CLIPFORMAT_UserFree(&flags, &cf2);
75 static void test_marshal_HWND(void)
77 unsigned char *buffer;
79 ULONG flags = MAKELONG(MSHCTX_LOCAL, NDR_LOCAL_DATA_REPRESENTATION);
80 HWND hwnd = GetDesktopWindow();
84 size = HWND_UserSize(&flags, 0, &hwnd);
85 ok(size == sizeof(*wirehwnd), "Wrong size %d\n", size);
87 buffer = HeapAlloc(GetProcessHeap(), 0, size);
88 HWND_UserMarshal(&flags, buffer, &hwnd);
89 wirehwnd = (wireHWND)buffer;
90 ok(wirehwnd->fContext == WDT_INPROC_CALL, "Context should be WDT_INPROC_CALL instead of 0x%08lx\n", wirehwnd->fContext);
91 ok(wirehwnd->u.hInproc == (LONG_PTR)hwnd, "Marshaled value should be %p instead of %p\n", hwnd, (HANDLE)wirehwnd->u.hRemote);
93 HWND_UserUnmarshal(&flags, buffer, &hwnd2);
94 ok(hwnd == hwnd2, "Didn't unmarshal properly\n");
95 HeapFree(GetProcessHeap(), 0, buffer);
97 HWND_UserFree(&flags, &hwnd2);
100 static void test_marshal_HGLOBAL(void)
102 unsigned char *buffer;
104 ULONG flags = MAKELONG(MSHCTX_LOCAL, NDR_LOCAL_DATA_REPRESENTATION);
107 unsigned char *wirehglobal;
111 flags = MAKELONG(MSHCTX_LOCAL, NDR_LOCAL_DATA_REPRESENTATION);
112 size = HGLOBAL_UserSize(&flags, 0, &hglobal);
113 /* native is poorly programmed and allocates 4 bytes more than it needs to
114 * here - Wine doesn't have to emulate that */
115 ok((size == 8) || (size == 12), "Size should be 12, instead of %d\n", size);
116 buffer = HeapAlloc(GetProcessHeap(), 0, size);
117 HGLOBAL_UserMarshal(&flags, buffer, &hglobal);
118 wirehglobal = buffer;
119 ok(*(ULONG *)wirehglobal == WDT_REMOTE_CALL, "Context should be WDT_REMOTE_CALL instead of 0x%08x\n", *(ULONG *)wirehglobal);
120 wirehglobal += sizeof(ULONG);
121 ok(*(ULONG *)wirehglobal == (ULONG)hglobal, "buffer+4 should be HGLOBAL\n");
122 HGLOBAL_UserUnmarshal(&flags, buffer, &hglobal2);
123 ok(hglobal2 == hglobal, "Didn't unmarshal properly\n");
124 HeapFree(GetProcessHeap(), 0, buffer);
125 HGLOBAL_UserFree(&flags, &hglobal2);
127 hglobal = GlobalAlloc(0, 4);
128 buffer = GlobalLock(hglobal);
129 for (i = 0; i < 4; i++)
131 GlobalUnlock(hglobal);
132 flags = MAKELONG(MSHCTX_LOCAL, NDR_LOCAL_DATA_REPRESENTATION);
133 size = HGLOBAL_UserSize(&flags, 0, &hglobal);
134 /* native is poorly programmed and allocates 4 bytes more than it needs to
135 * here - Wine doesn't have to emulate that */
136 ok((size == 24) || (size == 28), "Size should be 24 or 28, instead of %d\n", size);
137 buffer = HeapAlloc(GetProcessHeap(), 0, size);
138 HGLOBAL_UserMarshal(&flags, buffer, &hglobal);
139 wirehglobal = buffer;
140 ok(*(ULONG *)wirehglobal == WDT_REMOTE_CALL, "Context should be WDT_REMOTE_CALL instead of 0x%08x\n", *(ULONG *)wirehglobal);
141 wirehglobal += sizeof(ULONG);
142 ok(*(ULONG *)wirehglobal == (ULONG)hglobal, "buffer+0x4 should be HGLOBAL\n");
143 wirehglobal += sizeof(ULONG);
144 ok(*(ULONG *)wirehglobal == 4, "buffer+0x8 should be size of HGLOBAL\n");
145 wirehglobal += sizeof(ULONG);
146 ok(*(ULONG *)wirehglobal == (ULONG)hglobal, "buffer+0xc should be HGLOBAL\n");
147 wirehglobal += sizeof(ULONG);
148 ok(*(ULONG *)wirehglobal == 4, "buffer+0x10 should be size of HGLOBAL\n");
149 wirehglobal += sizeof(ULONG);
150 for (i = 0; i < 4; i++)
151 ok(wirehglobal[i] == i, "buffer+0x%x should be %d\n", 0x10 + i, i);
152 HGLOBAL_UserUnmarshal(&flags, buffer, &hglobal2);
153 ok(hglobal2 != NULL, "Didn't unmarshal properly\n");
154 HeapFree(GetProcessHeap(), 0, buffer);
155 HGLOBAL_UserFree(&flags, &hglobal2);
159 static HENHMETAFILE create_emf(void)
161 RECT rect = {0, 0, 100, 100};
162 HDC hdc = CreateEnhMetaFile(NULL, NULL, &rect, "HENHMETAFILE Marshaling Test\0Test\0\0");
163 ExtTextOut(hdc, 0, 0, ETO_OPAQUE, NULL, "Test String", strlen("Test String"), NULL);
164 return CloseEnhMetaFile(hdc);
167 static void test_marshal_HENHMETAFILE(void)
169 unsigned char *buffer;
171 ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
173 HENHMETAFILE hemf2 = NULL;
174 unsigned char *wirehemf;
178 size = HENHMETAFILE_UserSize(&flags, 0, &hemf);
179 ok(size > 20, "size should be at least 20 bytes, not %d\n", size);
180 buffer = HeapAlloc(GetProcessHeap(), 0, size);
181 HENHMETAFILE_UserMarshal(&flags, buffer, &hemf);
183 ok(*(DWORD *)wirehemf == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehemf);
184 wirehemf += sizeof(DWORD);
185 ok(*(DWORD *)wirehemf == (DWORD)(DWORD_PTR)hemf, "wirestgm + 0x4 should be hemf instead of 0x%08x\n", *(DWORD *)wirehemf);
186 wirehemf += sizeof(DWORD);
187 ok(*(DWORD *)wirehemf == (size - 0x10), "wirestgm + 0x8 should be size - 0x10 instead of 0x%08x\n", *(DWORD *)wirehemf);
188 wirehemf += sizeof(DWORD);
189 ok(*(DWORD *)wirehemf == (size - 0x10), "wirestgm + 0xc should be size - 0x10 instead of 0x%08x\n", *(DWORD *)wirehemf);
190 wirehemf += sizeof(DWORD);
191 ok(*(DWORD *)wirehemf == EMR_HEADER, "wirestgm + 0x10 should be EMR_HEADER instead of %d\n", *(DWORD *)wirehemf);
192 wirehemf += sizeof(DWORD);
193 /* ... rest of data not tested - refer to tests for GetEnhMetaFileBits
196 HENHMETAFILE_UserUnmarshal(&flags, buffer, &hemf2);
197 ok(hemf2 != NULL, "HENHMETAFILE didn't unmarshal\n");
198 HeapFree(GetProcessHeap(), 0, buffer);
199 HENHMETAFILE_UserFree(&flags, &hemf2);
200 DeleteEnhMetaFile(hemf);
205 size = HENHMETAFILE_UserSize(&flags, 0, &hemf);
206 ok(size == 8, "size should be 8 bytes, not %d\n", size);
207 buffer = HeapAlloc(GetProcessHeap(), 0, size);
208 HENHMETAFILE_UserMarshal(&flags, buffer, &hemf);
210 ok(*(DWORD *)wirehemf == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehemf);
211 wirehemf += sizeof(DWORD);
212 ok(*(DWORD *)wirehemf == (DWORD)(DWORD_PTR)hemf, "wirestgm + 0x4 should be hemf instead of 0x%08x\n", *(DWORD *)wirehemf);
213 wirehemf += sizeof(DWORD);
215 HENHMETAFILE_UserUnmarshal(&flags, buffer, &hemf2);
216 ok(hemf2 == NULL, "NULL HENHMETAFILE didn't unmarshal\n");
217 HeapFree(GetProcessHeap(), 0, buffer);
218 HENHMETAFILE_UserFree(&flags, &hemf2);
221 static HMETAFILE create_mf(void)
223 RECT rect = {0, 0, 100, 100};
224 HDC hdc = CreateMetaFile(NULL);
225 ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rect, "Test String", strlen("Test String"), NULL);
226 return CloseMetaFile(hdc);
229 static void test_marshal_HMETAFILE(void)
231 unsigned char *buffer;
233 ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
235 HMETAFILE hmf2 = NULL;
236 unsigned char *wirehmf;
240 size = HMETAFILE_UserSize(&flags, 0, &hmf);
241 ok(size > 20, "size should be at least 20 bytes, not %d\n", size);
242 buffer = HeapAlloc(GetProcessHeap(), 0, size);
243 HMETAFILE_UserMarshal(&flags, buffer, &hmf);
245 ok(*(DWORD *)wirehmf == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehmf);
246 wirehmf += sizeof(DWORD);
247 ok(*(DWORD *)wirehmf == (DWORD)(DWORD_PTR)hmf, "wirestgm + 0x4 should be hmf instead of 0x%08x\n", *(DWORD *)wirehmf);
248 wirehmf += sizeof(DWORD);
249 ok(*(DWORD *)wirehmf == (size - 0x10), "wirestgm + 0x8 should be size - 0x10 instead of 0x%08x\n", *(DWORD *)wirehmf);
250 wirehmf += sizeof(DWORD);
251 ok(*(DWORD *)wirehmf == (size - 0x10), "wirestgm + 0xc should be size - 0x10 instead of 0x%08x\n", *(DWORD *)wirehmf);
252 wirehmf += sizeof(DWORD);
253 ok(*(WORD *)wirehmf == 1, "wirestgm + 0x10 should be 1 instead of 0x%08x\n", *(DWORD *)wirehmf);
254 wirehmf += sizeof(DWORD);
255 /* ... rest of data not tested - refer to tests for GetMetaFileBits
258 HMETAFILE_UserUnmarshal(&flags, buffer, &hmf2);
259 ok(hmf2 != NULL, "HMETAFILE didn't unmarshal\n");
260 HeapFree(GetProcessHeap(), 0, buffer);
261 HMETAFILE_UserFree(&flags, &hmf2);
267 size = HMETAFILE_UserSize(&flags, 0, &hmf);
268 ok(size == 8, "size should be 8 bytes, not %d\n", size);
269 buffer = HeapAlloc(GetProcessHeap(), 0, size);
270 HMETAFILE_UserMarshal(&flags, buffer, &hmf);
272 ok(*(DWORD *)wirehmf == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehmf);
273 wirehmf += sizeof(DWORD);
274 ok(*(DWORD *)wirehmf == (DWORD)(DWORD_PTR)hmf, "wirestgm + 0x4 should be hmf instead of 0x%08x\n", *(DWORD *)wirehmf);
275 wirehmf += sizeof(DWORD);
277 HMETAFILE_UserUnmarshal(&flags, buffer, &hmf2);
278 ok(hmf2 == NULL, "NULL HMETAFILE didn't unmarshal\n");
279 HeapFree(GetProcessHeap(), 0, buffer);
280 HMETAFILE_UserFree(&flags, &hmf2);
283 #define USER_MARSHAL_PTR_PREFIX \
284 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
285 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
287 static void test_marshal_HMETAFILEPICT(void)
289 unsigned char *buffer, *buffer_end;
291 ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
293 HMETAFILEPICT hmfp2 = NULL;
295 unsigned char *wirehmfp;
297 hmfp = GlobalAlloc(GMEM_MOVEABLE, sizeof(*pmfp));
298 pmfp = GlobalLock(hmfp);
299 pmfp->mm = MM_ISOTROPIC;
302 pmfp->hMF = create_mf();
305 size = HMETAFILEPICT_UserSize(&flags, 0, &hmfp);
306 ok(size > 20, "size should be at least 20 bytes, not %d\n", size);
307 trace("size is %d\n", size);
308 buffer = HeapAlloc(GetProcessHeap(), 0, size);
309 buffer_end = HMETAFILEPICT_UserMarshal(&flags, buffer, &hmfp);
311 ok(*(DWORD *)wirehmfp == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehmfp);
312 wirehmfp += sizeof(DWORD);
313 ok(*(DWORD *)wirehmfp == (DWORD)(DWORD_PTR)hmfp, "wirestgm + 0x4 should be hmf instead of 0x%08x\n", *(DWORD *)wirehmfp);
314 wirehmfp += sizeof(DWORD);
315 ok(*(DWORD *)wirehmfp == MM_ISOTROPIC, "wirestgm + 0x8 should be MM_ISOTROPIC instead of 0x%08x\n", *(DWORD *)wirehmfp);
316 wirehmfp += sizeof(DWORD);
317 ok(*(DWORD *)wirehmfp == 1, "wirestgm + 0xc should be 1 instead of 0x%08x\n", *(DWORD *)wirehmfp);
318 wirehmfp += sizeof(DWORD);
319 ok(*(DWORD *)wirehmfp == 2, "wirestgm + 0x10 should be 2 instead of 0x%08x\n", *(DWORD *)wirehmfp);
320 wirehmfp += sizeof(DWORD);
321 ok(*(DWORD *)wirehmfp == USER_MARSHAL_PTR_PREFIX, "wirestgm + 0x14 should be \"User\" instead of 0x%08x\n", *(DWORD *)wirehmfp);
322 wirehmfp += sizeof(DWORD);
323 ok(*(DWORD *)wirehmfp == WDT_REMOTE_CALL, "wirestgm + 0x18 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehmfp);
324 wirehmfp += sizeof(DWORD);
325 pmfp = GlobalLock(hmfp);
326 ok(*(DWORD *)wirehmfp == (DWORD)(DWORD_PTR)pmfp->hMF, "wirestgm + 0x1c should be pmfp->hMF instead of 0x%08x\n", *(DWORD *)wirehmfp);
328 wirehmfp += sizeof(DWORD);
329 /* Note use (buffer_end - buffer) instead of size here, because size is an
330 * overestimate with native */
331 ok(*(DWORD *)wirehmfp == (buffer_end - buffer - 0x28), "wirestgm + 0x20 should be size - 0x34 instead of 0x%08x\n", *(DWORD *)wirehmfp);
332 wirehmfp += sizeof(DWORD);
333 ok(*(DWORD *)wirehmfp == (buffer_end - buffer - 0x28), "wirestgm + 0x24 should be size - 0x34 instead of 0x%08x\n", *(DWORD *)wirehmfp);
334 wirehmfp += sizeof(DWORD);
335 ok(*(WORD *)wirehmfp == 1, "wirehmfp + 0x28 should be 1 instead of 0x%08x\n", *(DWORD *)wirehmfp);
336 wirehmfp += sizeof(DWORD);
337 /* ... rest of data not tested - refer to tests for GetMetaFileBits
340 HMETAFILEPICT_UserUnmarshal(&flags, buffer, &hmfp2);
341 ok(hmfp2 != NULL, "HMETAFILEPICT didn't unmarshal\n");
342 HeapFree(GetProcessHeap(), 0, buffer);
343 HMETAFILEPICT_UserFree(&flags, &hmfp2);
344 pmfp = GlobalLock(hmfp);
345 DeleteMetaFile(pmfp->hMF);
352 size = HMETAFILEPICT_UserSize(&flags, 0, &hmfp);
353 ok(size == 8, "size should be 8 bytes, not %d\n", size);
354 buffer = HeapAlloc(GetProcessHeap(), 0, size);
355 HMETAFILEPICT_UserMarshal(&flags, buffer, &hmfp);
357 ok(*(DWORD *)wirehmfp == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehmfp);
358 wirehmfp += sizeof(DWORD);
359 ok(*(DWORD *)wirehmfp == (DWORD)(DWORD_PTR)hmfp, "wirestgm + 0x4 should be hmf instead of 0x%08x\n", *(DWORD *)wirehmfp);
360 wirehmfp += sizeof(DWORD);
363 HMETAFILEPICT_UserUnmarshal(&flags, buffer, &hmfp2);
364 ok(hmfp2 == NULL, "NULL HMETAFILE didn't unmarshal\n");
365 HeapFree(GetProcessHeap(), 0, buffer);
366 HMETAFILEPICT_UserFree(&flags, &hmfp2);
369 START_TEST(usrmarshal)
373 test_marshal_CLIPFORMAT();
375 test_marshal_HGLOBAL();
376 test_marshal_HENHMETAFILE();
377 test_marshal_HMETAFILE();
378 test_marshal_HMETAFILEPICT();