ReactOS  0.4.15-dev-316-g938df97
ndr_marshall.c
Go to the documentation of this file.
1 /*
2  * Unit test suite for ndr marshalling functions
3  *
4  * Copyright 2006 Huw Davies
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 
23 #include <stdarg.h>
24 
25 #include <windef.h>
26 #include <winbase.h>
27 #include <winnt.h>
28 #include <winerror.h>
29 #include <ole2.h>
30 
31 #include "rpc.h"
32 #include "rpcdce.h"
33 #include "rpcproxy.h"
34 #include "midles.h"
35 #include "ndrtypes.h"
36 
37 #include "wine/heap.h"
38 #include "wine/test.h"
39 
40 static int my_alloc_called;
41 static int my_free_called;
42 static void * CALLBACK my_alloc(SIZE_T size)
43 {
45  return NdrOleAllocate(size);
46 }
47 
48 static void CALLBACK my_free(void *ptr)
49 {
51  NdrOleFree(ptr);
52 }
53 
55  {
56  NULL,
57  my_alloc,
58  my_free,
59  { 0 },
60  0,
61  0,
62  0,
63  0,
64  NULL, /* format string, filled in by tests */
65  1, /* -error bounds_check flag */
66  0x20000, /* Ndr library version */
67  0,
68  0x50100a4, /* MIDL Version 5.1.164 */
69  0,
70  NULL,
71  0, /* notify & notify_flag routine table */
72  1, /* Flags */
73  0, /* Reserved3 */
74  0, /* Reserved4 */
75  0 /* Reserved5 */
76  };
77 
79 {
80  0
81 };
82 
84 {
85  0,
87 };
88 
90 {
91  sizeof(RPC_SERVER_INTERFACE),
92  {{0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x34}},{0,0}},
93  {{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}},
95  0,
96  0,
97  0,
98  0,
99  0,
100 };
101 
104 
106 {
107  RPC_MESSAGE RpcMessage;
108  MIDL_STUB_MESSAGE StubMsg;
109  MIDL_STUB_DESC StubDesc;
110  char ch = 0xde;
111 
112  static const unsigned char fmtstr_up_char[] =
113  {
114  0x12, 0x8, /* FC_UP [simple_pointer] */
115  0x2, /* FC_CHAR */
116  0x5c, /* FC_PAD */
117  };
118 
119  StubDesc = Object_StubDesc;
120  StubDesc.pFormatTypes = NULL;
121 
123  &RpcMessage,
124  &StubMsg,
125  &StubDesc,
126  0);
127 
128  StubMsg.BufferLength = 8;
129  StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
130  NdrPointerMarshall(&StubMsg, (unsigned char*)&ch, fmtstr_up_char);
131  ok(StubMsg.Buffer == StubMsg.BufferStart + 5, "%p %p\n", StubMsg.Buffer, StubMsg.BufferStart);
132 
133  use_pointer_ids = (*(unsigned int *)StubMsg.BufferStart != (UINT_PTR)&ch);
134  trace("Pointer marshalling using %s\n", use_pointer_ids ? "pointer ids" : "pointer value");
135 
136  HeapFree(GetProcessHeap(), 0, StubMsg.BufferStart);
137 }
138 
139 static void test_ndr_simple_type(void)
140 {
141  RPC_MESSAGE RpcMessage;
142  MIDL_STUB_MESSAGE StubMsg;
143  MIDL_STUB_DESC StubDesc;
144  LONG l, l2 = 0;
145 
146  StubDesc = Object_StubDesc;
147  StubDesc.pFormatTypes = NULL;
148 
150  &RpcMessage,
151  &StubMsg,
152  &StubDesc,
153  0);
154 
155  StubMsg.BufferLength = 16;
156  StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
157  l = 0xcafebabe;
158  NdrSimpleTypeMarshall(&StubMsg, (unsigned char*)&l, FC_LONG);
159  ok(StubMsg.Buffer == StubMsg.BufferStart + 4, "%p %p\n", StubMsg.Buffer, StubMsg.BufferStart);
160  ok(*(LONG*)StubMsg.BufferStart == l, "%d\n", *(LONG*)StubMsg.BufferStart);
161 
162  StubMsg.Buffer = StubMsg.BufferStart + 1;
163  NdrSimpleTypeMarshall(&StubMsg, (unsigned char*)&l, FC_LONG);
164  ok(StubMsg.Buffer == StubMsg.BufferStart + 8, "%p %p\n", StubMsg.Buffer, StubMsg.BufferStart);
165  ok(*(LONG*)(StubMsg.BufferStart + 4) == l, "%d\n", *(LONG*)StubMsg.BufferStart);
166 
167  StubMsg.Buffer = StubMsg.BufferStart + 1;
168  NdrSimpleTypeUnmarshall(&StubMsg, (unsigned char*)&l2, FC_LONG);
169  ok(StubMsg.Buffer == StubMsg.BufferStart + 8, "%p %p\n", StubMsg.Buffer, StubMsg.BufferStart);
170  ok(l2 == l, "%d\n", l2);
171 
172  HeapFree(GetProcessHeap(), 0, StubMsg.BufferStart);
173 }
174 
175 static void test_pointer_marshal(const unsigned char *formattypes,
176  void *memsrc, DWORD srcsize,
177  const void *wiredata,
178  ULONG wiredatalen,
179  int(*cmp)(const void*,const void*,size_t),
180  int num_additional_allocs,
181  const char *msgpfx)
182 {
183  RPC_MESSAGE RpcMessage;
184  MIDL_STUB_MESSAGE StubMsg;
185  MIDL_STUB_DESC StubDesc;
186  DWORD size;
187  void *ptr;
188  unsigned char *mem, *mem_orig;
189 
190  if(!cmp)
191  cmp = memcmp;
192 
193  StubDesc = Object_StubDesc;
194  StubDesc.pFormatTypes = formattypes;
195 
197  &RpcMessage,
198  &StubMsg,
199  &StubDesc,
200  0);
201 
202  StubMsg.BufferLength = 0;
203  NdrPointerBufferSize( &StubMsg,
204  memsrc,
205  formattypes );
206  ok(StubMsg.BufferLength >= wiredatalen, "%s: length %d\n", msgpfx, StubMsg.BufferLength);
207 
208  /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
209  StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
210  StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
211 
212  memset(StubMsg.BufferStart, 0x0, StubMsg.BufferLength); /* This is a hack to clear the padding between the ptr and longlong/double */
213 
214  ptr = NdrPointerMarshall( &StubMsg, memsrc, formattypes );
215  ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
216  if (srcsize == 8 && wiredatalen == 16 && StubMsg.Buffer - StubMsg.BufferStart == 12)
217  {
218  /* win9x doesn't align 8-byte types properly */
219  wiredatalen = 12;
220  }
221  else
222  {
223  ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
224  ok(!memcmp(StubMsg.BufferStart, wiredata, wiredatalen), "%s: incorrectly marshaled\n", msgpfx);
225  }
226 
227  StubMsg.Buffer = StubMsg.BufferStart;
228  StubMsg.MemorySize = 0;
229 
230  size = NdrPointerMemorySize( &StubMsg, formattypes );
231  ok(size == StubMsg.MemorySize, "%s: mem size %u size %u\n", msgpfx, StubMsg.MemorySize, size);
232  ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
233  if (formattypes[1] & FC_POINTER_DEREF)
234  ok(size == srcsize + sizeof(void *), "%s: mem size %u\n", msgpfx, size);
235  else
236  ok(size == srcsize, "%s: mem size %u\n", msgpfx, size);
237 
238  StubMsg.Buffer = StubMsg.BufferStart;
239  StubMsg.MemorySize = 16;
240  size = NdrPointerMemorySize( &StubMsg, formattypes );
241  ok(size == StubMsg.MemorySize, "%s: mem size %u size %u\n", msgpfx, StubMsg.MemorySize, size);
242  ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
243  if (formattypes[1] & FC_POINTER_DEREF)
244  ok(size == srcsize + sizeof(void *) + 16, "%s: mem size %u\n", msgpfx, size);
245  else
246  ok(size == srcsize + 16, "%s: mem size %u\n", msgpfx, size);
247 
248  StubMsg.Buffer = StubMsg.BufferStart;
249  StubMsg.MemorySize = 1;
250  size = NdrPointerMemorySize( &StubMsg, formattypes );
251  ok(size == StubMsg.MemorySize, "%s: mem size %u size %u\n", msgpfx, StubMsg.MemorySize, size);
252  ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
253  if (formattypes[1] & FC_POINTER_DEREF)
254  ok(size == srcsize + sizeof(void *) + (srcsize == 8 ? 8 : sizeof(void *)), "%s: mem size %u\n", msgpfx, size);
255  else
256  ok(size == srcsize + (srcsize == 8 ? 8 : sizeof(void *)), "%s: mem size %u\n", msgpfx, size);
257 
258  size = srcsize;
259  if (formattypes[1] & FC_POINTER_DEREF) size += 4;
260 
261  StubMsg.Buffer = StubMsg.BufferStart;
262  StubMsg.MemorySize = 0;
263  /* Using my_alloc() here is necessary to prevent a crash in Windows 7+. */
264  mem_orig = mem = my_alloc(size);
265  memset(mem, 0, size);
267  if (formattypes[1] & FC_POINTER_DEREF)
268  *(void**)mem = NULL;
269  ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 0 );
270  ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
271  ok(mem == mem_orig, "%s: mem has changed %p %p\n", msgpfx, mem, mem_orig);
272  ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx);
273  ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
274  ok(StubMsg.MemorySize == 0, "%s: memorysize %d\n", msgpfx, StubMsg.MemorySize);
275  ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
276  /* On Windows 7+ unmarshalling may involve calls to NdrFree, for unclear reasons. */
277  my_free_called = 0;
278 
279  NdrPointerFree(&StubMsg, mem, formattypes);
280  if ((formattypes[1] & FC_ALLOCED_ON_STACK) && (formattypes[1] & FC_POINTER_DEREF))
281  {
282  /* In this case the top-level pointer is not freed. */
283  ok(my_free_called == num_additional_allocs, "%s: my_free got called %d times\n", msgpfx, my_free_called);
284  HeapFree(GetProcessHeap(), 0, mem);
285  }
286  else
287  ok(my_free_called == 1 + num_additional_allocs, "%s: my_free got called %d times\n", msgpfx, my_free_called);
288 
289  /* reset the buffer and call with must alloc */
291  StubMsg.Buffer = StubMsg.BufferStart;
293  if (formattypes[1] & FC_POINTER_DEREF)
294  *(void**)mem = NULL;
295  ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 1 );
296  ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
297  /* doesn't allocate mem in this case */
298  ok(mem == mem_orig, "%s: mem has changed %p %p\n", msgpfx, mem, mem_orig);
299  ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx);
300  ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
301  ok(StubMsg.MemorySize == 0, "%s: memorysize %d\n", msgpfx, StubMsg.MemorySize);
302  ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
303  ok(!my_free_called, "%s: my_free got called %d times\n", msgpfx, my_free_called);
304 
305  NdrPointerFree(&StubMsg, mem, formattypes);
306  if ((formattypes[1] & FC_ALLOCED_ON_STACK) && (formattypes[1] & FC_POINTER_DEREF))
307  {
308  /* In this case the top-level pointer is not freed. */
309  ok(my_free_called == num_additional_allocs, "%s: my_free got called %d times\n", msgpfx, my_free_called);
310  HeapFree(GetProcessHeap(), 0, mem);
311  }
312  else
313  ok(my_free_called == 1 + num_additional_allocs, "%s: my_free got called %d times\n", msgpfx, my_free_called);
314 
315  if (formattypes[0] != FC_RP)
316  {
317  /* now pass the address of a NULL ptr */
318  mem = NULL;
320  StubMsg.Buffer = StubMsg.BufferStart;
321  ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 0 );
322  ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
323  ok(mem != StubMsg.BufferStart + wiredatalen - srcsize, "%s: mem points to buffer %p %p\n", msgpfx, mem, StubMsg.BufferStart);
324  ok(!cmp(mem, memsrc, size), "%s: incorrectly unmarshaled\n", msgpfx);
325  ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
326  ok(StubMsg.MemorySize == 0, "%s: memorysize %d\n", msgpfx, StubMsg.MemorySize);
327  ok(my_alloc_called == num_additional_allocs + 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
328  my_alloc_called = 0;
329  NdrPointerFree(&StubMsg, mem, formattypes);
330 
331  /* again pass address of NULL ptr, but pretend we're a server */
332  if (0) /* crashes on Win9x and NT4 */
333  {
334  mem = NULL;
335  StubMsg.Buffer = StubMsg.BufferStart;
336  StubMsg.IsClient = 0;
337  ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 0 );
338  ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
339  if (formattypes[2] == FC_ENUM16)
340  ok(mem != StubMsg.BufferStart + wiredatalen - srcsize, "%s: mem points to buffer %p %p\n", msgpfx, mem, StubMsg.BufferStart);
341  else
342  ok(mem == StubMsg.BufferStart + wiredatalen - srcsize, "%s: mem doesn't point to buffer %p %p\n", msgpfx, mem, StubMsg.BufferStart);
343  ok(!cmp(mem, memsrc, size), "%s: incorrectly unmarshaled\n", msgpfx);
344  ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
345  ok(StubMsg.MemorySize == 0, "%s: memorysize %d\n", msgpfx, StubMsg.MemorySize);
346  if (formattypes[2] != FC_ENUM16)
347  {
348  ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
349  my_alloc_called = 0;
350  }
351  }
352  }
353 
354  /* Server */
355  StubMsg.IsClient = 0;
356 
357  /* For most basetypes (but not enum16), memory will not be allocated but
358  * instead point directly to the buffer. */
360  StubMsg.Buffer = StubMsg.BufferStart;
361  mem = NULL;
362  ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 0 );
363  ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
364  ok(!!mem, "%s: mem was not allocated\n", msgpfx);
365  ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx);
366  ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
367  ok(StubMsg.MemorySize == 0, "%s: memorysize %d\n", msgpfx, StubMsg.MemorySize);
368  if (formattypes[2] == FC_ENUM16)
369  ok(my_alloc_called == 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
370  else
371  ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
372  ok(!my_free_called, "%s: my_free got called %d times\n", msgpfx, my_free_called);
373 
374  NdrPointerFree(&StubMsg, mem, formattypes);
375  if (formattypes[2] == FC_ENUM16)
376  ok(my_free_called == 1, "%s: my_free got called %d times\n", msgpfx, my_free_called);
377  else if ((formattypes[1] & FC_ALLOCED_ON_STACK) && (formattypes[1] & FC_POINTER_DEREF))
378  {
379  /* In theory this should be freed to correspond with the allocation, but
380  * FC_ALLOCED_ON_STACK is set, and NdrPointerFree() has no way of
381  * knowing that the memory allocated by NdrPointerUnmarshall() isn't
382  * stack memory. In practice it always *is* stack memory if ON_STACK is
383  * set, so this leak isn't a concern. */
384  ok(my_free_called == 0, "%s: my_free got called %d times\n", msgpfx, my_free_called);
385  HeapFree(GetProcessHeap(), 0, mem);
386  }
387  else
388  ok(my_free_called == num_additional_allocs, "%s: my_free got called %d times\n", msgpfx, my_free_called);
389 
390  /* reset the buffer and call with must alloc */
392  StubMsg.Buffer = StubMsg.BufferStart;
393  mem = NULL;
394  ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 1 );
395  ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
396  ok(!!mem, "%s: mem was not allocated\n", msgpfx);
397  ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx);
398  ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
399  ok(StubMsg.MemorySize == 0, "%s: memorysize %d\n", msgpfx, StubMsg.MemorySize);
400  if (formattypes[2] == FC_ENUM16)
401  ok(my_alloc_called == 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
402  else
403  ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
404  ok(!my_free_called, "%s: my_free got called %d times\n", msgpfx, my_free_called);
405 
406  NdrPointerFree(&StubMsg, mem, formattypes);
407  if (formattypes[2] == FC_ENUM16)
408  ok(my_free_called == 1, "%s: my_free got called %d times\n", msgpfx, my_free_called);
409  else if ((formattypes[1] & FC_ALLOCED_ON_STACK) && (formattypes[1] & FC_POINTER_DEREF))
410  {
411  ok(my_free_called == 0, "%s: my_free got called %d times\n", msgpfx, my_free_called);
412  HeapFree(GetProcessHeap(), 0, mem);
413  }
414  else
415  ok(my_free_called == num_additional_allocs, "%s: my_free got called %d times\n", msgpfx, my_free_called);
416 
417  /* Ξ€est with an existing pointer. Unless it's a stack pointer (and deref'd)
418  * a new pointer will be allocated anyway (in fact, an invalid pointer works
419  * in every such case). */
420 
422  StubMsg.Buffer = StubMsg.BufferStart;
424  if (formattypes[1] & FC_POINTER_DEREF)
425  *(void**)mem = NULL;
426  ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 0 );
427  ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
428  if ((formattypes[1] & FC_ALLOCED_ON_STACK) && (formattypes[1] & FC_POINTER_DEREF))
429  ok(mem == mem_orig, "%s: mem has changed %p %p\n", msgpfx, mem, mem_orig);
430  else
431  {
432  ok(mem != mem_orig, "%s: mem has not changed\n", msgpfx);
433  HeapFree(GetProcessHeap(), 0, mem_orig);
434  }
435  ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx);
436  ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
437  ok(StubMsg.MemorySize == 0, "%s: memorysize %d\n", msgpfx, StubMsg.MemorySize);
438  if (formattypes[2] == FC_ENUM16)
439  ok(my_alloc_called == 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
440  else if ((formattypes[1] & FC_ALLOCED_ON_STACK) && (formattypes[1] & FC_POINTER_DEREF))
441  ok(my_alloc_called == 0, "%s: my_alloc got called %d times\n", msgpfx, my_free_called);
442  else
443  ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
444  ok(!my_free_called, "%s: my_free got called %d times\n", msgpfx, my_free_called);
445 
446  NdrPointerFree(&StubMsg, mem, formattypes);
447  if (formattypes[2] == FC_ENUM16)
448  ok(my_free_called == 1, "%s: my_free got called %d times\n", msgpfx, my_free_called);
449  else if ((formattypes[1] & FC_ALLOCED_ON_STACK) && (formattypes[1] & FC_POINTER_DEREF))
450  {
451  ok(my_free_called == 0, "%s: my_free got called %d times\n", msgpfx, my_free_called);
452  HeapFree(GetProcessHeap(), 0, mem);
453  }
454  else
455  ok(my_free_called == num_additional_allocs, "%s: my_free got called %d times\n", msgpfx, my_free_called);
456 
457  /* reset the buffer and call with must alloc */
459  StubMsg.Buffer = StubMsg.BufferStart;
461  if (formattypes[1] & FC_POINTER_DEREF)
462  *(void**)mem = NULL;
463  ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 1 );
464  ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
465  if ((formattypes[1] & FC_ALLOCED_ON_STACK) && (formattypes[1] & FC_POINTER_DEREF))
466  ok(mem == mem_orig, "%s: mem has changed %p %p\n", msgpfx, mem, mem_orig);
467  else
468  {
469  ok(mem != mem_orig, "%s: mem has not changed\n", msgpfx);
470  HeapFree(GetProcessHeap(), 0, mem_orig);
471  }
472  ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx);
473  ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
474  ok(StubMsg.MemorySize == 0, "%s: memorysize %d\n", msgpfx, StubMsg.MemorySize);
475  if (formattypes[2] == FC_ENUM16)
476  ok(my_alloc_called == 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
477  else if ((formattypes[1] & FC_ALLOCED_ON_STACK) && (formattypes[1] & FC_POINTER_DEREF))
478  ok(my_alloc_called == 0, "%s: my_alloc got called %d times\n", msgpfx, my_free_called);
479  else
480  ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
481  ok(!my_free_called, "%s: my_free got called %d times\n", msgpfx, my_free_called);
482 
483  NdrPointerFree(&StubMsg, mem, formattypes);
484  if (formattypes[2] == FC_ENUM16)
485  ok(my_free_called == 1, "%s: my_free got called %d times\n", msgpfx, my_free_called);
486  else if ((formattypes[1] & FC_ALLOCED_ON_STACK) && (formattypes[1] & FC_POINTER_DEREF))
487  {
488  ok(my_free_called == 0, "%s: my_free got called %d times\n", msgpfx, my_free_called);
489  HeapFree(GetProcessHeap(), 0, mem);
490  }
491  else
492  ok(my_free_called == num_additional_allocs, "%s: my_free got called %d times\n", msgpfx, my_free_called);
493 
494  HeapFree(GetProcessHeap(), 0, StubMsg.BufferStart);
495 }
496 
497 static int deref_cmp(const void *s1, const void *s2, size_t num)
498 {
499  return memcmp(*(const void *const *)s1, *(const void *const *)s2, num);
500 }
501 
502 
503 static void test_simple_types(void)
504 {
505  unsigned char wiredata[16];
506  unsigned char ch;
507  unsigned char *ch_ptr;
508  unsigned short s;
509  unsigned int i;
510  ULONG l;
511  ULONGLONG ll;
512  float f;
513  double d;
514 
515  static const unsigned char fmtstr_up_char[] =
516  {
517  0x12, 0x8, /* FC_UP [simple_pointer] */
518  0x2, /* FC_CHAR */
519  0x5c, /* FC_PAD */
520  };
521  static const unsigned char fmtstr_up_byte[] =
522  {
523  0x12, 0x8, /* FC_UP [simple_pointer] */
524  0x1, /* FC_BYTE */
525  0x5c, /* FC_PAD */
526  };
527  static const unsigned char fmtstr_up_small[] =
528  {
529  0x12, 0x8, /* FC_UP [simple_pointer] */
530  0x3, /* FC_SMALL */
531  0x5c, /* FC_PAD */
532  };
533  static const unsigned char fmtstr_up_usmall[] =
534  {
535  0x12, 0x8, /* FC_UP [simple_pointer] */
536  0x4, /* FC_USMALL */
537  0x5c, /* FC_PAD */
538  };
539  static const unsigned char fmtstr_rp_char[] =
540  {
541  0x11, 0x8, /* FC_RP [simple_pointer] */
542  0x2, /* FC_CHAR */
543  0x5c, /* FC_PAD */
544  };
545  static const unsigned char fmtstr_rpup_char_onstack_deref[] =
546  {
547  0x11, 0x14, /* FC_RP [alloced_on_stack] [pointer_deref] */
548  NdrFcShort( 0x2 ), /* Offset= 2 (4) */
549  0x12, 0x8, /* FC_UP [simple_pointer] */
550  0x2, /* FC_CHAR */
551  0x5c, /* FC_PAD */
552  };
553  static const unsigned char fmtstr_rpup_char_onstack[] =
554  {
555  0x11, 0x04, /* FC_RP [alloced_on_stack] */
556  NdrFcShort( 0x2 ), /* Offset= 2 (4) */
557  0x12, 0x8, /* FC_UP [simple_pointer] */
558  0x2, /* FC_CHAR */
559  0x5c, /* FC_PAD */
560  };
561  static const unsigned char fmtstr_rpup_char_deref[] =
562  {
563  0x11, 0x10, /* FC_RP [pointer_deref] */
564  NdrFcShort( 0x2 ), /* Offset= 2 (4) */
565  0x12, 0x8, /* FC_UP [simple_pointer] */
566  0x2, /* FC_CHAR */
567  0x5c, /* FC_PAD */
568  };
569 
570  static const unsigned char fmtstr_up_wchar[] =
571  {
572  0x12, 0x8, /* FC_UP [simple_pointer] */
573  0x5, /* FC_WCHAR */
574  0x5c, /* FC_PAD */
575  };
576  static const unsigned char fmtstr_up_short[] =
577  {
578  0x12, 0x8, /* FC_UP [simple_pointer] */
579  0x6, /* FC_SHORT */
580  0x5c, /* FC_PAD */
581  };
582  static const unsigned char fmtstr_up_ushort[] =
583  {
584  0x12, 0x8, /* FC_UP [simple_pointer] */
585  0x7, /* FC_USHORT */
586  0x5c, /* FC_PAD */
587  };
588  static const unsigned char fmtstr_up_enum16[] =
589  {
590  0x12, 0x8, /* FC_UP [simple_pointer] */
591  0xd, /* FC_ENUM16 */
592  0x5c, /* FC_PAD */
593  };
594  static const unsigned char fmtstr_up_long[] =
595  {
596  0x12, 0x8, /* FC_UP [simple_pointer] */
597  0x8, /* FC_LONG */
598  0x5c, /* FC_PAD */
599  };
600  static const unsigned char fmtstr_up_ulong[] =
601  {
602  0x12, 0x8, /* FC_UP [simple_pointer] */
603  0x9, /* FC_ULONG */
604  0x5c, /* FC_PAD */
605  };
606  static const unsigned char fmtstr_up_enum32[] =
607  {
608  0x12, 0x8, /* FC_UP [simple_pointer] */
609  0xe, /* FC_ENUM32 */
610  0x5c, /* FC_PAD */
611  };
612  static const unsigned char fmtstr_up_errorstatus[] =
613  {
614  0x12, 0x8, /* FC_UP [simple_pointer] */
615  0x10, /* FC_ERROR_STATUS_T */
616  0x5c, /* FC_PAD */
617  };
618 
619  static const unsigned char fmtstr_up_longlong[] =
620  {
621  0x12, 0x8, /* FC_UP [simple_pointer] */
622  0xb, /* FC_HYPER */
623  0x5c, /* FC_PAD */
624  };
625  static const unsigned char fmtstr_up_float[] =
626  {
627  0x12, 0x8, /* FC_UP [simple_pointer] */
628  0xa, /* FC_FLOAT */
629  0x5c, /* FC_PAD */
630  };
631  static const unsigned char fmtstr_up_double[] =
632  {
633  0x12, 0x8, /* FC_UP [simple_pointer] */
634  0xc, /* FC_DOUBLE */
635  0x5c, /* FC_PAD */
636  };
637 
638  ch = 0xa5;
639  ch_ptr = &ch;
640  if (use_pointer_ids)
641  *(unsigned int *)wiredata = 0x20000;
642  else
643  *(unsigned int *)wiredata = (UINT_PTR)ch_ptr;
644  wiredata[4] = ch;
645 
646  test_pointer_marshal(fmtstr_up_char, ch_ptr, 1, wiredata, 5, NULL, 0, "up_char");
647  test_pointer_marshal(fmtstr_up_byte, ch_ptr, 1, wiredata, 5, NULL, 0, "up_byte");
648  test_pointer_marshal(fmtstr_up_small, ch_ptr, 1, wiredata, 5, NULL, 0, "up_small");
649  test_pointer_marshal(fmtstr_up_usmall, ch_ptr, 1, wiredata, 5, NULL, 0, "up_usmall");
650 
651  test_pointer_marshal(fmtstr_rp_char, ch_ptr, 1, &ch, 1, NULL, 0, "rp_char");
652 
653  test_pointer_marshal(fmtstr_rpup_char_onstack_deref, &ch_ptr, 1, wiredata, 5, deref_cmp, 1, "rpup_char_onstack_deref");
654  test_pointer_marshal(fmtstr_rpup_char_onstack, ch_ptr, 1, wiredata, 5, NULL, 0, "rpup_char_onstack");
655  test_pointer_marshal(fmtstr_rpup_char_deref, &ch_ptr, 1, wiredata, 5, deref_cmp, 1, "rpup_char_deref");
656 
657  s = 0xa597;
658  if (use_pointer_ids)
659  *(unsigned int *)wiredata = 0x20000;
660  else
661  *(unsigned int *)wiredata = (UINT_PTR)&s;
662  *(unsigned short*)(wiredata + 4) = s;
663 
664  test_pointer_marshal(fmtstr_up_wchar, &s, 2, wiredata, 6, NULL, 0, "up_wchar");
665  test_pointer_marshal(fmtstr_up_short, &s, 2, wiredata, 6, NULL, 0, "up_short");
666  test_pointer_marshal(fmtstr_up_ushort, &s, 2, wiredata, 6, NULL, 0, "up_ushort");
667 
668  i = 0x7fff;
669  if (use_pointer_ids)
670  *(unsigned int *)wiredata = 0x20000;
671  else
672  *(unsigned int *)wiredata = (UINT_PTR)&i;
673  *(unsigned short*)(wiredata + 4) = i;
674  test_pointer_marshal(fmtstr_up_enum16, &i, 4, wiredata, 6, NULL, 0, "up_enum16");
675 
676  l = 0xcafebabe;
677  if (use_pointer_ids)
678  *(unsigned int *)wiredata = 0x20000;
679  else
680  *(unsigned int *)wiredata = (UINT_PTR)&l;
681  *(ULONG*)(wiredata + 4) = l;
682 
683  test_pointer_marshal(fmtstr_up_long, &l, 4, wiredata, 8, NULL, 0, "up_long");
684  test_pointer_marshal(fmtstr_up_ulong, &l, 4, wiredata, 8, NULL, 0, "up_ulong");
685  test_pointer_marshal(fmtstr_up_enum32, &l, 4, wiredata, 8, NULL, 0, "up_emun32");
686  test_pointer_marshal(fmtstr_up_errorstatus, &l, 4, wiredata, 8, NULL, 0, "up_errorstatus");
687 
688  ll = ((ULONGLONG)0xcafebabe) << 32 | 0xdeadbeef;
689  if (use_pointer_ids)
690  *(unsigned int *)wiredata = 0x20000;
691  else
692  *(unsigned int *)wiredata = (UINT_PTR)&ll;
693  *(unsigned int *)(wiredata + 4) = 0;
694  *(ULONGLONG*)(wiredata + 8) = ll;
695  test_pointer_marshal(fmtstr_up_longlong, &ll, 8, wiredata, 16, NULL, 0, "up_longlong");
696 
697  f = 3.1415f;
698  if (use_pointer_ids)
699  *(unsigned int *)wiredata = 0x20000;
700  else
701  *(unsigned int *)wiredata = (UINT_PTR)&f;
702  *(float*)(wiredata + 4) = f;
703  test_pointer_marshal(fmtstr_up_float, &f, 4, wiredata, 8, NULL, 0, "up_float");
704 
705  d = 3.1415;
706  if (use_pointer_ids)
707  *(unsigned int *)wiredata = 0x20000;
708  else
709  *(unsigned int *)wiredata = (UINT_PTR)&d;
710  *(unsigned int *)(wiredata + 4) = 0;
711  *(double*)(wiredata + 8) = d;
712  test_pointer_marshal(fmtstr_up_double, &d, 8, wiredata, 16, NULL, 0, "up_double");
713 
714 }
715 
717 {
718  RPC_MESSAGE RpcMessage;
719  MIDL_STUB_MESSAGE StubMsg;
720  MIDL_STUB_DESC StubDesc;
721  DWORD size;
722  void *ptr;
723  char **p1;
724  char *p2;
725  char ch;
726  unsigned char *mem, *mem_orig;
727 
728  static const unsigned char fmtstr_ref_unique_out[] =
729  {
730  0x12, 0x8, /* FC_UP [simple_pointer] */
731  0x2, /* FC_CHAR */
732  0x5c, /* FC_PAD */
733  0x11, 0x14, /* FC_RP [alloced_on_stack] [pointer_deref] */
734  NdrFcShort( 0xfffffffa ), /* Offset= -6 (0) */
735  };
736 
737  p1 = &p2;
738  p2 = &ch;
739  ch = 0x22;
740 
741  StubDesc = Object_StubDesc;
742  StubDesc.pFormatTypes = fmtstr_ref_unique_out;
743 
745  &RpcMessage,
746  &StubMsg,
747  &StubDesc,
748  0);
749 
750  StubMsg.BufferLength = 0;
751  NdrPointerBufferSize( &StubMsg,
752  (unsigned char *)p1,
753  &fmtstr_ref_unique_out[4] );
754 
755  /* Windows overestimates the buffer size */
756  ok(StubMsg.BufferLength >= 5, "length %d\n", StubMsg.BufferLength);
757 
758  /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
759  StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
760  StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
761 
762  ptr = NdrPointerMarshall( &StubMsg, (unsigned char *)p1, &fmtstr_ref_unique_out[4] );
763  ok(ptr == NULL, "ret %p\n", ptr);
764  size = StubMsg.Buffer - StubMsg.BufferStart;
765  ok(size == 5, "Buffer %p Start %p len %d\n", StubMsg.Buffer, StubMsg.BufferStart, size);
766  ok(*(unsigned int *)StubMsg.BufferStart != 0, "pointer ID marshalled incorrectly\n");
767  ok(*(unsigned char *)(StubMsg.BufferStart + 4) == 0x22, "char data marshalled incorrectly: 0x%x\n",
768  *(unsigned char *)(StubMsg.BufferStart + 4));
769 
770  StubMsg.Buffer = StubMsg.BufferStart;
771  StubMsg.MemorySize = 0;
772  mem = NULL;
773 
774  /* Client */
775  my_alloc_called = 0;
776  StubMsg.Buffer = StubMsg.BufferStart;
777  mem = mem_orig = HeapAlloc(GetProcessHeap(), 0, sizeof(void *));
778  *(void **)mem = NULL;
779  NdrPointerUnmarshall( &StubMsg, &mem, &fmtstr_ref_unique_out[4], 0);
780  ok(mem == mem_orig, "mem alloced\n");
781  ok(my_alloc_called == 1, "alloc called %d\n", my_alloc_called);
782 
783  my_alloc_called = 0;
784  StubMsg.Buffer = StubMsg.BufferStart;
785  NdrPointerUnmarshall( &StubMsg, &mem, &fmtstr_ref_unique_out[4], 1);
786  ok(mem == mem_orig, "mem alloced\n");
787  ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
788 
789  my_free_called = 0;
790  StubMsg.Buffer = StubMsg.BufferStart;
791  NdrPointerFree( &StubMsg, mem, &fmtstr_ref_unique_out[4] );
792  ok(my_free_called == 1, "free called %d\n", my_free_called);
793 
794  mem = my_alloc(sizeof(void *));
795  *(void **)mem = NULL;
796  my_free_called = 0;
797  StubMsg.Buffer = StubMsg.BufferStart;
798  NdrPointerFree( &StubMsg, mem, &fmtstr_ref_unique_out[4] );
799  ok(my_free_called == 0, "free called %d\n", my_free_called);
800  my_free(mem);
801 
802  mem = my_alloc(sizeof(void *));
803  *(void **)mem = my_alloc(sizeof(char));
804  my_free_called = 0;
805  StubMsg.Buffer = StubMsg.BufferStart;
806  NdrPointerFree( &StubMsg, mem, &fmtstr_ref_unique_out[4] );
807  ok(my_free_called == 1, "free called %d\n", my_free_called);
808  my_free(mem);
809 
810  /* Server */
811  my_alloc_called = 0;
812  my_free_called = 0;
813  StubMsg.IsClient = 0;
814  mem = NULL;
815  StubMsg.Buffer = StubMsg.BufferStart;
816  NdrPointerUnmarshall( &StubMsg, &mem, &fmtstr_ref_unique_out[4], 0);
817  ok(mem != StubMsg.BufferStart, "mem pointing at buffer\n");
818  ok(my_alloc_called == 1, "alloc called %d\n", my_alloc_called);
819  NdrPointerFree( &StubMsg, mem, &fmtstr_ref_unique_out[4] );
820  ok(my_free_called == 0, "free called %d\n", my_free_called);
821  my_free(mem);
822 
823  my_alloc_called = 0;
824  my_free_called = 0;
825  mem = NULL;
826  StubMsg.Buffer = StubMsg.BufferStart;
827  NdrPointerUnmarshall( &StubMsg, &mem, &fmtstr_ref_unique_out[4], 1);
828  ok(mem != StubMsg.BufferStart, "mem pointing at buffer\n");
829  ok(my_alloc_called == 1, "alloc called %d\n", my_alloc_called);
830  NdrPointerFree( &StubMsg, mem, &fmtstr_ref_unique_out[4] );
831  ok(my_free_called == 0, "free called %d\n", my_free_called);
832  my_free(mem);
833 
834  my_alloc_called = 0;
835  mem = mem_orig;
836  *(void **)mem = NULL;
837  StubMsg.Buffer = StubMsg.BufferStart;
838  NdrPointerUnmarshall( &StubMsg, &mem, &fmtstr_ref_unique_out[4], 0);
839  ok(mem == mem_orig, "mem alloced\n");
840  ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
841 
842  my_alloc_called = 0;
843  mem = mem_orig;
844  *(void **)mem = NULL;
845  StubMsg.Buffer = StubMsg.BufferStart;
846  NdrPointerUnmarshall( &StubMsg, &mem, &fmtstr_ref_unique_out[4], 1);
847  ok(mem == mem_orig, "mem alloced\n");
848  ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
849 
850  mem = my_alloc(sizeof(void *));
851  *(void **)mem = NULL;
852  my_free_called = 0;
853  StubMsg.Buffer = StubMsg.BufferStart;
854  NdrPointerFree( &StubMsg, mem, &fmtstr_ref_unique_out[4] );
855  ok(my_free_called == 0, "free called %d\n", my_free_called);
856  my_free(mem);
857 
858  mem = my_alloc(sizeof(void *));
859  *(void **)mem = my_alloc(sizeof(char));
860  my_free_called = 0;
861  StubMsg.Buffer = StubMsg.BufferStart;
862  NdrPointerFree( &StubMsg, mem, &fmtstr_ref_unique_out[4] );
863  ok(my_free_called == 1, "free called %d\n", my_free_called);
864  my_free(mem);
865 
866  HeapFree(GetProcessHeap(), 0, mem_orig);
867  HeapFree(GetProcessHeap(), 0, StubMsg.RpcMsg->Buffer);
868 }
869 
870 static void test_simple_struct_marshal(const unsigned char *formattypes,
871  void *memsrc, DWORD srcsize,
872  const void *wiredata,
873  ULONG wiredatalen,
874  int(*cmp)(const void*,const void*,size_t),
875  int num_additional_allocs,
876  const char *msgpfx)
877 {
878  RPC_MESSAGE RpcMessage;
879  MIDL_STUB_MESSAGE StubMsg;
880  MIDL_STUB_DESC StubDesc;
881  DWORD size;
882  void *ptr;
883  unsigned char *mem, *mem_orig;
884 
886  if(!cmp)
887  cmp = memcmp;
888 
889  StubDesc = Object_StubDesc;
890  StubDesc.pFormatTypes = formattypes;
891 
892  NdrClientInitializeNew(&RpcMessage, &StubMsg, &StubDesc, 0);
893 
894  StubMsg.BufferLength = 0;
895  NdrSimpleStructBufferSize( &StubMsg, memsrc, formattypes );
896  ok(StubMsg.BufferLength >= wiredatalen, "%s: length %d\n", msgpfx, StubMsg.BufferLength);
897  StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
898  StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
899  ptr = NdrSimpleStructMarshall( &StubMsg, memsrc, formattypes );
900  ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
901  ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart);
902  ok(!memcmp(StubMsg.BufferStart, wiredata, wiredatalen), "%s: incorrectly marshaled %08x %08x %08x\n", msgpfx, *(DWORD*)StubMsg.BufferStart,*((DWORD*)StubMsg.BufferStart+1),*((DWORD*)StubMsg.BufferStart+2));
903 
904  StubMsg.Buffer = StubMsg.BufferStart;
905  StubMsg.MemorySize = 0;
906  size = NdrSimpleStructMemorySize( &StubMsg, formattypes );
907  ok(size == StubMsg.MemorySize, "%s: size != MemorySize\n", msgpfx);
908  ok(size == srcsize, "%s: mem size %u\n", msgpfx, size);
909  ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart);
910 
911  StubMsg.Buffer = StubMsg.BufferStart;
912  size = NdrSimpleStructMemorySize( &StubMsg, formattypes );
913  ok(size == StubMsg.MemorySize, "%s: size != MemorySize\n", msgpfx);
914  ok(StubMsg.MemorySize == ((srcsize + 3) & ~3) + srcsize, "%s: mem size %u\n", msgpfx, size);
915  ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart);
916  size = srcsize;
917  /*** Unmarshalling first with must_alloc false ***/
918 
919  StubMsg.Buffer = StubMsg.BufferStart;
920  StubMsg.MemorySize = 0;
921  mem_orig = mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, srcsize);
922  ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, 0 );
923  ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
924  ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart);
925  ok(mem == mem_orig, "%s: mem has changed %p %p\n", msgpfx, mem, mem_orig);
926  ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx);
927  ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
928  my_alloc_called = 0;
929  my_free_called = 0;
930  ok(StubMsg.MemorySize == 0, "%s: memorysize touched in unmarshal\n", msgpfx);
931  NdrSimpleStructFree(&StubMsg, mem, formattypes );
932  ok(my_free_called == num_additional_allocs, "free called %d\n", my_free_called);
933 
934  /* If we're a server we still use the supplied memory */
935  StubMsg.Buffer = StubMsg.BufferStart;
936  StubMsg.IsClient = 0;
937  ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, 0 );
938  ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
939  ok(mem == mem_orig, "%s: mem has changed %p %p\n", msgpfx, mem, mem_orig);
940  ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx);
941  ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
942  my_alloc_called = 0;
943  my_free_called = 0;
944  ok(StubMsg.MemorySize == 0, "%s: memorysize touched in unmarshal\n", msgpfx);
945  NdrSimpleStructFree(&StubMsg, mem, formattypes );
946  ok(my_free_called == num_additional_allocs, "free called %d\n", my_free_called);
947 
948  /* ...unless we pass a NULL ptr, then the buffer is used.
949  Passing a NULL ptr while we're a client && !must_alloc
950  crashes on Windows, so we won't do that. */
951 
952  if (0) /* crashes on Win9x and NT4 */
953  {
954  mem = NULL;
955  StubMsg.IsClient = 0;
956  StubMsg.Buffer = StubMsg.BufferStart;
957  ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, FALSE );
958  ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
959  ok(mem == StubMsg.BufferStart, "%s: mem not equal buffer\n", msgpfx);
960  ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx);
961  ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
962  my_alloc_called = 0;
963  ok(StubMsg.MemorySize == 0, "%s: memorysize touched in unmarshal\n", msgpfx);
964  NdrSimpleStructFree(&StubMsg, mem, formattypes );
965  ok(my_free_called == num_additional_allocs, "free called %d\n", my_free_called);
966  }
967 
968  /*** now must_alloc is true ***/
969 
970  /* with must_alloc set we always allocate new memory whether or not we're
971  a server and also when passing NULL */
972  mem = mem_orig;
973  StubMsg.IsClient = 1;
974  StubMsg.Buffer = StubMsg.BufferStart;
975  ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, 1 );
976  ok(ptr == NULL, "ret %p\n", ptr);
977  ok(mem != mem_orig, "mem not changed %p %p\n", mem, mem_orig);
978  ok(!cmp(mem, memsrc, srcsize), "incorrectly unmarshaled\n");
979  ok(my_alloc_called == num_additional_allocs + 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
980  my_alloc_called = 0;
981  my_free_called = 0;
982  ok(StubMsg.MemorySize == 0, "memorysize touched in unmarshal\n");
983  NdrSimpleStructFree(&StubMsg, mem, formattypes );
984  ok(my_free_called == num_additional_allocs, "free called %d\n", my_free_called);
985  my_free(mem);
986 
987  mem = NULL;
988  StubMsg.Buffer = StubMsg.BufferStart;
989  ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, 1 );
990  ok(ptr == NULL, "ret %p\n", ptr);
991  ok(mem != mem_orig, "mem not changed %p %p\n", mem, mem_orig);
992  ok(!cmp(mem, memsrc, srcsize), "incorrectly unmarshaled\n");
993  ok(my_alloc_called == num_additional_allocs + 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
994  my_alloc_called = 0;
995  my_free_called = 0;
996  ok(StubMsg.MemorySize == 0, "memorysize touched in unmarshal\n");
997  NdrSimpleStructFree(&StubMsg, mem, formattypes );
998  ok(my_free_called == num_additional_allocs, "free called %d\n", my_free_called);
999  my_free(mem);
1000 
1001  mem = mem_orig;
1002  StubMsg.Buffer = StubMsg.BufferStart;
1003  StubMsg.IsClient = 0;
1004  StubMsg.ReuseBuffer = 1;
1005  ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, 1 );
1006  ok(ptr == NULL, "ret %p\n", ptr);
1007  ok(mem != mem_orig, "mem not changed %p %p\n", mem, mem_orig);
1008  ok(mem != StubMsg.BufferStart, "mem is buffer mem\n");
1009  ok(!cmp(mem, memsrc, srcsize), "incorrectly unmarshaled\n");
1010  ok(my_alloc_called == num_additional_allocs + 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
1011  my_alloc_called = 0;
1012  my_free_called = 0;
1013  ok(StubMsg.MemorySize == 0, "memorysize touched in unmarshal\n");
1014  NdrSimpleStructFree(&StubMsg, mem, formattypes );
1015  ok(my_free_called == num_additional_allocs, "free called %d\n", my_free_called);
1016  my_free(mem);
1017 
1018  mem = NULL;
1019  StubMsg.Buffer = StubMsg.BufferStart;
1020  StubMsg.IsClient = 0;
1021  StubMsg.ReuseBuffer = 1;
1022  ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, 1 );
1023  ok(ptr == NULL, "ret %p\n", ptr);
1024  ok(mem != StubMsg.BufferStart, "mem is buffer mem\n");
1025  ok(!cmp(mem, memsrc, srcsize), "incorrectly unmarshaled\n");
1026  ok(my_alloc_called == num_additional_allocs + 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
1027  my_alloc_called = 0;
1028  my_free_called = 0;
1029  ok(StubMsg.MemorySize == 0, "memorysize touched in unmarshal\n");
1030  NdrSimpleStructFree(&StubMsg, mem, formattypes );
1031  ok(my_free_called == num_additional_allocs, "free called %d\n", my_free_called);
1032  my_free(mem);
1033 
1034  HeapFree(GetProcessHeap(), 0, mem_orig);
1035  HeapFree(GetProcessHeap(), 0, StubMsg.BufferStart);
1036 }
1037 
1038 typedef struct
1039 {
1042  char *pc1;
1043 } ps1_t;
1044 
1045 static int ps1_cmp(const void *s1, const void *s2, size_t num)
1046 {
1047  const ps1_t *p1, *p2;
1048 
1049  p1 = s1;
1050  p2 = s2;
1051 
1052  if(p1->l1 != p2->l1)
1053  return 1;
1054 
1055  if(p1->pl1 && p2->pl1)
1056  {
1057  if(*p1->pl1 != *p2->pl1)
1058  return 1;
1059  }
1060  else if(p1->pl1 || p2->pl1)
1061  return 1;
1062 
1063  if(p1->pc1 && p2->pc1)
1064  {
1065  if(*p1->pc1 != *p2->pc1)
1066  return 1;
1067  }
1068  else if(p1->pc1 || p2->pc1)
1069  return 1;
1070 
1071  return 0;
1072 }
1073 
1074 static void test_simple_struct(void)
1075 {
1076  unsigned char wiredata[28];
1077  ULONG wiredatalen;
1078  LONG l;
1079  char c;
1080  ps1_t ps1;
1081 
1082  static const unsigned char fmtstr_simple_struct[] =
1083  {
1084  0x12, 0x0, /* FC_UP */
1085  NdrFcShort( 0x2 ), /* Offset=2 */
1086  0x15, 0x3, /* FC_STRUCT [align 4] */
1087  NdrFcShort( 0x18 ), /* [size 24] */
1088  0x6, /* FC_SHORT */
1089  0x2, /* FC_CHAR */
1090  0x38, /* FC_ALIGNM4 */
1091  0x8, /* FC_LONG */
1092  0x8, /* FC_LONG */
1093  0x39, /* FC_ALIGNM8 */
1094  0xb, /* FC_HYPER */
1095  0x5b, /* FC_END */
1096  };
1097  struct {
1098  short s;
1099  char c;
1100  LONG l1, l2;
1101  LONGLONG ll;
1102  } s1;
1103 
1104  static const unsigned char fmtstr_pointer_struct[] =
1105  {
1106  0x12, 0x0, /* FC_UP */
1107  NdrFcShort( 0x2 ), /* Offset=2 */
1108 #ifdef _WIN64
1109  0x1a, /* FC_BOGUS_STRUCT */
1110  0x3, /* 3 */
1111  NdrFcShort(0x18), /* [size 24] */
1112  NdrFcShort(0x0),
1113  NdrFcShort(0x8), /* Offset= 8 (266) */
1114  0x08, /* FC_LONG */
1115  0x39, /* FC_ALIGNM8 */
1116  0x36, /* FC_POINTER */
1117  0x36, /* FC_POINTER */
1118  0x5c, /* FC_PAD */
1119  0x5b, /* FC_END */
1120  0x12, 0x8, /* FC_UP [simple_pointer] */
1121  0x08, /* FC_LONG */
1122  0x5c, /* FC_PAD */
1123  0x12, 0x8, /* FC_UP [simple_pointer] */
1124  0x02, /* FC_CHAR */
1125  0x5c, /* FC_PAD */
1126 #else
1127  0x16, 0x3, /* FC_PSTRUCT [align 4] */
1128  NdrFcShort( 0xc ), /* [size 12] */
1129  0x4b, /* FC_PP */
1130  0x5c, /* FC_PAD */
1131  0x46, /* FC_NO_REPEAT */
1132  0x5c, /* FC_PAD */
1133  NdrFcShort( 0x4 ), /* 4 */
1134  NdrFcShort( 0x4 ), /* 4 */
1135  0x13, 0x8, /* FC_OP [simple_pointer] */
1136  0x8, /* FC_LONG */
1137  0x5c, /* FC_PAD */
1138  0x46, /* FC_NO_REPEAT */
1139  0x5c, /* FC_PAD */
1140  NdrFcShort( 0x8 ), /* 8 */
1141  NdrFcShort( 0x8 ), /* 8 */
1142  0x13, 0x8, /* FC_OP [simple_pointer] */
1143  0x2, /* FC_CHAR */
1144  0x5c, /* FC_PAD */
1145  0x5b, /* FC_END */
1146  0x8, /* FC_LONG */
1147  0x8, /* FC_LONG */
1148  0x8, /* FC_LONG */
1149  0x5c, /* FC_PAD */
1150  0x5b, /* FC_END */
1151 #endif
1152  };
1153 
1154  /* zero the entire structure, including the holes */
1155  memset(&s1, 0, sizeof(s1));
1156 
1157  /* FC_STRUCT */
1158  s1.s = 0x1234;
1159  s1.c = 0xa5;
1160  s1.l1 = 0xdeadbeef;
1161  s1.l2 = 0xcafebabe;
1162  s1.ll = ((ULONGLONG) 0xbadefeed << 32) | 0x2468ace0;
1163 
1164  wiredatalen = 24;
1165  memcpy(wiredata, &s1, wiredatalen);
1166  test_simple_struct_marshal(fmtstr_simple_struct + 4, &s1, 24, wiredata, 24, NULL, 0, "struct");
1167 
1168  if (use_pointer_ids)
1169  *(unsigned int *)wiredata = 0x20000;
1170  else
1171  *(unsigned int *)wiredata = (UINT_PTR)&s1;
1172  memcpy(wiredata + 4, &s1, wiredatalen);
1173  test_pointer_marshal(fmtstr_simple_struct, &s1, 24, wiredata, 28, NULL, 0, "struct");
1174 
1175  if (sizeof(void *) == 8) return; /* it cannot be represented as a simple struct on Win64 */
1176 
1177  /* zero the entire structure, including the hole */
1178  memset(&ps1, 0, sizeof(ps1));
1179 
1180  /* FC_PSTRUCT */
1181  ps1.l1 = 0xdeadbeef;
1182  l = 0xcafebabe;
1183  ps1.pl1 = &l;
1184  c = 'a';
1185  ps1.pc1 = &c;
1186  *(unsigned int *)(wiredata + 4) = 0xdeadbeef;
1187  if (use_pointer_ids)
1188  {
1189  *(unsigned int *)(wiredata + 8) = 0x20000;
1190  *(unsigned int *)(wiredata + 12) = 0x20004;
1191  }
1192  else
1193  {
1194  *(unsigned int *)(wiredata + 8) = (UINT_PTR)&l;
1195  *(unsigned int *)(wiredata + 12) = (UINT_PTR)&c;
1196  }
1197  memcpy(wiredata + 16, &l, 4);
1198  memcpy(wiredata + 20, &c, 1);
1199 
1200  test_simple_struct_marshal(fmtstr_pointer_struct + 4, &ps1, 17, wiredata + 4, 17, ps1_cmp, 2, "pointer_struct");
1201  if (use_pointer_ids)
1202  {
1203  *(unsigned int *)wiredata = 0x20000;
1204  *(unsigned int *)(wiredata + 8) = 0x20004;
1205  *(unsigned int *)(wiredata + 12) = 0x20008;
1206  }
1207  else
1208  *(unsigned int *)wiredata = (UINT_PTR)&ps1;
1209  test_pointer_marshal(fmtstr_pointer_struct, &ps1, 17, wiredata, 21, ps1_cmp, 2, "pointer_struct");
1210 }
1211 
1212 struct aligned
1213 {
1214  int a;
1216 };
1217 
1218 static void test_struct_align(void)
1219 {
1220  RPC_MESSAGE RpcMessage;
1221  MIDL_STUB_MESSAGE StubMsg;
1222  MIDL_STUB_DESC StubDesc;
1223  void *ptr;
1224  struct aligned *memsrc_orig, *memsrc, *mem;
1225 
1226  /* force bogus struct so that members are marshalled individually */
1227  static const unsigned char fmtstr[] =
1228  {
1229  0x1a, /* FC_BOGUS_STRUCT */
1230  0x7, /* alignment 8 */
1231  NdrFcShort(0x10), /* memory size 16 */
1232  NdrFcShort(0x0),
1233  NdrFcShort(0x0),
1234  0x08, /* FC_LONG */
1235  0x39, /* FC_ALIGNM8 */
1236  0x0b, /* FC_HYPER */
1237  0x5b, /* FC_END */
1238  };
1239 
1240  memsrc_orig = heap_alloc_zero(sizeof(struct aligned) + 8);
1241  /* intentionally mis-align memsrc */
1242  memsrc = (struct aligned *)((((ULONG_PTR)memsrc_orig + 7) & ~7) + 4);
1243 
1244  memsrc->a = 0xdeadbeef;
1245  memsrc->b = ((ULONGLONG) 0xbadefeed << 32) | 0x2468ace0;
1246 
1247  StubDesc = Object_StubDesc;
1248  StubDesc.pFormatTypes = fmtstr;
1249  NdrClientInitializeNew(&RpcMessage, &StubMsg, &StubDesc, 0);
1250 
1251  StubMsg.BufferLength = 0;
1252  NdrComplexStructBufferSize(&StubMsg, (unsigned char *)memsrc, fmtstr);
1253 
1254  StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = heap_alloc(StubMsg.BufferLength);
1255  StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
1256 
1257  ptr = NdrComplexStructMarshall(&StubMsg, (unsigned char *)memsrc, fmtstr);
1258  ok(ptr == NULL, "ret %p\n", ptr);
1259 
1260  /* Server */
1261  StubMsg.IsClient = 0;
1262  mem = NULL;
1263  StubMsg.Buffer = StubMsg.BufferStart;
1264  ptr = NdrComplexStructUnmarshall(&StubMsg, (unsigned char **)&mem, fmtstr, 0);
1265  ok(ptr == NULL, "ret %p\n", ptr);
1266  ok(!memcmp(mem, memsrc, sizeof(*memsrc)), "struct wasn't unmarshalled correctly\n");
1267  StubMsg.pfnFree(mem);
1268 
1269  heap_free(StubMsg.RpcMsg->Buffer);
1270  heap_free(memsrc_orig);
1271 }
1272 
1274 {
1277 };
1278 
1279 static struct testiface *impl_from_IPersist(IPersist *iface)
1280 {
1281  return CONTAINING_RECORD(iface, struct testiface, IPersist_iface);
1282 }
1283 
1285 {
1286  if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IPersist))
1287  {
1288  *out = iface;
1289  IPersist_AddRef(iface);
1290  return S_OK;
1291  }
1292 
1293  *out = NULL;
1294  return E_NOINTERFACE;
1295 }
1296 
1298 {
1299  struct testiface *unk = impl_from_IPersist(iface);
1300  return ++unk->ref;
1301 }
1302 
1304 {
1305  struct testiface *unk = impl_from_IPersist(iface);
1306  return --unk->ref;
1307 }
1308 
1310 {
1311  *clsid = IID_IPersist;
1312  return S_OK;
1313 }
1314 
1315 static IPersistVtbl testiface_vtbl = {
1320 };
1321 
1322 static void test_iface_ptr(void)
1323 {
1324  struct testiface server_obj = {{&testiface_vtbl}, 1};
1325  struct testiface client_obj = {{&testiface_vtbl}, 1};
1326 
1327  MIDL_STUB_MESSAGE StubMsg;
1328  MIDL_STUB_DESC StubDesc;
1329  RPC_MESSAGE RpcMessage;
1330  IPersist *proxy;
1331  HRESULT hr;
1332  GUID clsid;
1333  void *ptr;
1334  LONG ref;
1335 
1336  static const unsigned char fmtstr_ip[] =
1337  {
1338  FC_IP,
1340  NdrFcLong(0x0000010c),
1341  NdrFcShort(0x0000),
1342  NdrFcShort(0x0000),
1343  0xc0,
1344  0x00,
1345  0x00,
1346  0x00,
1347  0x00,
1348  0x00,
1349  0x00,
1350  0x46,
1351  };
1352 
1353  CoInitialize(NULL);
1354 
1355  StubDesc = Object_StubDesc;
1356  StubDesc.pFormatTypes = fmtstr_ip;
1357 
1358  NdrClientInitializeNew(&RpcMessage, &StubMsg, &StubDesc, 0);
1359  StubMsg.BufferLength = 0;
1360  NdrInterfacePointerBufferSize(&StubMsg, (unsigned char *)&client_obj.IPersist_iface, fmtstr_ip);
1361 
1362  StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
1363  StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
1364 
1365  /* server -> client */
1366 
1367  StubMsg.IsClient = 0;
1369  StubMsg.Buffer = StubMsg.BufferStart;
1370  IPersist_AddRef(&server_obj.IPersist_iface);
1371  ptr = NdrInterfacePointerMarshall(&StubMsg, (unsigned char *)&server_obj.IPersist_iface, fmtstr_ip);
1372  ok(!ptr, "ret %p\n", ptr);
1373  ok(server_obj.ref > 2, "got %d references\n", server_obj.ref);
1374  ok(!my_alloc_called, "alloc called %d\n", my_alloc_called);
1375  ok(!my_free_called, "free called %d\n", my_free_called);
1376 
1377  NdrInterfacePointerFree(&StubMsg, (unsigned char *)&server_obj.IPersist_iface, fmtstr_ip);
1378  ok(server_obj.ref > 1, "got %d references\n", server_obj.ref);
1379 
1380  StubMsg.IsClient = 1;
1382  StubMsg.Buffer = StubMsg.BufferStart;
1383  proxy = NULL;
1384  ptr = NdrInterfacePointerUnmarshall(&StubMsg, (unsigned char **)&proxy, fmtstr_ip, 0);
1385  ok(!ptr, "ret %p\n", ptr);
1386  ok(!!proxy, "mem not alloced\n");
1387  ok(!my_alloc_called, "alloc called %d\n", my_alloc_called);
1388  ok(!my_free_called, "free called %d\n", my_free_called);
1389  ok(server_obj.ref > 1, "got %d references\n", server_obj.ref);
1390 
1391  hr = IPersist_GetClassID(proxy, &clsid);
1392  ok(hr == S_OK, "got hr %#x\n", hr);
1393  ok(IsEqualGUID(&clsid, &IID_IPersist), "wrong clsid %s\n", wine_dbgstr_guid(&clsid));
1394 
1395  ref = IPersist_Release(proxy);
1396  ok(ref == 1, "got %d references\n", ref);
1397  ok(server_obj.ref == 1, "got %d references\n", server_obj.ref);
1398 
1399  /* An existing interface pointer is released; this is necessary so that an
1400  * [in, out] pointer which changes does not leak references. */
1401 
1402  StubMsg.IsClient = 0;
1404  StubMsg.Buffer = StubMsg.BufferStart;
1405  IPersist_AddRef(&server_obj.IPersist_iface);
1406  ptr = NdrInterfacePointerMarshall(&StubMsg, (unsigned char *)&server_obj.IPersist_iface, fmtstr_ip);
1407  ok(!ptr, "ret %p\n", ptr);
1408  ok(server_obj.ref > 2, "got %d references\n", server_obj.ref);
1409  ok(!my_alloc_called, "alloc called %d\n", my_alloc_called);
1410  ok(!my_free_called, "free called %d\n", my_free_called);
1411 
1412  NdrInterfacePointerFree(&StubMsg, (unsigned char *)&server_obj.IPersist_iface, fmtstr_ip);
1413  ok(server_obj.ref > 1, "got %d references\n", server_obj.ref);
1414 
1415  StubMsg.IsClient = 1;
1417  StubMsg.Buffer = StubMsg.BufferStart;
1418  proxy = &client_obj.IPersist_iface;
1419  IPersist_AddRef(proxy);
1420  ptr = NdrInterfacePointerUnmarshall(&StubMsg, (unsigned char **)&proxy, fmtstr_ip, 0);
1421  ok(!ptr, "ret %p\n", ptr);
1422  ok(!!proxy && proxy != &client_obj.IPersist_iface, "mem not alloced\n");
1423  ok(!my_alloc_called, "alloc called %d\n", my_alloc_called);
1424  ok(!my_free_called, "free called %d\n", my_free_called);
1425  ok(server_obj.ref > 1, "got %d references\n", server_obj.ref);
1426  ok(client_obj.ref == 1, "got %d references\n", client_obj.ref);
1427 
1428  hr = IPersist_GetClassID(proxy, &clsid);
1429  ok(hr == S_OK, "got hr %#x\n", hr);
1430  ok(IsEqualGUID(&clsid, &IID_IPersist), "wrong clsid %s\n", wine_dbgstr_guid(&clsid));
1431 
1432  ref = IPersist_Release(proxy);
1433  ok(ref == 1, "got %d references\n", ref);
1434  ok(server_obj.ref == 1, "got %d references\n", server_obj.ref);
1435 
1436  /* client -> server */
1437 
1438  StubMsg.IsClient = 1;
1440  StubMsg.Buffer = StubMsg.BufferStart;
1441  IPersist_AddRef(&client_obj.IPersist_iface);
1442  ptr = NdrInterfacePointerMarshall(&StubMsg, (unsigned char *)&client_obj.IPersist_iface, fmtstr_ip);
1443  ok(!ptr, "ret %p\n", ptr);
1444  ok(client_obj.ref > 2, "got %d references\n", client_obj.ref);
1445  ok(!my_alloc_called, "alloc called %d\n", my_alloc_called);
1446  ok(!my_free_called, "free called %d\n", my_free_called);
1447 
1448  StubMsg.IsClient = 0;
1450  StubMsg.Buffer = StubMsg.BufferStart;
1451  proxy = NULL;
1452  ptr = NdrInterfacePointerUnmarshall(&StubMsg, (unsigned char **)&proxy, fmtstr_ip, 0);
1453  ok(!ptr, "ret %p\n", ptr);
1454  ok(!!proxy, "mem not alloced\n");
1455  ok(!my_alloc_called, "alloc called %d\n", my_alloc_called);
1456  ok(!my_free_called, "free called %d\n", my_free_called);
1457  ok(client_obj.ref > 2, "got %d references\n", client_obj.ref);
1458 
1459  hr = IPersist_GetClassID(proxy, &clsid);
1460  ok(hr == S_OK, "got hr %#x\n", hr);
1461  ok(IsEqualGUID(&clsid, &IID_IPersist), "wrong clsid %s\n", wine_dbgstr_guid(&clsid));
1462 
1463  ref = IPersist_Release(proxy);
1464  ok(client_obj.ref > 1, "got %d references\n", client_obj.ref);
1465  ok(ref == client_obj.ref, "expected %d references, got %d\n", client_obj.ref, ref);
1466 
1467  NdrInterfacePointerFree(&StubMsg, (unsigned char *)proxy, fmtstr_ip);
1468  ok(client_obj.ref == 1, "got %d references\n", client_obj.ref);
1469 
1470  /* same, but free the interface after calling NdrInterfacePointerFree */
1471 
1472  StubMsg.IsClient = 1;
1474  StubMsg.Buffer = StubMsg.BufferStart;
1475  IPersist_AddRef(&client_obj.IPersist_iface);
1476  ptr = NdrInterfacePointerMarshall(&StubMsg, (unsigned char *)&client_obj.IPersist_iface, fmtstr_ip);
1477  ok(!ptr, "ret %p\n", ptr);
1478  ok(client_obj.ref > 2, "got %d references\n", client_obj.ref);
1479  ok(!my_alloc_called, "alloc called %d\n", my_alloc_called);
1480  ok(!my_free_called, "free called %d\n", my_free_called);
1481 
1482  StubMsg.IsClient = 0;
1484  StubMsg.Buffer = StubMsg.BufferStart;
1485  proxy = NULL;
1486  ptr = NdrInterfacePointerUnmarshall(&StubMsg, (unsigned char **)&proxy, fmtstr_ip, 0);
1487  ok(!ptr, "ret %p\n", ptr);
1488  ok(!!proxy, "mem not alloced\n");
1489  ok(!my_alloc_called, "alloc called %d\n", my_alloc_called);
1490  ok(!my_free_called, "free called %d\n", my_free_called);
1491  ok(client_obj.ref > 2, "got %d references\n", client_obj.ref);
1492 
1493  NdrInterfacePointerFree(&StubMsg, (unsigned char *)proxy, fmtstr_ip);
1494  ok(client_obj.ref > 1, "got %d references\n", client_obj.ref);
1495 
1496  hr = IPersist_GetClassID(proxy, &clsid);
1497  ok(hr == S_OK, "got hr %#x\n", hr);
1498  ok(IsEqualGUID(&clsid, &IID_IPersist), "wrong clsid %s\n", wine_dbgstr_guid(&clsid));
1499 
1500  ref = IPersist_Release(proxy);
1501  ok(ref == 1, "got %d references\n", ref);
1502  ok(client_obj.ref == 1, "got %d references\n", client_obj.ref);
1503 
1504  /* An existing interface pointer is *not* released (in fact, it is ignored
1505  * and may be invalid). In practice it will always be NULL anyway. */
1506 
1507  StubMsg.IsClient = 1;
1509  StubMsg.Buffer = StubMsg.BufferStart;
1510  IPersist_AddRef(&client_obj.IPersist_iface);
1511  ptr = NdrInterfacePointerMarshall(&StubMsg, (unsigned char *)&client_obj.IPersist_iface, fmtstr_ip);
1512  ok(!ptr, "ret %p\n", ptr);
1513  ok(client_obj.ref > 2, "got %d references\n", client_obj.ref);
1514  ok(!my_alloc_called, "alloc called %d\n", my_alloc_called);
1515  ok(!my_free_called, "free called %d\n", my_free_called);
1516 
1517  StubMsg.IsClient = 0;
1519  StubMsg.Buffer = StubMsg.BufferStart;
1520  proxy = &server_obj.IPersist_iface;
1521  IPersist_AddRef(proxy);
1522  ptr = NdrInterfacePointerUnmarshall(&StubMsg, (unsigned char **)&proxy, fmtstr_ip, 0);
1523  ok(!ptr, "ret %p\n", ptr);
1524  ok(!!proxy && proxy != &server_obj.IPersist_iface, "mem not alloced\n");
1525  ok(!my_alloc_called, "alloc called %d\n", my_alloc_called);
1526  ok(!my_free_called, "free called %d\n", my_free_called);
1527  ok(client_obj.ref > 2, "got %d references\n", client_obj.ref);
1528  ok(server_obj.ref == 2, "got %d references\n", server_obj.ref);
1529  IPersist_Release(&server_obj.IPersist_iface);
1530 
1531  hr = IPersist_GetClassID(proxy, &clsid);
1532  ok(hr == S_OK, "got hr %#x\n", hr);
1533  ok(IsEqualGUID(&clsid, &IID_IPersist), "wrong clsid %s\n", wine_dbgstr_guid(&clsid));
1534 
1535  ref = IPersist_Release(proxy);
1536  ok(client_obj.ref > 1, "got %d references\n", client_obj.ref);
1537  ok(ref == client_obj.ref, "expected %d references, got %d\n", client_obj.ref, ref);
1538 
1539  NdrInterfacePointerFree(&StubMsg, (unsigned char *)proxy, fmtstr_ip);
1540  ok(client_obj.ref == 1, "got %d references\n", client_obj.ref);
1541 
1542  HeapFree(GetProcessHeap(), 0, StubMsg.BufferStart);
1543 
1544  CoUninitialize();
1545 }
1546 
1547 static void test_fullpointer_xlat(void)
1548 {
1549  PFULL_PTR_XLAT_TABLES pXlatTables;
1550  ULONG RefId;
1551  int ret;
1552  void *Pointer;
1553 
1554  pXlatTables = NdrFullPointerXlatInit(2, XLAT_CLIENT);
1555 
1556  /* "marshaling" phase */
1557 
1558  ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebeef, 1, &RefId);
1559  ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1560  ok(RefId == 0x1, "RefId should be 0x1 instead of 0x%x\n", RefId);
1561 
1562  ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebeef, 0, &RefId);
1563  ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1564  ok(RefId == 0x1, "RefId should be 0x1 instead of 0x%x\n", RefId);
1565 
1566  ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebabe, 0, &RefId);
1567  ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1568  ok(RefId == 0x2, "RefId should be 0x2 instead of 0x%x\n", RefId);
1569 
1570  ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xdeadbeef, 0, &RefId);
1571  ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1572  ok(RefId == 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId);
1573 
1574  ret = NdrFullPointerQueryPointer(pXlatTables, NULL, 0, &RefId);
1575  ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1576  ok(RefId == 0, "RefId should be 0 instead of 0x%x\n", RefId);
1577 
1578  /* "unmarshaling" phase */
1579 
1580  ret = NdrFullPointerQueryRefId(pXlatTables, 0x0, 0, &Pointer);
1581  ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1582 
1583  ret = NdrFullPointerQueryRefId(pXlatTables, 0x2, 0, &Pointer);
1584  ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1585  ok(Pointer == (void *)0xcafebabe, "Pointer should be 0xcafebabe instead of %p\n", Pointer);
1586 
1587  ret = NdrFullPointerQueryRefId(pXlatTables, 0x4, 0, &Pointer);
1588  ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1589  ok(Pointer == NULL, "Pointer should be NULL instead of %p\n", Pointer);
1590 
1591  NdrFullPointerInsertRefId(pXlatTables, 0x4, (void *)0xdeadbabe);
1592 
1593  ret = NdrFullPointerQueryRefId(pXlatTables, 0x4, 1, &Pointer);
1594  ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1595  ok(Pointer == (void *)0xdeadbabe, "Pointer should be (void *)0xdeadbabe instead of %p\n", Pointer);
1596 
1597  NdrFullPointerXlatFree(pXlatTables);
1598 
1599  pXlatTables = NdrFullPointerXlatInit(2, XLAT_SERVER);
1600 
1601  /* "unmarshaling" phase */
1602 
1603  ret = NdrFullPointerQueryRefId(pXlatTables, 0x2, 1, &Pointer);
1604  ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1605  ok(Pointer == NULL, "Pointer should be NULL instead of %p\n", Pointer);
1606 
1607  NdrFullPointerInsertRefId(pXlatTables, 0x2, (void *)0xcafebabe);
1608 
1609  ret = NdrFullPointerQueryRefId(pXlatTables, 0x2, 0, &Pointer);
1610  ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1611  ok(Pointer == (void *)0xcafebabe, "Pointer should be (void *)0xcafebabe instead of %p\n", Pointer);
1612 
1613  ret = NdrFullPointerQueryRefId(pXlatTables, 0x2, 1, &Pointer);
1614  ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1615  ok(Pointer == (void *)0xcafebabe, "Pointer should be (void *)0xcafebabe instead of %p\n", Pointer);
1616 
1617  /* "marshaling" phase */
1618 
1619  ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebeef, 1, &RefId);
1620  ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1621  ok(RefId == 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId);
1622 
1623  ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebeef, 1, &RefId);
1624  ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1625  ok(RefId == 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId);
1626 
1627  ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebeef, 0, &RefId);
1628  ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1629  ok(RefId == 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId);
1630 
1631  ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebabe, 0, &RefId);
1632  ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1633  ok(RefId == 0x2, "RefId should be 0x2 instead of 0x%x\n", RefId);
1634 
1635  ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xdeadbeef, 0, &RefId);
1636  ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1637  ok(RefId == 0x4, "RefId should be 0x4 instead of 0x%x\n", RefId);
1638 
1639  /* "freeing" phase */
1640 
1641  ret = NdrFullPointerFree(pXlatTables, (void *)0xcafebeef);
1642  ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1643 
1644  ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebeef, 0x20, &RefId);
1645  ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1646  ok(RefId == 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId);
1647 
1648  ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebeef, 1, &RefId);
1649  ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1650  ok(RefId == 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId);
1651 
1652  ret = NdrFullPointerFree(pXlatTables, (void *)0xcafebabe);
1653  ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1654 
1655  ret = NdrFullPointerFree(pXlatTables, (void *)0xdeadbeef);
1656  ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1657 
1658  ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xdeadbeef, 0x20, &RefId);
1659  ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1660  ok(RefId == 0x4, "RefId should be 0x4 instead of 0x%x\n", RefId);
1661 
1662  ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xdeadbeef, 1, &RefId);
1663  ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1664  ok(RefId == 0x4, "RefId should be 0x4 instead of 0x%x\n", RefId);
1665 
1666  ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xdeadbeef, 1, &RefId);
1667  ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1668  ok(RefId == 0x4, "RefId should be 0x4 instead of 0x%x\n", RefId);
1669 
1670  ret = NdrFullPointerFree(pXlatTables, (void *)0xdeadbeef);
1671  ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1672 
1673  NdrFullPointerXlatFree(pXlatTables);
1674 }
1675 
1676 /* verify stub data that is identical between client and server */
1677 static void test_common_stub_data( const char *prefix, const MIDL_STUB_MESSAGE *stubMsg )
1678 {
1679  void *unset_ptr;
1680 
1681  memset(&unset_ptr, 0xcc, sizeof(unset_ptr));
1682 
1683 #define TEST_ZERO(field, fmt) ok(stubMsg->field == 0, "%s: " #field " should have been set to zero instead of " fmt "\n", prefix, stubMsg->field)
1684 #define TEST_POINTER_UNSET(field) ok(stubMsg->field == unset_ptr, "%s: " #field " should have been unset instead of %p\n", prefix, stubMsg->field)
1685 #define TEST_ULONG_UNSET(field) ok(stubMsg->field == 0xcccccccc, "%s: " #field " should have been unset instead of 0x%x\n", prefix, stubMsg->field)
1686 #define TEST_ULONG_PTR_UNSET(field) ok(stubMsg->field == (ULONG_PTR)unset_ptr, "%s: " #field " should have been unset instead of 0x%lx\n", prefix, stubMsg->field)
1687 
1688  TEST_POINTER_UNSET(BufferMark);
1691  TEST_ZERO(pAllocAllNodesContext, "%p");
1692  ok(stubMsg->pPointerQueueState == 0 ||
1693  broken(stubMsg->pPointerQueueState == unset_ptr), /* win2k */
1694  "%s: pPointerQueueState should have been unset instead of %p\n",
1695  prefix, stubMsg->pPointerQueueState);
1696  TEST_ZERO(IgnoreEmbeddedPointers, "%d");
1697  TEST_ZERO(PointerBufferMark, "%p");
1698  ok( stubMsg->uFlags == 0 ||
1699  broken(stubMsg->uFlags == 0xcc), /* win9x */
1700  "%s: uFlags should have been set to zero instead of 0x%x\n", prefix, stubMsg->uFlags );
1701  /* FIXME: UniquePtrCount */
1702  TEST_ULONG_PTR_UNSET(MaxCount);
1704  TEST_ULONG_UNSET(ActualCount);
1705  ok(stubMsg->pfnAllocate == my_alloc, "%s: pfnAllocate should have been %p instead of %p\n",
1706  prefix, my_alloc, stubMsg->pfnAllocate);
1707  ok(stubMsg->pfnFree == my_free, "%s: pfnFree should have been %p instead of %p\n",
1708  prefix, my_free, stubMsg->pfnFree);
1709  TEST_ZERO(StackTop, "%p");
1710  TEST_POINTER_UNSET(pPresentedType);
1711  TEST_POINTER_UNSET(pTransmitType);
1712  TEST_POINTER_UNSET(SavedHandle);
1713  ok(stubMsg->StubDesc == &Object_StubDesc, "%s: StubDesc should have been %p instead of %p\n",
1714  prefix, &Object_StubDesc, stubMsg->StubDesc);
1715  TEST_ZERO(FullPtrRefId, "%d");
1716  ok( stubMsg->PointerLength == 0 ||
1717  broken(stubMsg->PointerLength == 1), /* win9x, nt4 */
1718  "%s: pAsyncMsg should have been set to zero instead of %d\n", prefix, stubMsg->PointerLength );
1719  TEST_ZERO(fInDontFree, "%d");
1720  TEST_ZERO(fDontCallFreeInst, "%d");
1721  ok( stubMsg->fHasReturn == 0 || broken(stubMsg->fHasReturn), /* win9x, nt4 */
1722  "%s: fHasReturn should have been set to zero instead of %d\n", prefix, stubMsg->fHasReturn );
1723  TEST_ZERO(fHasExtensions, "%d");
1724  TEST_ZERO(fHasNewCorrDesc, "%d");
1725  ok(stubMsg->fIsIn == 0 || broken(stubMsg->fIsIn), /* win9x, nt4 */
1726  "%s: fIsIn should have been set to 0 instead of %d\n", prefix, stubMsg->fIsIn);
1727  TEST_ZERO(fIsOicf, "%d");
1728  ok(stubMsg->fBufferValid == 0,
1729  "%s: fBufferValid should have been set to 0 instead of %d\n", prefix, stubMsg->fBufferValid);
1730  TEST_ZERO(fNeedMCCP, "%d");
1731  ok(stubMsg->fUnused == 0 ||
1732  stubMsg->fUnused == -2, /* Vista */
1733  "%s: fUnused should have been set to 0 or -2 instead of %d\n", prefix, stubMsg->fUnused);
1734  ok(stubMsg->fUnused2 == 0xffffcccc, "%s: fUnused2 should have been 0xffffcccc instead of 0x%x\n",
1735  prefix, stubMsg->fUnused2);
1736  ok(stubMsg->dwDestContext == MSHCTX_DIFFERENTMACHINE,
1737  "%s: dwDestContext should have been MSHCTX_DIFFERENTMACHINE instead of %d\n",
1738  prefix, stubMsg->dwDestContext);
1739  TEST_ZERO(pvDestContext, "%p");
1740  TEST_POINTER_UNSET(SavedContextHandles);
1742  TEST_ZERO(pRpcChannelBuffer, "%p");
1743  TEST_ZERO(pArrayInfo, "%p");
1744  TEST_POINTER_UNSET(SizePtrCountArray);
1745  TEST_POINTER_UNSET(SizePtrOffsetArray);
1746  TEST_POINTER_UNSET(SizePtrLengthArray);
1747  TEST_POINTER_UNSET(pArgQueue);
1748  TEST_ZERO(dwStubPhase, "%d");
1749  /* FIXME: where does this value come from? */
1750  trace("%s: LowStackMark is %p\n", prefix, stubMsg->LowStackMark);
1751  ok( stubMsg->pAsyncMsg == 0 || broken(stubMsg->pAsyncMsg == unset_ptr), /* win9x, nt4 */
1752  "%s: pAsyncMsg should have been set to zero instead of %p\n", prefix, stubMsg->pAsyncMsg );
1753  ok( stubMsg->pCorrInfo == 0 || broken(stubMsg->pCorrInfo == unset_ptr), /* win9x, nt4 */
1754  "%s: pCorrInfo should have been set to zero instead of %p\n", prefix, stubMsg->pCorrInfo );
1755  ok( stubMsg->pCorrMemory == 0 || broken(stubMsg->pCorrMemory == unset_ptr), /* win9x, nt4 */
1756  "%s: pCorrMemory should have been set to zero instead of %p\n", prefix, stubMsg->pCorrMemory );
1757  ok( stubMsg->pMemoryList == 0 || broken(stubMsg->pMemoryList == unset_ptr), /* win9x, nt4 */
1758  "%s: pMemoryList should have been set to zero instead of %p\n", prefix, stubMsg->pMemoryList );
1759  TEST_POINTER_UNSET(pCSInfo);
1760  TEST_POINTER_UNSET(ConformanceMark);
1761  TEST_POINTER_UNSET(VarianceMark);
1762  ok(stubMsg->Unused == (ULONG_PTR)unset_ptr, "%s: Unused should have be unset instead of 0x%lx\n",
1763  prefix, stubMsg->Unused);
1764  TEST_POINTER_UNSET(pContext);
1765  TEST_POINTER_UNSET(ContextHandleHash);
1766  TEST_POINTER_UNSET(pUserMarshalList);
1767  TEST_ULONG_PTR_UNSET(Reserved51_3);
1768  TEST_ULONG_PTR_UNSET(Reserved51_4);
1769  TEST_ULONG_PTR_UNSET(Reserved51_5);
1770 
1771 #undef TEST_ULONG_PTR_UNSET
1772 #undef TEST_ULONG_UNSET
1773 #undef TEST_POINTER_UNSET
1774 #undef TEST_ZERO
1775 }
1776 
1777 static void test_client_init(void)
1778 {
1779  MIDL_STUB_MESSAGE stubMsg;
1780  RPC_MESSAGE rpcMsg;
1781  void *unset_ptr;
1782 
1783  memset(&rpcMsg, 0xcc, sizeof(rpcMsg));
1784  memset(&stubMsg, 0xcc, sizeof(stubMsg));
1785  memset(&unset_ptr, 0xcc, sizeof(unset_ptr));
1786 
1787  NdrClientInitializeNew(&rpcMsg, &stubMsg, &Object_StubDesc, 1);
1788 
1789  test_common_stub_data( "NdrClientInitializeNew", &stubMsg );
1790 
1791  ok(stubMsg.RpcMsg == &rpcMsg, "stubMsg.RpcMsg should have been %p instead of %p\n", &rpcMsg, stubMsg.RpcMsg);
1792  ok(rpcMsg.Handle == NULL, "rpcMsg.Handle should have been NULL instead of %p\n", rpcMsg.Handle);
1793  ok(rpcMsg.Buffer == unset_ptr, "rpcMsg.Buffer should have been unset instead of %p\n",
1794  rpcMsg.Buffer);
1795  ok(rpcMsg.BufferLength == 0xcccccccc, "rpcMsg.BufferLength should have been unset instead of %d\n", rpcMsg.BufferLength);
1796  ok(rpcMsg.ProcNum == 0x8001, "rpcMsg.ProcNum should have been 0x8001 instead of 0x%x\n", rpcMsg.ProcNum);
1797  ok(rpcMsg.TransferSyntax == unset_ptr, "rpcMsg.TransferSyntax should have been unset instead of %p\n", rpcMsg.TransferSyntax);
1799  "rpcMsg.RpcInterfaceInformation should have been %p instead of %p\n",
1801  /* Note: ReservedForRuntime not tested */
1802  ok(rpcMsg.ManagerEpv == unset_ptr, "rpcMsg.ManagerEpv should have been unset instead of %p\n", rpcMsg.ManagerEpv);
1803  ok(rpcMsg.ImportContext == unset_ptr, "rpcMsg.ImportContext should have been unset instead of %p\n", rpcMsg.ImportContext);
1804  ok(rpcMsg.RpcFlags == 0, "rpcMsg.RpcFlags should have been 0 instead of 0x%x\n", rpcMsg.RpcFlags);
1805 
1806  ok(stubMsg.Buffer == unset_ptr, "stubMsg.Buffer should have been unset instead of %p\n",
1807  stubMsg.Buffer);
1808  ok(stubMsg.BufferStart == NULL, "stubMsg.BufferStart should have been NULL instead of %p\n",
1809  stubMsg.BufferStart);
1810  ok(stubMsg.BufferEnd == NULL, "stubMsg.BufferEnd should have been NULL instead of %p\n",
1811  stubMsg.BufferEnd);
1812  ok(stubMsg.BufferLength == 0, "stubMsg.BufferLength should have been 0 instead of %u\n",
1813  stubMsg.BufferLength);
1814  ok(stubMsg.IsClient == 1, "stubMsg.IsClient should have been 1 instead of %u\n", stubMsg.IsClient);
1815  ok(stubMsg.ReuseBuffer == 0, "stubMsg.ReuseBuffer should have been 0 instead of %d\n",
1816  stubMsg.ReuseBuffer);
1817  ok(stubMsg.CorrDespIncrement == 0, "stubMsg.CorrDespIncrement should have been 0 instead of %d\n",
1818  stubMsg.CorrDespIncrement);
1819  ok(stubMsg.FullPtrXlatTables == unset_ptr, "stubMsg.FullPtrXlatTables should have been unset instead of %p\n",
1820  stubMsg.FullPtrXlatTables);
1821 }
1822 
1823 static void test_server_init(void)
1824 {
1825  MIDL_STUB_MESSAGE stubMsg;
1826  RPC_MESSAGE rpcMsg;
1827  unsigned char *ret;
1828  unsigned char buffer[256];
1829 
1830  memset(&rpcMsg, 0, sizeof(rpcMsg));
1831  rpcMsg.Buffer = buffer;
1832  rpcMsg.BufferLength = sizeof(buffer);
1833  rpcMsg.RpcFlags = RPC_BUFFER_COMPLETE;
1834 
1835  memset(&stubMsg, 0xcc, sizeof(stubMsg));
1836 
1837  ret = NdrServerInitializeNew(&rpcMsg, &stubMsg, &Object_StubDesc);
1838  ok(ret == NULL, "NdrServerInitializeNew should have returned NULL instead of %p\n", ret);
1839 
1840  test_common_stub_data( "NdrServerInitializeNew", &stubMsg );
1841 
1842  ok(stubMsg.RpcMsg == &rpcMsg, "stubMsg.RpcMsg should have been %p instead of %p\n", &rpcMsg, stubMsg.RpcMsg);
1843  ok(stubMsg.Buffer == buffer, "stubMsg.Buffer should have been %p instead of %p\n", buffer, stubMsg.Buffer);
1844  ok(stubMsg.BufferStart == buffer, "stubMsg.BufferStart should have been %p instead of %p\n", buffer, stubMsg.BufferStart);
1845  ok(stubMsg.BufferEnd == buffer + sizeof(buffer), "stubMsg.BufferEnd should have been %p instead of %p\n", buffer + sizeof(buffer), stubMsg.BufferEnd);
1846 todo_wine
1847  ok(stubMsg.BufferLength == 0, "stubMsg.BufferLength should have been 0 instead of %u\n", stubMsg.BufferLength);
1848  ok(stubMsg.IsClient == 0, "stubMsg.IsClient should have been 0 instead of %u\n", stubMsg.IsClient);
1849  ok(stubMsg.ReuseBuffer == 0 ||
1850  broken(stubMsg.ReuseBuffer == 1), /* win2k */
1851  "stubMsg.ReuseBuffer should have been set to zero instead of %d\n", stubMsg.ReuseBuffer);
1852  ok(stubMsg.CorrDespIncrement == 0 ||
1853  broken(stubMsg.CorrDespIncrement == 0xcc), /* <= Win 2003 */
1854  "CorrDespIncrement should have been set to zero instead of 0x%x\n", stubMsg.CorrDespIncrement);
1855  ok(stubMsg.FullPtrXlatTables == 0, "stubMsg.BufferLength should have been 0 instead of %p\n", stubMsg.FullPtrXlatTables);
1856 }
1857 
1858 static void test_ndr_allocate(void)
1859 {
1860  RPC_MESSAGE RpcMessage;
1861  MIDL_STUB_MESSAGE StubMsg;
1862  MIDL_STUB_DESC StubDesc;
1863  void *p1, *p2;
1864  struct tag_mem_list_v2_t
1865  {
1866  DWORD magic;
1867  DWORD size;
1868  DWORD unknown;
1869  struct tag_mem_list_v2_t *next;
1870  } *mem_list_v2;
1871  const DWORD magic_MEML = 'M' << 24 | 'E' << 16 | 'M' << 8 | 'L';
1872 
1873  StubDesc = Object_StubDesc;
1874  NdrClientInitializeNew(&RpcMessage, &StubMsg, &StubDesc, 0);
1875 
1877  p1 = NdrAllocate(&StubMsg, 10);
1878  p2 = NdrAllocate(&StubMsg, 24);
1879  ok(my_alloc_called == 2, "alloc called %d\n", my_alloc_called);
1880  ok(StubMsg.pMemoryList != NULL, "StubMsg.pMemoryList NULL\n");
1881  if(StubMsg.pMemoryList)
1882  {
1883  mem_list_v2 = StubMsg.pMemoryList;
1884  if (mem_list_v2->size == 24)
1885  {
1886  trace("v2 mem list format\n");
1887  ok((char *)mem_list_v2 == (char *)p2 + 24, "expected mem_list_v2 pointer %p, but got %p\n", (char *)p2 + 24, mem_list_v2);
1888  ok(mem_list_v2->magic == magic_MEML, "magic %08x\n", mem_list_v2->magic);
1889  ok(mem_list_v2->size == 24, "wrong size for p2 %d\n", mem_list_v2->size);
1890  ok(mem_list_v2->unknown == 0, "wrong unknown for p2 0x%x\n", mem_list_v2->unknown);
1891  ok(mem_list_v2->next != NULL, "next NULL\n");
1892  mem_list_v2 = mem_list_v2->next;
1893  if(mem_list_v2)
1894  {
1895  ok((char *)mem_list_v2 == (char *)p1 + 16, "expected mem_list_v2 pointer %p, but got %p\n", (char *)p1 + 16, mem_list_v2);
1896  ok(mem_list_v2->magic == magic_MEML, "magic %08x\n", mem_list_v2->magic);
1897  ok(mem_list_v2->size == 16, "wrong size for p1 %d\n", mem_list_v2->size);
1898  ok(mem_list_v2->unknown == 0, "wrong unknown for p1 0x%x\n", mem_list_v2->unknown);
1899  ok(mem_list_v2->next == NULL, "next %p\n", mem_list_v2->next);
1900  }
1901  }
1902  else win_skip("v1 mem list format\n");
1903  }
1904  /* NdrFree isn't exported so we can't test free'ing */
1905  my_free(p1);
1906  my_free(p2);
1907 }
1908 
1909 static void test_conformant_array(void)
1910 {
1911  RPC_MESSAGE RpcMessage;
1912  MIDL_STUB_MESSAGE StubMsg;
1913  MIDL_STUB_DESC StubDesc;
1914  void *ptr;
1915  unsigned char *mem, *mem_orig;
1916  unsigned char memsrc[20];
1917  unsigned int i;
1918 
1919  static const unsigned char fmtstr_conf_array[] =
1920  {
1921  0x1b, /* FC_CARRAY */
1922  0x0, /* align */
1923  NdrFcShort( 0x1 ), /* elem size */
1924  0x40, /* Corr desc: const */
1925  0x0,
1926  NdrFcShort(0x10), /* const = 0x10 */
1927  0x1, /* FC_BYTE */
1928  0x5b /* FC_END */
1929  };
1930 
1931  for (i = 0; i < sizeof(memsrc); i++)
1932  memsrc[i] = i * i;
1933 
1934  StubDesc = Object_StubDesc;
1935  StubDesc.pFormatTypes = fmtstr_conf_array;
1936 
1938  &RpcMessage,
1939  &StubMsg,
1940  &StubDesc,
1941  0);
1942 
1943  StubMsg.BufferLength = 0;
1944  NdrConformantArrayBufferSize( &StubMsg,
1945  memsrc,
1946  fmtstr_conf_array );
1947  ok(StubMsg.BufferLength >= 20, "length %d\n", StubMsg.BufferLength);
1948 
1949  /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
1950  StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
1951  StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
1952 
1953  ptr = NdrConformantArrayMarshall( &StubMsg, memsrc, fmtstr_conf_array );
1954  ok(ptr == NULL, "ret %p\n", ptr);
1955  ok(StubMsg.Buffer - StubMsg.BufferStart == 20, "Buffer %p Start %p len %d\n", StubMsg.Buffer, StubMsg.BufferStart, 20);
1956  ok(!memcmp(StubMsg.BufferStart + 4, memsrc, 16), "incorrectly marshaled\n");
1957 
1958  StubMsg.Buffer = StubMsg.BufferStart;
1959  StubMsg.MemorySize = 0;
1960  mem = NULL;
1961 
1962  /* Client */
1963  my_alloc_called = 0;
1964  /* passing mem == NULL with must_alloc == 0 crashes under Windows */
1965  NdrConformantArrayUnmarshall( &StubMsg, &mem, fmtstr_conf_array, 1);
1966  ok(mem != NULL, "mem not alloced\n");
1967  ok(mem != StubMsg.BufferStart + 4, "mem pointing at buffer\n");
1968  ok(my_alloc_called == 1, "alloc called %d\n", my_alloc_called);
1969 
1970  my_alloc_called = 0;
1971  StubMsg.Buffer = StubMsg.BufferStart;
1972  mem_orig = mem;
1973  NdrConformantArrayUnmarshall( &StubMsg, &mem, fmtstr_conf_array, 0);
1974  ok(mem == mem_orig, "mem alloced\n");
1975  ok(mem != StubMsg.BufferStart + 4, "mem pointing at buffer\n");
1976  ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
1977 
1978  my_alloc_called = 0;
1979  StubMsg.Buffer = StubMsg.BufferStart;
1980  NdrConformantArrayUnmarshall( &StubMsg, &mem, fmtstr_conf_array, 1);
1981  ok(mem != mem_orig, "mem not alloced\n");
1982  ok(mem != StubMsg.BufferStart + 4, "mem pointing at buffer\n");
1983  ok(my_alloc_called == 1, "alloc called %d\n", my_alloc_called);
1984 
1985  my_free_called = 0;
1986  StubMsg.Buffer = StubMsg.BufferStart;
1987  NdrConformantArrayFree( &StubMsg, mem, fmtstr_conf_array );
1988  ok(my_free_called == 0, "free called %d\n", my_free_called);
1989  StubMsg.pfnFree(mem);
1990 
1991  /* Server */
1992  my_alloc_called = 0;
1993  StubMsg.IsClient = 0;
1994  mem = NULL;
1995  StubMsg.Buffer = StubMsg.BufferStart;
1996  NdrConformantArrayUnmarshall( &StubMsg, &mem, fmtstr_conf_array, 0);
1997  ok(mem == StubMsg.BufferStart + 4 || broken(!mem), /* win9x, nt4 */
1998  "mem not pointing at buffer %p/%p\n", mem, StubMsg.BufferStart + 4);
1999  ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2000  my_alloc_called = 0;
2001  mem = NULL;
2002  StubMsg.Buffer = StubMsg.BufferStart;
2003  NdrConformantArrayUnmarshall( &StubMsg, &mem, fmtstr_conf_array, 1);
2004  ok(mem != StubMsg.BufferStart + 4, "mem pointing at buffer\n");
2005  ok(my_alloc_called == 1, "alloc called %d\n", my_alloc_called);
2006  StubMsg.pfnFree(mem);
2007 
2008  my_alloc_called = 0;
2009  mem = mem_orig;
2010  StubMsg.Buffer = StubMsg.BufferStart;
2011  NdrConformantArrayUnmarshall( &StubMsg, &mem, fmtstr_conf_array, 0);
2012  ok(mem == mem_orig, "mem alloced\n");
2013  ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2014 
2015  my_alloc_called = 0;
2016  mem = mem_orig;
2017  StubMsg.Buffer = StubMsg.BufferStart;
2018  NdrConformantArrayUnmarshall( &StubMsg, &mem, fmtstr_conf_array, 1);
2019  ok(mem != StubMsg.BufferStart + 4, "mem pointing at buffer\n");
2020  ok(my_alloc_called == 1, "alloc called %d\n", my_alloc_called);
2021  StubMsg.pfnFree(mem);
2022  StubMsg.pfnFree(mem_orig);
2023 
2024  HeapFree(GetProcessHeap(), 0, StubMsg.RpcMsg->Buffer);
2025 }
2026 
2027 static void test_conformant_string(void)
2028 {
2029  RPC_MESSAGE RpcMessage;
2030  MIDL_STUB_MESSAGE StubMsg;
2031  MIDL_STUB_DESC StubDesc;
2032  DWORD size;
2033  void *ptr;
2034  unsigned char *mem, *mem_orig;
2035  char memsrc[] = "This is a test string";
2036 
2037  static const unsigned char fmtstr_conf_str[] =
2038  {
2039  0x11, 0x8, /* FC_RP [simple_pointer] */
2040  0x22, /* FC_C_CSTRING */
2041  0x5c, /* FC_PAD */
2042  };
2043 
2044  StubDesc = Object_StubDesc;
2045  StubDesc.pFormatTypes = fmtstr_conf_str;
2046 
2047  memset( &StubMsg, 0, sizeof(StubMsg) ); /* needed on win9x and nt4 */
2049  &RpcMessage,
2050  &StubMsg,
2051  &StubDesc,
2052  0);
2053 
2054  StubMsg.BufferLength = 0;
2055  NdrPointerBufferSize( &StubMsg,
2056  (unsigned char *)memsrc,
2057  fmtstr_conf_str );
2058  ok(StubMsg.BufferLength >= sizeof(memsrc) + 12, "length %d\n", StubMsg.BufferLength);
2059 
2060  /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
2061  StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
2062  StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
2063 
2064  ptr = NdrPointerMarshall( &StubMsg, (unsigned char *)memsrc, fmtstr_conf_str );
2065  ok(ptr == NULL, "ret %p\n", ptr);
2066  size = StubMsg.Buffer - StubMsg.BufferStart;
2067  ok(size == sizeof(memsrc) + 12, "Buffer %p Start %p len %d\n",
2068  StubMsg.Buffer, StubMsg.BufferStart, size);
2069  ok(!memcmp(StubMsg.BufferStart + 12, memsrc, sizeof(memsrc)), "incorrectly marshaled\n");
2070 
2071  StubMsg.Buffer = StubMsg.BufferStart;
2072  StubMsg.MemorySize = 0;
2073  mem = NULL;
2074 
2075  /* Client */
2076  my_alloc_called = 0;
2077  StubMsg.Buffer = StubMsg.BufferStart;
2078  mem = mem_orig = HeapAlloc(GetProcessHeap(), 0, sizeof(memsrc));
2079  /* Windows apparently checks string length on the output buffer to determine its size... */
2080  memset( mem, 'x', sizeof(memsrc) - 1 );
2081  mem[sizeof(memsrc) - 1] = 0;
2082  NdrPointerUnmarshall( &StubMsg, &mem, fmtstr_conf_str, 0);
2083  ok(mem == mem_orig, "mem not alloced\n");
2084  ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2085 
2086  my_alloc_called = 0;
2087  StubMsg.Buffer = StubMsg.BufferStart;
2088  NdrPointerUnmarshall( &StubMsg, &mem, fmtstr_conf_str, 1);
2089  ok(mem == mem_orig, "mem not alloced\n");
2090  ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2091 
2092  /* Prevent a memory leak when running with Wine.
2093  Remove once the todo_wine block above is fixed. */
2094  if (mem != mem_orig)
2095  HeapFree(GetProcessHeap(), 0, mem_orig);
2096 
2097  my_free_called = 0;
2098  StubMsg.Buffer = StubMsg.BufferStart;
2099  NdrPointerFree( &StubMsg, mem, fmtstr_conf_str );
2100  ok(my_free_called == 1, "free called %d\n", my_free_called);
2101 
2102  mem = my_alloc(10);
2103  my_free_called = 0;
2104  StubMsg.Buffer = StubMsg.BufferStart;
2105  NdrPointerFree( &StubMsg, mem, fmtstr_conf_str );
2106  ok(my_free_called == 1, "free called %d\n", my_free_called);
2107 
2108  /* Server */
2109  my_alloc_called = 0;
2110  StubMsg.IsClient = 0;
2111  mem = NULL;
2112  StubMsg.Buffer = StubMsg.BufferStart;
2113  NdrPointerUnmarshall( &StubMsg, &mem, fmtstr_conf_str, 0);
2114  ok(mem == StubMsg.BufferStart + 12 || broken(!mem), /* win9x, nt4 */
2115  "mem not pointing at buffer %p/%p\n", mem, StubMsg.BufferStart + 12 );
2116  ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2117 
2118  my_alloc_called = 0;
2119  mem = NULL;
2120  StubMsg.Buffer = StubMsg.BufferStart;
2121  NdrPointerUnmarshall( &StubMsg, &mem, fmtstr_conf_str, 1);
2122  ok(mem == StubMsg.BufferStart + 12 || broken(!mem), /* win9x, nt4 */
2123  "mem not pointing at buffer %p/%p\n", mem, StubMsg.BufferStart + 12 );
2124  ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2125 
2126  my_alloc_called = 0;
2127  mem = mem_orig = HeapAlloc(GetProcessHeap(), 0, sizeof(memsrc));
2128  StubMsg.Buffer = StubMsg.BufferStart;
2129  NdrPointerUnmarshall( &StubMsg, &mem, fmtstr_conf_str, 0);
2130  ok(mem == StubMsg.BufferStart + 12 || broken(!mem), /* win9x, nt4 */
2131  "mem not pointing at buffer %p/%p\n", mem, StubMsg.BufferStart + 12 );
2132  ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2133 
2134  my_alloc_called = 0;
2135  mem = mem_orig;
2136  StubMsg.Buffer = StubMsg.BufferStart;
2137  NdrPointerUnmarshall( &StubMsg, &mem, fmtstr_conf_str, 1);
2138  ok(mem == StubMsg.BufferStart + 12 || broken(!mem), /* win9x, nt4 */
2139  "mem not pointing at buffer %p/%p\n", mem, StubMsg.BufferStart + 12 );
2140  ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2141 
2142  mem = my_alloc(10);
2143  my_free_called = 0;
2144  StubMsg.Buffer = StubMsg.BufferStart;
2145  NdrPointerFree( &StubMsg, mem, fmtstr_conf_str );
2146  ok(my_free_called == 1, "free called %d\n", my_free_called);
2147 
2148  HeapFree(GetProcessHeap(), 0, mem_orig);
2149  HeapFree(GetProcessHeap(), 0, StubMsg.RpcMsg->Buffer);
2150 }
2151 
2152 static void test_nonconformant_string(void)
2153 {
2154  RPC_MESSAGE RpcMessage;
2155  MIDL_STUB_MESSAGE StubMsg;
2156  MIDL_STUB_DESC StubDesc;
2157  DWORD size;
2158  void *ptr;
2159  unsigned char *mem, *mem_orig;
2160  unsigned char memsrc[10] = "This is";
2161  unsigned char memsrc2[10] = "This is a";
2162 
2163  static const unsigned char fmtstr_nonconf_str[] =
2164  {
2165  0x26, /* FC_CSTRING */
2166  0x5c, /* FC_PAD */
2167  NdrFcShort( 0xa ), /* 10 */
2168  };
2169 
2170  StubDesc = Object_StubDesc;
2171  StubDesc.pFormatTypes = fmtstr_nonconf_str;
2172 
2173  /* length < size */
2175  &RpcMessage,
2176  &StubMsg,
2177  &StubDesc,
2178  0);
2179 
2180  StubMsg.BufferLength = 0;
2181 
2182  NdrNonConformantStringBufferSize( &StubMsg, memsrc, fmtstr_nonconf_str );
2183  ok(StubMsg.BufferLength >= strlen((char *)memsrc) + 1 + 8, "length %d\n", StubMsg.BufferLength);
2184 
2185  /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
2186  StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
2187  StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
2188 
2189  ptr = NdrNonConformantStringMarshall( &StubMsg, memsrc, fmtstr_nonconf_str );
2190  ok(ptr == NULL, "ret %p\n", ptr);
2191  size = StubMsg.Buffer - StubMsg.BufferStart;
2192  ok(size == strlen((char *)memsrc) + 1 + 8, "Buffer %p Start %p len %d\n",
2193  StubMsg.Buffer, StubMsg.BufferStart, size);
2194  ok(!memcmp(StubMsg.BufferStart + 8, memsrc, strlen((char *)memsrc) + 1), "incorrectly marshaled\n");
2195 
2196  StubMsg.Buffer = StubMsg.BufferStart;
2197  StubMsg.MemorySize = 0;
2198  mem = NULL;
2199 
2200  /* Client */
2201  my_alloc_called = 0;
2202  StubMsg.Buffer = StubMsg.BufferStart;
2203  mem = mem_orig = HeapAlloc(GetProcessHeap(), 0, sizeof(memsrc));
2204  NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 0);
2205  ok(mem == mem_orig, "mem alloced\n");
2206  ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2207 
2208  my_alloc_called = 0;
2209  StubMsg.Buffer = StubMsg.BufferStart;
2210  NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 1);
2211  todo_wine
2212  ok(mem == mem_orig, "mem alloced\n");
2213  todo_wine
2214  ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2215 
2216  /* Server */
2217  my_alloc_called = 0;
2218  StubMsg.IsClient = 0;
2219  mem = NULL;
2220  StubMsg.Buffer = StubMsg.BufferStart;
2221  NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 0);
2222  ok(mem != mem_orig, "mem not alloced\n");
2223  ok(mem != StubMsg.BufferStart + 8, "mem pointing at buffer\n");
2224  ok(my_alloc_called == 1, "alloc called %d\n", my_alloc_called);
2225  NdrOleFree(mem);
2226 
2227  my_alloc_called = 0;
2228  mem = mem_orig;
2229  StubMsg.Buffer = StubMsg.BufferStart;
2230  NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 0);
2231  ok(mem == mem_orig, "mem alloced\n");
2232  ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2233 
2234  my_alloc_called = 0;
2235  mem = mem_orig;
2236  StubMsg.Buffer = StubMsg.BufferStart;
2237  NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 1);
2238  todo_wine
2239  ok(mem == mem_orig, "mem alloced\n");
2240  todo_wine
2241  ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2242 
2243  HeapFree(GetProcessHeap(), 0, mem_orig);
2244  HeapFree(GetProcessHeap(), 0, StubMsg.RpcMsg->Buffer);
2245 
2246  /* length = size */
2248  &RpcMessage,
2249  &StubMsg,
2250  &StubDesc,
2251  0);
2252 
2253  StubMsg.BufferLength = 0;
2254 
2255  NdrNonConformantStringBufferSize( &StubMsg, memsrc2, fmtstr_nonconf_str );
2256  ok(StubMsg.BufferLength >= strlen((char *)memsrc2) + 1 + 8, "length %d\n", StubMsg.BufferLength);
2257 
2258  /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
2259  StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
2260  StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
2261 
2262  ptr = NdrNonConformantStringMarshall( &StubMsg, memsrc2, fmtstr_nonconf_str );
2263  ok(ptr == NULL, "ret %p\n", ptr);
2264  size = StubMsg.Buffer - StubMsg.BufferStart;
2265  ok(size == strlen((char *)memsrc2) + 1 + 8, "Buffer %p Start %p len %d\n",
2266  StubMsg.Buffer, StubMsg.BufferStart, size);
2267  ok(!memcmp(StubMsg.BufferStart + 8, memsrc2, strlen((char *)memsrc2) + 1), "incorrectly marshaled\n");
2268 
2269  StubMsg.Buffer = StubMsg.BufferStart;
2270  StubMsg.MemorySize = 0;
2271  mem = NULL;
2272 
2273  /* Client */
2274  my_alloc_called = 0;
2275  StubMsg.Buffer = StubMsg.BufferStart;
2276  mem = mem_orig = HeapAlloc(GetProcessHeap(), 0, sizeof(memsrc));
2277  NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 0);
2278  ok(mem == mem_orig, "mem alloced\n");
2279  ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2280 
2281  my_alloc_called = 0;
2282  StubMsg.Buffer = StubMsg.BufferStart;
2283  NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 1);
2284  todo_wine
2285  ok(mem == mem_orig, "mem alloced\n");
2286  todo_wine
2287  ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2288 
2289  /* Server */
2290  my_alloc_called = 0;
2291  StubMsg.IsClient = 0;
2292  mem = NULL;
2293  StubMsg.Buffer = StubMsg.BufferStart;
2294  NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 0);
2295  ok(mem != mem_orig, "mem not alloced\n");
2296  ok(mem != StubMsg.BufferStart + 8, "mem pointing at buffer\n");
2297  ok(my_alloc_called == 1, "alloc called %d\n", my_alloc_called);
2298  NdrOleFree(mem);
2299 
2300  my_alloc_called = 0;
2301  mem = mem_orig;
2302  StubMsg.Buffer = StubMsg.BufferStart;
2303  NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 0);
2304  ok(mem == mem_orig, "mem alloced\n");
2305  ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2306 
2307  my_alloc_called = 0;
2308  mem = mem_orig;
2309  StubMsg.Buffer = StubMsg.BufferStart;
2310  NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 1);
2311  todo_wine
2312  ok(mem == mem_orig, "mem alloced\n");
2313  todo_wine
2314  ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2315 
2316  HeapFree(GetProcessHeap(), 0, mem_orig);
2317  HeapFree(GetProcessHeap(), 0, StubMsg.RpcMsg->Buffer);
2318 }
2319 
2320 static void test_conf_complex_struct(void)
2321 {
2322  RPC_MESSAGE RpcMessage;
2323  MIDL_STUB_MESSAGE StubMsg;
2324  MIDL_STUB_DESC StubDesc;
2325  void *ptr;
2326  unsigned int i;
2327  struct conf_complex
2328  {
2329  unsigned int size;
2330  unsigned int *array[1];
2331  };
2332  struct conf_complex *memsrc;
2333  struct conf_complex *mem;
2334 
2335  static const unsigned char fmtstr_complex_struct[] =
2336  {
2337 /* 0 */
2338  0x1b, /* FC_CARRAY */
2339  0x3, /* 3 */
2340 /* 2 */ NdrFcShort( 0x4 ), /* 4 */
2341 /* 4 */ 0x8, /* Corr desc: FC_LONG */
2342  0x0, /* */
2343 /* 6 */ NdrFcShort( 0xfffc ), /* -4 */
2344 /* 8 */
2345  0x4b, /* FC_PP */
2346  0x5c, /* FC_PAD */
2347 /* 10 */
2348  0x48, /* FC_VARIABLE_REPEAT */
2349  0x49, /* FC_FIXED_OFFSET */
2350 /* 12 */ NdrFcShort( 0x4 ), /* 4 */
2351 /* 14 */ NdrFcShort( 0x0 ), /* 0 */
2352 /* 16 */ NdrFcShort( 0x1 ), /* 1 */
2353 /* 18 */ NdrFcShort( 0x0 ), /* 0 */
2354 /* 20 */ NdrFcShort( 0x0 ), /* 0 */
2355 /* 22 */ 0x12, 0x8, /* FC_UP [simple_pointer] */
2356 /* 24 */ 0x8, /* FC_LONG */
2357  0x5c, /* FC_PAD */
2358 /* 26 */
2359  0x5b, /* FC_END */
2360 
2361  0x8, /* FC_LONG */
2362 /* 28 */ 0x5c, /* FC_PAD */
2363  0x5b, /* FC_END */
2364 /* 30 */
2365  0x1a, /* FC_BOGUS_STRUCT */
2366  0x3, /* 3 */
2367 /* 32 */ NdrFcShort( 0x4 ), /* 4 */
2368 /* 34 */ NdrFcShort( 0xffffffde ), /* Offset= -34 (0) */
2369 /* 36 */ NdrFcShort( 0x0 ), /* Offset= 0 (36) */
2370 /* 38 */ 0x8, /* FC_LONG */
2371  0x5b, /* FC_END */
2372  };
2373 
2375  FIELD_OFFSET(struct conf_complex, array[20]));
2376  memsrc->size = 20;
2377 
2378  StubDesc = Object_StubDesc;
2379  StubDesc.pFormatTypes = fmtstr_complex_struct;
2380 
2382  &RpcMessage,
2383  &StubMsg,
2384  &StubDesc,
2385  0);
2386 
2387  StubMsg.BufferLength = 0;
2388  NdrComplexStructBufferSize( &StubMsg,
2389  (unsigned char *)memsrc,
2390  &fmtstr_complex_struct[30] );
2391  ok(StubMsg.BufferLength >= 28, "length %d\n", StubMsg.BufferLength);
2392 
2393  /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
2394  StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
2395  StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
2396 
2397  ptr = NdrComplexStructMarshall( &StubMsg, (unsigned char *)memsrc,
2398  &fmtstr_complex_struct[30] );
2399  ok(ptr == NULL, "ret %p\n", ptr);
2400  ok(*(unsigned int *)StubMsg.BufferStart == 20, "Conformance should have been 20 instead of %d\n", *(unsigned int *)StubMsg.BufferStart);
2401  ok(*(unsigned int *)(StubMsg.BufferStart + 4) == 20, "conf_complex.size should have been 20 instead of %d\n", *(unsigned int *)(StubMsg.BufferStart + 4));
2402  for (i = 0; i < 20; i++)
2403  ok(*(unsigned int *)(StubMsg.BufferStart + 8 + i * 4) == 0, "pointer id for conf_complex.array[%d] should have been 0 instead of 0x%x\n", i, *(unsigned int *)(StubMsg.BufferStart + 8 + i * 4));
2404 
2405  /* Server */
2406  my_alloc_called = 0;
2407  StubMsg.IsClient = 0;
2408  mem = NULL;
2409  StubMsg.Buffer = StubMsg.BufferStart;
2410  ptr = NdrComplexStructUnmarshall( &StubMsg, (unsigned char **)&mem, &fmtstr_complex_struct[30], 0);
2411  ok(ptr == NULL, "ret %p\n", ptr);
2412  ok(mem->size == 20, "mem->size wasn't unmarshalled correctly (%d)\n", mem->size);
2413  ok(mem->array[0] == NULL, "mem->array[0] wasn't unmarshalled correctly (%p)\n", mem->array[0]);
2414  StubMsg.pfnFree(mem);
2415 
2416  HeapFree(GetProcessHeap(), 0, StubMsg.RpcMsg->Buffer);
2417  HeapFree(GetProcessHeap(), 0, memsrc);
2418 }
2419 
2420 
2421 static void test_conf_complex_array(void)
2422 {
2423  RPC_MESSAGE RpcMessage;
2424  MIDL_STUB_MESSAGE StubMsg;
2425  MIDL_STUB_DESC StubDesc;
2426  void *ptr;
2427  unsigned int i, j;
2428  struct conf_complex
2429  {
2430  unsigned int dim1, dim2;
2431  DWORD **array;
2432  };
2433  struct conf_complex memsrc;
2434  struct conf_complex *mem;
2435  DWORD *buf, expected_length;
2436 
2437  static const unsigned char fmtstr_complex_array[] =
2438  {
2439 
2440 /* 0 */ 0x21, /* FC_BOGUS_ARRAY */
2441  0x3, /* 3 */
2442 /* 2 */ NdrFcShort( 0x0 ), /* 0 */
2443 /* 4 */ 0x19, 0x0, /* Corr desc: field pointer, FC_ULONG */
2444 /* 6 */ NdrFcShort( 0x4 ), /* 4 */
2445 /* 8 */ NdrFcLong( 0xffffffff ), /* -1 */
2446 /* 12 */ 0x8, /* FC_LONG */
2447  0x5b, /* FC_END */
2448 /* 14 */
2449  0x21, /* FC_BOGUS_ARRAY */
2450  0x3, /* 3 */
2451 /* 16 */ NdrFcShort( 0x0 ), /* 0 */
2452 /* 18 */ 0x19, /* Corr desc: field pointer, FC_ULONG */
2453  0x0, /* */
2454 /* 20 */ NdrFcShort( 0x0 ), /* 0 */
2455 /* 22 */ NdrFcLong( 0xffffffff ), /* -1 */
2456 /* 26 */ 0x12, 0x0, /* FC_UP */
2457 /* 28 */ NdrFcShort( 0xffe4 ), /* Offset= -28 (0) */
2458 /* 30 */ 0x5c, /* FC_PAD */
2459  0x5b, /* FC_END */
2460 
2461 #ifdef _WIN64
2462 /* 32 */ 0x1a, /* FC_BOGUS_STRUCT */
2463  0x3, /* 3 */
2464 /* 34 */ NdrFcShort( 0x10 ), /* 16 */
2465 /* 36 */ NdrFcShort( 0x0 ), /* 0 */
2466 /* 38 */ NdrFcShort( 0x6 ), /* Offset= 6 (44) */
2467 /* 40 */ 0x8, /* FC_LONG */
2468  0x8, /* FC_LONG */
2469 /* 42 */ 0x36, /* FC_POINTER */
2470  0x5b, /* FC_END */
2471 /* 44 */
2472  0x12, 0x0, /* FC_UP */
2473 /* 46 */ NdrFcShort( 0xffe0 ), /* Offset= -32 (14) */
2474 #else
2475 /* 32 */
2476  0x16, /* FC_PSTRUCT */
2477  0x3, /* 3 */
2478 /* 34 */ NdrFcShort( 0xc ), /* 12 */
2479 /* 36 */ 0x4b, /* FC_PP */
2480  0x5c, /* FC_PAD */
2481 /* 38 */ 0x46, /* FC_NO_REPEAT */
2482  0x5c, /* FC_PAD */
2483 /* 40 */ NdrFcShort( 0x8 ), /* 8 */
2484 /* 42 */ NdrFcShort( 0x8 ), /* 8 */
2485 /* 44 */ 0x12, 0x0, /* FC_UP */
2486 /* 46 */ NdrFcShort( 0xffe0 ), /* Offset= -32 (14) */
2487 /* 48 */ 0x5b, /* FC_END */
2488  0x8, /* FC_LONG */
2489 /* 50 */ 0x8, /* FC_LONG */
2490  0x8, /* FC_LONG */
2491 /* 52 */ 0x5c, /* FC_PAD */
2492  0x5b, /* FC_END */
2493 #endif
2494  };
2495 
2496  memsrc.dim1 = 5;
2497  memsrc.dim2 = 3;
2498 
2499  memsrc.array = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, memsrc.dim1 * sizeof(DWORD*));
2500 
2501  for(i = 0; i < memsrc.dim1; i++)
2502  {
2503  memsrc.array[i] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, memsrc.dim2 * sizeof(DWORD));
2504  for(j = 0; j < memsrc.dim2; j++)
2505  memsrc.array[i][j] = i * memsrc.dim2 + j;
2506  }
2507 
2508  StubDesc = Object_StubDesc;
2509  StubDesc.pFormatTypes = fmtstr_complex_array;
2510 
2512  &RpcMessage,
2513  &StubMsg,
2514  &StubDesc,
2515  0);
2516 
2517  StubMsg.BufferLength = 0;
2518 
2519 #ifdef _WIN64
2520  NdrComplexStructBufferSize( &StubMsg,
2521  (unsigned char *)&memsrc,
2522  &fmtstr_complex_array[32] );
2523 #else
2524  NdrSimpleStructBufferSize( &StubMsg,
2525  (unsigned char *)&memsrc,
2526  &fmtstr_complex_array[32] );
2527 #endif
2528 
2529  expected_length = (4 + memsrc.dim1 * (2 + memsrc.dim2)) * 4;
2530  ok(StubMsg.BufferLength >= expected_length, "length %d\n", StubMsg.BufferLength);
2531 
2532  /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
2533  StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
2534  StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
2535 
2536 #ifdef _WIN64
2537  ptr = NdrComplexStructMarshall( &StubMsg, (unsigned char *)&memsrc,
2538  &fmtstr_complex_array[32] );
2539 #else
2540  ptr = NdrSimpleStructMarshall( &StubMsg, (unsigned char *)&memsrc,
2541  &fmtstr_complex_array[32] );
2542 #endif
2543 
2544  ok(ptr == NULL, "ret %p\n", ptr);
2545  ok((char*)StubMsg.Buffer == (char*)StubMsg.BufferStart + expected_length, "not at expected length\n");
2546 
2547  buf = (DWORD *)StubMsg.BufferStart;
2548 
2549  ok(*buf == memsrc.dim1, "dim1 should have been %d instead of %08x\n", memsrc.dim1, *buf);
2550  buf++;
2551  ok(*buf == memsrc.dim2, "dim2 should have been %d instead of %08x\n", memsrc.dim2, *buf);
2552  buf++;
2553  ok(*buf != 0, "pointer id should be non-zero\n");
2554  buf++;
2555  ok(*buf == memsrc.dim1, "Conformance should have been %d instead of %08x\n", memsrc.dim1, *buf);
2556  buf++;
2557  for(i = 0; i < memsrc.dim1; i++)
2558  {
2559  ok(*buf != 0, "pointer id[%d] should be non-zero\n", i);
2560  buf++;
2561  }
2562  for(i = 0; i < memsrc.dim1; i++)
2563  {
2564  ok(*buf == memsrc.dim2, "Conformance should have been %d instead of %08x\n", memsrc.dim2, *buf);
2565  buf++;
2566  for(j = 0; j < memsrc.dim2; j++)
2567  {
2568  ok(*buf == i * memsrc.dim2 + j, "got %08x\n", *buf);
2569  buf++;
2570  }
2571  }
2572 
2573  ok((void*)buf == StubMsg.Buffer, "not at end of buffer\n");
2574 
2575  /* Server */
2576  my_alloc_called = 0;
2577  StubMsg.IsClient = 0;
2578  mem = NULL;
2579  StubMsg.Buffer = StubMsg.BufferStart;
2580 #ifdef _WIN64
2581  ptr = NdrComplexStructUnmarshall( &StubMsg, (unsigned char **)&mem, &fmtstr_complex_array[32], 0);
2582 #else
2583  ptr = NdrSimpleStructUnmarshall( &StubMsg, (unsigned char **)&mem, &fmtstr_complex_array[32], 0);
2584 #endif
2585  ok(ptr == NULL, "ret %p\n", ptr);
2586  ok(mem->dim1 == memsrc.dim1, "mem->dim1 wasn't unmarshalled correctly (%d)\n", mem->dim1);
2587  ok(mem->dim2 == memsrc.dim2, "mem->dim2 wasn't unmarshalled correctly (%d)\n", mem->dim2);
2588  ok(mem->array[1][0] == memsrc.dim2, "mem->array[1][0] wasn't unmarshalled correctly (%d)\n", mem->array[1][0]);
2589 
2590  StubMsg.Buffer = StubMsg.BufferStart;
2591 #ifdef _WIN64
2592  NdrComplexStructFree( &StubMsg, (unsigned char*)mem, &fmtstr_complex_array[32]);
2593 #else
2594  NdrSimpleStructFree( &StubMsg, (unsigned char*)mem, &fmtstr_complex_array[32]);
2595 #endif
2596 
2597  HeapFree(GetProcessHeap(), 0, StubMsg.RpcMsg->Buffer);
2598 
2599  for(i = 0; i < memsrc.dim1; i++)
2600  HeapFree(GetProcessHeap(), 0, memsrc.array[i]);
2601  HeapFree(GetProcessHeap(), 0, memsrc.array);
2602 }
2603 
2604 static void test_ndr_buffer(void)
2605 {
2606  static unsigned char ncalrpc[] = "ncalrpc";
2607  static unsigned char endpoint[] = "winetest:test_ndr_buffer";
2608  RPC_MESSAGE RpcMessage;
2609  MIDL_STUB_MESSAGE StubMsg;
2610  MIDL_STUB_DESC StubDesc = Object_StubDesc;
2611  unsigned char *ret;
2612  unsigned char *binding;
2615  ULONG prev_buffer_length;
2616  BOOL old_buffer_valid_location;
2617 
2619 
2620  status = RpcServerUseProtseqEpA(ncalrpc, 20, endpoint, NULL);
2621  ok(RPC_S_OK == status, "RpcServerUseProtseqEp failed with status %u\n", status);
2623  ok(RPC_S_OK == status, "RpcServerRegisterIf failed with status %u\n", status);
2624  status = RpcServerListen(1, 20, TRUE);
2625  ok(RPC_S_OK == status, "RpcServerListen failed with status %u\n", status);
2626  if (status != RPC_S_OK)
2627  {
2628  /* Failed to create a server, running client tests is useless */
2629  return;
2630  }
2631 
2632  status = RpcStringBindingComposeA(NULL, ncalrpc, NULL, endpoint, NULL, &binding);
2633  ok(status == RPC_S_OK, "RpcStringBindingCompose failed (%u)\n", status);
2634 
2636  ok(status == RPC_S_OK, "RpcBindingFromStringBinding failed (%u)\n", status);
2637  RpcStringFreeA(&binding);
2638 
2639  NdrClientInitializeNew(&RpcMessage, &StubMsg, &StubDesc, 5);
2640 
2641  ret = NdrGetBuffer(&StubMsg, 10, Handle);
2642  ok(ret == StubMsg.Buffer, "NdrGetBuffer should have returned the same value as StubMsg.Buffer instead of %p\n", ret);
2643  ok(RpcMessage.Handle != NULL, "RpcMessage.Handle should not have been NULL\n");
2644  ok(RpcMessage.Buffer != NULL, "RpcMessage.Buffer should not have been NULL\n");
2645  ok(RpcMessage.BufferLength == 10 ||
2646  broken(RpcMessage.BufferLength == 12), /* win2k */
2647  "RpcMessage.BufferLength should have been 10 instead of %d\n", RpcMessage.BufferLength);
2648  ok(RpcMessage.RpcFlags == 0, "RpcMessage.RpcFlags should have been 0x0 instead of 0x%x\n", RpcMessage.RpcFlags);
2649  ok(StubMsg.Buffer != NULL, "Buffer should not have been NULL\n");
2650  ok(!StubMsg.BufferStart, "BufferStart should have been NULL instead of %p\n", StubMsg.BufferStart);
2651  ok(!StubMsg.BufferEnd, "BufferEnd should have been NULL instead of %p\n", StubMsg.BufferEnd);
2652 todo_wine
2653  ok(StubMsg.BufferLength == 0, "BufferLength should have left as 0 instead of being set to %d\n", StubMsg.BufferLength);
2654  old_buffer_valid_location = !StubMsg.fBufferValid;
2655  if (old_buffer_valid_location)
2656  ok(broken(StubMsg.CorrDespIncrement == TRUE), "fBufferValid should have been TRUE instead of 0x%x\n", StubMsg.CorrDespIncrement);
2657  else
2658  ok(StubMsg.fBufferValid, "fBufferValid should have been non-zero instead of 0x%x\n", StubMsg.fBufferValid);
2659 
2660  prev_buffer_length = RpcMessage.BufferLength;
2661  StubMsg.BufferLength = 1;
2662  NdrFreeBuffer(&StubMsg);
2663  ok(RpcMessage.Handle != NULL, "RpcMessage.Handle should not have been NULL\n");
2664  ok(RpcMessage.Buffer != NULL, "RpcMessage.Buffer should not have been NULL\n");
2665  ok(RpcMessage.BufferLength == prev_buffer_length, "RpcMessage.BufferLength should have been left as %d instead of %d\n", prev_buffer_length, RpcMessage.BufferLength);
2666  ok(StubMsg.Buffer != NULL, "Buffer should not have been NULL\n");
2667  ok(StubMsg.BufferLength == 1, "BufferLength should have left as 1 instead of being set to %d\n", StubMsg.BufferLength);
2668  if (old_buffer_valid_location)
2669  ok(broken(StubMsg.CorrDespIncrement == FALSE), "fBufferValid should have been FALSE instead of 0x%x\n", StubMsg.CorrDespIncrement);
2670  else
2671  ok(!StubMsg.fBufferValid, "fBufferValid should have been FALSE instead of %d\n", StubMsg.fBufferValid);
2672 
2673  /* attempt double-free */
2674  NdrFreeBuffer(&StubMsg);
2675 
2677 
2679  ok(status == RPC_S_OK, "RpcServerUnregisterIf failed (%u)\n", status);
2680 }
2681 
2683 {
2684  RPC_STATUS rpc_status;
2685  MIDL_STUB_MESSAGE StubMsg;
2686  RPC_MESSAGE RpcMessage;
2687 
2688  NdrClientInitializeNew(&RpcMessage, &StubMsg, &Object_StubDesc, 5);
2689 
2690  for (rpc_status = 0; rpc_status < 10000; rpc_status++)
2691  {
2693  ULONG comm_status = 0;
2694  ULONG fault_status = 0;
2695  ULONG expected_comm_status = 0;
2696  ULONG expected_fault_status = 0;
2697  status = NdrMapCommAndFaultStatus(&StubMsg, &comm_status, &fault_status, rpc_status);
2698  ok(status == RPC_S_OK, "NdrMapCommAndFaultStatus failed with error %d\n", status);
2699  switch (rpc_status)
2700  {
2701  case ERROR_INVALID_HANDLE:
2702  case RPC_S_INVALID_BINDING:
2703  case RPC_S_UNKNOWN_IF:
2705  case RPC_S_SERVER_TOO_BUSY:
2706  case RPC_S_CALL_FAILED_DNE:
2707  case RPC_S_PROTOCOL_ERROR:
2711  case EPT_S_NOT_REGISTERED:
2712  case RPC_S_COMM_FAILURE:
2713  expected_comm_status = rpc_status;
2714  break;
2715  default:
2716  expected_fault_status = rpc_status;
2717  }
2718  ok(comm_status == expected_comm_status, "NdrMapCommAndFaultStatus should have mapped %d to comm status %d instead of %d\n",
2719  rpc_status, expected_comm_status, comm_status);
2720  ok(fault_status == expected_fault_status, "NdrMapCommAndFaultStatus should have mapped %d to fault status %d instead of %d\n",
2721  rpc_status, expected_fault_status, fault_status);
2722  }
2723 }
2724 
2726 {
2728  MIDL_STUB_MESSAGE stubmsg;
2729  USER_MARSHAL_CB umcb;
2731  unsigned char buffer[16];
2732  void *rpc_channel_buffer = (void *)(ULONG_PTR)0xcafebabe;
2734 
2735  /* unmarshall */
2736 
2737  memset(&rpc_msg, 0xcc, sizeof(rpc_msg));
2738  rpc_msg.Buffer = buffer;
2739  rpc_msg.BufferLength = 16;
2740 
2741  memset(&stubmsg, 0xcc, sizeof(stubmsg));
2742  stubmsg.RpcMsg = &rpc_msg;
2743  stubmsg.dwDestContext = MSHCTX_INPROC;
2744  stubmsg.pvDestContext = NULL;
2745  stubmsg.Buffer = buffer + 15;
2746  stubmsg.BufferLength = 0;
2747  stubmsg.BufferEnd = NULL;
2748  stubmsg.pRpcChannelBuffer = rpc_channel_buffer;
2749  stubmsg.StubDesc = NULL;
2750  stubmsg.pfnAllocate = my_alloc;
2751  stubmsg.pfnFree = my_free;
2752 
2753  memset(&umcb, 0xcc, sizeof(umcb));
2754  umcb.Flags = MAKELONG(MSHCTX_INPROC, NDR_LOCAL_DATA_REPRESENTATION);
2755  umcb.pStubMsg = &stubmsg;
2758 
2759  memset(&umi, 0xaa, sizeof(umi));
2760 
2761  status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2762  ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %d\n", status);
2763  ok( umi.InformationLevel == 1,
2764  "umi.InformationLevel was %u instead of 1\n",
2765  umi.InformationLevel);
2766  ok( U1(umi).Level1.Buffer == buffer + 15,
2767  "umi.Level1.Buffer was %p instead of %p\n",
2768  U1(umi).Level1.Buffer, buffer);
2769  ok( U1(umi).Level1.BufferSize == 1,
2770  "umi.Level1.BufferSize was %u instead of 1\n",
2771  U1(umi).Level1.BufferSize);
2772  ok( U1(umi).Level1.pfnAllocate == my_alloc,
2773  "umi.Level1.pfnAllocate was %p instead of %p\n",
2774  U1(umi).Level1.pfnAllocate, my_alloc);
2775  ok( U1(umi).Level1.pfnFree == my_free,
2776  "umi.Level1.pfnFree was %p instead of %p\n",
2777  U1(umi).Level1.pfnFree, my_free);
2778  ok( U1(umi).Level1.pRpcChannelBuffer == rpc_channel_buffer,
2779  "umi.Level1.pRpcChannelBuffer was %p instead of %p\n",
2780  U1(umi).Level1.pRpcChannelBuffer, rpc_channel_buffer);
2781 
2782  /* buffer size */
2783 
2784  rpc_msg.Buffer = buffer;
2785  rpc_msg.BufferLength = 16;
2786 
2787  stubmsg.Buffer = buffer;
2788  stubmsg.BufferLength = 16;
2789  stubmsg.BufferEnd = NULL;
2790 
2792 
2793  memset(&umi, 0xaa, sizeof(umi));
2794 
2795  status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2796  ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %d\n", status);
2797  ok( umi.InformationLevel == 1,
2798  "umi.InformationLevel was %u instead of 1\n",
2799  umi.InformationLevel);
2800  ok( U1(umi).Level1.Buffer == NULL,
2801  "umi.Level1.Buffer was %p instead of NULL\n",
2802  U1(umi).Level1.Buffer);
2803  ok( U1(umi).Level1.BufferSize == 0,
2804  "umi.Level1.BufferSize was %u instead of 0\n",
2805  U1(umi).Level1.BufferSize);
2806  ok( U1(umi).Level1.pfnAllocate == my_alloc,
2807  "umi.Level1.pfnAllocate was %p instead of %p\n",
2808  U1(umi).Level1.pfnAllocate, my_alloc);
2809  ok( U1(umi).Level1.pfnFree == my_free,
2810  "umi.Level1.pfnFree was %p instead of %p\n",
2811  U1(umi).Level1.pfnFree, my_free);
2812  ok( U1(umi).Level1.pRpcChannelBuffer == rpc_channel_buffer,
2813  "umi.Level1.pRpcChannelBuffer was %p instead of %p\n",
2814  U1(umi).Level1.pRpcChannelBuffer, rpc_channel_buffer);
2815 
2816  /* marshall */
2817 
2818  rpc_msg.Buffer = buffer;
2819  rpc_msg.BufferLength = 16;
2820 
2821  stubmsg.Buffer = buffer + 15;
2822  stubmsg.BufferLength = 0;
2823  stubmsg.BufferEnd = NULL;
2824 
2826 
2827  memset(&umi, 0xaa, sizeof(umi));
2828 
2829  status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2830  ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %d\n", status);
2831  ok( umi.InformationLevel == 1,
2832  "umi.InformationLevel was %u instead of 1\n",
2833  umi.InformationLevel);
2834  ok( U1(umi).Level1.Buffer == buffer + 15,
2835  "umi.Level1.Buffer was %p instead of %p\n",
2836  U1(umi).Level1.Buffer, buffer);
2837  ok( U1(umi).Level1.BufferSize == 1,
2838  "umi.Level1.BufferSize was %u instead of 1\n",
2839  U1(umi).Level1.BufferSize);
2840  ok( U1(umi).Level1.pfnAllocate == my_alloc,
2841  "umi.Level1.pfnAllocate was %p instead of %p\n",
2842  U1(umi).Level1.pfnAllocate, my_alloc);
2843  ok( U1(umi).Level1.pfnFree == my_free,
2844  "umi.Level1.pfnFree was %p instead of %p\n",
2845  U1(umi).Level1.pfnFree, my_free);
2846  ok( U1(umi).Level1.pRpcChannelBuffer == rpc_channel_buffer,
2847  "umi.Level1.pRpcChannelBuffer was %p instead of %p\n",
2848  U1(umi).Level1.pRpcChannelBuffer, rpc_channel_buffer);
2849 
2850  /* free */
2851 
2852  rpc_msg.Buffer = buffer;
2853  rpc_msg.BufferLength = 16;
2854 
2855  stubmsg.Buffer = buffer;
2856  stubmsg.BufferLength = 16;
2857  stubmsg.BufferEnd = NULL;
2858 
2860 
2861  memset(&umi, 0xaa, sizeof(umi));
2862 
2863  status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2864  ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %d\n", status);
2865  ok( umi.InformationLevel == 1,
2866  "umi.InformationLevel was %u instead of 1\n",
2867  umi.InformationLevel);
2868  ok( U1(umi).Level1.Buffer == NULL,
2869  "umi.Level1.Buffer was %p instead of NULL\n",
2870  U1(umi).Level1.Buffer);
2871  ok( U1(umi).Level1.BufferSize == 0,
2872  "umi.Level1.BufferSize was %u instead of 0\n",
2873  U1(umi).Level1.BufferSize);
2874  ok( U1(umi).Level1.pfnAllocate == my_alloc,
2875  "umi.Level1.pfnAllocate was %p instead of %p\n",
2876  U1(umi).Level1.pfnAllocate, my_alloc);
2877  ok( U1(umi).Level1.pfnFree == my_free,
2878  "umi.Level1.pfnFree was %p instead of %p\n",
2879  U1(umi).Level1.pfnFree, my_free);
2880  ok( U1(umi).Level1.pRpcChannelBuffer == rpc_channel_buffer,
2881  "umi.Level1.pRpcChannelBuffer was %p instead of %p\n",
2882  U1(umi).Level1.pRpcChannelBuffer, rpc_channel_buffer);
2883 
2884  /* boundary test */
2885 
2886  rpc_msg.Buffer = buffer;
2887  rpc_msg.BufferLength = 15;
2888 
2889  stubmsg.Buffer = buffer + 15;
2890  stubmsg.BufferLength = 0;
2891  stubmsg.BufferEnd = NULL;
2892 
2894 
2895  status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2896  ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %d\n", status);
2897  ok( U1(umi).Level1.BufferSize == 0,
2898  "umi.Level1.BufferSize was %u instead of 0\n",
2899  U1(umi).Level1.BufferSize);
2900 
2901  /* error conditions */
2902 
2903  rpc_msg.BufferLength = 14;
2904  status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2906  "NdrGetUserMarshalInfo should have failed with ERROR_INVALID_USER_BUFFER instead of %d\n", status);
2907 
2908  rpc_msg.BufferLength = 15;
2909  status = NdrGetUserMarshalInfo(&umcb.Flags, 9999, &umi);
2911  "NdrGetUserMarshalInfo should have failed with RPC_S_INVALID_ARG instead of %d\n", status);
2912 
2913  umcb.CBType = 9999;
2914  status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2915  ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %d\n", status);
2916 
2918  umcb.Signature = 0;
2919  status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2921  "NdrGetUserMarshalInfo should have failed with RPC_S_INVALID_ARG instead of %d\n", status);
2922 }
2923 
2925 {
2926  ULONG encoded_size;
2928  handle_t handle;
2929  char *buffer;
2930 
2932  ok(status == RPC_S_INVALID_ARG, "got %d\n", status);
2933 
2935  ok(status == RPC_S_INVALID_ARG, "got %d\n", status);
2936 
2937  status = MesEncodeFixedBufferHandleCreate((char*)0xdeadbeef, 0, NULL, &handle);
2938  ok(status == RPC_X_INVALID_BUFFER, "got %d\n", status);
2939 
2940  buffer = (void*)((0xdeadbeef + 7) & ~7);
2942  ok(status == RPC_S_INVALID_ARG, "got %d\n", status);
2943 
2944  status = MesEncodeFixedBufferHandleCreate(buffer, 0, &encoded_size, &handle);
2945 todo_wine
2946  ok(status == RPC_S_INVALID_ARG, "got %d\n", status);
2947 if (status == RPC_S_OK) {
2949 }
2951  ok(status == RPC_S_INVALID_ARG, "got %d\n", status);
2952 
2953  status = MesEncodeFixedBufferHandleCreate(buffer, 32, &encoded_size, &handle);
2954  ok(status == RPC_S_OK, "got %d\n", status);
2955 
2957  &buffer, 32, &encoded_size);
2958  ok(status == RPC_S_INVALID_ARG, "got %d\n", status);
2959 
2960  /* convert to dynamic buffer handle */
2962  &buffer, 32, &encoded_size);
2963  ok(status == RPC_S_OK, "got %d\n", status);
2964 
2966  NULL, 32, &encoded_size);
2967  ok(status == RPC_S_INVALID_ARG, "got %d\n", status);
2968 
2970  &buffer, 32, NULL);
2971  ok(status == RPC_S_INVALID_ARG, "got %d\n", status);
2972 
2973  /* invalid handle type */
2975  &buffer, 32, &encoded_size);
2976  ok(status == RPC_S_INVALID_ARG, "got %d\n", status);
2977 
2979  ok(status == RPC_S_OK, "got %d\n", status);
2980 }
2981 
2983 {
2984  MIDL_STUB_MESSAGE stub_msg;
2985  BYTE buf[256];
2986 
2987  memset( &stub_msg, 0, sizeof(stub_msg) );
2988  memset( buf, 0, sizeof(buf) );
2989 
2990  NdrCorrelationInitialize( &stub_msg, buf, sizeof(buf), 0 );
2991  ok( stub_msg.CorrDespIncrement == 2 ||
2992  broken(stub_msg.CorrDespIncrement == 0), /* <= Win 2003 */
2993  "got %d\n", stub_msg.CorrDespIncrement );
2994 
2995  memset( &stub_msg, 0, sizeof(stub_msg) );
2996  memset( buf, 0, sizeof(buf) );
2997 
2998  stub_msg.CorrDespIncrement = 1;
2999  NdrCorrelationInitialize( &stub_msg, buf, sizeof(buf), 0 );
3000  ok( stub_msg.CorrDespIncrement == 1, "got %d\n", stub_msg.CorrDespIncrement );
3001 }
3002 
3003 START_TEST( ndr_marshall )
3004 {
3006 
3012  test_iface_ptr();
3014  test_client_init();
3015  test_server_init();
3022  test_ndr_buffer();
3027 }
static void test_simple_struct(void)
void WINAPI NdrInterfacePointerFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
Definition: ndr_ole.c:411
void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
#define RPC_S_UNKNOWN_IF
Definition: winerror.h:1028
void WINAPI NdrSimpleTypeMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, unsigned char FormatChar)
unsigned __int3264 UINT_PTR
Definition: activex.cpp:275
unsigned char *WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc)
RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi)
void * RpcInterfaceInformation
Definition: rpcdcep.h:44
void * RpcInterfaceInformation
Definition: rpcndr.h:362
static void test_fullpointer_xlat(void)
LONG l1
#define U1(x)
Definition: test.h:188
RPC_STATUS WINAPI RpcBindingFree(RPC_BINDING_HANDLE *Binding)
Definition: rpc_binding.c:783
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
struct S2 s2
int proxy
Definition: main.c:67
#define RPC_S_UNSUPPORTED_TRANS_SYN
Definition: winerror.h:1040
int WINAPI NdrFullPointerQueryRefId(PFULL_PTR_XLAT_TABLES pXlatTables, ULONG RefId, unsigned char QueryType, void **ppPointer)
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
static int deref_cmp(const void *s1, const void *s2, size_t num)
Definition: ndr_marshall.c:497
static void test_simple_struct_marshal(const unsigned char *formattypes, void *memsrc, DWORD srcsize, const void *wiredata, ULONG wiredatalen, int(*cmp)(const void *, const void *, size_t), int num_additional_allocs, const char *msgpfx)
Definition: ndr_marshall.c:870
#define FC_POINTER_DEREF
Definition: ndrtypes.h:276
#define RPC_S_PROCNUM_OUT_OF_RANGE
Definition: winerror.h:1053
#define E_NOINTERFACE
Definition: winerror.h:2364
static int my_alloc_called
Definition: ndr_marshall.c:40
#define TEST_ULONG_UNSET(field)
static BOOL use_pointer_ids
Definition: ndr_marshall.c:103
static void test_conf_complex_struct(void)
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
RPC_STATUS WINAPI MesHandleFree(handle_t Handle)
Definition: ndr_es.c:162
static void test_ndr_buffer(void)
HRESULT hr
Definition: shlfolder.c:183
GLint x0
Definition: linetemp.h:95
unsigned char *WINAPI NdrInterfacePointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
Definition: ndr_ole.c:306
void WINAPI NdrFullPointerXlatFree(PFULL_PTR_XLAT_TABLES pXlatTables)
ULONG MemorySize
Definition: rpcndr.h:208
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
static void test_pointer_marshal(const unsigned char *formattypes, void *memsrc, DWORD srcsize, const void *wiredata, ULONG wiredatalen, int(*cmp)(const void *, const void *, size_t), int num_additional_allocs, const char *msgpfx)
Definition: ndr_marshall.c:175
static void test_server_init(void)
static void CALLBACK my_free(void *ptr)
Definition: ndr_marshall.c:48
RPC_STATUS WINAPI RpcStringBindingComposeA(RPC_CSTR ObjUuid, RPC_CSTR Protseq, RPC_CSTR NetworkAddr, RPC_CSTR Endpoint, RPC_CSTR Options, RPC_CSTR *StringBinding)
Definition: rpc_binding.c:457
void(__RPC_STUB * RPC_DISPATCH_FUNCTION)(PRPC_MESSAGE Message)
Definition: rpcdcep.h:82
const GUID IID_IPersist
Definition: proxy.cpp:14
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
unsigned char *WINAPI NdrServerInitializeNew(PRPC_MESSAGE pRpcMsg, PMIDL_STUB_MESSAGE pStubMsg, PMIDL_STUB_DESC pStubDesc)
unsigned char * Buffer
Definition: rpcndr.h:203
#define CALLBACK
Definition: compat.h:27
unsigned char * pCorrMemory
Definition: rpcndr.h:263
static int my_free_called
Definition: ndr_marshall.c:41
static ULONGLONG Memory
Definition: CcMapData_drv.c:35
#define RPC_S_INVALID_ARG
Definition: rpcnterr.h:23
u32_t magic(void)
struct _FULL_PTR_XLAT_TABLES * FullPtrXlatTables
Definition: rpcndr.h:231
const char * wine_dbgstr_guid(const GUID *guid)
#define RPC_S_SERVER_UNAVAILABLE
Definition: winerror.h:1033
const struct _MIDL_STUB_DESC * StubDesc
Definition: rpcndr.h:230
GLuint buffer
Definition: glext.h:5915
START_TEST(ndr_marshall)
#define NdrFcShort(s)
Definition: rpcndr.h:134
void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
PRPC_MESSAGE RpcMsg
Definition: rpcndr.h:202
static void test_NdrGetUserMarshalInfo(void)
static ULONG WINAPI test_persist_Release(IPersist *iface)
#define cmp(status, error)
Definition: error.c:114
static void test_iface_ptr(void)
RPC_STATUS WINAPI RpcStringFreeA(RPC_CSTR *String)
Definition: rpcrt4_main.c:158
void * LowStackMark
Definition: rpcndr.h:260
Definition: send.c:48
RPC_STATUS WINAPI RpcServerUnregisterIf(RPC_IF_HANDLE IfSpec, UUID *MgrTypeUuid, UINT WaitForCallsToComplete)
Definition: rpc_server.c:1202
#define RPC_X_INVALID_BUFFER
Definition: rpcnterr.h:40
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
static ULONG WINAPI test_persist_AddRef(IPersist *iface)
uint32_t ULONG_PTR
Definition: typedefs.h:64
#define ERROR_INVALID_USER_BUFFER
Definition: winerror.h:1091
static void test_common_stub_data(const char *prefix, const MIDL_STUB_MESSAGE *stubMsg)
unsigned int BufferLength
Definition: rpcdcep.h:41
INT_PTR Unused
Definition: rpcndr.h:268
int WINAPI NdrFullPointerFree(PFULL_PTR_XLAT_TABLES pXlatTables, void *Pointer)
unsigned char *WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
long RPC_STATUS
Definition: rpc.h:52
ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
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
void * Buffer
Definition: rpcdcep.h:40
#define TEST_POINTER_UNSET(field)
unsigned char *WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
unsigned char *WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc)
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
void * RPC_IF_HANDLE
Definition: rpcdce.h:49
LONG * pl1
static void test_MesEncodeFixedBufferHandleCreate(void)
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
void *WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, SIZE_T len)
Definition: ndr_marshall.c:419
RPC_STATUS WINAPI RpcServerListen(UINT MinimumCallThreads, UINT MaxCalls, UINT DontWait)
Definition: rpc_server.c:1520
DWORD dwDestContext
Definition: rpcndr.h:249
GLenum GLint ref
Definition: glext.h:6028
struct NDR_POINTER_QUEUE_STATE * pPointerQueueState
Definition: rpcndr.h:215
static PVOID ptr
Definition: dispmode.c:27
static void test_nonconformant_string(void)
LONGLONG b
unsigned int ProcNum
Definition: rpcdcep.h:42
void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
static void test_simple_types(void)
Definition: ndr_marshall.c:503
static void test_client_init(void)
#define MAKELONG(a, b)
Definition: typedefs.h:248
#define RPC_S_CALL_FAILED_DNE
Definition: winerror.h:1038
#define RPC_S_INVALID_BINDING
Definition: winerror.h:1013
smooth NULL
Definition: ftsmooth.c:416
static void test_struct_align(void)
void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
#define FC_ALLOCED_ON_STACK
Definition: ndrtypes.h:274
char * pc1
static void test_NdrCorrelationInitialize(void)
unsigned char *WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
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
#define NdrFcLong(s)
Definition: rpcndr.h:135
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 GLint GLint j
Definition: glfuncs.h:250
r l[0]
Definition: byte_order.h:167
#define RPC_S_PROTOCOL_ERROR
Definition: winerror.h:1039
RPC_STATUS WINAPI MesBufferHandleReset(handle_t Handle, ULONG HandleStyle, MIDL_ES_CODE Operation, char **Buffer, ULONG BufferSize, ULONG *EncodedSize)
Definition: ndr_es.c:128
static const MIDL_STUB_DESC Object_StubDesc
Definition: ndr_marshall.c:54
int64_t LONGLONG
Definition: typedefs.h:67
_In_ HANDLE Handle
Definition: extypes.h:390
static void test_conformant_array(void)
GLfloat f
Definition: glext.h:7540
#define RPC_S_UNSUPPORTED_TYPE
Definition: winerror.h:1041
#define TEST_ZERO(field, fmt)
GLsizeiptr size
Definition: glext.h:5919
unsigned char *WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc)
#define GetProcessHeap()
Definition: compat.h:404
#define trace
Definition: atltest.h:70
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define d
Definition: ke_i.h:81
RPC_STATUS WINAPI RpcBindingFromStringBindingA(RPC_CSTR StringBinding, RPC_BINDING_HANDLE *Binding)
Definition: rpc_binding.c:836
void * pvDestContext
Definition: rpcndr.h:250
unsigned char *WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc)
LONG HRESULT
Definition: typedefs.h:78
unsigned char *WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc)
struct S1 s1
uint64_t ULONGLONG
Definition: typedefs.h:66
RPC_STATUS WINAPI RpcServerUseProtseqEpA(RPC_CSTR Protseq, UINT MaxCalls, RPC_CSTR Endpoint, LPVOID SecurityDescriptor)
Definition: rpc_server.c:910
#define RPC_S_COMM_FAILURE
Definition: winerror.h:1127
const GUID IID_IUnknown
ULONG RpcFlags
Definition: rpcdcep.h:48
#define WINAPI
Definition: msvc.h:6
const GLubyte * c
Definition: glext.h:8905
static FILE * out
Definition: regtests2xml.c:44
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint num
Definition: glext.h:9618
RPC_STATUS WINAPI RpcServerRegisterIf(RPC_IF_HANDLE IfSpec, UUID *MgrTypeUuid, RPC_MGR_EPV *MgrEpv)
Definition: rpc_server.c:1116
struct _RPC_SERVER_INTERFACE RPC_SERVER_INTERFACE
unsigned char *WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
const unsigned char * pFormatTypes
Definition: rpcndr.h:374
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
Definition: id3.c:18
void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
unsigned char * BufferStart
Definition: rpcndr.h:204
void * pMemoryList
Definition: rpcndr.h:264
ULONG BufferLength
Definition: rpcndr.h:207
unsigned char * BufferEnd
Definition: rpcndr.h:205
IPersist IPersist_iface
PRPC_SYNTAX_IDENTIFIER TransferSyntax
Definition: rpcdcep.h:43
int ret
static RPC_IF_HANDLE IFoo_v0_0_s_ifspec
Definition: ndr_marshall.c:102
REFCLSID clsid
Definition: msctf.c:82
unsigned int fBufferValid
Definition: rpcndr.h:243
#define todo_wine
Definition: test.h:162
static CONST DWORD MemorySize[]
Definition: svga.c:32
static void test_ndr_allocate(void)
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLdouble s
Definition: gl.h:2039
static const RPC_SERVER_INTERFACE IFoo___RpcServerInterface
Definition: ndr_marshall.c:89
void *WINAPI NdrOleAllocate(SIZE_T Size)
Definition: ndr_ole.c:423
static void test_NdrMapCommAndFaultStatus(void)
RPC_MGR_EPV * ManagerEpv
Definition: rpcdcep.h:46
static void test_conf_complex_array(void)
PNDR_ASYNC_MESSAGE pAsyncMsg
Definition: rpcndr.h:261
unsigned char BYTE
Definition: xxhash.c:193
#define broken(x)
Definition: _sntprintf.h:21
static void test_nontrivial_pointer_types(void)
Definition: ndr_marshall.c:716
unsigned int fIsIn
Definition: rpcndr.h:240
static RPC_DISPATCH_TABLE IFoo_v0_0_DispatchTable
Definition: ndr_marshall.c:83
#define RPC_S_SERVER_TOO_BUSY
Definition: winerror.h:1034
void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
USER_MARSHAL_CB_TYPE CBType
Definition: rpcndr.h:336
ULONG_PTR SIZE_T
Definition: typedefs.h:79
static HRESULT WINAPI test_persist_QueryInterface(IPersist *iface, REFIID iid, void **out)
#define S_OK
Definition: intsafe.h:59
#define RPC_BUFFER_COMPLETE
Definition: rpcdcep.h:67
Definition: nis.h:10
#define NDR_LOCAL_DATA_REPRESENTATION
Definition: rpcndr.h:107
static unsigned __int64 next
Definition: rand_nt.c:6
PFULL_PTR_XLAT_TABLES WINAPI NdrFullPointerXlatInit(ULONG NumberOfPointers, XLAT_SIDE XlatSide)
PNDR_CORRELATION_INFO pCorrInfo
Definition: rpcndr.h:262
unsigned char IsClient
Definition: rpcndr.h:210
static void test_ndr_simple_type(void)
Definition: ndr_marshall.c:139
#define USER_MARSHAL_CB_SIGNATURE
Definition: rpcndr.h:318
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
void WINAPI NdrOleFree(void *NodeToFree)
Definition: ndr_ole.c:432
void WINAPI NdrFreeBuffer(PMIDL_STUB_MESSAGE pStubMsg)
ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
#define f
Definition: ke_i.h:83
#define ok(value,...)
Definition: atltest.h:57
static void *CALLBACK my_alloc(SIZE_T size)
Definition: ndr_marshall.c:42
unsigned int fHasReturn
Definition: rpcndr.h:237
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
void WINAPI NdrInterfacePointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
Definition: ndr_ole.c:373
unsigned char *WINAPI NdrGetBuffer(PMIDL_STUB_MESSAGE stubmsg, ULONG buflen, RPC_BINDING_HANDLE handle)
w ll
Definition: byte_order.h:166
ULONG Signature
Definition: rpcndr.h:335
#define EPT_S_NOT_REGISTERED
Definition: winerror.h:1061
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
RPC_STATUS RPC_ENTRY MesEncodeFixedBufferHandleCreate(char *Buffer, ULONG BufferSize, ULONG *pEncodedSize, handle_t *pHandle)
Definition: ndr_es.c:183
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
static RPC_DISPATCH_FUNCTION IFoo_table[]
Definition: ndr_marshall.c:78
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3706
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
static void test_conformant_string(void)
#define TEST_ULONG_PTR_UNSET(field)
Definition: mem.c:156
unsigned char CorrDespIncrement
Definition: rpcndr.h:218
unsigned char *WINAPI NdrInterfacePointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc)
Definition: ndr_ole.c:336
void WINAPI NdrSimpleTypeUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, unsigned char FormatChar)
void * ImportContext
Definition: rpcdcep.h:47
void WINAPI NdrFullPointerInsertRefId(PFULL_PTR_XLAT_TABLES pXlatTables, ULONG RefId, void *pPointer)
#define c
Definition: ke_i.h:80
void WINAPI NdrClientInitializeNew(PRPC_MESSAGE pRpcMessage, PMIDL_STUB_MESSAGE pStubMsg, PMIDL_STUB_DESC pStubDesc, unsigned int ProcNum)
unsigned int ULONG
Definition: retypes.h:1
PMIDL_STUB_MESSAGE pStubMsg
Definition: rpcndr.h:333
static int ps1_cmp(const void *s1, const void *s2, size_t num)
static IPersistVtbl testiface_vtbl
static void determine_pointer_marshalling_style(void)
Definition: ndr_marshall.c:105
static HRESULT WINAPI test_persist_GetClassId(IPersist *iface, GUID *clsid)
RPC_STATUS RPC_ENTRY NdrMapCommAndFaultStatus(PMIDL_STUB_MESSAGE pStubMsg, ULONG *pCommStatus, ULONG *pFaultStatus, RPC_STATUS Status)
static struct testiface * impl_from_IPersist(IPersist *iface)
unsigned char uFlags
Definition: rpcndr.h:219
#define memset(x, y, z)
Definition: compat.h:39
static SERVICE_STATUS status
Definition: service.c:31
#define win_skip
Definition: test.h:149
RPC_BINDING_HANDLE Handle
Definition: rpcdcep.h:38
#define HeapFree(x, y, z)
Definition: compat.h:403
unsigned char *WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
int WINAPI NdrFullPointerQueryPointer(PFULL_PTR_XLAT_TABLES pXlatTables, void *pPointer, unsigned char QueryType, ULONG *pRefId)
void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
struct IRpcChannelBuffer * pRpcChannelBuffer
Definition: rpcndr.h:253
#define RPC_S_OK
Definition: rpcnterr.h:22
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 GLint GLint GLenum GLenum GLenum GLint GLuint GLenum GLenum GLfloat GLenum GLfloat GLenum GLint const GLfloat GLenum GLint const GLushort GLint GLint GLsizei GLsizei GLenum GLsizei GLsizei GLenum GLenum const GLvoid GLenum GLdouble GLenum GLint GLenum GLenum GLint GLenum GLenum GLfloat GLenum GLenum GLfloat GLenum GLfloat GLenum GLushort const GLubyte GLenum GLenum GLenum GLint GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLvoid GLenum GLenum GLint GLenum GLint GLenum GLint GLuint GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble const GLfloat GLenum const GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble GLint GLint GLsizei GLsizei GLenum GLuint GLenum array
Definition: glfuncs.h:320
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
ULONG PointerLength
Definition: rpcndr.h:233
Definition: ps.c:97