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