ReactOS  0.4.10-dev-479-g13a3cf0
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 
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 *);
36 
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 *);
41 
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 *);
46 
48 unsigned char * __RPC_USER HBRUSH_UserMarshal(ULONG *, unsigned char *, HBRUSH *);
49 unsigned char * __RPC_USER HBRUSH_UserUnmarshal(ULONG *, unsigned char *, HBRUSH *);
50 void __RPC_USER HBRUSH_UserFree(ULONG *, HBRUSH *);
51 
54 {
55  ok(g_expect_user_alloc, "unexpected user_allocate call\n");
56  return CoTaskMemAlloc(size);
57 }
58 
60 static void WINAPI user_free(void *p)
61 {
62  ok(g_expect_user_free, "unexpected user_free call\n");
63  CoTaskMemFree(p);
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 
90 struct host_object_data
91 {
92  IStream *stream;
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  {
129  SetEvent((HANDLE)msg.lParam);
130  }
131  else
132  DispatchMessageA(&msg);
133  }
134 
135  HeapFree(GetProcessHeap(), 0, data);
136 
137  CoUninitialize();
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;
153  data->filter = filter;
154 
155  *thread = CreateThread(NULL, 0, host_object_proc, data, 0, &tid);
156 
157  /* wait for marshaling to complete before returning */
158  ok( !WaitForSingleObject(marshal_event, 10000), "wait timed out\n" );
159  CloseHandle(marshal_event);
160 
161  return tid;
162 }
163 
165 {
166  BOOL ret = PostThreadMessageA(tid, WM_QUIT, 0, 0);
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" );
170  CloseHandle(thread);
171 }
172 
173 static 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 
185 static 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 
201  buffer = HeapAlloc(GetProcessHeap(), 0, size);
202  memset( buffer, 0xcc, size );
203  init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
204  buffer_end = CLIPFORMAT_UserMarshal(&umcb.Flags, buffer + 1, &cf);
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);
214  buffer_end = CLIPFORMAT_UserUnmarshal(&umcb.Flags, buffer + 1, &cf2);
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");
217  HeapFree(GetProcessHeap(), 0, buffer);
218 
219  init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
220  CLIPFORMAT_UserFree(&umcb.Flags, &cf2);
221 }
222 
223 static 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 
238  buffer = HeapAlloc(GetProcessHeap(), 0, size);
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");
250  HeapFree(GetProcessHeap(), 0, buffer);
251 
252  init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
253  HWND_UserFree(&umcb.Flags, &hwnd2);
254 }
255 
256 static 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);
274  buffer = HeapAlloc(GetProcessHeap(), 0, 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");
285  HeapFree(GetProcessHeap(), 0, buffer);
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);
309  buffer = HeapAlloc(GetProcessHeap(), 0, 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");
330  HeapFree(GetProcessHeap(), 0, buffer);
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 
337 static 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 
345 static void test_marshal_HENHMETAFILE(void)
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);
361  buffer = HeapAlloc(GetProcessHeap(), 0, 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);
379  buffer_end = HENHMETAFILE_UserUnmarshal(&umcb.Flags, buffer + 1, &hemf2);
380  ok(buffer_end == buffer + size, "got %p buffer %p\n", buffer_end, buffer);
381  ok(hemf2 != NULL, "HENHMETAFILE didn't unmarshal\n");
382  HeapFree(GetProcessHeap(), 0, buffer);
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);
393  buffer = HeapAlloc(GetProcessHeap(), 0, 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);
403  buffer_end = HENHMETAFILE_UserUnmarshal(&umcb.Flags, buffer + 1, &hemf2);
404  ok(buffer_end == buffer + size, "got %p buffer %p\n", buffer_end, buffer);
405  ok(hemf2 == NULL, "NULL HENHMETAFILE didn't unmarshal\n");
406  HeapFree(GetProcessHeap(), 0, buffer);
407  init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
408  HENHMETAFILE_UserFree(&umcb.Flags, &hemf2);
409 }
410 
411 static 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 
419 static 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);
435  buffer = HeapAlloc(GetProcessHeap(), 0, 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");
455  HeapFree(GetProcessHeap(), 0, buffer);
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);
464  buffer = HeapAlloc(GetProcessHeap(), 0, 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");
476  HeapFree(GetProcessHeap(), 0, buffer);
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 
484 static void test_marshal_HMETAFILEPICT(void)
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);
507  buffer = HeapAlloc(GetProcessHeap(), 0, size);
508  init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
509  buffer_end = HMETAFILEPICT_UserMarshal(&umcb.Flags, buffer + 1, &hmfp);
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");
542  HeapFree(GetProcessHeap(), 0, buffer);
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);
556  buffer = HeapAlloc(GetProcessHeap(), 0, size);
557  init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
558  buffer_end = HMETAFILEPICT_UserMarshal(&umcb.Flags, buffer + 1, &hmfp);
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);
568  buffer_end = HMETAFILEPICT_UserUnmarshal(&umcb.Flags, buffer + 1, &hmfp2);
569  ok(buffer_end == buffer + size, "got %p buffer %p\n", buffer_end, buffer);
570  ok(hmfp2 == NULL, "NULL HMETAFILE didn't unmarshal\n");
571  HeapFree(GetProcessHeap(), 0, buffer);
572  init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
573  HMETAFILEPICT_UserFree(&umcb.Flags, &hmfp2);
574 }
575 
576 typedef struct
577 {
580 } TestUnknown;
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 
594  if (IsEqualGUID(riid, &IID_IUnknown))
595  {
596  *ppvObj = iface;
597  IUnknown_AddRef(iface);
598  return S_OK;
599  }
600 
601  *ppvObj = NULL;
602  return E_NOINTERFACE;
603 }
604 
606 {
607  TestUnknown *This = impl_from_IUnknown(iface);
608  return InterlockedIncrement(&This->refs);
609 }
610 
612 {
613  TestUnknown *This = impl_from_IUnknown(iface);
614  return InterlockedDecrement(&This->refs);
615 }
616 
617 static const IUnknownVtbl TestUnknown_Vtbl =
618 {
622 };
623 
625 {
628 };
629 
630 static 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 
640  if (IsEqualIID(riid, &IID_IUnknown) ||
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 
664 static const IStreamVtbl TestStream_Vtbl =
665 {
669  /* the rest can be NULLs */
670 };
671 
674 static struct test_stream Test_Stream = { {&TestStream_Vtbl}, 1 };
675 static struct test_stream Test_Stream2 = { {&TestStream_Vtbl}, 1 };
676 
678 unsigned char * __RPC_USER WdtpInterfacePointer_UserMarshal(ULONG *, ULONG, unsigned char *, IUnknown *, REFIID);
679 unsigned 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);
704  size = WdtpInterfacePointer_UserSize(&umcb.Flags, ctx, 0, unk, &IID_IUnknown);
705  ok(size == 0, "size should be 0 bytes, not %d\n", size);
706  buffer = HeapAlloc(GetProcessHeap(), 0, size);
707  buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, ctx, buffer, unk, &IID_IUnknown);
708  ok(buffer_end == buffer, "buffer_end %p buffer %p\n", buffer_end, buffer);
709  HeapFree(GetProcessHeap(), 0, 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 
714  unk = &Test_Unknown.IUnknown_iface;
715  Test_Unknown.refs = 1;
716 
717  CreateStreamOnHGlobal(h, TRUE, &stm);
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);
723 todo_wine
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);
727  size = WdtpInterfacePointer_UserSize(&umcb.Flags, ctx, 0, unk, &IID_IUnknown);
728  ok(size >= marshal_size + 2 * sizeof(DWORD), "marshal size %x got %x\n", marshal_size, size);
729  buffer = HeapAlloc(GetProcessHeap(), 0, size);
730  init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, umcb_ctx);
731  buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, ctx, buffer, unk, &IID_IUnknown);
732 todo_wine
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");
744  GlobalUnlock(h);
745  zero.QuadPart = 0;
746  IStream_Seek(stm, zero, STREAM_SEEK_SET, NULL);
748  IStream_Release(stm);
749 
750  Test_Unknown2.refs = 1;
751  unk2 = &Test_Unknown2.IUnknown_iface;
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 
757  WdtpInterfacePointer_UserUnmarshal(&umcb.Flags, buffer, &unk2, &IID_IUnknown);
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);
761  HeapFree(GetProcessHeap(), 0, buffer);
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;
802  IUnknown *unk = &Test_Unknown.IUnknown_iface;
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 
825  buffer = HeapAlloc(GetProcessHeap(), 0, size);
826  init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
827  buffer_end = STGMEDIUM_UserMarshal(&umcb.Flags, buffer, &med);
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 
838  Test_Unknown2.refs = 1;
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 
849  HeapFree(GetProcessHeap(), 0, buffer);
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 
892  buffer = HeapAlloc(GetProcessHeap(), 0, size);
893  memset(buffer, 0xcc, size);
894  init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
895  buffer_end = STGMEDIUM_UserMarshal(&umcb.Flags, buffer, &med);
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;
908  Test_Unknown2.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 
921  HeapFree(GetProcessHeap(), 0, buffer);
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 
951  buffer = HeapAlloc(GetProcessHeap(), 0, size);
952  memset(buffer, 0xcc, size);
953  init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
954  buffer_end = STGMEDIUM_UserMarshal(&umcb.Flags, buffer, &med);
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;
966  Test_Unknown2.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 
979  HeapFree(GetProcessHeap(), 0, buffer);
980  init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
981  STGMEDIUM_UserFree(&umcb.Flags, &med2);
982 }
983 
984 static 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 
997 static 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 
1021  buffer = HeapAlloc(GetProcessHeap(), 0, size);
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 
1036  HeapFree(GetProcessHeap(), 0, buffer);
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 
1059  buffer = HeapAlloc(GetProcessHeap(), 0, size);
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 += sizeof(str1W)/sizeof(WCHAR);
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 
1087  HeapFree(GetProcessHeap(), 0, buffer);
1088  init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
1089 
1091  SNB_UserFree(&umcb.Flags, &snb2);
1093 
1094  HeapFree(GetProcessHeap(), 0, src);
1095 }
1096 
1097 static 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 
1111  buffer = HeapAlloc(GetProcessHeap(), 0, size);
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");
1123  HeapFree(GetProcessHeap(), 0, buffer);
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 
1130 static void test_marshal_HICON(void)
1131 {
1132  static const BYTE bmp_bits[1024];
1133  MIDL_STUB_MESSAGE stub_msg;
1134  HICON hIcon, hIcon2;
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 
1148  buffer = HeapAlloc(GetProcessHeap(), 0, size);
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");
1160  HeapFree(GetProcessHeap(), 0, buffer);
1161 
1162  init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
1163  HICON_UserFree(&umcb.Flags, &hIcon2);
1164  DestroyIcon(hIcon);
1165 }
1166 
1167 static 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 
1189  buffer = HeapAlloc(GetProcessHeap(), 0, size);
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");
1201  HeapFree(GetProcessHeap(), 0, buffer);
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 
1208 static 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);
1232  buffer_end = HBITMAP_UserMarshal(&umcb.Flags, buffer + 1, &hBitmap);
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");
1240  HeapFree(GetProcessHeap(), 0, buffer);
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);
1253  buffer_end = HBITMAP_UserMarshal(&umcb.Flags, buffer + 1, &hBitmap);
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");
1264  HeapFree(GetProcessHeap(), 0, buffer);
1265 
1266  init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
1267  HBITMAP_UserFree(&umcb.Flags, &hBitmap2);
1268  DeleteObject(hBitmap);
1269 }
1270 
1271 struct 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 
1317 static const IDataObjectVtbl obj_data_object_vtbl =
1318 {
1320  obj_AddRef,
1321  obj_Release,
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 
1333 static struct obj obj =
1334 {
1336 };
1337 
1338 static void test_GetDataHere_Proxy(void)
1339 {
1340  HRESULT hr;
1341  IStream *stm;
1342  HANDLE thread;
1343  DWORD tid;
1344  static const LARGE_INTEGER zero;
1345  IDataObject *data;
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 );
1415  end_host_object( tid, thread );
1416 }
1417 
1418 START_TEST(usrmarshal)
1419 {
1421 
1430  test_marshal_SNB();
1431  test_marshal_HDC();
1435 
1437 
1438  CoUninitialize();
1439 }
static void test_marshal_HGLOBAL(void)
Definition: usrmarshal.c:256
HRESULT WINAPI CoReleaseMarshalData(IStream *pStream)
Definition: marshal.c:1907
static void test_marshal_HDC(void)
Definition: usrmarshal.c:1097
#define MM_ISOTROPIC
Definition: wingdi.h:868
int WINAPI GetObjectA(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
HANDLE HGLOBAL
Definition: windef.h:243
#define HDC
Definition: msvc.h:22
#define buffer_end
Definition: intsym.h:264
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv)
Definition: marshal.c:1838
HMETAFILE hMF
Definition: wingdi.h:2585
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
static HICON
Definition: imagelist.c:84
unsigned short WORD
Definition: ntddk_ex.h:93
#define REFIID
Definition: guiddef.h:113
#define TRUE
Definition: types.h:120
static void test_marshal_HBRUSH(void)
Definition: usrmarshal.c:1167
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
#define CloseHandle
Definition: compat.h:398
#define E_NOINTERFACE
Definition: winerror.h:2364
static struct test_stream * impl_from_IStream(IStream *iface)
Definition: usrmarshal.c:630
#define HBITMAP
Definition: msvc.h:28
const GUID IID_IUnknown
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:422
static const IStreamVtbl TestStream_Vtbl
Definition: usrmarshal.c:664
ULONG __RPC_USER HENHMETAFILE_UserSize(ULONG *pFlags, ULONG size, HENHMETAFILE *phEmf)
Definition: usrmarshal.c:1098
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
#define RELEASEMARSHALDATA
Definition: usrmarshal.c:88
void __RPC_USER HMETAFILE_UserFree(ULONG *pFlags, HMETAFILE *phmf)
Definition: usrmarshal.c:1070
ULONG __RPC_USER HMETAFILE_UserSize(ULONG *pFlags, ULONG StartingSize, HMETAFILE *phmf)
Definition: usrmarshal.c:900
static void marshal_STGMEDIUM(BOOL client, BOOL in, BOOL out)
Definition: usrmarshal.c:794
UINT lbStyle
Definition: wingdi.h:1724
Definition: http.c:6587
HDC WINAPI GetDC(_In_opt_ HWND)
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2022
__wchar_t WCHAR
Definition: xmlstorage.h:180
static GUID *static VARTYPE *static ULONG
Definition: usrmarshal.c:41
REFIID riid
Definition: precomp.h:44
unsigned char *__RPC_USER HGLOBAL_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HGLOBAL *phGlobal)
Definition: usrmarshal.c:426
static void test_marshal_HENHMETAFILE(void)
Definition: usrmarshal.c:345
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
static HRESULT WINAPI Test_IStream_QueryInterface(IStream *iface, REFIID riid, LPVOID *ppvObj)
Definition: usrmarshal.c:635
ULONG_PTR lbHatch
Definition: wingdi.h:1726
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
HDC WINAPI CreateMetaFileA(_In_opt_ LPCSTR)
#define U(x)
Definition: wordpad.c:44
static struct test_stream Test_Stream2
Definition: usrmarshal.c:675
static ULONG WINAPI obj_AddRef(IDataObject *iface)
Definition: usrmarshal.c:1293
unsigned char * Buffer
Definition: rpcndr.h:203
#define CALLBACK
Definition: compat.h:27
const char * fmt
Definition: wsprintf.c:30
#define WM_QUIT
Definition: winuser.h:1600
static void test_marshal_SNB(void)
Definition: usrmarshal.c:997
IUnknown * object
Definition: marshal.c:564
HANDLE HWND
Definition: compat.h:13
BOOL WINAPI GetMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
BOOL WINAPI PostThreadMessageA(_In_ DWORD, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
unsigned char *__RPC_USER HBRUSH_UserMarshal(ULONG *, unsigned char *, HBRUSH *)
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:679
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
unsigned char *__RPC_USER HBITMAP_UserUnmarshal(ULONG *flags, unsigned char *buffer, HBITMAP *bmp)
Definition: usrmarshal.c:702
GLuint buffer
Definition: glext.h:5915
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm)
const GUID IID_IDataObject
static void test_marshal_HICON(void)
Definition: usrmarshal.c:1130
PRPC_MESSAGE RpcMsg
Definition: rpcndr.h:202
IStream * stream
Definition: marshal.c:562
void __RPC_USER HENHMETAFILE_UserFree(ULONG *pFlags, HENHMETAFILE *phEmf)
Definition: usrmarshal.c:1266
BOOL WINAPI PeekMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
static DWORD start_host_object2(IStream *stream, REFIID riid, IUnknown *object, MSHLFLAGS marshal_flags, IMessageFilter *filter, HANDLE *thread)
Definition: usrmarshal.c:142
#define lstrlenW
Definition: compat.h:407
static void test_marshal_HMETAFILEPICT(void)
Definition: usrmarshal.c:484
#define DWORD
Definition: msvc.h:34
static struct test_stream Test_Stream
Definition: usrmarshal.c:674
static HMETAFILE create_mf(void)
Definition: usrmarshal.c:411
& rect
Definition: startmenu.cpp:1413
DWORD DWORD
Definition: winlogon.h:83
static DWORD block_size(DWORD block)
Definition: jsutils.c:64
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
#define PM_NOREMOVE
Definition: winuser.h:1176
unsigned char *__RPC_USER HBITMAP_UserMarshal(ULONG *flags, unsigned char *buffer, HBITMAP *bmp)
Definition: usrmarshal.c:642
uint32_t ULONG_PTR
Definition: typedefs.h:63
HDC hdc2
Definition: SelectObject.c:10
SIZE_T NTAPI GlobalSize(HGLOBAL hMem)
Definition: heapmem.c:1090
unsigned int BufferLength
Definition: rpcdcep.h:41
ULONG __RPC_USER SNB_UserSize(ULONG *pFlags, ULONG StartingSize, SNB *pSnb)
Definition: usrmarshal.c:2093
GLuint const GLubyte GLvoid * src
Definition: s_context.h:57
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
static void test_marshal_HWND(void)
Definition: usrmarshal.c:223
static void test_marshal_CLIPFORMAT(void)
Definition: usrmarshal.c:185
GLenum GLclampf GLint i
Definition: glfuncs.h:14
START_TEST(usrmarshal)
Definition: usrmarshal.c:1418
void * Buffer
Definition: rpcdcep.h:40
#define FALSE
Definition: types.h:117
#define ETO_OPAQUE
Definition: wingdi.h:645
long LONG
Definition: pedump.c:60
unsigned char *__RPC_USER STGMEDIUM_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, STGMEDIUM *pStgMedium)
Definition: usrmarshal.c:1896
static ULONG WINAPI Test_IUnknown_AddRef(LPUNKNOWN iface)
Definition: usrmarshal.c:605
static LPUNKNOWN
Definition: ndr_ole.c:49
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: CString.cpp:62
ULONG __RPC_USER HMETAFILEPICT_UserSize(ULONG *pFlags, ULONG size, HMETAFILEPICT *phMfp)
Definition: usrmarshal.c:1294
HDC hdc
Definition: msvc.h:53
#define MAKELONG(a, b)
Definition: typedefs.h:248
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:135
HANDLE marshal_event
Definition: marshal.c:569
smooth NULL
Definition: ftsmooth.c:416
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:635
HDC WINAPI CreateEnhMetaFileA(_In_opt_ HDC, _In_opt_ LPCSTR, _In_opt_ LPCRECT, _In_opt_ LPCSTR)
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:583
static DWORD CALLBACK host_object_proc(LPVOID p)
Definition: usrmarshal.c:100
BOOL WINAPI DeleteEnhMetaFile(_In_opt_ HENHMETAFILE)
HMETAFILE WINAPI CloseMetaFile(_In_ HDC hdc)
unsigned char *__RPC_USER HMETAFILEPICT_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HMETAFILEPICT *phMfp)
Definition: usrmarshal.c:1344
ULONG __RPC_USER HGLOBAL_UserSize(ULONG *pFlags, ULONG StartingSize, HGLOBAL *phGlobal)
Definition: usrmarshal.c:380
IUnknown IUnknown_iface
Definition: usrmarshal.c:578
#define __RPC_USER
Definition: rpc.h:65
static void marshal_WdtpInterfacePointer(DWORD umcb_ctx, DWORD ctx, BOOL client, BOOL in, BOOL out)
Definition: usrmarshal.c:681
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
unsigned char *__RPC_USER CLIPFORMAT_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, CLIPFORMAT *pCF)
Definition: usrmarshal.c:146
static void test_marshal_HBITMAP(void)
Definition: usrmarshal.c:1208
IStream IStream_iface
Definition: usrmarshal.c:626
#define ok(value,...)
Definition: CComObject.cpp:34
unsigned char *__RPC_USER HENHMETAFILE_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HENHMETAFILE *phEmf)
Definition: usrmarshal.c:1201
Definition: uimain.c:88
void __RPC_USER HGLOBAL_UserFree(ULONG *pFlags, HGLOBAL *phGlobal)
Definition: usrmarshal.c:571
static const IDataObjectVtbl obj_data_object_vtbl
Definition: usrmarshal.c:1317
unsigned char *__RPC_USER HMETAFILE_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HMETAFILE *phmf)
Definition: usrmarshal.c:947
unsigned int BOOL
Definition: ntddk_ex.h:94
GLsizeiptr size
Definition: glext.h:5919
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
LONG HRESULT
Definition: typedefs.h:77
static HICON hIcon2
unsigned char *WINAPI WdtpInterfacePointer_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, IUnknown **ppunk, REFIID riid)
Definition: usrmarshal.c:1608
#define RGB(r, g, b)
Definition: wingdi.h:2917
LONG WINAPI GetBitmapBits(_In_ HBITMAP hbit, _In_ LONG cb, _Out_writes_bytes_(cb) LPVOID lpvBits)
COLORREF lbColor
Definition: wingdi.h:1725
HICON WINAPI CreateIcon(_In_opt_ HINSTANCE, _In_ int, _In_ int, _In_ BYTE, _In_ BYTE, _In_ const BYTE *, _In_ const BYTE *)
Definition: cursoricon.c:2364
static FILE * client
Definition: client.c:41
static FILE * out
Definition: regtests2xml.c:44
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
ULONG __RPC_USER HBITMAP_UserSize(ULONG *flags, ULONG size, HBITMAP *bmp)
Definition: usrmarshal.c:599
static HRESULT WINAPI obj_QueryInterface(IDataObject *iface, REFIID iid, void **obj)
Definition: usrmarshal.c:1276
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
HENHMETAFILE WINAPI CloseEnhMetaFile(_In_ HDC hdc)
static void end_host_object(DWORD tid, HANDLE thread)
Definition: usrmarshal.c:164
#define DV_E_TYMED
Definition: winerror.h:2638
static HANDLE thread
Definition: service.c:33
unsigned char *__RPC_USER CLIPFORMAT_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, CLIPFORMAT *pCF)
Definition: usrmarshal.c:208
static double zero
Definition: j0_y0.c:96
int ret
static void test_marshal_WdtpInterfacePointer(void)
Definition: usrmarshal.c:766
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
#define todo_wine
Definition: test.h:154
#define InterlockedDecrement
Definition: armddk.h:52
Definition: parse.h:22
GLuint GLuint stream
Definition: glext.h:7522
static ULONG WINAPI Test_IStream_Release(IStream *iface)
Definition: usrmarshal.c:658
#define EMR_HEADER
Definition: wingdi.h:75
MSHLFLAGS marshal_flags
Definition: marshal.c:565
static void test_GetDataHere_Proxy(void)
Definition: usrmarshal.c:1338
unsigned int fIsOut
Definition: rpcndr.h:241
unsigned char *__RPC_USER HENHMETAFILE_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HENHMETAFILE *phEmf)
Definition: usrmarshal.c:1143
static void test_marshal_HMETAFILE(void)
Definition: usrmarshal.c:419
static HENHMETAFILE create_emf(void)
Definition: usrmarshal.c:337
unsigned char *__RPC_USER HMETAFILEPICT_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HMETAFILEPICT *phMfp)
Definition: usrmarshal.c:1407
void __RPC_USER HMETAFILEPICT_UserFree(ULONG *pFlags, HMETAFILEPICT *phMfp)
Definition: usrmarshal.c:1478
uint32_t DWORD_PTR
Definition: typedefs.h:63
#define WINAPI
Definition: msvc.h:20
#define USER_MARSHAL_PTR_PREFIX
Definition: usrmarshal.c:480
#define WM_USER
Definition: winuser.h:1851
UINT WINAPI RegisterClipboardFormatA(_In_ LPCSTR)
static HRESULT WINAPI obj_DO_GetDataHere(IDataObject *iface, FORMATETC *fmt, STGMEDIUM *med)
Definition: usrmarshal.c:1303
HBRUSH WINAPI CreateBrushIndirect(_In_ const LOGBRUSH *plb)
#define broken(x)
Definition: _sntprintf.h:21
unsigned char BYTE
Definition: ntddk_ex.h:96
static TestUnknown * impl_from_IUnknown(IUnknown *iface)
Definition: usrmarshal.c:582
GLfloat CONST GLvector4f * in
Definition: m_xform.h:122
unsigned int fIsIn
Definition: rpcndr.h:240
unsigned char *__RPC_USER HGLOBAL_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HGLOBAL *phGlobal)
Definition: usrmarshal.c:488
IDataObject IDataObject_iface
Definition: usrmarshal.c:1273
static BOOL g_expect_user_free
Definition: usrmarshal.c:59
unsigned char *__RPC_USER HMETAFILE_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HMETAFILE *phmf)
Definition: usrmarshal.c:1005
USER_MARSHAL_CB_TYPE CBType
Definition: rpcndr.h:336
ULONG_PTR SIZE_T
Definition: typedefs.h:78
static const IUnknownVtbl TestUnknown_Vtbl
Definition: usrmarshal.c:617
#define S_OK
Definition: intsafe.h:59
DWORD *typedef HANDLE
Definition: winlogon.h:60
#define NDR_LOCAL_DATA_REPRESENTATION
Definition: rpcndr.h:107
#define InterlockedIncrement
Definition: armddk.h:53
static TestUnknown Test_Unknown2
Definition: usrmarshal.c:673
ULONG __RPC_USER WdtpInterfacePointer_UserSize(ULONG *pFlags, ULONG RealFlags, ULONG StartingSize, IUnknown *punk, REFIID riid)
Definition: usrmarshal.c:1516
#define lstrcpyW
Definition: compat.h:406
unsigned char IsClient
Definition: rpcndr.h:210
void __RPC_USER SNB_UserFree(ULONG *pFlags, SNB *pSnb)
Definition: usrmarshal.c:2200
HICON hIcon
Definition: msconfig.c:44
#define USER_MARSHAL_CB_SIGNATURE
Definition: rpcndr.h:318
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:1994
unsigned char *__RPC_USER SNB_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, SNB *pSnb)
Definition: usrmarshal.c:2162
ULONG __RPC_USER STGMEDIUM_UserSize(ULONG *pFlags, ULONG StartingSize, STGMEDIUM *pStgMedium)
Definition: usrmarshal.c:1691
void __RPC_USER HBITMAP_UserFree(ULONG *flags, HBITMAP *bmp)
Definition: usrmarshal.c:772
unsigned char *__RPC_USER STGMEDIUM_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, STGMEDIUM *pStgMedium)
Definition: usrmarshal.c:1786
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
static ULONG WINAPI obj_Release(IDataObject *iface)
Definition: usrmarshal.c:1298
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
Definition: compobj.c:1938
ULONG Signature
Definition: rpcndr.h:335
#define min(a, b)
Definition: monoChain.cc:55
struct _ULARGE_INTEGER::@3679 u
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4024
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
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)
IMessageFilter * filter
Definition: marshal.c:566
void __RPC_USER CLIPFORMAT_UserFree(ULONG *pFlags, CLIPFORMAT *pCF)
Definition: usrmarshal.c:275
unsigned char *__RPC_USER SNB_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, SNB *pSnb)
Definition: usrmarshal.c:2126
void __RPC_USER STGMEDIUM_UserFree(ULONG *pFlags, STGMEDIUM *pStgMedium)
Definition: usrmarshal.c:2039
#define msg(x)
Definition: auth_time.c:54
static void *WINAPI user_allocate(SIZE_T size)
Definition: usrmarshal.c:53
static const char cf_marshaled[]
Definition: usrmarshal.c:173
unsigned int ULONG
Definition: retypes.h:1
PMIDL_STUB_MESSAGE pStubMsg
Definition: rpcndr.h:333
BOOL WINAPI DeleteMetaFile(_In_ HMETAFILE)
static HRESULT WINAPI Test_IUnknown_QueryInterface(LPUNKNOWN iface, REFIID riid, LPVOID *ppvObj)
Definition: usrmarshal.c:587
#define BS_SOLID
Definition: wingdi.h:1067
GLfloat GLfloat p
Definition: glext.h:8902
HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk, DWORD dwDestContext, void *pvDestContext, DWORD mshlFlags)
Definition: marshal.c:1724
#define E_POINTER
Definition: winerror.h:2365
static void WINAPI user_free(void *p)
Definition: usrmarshal.c:60
#define memset(x, y, z)
Definition: compat.h:39
HRESULT WINAPI CoRegisterMessageFilter(LPMESSAGEFILTER lpMessageFilter, LPMESSAGEFILTER *lplpMessageFilter)
Definition: compobj.c:3958
static TfClientId tid
static HBITMAP hBitmap
Definition: timezone.c:34
ULONG __RPC_USER CLIPFORMAT_UserSize(ULONG *pFlags, ULONG size, CLIPFORMAT *pCF)
Definition: usrmarshal.c:101
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:406
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glext.h:7005
ULONG __RPC_USER HBRUSH_UserSize(ULONG *, ULONG, HBRUSH *)
#define LOWORD(l)
Definition: pedump.c:82
Definition: dsound.c:943
#define HeapFree(x, y, z)
Definition: compat.h:394
#define GMEM_MOVEABLE
Definition: winbase.h:291
unsigned char *__RPC_USER HBRUSH_UserUnmarshal(ULONG *, unsigned char *, HBRUSH *)
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:90
unsigned char *WINAPI WdtpInterfacePointer_UserMarshal(ULONG *pFlags, ULONG RealFlags, unsigned char *pBuffer, IUnknown *punk, REFIID riid)
Definition: usrmarshal.c:1551
void * object
Definition: jmemsys.h:48
static ULONG WINAPI Test_IUnknown_Release(LPUNKNOWN iface)
Definition: usrmarshal.c:611
static void test_marshal_STGMEDIUM(void)
Definition: usrmarshal.c:984
static ULONG WINAPI Test_IStream_AddRef(IStream *iface)
Definition: usrmarshal.c:652
static TestUnknown Test_Unknown
Definition: usrmarshal.c:672
LONGLONG QuadPart
Definition: typedefs.h:112
HBITMAP WINAPI CreateBitmap(_In_ INT cx, _In_ INT cy, _In_ UINT cPlanes, _In_ UINT cBitsPerPel, _In_opt_ const VOID *pvBits)
static BOOL g_expect_user_alloc
Definition: usrmarshal.c:52
void __RPC_USER HBRUSH_UserFree(ULONG *, HBRUSH *)