ReactOS 0.4.15-dev-7897-g78dc504
usrmarshal.c
Go to the documentation of this file.
1/*
2 * User Marshaling Tests
3 *
4 * Copyright 2004-2006 Robert Shearman for CodeWeavers
5 *
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.
10 *
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.
15 *
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
19 */
20
21#define COBJMACROS
22#define CONST_VTABLE
23#include <stdarg.h>
24
25#include "windef.h"
26#include "winbase.h"
27#include "objbase.h"
28#include "objidl.h"
29
30#include "wine/test.h"
31
33unsigned char * __RPC_USER HMETAFILE_UserMarshal(ULONG *, unsigned char *, HMETAFILE *);
34unsigned char * __RPC_USER HMETAFILE_UserUnmarshal(ULONG *, unsigned char *, HMETAFILE *);
35void __RPC_USER HMETAFILE_UserFree(ULONG *, HMETAFILE *);
36
38unsigned char * __RPC_USER HENHMETAFILE_UserMarshal (ULONG *, unsigned char *, HENHMETAFILE *);
39unsigned char * __RPC_USER HENHMETAFILE_UserUnmarshal(ULONG *, unsigned char *, HENHMETAFILE *);
40void __RPC_USER HENHMETAFILE_UserFree(ULONG *, HENHMETAFILE *);
41
43unsigned char * __RPC_USER HMETAFILEPICT_UserMarshal (ULONG *, unsigned char *, HMETAFILEPICT *);
44unsigned char * __RPC_USER HMETAFILEPICT_UserUnmarshal(ULONG *, unsigned char *, HMETAFILEPICT *);
45void __RPC_USER HMETAFILEPICT_UserFree(ULONG *, HMETAFILEPICT *);
46
48unsigned char * __RPC_USER HBRUSH_UserMarshal(ULONG *, unsigned char *, HBRUSH *);
49unsigned char * __RPC_USER HBRUSH_UserUnmarshal(ULONG *, unsigned char *, HBRUSH *);
51
54{
55 ok(g_expect_user_alloc, "unexpected user_allocate call\n");
56 return CoTaskMemAlloc(size);
57}
58
60static void WINAPI user_free(void *p)
61{
62 ok(g_expect_user_free, "unexpected user_free call\n");
64}
65
67 PMIDL_STUB_MESSAGE stub_msg,
68 PRPC_MESSAGE rpc_msg, unsigned char *buffer,
69 unsigned int size, MSHCTX context)
70{
71 memset(rpc_msg, 0, sizeof(*rpc_msg));
72 rpc_msg->Buffer = buffer;
73 rpc_msg->BufferLength = size;
74
75 memset(stub_msg, 0, sizeof(*stub_msg));
76 stub_msg->RpcMsg = rpc_msg;
77 stub_msg->Buffer = buffer;
78 stub_msg->pfnAllocate = user_allocate;
79 stub_msg->pfnFree = user_free;
80
81 memset(umcb, 0, sizeof(*umcb));
83 umcb->pStubMsg = stub_msg;
86}
87
88#define RELEASEMARSHALDATA WM_USER
89
91{
95 MSHLFLAGS marshal_flags;
98};
99
101{
102 struct host_object_data *data = p;
103 HRESULT hr;
104 MSG msg;
105
107
108 if (data->filter)
109 {
110 IMessageFilter * prev_filter = NULL;
111 hr = CoRegisterMessageFilter(data->filter, &prev_filter);
112 if (prev_filter) IMessageFilter_Release(prev_filter);
113 ok(hr == S_OK, "got %08x\n", hr);
114 }
115
116 hr = CoMarshalInterface(data->stream, &data->iid, data->object, MSHCTX_INPROC, NULL, data->marshal_flags);
117 ok(hr == S_OK, "got %08x\n", hr);
118
119 /* force the message queue to be created before signaling parent thread */
121
122 SetEvent(data->marshal_event);
123
124 while (GetMessageA(&msg, NULL, 0, 0))
125 {
126 if (msg.hwnd == NULL && msg.message == RELEASEMARSHALDATA)
127 {
128 CoReleaseMarshalData(data->stream);
129 SetEvent((HANDLE)msg.lParam);
130 }
131 else
133 }
134
136
138
139 return hr;
140}
141
143{
144 DWORD tid = 0;
146 struct host_object_data *data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data));
147
148 data->stream = stream;
149 data->iid = *riid;
150 data->object = object;
151 data->marshal_flags = marshal_flags;
152 data->marshal_event = marshal_event;
153 data->filter = filter;
154
156
157 /* wait for marshaling to complete before returning */
158 ok( !WaitForSingleObject(marshal_event, 10000), "wait timed out\n" );
160
161 return tid;
162}
163
165{
167 ok(ret, "PostThreadMessage failed with error %d\n", GetLastError());
168 /* be careful of races - don't return until hosting thread has terminated */
169 ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
171}
172
173static const char cf_marshaled[] =
174{
175 0x9, 0x0, 0x0, 0x0,
176 0x0, 0x0, 0x0, 0x0,
177 0x9, 0x0, 0x0, 0x0,
178 'M', 0x0, 'y', 0x0,
179 'F', 0x0, 'o', 0x0,
180 'r', 0x0, 'm', 0x0,
181 'a', 0x0, 't', 0x0,
182 0x0, 0x0
183};
184
185static void test_marshal_CLIPFORMAT(void)
186{
187 USER_MARSHAL_CB umcb;
188 MIDL_STUB_MESSAGE stub_msg;
190 unsigned char *buffer, *buffer_end;
191 ULONG i, size;
192 CLIPFORMAT cf = RegisterClipboardFormatA("MyFormat");
193 CLIPFORMAT cf2;
194
195 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
196 size = CLIPFORMAT_UserSize(&umcb.Flags, 1, &cf);
197 ok(size == 12 + sizeof(cf_marshaled) ||
198 broken(size == 16 + sizeof(cf_marshaled)), /* win64 adds 4 extra (unused) bytes */
199 "CLIPFORMAT: Wrong size %d\n", size);
200
202 memset( buffer, 0xcc, size );
203 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
205 ok(buffer_end == buffer + 12 + sizeof(cf_marshaled), "got %p buffer %p\n", buffer_end, buffer);
206 ok(*(LONG *)(buffer + 4) == WDT_REMOTE_CALL, "CLIPFORMAT: Context should be WDT_REMOTE_CALL instead of 0x%08x\n", *(LONG *)(buffer + 0));
207 ok(*(DWORD *)(buffer + 8) == cf, "CLIPFORMAT: Marshaled value should be 0x%04x instead of 0x%04x\n", cf, *(DWORD *)(buffer + 4));
208 ok(!memcmp(buffer + 12, cf_marshaled, min( sizeof(cf_marshaled), size-12 )), "Marshaled data differs\n");
209 if (size > sizeof(cf_marshaled) + 12) /* make sure the extra bytes are not used */
210 for (i = sizeof(cf_marshaled) + 12; i < size; i++)
211 ok( buffer[i] == 0xcc, "buffer offset %u has been set to %x\n", i, buffer[i] );
212
213 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
215 ok(buffer_end == buffer + 12 + sizeof(cf_marshaled), "got %p buffer %p\n", buffer_end, buffer);
216 ok(cf == cf2, "CLIPFORMAT: Didn't unmarshal properly\n");
218
219 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
220 CLIPFORMAT_UserFree(&umcb.Flags, &cf2);
221}
222
223static void test_marshal_HWND(void)
224{
225 USER_MARSHAL_CB umcb;
226 MIDL_STUB_MESSAGE stub_msg;
228 unsigned char *buffer, *buffer_end;
229 ULONG size;
231 HWND hwnd2;
232 wireHWND wirehwnd;
233
234 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
235 size = HWND_UserSize(&umcb.Flags, 1, &hwnd);
236 ok(size == 4 + sizeof(*wirehwnd), "Wrong size %d\n", size);
237
239 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
240 buffer_end = HWND_UserMarshal(&umcb.Flags, buffer + 1, &hwnd);
241 ok(buffer_end == buffer + size, "got %p buffer %p\n", buffer_end, buffer);
242 wirehwnd = (wireHWND)(buffer + 4);
243 ok(wirehwnd->fContext == WDT_INPROC_CALL, "Context should be WDT_INPROC_CALL instead of 0x%08x\n", wirehwnd->fContext);
244 ok(wirehwnd->u.hInproc == (LONG_PTR)hwnd, "Marshaled value should be %p instead of %x\n", hwnd, wirehwnd->u.hRemote);
245
246 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
247 buffer_end = HWND_UserUnmarshal(&umcb.Flags, buffer + 1, &hwnd2);
248 ok(buffer_end == buffer + size, "got %p buffer %p\n", buffer_end, buffer);
249 ok(hwnd == hwnd2, "Didn't unmarshal properly\n");
251
252 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
253 HWND_UserFree(&umcb.Flags, &hwnd2);
254}
255
256static void test_marshal_HGLOBAL(void)
257{
258 USER_MARSHAL_CB umcb;
259 MIDL_STUB_MESSAGE stub_msg;
261 unsigned char *buffer;
263 HGLOBAL hglobal;
264 HGLOBAL hglobal2;
265 unsigned char *wirehglobal;
266 int i;
267
268 hglobal = NULL;
269 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
270 size = HGLOBAL_UserSize(&umcb.Flags, 0, &hglobal);
271 /* native is poorly programmed and allocates 4/8 bytes more than it needs to
272 * here - Wine doesn't have to emulate that */
273 ok((size == 8) || broken(size == 12) || broken(size == 16), "Size should be 8, instead of %d\n", size);
275 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
276 HGLOBAL_UserMarshal(&umcb.Flags, buffer, &hglobal);
277 wirehglobal = buffer;
278 ok(*(ULONG *)wirehglobal == WDT_REMOTE_CALL, "Context should be WDT_REMOTE_CALL instead of 0x%08x\n", *(ULONG *)wirehglobal);
279 wirehglobal += sizeof(ULONG);
280 ok(*(ULONG *)wirehglobal == 0, "buffer+4 should be HGLOBAL\n");
281 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
282 hglobal2 = NULL;
283 HGLOBAL_UserUnmarshal(&umcb.Flags, buffer, &hglobal2);
284 ok(hglobal2 == hglobal, "Didn't unmarshal properly\n");
286 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
287 HGLOBAL_UserFree(&umcb.Flags, &hglobal2);
288
289
290 for(block_size = 0; block_size <= 17; block_size++)
291 {
292 ULONG actual_size, expected_size;
293
294 hglobal = GlobalAlloc(0, block_size);
295 buffer = GlobalLock(hglobal);
296 for (i = 0; i < block_size; i++)
297 buffer[i] = i;
298 GlobalUnlock(hglobal);
299 actual_size = GlobalSize(hglobal);
300 expected_size = actual_size + 5 * sizeof(DWORD);
301 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
302 size = HGLOBAL_UserSize(&umcb.Flags, 0, &hglobal);
303 /* native is poorly programmed and allocates 4/8 bytes more than it needs to
304 * here - Wine doesn't have to emulate that */
305 ok(size == expected_size ||
306 broken(size == expected_size + 4) ||
307 broken(size == expected_size + 8),
308 "%d: got size %d\n", block_size, size);
310 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
311 HGLOBAL_UserMarshal(&umcb.Flags, buffer, &hglobal);
312 wirehglobal = buffer;
313 ok(*(ULONG *)wirehglobal == WDT_REMOTE_CALL, "Context should be WDT_REMOTE_CALL instead of 0x%08x\n", *(ULONG *)wirehglobal);
314 wirehglobal += sizeof(ULONG);
315 ok(*(ULONG *)wirehglobal == (ULONG)(ULONG_PTR)hglobal, "buffer+0x4 should be HGLOBAL\n");
316 wirehglobal += sizeof(ULONG);
317 ok(*(ULONG *)wirehglobal == actual_size, "%d: buffer+0x8 %08x\n", block_size, *(ULONG *)wirehglobal);
318 wirehglobal += sizeof(ULONG);
319 ok(*(ULONG *)wirehglobal == (ULONG)(ULONG_PTR)hglobal, "buffer+0xc should be HGLOBAL\n");
320 wirehglobal += sizeof(ULONG);
321 ok(*(ULONG *)wirehglobal == actual_size, "%d: buffer+0x10 %08x\n", block_size, *(ULONG *)wirehglobal);
322 wirehglobal += sizeof(ULONG);
323 for (i = 0; i < block_size; i++)
324 ok(wirehglobal[i] == i, "buffer+0x%x should be %d\n", 0x10 + i, i);
325
326 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
327 hglobal2 = NULL;
328 HGLOBAL_UserUnmarshal(&umcb.Flags, buffer, &hglobal2);
329 ok(hglobal2 != NULL, "Didn't unmarshal properly\n");
331 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
332 HGLOBAL_UserFree(&umcb.Flags, &hglobal2);
333 GlobalFree(hglobal);
334 }
335}
336
337static HENHMETAFILE create_emf(void)
338{
339 const RECT rect = {0, 0, 100, 100};
340 HDC hdc = CreateEnhMetaFileA(NULL, NULL, &rect, "HENHMETAFILE Marshaling Test\0Test\0\0");
341 ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rect, "Test String", strlen("Test String"), NULL);
342 return CloseEnhMetaFile(hdc);
343}
344
346{
347 USER_MARSHAL_CB umcb;
348 MIDL_STUB_MESSAGE stub_msg;
350 unsigned char *buffer, *buffer_end;
351 ULONG size;
352 HENHMETAFILE hemf;
353 HENHMETAFILE hemf2 = NULL;
354 unsigned char *wirehemf;
355
356 hemf = create_emf();
357
358 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
359 size = HENHMETAFILE_UserSize(&umcb.Flags, 1, &hemf);
360 ok(size > 24, "size should be at least 24 bytes, not %d\n", size);
362 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
363 buffer_end = HENHMETAFILE_UserMarshal(&umcb.Flags, buffer + 1, &hemf);
364 ok(buffer_end == buffer + size, "got %p buffer %p\n", buffer_end, buffer);
365 wirehemf = buffer + 4;
366 ok(*(DWORD *)wirehemf == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehemf);
367 wirehemf += sizeof(DWORD);
368 ok(*(DWORD *)wirehemf == (DWORD)(DWORD_PTR)hemf, "wirestgm + 0x4 should be hemf instead of 0x%08x\n", *(DWORD *)wirehemf);
369 wirehemf += sizeof(DWORD);
370 ok(*(DWORD *)wirehemf == (size - 0x14), "wirestgm + 0x8 should be size - 0x14 instead of 0x%08x\n", *(DWORD *)wirehemf);
371 wirehemf += sizeof(DWORD);
372 ok(*(DWORD *)wirehemf == (size - 0x14), "wirestgm + 0xc should be size - 0x14 instead of 0x%08x\n", *(DWORD *)wirehemf);
373 wirehemf += sizeof(DWORD);
374 ok(*(DWORD *)wirehemf == EMR_HEADER, "wirestgm + 0x10 should be EMR_HEADER instead of %d\n", *(DWORD *)wirehemf);
375 /* ... rest of data not tested - refer to tests for GetEnhMetaFileBits
376 * at this point */
377
378 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
380 ok(buffer_end == buffer + size, "got %p buffer %p\n", buffer_end, buffer);
381 ok(hemf2 != NULL, "HENHMETAFILE didn't unmarshal\n");
383 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
384 HENHMETAFILE_UserFree(&umcb.Flags, &hemf2);
385 DeleteEnhMetaFile(hemf);
386
387 /* test NULL emf */
388 hemf = NULL;
389
390 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
391 size = HENHMETAFILE_UserSize(&umcb.Flags, 1, &hemf);
392 ok(size == 12, "size should be 12 bytes, not %d\n", size);
394 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
395 buffer_end = HENHMETAFILE_UserMarshal(&umcb.Flags, buffer + 1, &hemf);
396 ok(buffer_end == buffer + size, "got %p buffer %p\n", buffer_end, buffer);
397 wirehemf = buffer + 4;
398 ok(*(DWORD *)wirehemf == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehemf);
399 wirehemf += sizeof(DWORD);
400 ok(*(DWORD *)wirehemf == (DWORD)(DWORD_PTR)hemf, "wirestgm + 0x4 should be hemf instead of 0x%08x\n", *(DWORD *)wirehemf);
401
402 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
404 ok(buffer_end == buffer + size, "got %p buffer %p\n", buffer_end, buffer);
405 ok(hemf2 == NULL, "NULL HENHMETAFILE didn't unmarshal\n");
407 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
408 HENHMETAFILE_UserFree(&umcb.Flags, &hemf2);
409}
410
411static HMETAFILE create_mf(void)
412{
413 RECT rect = {0, 0, 100, 100};
415 ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rect, "Test String", strlen("Test String"), NULL);
416 return CloseMetaFile(hdc);
417}
418
419static void test_marshal_HMETAFILE(void)
420{
421 USER_MARSHAL_CB umcb;
422 MIDL_STUB_MESSAGE stub_msg;
424 unsigned char *buffer;
425 ULONG size;
426 HMETAFILE hmf;
427 HMETAFILE hmf2 = NULL;
428 unsigned char *wirehmf;
429
430 hmf = create_mf();
431
432 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
433 size = HMETAFILE_UserSize(&umcb.Flags, 0, &hmf);
434 ok(size > 20, "size should be at least 20 bytes, not %d\n", size);
436 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
437 HMETAFILE_UserMarshal(&umcb.Flags, buffer, &hmf);
438 wirehmf = buffer;
439 ok(*(DWORD *)wirehmf == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehmf);
440 wirehmf += sizeof(DWORD);
441 ok(*(DWORD *)wirehmf == (DWORD)(DWORD_PTR)hmf, "wirestgm + 0x4 should be hmf instead of 0x%08x\n", *(DWORD *)wirehmf);
442 wirehmf += sizeof(DWORD);
443 ok(*(DWORD *)wirehmf == (size - 0x10), "wirestgm + 0x8 should be size - 0x10 instead of 0x%08x\n", *(DWORD *)wirehmf);
444 wirehmf += sizeof(DWORD);
445 ok(*(DWORD *)wirehmf == (size - 0x10), "wirestgm + 0xc should be size - 0x10 instead of 0x%08x\n", *(DWORD *)wirehmf);
446 wirehmf += sizeof(DWORD);
447 ok(*(WORD *)wirehmf == 1, "wirestgm + 0x10 should be 1 instead of 0x%08x\n", *(DWORD *)wirehmf);
448 wirehmf += sizeof(DWORD);
449 /* ... rest of data not tested - refer to tests for GetMetaFileBits
450 * at this point */
451
452 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
453 HMETAFILE_UserUnmarshal(&umcb.Flags, buffer, &hmf2);
454 ok(hmf2 != NULL, "HMETAFILE didn't unmarshal\n");
456 HMETAFILE_UserFree(&umcb.Flags, &hmf2);
457 DeleteMetaFile(hmf);
458
459 /* test NULL emf */
460 hmf = NULL;
461
462 size = HMETAFILE_UserSize(&umcb.Flags, 0, &hmf);
463 ok(size == 8, "size should be 8 bytes, not %d\n", size);
465 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
466 HMETAFILE_UserMarshal(&umcb.Flags, buffer, &hmf);
467 wirehmf = buffer;
468 ok(*(DWORD *)wirehmf == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehmf);
469 wirehmf += sizeof(DWORD);
470 ok(*(DWORD *)wirehmf == (DWORD)(DWORD_PTR)hmf, "wirestgm + 0x4 should be hmf instead of 0x%08x\n", *(DWORD *)wirehmf);
471 wirehmf += sizeof(DWORD);
472
473 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
474 HMETAFILE_UserUnmarshal(&umcb.Flags, buffer, &hmf2);
475 ok(hmf2 == NULL, "NULL HMETAFILE didn't unmarshal\n");
477 HMETAFILE_UserFree(&umcb.Flags, &hmf2);
478}
479
480#define USER_MARSHAL_PTR_PREFIX \
481 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
482 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
483
485{
486 USER_MARSHAL_CB umcb;
487 MIDL_STUB_MESSAGE stub_msg;
489 unsigned char *buffer, *buffer_end;
490 ULONG size;
491 HMETAFILEPICT hmfp;
492 HMETAFILEPICT hmfp2 = NULL;
493 METAFILEPICT *pmfp;
494 unsigned char *wirehmfp;
495
496 hmfp = GlobalAlloc(GMEM_MOVEABLE, sizeof(*pmfp));
497 pmfp = GlobalLock(hmfp);
498 pmfp->mm = MM_ISOTROPIC;
499 pmfp->xExt = 1;
500 pmfp->yExt = 2;
501 pmfp->hMF = create_mf();
502 GlobalUnlock(hmfp);
503
504 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
505 size = HMETAFILEPICT_UserSize(&umcb.Flags, 1, &hmfp);
506 ok(size > 24, "size should be at least 24 bytes, not %d\n", size);
508 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
510 wirehmfp = buffer + 4;
511 ok(*(DWORD *)wirehmfp == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehmfp);
512 wirehmfp += sizeof(DWORD);
513 ok(*(DWORD *)wirehmfp == (DWORD)(DWORD_PTR)hmfp, "wirestgm + 0x4 should be hmf instead of 0x%08x\n", *(DWORD *)wirehmfp);
514 wirehmfp += sizeof(DWORD);
515 ok(*(DWORD *)wirehmfp == MM_ISOTROPIC, "wirestgm + 0x8 should be MM_ISOTROPIC instead of 0x%08x\n", *(DWORD *)wirehmfp);
516 wirehmfp += sizeof(DWORD);
517 ok(*(DWORD *)wirehmfp == 1, "wirestgm + 0xc should be 1 instead of 0x%08x\n", *(DWORD *)wirehmfp);
518 wirehmfp += sizeof(DWORD);
519 ok(*(DWORD *)wirehmfp == 2, "wirestgm + 0x10 should be 2 instead of 0x%08x\n", *(DWORD *)wirehmfp);
520 wirehmfp += sizeof(DWORD);
521 ok(*(DWORD *)wirehmfp == USER_MARSHAL_PTR_PREFIX, "wirestgm + 0x14 should be \"User\" instead of 0x%08x\n", *(DWORD *)wirehmfp);
522 wirehmfp += sizeof(DWORD);
523 ok(*(DWORD *)wirehmfp == WDT_REMOTE_CALL, "wirestgm + 0x18 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehmfp);
524 wirehmfp += sizeof(DWORD);
525 pmfp = GlobalLock(hmfp);
526 ok(*(DWORD *)wirehmfp == (DWORD)(DWORD_PTR)pmfp->hMF, "wirestgm + 0x1c should be pmfp->hMF instead of 0x%08x\n", *(DWORD *)wirehmfp);
527 GlobalUnlock(hmfp);
528 wirehmfp += sizeof(DWORD);
529 /* Note use (buffer_end - buffer) instead of size here, because size is an
530 * overestimate with native */
531 ok(*(DWORD *)wirehmfp == (buffer_end - buffer - 0x2c), "wirestgm + 0x20 should be size - 0x34 instead of 0x%08x\n", *(DWORD *)wirehmfp);
532 wirehmfp += sizeof(DWORD);
533 ok(*(DWORD *)wirehmfp == (buffer_end - buffer - 0x2c), "wirestgm + 0x24 should be size - 0x34 instead of 0x%08x\n", *(DWORD *)wirehmfp);
534 wirehmfp += sizeof(DWORD);
535 ok(*(WORD *)wirehmfp == 1, "wirehmfp + 0x28 should be 1 instead of 0x%08x\n", *(DWORD *)wirehmfp);
536 /* ... rest of data not tested - refer to tests for GetMetaFileBits
537 * at this point */
538
539 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
540 HMETAFILEPICT_UserUnmarshal(&umcb.Flags, buffer + 1, &hmfp2);
541 ok(hmfp2 != NULL, "HMETAFILEPICT didn't unmarshal\n");
543 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
544 HMETAFILEPICT_UserFree(&umcb.Flags, &hmfp2);
545 pmfp = GlobalLock(hmfp);
546 DeleteMetaFile(pmfp->hMF);
547 GlobalUnlock(hmfp);
548 GlobalFree(hmfp);
549
550 /* test NULL emf */
551 hmfp = NULL;
552
553 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
554 size = HMETAFILEPICT_UserSize(&umcb.Flags, 1, &hmfp);
555 ok(size == 12, "size should be 12 bytes, not %d\n", size);
557 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
559 ok(buffer_end == buffer + size, "got %p buffer %p\n", buffer_end, buffer);
560 wirehmfp = buffer + 4;
561 ok(*(DWORD *)wirehmfp == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehmfp);
562 wirehmfp += sizeof(DWORD);
563 ok(*(DWORD *)wirehmfp == (DWORD)(DWORD_PTR)hmfp, "wirestgm + 0x4 should be hmf instead of 0x%08x\n", *(DWORD *)wirehmfp);
564 wirehmfp += sizeof(DWORD);
565
566 hmfp2 = NULL;
567 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
569 ok(buffer_end == buffer + size, "got %p buffer %p\n", buffer_end, buffer);
570 ok(hmfp2 == NULL, "NULL HMETAFILE didn't unmarshal\n");
572 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
573 HMETAFILEPICT_UserFree(&umcb.Flags, &hmfp2);
574}
575
576typedef struct
577{
581
583{
584 return CONTAINING_RECORD(iface, TestUnknown, IUnknown_iface);
585}
586
588 LPUNKNOWN iface,
589 REFIID riid,
590 LPVOID *ppvObj)
591{
592 if (ppvObj == NULL) return E_POINTER;
593
595 {
596 *ppvObj = iface;
597 IUnknown_AddRef(iface);
598 return S_OK;
599 }
600
601 *ppvObj = NULL;
602 return E_NOINTERFACE;
603}
604
606{
608 return InterlockedIncrement(&This->refs);
609}
610
612{
614 return InterlockedDecrement(&This->refs);
615}
616
617static const IUnknownVtbl TestUnknown_Vtbl =
618{
622};
623
625{
628};
629
630static inline struct test_stream *impl_from_IStream(IStream *iface)
631{
632 return CONTAINING_RECORD(iface, struct test_stream, IStream_iface);
633}
634
636 REFIID riid, LPVOID *ppvObj)
637{
638 if (ppvObj == NULL) return E_POINTER;
639
641 IsEqualIID(riid, &IID_IStream))
642 {
643 *ppvObj = iface;
644 IStream_AddRef(iface);
645 return S_OK;
646 }
647
648 *ppvObj = NULL;
649 return E_NOINTERFACE;
650}
651
653{
654 struct test_stream *This = impl_from_IStream(iface);
655 return InterlockedIncrement(&This->refs);
656}
657
659{
660 struct test_stream *This = impl_from_IStream(iface);
661 return InterlockedDecrement(&This->refs);
662}
663
664static const IStreamVtbl TestStream_Vtbl =
665{
669 /* the rest can be NULLs */
670};
671
674static struct test_stream Test_Stream = { {&TestStream_Vtbl}, 1 };
675static struct test_stream Test_Stream2 = { {&TestStream_Vtbl}, 1 };
676
678unsigned char * __RPC_USER WdtpInterfacePointer_UserMarshal(ULONG *, ULONG, unsigned char *, IUnknown *, REFIID);
679unsigned char * __RPC_USER WdtpInterfacePointer_UserUnmarshal(ULONG *, unsigned char *, IUnknown **, REFIID);
680
682{
683 USER_MARSHAL_CB umcb;
684 MIDL_STUB_MESSAGE stub_msg;
686 unsigned char *buffer, *buffer_end;
687 ULONG size;
688 IUnknown *unk;
689 IUnknown *unk2;
690 unsigned char *wireip;
692 IStream *stm;
693 void *marshal_data;
696 DWORD marshal_size;
697
698 /* shows that the WdtpInterfacePointer functions don't marshal anything for
699 * NULL pointers, so code using these functions must handle that case
700 * itself */
701
702 unk = NULL;
703 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, umcb_ctx);
705 ok(size == 0, "size should be 0 bytes, not %d\n", size);
708 ok(buffer_end == buffer, "buffer_end %p buffer %p\n", buffer_end, buffer);
710
711 /* Now for a non-NULL pointer. The marshalled data are two size DWORDS and then
712 the result of CoMarshalInterface called with the LOWORD of the ctx */
713
715 Test_Unknown.refs = 1;
716
718 CoMarshalInterface(stm, &IID_IUnknown, unk, LOWORD(ctx), NULL, MSHLFLAGS_NORMAL);
719 zero.QuadPart = 0;
720 IStream_Seek(stm, zero, STREAM_SEEK_CUR, &pos);
721 marshal_size = pos.u.LowPart;
722 marshal_data = GlobalLock(h);
724 ok(Test_Unknown.refs == 2, "got %d\n", Test_Unknown.refs);
725
726 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, umcb_ctx);
728 ok(size >= marshal_size + 2 * sizeof(DWORD), "marshal size %x got %x\n", marshal_size, size);
730 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, umcb_ctx);
733 ok(Test_Unknown.refs == 2, "got %d\n", Test_Unknown.refs);
734 wireip = buffer;
735
736 ok(buffer_end == buffer + marshal_size + 2 * sizeof(DWORD), "buffer_end %p buffer %p\n", buffer_end, buffer);
737
738 ok(*(DWORD *)wireip == marshal_size, "wireip + 0x0 should be %x instead of %x\n", marshal_size, *(DWORD *)wireip);
739 wireip += sizeof(DWORD);
740 ok(*(DWORD *)wireip == marshal_size, "wireip + 0x4 should be %x instead of %x\n", marshal_size, *(DWORD *)wireip);
741 wireip += sizeof(DWORD);
742
743 ok(!memcmp(marshal_data, wireip, marshal_size), "buffer mismatch\n");
745 zero.QuadPart = 0;
746 IStream_Seek(stm, zero, STREAM_SEEK_SET, NULL);
748 IStream_Release(stm);
749
752 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, umcb_ctx);
753 umcb.pStubMsg->IsClient = client;
754 umcb.pStubMsg->fIsIn = in;
755 umcb.pStubMsg->fIsOut = out;
756
758 ok(unk2 != NULL, "IUnknown object didn't unmarshal properly\n");
759 ok(Test_Unknown.refs == 2, "got %d\n", Test_Unknown.refs);
760 ok(Test_Unknown2.refs == 0, "got %d\n", Test_Unknown2.refs);
762 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_INPROC);
763 IUnknown_Release(unk2);
764}
765
767{
768 /*
769 * There are two places where we can pass the marshalling ctx: as
770 * part of the umcb and as a separate flag. The loword of that
771 * separate flag field is what matters.
772 */
773
774 /* All three are marshalled as inproc */
775 marshal_WdtpInterfacePointer(MSHCTX_INPROC, MSHCTX_INPROC, 0,0,0);
776 marshal_WdtpInterfacePointer(MSHCTX_DIFFERENTMACHINE, MSHCTX_INPROC,0,0,0);
777 marshal_WdtpInterfacePointer(MSHCTX_INPROC, MAKELONG(MSHCTX_INPROC, 0xffff),0,0,0);
778
779 /* All three are marshalled as remote */
780 marshal_WdtpInterfacePointer(MSHCTX_INPROC, MSHCTX_DIFFERENTMACHINE,0,0,0);
781 marshal_WdtpInterfacePointer(MSHCTX_DIFFERENTMACHINE, MSHCTX_DIFFERENTMACHINE,0,0,0);
782 marshal_WdtpInterfacePointer(MSHCTX_INPROC, MAKELONG(MSHCTX_DIFFERENTMACHINE, 0xffff),0,0,0);
783
784 /* Test different combinations of client, in and out */
785 marshal_WdtpInterfacePointer(MSHCTX_INPROC, MSHCTX_DIFFERENTMACHINE,0,0,1);
786 marshal_WdtpInterfacePointer(MSHCTX_INPROC, MSHCTX_DIFFERENTMACHINE,0,1,0);
787 marshal_WdtpInterfacePointer(MSHCTX_INPROC, MSHCTX_DIFFERENTMACHINE,0,1,1);
788 marshal_WdtpInterfacePointer(MSHCTX_INPROC, MSHCTX_DIFFERENTMACHINE,1,0,0);
789 marshal_WdtpInterfacePointer(MSHCTX_INPROC, MSHCTX_DIFFERENTMACHINE,1,0,1);
790 marshal_WdtpInterfacePointer(MSHCTX_INPROC, MSHCTX_DIFFERENTMACHINE,1,1,0);
791 marshal_WdtpInterfacePointer(MSHCTX_INPROC, MSHCTX_DIFFERENTMACHINE,1,1,1);
792}
793
795{
796 USER_MARSHAL_CB umcb;
797 MIDL_STUB_MESSAGE stub_msg;
799 unsigned char *buffer, *buffer_end, *expect_buffer, *expect_buffer_end;
800 ULONG size, expect_size;
801 STGMEDIUM med, med2;
803 IStream *stm = &Test_Stream.IStream_iface;
804
805 /* TYMED_NULL with pUnkForRelease */
806
807 Test_Unknown.refs = 1;
808
809 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
810 expect_size = WdtpInterfacePointer_UserSize(&umcb.Flags, umcb.Flags, 2 * sizeof(DWORD), unk, &IID_IUnknown);
811 expect_buffer = HeapAlloc(GetProcessHeap(), 0, expect_size);
812 *(DWORD*)expect_buffer = TYMED_NULL;
813 *((DWORD*)expect_buffer + 1) = 0xdeadbeef;
814 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, expect_buffer, expect_size, MSHCTX_DIFFERENTMACHINE);
815 expect_buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, umcb.Flags, expect_buffer + 2 * sizeof(DWORD), unk, &IID_IUnknown);
816
817 med.tymed = TYMED_NULL;
818 U(med).pstg = NULL;
819 med.pUnkForRelease = unk;
820
821 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
822 size = STGMEDIUM_UserSize(&umcb.Flags, 0, &med);
823 ok(size == expect_size, "size %d should be %d bytes\n", size, expect_size);
824
826 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
828 ok(buffer_end - buffer == expect_buffer_end - expect_buffer, "buffer size mismatch\n");
829 ok(*(DWORD*)buffer == TYMED_NULL, "got %08x\n", *(DWORD*)buffer);
830 ok(*((DWORD*)buffer+1) != 0, "got %08x\n", *((DWORD*)buffer+1));
831 ok(!memcmp(buffer+8, expect_buffer + 8, expect_buffer_end - expect_buffer - 8), "buffer mismatch\n");
832
833 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
834 umcb.pStubMsg->IsClient = client;
835 umcb.pStubMsg->fIsIn = in;
836 umcb.pStubMsg->fIsOut = out;
837
839 med2.tymed = TYMED_NULL;
840 U(med2).pstm = NULL;
841 med2.pUnkForRelease = &Test_Unknown2.IUnknown_iface;
842
843 STGMEDIUM_UserUnmarshal(&umcb.Flags, buffer, &med2);
844
845 ok(med2.tymed == TYMED_NULL, "got tymed %x\n", med2.tymed);
846 ok(med2.pUnkForRelease != NULL, "Incorrectly unmarshalled\n");
847 ok(Test_Unknown2.refs == 0, "got %d\n", Test_Unknown2.refs);
848
850 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
851 STGMEDIUM_UserFree(&umcb.Flags, &med2);
852
853 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, expect_buffer, expect_size, MSHCTX_DIFFERENTMACHINE);
854 med2.tymed = TYMED_NULL;
855 U(med2).pstm = NULL;
856 med2.pUnkForRelease = NULL;
857 STGMEDIUM_UserUnmarshal(&umcb.Flags, expect_buffer, &med2);
858 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
859 STGMEDIUM_UserFree(&umcb.Flags, &med2);
860
861 ok(Test_Unknown.refs == 1, "got %d\n", Test_Unknown.refs);
862
863 HeapFree(GetProcessHeap(), 0, expect_buffer);
864
865 /* TYMED_ISTREAM with pUnkForRelease */
866
867 Test_Unknown.refs = 1;
868 Test_Stream.refs = 1;
869
870 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
871 expect_size = WdtpInterfacePointer_UserSize(&umcb.Flags, umcb.Flags, 3 * sizeof(DWORD), (IUnknown*)stm, &IID_IStream);
872 expect_size = WdtpInterfacePointer_UserSize(&umcb.Flags, umcb.Flags, expect_size, unk, &IID_IUnknown);
873
874 expect_buffer = HeapAlloc(GetProcessHeap(), 0, expect_size);
875 /* There may be a hole between the two interfaces so init the buffer to something */
876 memset(expect_buffer, 0xcc, expect_size);
877 *(DWORD*)expect_buffer = TYMED_ISTREAM;
878 *((DWORD*)expect_buffer + 1) = 0xdeadbeef;
879 *((DWORD*)expect_buffer + 2) = 0xcafe;
880 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, expect_buffer, expect_size, MSHCTX_DIFFERENTMACHINE);
881 expect_buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, umcb.Flags, expect_buffer + 3 * sizeof(DWORD), (IUnknown*)stm, &IID_IStream);
882 expect_buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, umcb.Flags, expect_buffer_end, unk, &IID_IUnknown);
883
884 med.tymed = TYMED_ISTREAM;
885 U(med).pstm = stm;
886 med.pUnkForRelease = unk;
887
888 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
889 size = STGMEDIUM_UserSize(&umcb.Flags, 0, &med);
890 ok(size == expect_size, "size %d should be %d bytes\n", size, expect_size);
891
893 memset(buffer, 0xcc, size);
894 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
896 ok(buffer_end - buffer == expect_buffer_end - expect_buffer, "buffer size mismatch\n");
897 ok(*(DWORD*)buffer == TYMED_ISTREAM, "got %08x\n", *(DWORD*)buffer);
898 ok(*((DWORD*)buffer+1) != 0, "got %08x\n", *((DWORD*)buffer+1));
899 ok(*((DWORD*)buffer+2) != 0, "got %08x\n", *((DWORD*)buffer+2));
900 ok(!memcmp(buffer + 12, expect_buffer + 12, (buffer_end - buffer) - 12), "buffer mismatch\n");
901
902 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
903 umcb.pStubMsg->IsClient = client;
904 umcb.pStubMsg->fIsIn = in;
905 umcb.pStubMsg->fIsOut = out;
906
907 Test_Stream2.refs = 1;
909 med2.tymed = TYMED_ISTREAM;
910 U(med2).pstm = &Test_Stream2.IStream_iface;
911 med2.pUnkForRelease = &Test_Unknown2.IUnknown_iface;
912
913 STGMEDIUM_UserUnmarshal(&umcb.Flags, buffer, &med2);
914
915 ok(med2.tymed == TYMED_ISTREAM, "got tymed %x\n", med2.tymed);
916 ok(U(med2).pstm != NULL, "Incorrectly unmarshalled\n");
917 ok(med2.pUnkForRelease != NULL, "Incorrectly unmarshalled\n");
918 ok(Test_Stream2.refs == 0, "got %d\n", Test_Stream2.refs);
919 ok(Test_Unknown2.refs == 0, "got %d\n", Test_Unknown2.refs);
920
922 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
923 STGMEDIUM_UserFree(&umcb.Flags, &med2);
924
925 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, expect_buffer, expect_size, MSHCTX_DIFFERENTMACHINE);
926 med2.tymed = TYMED_NULL;
927 U(med2).pstm = NULL;
928 med2.pUnkForRelease = NULL;
929 STGMEDIUM_UserUnmarshal(&umcb.Flags, expect_buffer, &med2);
930 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
931 STGMEDIUM_UserFree(&umcb.Flags, &med2);
932
933 ok(Test_Unknown.refs == 1, "got %d\n", Test_Unknown.refs);
934 ok(Test_Stream.refs == 1, "got %d\n", Test_Stream.refs);
935
936 HeapFree(GetProcessHeap(), 0, expect_buffer);
937
938 /* TYMED_ISTREAM = NULL with pUnkForRelease = NULL */
939
940 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
941 expect_size = 3 * sizeof(DWORD);
942
943 med.tymed = TYMED_ISTREAM;
944 U(med).pstm = NULL;
945 med.pUnkForRelease = NULL;
946
947 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
948 size = STGMEDIUM_UserSize(&umcb.Flags, 0, &med);
949 ok(size == expect_size, "size %d should be %d bytes\n", size, expect_size);
950
952 memset(buffer, 0xcc, size);
953 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
955 ok(buffer_end - buffer == expect_size, "buffer size mismatch\n");
956 ok(*(DWORD*)buffer == TYMED_ISTREAM, "got %08x\n", *(DWORD*)buffer);
957 ok(*((DWORD*)buffer+1) == 0, "got %08x\n", *((DWORD*)buffer+1));
958 ok(*((DWORD*)buffer+2) == 0, "got %08x\n", *((DWORD*)buffer+2));
959
960 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
961 umcb.pStubMsg->IsClient = client;
962 umcb.pStubMsg->fIsIn = in;
963 umcb.pStubMsg->fIsOut = out;
964
965 Test_Stream2.refs = 1;
967 med2.tymed = TYMED_ISTREAM;
968 U(med2).pstm = &Test_Stream2.IStream_iface;
969 med2.pUnkForRelease = &Test_Unknown2.IUnknown_iface;
970
971 STGMEDIUM_UserUnmarshal(&umcb.Flags, buffer, &med2);
972
973 ok(med2.tymed == TYMED_ISTREAM, "got tymed %x\n", med2.tymed);
974 ok(U(med2).pstm == NULL, "Incorrectly unmarshalled\n");
975 ok(med2.pUnkForRelease == &Test_Unknown2.IUnknown_iface, "Incorrectly unmarshalled\n");
976 ok(Test_Stream2.refs == 0, "got %d\n", Test_Stream2.refs);
977 ok(Test_Unknown2.refs == 1, "got %d\n", Test_Unknown2.refs);
978
980 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
981 STGMEDIUM_UserFree(&umcb.Flags, &med2);
982}
983
984static void test_marshal_STGMEDIUM(void)
985{
986 marshal_STGMEDIUM(0, 0, 0);
987 marshal_STGMEDIUM(0, 0, 1);
988 marshal_STGMEDIUM(0, 1, 0);
989 marshal_STGMEDIUM(0, 1, 1);
990 /* For Windows versions post 2003, client side, non-[in,out] STGMEDIUMs get zero-initialised.
991 However since inline stubs don't set fIsIn or fIsOut this behaviour would break
992 ref counting in GetDataHere_Proxy for example, as we'd end up not releasing the original
993 interface. For simplicity we don't test or implement this. */
994 marshal_STGMEDIUM(1, 1, 1);
995}
996
997static void test_marshal_SNB(void)
998{
999 static const WCHAR str1W[] = {'s','t','r','i','n','g','1',0};
1000 static const WCHAR str2W[] = {'s','t','r','2',0};
1001 unsigned char *buffer, *src, *mbuf;
1002 MIDL_STUB_MESSAGE stub_msg;
1003 WCHAR **ptrW, *dataW;
1004 USER_MARSHAL_CB umcb;
1006 RemSNB *wiresnb;
1007 SNB snb, snb2;
1008 ULONG size;
1009
1010 /* 4 bytes alignment */
1011 snb = NULL;
1012 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
1013 size = SNB_UserSize(&umcb.Flags, 3, &snb);
1014 ok(size == 16, "Size should be 16, instead of %d\n", size);
1015
1016 /* NULL block */
1017 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
1018 size = SNB_UserSize(&umcb.Flags, 0, &snb);
1019 ok(size == 12, "Size should be 12, instead of %d\n", size);
1020
1022 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
1023 mbuf = SNB_UserMarshal(&umcb.Flags, buffer, &snb);
1024 ok(mbuf == buffer + size, "got %p, %p\n", mbuf, buffer + size);
1025
1026 wiresnb = (RemSNB*)buffer;
1027 ok(wiresnb->ulCntStr == 0, "got %u\n", wiresnb->ulCntStr);
1028 ok(wiresnb->ulCntChar == 0, "got %u\n", wiresnb->ulCntChar);
1029 ok(*(ULONG*)wiresnb->rgString == 0, "got %u\n", *(ULONG*)wiresnb->rgString);
1030
1031 snb2 = NULL;
1032 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
1033 SNB_UserUnmarshal(&umcb.Flags, buffer, &snb2);
1034 ok(snb2 == NULL, "got %p\n", snb2);
1035
1037 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
1038 SNB_UserFree(&umcb.Flags, &snb2);
1039
1040 /* block with actual data */
1041
1042 /* allocate source block, n+1 pointers first, then data */
1043 src = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR*)*3 + sizeof(str1W) + sizeof(str2W));
1044 ptrW = (WCHAR**)src;
1045 dataW = *ptrW = (WCHAR*)(src + 3*sizeof(WCHAR*));
1046 ptrW++;
1047 *ptrW = (WCHAR*)(src + 3*sizeof(WCHAR*) + sizeof(str1W));
1048 ptrW++;
1049 *ptrW = NULL;
1050 lstrcpyW(dataW, str1W);
1051 dataW += lstrlenW(str1W) + 1;
1052 lstrcpyW(dataW, str2W);
1053
1054 snb = (SNB)src;
1055 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
1056 size = SNB_UserSize(&umcb.Flags, 0, &snb);
1057 ok(size == 38, "Size should be 38, instead of %d\n", size);
1058
1060 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
1061 SNB_UserMarshal(&umcb.Flags, buffer, &snb);
1062
1063 wiresnb = (RemSNB*)buffer;
1064 ok(wiresnb->ulCntStr == 13, "got %u\n", wiresnb->ulCntStr);
1065 ok(wiresnb->ulCntChar == 2, "got %u\n", wiresnb->ulCntChar);
1066 /* payload length is stored one more time, as ULONG */
1067 ok(*(ULONG*)wiresnb->rgString == wiresnb->ulCntStr, "got %u\n", *(ULONG*)wiresnb->rgString);
1068 dataW = &wiresnb->rgString[2];
1069 ok(!lstrcmpW(dataW, str1W), "marshalled string 0: %s\n", wine_dbgstr_w(dataW));
1070 dataW += ARRAY_SIZE(str1W);
1071 ok(!lstrcmpW(dataW, str2W), "marshalled string 1: %s\n", wine_dbgstr_w(dataW));
1072
1073 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
1074
1076 snb2 = NULL;
1077 SNB_UserUnmarshal(&umcb.Flags, buffer, &snb2);
1079
1080 ptrW = snb2;
1081 ok(!lstrcmpW(*ptrW, str1W), "unmarshalled string 0: %s\n", wine_dbgstr_w(*ptrW));
1082 ptrW++;
1083 ok(!lstrcmpW(*ptrW, str2W), "unmarshalled string 1: %s\n", wine_dbgstr_w(*ptrW));
1084 ptrW++;
1085 ok(*ptrW == NULL, "expected terminating NULL ptr, got %p, start %p\n", *ptrW, snb2);
1086
1088 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
1089
1091 SNB_UserFree(&umcb.Flags, &snb2);
1093
1095}
1096
1097static void test_marshal_HDC(void)
1098{
1099 MIDL_STUB_MESSAGE stub_msg;
1100 HDC hdc = GetDC(0), hdc2;
1101 USER_MARSHAL_CB umcb;
1103 unsigned char *buffer, *buffer_end;
1104 wireHDC wirehdc;
1105 ULONG size;
1106
1107 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
1108 size = HDC_UserSize(&umcb.Flags, 1, &hdc);
1109 ok(size == 4 + sizeof(*wirehdc), "Wrong size %d\n", size);
1110
1112 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
1113 buffer_end = HDC_UserMarshal(&umcb.Flags, buffer + 1, &hdc);
1114 ok(buffer_end == buffer + 4 + sizeof(*wirehdc), "got %p buffer %p\n", buffer_end, buffer);
1115 wirehdc = (wireHDC)(buffer + 4);
1116 ok(wirehdc->fContext == WDT_INPROC_CALL, "Context should be WDT_INPROC_CALL instead of 0x%08x\n", wirehdc->fContext);
1117 ok(wirehdc->u.hInproc == (LONG_PTR)hdc, "Marshaled value should be %p instead of %x\n", hdc, wirehdc->u.hRemote);
1118
1119 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
1120 buffer_end = HDC_UserUnmarshal(&umcb.Flags, buffer + 1, &hdc2);
1121 ok(buffer_end == buffer + 4 + sizeof(*wirehdc), "got %p buffer %p\n", buffer_end, buffer);
1122 ok(hdc == hdc2, "Didn't unmarshal properly\n");
1124
1125 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
1126 HDC_UserFree(&umcb.Flags, &hdc2);
1127 ReleaseDC(0, hdc);
1128}
1129
1130static void test_marshal_HICON(void)
1131{
1132 static const BYTE bmp_bits[1024];
1133 MIDL_STUB_MESSAGE stub_msg;
1135 USER_MARSHAL_CB umcb;
1137 unsigned char *buffer, *buffer_end;
1138 wireHICON wirehicon;
1139 ULONG size;
1140
1141 hIcon = CreateIcon(0, 16, 16, 1, 1, bmp_bits, bmp_bits);
1142 ok(hIcon != 0, "CreateIcon failed\n");
1143
1144 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
1145 size = HICON_UserSize(&umcb.Flags, 1, &hIcon);
1146 ok(size == 4 + sizeof(*wirehicon), "Wrong size %d\n", size);
1147
1149 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
1150 buffer_end = HICON_UserMarshal(&umcb.Flags, buffer + 1, &hIcon);
1151 ok(buffer_end == buffer + 4 + sizeof(*wirehicon), "got %p buffer %p\n", buffer_end, buffer);
1152 wirehicon = (wireHICON)(buffer + 4);
1153 ok(wirehicon->fContext == WDT_INPROC_CALL, "Context should be WDT_INPROC_CALL instead of 0x%08x\n", wirehicon->fContext);
1154 ok(wirehicon->u.hInproc == (LONG_PTR)hIcon, "Marshaled value should be %p instead of %x\n", hIcon, wirehicon->u.hRemote);
1155
1156 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
1157 buffer_end = HICON_UserUnmarshal(&umcb.Flags, buffer + 1, &hIcon2);
1158 ok(buffer_end == buffer + 4 + sizeof(*wirehicon), "got %p buffer %p\n", buffer_end, buffer);
1159 ok(hIcon == hIcon2, "Didn't unmarshal properly\n");
1161
1162 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
1163 HICON_UserFree(&umcb.Flags, &hIcon2);
1165}
1166
1167static void test_marshal_HBRUSH(void)
1168{
1169 MIDL_STUB_MESSAGE stub_msg;
1170 HBRUSH hBrush, hBrush2;
1171 USER_MARSHAL_CB umcb;
1173 unsigned char *buffer, *buffer_end;
1174 LOGBRUSH logbrush;
1175 wireHBRUSH wirehbrush;
1176 ULONG size;
1177
1178 logbrush.lbStyle = BS_SOLID;
1179 logbrush.lbColor = RGB(0, 0, 0);
1180 logbrush.lbHatch = 0;
1181
1182 hBrush = CreateBrushIndirect(&logbrush);
1183 ok(hBrush != 0, "CreateBrushIndirect failed\n");
1184
1185 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
1186 size = HBRUSH_UserSize(&umcb.Flags, 1, &hBrush);
1187 ok(size == 4 + sizeof(*wirehbrush), "Wrong size %d\n", size);
1188
1190 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
1191 buffer_end = HBRUSH_UserMarshal(&umcb.Flags, buffer + 1, &hBrush);
1192 ok(buffer_end == buffer + 4 + sizeof(*wirehbrush), "got %p buffer %p\n", buffer_end, buffer);
1193 wirehbrush = (wireHBRUSH)(buffer + 4);
1194 ok(wirehbrush->fContext == WDT_INPROC_CALL, "Context should be WDT_INPROC_CALL instead of 0x%08x\n", wirehbrush->fContext);
1195 ok(wirehbrush->u.hInproc == (LONG_PTR)hBrush, "Marshaled value should be %p instead of %x\n", hBrush, wirehbrush->u.hRemote);
1196
1197 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
1198 buffer_end = HBRUSH_UserUnmarshal(&umcb.Flags, buffer + 1, &hBrush2);
1199 ok(buffer_end == buffer + 4 + sizeof(*wirehbrush), "got %p buffer %p\n", buffer_end, buffer);
1200 ok(hBrush == hBrush2, "Didn't unmarshal properly\n");
1202
1203 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
1204 HBRUSH_UserFree(&umcb.Flags, &hBrush2);
1205 DeleteObject(hBrush);
1206}
1207
1208static void test_marshal_HBITMAP(void)
1209{
1210 static const ULONG header_size = FIELD_OFFSET(userBITMAP, cbSize);
1211 static BYTE bmp_bits[1024];
1212 MIDL_STUB_MESSAGE stub_msg;
1213 HBITMAP hBitmap, hBitmap2;
1214 USER_MARSHAL_CB umcb;
1216 unsigned char *buffer, *buffer_end;
1217 unsigned char bitmap[1024];
1218 ULONG size, bitmap_size;
1219
1220 hBitmap = CreateBitmap(16, 16, 1, 1, bmp_bits);
1221 ok(hBitmap != 0, "CreateBitmap failed\n");
1222 size = GetObjectA(hBitmap, sizeof(bitmap), bitmap);
1223 ok(size != 0, "GetObject failed\n");
1224 bitmap_size = GetBitmapBits(hBitmap, 0, NULL);
1225 ok(bitmap_size != 0, "GetBitmapBits failed\n");
1226
1227 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_INPROC);
1228 size = HBITMAP_UserSize(&umcb.Flags, 1, &hBitmap);
1229 ok(size == 0xc, "Wrong size %d\n", size);
1230 buffer = HeapAlloc(GetProcessHeap(), 0, size + 4);
1231 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_INPROC);
1233 ok(buffer_end == buffer + 0xc, "HBITMAP_UserMarshal() returned wrong size %d\n", (LONG)(buffer_end - buffer));
1234 ok(*(ULONG *)(buffer + 0x4) == WDT_INPROC_CALL, "Context should be WDT_INPROC_CALL instead of 0x%08x\n", *(ULONG *)(buffer + 0x4));
1235 ok(*(ULONG *)(buffer + 0x8) == (ULONG)(ULONG_PTR)hBitmap, "wirestgm + 0x4 should be bitmap handle instead of 0x%08x\n", *(ULONG *)(buffer + 0x8));
1236
1237 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_INPROC);
1238 HBITMAP_UserUnmarshal(&umcb.Flags, buffer + 1, &hBitmap2);
1239 ok(hBitmap2 != NULL, "Didn't unmarshal properly\n");
1241
1242 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_INPROC);
1243 HBITMAP_UserFree(&umcb.Flags, &hBitmap2);
1244
1245 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
1246 size = HBITMAP_UserSize(&umcb.Flags, 1, &hBitmap);
1247 ok(size == 0x10 + header_size + bitmap_size ||
1248 broken(size == 0x14 + header_size + bitmap_size), /* Windows adds 4 extra (unused) bytes */
1249 "Wrong size %d\n", size);
1250
1251 buffer = HeapAlloc(GetProcessHeap(), 0, size + 4);
1252 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
1254 ok(buffer_end == buffer + 0x10 + header_size + bitmap_size, "HBITMAP_UserMarshal() returned wrong size %d\n", (LONG)(buffer_end - buffer));
1255 ok(*(ULONG *)(buffer + 0x4) == WDT_REMOTE_CALL, "Context should be WDT_REMOTE_CALL instead of 0x%08x\n", *(ULONG *)buffer);
1256 ok(*(ULONG *)(buffer + 0x8) == (ULONG)(ULONG_PTR)hBitmap, "wirestgm + 0x4 should be bitmap handle instead of 0x%08x\n", *(ULONG *)(buffer + 0x4));
1257 ok(*(ULONG *)(buffer + 0xc) == (ULONG)(ULONG_PTR)bitmap_size, "wirestgm + 0x8 should be bitmap size instead of 0x%08x\n", *(ULONG *)(buffer + 0x4));
1258 ok(!memcmp(buffer + 0x10, bitmap, header_size), "buffer mismatch\n");
1259 ok(!memcmp(buffer + 0x10 + header_size, bmp_bits, bitmap_size), "buffer mismatch\n");
1260
1261 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
1262 HBITMAP_UserUnmarshal(&umcb.Flags, buffer + 1, &hBitmap2);
1263 ok(hBitmap2 != NULL, "Didn't unmarshal properly\n");
1265
1266 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
1267 HBITMAP_UserFree(&umcb.Flags, &hBitmap2);
1269}
1270
1271struct obj
1272{
1274};
1275
1277{
1278 *obj = NULL;
1279
1280 if (IsEqualGUID(iid, &IID_IUnknown) ||
1282 *obj = iface;
1283
1284 if (*obj)
1285 {
1286 IDataObject_AddRef(iface);
1287 return S_OK;
1288 }
1289
1290 return E_NOINTERFACE;
1291}
1292
1294{
1295 return 2;
1296}
1297
1299{
1300 return 1;
1301}
1302
1304 STGMEDIUM *med)
1305{
1306 ok( med->pUnkForRelease == NULL, "got %p\n", med->pUnkForRelease );
1307
1308 if (fmt->cfFormat == 2)
1309 {
1310 IStream_Release(U(med)->pstm);
1311 U(med)->pstm = &Test_Stream2.IStream_iface;
1312 }
1313
1314 return S_OK;
1315}
1316
1317static const IDataObjectVtbl obj_data_object_vtbl =
1318{
1320 obj_AddRef,
1322 NULL, /* GetData */
1324 NULL, /* QueryGetData */
1325 NULL, /* GetCanonicalFormatEtc */
1326 NULL, /* SetData */
1327 NULL, /* EnumFormatEtc */
1328 NULL, /* DAdvise */
1329 NULL, /* DUnadvise */
1330 NULL /* EnumDAdvise */
1331};
1332
1333static struct obj obj =
1334{
1336};
1337
1338static void test_GetDataHere_Proxy(void)
1339{
1340 HRESULT hr;
1341 IStream *stm;
1342 HANDLE thread;
1343 DWORD tid;
1344 static const LARGE_INTEGER zero;
1346 FORMATETC fmt;
1347 STGMEDIUM med;
1348
1349 hr = CreateStreamOnHGlobal( NULL, TRUE, &stm );
1350 ok( hr == S_OK, "got %08x\n", hr );
1351 tid = start_host_object2( stm, &IID_IDataObject, (IUnknown *)&obj.IDataObject_iface, MSHLFLAGS_NORMAL, NULL, &thread );
1352
1353 IStream_Seek( stm, zero, STREAM_SEEK_SET, NULL );
1354 hr = CoUnmarshalInterface( stm, &IID_IDataObject, (void **)&data );
1355 ok( hr == S_OK, "got %08x\n", hr );
1356 IStream_Release( stm );
1357
1358 Test_Stream.refs = 1;
1359 Test_Stream2.refs = 1;
1360 Test_Unknown.refs = 1;
1361
1362 fmt.cfFormat = 1;
1363 fmt.ptd = NULL;
1364 fmt.dwAspect = DVASPECT_CONTENT;
1365 fmt.lindex = -1;
1366 U(med).pstm = NULL;
1367 med.pUnkForRelease = &Test_Unknown.IUnknown_iface;
1368
1369 fmt.tymed = med.tymed = TYMED_NULL;
1370 hr = IDataObject_GetDataHere( data, &fmt, &med );
1371 ok( hr == DV_E_TYMED, "got %08x\n", hr );
1372
1373 for (fmt.tymed = TYMED_HGLOBAL; fmt.tymed <= TYMED_ENHMF; fmt.tymed <<= 1)
1374 {
1375 med.tymed = fmt.tymed;
1376 hr = IDataObject_GetDataHere( data, &fmt, &med );
1377 ok( hr == (fmt.tymed <= TYMED_ISTORAGE ? S_OK : DV_E_TYMED), "got %08x for tymed %d\n", hr, fmt.tymed );
1378 ok( Test_Unknown.refs == 1, "got %d\n", Test_Unknown.refs );
1379 }
1380
1381 fmt.tymed = TYMED_ISTREAM;
1382 med.tymed = TYMED_ISTORAGE;
1383 hr = IDataObject_GetDataHere( data, &fmt, &med );
1384 ok( hr == DV_E_TYMED, "got %08x\n", hr );
1385
1386 fmt.tymed = med.tymed = TYMED_ISTREAM;
1387 U(med).pstm = &Test_Stream.IStream_iface;
1388 med.pUnkForRelease = &Test_Unknown.IUnknown_iface;
1389
1390 hr = IDataObject_GetDataHere( data, &fmt, &med );
1391 ok( hr == S_OK, "got %08x\n", hr );
1392
1393 ok( U(med).pstm == &Test_Stream.IStream_iface, "stm changed\n" );
1394 ok( med.pUnkForRelease == &Test_Unknown.IUnknown_iface, "punk changed\n" );
1395
1396 ok( Test_Stream.refs == 1, "got %d\n", Test_Stream.refs );
1397 ok( Test_Unknown.refs == 1, "got %d\n", Test_Unknown.refs );
1398
1399 fmt.cfFormat = 2;
1400 fmt.tymed = med.tymed = TYMED_ISTREAM;
1401 U(med).pstm = &Test_Stream.IStream_iface;
1402 med.pUnkForRelease = &Test_Unknown.IUnknown_iface;
1403
1404 hr = IDataObject_GetDataHere( data, &fmt, &med );
1405 ok( hr == S_OK, "got %08x\n", hr );
1406
1407 ok( U(med).pstm == &Test_Stream.IStream_iface, "stm changed\n" );
1408 ok( med.pUnkForRelease == &Test_Unknown.IUnknown_iface, "punk changed\n" );
1409
1410 ok( Test_Stream.refs == 1, "got %d\n", Test_Stream.refs );
1411 ok( Test_Unknown.refs == 1, "got %d\n", Test_Unknown.refs );
1412 ok( Test_Stream2.refs == 0, "got %d\n", Test_Stream2.refs );
1413
1414 IDataObject_Release( data );
1416}
1417
1418START_TEST(usrmarshal)
1419{
1421
1435
1437
1439}
static HICON hIcon2
HDC hdc2
Definition: SelectObject.c:10
#define broken(x)
Definition: _sntprintf.h:21
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
#define msg(x)
Definition: auth_time.c:54
#define ARRAY_SIZE(A)
Definition: main.h:33
#define U(x)
Definition: wordpad.c:45
static HANDLE thread
Definition: service.c:33
const GUID IID_IUnknown
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static HBITMAP hBitmap
Definition: timezone.c:26
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CALLBACK
Definition: compat.h:35
#define lstrcpyW
Definition: compat.h:749
#define lstrlenW
Definition: compat.h:750
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
HRESULT WINAPI CoRegisterMessageFilter(LPMESSAGEFILTER lpMessageFilter, LPMESSAGEFILTER *lplpMessageFilter)
Definition: compobj.c:4046
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
Definition: compobj.c:2002
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm)
HRESULT WINAPI CoReleaseMarshalData(IStream *pStream)
Definition: marshal.c:2055
HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv)
Definition: marshal.c:1981
HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk, DWORD dwDestContext, void *pvDestContext, DWORD mshlFlags)
Definition: marshal.c:1876
void __RPC_USER HBITMAP_UserFree(ULONG *flags, HBITMAP *bmp)
Definition: usrmarshal.c:771
void __RPC_USER HMETAFILE_UserFree(ULONG *pFlags, HMETAFILE *phmf)
Definition: usrmarshal.c:1069
unsigned char *__RPC_USER CLIPFORMAT_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, CLIPFORMAT *pCF)
Definition: usrmarshal.c:145
unsigned char *__RPC_USER STGMEDIUM_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, STGMEDIUM *pStgMedium)
Definition: usrmarshal.c:1785
ULONG __RPC_USER HMETAFILEPICT_UserSize(ULONG *pFlags, ULONG size, HMETAFILEPICT *phMfp)
Definition: usrmarshal.c:1293
ULONG __RPC_USER HMETAFILE_UserSize(ULONG *pFlags, ULONG StartingSize, HMETAFILE *phmf)
Definition: usrmarshal.c:899
unsigned char *__RPC_USER SNB_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, SNB *pSnb)
Definition: usrmarshal.c:2179
unsigned char *__RPC_USER HMETAFILEPICT_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HMETAFILEPICT *phMfp)
Definition: usrmarshal.c:1406
unsigned char *__RPC_USER HMETAFILE_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HMETAFILE *phmf)
Definition: usrmarshal.c:1004
void __RPC_USER HENHMETAFILE_UserFree(ULONG *pFlags, HENHMETAFILE *phEmf)
Definition: usrmarshal.c:1265
unsigned char *WINAPI WdtpInterfacePointer_UserMarshal(ULONG *pFlags, ULONG RealFlags, unsigned char *pBuffer, IUnknown *punk, REFIID riid)
Definition: usrmarshal.c:1550
ULONG __RPC_USER CLIPFORMAT_UserSize(ULONG *pFlags, ULONG size, CLIPFORMAT *pCF)
Definition: usrmarshal.c:100
#define USER_MARSHAL_PTR_PREFIX
Definition: usrmarshal.c:47
ULONG __RPC_USER HBITMAP_UserSize(ULONG *flags, ULONG size, HBITMAP *bmp)
Definition: usrmarshal.c:598
unsigned char *__RPC_USER HMETAFILE_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HMETAFILE *phmf)
Definition: usrmarshal.c:946
unsigned char *__RPC_USER HGLOBAL_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HGLOBAL *phGlobal)
Definition: usrmarshal.c:425
unsigned char *__RPC_USER STGMEDIUM_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, STGMEDIUM *pStgMedium)
Definition: usrmarshal.c:1895
unsigned char *__RPC_USER SNB_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, SNB *pSnb)
Definition: usrmarshal.c:2143
unsigned char *__RPC_USER HENHMETAFILE_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HENHMETAFILE *phEmf)
Definition: usrmarshal.c:1200
unsigned char *__RPC_USER HBITMAP_UserMarshal(ULONG *flags, unsigned char *buffer, HBITMAP *bmp)
Definition: usrmarshal.c:641
void __RPC_USER STGMEDIUM_UserFree(ULONG *flags, STGMEDIUM *med)
Definition: usrmarshal.c:2038
unsigned char *__RPC_USER HMETAFILEPICT_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HMETAFILEPICT *phMfp)
Definition: usrmarshal.c:1343
ULONG __RPC_USER HENHMETAFILE_UserSize(ULONG *pFlags, ULONG size, HENHMETAFILE *phEmf)
Definition: usrmarshal.c:1097
void __RPC_USER HMETAFILEPICT_UserFree(ULONG *pFlags, HMETAFILEPICT *phMfp)
Definition: usrmarshal.c:1477
unsigned char *__RPC_USER HENHMETAFILE_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HENHMETAFILE *phEmf)
Definition: usrmarshal.c:1142
ULONG __RPC_USER HGLOBAL_UserSize(ULONG *pFlags, ULONG StartingSize, HGLOBAL *phGlobal)
Definition: usrmarshal.c:379
unsigned char *__RPC_USER HBITMAP_UserUnmarshal(ULONG *flags, unsigned char *buffer, HBITMAP *bmp)
Definition: usrmarshal.c:701
ULONG __RPC_USER SNB_UserSize(ULONG *pFlags, ULONG StartingSize, SNB *pSnb)
Definition: usrmarshal.c:2110
ULONG __RPC_USER STGMEDIUM_UserSize(ULONG *pFlags, ULONG StartingSize, STGMEDIUM *pStgMedium)
Definition: usrmarshal.c:1690
void __RPC_USER CLIPFORMAT_UserFree(ULONG *pFlags, CLIPFORMAT *pCF)
Definition: usrmarshal.c:274
unsigned char *WINAPI WdtpInterfacePointer_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, IUnknown **ppunk, REFIID riid)
Definition: usrmarshal.c:1607
unsigned char *__RPC_USER CLIPFORMAT_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, CLIPFORMAT *pCF)
Definition: usrmarshal.c:207
void __RPC_USER SNB_UserFree(ULONG *pFlags, SNB *pSnb)
Definition: usrmarshal.c:2217
unsigned char *__RPC_USER HGLOBAL_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HGLOBAL *phGlobal)
Definition: usrmarshal.c:487
void __RPC_USER HGLOBAL_UserFree(ULONG *pFlags, HGLOBAL *phGlobal)
Definition: usrmarshal.c:570
ULONG __RPC_USER WdtpInterfacePointer_UserSize(ULONG *pFlags, ULONG RealFlags, ULONG StartingSize, IUnknown *punk, REFIID riid)
Definition: usrmarshal.c:1515
#define RGB(r, g, b)
Definition: precomp.h:71
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
pKey DeleteObject()
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
GLenum src
Definition: glext.h:6340
GLuint buffer
Definition: glext.h:5915
GLuint in
Definition: glext.h:9616
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glext.h:7005
GLfloat GLfloat p
Definition: glext.h:8902
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
SIZE_T NTAPI GlobalSize(HGLOBAL hMem)
Definition: heapmem.c:1090
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define buffer_end
Definition: intsym.h:274
static DWORD block_size(DWORD block)
Definition: jsutils.c:66
#define wine_dbgstr_w
Definition: kernel32.h:34
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
HDC hdc
Definition: main.c:9
static HBITMAP
Definition: button.c:44
static HDC
Definition: imagelist.c:92
static HICON
Definition: imagelist.c:84
static TfClientId tid
#define todo_wine
Definition: custom.c:79
static void WINAPI user_free(void *p)
Definition: usrmarshal.c:60
static void marshal_STGMEDIUM(BOOL client, BOOL in, BOOL out)
Definition: usrmarshal.c:794
static void test_marshal_HENHMETAFILE(void)
Definition: usrmarshal.c:345
static const IStreamVtbl TestStream_Vtbl
Definition: usrmarshal.c:664
static void marshal_WdtpInterfacePointer(DWORD umcb_ctx, DWORD ctx, BOOL client, BOOL in, BOOL out)
Definition: usrmarshal.c:681
static HRESULT WINAPI Test_IUnknown_QueryInterface(LPUNKNOWN iface, REFIID riid, LPVOID *ppvObj)
Definition: usrmarshal.c:587
static ULONG WINAPI obj_AddRef(IDataObject *iface)
Definition: usrmarshal.c:1293
static HMETAFILE create_mf(void)
Definition: usrmarshal.c:411
static ULONG WINAPI Test_IStream_Release(IStream *iface)
Definition: usrmarshal.c:658
static ULONG WINAPI Test_IStream_AddRef(IStream *iface)
Definition: usrmarshal.c:652
static struct test_stream Test_Stream
Definition: usrmarshal.c:674
static void test_marshal_WdtpInterfacePointer(void)
Definition: usrmarshal.c:766
static void test_marshal_HMETAFILEPICT(void)
Definition: usrmarshal.c:484
static HENHMETAFILE create_emf(void)
Definition: usrmarshal.c:337
static ULONG WINAPI Test_IUnknown_Release(LPUNKNOWN iface)
Definition: usrmarshal.c:611
static void test_marshal_HDC(void)
Definition: usrmarshal.c:1097
static BOOL g_expect_user_alloc
Definition: usrmarshal.c:52
static void test_marshal_HICON(void)
Definition: usrmarshal.c:1130
static void test_marshal_CLIPFORMAT(void)
Definition: usrmarshal.c:185
static void end_host_object(DWORD tid, HANDLE thread)
Definition: usrmarshal.c:164
static void test_marshal_HBRUSH(void)
Definition: usrmarshal.c:1167
static void test_marshal_HWND(void)
Definition: usrmarshal.c:223
static BOOL g_expect_user_free
Definition: usrmarshal.c:59
static TestUnknown Test_Unknown2
Definition: usrmarshal.c:673
static void test_GetDataHere_Proxy(void)
Definition: usrmarshal.c:1338
#define RELEASEMARSHALDATA
Definition: usrmarshal.c:88
static HRESULT WINAPI obj_DO_GetDataHere(IDataObject *iface, FORMATETC *fmt, STGMEDIUM *med)
Definition: usrmarshal.c:1303
void __RPC_USER HBRUSH_UserFree(ULONG *, HBRUSH *)
static ULONG WINAPI Test_IUnknown_AddRef(LPUNKNOWN iface)
Definition: usrmarshal.c:605
static TestUnknown * impl_from_IUnknown(IUnknown *iface)
Definition: usrmarshal.c:582
static const IDataObjectVtbl obj_data_object_vtbl
Definition: usrmarshal.c:1317
ULONG __RPC_USER HBRUSH_UserSize(ULONG *, ULONG, HBRUSH *)
static void test_marshal_HMETAFILE(void)
Definition: usrmarshal.c:419
static DWORD start_host_object2(IStream *stream, REFIID riid, IUnknown *object, MSHLFLAGS marshal_flags, IMessageFilter *filter, HANDLE *thread)
Definition: usrmarshal.c:142
static HRESULT WINAPI obj_QueryInterface(IDataObject *iface, REFIID iid, void **obj)
Definition: usrmarshal.c:1276
unsigned char *__RPC_USER HBRUSH_UserUnmarshal(ULONG *, unsigned char *, HBRUSH *)
static TestUnknown Test_Unknown
Definition: usrmarshal.c:672
static ULONG WINAPI obj_Release(IDataObject *iface)
Definition: usrmarshal.c:1298
static DWORD CALLBACK host_object_proc(LPVOID p)
Definition: usrmarshal.c:100
static struct test_stream Test_Stream2
Definition: usrmarshal.c:675
static void test_marshal_HBITMAP(void)
Definition: usrmarshal.c:1208
static struct test_stream * impl_from_IStream(IStream *iface)
Definition: usrmarshal.c:630
static void test_marshal_STGMEDIUM(void)
Definition: usrmarshal.c:984
static void test_marshal_SNB(void)
Definition: usrmarshal.c:997
static void test_marshal_HGLOBAL(void)
Definition: usrmarshal.c:256
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)
Definition: usrmarshal.c:66
static void *WINAPI user_allocate(SIZE_T size)
Definition: usrmarshal.c:53
static HRESULT WINAPI Test_IStream_QueryInterface(IStream *iface, REFIID riid, LPVOID *ppvObj)
Definition: usrmarshal.c:635
static const IUnknownVtbl TestUnknown_Vtbl
Definition: usrmarshal.c:617
unsigned char *__RPC_USER HBRUSH_UserMarshal(ULONG *, unsigned char *, HBRUSH *)
static const char cf_marshaled[]
Definition: usrmarshal.c:173
#define min(a, b)
Definition: monoChain.cc:55
HICON hIcon
Definition: msconfig.c:44
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
static LPUNKNOWN
Definition: ndr_ole.c:49
#define DWORD
Definition: nt_native.h:44
@ COINIT_APARTMENTTHREADED
Definition: objbase.h:278
const GUID IID_IDataObject
#define LOWORD(l)
Definition: pedump.c:82
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
static FILE * out
Definition: regtests2xml.c:44
#define NDR_LOCAL_DATA_REPRESENTATION
Definition: rpcndr.h:107
@ USER_MARSHAL_CB_BUFFER_SIZE
Definition: rpcndr.h:324
@ USER_MARSHAL_CB_UNMARSHALL
Definition: rpcndr.h:326
#define USER_MARSHAL_CB_SIGNATURE
Definition: rpcndr.h:318
#define __RPC_USER
Definition: rpc.h:65
#define memset(x, y, z)
Definition: compat.h:39
static FILE * client
Definition: client.c:41
int zero
Definition: sehframes.cpp:29
HRESULT hr
Definition: shlfolder.c:183
& rect
Definition: startmenu.cpp:1413
IUnknown IUnknown_iface
Definition: usrmarshal.c:578
unsigned int fIsIn
Definition: rpcndr.h:240
unsigned char * Buffer
Definition: rpcndr.h:203
PRPC_MESSAGE RpcMsg
Definition: rpcndr.h:202
unsigned char IsClient
Definition: rpcndr.h:210
unsigned int fIsOut
Definition: rpcndr.h:241
USER_MARSHAL_CB_TYPE CBType
Definition: rpcndr.h:336
ULONG Signature
Definition: rpcndr.h:335
PMIDL_STUB_MESSAGE pStubMsg
Definition: rpcndr.h:333
Definition: uimain.c:89
Definition: http.c:7252
Definition: dsound.c:943
IMessageFilter * filter
Definition: marshal.c:608
HANDLE marshal_event
Definition: marshal.c:611
MSHLFLAGS marshal_flags
Definition: marshal.c:607
IUnknown * object
Definition: marshal.c:606
IStream * stream
Definition: marshal.c:604
IDataObject IDataObject_iface
Definition: usrmarshal.c:1273
Definition: parse.h:23
UINT lbStyle
Definition: wingdi.h:1747
ULONG_PTR lbHatch
Definition: wingdi.h:1749
COLORREF lbColor
Definition: wingdi.h:1748
HMETAFILE hMF
Definition: wingdi.h:2608
IStream IStream_iface
Definition: usrmarshal.c:626
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:637
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
int ret
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define GMEM_MOVEABLE
Definition: winbase.h:294
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
#define WINAPI
Definition: msvc.h:6
#define E_NOINTERFACE
Definition: winerror.h:2364
#define DV_E_TYMED
Definition: winerror.h:2638
#define E_POINTER
Definition: winerror.h:2365
BOOL WINAPI DeleteMetaFile(_In_ HMETAFILE)
HBRUSH WINAPI CreateBrushIndirect(_In_ const LOGBRUSH *plb)
HBITMAP WINAPI CreateBitmap(_In_ INT cx, _In_ INT cy, _In_ UINT cPlanes, _In_ UINT cBitsPerPel, _In_opt_ const VOID *pvBits)
BOOL WINAPI DeleteEnhMetaFile(_In_opt_ HENHMETAFILE)
int WINAPI GetObjectA(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
HDC WINAPI CreateMetaFileA(_In_opt_ LPCSTR)
HMETAFILE WINAPI CloseMetaFile(_In_ HDC hdc)
LONG WINAPI GetBitmapBits(_In_ HBITMAP hbit, _In_ LONG cb, _Out_writes_bytes_(cb) LPVOID lpvBits)
BOOL WINAPI ExtTextOutA(_In_ HDC hdc, _In_ int x, _In_ int y, _In_ UINT options, _In_opt_ const RECT *lprect, _In_reads_opt_(c) LPCSTR lpString, _In_ UINT c, _In_reads_opt_(c) const INT *lpDx)
HDC WINAPI CreateEnhMetaFileA(_In_opt_ HDC, _In_opt_ LPCSTR, _In_opt_ LPCRECT, _In_opt_ LPCSTR)
#define ETO_OPAQUE
Definition: wingdi.h:647
#define MM_ISOTROPIC
Definition: wingdi.h:870
HENHMETAFILE WINAPI CloseEnhMetaFile(_In_ HDC hdc)
#define EMR_HEADER
Definition: wingdi.h:75
#define BS_SOLID
Definition: wingdi.h:1086
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
#define WM_QUIT
Definition: winuser.h:1623
HICON WINAPI CreateIcon(_In_opt_ HINSTANCE, _In_ int, _In_ int, _In_ BYTE, _In_ BYTE, _In_ const BYTE *, _In_ const BYTE *)
Definition: cursoricon.c:2395
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:656
HDC WINAPI GetDC(_In_opt_ HWND)
BOOL WINAPI PeekMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
#define WM_USER
Definition: winuser.h:1895
BOOL WINAPI PostThreadMessageA(_In_ DWORD, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI GetMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
UINT WINAPI RegisterClipboardFormatA(_In_ LPCSTR)
#define PM_NOREMOVE
Definition: winuser.h:1195
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2053
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned char BYTE
Definition: xxhash.c:193