ole32: Remove an unnecessary special case in StorageBaseImpl_CopyTo.
[wine] / dlls / rpcrt4 / tests / ndr_marshall.c
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 #include <stdarg.h>
22
23 #define NTDDI_WIN2K   0x05000000
24 #define NTDDI_VERSION NTDDI_WIN2K /* for some MIDL_STUB_MESSAGE fields */
25
26 #include "wine/test.h"
27 #include <windef.h>
28 #include <winbase.h>
29 #include <winnt.h>
30 #include <winerror.h>
31
32 #include "rpc.h"
33 #include "rpcdce.h"
34 #include "rpcproxy.h"
35
36
37 static int my_alloc_called;
38 static int my_free_called;
39 static void * CALLBACK my_alloc(SIZE_T size)
40 {
41     my_alloc_called++;
42     return NdrOleAllocate(size);
43 }
44
45 static void CALLBACK my_free(void *ptr)
46 {
47     my_free_called++;
48     NdrOleFree(ptr);
49 }
50
51 static const MIDL_STUB_DESC Object_StubDesc = 
52     {
53     NULL,
54     my_alloc,
55     my_free,
56     { 0 },
57     0,
58     0,
59     0,
60     0,
61     NULL, /* format string, filled in by tests */
62     1, /* -error bounds_check flag */
63     0x20000, /* Ndr library version */
64     0,
65     0x50100a4, /* MIDL Version 5.1.164 */
66     0,
67     NULL,
68     0,  /* notify & notify_flag routine table */
69     1,  /* Flags */
70     0,  /* Reserved3 */
71     0,  /* Reserved4 */
72     0   /* Reserved5 */
73     };
74
75 static RPC_DISPATCH_FUNCTION IFoo_table[] =
76 {
77     0
78 };
79
80 static RPC_DISPATCH_TABLE IFoo_v0_0_DispatchTable =
81 {
82     0,
83     IFoo_table
84 };
85
86 static const RPC_SERVER_INTERFACE IFoo___RpcServerInterface =
87 {
88     sizeof(RPC_SERVER_INTERFACE),
89     {{0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x34}},{0,0}},
90     {{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}},
91     &IFoo_v0_0_DispatchTable,
92     0,
93     0,
94     0,
95     0,
96     0,
97 };
98
99 static RPC_IF_HANDLE IFoo_v0_0_s_ifspec = (RPC_IF_HANDLE)& IFoo___RpcServerInterface;
100 static BOOL use_pointer_ids = FALSE;
101
102 static void determine_pointer_marshalling_style(void)
103 {
104     RPC_MESSAGE RpcMessage;
105     MIDL_STUB_MESSAGE StubMsg;
106     MIDL_STUB_DESC StubDesc;
107     char ch = 0xde;
108
109     static const unsigned char fmtstr_up_char[] =
110     {
111         0x12, 0x8,      /* FC_UP [simple_pointer] */
112         0x2,            /* FC_CHAR */
113         0x5c,           /* FC_PAD */
114     };
115
116     StubDesc = Object_StubDesc;
117     StubDesc.pFormatTypes = NULL;
118
119     NdrClientInitializeNew(
120                            &RpcMessage,
121                            &StubMsg,
122                            &StubDesc,
123                            0);
124
125     StubMsg.BufferLength = 8;
126     StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
127     NdrPointerMarshall(&StubMsg, (unsigned char*)&ch, fmtstr_up_char);
128     ok(StubMsg.Buffer == StubMsg.BufferStart + 5, "%p %p\n", StubMsg.Buffer, StubMsg.BufferStart);
129
130     use_pointer_ids = (*(unsigned int *)StubMsg.BufferStart != (UINT_PTR)&ch);
131     trace("Pointer marshalling using %s\n", use_pointer_ids ? "pointer ids" : "pointer value");
132
133     HeapFree(GetProcessHeap(), 0, StubMsg.BufferStart);
134 }
135
136 static void test_ndr_simple_type(void)
137 {
138     RPC_MESSAGE RpcMessage;
139     MIDL_STUB_MESSAGE StubMsg;
140     MIDL_STUB_DESC StubDesc;
141     LONG l, l2 = 0;
142
143     StubDesc = Object_StubDesc;
144     StubDesc.pFormatTypes = NULL;
145
146     NdrClientInitializeNew(
147                            &RpcMessage,
148                            &StubMsg,
149                            &StubDesc,
150                            0);
151
152     StubMsg.BufferLength = 16;
153     StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
154     l = 0xcafebabe;
155     NdrSimpleTypeMarshall(&StubMsg, (unsigned char*)&l, 8 /* FC_LONG */);
156     ok(StubMsg.Buffer == StubMsg.BufferStart + 4, "%p %p\n", StubMsg.Buffer, StubMsg.BufferStart);
157     ok(*(LONG*)StubMsg.BufferStart == l, "%d\n", *(LONG*)StubMsg.BufferStart);
158
159     StubMsg.Buffer = StubMsg.BufferStart + 1;
160     NdrSimpleTypeMarshall(&StubMsg, (unsigned char*)&l, 8 /* FC_LONG */);
161     ok(StubMsg.Buffer == StubMsg.BufferStart + 8, "%p %p\n", StubMsg.Buffer, StubMsg.BufferStart);
162     ok(*(LONG*)(StubMsg.BufferStart + 4) == l, "%d\n", *(LONG*)StubMsg.BufferStart);
163
164     StubMsg.Buffer = StubMsg.BufferStart + 1;
165     NdrSimpleTypeUnmarshall(&StubMsg, (unsigned char*)&l2, 8 /* FC_LONG */);
166     ok(StubMsg.Buffer == StubMsg.BufferStart + 8, "%p %p\n", StubMsg.Buffer, StubMsg.BufferStart);
167     ok(l2 == l, "%d\n", l2);
168
169     HeapFree(GetProcessHeap(), 0, StubMsg.BufferStart);
170 }
171
172 static void test_pointer_marshal(const unsigned char *formattypes,
173                                  void *memsrc, DWORD srcsize,
174                                  const void *wiredata,
175                                  ULONG wiredatalen,
176                                  int(*cmp)(const void*,const void*,size_t),
177                                  int num_additional_allocs,
178                                  const char *msgpfx)
179 {
180     RPC_MESSAGE RpcMessage;
181     MIDL_STUB_MESSAGE StubMsg;
182     MIDL_STUB_DESC StubDesc;
183     DWORD size;
184     void *ptr;
185     unsigned char *mem, *mem_orig;
186
187     my_alloc_called = my_free_called = 0;
188     if(!cmp)
189         cmp = memcmp;
190
191     StubDesc = Object_StubDesc;
192     StubDesc.pFormatTypes = formattypes;
193
194     NdrClientInitializeNew(
195                            &RpcMessage,
196                            &StubMsg,
197                            &StubDesc,
198                            0);
199
200     StubMsg.BufferLength = 0;
201     NdrPointerBufferSize( &StubMsg,
202                           memsrc,
203                           formattypes );
204     ok(StubMsg.BufferLength >= wiredatalen, "%s: length %d\n", msgpfx, StubMsg.BufferLength);
205
206     /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
207     StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
208     StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
209
210     memset(StubMsg.BufferStart, 0x0, StubMsg.BufferLength); /* This is a hack to clear the padding between the ptr and longlong/double */
211
212     ptr = NdrPointerMarshall( &StubMsg,  memsrc, formattypes );
213     ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
214     if (srcsize == 8 && wiredatalen == 16 && StubMsg.Buffer - StubMsg.BufferStart == 12)
215     {
216         /* win9x doesn't align 8-byte types properly */
217         wiredatalen = 12;
218     }
219     else
220     {
221         ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
222         ok(!memcmp(StubMsg.BufferStart, wiredata, wiredatalen), "%s: incorrectly marshaled\n", msgpfx);
223     }
224
225     StubMsg.Buffer = StubMsg.BufferStart;
226     StubMsg.MemorySize = 0;
227
228     size = NdrPointerMemorySize( &StubMsg, formattypes );
229     ok(size == StubMsg.MemorySize, "%s: mem size %u size %u\n", msgpfx, StubMsg.MemorySize, size);
230     ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
231     if(formattypes[1] & 0x10 /* FC_POINTER_DEREF */)
232         ok(size == srcsize + sizeof(void *), "%s: mem size %u\n", msgpfx, size);
233     else
234         ok(size == srcsize, "%s: mem size %u\n", msgpfx, size);
235
236     StubMsg.Buffer = StubMsg.BufferStart;
237     StubMsg.MemorySize = 16;
238     size = NdrPointerMemorySize( &StubMsg, formattypes );
239     ok(size == StubMsg.MemorySize, "%s: mem size %u size %u\n", msgpfx, StubMsg.MemorySize, size);
240     ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
241     if(formattypes[1] & 0x10 /* FC_POINTER_DEREF */)
242         ok(size == srcsize + sizeof(void *) + 16, "%s: mem size %u\n", msgpfx, size);
243     else
244         ok(size == srcsize + 16, "%s: mem size %u\n", msgpfx, size);
245
246     StubMsg.Buffer = StubMsg.BufferStart;
247     StubMsg.MemorySize = 1;
248     size = NdrPointerMemorySize( &StubMsg, formattypes );
249     ok(size == StubMsg.MemorySize, "%s: mem size %u size %u\n", msgpfx, StubMsg.MemorySize, size);
250     ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
251     if(formattypes[1] & 0x10 /* FC_POINTER_DEREF */)
252         ok(size == srcsize + sizeof(void *) + (srcsize == 8 ? 8 : sizeof(void *)), "%s: mem size %u\n", msgpfx, size);
253     else
254         ok(size == srcsize + (srcsize == 8 ? 8 : sizeof(void *)), "%s: mem size %u\n", msgpfx, size);
255
256     size = srcsize;
257     if(formattypes[1] & 0x10) size += 4;
258
259     StubMsg.Buffer = StubMsg.BufferStart;
260     StubMsg.MemorySize = 0;
261     mem_orig = mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
262
263     if(formattypes[1] & 0x10 /* FC_POINTER_DEREF */)
264         *(void**)mem = NULL;
265     ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 0 );
266     ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
267     ok(mem == mem_orig, "%s: mem has changed %p %p\n", msgpfx, mem, mem_orig);
268     ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx);
269     ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
270     ok(StubMsg.MemorySize == 0, "%s: memorysize %d\n", msgpfx, StubMsg.MemorySize);
271     ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called); 
272     my_alloc_called = 0;
273
274     /* reset the buffer and call with must alloc */
275     StubMsg.Buffer = StubMsg.BufferStart;
276     if(formattypes[1] & 0x10 /* FC_POINTER_DEREF */)
277         *(void**)mem = NULL;
278     ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 1 );
279     ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
280     /* doesn't allocate mem in this case */
281 todo_wine {
282     ok(mem == mem_orig, "%s: mem has changed %p %p\n", msgpfx, mem, mem_orig);
283  }
284     ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx);
285     ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
286     ok(StubMsg.MemorySize == 0, "%s: memorysize %d\n", msgpfx, StubMsg.MemorySize);
287
288 todo_wine {
289     ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called); 
290 }
291     my_alloc_called = 0;
292     if(formattypes[0] != 0x11 /* FC_RP */)
293     {
294         /* now pass the address of a NULL ptr */
295         mem = NULL;
296         StubMsg.Buffer = StubMsg.BufferStart;
297         ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 0 );
298         ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
299         ok(mem != StubMsg.BufferStart + wiredatalen - srcsize, "%s: mem points to buffer %p %p\n", msgpfx, mem, StubMsg.BufferStart);
300         ok(!cmp(mem, memsrc, size), "%s: incorrectly unmarshaled\n", msgpfx);
301         ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
302         ok(StubMsg.MemorySize == 0, "%s: memorysize %d\n", msgpfx, StubMsg.MemorySize);
303         ok(my_alloc_called == num_additional_allocs + 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called); 
304         my_alloc_called = 0;
305         NdrPointerFree(&StubMsg, mem, formattypes);
306  
307         /* again pass address of NULL ptr, but pretend we're a server */
308         if (0)  /* crashes on Win9x and NT4 */
309         {
310             mem = NULL;
311             StubMsg.Buffer = StubMsg.BufferStart;
312             StubMsg.IsClient = 0;
313             ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 0 );
314             ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
315             if (formattypes[2] == 0xd /* FC_ENUM16 */)
316                 ok(mem != StubMsg.BufferStart + wiredatalen - srcsize, "%s: mem points to buffer %p %p\n", msgpfx, mem, StubMsg.BufferStart);
317             else
318                 ok(mem == StubMsg.BufferStart + wiredatalen - srcsize, "%s: mem doesn't point to buffer %p %p\n", msgpfx, mem, StubMsg.BufferStart);
319             ok(!cmp(mem, memsrc, size), "%s: incorrectly unmarshaled\n", msgpfx);
320             ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
321             ok(StubMsg.MemorySize == 0, "%s: memorysize %d\n", msgpfx, StubMsg.MemorySize);
322             if (formattypes[2] != 0xd /* FC_ENUM16 */) {
323                 ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
324                 my_alloc_called = 0;
325             }
326         }
327     }
328     HeapFree(GetProcessHeap(), 0, mem_orig);
329     HeapFree(GetProcessHeap(), 0, StubMsg.BufferStart);
330 }
331
332 static int deref_cmp(const void *s1, const void *s2, size_t num)
333 {
334     return memcmp(*(const void *const *)s1, *(const void *const *)s2, num);
335 }
336
337
338 static void test_simple_types(void)
339 {
340     unsigned char wiredata[16];
341     unsigned char ch;
342     unsigned char *ch_ptr;
343     unsigned short s;
344     unsigned int i;
345     ULONG l;
346     ULONGLONG ll;
347     float f;
348     double d;
349
350     static const unsigned char fmtstr_up_char[] =
351     {
352         0x12, 0x8,      /* FC_UP [simple_pointer] */
353         0x2,            /* FC_CHAR */
354         0x5c,           /* FC_PAD */
355     };
356     static const unsigned char fmtstr_up_byte[] =
357     {
358         0x12, 0x8,      /* FC_UP [simple_pointer] */
359         0x1,            /* FC_BYTE */
360         0x5c,           /* FC_PAD */
361     };
362     static const unsigned char fmtstr_up_small[] =
363     {
364         0x12, 0x8,      /* FC_UP [simple_pointer] */
365         0x3,            /* FC_SMALL */
366         0x5c,           /* FC_PAD */
367     };
368     static const unsigned char fmtstr_up_usmall[] =
369     {
370         0x12, 0x8,      /* FC_UP [simple_pointer] */
371         0x4,            /* FC_USMALL */
372         0x5c,           /* FC_PAD */
373     };  
374     static const unsigned char fmtstr_rp_char[] =
375     {
376         0x11, 0x8,      /* FC_RP [simple_pointer] */
377         0x2,            /* FC_CHAR */
378         0x5c,           /* FC_PAD */
379     };
380     static const unsigned char fmtstr_rpup_char[] =
381     {
382         0x11, 0x14,     /* FC_RP [alloced_on_stack] */
383         NdrFcShort( 0x2 ),      /* Offset= 2 (4) */
384         0x12, 0x8,      /* FC_UP [simple_pointer] */
385         0x2,            /* FC_CHAR */
386         0x5c,           /* FC_PAD */
387     };
388     static const unsigned char fmtstr_rpup_char2[] =
389     {
390         0x11, 0x04,     /* FC_RP [alloced_on_stack] */
391         NdrFcShort( 0x2 ),      /* Offset= 2 (4) */
392         0x12, 0x8,      /* FC_UP [simple_pointer] */
393         0x2,            /* FC_CHAR */
394         0x5c,           /* FC_PAD */
395     };
396
397     static const unsigned char fmtstr_up_wchar[] =
398     {
399         0x12, 0x8,      /* FC_UP [simple_pointer] */
400         0x5,            /* FC_WCHAR */
401         0x5c,           /* FC_PAD */
402     };
403     static const unsigned char fmtstr_up_short[] =
404     {
405         0x12, 0x8,      /* FC_UP [simple_pointer] */
406         0x6,            /* FC_SHORT */
407         0x5c,           /* FC_PAD */
408     };
409     static const unsigned char fmtstr_up_ushort[] =
410     {
411         0x12, 0x8,      /* FC_UP [simple_pointer] */
412         0x7,            /* FC_USHORT */
413         0x5c,           /* FC_PAD */
414     };
415     static const unsigned char fmtstr_up_enum16[] =
416     {
417         0x12, 0x8,      /* FC_UP [simple_pointer] */
418         0xd,            /* FC_ENUM16 */
419         0x5c,           /* FC_PAD */
420     };
421     static const unsigned char fmtstr_up_long[] =
422     {
423         0x12, 0x8,      /* FC_UP [simple_pointer] */
424         0x8,            /* FC_LONG */
425         0x5c,           /* FC_PAD */
426     };
427     static const unsigned char fmtstr_up_ulong[] =
428     {
429         0x12, 0x8,      /* FC_UP [simple_pointer] */
430         0x9,            /* FC_ULONG */
431         0x5c,           /* FC_PAD */
432     };
433     static const unsigned char fmtstr_up_enum32[] =
434     {
435         0x12, 0x8,      /* FC_UP [simple_pointer] */
436         0xe,            /* FC_ENUM32 */
437         0x5c,           /* FC_PAD */
438     };
439     static const unsigned char fmtstr_up_errorstatus[] =
440     {
441         0x12, 0x8,      /* FC_UP [simple_pointer] */
442         0x10,           /* FC_ERROR_STATUS_T */
443         0x5c,           /* FC_PAD */
444     };
445
446     static const unsigned char fmtstr_up_longlong[] =
447     {
448         0x12, 0x8,      /* FC_UP [simple_pointer] */
449         0xb,            /* FC_HYPER */
450         0x5c,           /* FC_PAD */
451     };
452     static const unsigned char fmtstr_up_float[] =
453     {
454         0x12, 0x8,      /* FC_UP [simple_pointer] */
455         0xa,            /* FC_FLOAT */
456         0x5c,           /* FC_PAD */
457     };
458     static const unsigned char fmtstr_up_double[] =
459     {
460         0x12, 0x8,      /* FC_UP [simple_pointer] */
461         0xc,            /* FC_DOUBLE */
462         0x5c,           /* FC_PAD */
463     };
464
465     ch = 0xa5;
466     ch_ptr = &ch;
467     if (use_pointer_ids)
468         *(unsigned int *)wiredata = 0x20000;
469     else
470         *(unsigned int *)wiredata = (UINT_PTR)ch_ptr;
471     wiredata[4] = ch;
472  
473     test_pointer_marshal(fmtstr_up_char, ch_ptr, 1, wiredata, 5, NULL, 0, "up_char");
474     test_pointer_marshal(fmtstr_up_byte, ch_ptr, 1, wiredata, 5, NULL, 0, "up_byte");
475     test_pointer_marshal(fmtstr_up_small, ch_ptr, 1, wiredata, 5, NULL, 0,  "up_small");
476     test_pointer_marshal(fmtstr_up_usmall, ch_ptr, 1, wiredata, 5, NULL, 0, "up_usmall");
477
478     test_pointer_marshal(fmtstr_rp_char, ch_ptr, 1, &ch, 1, NULL, 0, "rp_char");
479
480     test_pointer_marshal(fmtstr_rpup_char, &ch_ptr, 1, wiredata, 5, deref_cmp, 1, "rpup_char");
481     test_pointer_marshal(fmtstr_rpup_char2, ch_ptr, 1, wiredata, 5, NULL, 0, "rpup_char2");
482
483     s = 0xa597;
484     if (use_pointer_ids)
485         *(unsigned int *)wiredata = 0x20000;
486     else
487         *(unsigned int *)wiredata = (UINT_PTR)&s;
488     *(unsigned short*)(wiredata + 4) = s;
489
490     test_pointer_marshal(fmtstr_up_wchar, &s, 2, wiredata, 6, NULL, 0, "up_wchar");
491     test_pointer_marshal(fmtstr_up_short, &s, 2, wiredata, 6, NULL, 0, "up_short");
492     test_pointer_marshal(fmtstr_up_ushort, &s, 2, wiredata, 6, NULL, 0, "up_ushort");
493
494     i = 0x7fff;
495     if (use_pointer_ids)
496         *(unsigned int *)wiredata = 0x20000;
497     else
498         *(unsigned int *)wiredata = (UINT_PTR)&i;
499     *(unsigned short*)(wiredata + 4) = i;
500     test_pointer_marshal(fmtstr_up_enum16, &i, 4, wiredata, 6, NULL, 0, "up_enum16");
501
502     l = 0xcafebabe;
503     if (use_pointer_ids)
504         *(unsigned int *)wiredata = 0x20000;
505     else
506         *(unsigned int *)wiredata = (UINT_PTR)&l;
507     *(ULONG*)(wiredata + 4) = l;
508
509     test_pointer_marshal(fmtstr_up_long, &l, 4, wiredata, 8, NULL, 0, "up_long");
510     test_pointer_marshal(fmtstr_up_ulong, &l, 4, wiredata, 8, NULL, 0,  "up_ulong");
511     test_pointer_marshal(fmtstr_up_enum32, &l, 4, wiredata, 8, NULL, 0,  "up_emun32");
512     test_pointer_marshal(fmtstr_up_errorstatus, &l, 4, wiredata, 8, NULL, 0,  "up_errorstatus");
513
514     ll = ((ULONGLONG)0xcafebabe) << 32 | 0xdeadbeef;
515     if (use_pointer_ids)
516         *(unsigned int *)wiredata = 0x20000;
517     else
518         *(unsigned int *)wiredata = (UINT_PTR)&ll;
519     *(unsigned int *)(wiredata + 4) = 0;
520     *(ULONGLONG*)(wiredata + 8) = ll;
521     test_pointer_marshal(fmtstr_up_longlong, &ll, 8, wiredata, 16, NULL, 0, "up_longlong");
522
523     f = 3.1415f;
524     if (use_pointer_ids)
525         *(unsigned int *)wiredata = 0x20000;
526     else
527         *(unsigned int *)wiredata = (UINT_PTR)&f;
528     *(float*)(wiredata + 4) = f;
529     test_pointer_marshal(fmtstr_up_float, &f, 4, wiredata, 8, NULL, 0, "up_float");
530
531     d = 3.1415;
532     if (use_pointer_ids)
533         *(unsigned int *)wiredata = 0x20000;
534     else
535         *(unsigned int *)wiredata = (UINT_PTR)&d;
536     *(unsigned int *)(wiredata + 4) = 0;
537     *(double*)(wiredata + 8) = d;
538     test_pointer_marshal(fmtstr_up_double, &d, 8, wiredata, 16, NULL, 0,  "up_double");
539
540 }
541
542 static void test_nontrivial_pointer_types(void)
543 {
544     RPC_MESSAGE RpcMessage;
545     MIDL_STUB_MESSAGE StubMsg;
546     MIDL_STUB_DESC StubDesc;
547     DWORD size;
548     void *ptr;
549     char **p1;
550     char *p2;
551     char ch;
552     unsigned char *mem, *mem_orig;
553
554     static const unsigned char fmtstr_ref_unique_out[] =
555     {
556         0x12, 0x8,      /* FC_UP [simple_pointer] */
557         0x2,            /* FC_CHAR */
558         0x5c,           /* FC_PAD */
559         0x11, 0x14,     /* FC_RP [alloced_on_stack] [pointer_deref] */
560         NdrFcShort( 0xfffffffa ),       /* Offset= -6 (0) */
561     };
562
563     p1 = &p2;
564     p2 = &ch;
565     ch = 0x22;
566
567     StubDesc = Object_StubDesc;
568     StubDesc.pFormatTypes = fmtstr_ref_unique_out;
569
570     NdrClientInitializeNew(
571                            &RpcMessage,
572                            &StubMsg,
573                            &StubDesc,
574                            0);
575
576     StubMsg.BufferLength = 0;
577     NdrPointerBufferSize( &StubMsg,
578                           (unsigned char *)p1,
579                           &fmtstr_ref_unique_out[4] );
580
581     /* Windows overestimates the buffer size */
582     ok(StubMsg.BufferLength >= 5, "length %d\n", StubMsg.BufferLength);
583
584     /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
585     StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
586     StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
587
588     ptr = NdrPointerMarshall( &StubMsg, (unsigned char *)p1, &fmtstr_ref_unique_out[4] );
589     ok(ptr == NULL, "ret %p\n", ptr);
590     size = StubMsg.Buffer - StubMsg.BufferStart;
591     ok(size == 5, "Buffer %p Start %p len %d\n", StubMsg.Buffer, StubMsg.BufferStart, size);
592     ok(*(unsigned int *)StubMsg.BufferStart != 0, "pointer ID marshalled incorrectly\n");
593     ok(*(unsigned char *)(StubMsg.BufferStart + 4) == 0x22, "char data marshalled incorrectly: 0x%x\n",
594        *(unsigned char *)(StubMsg.BufferStart + 4));
595
596     StubMsg.Buffer = StubMsg.BufferStart;
597     StubMsg.MemorySize = 0;
598     mem = NULL;
599
600     /* Client */
601     my_alloc_called = 0;
602     StubMsg.Buffer = StubMsg.BufferStart;
603     mem = mem_orig = HeapAlloc(GetProcessHeap(), 0, sizeof(void *));
604     *(void **)mem = NULL;
605     NdrPointerUnmarshall( &StubMsg, &mem, &fmtstr_ref_unique_out[4], 0);
606     ok(mem == mem_orig, "mem alloced\n");
607     ok(my_alloc_called == 1, "alloc called %d\n", my_alloc_called);
608
609     my_alloc_called = 0;
610     StubMsg.Buffer = StubMsg.BufferStart;
611     NdrPointerUnmarshall( &StubMsg, &mem, &fmtstr_ref_unique_out[4], 1);
612     todo_wine {
613         ok(mem == mem_orig, "mem alloced\n");
614         ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
615     }
616
617     my_free_called = 0;
618     StubMsg.Buffer = StubMsg.BufferStart;
619     NdrPointerFree( &StubMsg, mem, &fmtstr_ref_unique_out[4] );
620     ok(my_free_called == 1, "free called %d\n", my_free_called);
621
622     mem = my_alloc(sizeof(void *));
623     *(void **)mem = NULL;
624     my_free_called = 0;
625     StubMsg.Buffer = StubMsg.BufferStart;
626     NdrPointerFree( &StubMsg, mem, &fmtstr_ref_unique_out[4] );
627     ok(my_free_called == 0, "free called %d\n", my_free_called);
628     my_free(mem);
629
630     mem = my_alloc(sizeof(void *));
631     *(void **)mem = my_alloc(sizeof(char));
632     my_free_called = 0;
633     StubMsg.Buffer = StubMsg.BufferStart;
634     NdrPointerFree( &StubMsg, mem, &fmtstr_ref_unique_out[4] );
635     ok(my_free_called == 1, "free called %d\n", my_free_called);
636     my_free(mem);
637
638     /* Server */
639     my_alloc_called = 0;
640     StubMsg.IsClient = 0;
641     mem = NULL;
642     StubMsg.Buffer = StubMsg.BufferStart;
643     NdrPointerUnmarshall( &StubMsg, &mem, &fmtstr_ref_unique_out[4], 0);
644     ok(mem != StubMsg.BufferStart, "mem pointing at buffer\n");
645     todo_wine
646     ok(my_alloc_called == 1, "alloc called %d\n", my_alloc_called);
647     NdrPointerFree( &StubMsg, mem, &fmtstr_ref_unique_out[4] );
648
649     my_alloc_called = 0;
650     mem = NULL;
651     StubMsg.Buffer = StubMsg.BufferStart;
652     NdrPointerUnmarshall( &StubMsg, &mem, &fmtstr_ref_unique_out[4], 1);
653     ok(mem != StubMsg.BufferStart, "mem pointing at buffer\n");
654     todo_wine
655     ok(my_alloc_called == 1, "alloc called %d\n", my_alloc_called);
656     NdrPointerFree( &StubMsg, mem, &fmtstr_ref_unique_out[4] );
657
658     my_alloc_called = 0;
659     mem = mem_orig;
660     *(void **)mem = NULL;
661     StubMsg.Buffer = StubMsg.BufferStart;
662     NdrPointerUnmarshall( &StubMsg, &mem, &fmtstr_ref_unique_out[4], 0);
663     todo_wine {
664         ok(mem == mem_orig, "mem alloced\n");
665         ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
666     }
667
668     my_alloc_called = 0;
669     mem = mem_orig;
670     *(void **)mem = NULL;
671     StubMsg.Buffer = StubMsg.BufferStart;
672     NdrPointerUnmarshall( &StubMsg, &mem, &fmtstr_ref_unique_out[4], 1);
673     todo_wine {
674         ok(mem == mem_orig, "mem alloced\n");
675         ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
676     }
677
678     mem = my_alloc(sizeof(void *));
679     *(void **)mem = NULL;
680     my_free_called = 0;
681     StubMsg.Buffer = StubMsg.BufferStart;
682     NdrPointerFree( &StubMsg, mem, &fmtstr_ref_unique_out[4] );
683     ok(my_free_called == 0, "free called %d\n", my_free_called);
684     my_free(mem);
685
686     mem = my_alloc(sizeof(void *));
687     *(void **)mem = my_alloc(sizeof(char));
688     my_free_called = 0;
689     StubMsg.Buffer = StubMsg.BufferStart;
690     NdrPointerFree( &StubMsg, mem, &fmtstr_ref_unique_out[4] );
691     ok(my_free_called == 1, "free called %d\n", my_free_called);
692     my_free(mem);
693
694     HeapFree(GetProcessHeap(), 0, mem_orig);
695     HeapFree(GetProcessHeap(), 0, StubMsg.RpcMsg->Buffer);
696 }
697
698 static void test_simple_struct_marshal(const unsigned char *formattypes,
699                                        void *memsrc, DWORD srcsize,
700                                        const void *wiredata,
701                                        ULONG wiredatalen,
702                                        int(*cmp)(const void*,const void*,size_t),
703                                        int num_additional_allocs,
704                                        const char *msgpfx)
705 {
706     RPC_MESSAGE RpcMessage;
707     MIDL_STUB_MESSAGE StubMsg;
708     MIDL_STUB_DESC StubDesc;
709     DWORD size;
710     void *ptr;
711     unsigned char *mem, *mem_orig;
712
713     my_alloc_called = my_free_called = 0;
714     if(!cmp)
715         cmp = memcmp;
716
717     StubDesc = Object_StubDesc;
718     StubDesc.pFormatTypes = formattypes;
719
720     NdrClientInitializeNew(&RpcMessage, &StubMsg, &StubDesc, 0);
721
722     StubMsg.BufferLength = 0;
723     NdrSimpleStructBufferSize( &StubMsg, memsrc, formattypes );
724     ok(StubMsg.BufferLength >= wiredatalen, "%s: length %d\n", msgpfx, StubMsg.BufferLength);
725     StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
726     StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
727     ptr = NdrSimpleStructMarshall( &StubMsg,  memsrc, formattypes );
728     ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
729     ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart);
730     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));
731
732     StubMsg.Buffer = StubMsg.BufferStart;
733     StubMsg.MemorySize = 0;
734     size = NdrSimpleStructMemorySize( &StubMsg, formattypes );
735     ok(size == StubMsg.MemorySize, "%s: size != MemorySize\n", msgpfx);
736     ok(size == srcsize, "%s: mem size %u\n", msgpfx, size);
737     ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart);
738
739     StubMsg.Buffer = StubMsg.BufferStart;
740     size = NdrSimpleStructMemorySize( &StubMsg, formattypes );
741     ok(size == StubMsg.MemorySize, "%s: size != MemorySize\n", msgpfx);
742     ok(StubMsg.MemorySize == ((srcsize + 3) & ~3) + srcsize, "%s: mem size %u\n", msgpfx, size);
743     ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart);
744     size = srcsize;
745     /*** Unmarshalling first with must_alloc false ***/
746
747     StubMsg.Buffer = StubMsg.BufferStart;
748     StubMsg.MemorySize = 0;
749     mem_orig = mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, srcsize);
750     ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, 0 );
751     ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
752     ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart);
753     ok(mem == mem_orig, "%s: mem has changed %p %p\n", msgpfx, mem, mem_orig);
754     ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx);
755     ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called); 
756     my_alloc_called = 0;
757     ok(StubMsg.MemorySize == 0, "%s: memorysize touched in unmarshal\n", msgpfx);
758
759     /* If we're a server we still use the supplied memory */
760     StubMsg.Buffer = StubMsg.BufferStart;
761     StubMsg.IsClient = 0;
762     ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, 0 );
763     ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
764     ok(mem == mem_orig, "%s: mem has changed %p %p\n", msgpfx, mem, mem_orig);
765     ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx); 
766     ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
767     my_alloc_called = 0;
768     ok(StubMsg.MemorySize == 0, "%s: memorysize touched in unmarshal\n", msgpfx);
769
770     /* ...unless we pass a NULL ptr, then the buffer is used. 
771        Passing a NULL ptr while we're a client && !must_alloc
772        crashes on Windows, so we won't do that. */
773
774     if (0)  /* crashes on Win9x and NT4 */
775     {
776         mem = NULL;
777         StubMsg.IsClient = 0;
778         StubMsg.Buffer = StubMsg.BufferStart;
779         ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, FALSE );
780         ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
781         ok(mem == StubMsg.BufferStart, "%s: mem not equal buffer\n", msgpfx);
782         ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx);
783         ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
784         my_alloc_called = 0;
785         ok(StubMsg.MemorySize == 0, "%s: memorysize touched in unmarshal\n", msgpfx);
786     }
787
788     /*** now must_alloc is true ***/
789
790     /* with must_alloc set we always allocate new memory whether or not we're
791        a server and also when passing NULL */
792     mem = mem_orig;
793     StubMsg.IsClient = 1;
794     StubMsg.Buffer = StubMsg.BufferStart;
795     ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, 1 );
796     ok(ptr == NULL, "ret %p\n", ptr);
797     ok(mem != mem_orig, "mem not changed %p %p\n", mem, mem_orig);
798     ok(!cmp(mem, memsrc, srcsize), "incorrectly unmarshaled\n");
799     ok(my_alloc_called == num_additional_allocs + 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
800     my_alloc_called = 0;
801     ok(StubMsg.MemorySize == 0, "memorysize touched in unmarshal\n");
802
803     mem = NULL;
804     StubMsg.Buffer = StubMsg.BufferStart;
805     ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, 1 );
806     ok(ptr == NULL, "ret %p\n", ptr);
807     ok(mem != mem_orig, "mem not changed %p %p\n", mem, mem_orig);
808     ok(!cmp(mem, memsrc, srcsize), "incorrectly unmarshaled\n");
809     ok(my_alloc_called == num_additional_allocs + 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
810     my_alloc_called = 0; 
811     ok(StubMsg.MemorySize == 0, "memorysize touched in unmarshal\n");
812
813     mem = mem_orig;
814     StubMsg.Buffer = StubMsg.BufferStart;
815     StubMsg.IsClient = 0;
816     StubMsg.ReuseBuffer = 1;
817     ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, 1 );
818     ok(ptr == NULL, "ret %p\n", ptr);
819     ok(mem != mem_orig, "mem not changed %p %p\n", mem, mem_orig);
820     ok(mem != StubMsg.BufferStart, "mem is buffer mem\n");
821     ok(!cmp(mem, memsrc, srcsize), "incorrectly unmarshaled\n");
822     ok(my_alloc_called == num_additional_allocs + 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
823     my_alloc_called = 0;
824     ok(StubMsg.MemorySize == 0, "memorysize touched in unmarshal\n");
825
826     mem = NULL;
827     StubMsg.Buffer = StubMsg.BufferStart;
828     StubMsg.IsClient = 0;
829     StubMsg.ReuseBuffer = 1;
830     ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, 1 );
831     ok(ptr == NULL, "ret %p\n", ptr);
832     ok(mem != StubMsg.BufferStart, "mem is buffer mem\n");
833     ok(!cmp(mem, memsrc, srcsize), "incorrectly unmarshaled\n"); 
834     ok(my_alloc_called == num_additional_allocs + 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
835     my_alloc_called = 0;
836     ok(StubMsg.MemorySize == 0, "memorysize touched in unmarshal\n");
837
838     HeapFree(GetProcessHeap(), 0, mem_orig);
839     HeapFree(GetProcessHeap(), 0, StubMsg.BufferStart);
840 }
841
842 typedef struct
843 {
844     LONG l1;
845     LONG *pl1;
846     char *pc1;
847 } ps1_t;
848
849 static int ps1_cmp(const void *s1, const void *s2, size_t num)
850 {
851     const ps1_t *p1, *p2;
852
853     p1 = s1;
854     p2 = s2;
855
856     if(p1->l1 != p2->l1)
857         return 1;
858
859     if(p1->pl1 && p2->pl1)
860     {
861         if(*p1->pl1 != *p2->pl1)
862             return 1;
863     }
864     else if(p1->pl1 || p1->pl1)
865         return 1;
866
867     if(p1->pc1 && p2->pc1)
868     {
869         if(*p1->pc1 != *p2->pc1)
870             return 1;
871     }
872     else if(p1->pc1 || p1->pc1)
873         return 1;
874
875     return 0;
876 }
877
878 static void test_simple_struct(void)
879 {
880     unsigned char wiredata[28];
881     ULONG wiredatalen;
882     LONG l;
883     char c;
884     ps1_t ps1;
885
886     static const unsigned char fmtstr_simple_struct[] =
887     {
888         0x12, 0x0,      /* FC_UP */
889         NdrFcShort( 0x2 ), /* Offset=2 */
890         0x15, 0x3,      /* FC_STRUCT [align 4] */
891         NdrFcShort( 0x18 ),      /* [size 24] */
892         0x6,            /* FC_SHORT */
893         0x2,            /* FC_CHAR */ 
894         0x38,           /* FC_ALIGNM4 */
895         0x8,            /* FC_LONG */
896         0x8,            /* FC_LONG */
897         0x39,           /* FC_ALIGNM8 */
898         0xb,            /* FC_HYPER */ 
899         0x5b,           /* FC_END */
900     };
901     struct {
902         short s;
903         char c;
904         LONG l1, l2;
905         LONGLONG ll;
906     } s1;
907
908     static const unsigned char fmtstr_pointer_struct[] =
909     { 
910         0x12, 0x0,      /* FC_UP */
911         NdrFcShort( 0x2 ), /* Offset=2 */
912 #ifdef _WIN64
913         0x1a,   /* FC_BOGUS_STRUCT */
914         0x3,    /* 3 */
915         NdrFcShort(0x18),       /* [size 24] */
916         NdrFcShort(0x0),
917         NdrFcShort(0x8),        /* Offset= 8 (266) */
918         0x08,   /* FC_LONG */
919         0x39,   /* FC_ALIGNM8 */
920         0x36,   /* FC_POINTER */
921         0x36,   /* FC_POINTER */
922         0x5c,           /* FC_PAD */
923         0x5b,           /* FC_END */
924         0x12, 0x8,      /* FC_UP [simple_pointer] */
925         0x08,   /* FC_LONG */
926         0x5c,   /* FC_PAD */
927         0x12, 0x8,      /* FC_UP [simple_pointer] */
928         0x02,   /* FC_CHAR */
929         0x5c,   /* FC_PAD */
930 #else
931         0x16, 0x3,      /* FC_PSTRUCT [align 4] */
932         NdrFcShort( 0xc ),      /* [size 12] */
933         0x4b,           /* FC_PP */
934         0x5c,           /* FC_PAD */
935         0x46,           /* FC_NO_REPEAT */
936         0x5c,           /* FC_PAD */
937         NdrFcShort( 0x4 ),      /* 4 */
938         NdrFcShort( 0x4 ),      /* 4 */
939         0x13, 0x8,      /* FC_OP [simple_pointer] */
940         0x8,            /* FC_LONG */
941         0x5c,           /* FC_PAD */
942         0x46,           /* FC_NO_REPEAT */
943         0x5c,           /* FC_PAD */
944         NdrFcShort( 0x8 ),      /* 8 */
945         NdrFcShort( 0x8 ),      /* 8 */
946         0x13, 0x8,      /* FC_OP [simple_pointer] */
947         0x2,            /* FC_CHAR */
948         0x5c,           /* FC_PAD */
949         0x5b,           /* FC_END */
950         0x8,            /* FC_LONG */
951         0x8,            /* FC_LONG */
952         0x8,            /* FC_LONG */
953         0x5c,           /* FC_PAD */
954         0x5b,           /* FC_END */
955 #endif
956     };
957
958     /* zero the entire structure, including the holes */
959     memset(&s1, 0, sizeof(s1));
960
961     /* FC_STRUCT */
962     s1.s = 0x1234;
963     s1.c = 0xa5;
964     s1.l1 = 0xdeadbeef;
965     s1.l2 = 0xcafebabe;
966     s1.ll = ((LONGLONG) 0xbadefeed << 32) | 0x2468ace0;
967
968     wiredatalen = 24;
969     memcpy(wiredata, &s1, wiredatalen); 
970     test_simple_struct_marshal(fmtstr_simple_struct + 4, &s1, 24, wiredata, 24, NULL, 0, "struct");
971
972     if (use_pointer_ids)
973         *(unsigned int *)wiredata = 0x20000;
974     else
975         *(unsigned int *)wiredata = (UINT_PTR)&s1;
976     memcpy(wiredata + 4, &s1, wiredatalen);
977     test_pointer_marshal(fmtstr_simple_struct, &s1, 24, wiredata, 28, NULL, 0, "struct");
978
979     if (sizeof(void *) == 8) return;  /* it cannot be represented as a simple struct on Win64 */
980
981     /* zero the entire structure, including the hole */
982     memset(&ps1, 0, sizeof(ps1));
983
984     /* FC_PSTRUCT */
985     ps1.l1 = 0xdeadbeef;
986     l = 0xcafebabe;
987     ps1.pl1 = &l;
988     c = 'a';
989     ps1.pc1 = &c;
990     *(unsigned int *)(wiredata + 4) = 0xdeadbeef;
991     if (use_pointer_ids)
992     {
993         *(unsigned int *)(wiredata + 8) = 0x20000;
994         *(unsigned int *)(wiredata + 12) = 0x20004;
995     }
996     else
997     {
998         *(unsigned int *)(wiredata + 8) = (UINT_PTR)&l;
999         *(unsigned int *)(wiredata + 12) = (UINT_PTR)&c;
1000     }
1001     memcpy(wiredata + 16, &l, 4);
1002     memcpy(wiredata + 20, &c, 1);
1003
1004     test_simple_struct_marshal(fmtstr_pointer_struct + 4, &ps1, 17, wiredata + 4, 17, ps1_cmp, 2, "pointer_struct");
1005     if (use_pointer_ids)
1006     {
1007         *(unsigned int *)wiredata = 0x20000;
1008         *(unsigned int *)(wiredata + 8) = 0x20004;
1009         *(unsigned int *)(wiredata + 12) = 0x20008;
1010     }
1011     else
1012         *(unsigned int *)wiredata = (UINT_PTR)&ps1;
1013     test_pointer_marshal(fmtstr_pointer_struct, &ps1, 17, wiredata, 21, ps1_cmp, 2, "pointer_struct");
1014 }
1015
1016 static void test_fullpointer_xlat(void)
1017 {
1018     PFULL_PTR_XLAT_TABLES pXlatTables;
1019     ULONG RefId;
1020     int ret;
1021     void *Pointer;
1022
1023     pXlatTables = NdrFullPointerXlatInit(2, XLAT_CLIENT);
1024
1025     /* "marshaling" phase */
1026
1027     ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebeef, 1, &RefId);
1028     ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1029     ok(RefId == 0x1, "RefId should be 0x1 instead of 0x%x\n", RefId);
1030
1031     ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebeef, 0, &RefId);
1032     ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1033     ok(RefId == 0x1, "RefId should be 0x1 instead of 0x%x\n", RefId);
1034
1035     ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebabe, 0, &RefId);
1036     ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1037     ok(RefId == 0x2, "RefId should be 0x2 instead of 0x%x\n", RefId);
1038
1039     ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xdeadbeef, 0, &RefId);
1040     ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1041     ok(RefId == 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId);
1042
1043     ret = NdrFullPointerQueryPointer(pXlatTables, NULL, 0, &RefId);
1044     ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1045     ok(RefId == 0, "RefId should be 0 instead of 0x%x\n", RefId);
1046
1047     /* "unmarshaling" phase */
1048
1049     ret = NdrFullPointerQueryRefId(pXlatTables, 0x0, 0, &Pointer);
1050     ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1051
1052     ret = NdrFullPointerQueryRefId(pXlatTables, 0x2, 0, &Pointer);
1053     ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1054     ok(Pointer == (void *)0xcafebabe, "Pointer should be 0xcafebabe instead of %p\n", Pointer);
1055
1056     ret = NdrFullPointerQueryRefId(pXlatTables, 0x4, 0, &Pointer);
1057     ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1058     ok(Pointer == NULL, "Pointer should be NULL instead of %p\n", Pointer);
1059
1060     NdrFullPointerInsertRefId(pXlatTables, 0x4, (void *)0xdeadbabe);
1061
1062     ret = NdrFullPointerQueryRefId(pXlatTables, 0x4, 1, &Pointer);
1063     ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1064     ok(Pointer == (void *)0xdeadbabe, "Pointer should be (void *)0xdeadbabe instead of %p\n", Pointer);
1065
1066     NdrFullPointerXlatFree(pXlatTables);
1067
1068     pXlatTables = NdrFullPointerXlatInit(2, XLAT_SERVER);
1069
1070     /* "unmarshaling" phase */
1071
1072     ret = NdrFullPointerQueryRefId(pXlatTables, 0x2, 1, &Pointer);
1073     ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1074     ok(Pointer == NULL, "Pointer should be NULL instead of %p\n", Pointer);
1075
1076     NdrFullPointerInsertRefId(pXlatTables, 0x2, (void *)0xcafebabe);
1077
1078     ret = NdrFullPointerQueryRefId(pXlatTables, 0x2, 0, &Pointer);
1079     ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1080     ok(Pointer == (void *)0xcafebabe, "Pointer should be (void *)0xcafebabe instead of %p\n", Pointer);
1081
1082     ret = NdrFullPointerQueryRefId(pXlatTables, 0x2, 1, &Pointer);
1083     ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1084     ok(Pointer == (void *)0xcafebabe, "Pointer should be (void *)0xcafebabe instead of %p\n", Pointer);
1085
1086     /* "marshaling" phase */
1087
1088     ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebeef, 1, &RefId);
1089     ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1090     ok(RefId == 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId);
1091
1092     ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebeef, 1, &RefId);
1093     ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1094     ok(RefId == 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId);
1095
1096     ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebeef, 0, &RefId);
1097     ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1098     ok(RefId == 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId);
1099
1100     ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebabe, 0, &RefId);
1101     ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1102     ok(RefId == 0x2, "RefId should be 0x2 instead of 0x%x\n", RefId);
1103
1104     ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xdeadbeef, 0, &RefId);
1105     ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1106     ok(RefId == 0x4, "RefId should be 0x4 instead of 0x%x\n", RefId);
1107
1108     /* "freeing" phase */
1109
1110     ret = NdrFullPointerFree(pXlatTables, (void *)0xcafebeef);
1111     ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1112
1113     ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebeef, 0x20, &RefId);
1114     ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1115     ok(RefId == 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId);
1116
1117     ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebeef, 1, &RefId);
1118     ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1119     ok(RefId == 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId);
1120
1121     ret = NdrFullPointerFree(pXlatTables, (void *)0xcafebabe);
1122     ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1123
1124     ret = NdrFullPointerFree(pXlatTables, (void *)0xdeadbeef);
1125     ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1126
1127     ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xdeadbeef, 0x20, &RefId);
1128     ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1129     ok(RefId == 0x4, "RefId should be 0x4 instead of 0x%x\n", RefId);
1130
1131     ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xdeadbeef, 1, &RefId);
1132     ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1133     ok(RefId == 0x4, "RefId should be 0x4 instead of 0x%x\n", RefId);
1134
1135     ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xdeadbeef, 1, &RefId);
1136     ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1137     ok(RefId == 0x4, "RefId should be 0x4 instead of 0x%x\n", RefId);
1138
1139     ret = NdrFullPointerFree(pXlatTables, (void *)0xdeadbeef);
1140     ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1141
1142     NdrFullPointerXlatFree(pXlatTables);
1143 }
1144
1145 /* verify stub data that is identical between client and server */
1146 static void test_common_stub_data( const char *prefix, const MIDL_STUB_MESSAGE *stubMsg )
1147 {
1148     void *unset_ptr;
1149
1150     memset(&unset_ptr, 0xcc, sizeof(unset_ptr));
1151
1152 #define TEST_ZERO(field, fmt) ok(stubMsg->field == 0, "%s: " #field " should have been set to zero instead of " fmt "\n", prefix, stubMsg->field)
1153 #define TEST_POINTER_UNSET(field) ok(stubMsg->field == unset_ptr, "%s: " #field " should have been unset instead of %p\n", prefix, stubMsg->field)
1154 #define TEST_ULONG_UNSET(field) ok(stubMsg->field == 0xcccccccc, "%s: " #field " should have been unset instead of 0x%x\n", prefix, stubMsg->field)
1155 #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)
1156
1157     TEST_POINTER_UNSET(BufferMark);
1158     TEST_ULONG_UNSET(MemorySize);
1159     TEST_POINTER_UNSET(Memory);
1160     TEST_ZERO(pAllocAllNodesContext, "%p");
1161     ok(stubMsg->pPointerQueueState == 0 ||
1162        broken(stubMsg->pPointerQueueState == unset_ptr), /* win2k */
1163        "%s: pPointerQueueState should have been unset instead of %p\n",
1164        prefix, stubMsg->pPointerQueueState);
1165     TEST_ZERO(IgnoreEmbeddedPointers, "%d");
1166     TEST_ZERO(PointerBufferMark, "%p");
1167     ok( stubMsg->uFlags == 0 ||
1168         broken(stubMsg->uFlags == 0xcc), /* win9x */
1169         "%s: uFlags should have been set to zero instead of 0x%x\n", prefix, stubMsg->uFlags );
1170     /* FIXME: UniquePtrCount */
1171     TEST_ULONG_PTR_UNSET(MaxCount);
1172     TEST_ULONG_UNSET(Offset);
1173     TEST_ULONG_UNSET(ActualCount);
1174     ok(stubMsg->pfnAllocate == my_alloc, "%s: pfnAllocate should have been %p instead of %p\n",
1175        prefix, my_alloc, stubMsg->pfnAllocate);
1176     ok(stubMsg->pfnFree == my_free, "%s: pfnFree should have been %p instead of %p\n",
1177        prefix, my_free, stubMsg->pfnFree);
1178     TEST_ZERO(StackTop, "%p");
1179     TEST_POINTER_UNSET(pPresentedType);
1180     TEST_POINTER_UNSET(pTransmitType);
1181     TEST_POINTER_UNSET(SavedHandle);
1182     ok(stubMsg->StubDesc == &Object_StubDesc, "%s: StubDesc should have been %p instead of %p\n",
1183        prefix, &Object_StubDesc, stubMsg->StubDesc);
1184     TEST_ZERO(FullPtrRefId, "%d");
1185     ok( stubMsg->PointerLength == 0 ||
1186         broken(stubMsg->PointerLength == 1), /* win9x, nt4 */
1187         "%s: pAsyncMsg should have been set to zero instead of %d\n", prefix, stubMsg->PointerLength );
1188     TEST_ZERO(fInDontFree, "%d");
1189     TEST_ZERO(fDontCallFreeInst, "%d");
1190     ok( stubMsg->fHasReturn == 0 || broken(stubMsg->fHasReturn), /* win9x, nt4 */
1191         "%s: fHasReturn should have been set to zero instead of %d\n", prefix, stubMsg->fHasReturn );
1192     TEST_ZERO(fHasExtensions, "%d");
1193     TEST_ZERO(fHasNewCorrDesc, "%d");
1194     ok(stubMsg->fIsIn == 0 || broken(stubMsg->fIsIn), /* win9x, nt4 */
1195        "%s: fIsIn should have been set to 0 instead of %d\n", prefix, stubMsg->fIsIn);
1196     TEST_ZERO(fIsOicf, "%d");
1197     ok(stubMsg->fBufferValid == 0,
1198        "%s: fBufferValid should have been set to 0 instead of %d\n", prefix, stubMsg->fBufferValid);
1199     TEST_ZERO(fNeedMCCP, "%d");
1200     ok(stubMsg->fUnused == 0 ||
1201        stubMsg->fUnused == -2, /* Vista */
1202        "%s: fUnused should have been set to 0 or -2 instead of %d\n", prefix, stubMsg->fUnused);
1203     ok(stubMsg->fUnused2 == 0xffffcccc, "%s: fUnused2 should have been 0xffffcccc instead of 0x%x\n",
1204        prefix, stubMsg->fUnused2);
1205     ok(stubMsg->dwDestContext == MSHCTX_DIFFERENTMACHINE,
1206        "%s: dwDestContext should have been MSHCTX_DIFFERENTMACHINE instead of %d\n",
1207        prefix, stubMsg->dwDestContext);
1208     TEST_ZERO(pvDestContext, "%p");
1209     TEST_POINTER_UNSET(SavedContextHandles);
1210     TEST_ULONG_UNSET(ParamNumber);
1211     TEST_ZERO(pRpcChannelBuffer, "%p");
1212     TEST_ZERO(pArrayInfo, "%p");
1213     TEST_POINTER_UNSET(SizePtrCountArray);
1214     TEST_POINTER_UNSET(SizePtrOffsetArray);
1215     TEST_POINTER_UNSET(SizePtrLengthArray);
1216     TEST_POINTER_UNSET(pArgQueue);
1217     TEST_ZERO(dwStubPhase, "%d");
1218     /* FIXME: where does this value come from? */
1219     trace("%s: LowStackMark is %p\n", prefix, stubMsg->LowStackMark);
1220     ok( stubMsg->pAsyncMsg == 0 || broken(stubMsg->pAsyncMsg == unset_ptr), /* win9x, nt4 */
1221         "%s: pAsyncMsg should have been set to zero instead of %p\n", prefix, stubMsg->pAsyncMsg );
1222     ok( stubMsg->pCorrInfo == 0 || broken(stubMsg->pCorrInfo == unset_ptr), /* win9x, nt4 */
1223         "%s: pCorrInfo should have been set to zero instead of %p\n", prefix, stubMsg->pCorrInfo );
1224     ok( stubMsg->pCorrMemory == 0 || broken(stubMsg->pCorrMemory == unset_ptr), /* win9x, nt4 */
1225         "%s: pCorrMemory should have been set to zero instead of %p\n", prefix, stubMsg->pCorrMemory );
1226     ok( stubMsg->pMemoryList == 0 || broken(stubMsg->pMemoryList == unset_ptr), /* win9x, nt4 */
1227         "%s: pMemoryList should have been set to zero instead of %p\n", prefix, stubMsg->pMemoryList );
1228     TEST_POINTER_UNSET(pCSInfo);
1229     TEST_POINTER_UNSET(ConformanceMark);
1230     TEST_POINTER_UNSET(VarianceMark);
1231     ok(stubMsg->Unused == (ULONG_PTR)unset_ptr, "%s: Unused should have be unset instead of 0x%lx\n",
1232        prefix, stubMsg->Unused);
1233     TEST_POINTER_UNSET(pContext);
1234     TEST_POINTER_UNSET(ContextHandleHash);
1235     TEST_POINTER_UNSET(pUserMarshalList);
1236     TEST_ULONG_PTR_UNSET(Reserved51_3);
1237     TEST_ULONG_PTR_UNSET(Reserved51_4);
1238     TEST_ULONG_PTR_UNSET(Reserved51_5);
1239
1240 #undef TEST_ULONG_PTR_UNSET
1241 #undef TEST_ULONG_UNSET
1242 #undef TEST_POINTER_UNSET
1243 #undef TEST_ZERO
1244 }
1245
1246 static void test_client_init(void)
1247 {
1248     MIDL_STUB_MESSAGE stubMsg;
1249     RPC_MESSAGE rpcMsg;
1250     void *unset_ptr;
1251
1252     memset(&rpcMsg, 0xcc, sizeof(rpcMsg));
1253     memset(&stubMsg, 0xcc, sizeof(stubMsg));
1254     memset(&unset_ptr, 0xcc, sizeof(unset_ptr));
1255
1256     NdrClientInitializeNew(&rpcMsg, &stubMsg, &Object_StubDesc, 1);
1257
1258     test_common_stub_data( "NdrClientInitializeNew", &stubMsg );
1259
1260     ok(stubMsg.RpcMsg == &rpcMsg, "stubMsg.RpcMsg should have been %p instead of %p\n", &rpcMsg, stubMsg.RpcMsg);
1261     ok(rpcMsg.Handle == NULL, "rpcMsg.Handle should have been NULL instead of %p\n", rpcMsg.Handle);
1262     ok(rpcMsg.Buffer == unset_ptr, "rpcMsg.Buffer should have been unset instead of %p\n",
1263        rpcMsg.Buffer);
1264     ok(rpcMsg.BufferLength == 0xcccccccc, "rpcMsg.BufferLength should have been unset instead of %d\n", rpcMsg.BufferLength);
1265     ok(rpcMsg.ProcNum == 0x8001, "rpcMsg.ProcNum should have been 0x8001 instead of 0x%x\n", rpcMsg.ProcNum);
1266     ok(rpcMsg.TransferSyntax == unset_ptr, "rpcMsg.TransferSyntax should have been unset instead of %p\n", rpcMsg.TransferSyntax);
1267     ok(rpcMsg.RpcInterfaceInformation == Object_StubDesc.RpcInterfaceInformation,
1268         "rpcMsg.RpcInterfaceInformation should have been %p instead of %p\n",
1269         Object_StubDesc.RpcInterfaceInformation, rpcMsg.RpcInterfaceInformation);
1270     /* Note: ReservedForRuntime not tested */
1271     ok(rpcMsg.ManagerEpv == unset_ptr, "rpcMsg.ManagerEpv should have been unset instead of %p\n", rpcMsg.ManagerEpv);
1272     ok(rpcMsg.ImportContext == unset_ptr, "rpcMsg.ImportContext should have been unset instead of %p\n", rpcMsg.ImportContext);
1273     ok(rpcMsg.RpcFlags == 0, "rpcMsg.RpcFlags should have been 0 instead of 0x%x\n", rpcMsg.RpcFlags);
1274
1275     ok(stubMsg.Buffer == unset_ptr, "stubMsg.Buffer should have been unset instead of %p\n",
1276        stubMsg.Buffer);
1277     ok(stubMsg.BufferStart == NULL, "stubMsg.BufferStart should have been NULL instead of %p\n",
1278        stubMsg.BufferStart);
1279     ok(stubMsg.BufferEnd == NULL, "stubMsg.BufferEnd should have been NULL instead of %p\n",
1280        stubMsg.BufferEnd);
1281     ok(stubMsg.BufferLength == 0, "stubMsg.BufferLength should have been 0 instead of %u\n",
1282        stubMsg.BufferLength);
1283     ok(stubMsg.IsClient == 1, "stubMsg.IsClient should have been 1 instead of %u\n", stubMsg.IsClient);
1284     ok(stubMsg.ReuseBuffer == 0, "stubMsg.ReuseBuffer should have been 0 instead of %d\n",
1285        stubMsg.ReuseBuffer);
1286     ok(stubMsg.CorrDespIncrement == 0, "stubMsg.CorrDespIncrement should have been 0 instead of %d\n",
1287        stubMsg.CorrDespIncrement);
1288     ok(stubMsg.FullPtrXlatTables == unset_ptr, "stubMsg.FullPtrXlatTables should have been unset instead of %p\n",
1289        stubMsg.FullPtrXlatTables);
1290 }
1291
1292 static void test_server_init(void)
1293 {
1294     MIDL_STUB_MESSAGE stubMsg;
1295     RPC_MESSAGE rpcMsg;
1296     unsigned char *ret;
1297     unsigned char buffer[256];
1298
1299     memset(&rpcMsg, 0, sizeof(rpcMsg));
1300     rpcMsg.Buffer = buffer;
1301     rpcMsg.BufferLength = sizeof(buffer);
1302     rpcMsg.RpcFlags = RPC_BUFFER_COMPLETE;
1303
1304     memset(&stubMsg, 0xcc, sizeof(stubMsg));
1305
1306     ret = NdrServerInitializeNew(&rpcMsg, &stubMsg, &Object_StubDesc);
1307     ok(ret == NULL, "NdrServerInitializeNew should have returned NULL instead of %p\n", ret);
1308
1309     test_common_stub_data( "NdrServerInitializeNew", &stubMsg );
1310
1311     ok(stubMsg.RpcMsg == &rpcMsg, "stubMsg.RpcMsg should have been %p instead of %p\n", &rpcMsg, stubMsg.RpcMsg);
1312     ok(stubMsg.Buffer == buffer, "stubMsg.Buffer should have been %p instead of %p\n", buffer, stubMsg.Buffer);
1313     ok(stubMsg.BufferStart == buffer, "stubMsg.BufferStart should have been %p instead of %p\n", buffer, stubMsg.BufferStart);
1314     ok(stubMsg.BufferEnd == buffer + sizeof(buffer), "stubMsg.BufferEnd should have been %p instead of %p\n", buffer + sizeof(buffer), stubMsg.BufferEnd);
1315 todo_wine
1316     ok(stubMsg.BufferLength == 0, "stubMsg.BufferLength should have been 0 instead of %u\n", stubMsg.BufferLength);
1317     ok(stubMsg.IsClient == 0, "stubMsg.IsClient should have been 0 instead of %u\n", stubMsg.IsClient);
1318     ok(stubMsg.ReuseBuffer == 0 ||
1319        broken(stubMsg.ReuseBuffer == 1), /* win2k */
1320        "stubMsg.ReuseBuffer should have been set to zero instead of %d\n", stubMsg.ReuseBuffer);
1321     ok(stubMsg.CorrDespIncrement == 0xcc ||
1322        stubMsg.CorrDespIncrement == 0,
1323        "CorrDespIncrement should have been unset instead of 0x%x\n", stubMsg.CorrDespIncrement);
1324     ok(stubMsg.FullPtrXlatTables == 0, "stubMsg.BufferLength should have been 0 instead of %p\n", stubMsg.FullPtrXlatTables);
1325 }
1326
1327 static void test_ndr_allocate(void)
1328 {
1329     RPC_MESSAGE RpcMessage;
1330     MIDL_STUB_MESSAGE StubMsg;
1331     MIDL_STUB_DESC StubDesc;
1332     void *p1, *p2;
1333     struct tag_mem_list_v2_t
1334     {
1335         DWORD magic;
1336         DWORD size;
1337         DWORD unknown;
1338         struct tag_mem_list_v2_t *next;
1339     } *mem_list_v2;
1340     const DWORD magic_MEML = 'M' << 24 | 'E' << 16 | 'M' << 8 | 'L';
1341
1342     StubDesc = Object_StubDesc;
1343     NdrClientInitializeNew(&RpcMessage, &StubMsg, &StubDesc, 0);
1344
1345     my_alloc_called = my_free_called = 0;
1346     p1 = NdrAllocate(&StubMsg, 10);
1347     p2 = NdrAllocate(&StubMsg, 24);
1348     ok(my_alloc_called == 2, "alloc called %d\n", my_alloc_called);
1349     ok(StubMsg.pMemoryList != NULL, "StubMsg.pMemoryList NULL\n");
1350     if(StubMsg.pMemoryList)
1351     {
1352         mem_list_v2 = StubMsg.pMemoryList;
1353         if (mem_list_v2->size == 24)
1354         {
1355             trace("v2 mem list format\n");
1356             ok((char *)mem_list_v2 == (char *)p2 + 24, "expected mem_list_v2 pointer %p, but got %p\n", (char *)p2 + 24, mem_list_v2);
1357             ok(mem_list_v2->magic == magic_MEML, "magic %08x\n", mem_list_v2->magic);
1358             ok(mem_list_v2->size == 24, "wrong size for p2 %d\n", mem_list_v2->size);
1359             ok(mem_list_v2->unknown == 0, "wrong unknown for p2 0x%x\n", mem_list_v2->unknown);
1360             ok(mem_list_v2->next != NULL, "next NULL\n");
1361             mem_list_v2 = mem_list_v2->next;
1362             if(mem_list_v2)
1363             {
1364                 ok((char *)mem_list_v2 == (char *)p1 + 16, "expected mem_list_v2 pointer %p, but got %p\n", (char *)p1 + 16, mem_list_v2);
1365                 ok(mem_list_v2->magic == magic_MEML, "magic %08x\n", mem_list_v2->magic);
1366                 ok(mem_list_v2->size == 16, "wrong size for p1 %d\n", mem_list_v2->size);
1367                 ok(mem_list_v2->unknown == 0, "wrong unknown for p1 0x%x\n", mem_list_v2->unknown);
1368                 ok(mem_list_v2->next == NULL, "next %p\n", mem_list_v2->next);
1369             }
1370         }
1371         else win_skip("v1 mem list format\n");
1372     }
1373     /* NdrFree isn't exported so we can't test free'ing */
1374 }
1375
1376 static void test_conformant_array(void)
1377 {
1378     RPC_MESSAGE RpcMessage;
1379     MIDL_STUB_MESSAGE StubMsg;
1380     MIDL_STUB_DESC StubDesc;
1381     void *ptr;
1382     unsigned char *mem, *mem_orig;
1383     unsigned char memsrc[20];
1384     unsigned int i;
1385
1386     static const unsigned char fmtstr_conf_array[] =
1387     {
1388         0x1b,              /* FC_CARRAY */
1389         0x0,               /* align */
1390         NdrFcShort( 0x1 ), /* elem size */
1391         0x40,              /* Corr desc:  const */
1392         0x0,
1393         NdrFcShort(0x10),  /* const = 0x10 */
1394         0x1,               /* FC_BYTE */
1395         0x5b               /* FC_END */
1396     };
1397
1398     for (i = 0; i < sizeof(memsrc); i++)
1399         memsrc[i] = i * i;
1400
1401     StubDesc = Object_StubDesc;
1402     StubDesc.pFormatTypes = fmtstr_conf_array;
1403
1404     NdrClientInitializeNew(
1405                            &RpcMessage,
1406                            &StubMsg,
1407                            &StubDesc,
1408                            0);
1409
1410     StubMsg.BufferLength = 0;
1411     NdrConformantArrayBufferSize( &StubMsg,
1412                           memsrc,
1413                           fmtstr_conf_array );
1414     ok(StubMsg.BufferLength >= 20, "length %d\n", StubMsg.BufferLength);
1415
1416     /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
1417     StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
1418     StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
1419
1420     ptr = NdrConformantArrayMarshall( &StubMsg,  memsrc, fmtstr_conf_array );
1421     ok(ptr == NULL, "ret %p\n", ptr);
1422     ok(StubMsg.Buffer - StubMsg.BufferStart == 20, "Buffer %p Start %p len %d\n", StubMsg.Buffer, StubMsg.BufferStart, 20);
1423     ok(!memcmp(StubMsg.BufferStart + 4, memsrc, 16), "incorrectly marshaled\n");
1424
1425     StubMsg.Buffer = StubMsg.BufferStart;
1426     StubMsg.MemorySize = 0;
1427     mem = NULL;
1428
1429     /* Client */
1430     my_alloc_called = 0;
1431     /* passing mem == NULL with must_alloc == 0 crashes under Windows */
1432     NdrConformantArrayUnmarshall( &StubMsg, &mem, fmtstr_conf_array, 1);
1433     ok(mem != NULL, "mem not alloced\n");
1434     ok(mem != StubMsg.BufferStart + 4, "mem pointing at buffer\n");
1435     ok(my_alloc_called == 1, "alloc called %d\n", my_alloc_called);
1436
1437     my_alloc_called = 0;
1438     StubMsg.Buffer = StubMsg.BufferStart;
1439     mem_orig = mem;
1440     NdrConformantArrayUnmarshall( &StubMsg, &mem, fmtstr_conf_array, 0);
1441     ok(mem == mem_orig, "mem alloced\n");
1442     ok(mem != StubMsg.BufferStart + 4, "mem pointing at buffer\n");
1443     ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
1444
1445     my_alloc_called = 0;
1446     StubMsg.Buffer = StubMsg.BufferStart;
1447     NdrConformantArrayUnmarshall( &StubMsg, &mem, fmtstr_conf_array, 1);
1448     ok(mem != mem_orig, "mem not alloced\n");
1449     ok(mem != StubMsg.BufferStart + 4, "mem pointing at buffer\n");
1450     ok(my_alloc_called == 1, "alloc called %d\n", my_alloc_called);
1451
1452     my_free_called = 0;
1453     StubMsg.Buffer = StubMsg.BufferStart;
1454     NdrConformantArrayFree( &StubMsg, mem, fmtstr_conf_array );
1455     ok(my_free_called == 0, "free called %d\n", my_free_called);
1456     StubMsg.pfnFree(mem);
1457
1458     /* Server */
1459     my_alloc_called = 0;
1460     StubMsg.IsClient = 0;
1461     mem = NULL;
1462     StubMsg.Buffer = StubMsg.BufferStart;
1463     NdrConformantArrayUnmarshall( &StubMsg, &mem, fmtstr_conf_array, 0);
1464     ok(mem == StubMsg.BufferStart + 4 || broken(!mem),  /* win9x, nt4 */
1465        "mem not pointing at buffer %p/%p\n", mem, StubMsg.BufferStart + 4);
1466     ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
1467     my_alloc_called = 0;
1468     mem = NULL;
1469     StubMsg.Buffer = StubMsg.BufferStart;
1470     NdrConformantArrayUnmarshall( &StubMsg, &mem, fmtstr_conf_array, 1);
1471     ok(mem != StubMsg.BufferStart + 4, "mem pointing at buffer\n");
1472     ok(my_alloc_called == 1, "alloc called %d\n", my_alloc_called);
1473     StubMsg.pfnFree(mem);
1474
1475     my_alloc_called = 0;
1476     mem = mem_orig;
1477     StubMsg.Buffer = StubMsg.BufferStart;
1478     NdrConformantArrayUnmarshall( &StubMsg, &mem, fmtstr_conf_array, 0);
1479     ok(mem == mem_orig, "mem alloced\n");
1480     ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
1481
1482     my_alloc_called = 0;
1483     mem = mem_orig;
1484     StubMsg.Buffer = StubMsg.BufferStart;
1485     NdrConformantArrayUnmarshall( &StubMsg, &mem, fmtstr_conf_array, 1);
1486     ok(mem != StubMsg.BufferStart + 4, "mem pointing at buffer\n");
1487     ok(my_alloc_called == 1, "alloc called %d\n", my_alloc_called);
1488     StubMsg.pfnFree(mem);
1489     StubMsg.pfnFree(mem_orig);
1490
1491     HeapFree(GetProcessHeap(), 0, StubMsg.RpcMsg->Buffer);
1492 }
1493
1494 static void test_conformant_string(void)
1495 {
1496     RPC_MESSAGE RpcMessage;
1497     MIDL_STUB_MESSAGE StubMsg;
1498     MIDL_STUB_DESC StubDesc;
1499     DWORD size;
1500     void *ptr;
1501     unsigned char *mem, *mem_orig;
1502     char memsrc[] = "This is a test string";
1503
1504     static const unsigned char fmtstr_conf_str[] =
1505     {
1506                         0x11, 0x8,      /* FC_RP [simple_pointer] */
1507                         0x22,           /* FC_C_CSTRING */
1508                         0x5c,           /* FC_PAD */
1509     };
1510
1511     StubDesc = Object_StubDesc;
1512     StubDesc.pFormatTypes = fmtstr_conf_str;
1513
1514     memset( &StubMsg, 0, sizeof(StubMsg) );  /* needed on win9x and nt4 */
1515     NdrClientInitializeNew(
1516                            &RpcMessage,
1517                            &StubMsg,
1518                            &StubDesc,
1519                            0);
1520
1521     StubMsg.BufferLength = 0;
1522     NdrPointerBufferSize( &StubMsg,
1523                           (unsigned char *)memsrc,
1524                           fmtstr_conf_str );
1525     ok(StubMsg.BufferLength >= sizeof(memsrc) + 12, "length %d\n", StubMsg.BufferLength);
1526
1527     /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
1528     StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
1529     StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
1530
1531     ptr = NdrPointerMarshall( &StubMsg, (unsigned char *)memsrc, fmtstr_conf_str );
1532     ok(ptr == NULL, "ret %p\n", ptr);
1533     size = StubMsg.Buffer - StubMsg.BufferStart;
1534     ok(size == sizeof(memsrc) + 12, "Buffer %p Start %p len %d\n",
1535        StubMsg.Buffer, StubMsg.BufferStart, size);
1536     ok(!memcmp(StubMsg.BufferStart + 12, memsrc, sizeof(memsrc)), "incorrectly marshaled\n");
1537
1538     StubMsg.Buffer = StubMsg.BufferStart;
1539     StubMsg.MemorySize = 0;
1540     mem = NULL;
1541
1542     /* Client */
1543     my_alloc_called = 0;
1544     StubMsg.Buffer = StubMsg.BufferStart;
1545     mem = mem_orig = HeapAlloc(GetProcessHeap(), 0, sizeof(memsrc));
1546     NdrPointerUnmarshall( &StubMsg, &mem, fmtstr_conf_str, 0);
1547     ok(mem == mem_orig, "mem not alloced\n");
1548     ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
1549
1550     my_alloc_called = 0;
1551     StubMsg.Buffer = StubMsg.BufferStart;
1552     NdrPointerUnmarshall( &StubMsg, &mem, fmtstr_conf_str, 1);
1553 todo_wine {
1554     ok(mem == mem_orig, "mem not alloced\n");
1555     ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
1556 }
1557
1558     my_free_called = 0;
1559     StubMsg.Buffer = StubMsg.BufferStart;
1560     NdrPointerFree( &StubMsg, mem, fmtstr_conf_str );
1561     ok(my_free_called == 1, "free called %d\n", my_free_called);
1562
1563     mem = my_alloc(10);
1564     my_free_called = 0;
1565     StubMsg.Buffer = StubMsg.BufferStart;
1566     NdrPointerFree( &StubMsg, mem, fmtstr_conf_str );
1567     ok(my_free_called == 1, "free called %d\n", my_free_called);
1568
1569     /* Server */
1570     my_alloc_called = 0;
1571     StubMsg.IsClient = 0;
1572     mem = NULL;
1573     StubMsg.Buffer = StubMsg.BufferStart;
1574     NdrPointerUnmarshall( &StubMsg, &mem, fmtstr_conf_str, 0);
1575     ok(mem == StubMsg.BufferStart + 12 || broken(!mem), /* win9x, nt4 */
1576        "mem not pointing at buffer %p/%p\n", mem, StubMsg.BufferStart + 12 );
1577     ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
1578
1579     my_alloc_called = 0;
1580     mem = NULL;
1581     StubMsg.Buffer = StubMsg.BufferStart;
1582     NdrPointerUnmarshall( &StubMsg, &mem, fmtstr_conf_str, 1);
1583 todo_wine {
1584     ok(mem == StubMsg.BufferStart + 12 || broken(!mem), /* win9x, nt4 */
1585        "mem not pointing at buffer %p/%p\n", mem, StubMsg.BufferStart + 12 );
1586     ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
1587 }
1588
1589     my_alloc_called = 0;
1590     mem = mem_orig = HeapAlloc(GetProcessHeap(), 0, sizeof(memsrc));
1591     StubMsg.Buffer = StubMsg.BufferStart;
1592     NdrPointerUnmarshall( &StubMsg, &mem, fmtstr_conf_str, 0);
1593     ok(mem == StubMsg.BufferStart + 12 || broken(!mem), /* win9x, nt4 */
1594        "mem not pointing at buffer %p/%p\n", mem, StubMsg.BufferStart + 12 );
1595     ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
1596
1597     my_alloc_called = 0;
1598     mem = mem_orig;
1599     StubMsg.Buffer = StubMsg.BufferStart;
1600     NdrPointerUnmarshall( &StubMsg, &mem, fmtstr_conf_str, 1);
1601 todo_wine {
1602     ok(mem == StubMsg.BufferStart + 12 || broken(!mem), /* win9x, nt4 */
1603        "mem not pointing at buffer %p/%p\n", mem, StubMsg.BufferStart + 12 );
1604     ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
1605 }
1606
1607     mem = my_alloc(10);
1608     my_free_called = 0;
1609     StubMsg.Buffer = StubMsg.BufferStart;
1610     NdrPointerFree( &StubMsg, mem, fmtstr_conf_str );
1611     ok(my_free_called == 1, "free called %d\n", my_free_called);
1612
1613     HeapFree(GetProcessHeap(), 0, mem_orig);
1614     HeapFree(GetProcessHeap(), 0, StubMsg.RpcMsg->Buffer);
1615 }
1616
1617 static void test_nonconformant_string(void)
1618 {
1619     RPC_MESSAGE RpcMessage;
1620     MIDL_STUB_MESSAGE StubMsg;
1621     MIDL_STUB_DESC StubDesc;
1622     DWORD size;
1623     void *ptr;
1624     unsigned char *mem, *mem_orig;
1625     unsigned char memsrc[10] = "This is";
1626     unsigned char memsrc2[10] = "This is a";
1627
1628     static const unsigned char fmtstr_nonconf_str[] =
1629     {
1630                         0x26,           /* FC_CSTRING */
1631                         0x5c,           /* FC_PAD */
1632                         NdrFcShort( 0xa ),      /* 10 */
1633     };
1634
1635     StubDesc = Object_StubDesc;
1636     StubDesc.pFormatTypes = fmtstr_nonconf_str;
1637
1638     /* length < size */
1639     NdrClientInitializeNew(
1640                            &RpcMessage,
1641                            &StubMsg,
1642                            &StubDesc,
1643                            0);
1644
1645     StubMsg.BufferLength = 0;
1646
1647     NdrNonConformantStringBufferSize( &StubMsg, memsrc, fmtstr_nonconf_str );
1648     ok(StubMsg.BufferLength >= strlen((char *)memsrc) + 1 + 8, "length %d\n", StubMsg.BufferLength);
1649
1650     /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
1651     StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
1652     StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
1653
1654     ptr = NdrNonConformantStringMarshall( &StubMsg, memsrc, fmtstr_nonconf_str );
1655     ok(ptr == NULL, "ret %p\n", ptr);
1656     size = StubMsg.Buffer - StubMsg.BufferStart;
1657     ok(size == strlen((char *)memsrc) + 1 + 8, "Buffer %p Start %p len %d\n",
1658        StubMsg.Buffer, StubMsg.BufferStart, size);
1659     ok(!memcmp(StubMsg.BufferStart + 8, memsrc, strlen((char *)memsrc) + 1), "incorrectly marshaled\n");
1660
1661     StubMsg.Buffer = StubMsg.BufferStart;
1662     StubMsg.MemorySize = 0;
1663     mem = NULL;
1664
1665     /* Client */
1666     my_alloc_called = 0;
1667     StubMsg.Buffer = StubMsg.BufferStart;
1668     mem = mem_orig = HeapAlloc(GetProcessHeap(), 0, sizeof(memsrc));
1669     NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 0);
1670     ok(mem == mem_orig, "mem alloced\n");
1671     ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
1672
1673     my_alloc_called = 0;
1674     StubMsg.Buffer = StubMsg.BufferStart;
1675     NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 1);
1676     todo_wine
1677     ok(mem == mem_orig, "mem alloced\n");
1678     todo_wine
1679     ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
1680
1681     /* Server */
1682     my_alloc_called = 0;
1683     StubMsg.IsClient = 0;
1684     mem = NULL;
1685     StubMsg.Buffer = StubMsg.BufferStart;
1686     NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 0);
1687     ok(mem != mem_orig, "mem not alloced\n");
1688     ok(mem != StubMsg.BufferStart + 8, "mem pointing at buffer\n");
1689     ok(my_alloc_called == 1, "alloc called %d\n", my_alloc_called);
1690     NdrOleFree(mem);
1691
1692     my_alloc_called = 0;
1693     mem = mem_orig;
1694     StubMsg.Buffer = StubMsg.BufferStart;
1695     NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 0);
1696     ok(mem == mem_orig, "mem alloced\n");
1697     ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
1698
1699     my_alloc_called = 0;
1700     mem = mem_orig;
1701     StubMsg.Buffer = StubMsg.BufferStart;
1702     NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 1);
1703     todo_wine
1704     ok(mem == mem_orig, "mem alloced\n");
1705     todo_wine
1706     ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
1707
1708     HeapFree(GetProcessHeap(), 0, mem_orig);
1709     HeapFree(GetProcessHeap(), 0, StubMsg.RpcMsg->Buffer);
1710
1711     /* length = size */
1712     NdrClientInitializeNew(
1713                            &RpcMessage,
1714                            &StubMsg,
1715                            &StubDesc,
1716                            0);
1717
1718     StubMsg.BufferLength = 0;
1719
1720     NdrNonConformantStringBufferSize( &StubMsg, memsrc2, fmtstr_nonconf_str );
1721     ok(StubMsg.BufferLength >= strlen((char *)memsrc2) + 1 + 8, "length %d\n", StubMsg.BufferLength);
1722
1723     /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
1724     StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
1725     StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
1726
1727     ptr = NdrNonConformantStringMarshall( &StubMsg, memsrc2, fmtstr_nonconf_str );
1728     ok(ptr == NULL, "ret %p\n", ptr);
1729     size = StubMsg.Buffer - StubMsg.BufferStart;
1730     ok(size == strlen((char *)memsrc2) + 1 + 8, "Buffer %p Start %p len %d\n",
1731        StubMsg.Buffer, StubMsg.BufferStart, size);
1732     ok(!memcmp(StubMsg.BufferStart + 8, memsrc2, strlen((char *)memsrc2) + 1), "incorrectly marshaled\n");
1733
1734     StubMsg.Buffer = StubMsg.BufferStart;
1735     StubMsg.MemorySize = 0;
1736     mem = NULL;
1737
1738     /* Client */
1739     my_alloc_called = 0;
1740     StubMsg.Buffer = StubMsg.BufferStart;
1741     mem = mem_orig = HeapAlloc(GetProcessHeap(), 0, sizeof(memsrc));
1742     NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 0);
1743     ok(mem == mem_orig, "mem alloced\n");
1744     ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
1745
1746     my_alloc_called = 0;
1747     StubMsg.Buffer = StubMsg.BufferStart;
1748     NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 1);
1749     todo_wine
1750     ok(mem == mem_orig, "mem alloced\n");
1751     todo_wine
1752     ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
1753
1754     /* Server */
1755     my_alloc_called = 0;
1756     StubMsg.IsClient = 0;
1757     mem = NULL;
1758     StubMsg.Buffer = StubMsg.BufferStart;
1759     NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 0);
1760     ok(mem != mem_orig, "mem not alloced\n");
1761     ok(mem != StubMsg.BufferStart + 8, "mem pointing at buffer\n");
1762     ok(my_alloc_called == 1, "alloc called %d\n", my_alloc_called);
1763     NdrOleFree(mem);
1764
1765     my_alloc_called = 0;
1766     mem = mem_orig;
1767     StubMsg.Buffer = StubMsg.BufferStart;
1768     NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 0);
1769     ok(mem == mem_orig, "mem alloced\n");
1770     ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
1771
1772     my_alloc_called = 0;
1773     mem = mem_orig;
1774     StubMsg.Buffer = StubMsg.BufferStart;
1775     NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 1);
1776     todo_wine
1777     ok(mem == mem_orig, "mem alloced\n");
1778     todo_wine
1779     ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
1780
1781     HeapFree(GetProcessHeap(), 0, mem_orig);
1782     HeapFree(GetProcessHeap(), 0, StubMsg.RpcMsg->Buffer);
1783 }
1784
1785 static void test_conf_complex_struct(void)
1786 {
1787     RPC_MESSAGE RpcMessage;
1788     MIDL_STUB_MESSAGE StubMsg;
1789     MIDL_STUB_DESC StubDesc;
1790     void *ptr;
1791     unsigned int i;
1792     struct conf_complex
1793     {
1794       unsigned int size;
1795       unsigned int *array[1];
1796     };
1797     struct conf_complex *memsrc;
1798     struct conf_complex *mem;
1799
1800     static const unsigned char fmtstr_complex_struct[] =
1801     {
1802 /* 0 */
1803                         0x1b,           /* FC_CARRAY */
1804                         0x3,            /* 3 */
1805 /* 2 */ NdrFcShort( 0x4 ),      /* 4 */
1806 /* 4 */ 0x8,            /* Corr desc: FC_LONG */
1807                         0x0,            /*  */
1808 /* 6 */ NdrFcShort( 0xfffc ),   /* -4 */
1809 /* 8 */
1810                         0x4b,           /* FC_PP */
1811                         0x5c,           /* FC_PAD */
1812 /* 10 */
1813                         0x48,           /* FC_VARIABLE_REPEAT */
1814                         0x49,           /* FC_FIXED_OFFSET */
1815 /* 12 */        NdrFcShort( 0x4 ),      /* 4 */
1816 /* 14 */        NdrFcShort( 0x0 ),      /* 0 */
1817 /* 16 */        NdrFcShort( 0x1 ),      /* 1 */
1818 /* 18 */        NdrFcShort( 0x0 ),      /* 0 */
1819 /* 20 */        NdrFcShort( 0x0 ),      /* 0 */
1820 /* 22 */        0x12, 0x8,      /* FC_UP [simple_pointer] */
1821 /* 24 */        0x8,            /* FC_LONG */
1822                         0x5c,           /* FC_PAD */
1823 /* 26 */
1824                         0x5b,           /* FC_END */
1825
1826                         0x8,            /* FC_LONG */
1827 /* 28 */        0x5c,           /* FC_PAD */
1828                         0x5b,           /* FC_END */
1829 /* 30 */
1830                         0x1a,           /* FC_BOGUS_STRUCT */
1831                         0x3,            /* 3 */
1832 /* 32 */        NdrFcShort( 0x4 ),      /* 4 */
1833 /* 34 */        NdrFcShort( 0xffffffde ),       /* Offset= -34 (0) */
1834 /* 36 */        NdrFcShort( 0x0 ),      /* Offset= 0 (36) */
1835 /* 38 */        0x8,            /* FC_LONG */
1836                         0x5b,           /* FC_END */
1837     };
1838
1839     memsrc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1840                        FIELD_OFFSET(struct conf_complex, array[20]));
1841     memsrc->size = 20;
1842
1843     StubDesc = Object_StubDesc;
1844     StubDesc.pFormatTypes = fmtstr_complex_struct;
1845
1846     NdrClientInitializeNew(
1847                            &RpcMessage,
1848                            &StubMsg,
1849                            &StubDesc,
1850                            0);
1851
1852     StubMsg.BufferLength = 0;
1853     NdrComplexStructBufferSize( &StubMsg,
1854                                 (unsigned char *)memsrc,
1855                                 &fmtstr_complex_struct[30] );
1856     ok(StubMsg.BufferLength >= 28, "length %d\n", StubMsg.BufferLength);
1857
1858     /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
1859     StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
1860     StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
1861
1862     ptr = NdrComplexStructMarshall( &StubMsg, (unsigned char *)memsrc,
1863                                     &fmtstr_complex_struct[30] );
1864     ok(ptr == NULL, "ret %p\n", ptr);
1865     ok(*(unsigned int *)StubMsg.BufferStart == 20, "Conformance should have been 20 instead of %d\n", *(unsigned int *)StubMsg.BufferStart);
1866     ok(*(unsigned int *)(StubMsg.BufferStart + 4) == 20, "conf_complex.size should have been 20 instead of %d\n", *(unsigned int *)(StubMsg.BufferStart + 4));
1867     for (i = 0; i < 20; i++)
1868       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));
1869
1870     /* Server */
1871     my_alloc_called = 0;
1872     StubMsg.IsClient = 0;
1873     mem = NULL;
1874     StubMsg.Buffer = StubMsg.BufferStart;
1875     ptr = NdrComplexStructUnmarshall( &StubMsg, (unsigned char **)&mem, &fmtstr_complex_struct[30], 0);
1876     ok(ptr == NULL, "ret %p\n", ptr);
1877     ok(mem->size == 20, "mem->size wasn't unmarshalled correctly (%d)\n", mem->size);
1878     ok(mem->array[0] == NULL, "mem->array[0] wasn't unmarshalled correctly (%p)\n", mem->array[0]);
1879     StubMsg.pfnFree(mem);
1880
1881     HeapFree(GetProcessHeap(), 0, StubMsg.RpcMsg->Buffer);
1882     HeapFree(GetProcessHeap(), 0, memsrc);
1883 }
1884
1885 static void test_ndr_buffer(void)
1886 {
1887     static unsigned char ncalrpc[] = "ncalrpc";
1888     static unsigned char endpoint[] = "winetest:test_ndr_buffer";
1889     RPC_MESSAGE RpcMessage;
1890     MIDL_STUB_MESSAGE StubMsg;
1891     MIDL_STUB_DESC StubDesc = Object_StubDesc;
1892     unsigned char *ret;
1893     unsigned char *binding;
1894     RPC_BINDING_HANDLE Handle;
1895     RPC_STATUS status;
1896     ULONG prev_buffer_length;
1897     BOOL old_buffer_valid_location;
1898
1899     StubDesc.RpcInterfaceInformation = (void *)&IFoo___RpcServerInterface;
1900
1901     status = RpcServerUseProtseqEp(ncalrpc, 20, endpoint, NULL);
1902     ok(RPC_S_OK == status, "RpcServerUseProtseqEp failed with status %u\n", status);
1903     status = RpcServerRegisterIf(IFoo_v0_0_s_ifspec, NULL, NULL);
1904     ok(RPC_S_OK == status, "RpcServerRegisterIf failed with status %u\n", status);
1905     status = RpcServerListen(1, 20, TRUE);
1906     ok(RPC_S_OK == status, "RpcServerListen failed with status %u\n", status);
1907     if (status != RPC_S_OK)
1908     {
1909         /* Failed to create a server, running client tests is useless */
1910         return;
1911     }
1912
1913     status = RpcStringBindingCompose(NULL, ncalrpc, NULL, endpoint, NULL, &binding);
1914     ok(status == RPC_S_OK, "RpcStringBindingCompose failed (%u)\n", status);
1915
1916     status = RpcBindingFromStringBinding(binding, &Handle);
1917     ok(status == RPC_S_OK, "RpcBindingFromStringBinding failed (%u)\n", status);
1918     RpcStringFree(&binding);
1919
1920     NdrClientInitializeNew(&RpcMessage, &StubMsg, &StubDesc, 5);
1921
1922     ret = NdrGetBuffer(&StubMsg, 10, Handle);
1923     ok(ret == StubMsg.Buffer, "NdrGetBuffer should have returned the same value as StubMsg.Buffer instead of %p\n", ret);
1924     ok(RpcMessage.Handle != NULL, "RpcMessage.Handle should not have been NULL\n");
1925     ok(RpcMessage.Buffer != NULL, "RpcMessage.Buffer should not have been NULL\n");
1926     ok(RpcMessage.BufferLength == 10 ||
1927        broken(RpcMessage.BufferLength == 12), /* win2k */
1928        "RpcMessage.BufferLength should have been 10 instead of %d\n", RpcMessage.BufferLength);
1929     ok(RpcMessage.RpcFlags == 0, "RpcMessage.RpcFlags should have been 0x0 instead of 0x%x\n", RpcMessage.RpcFlags);
1930     ok(StubMsg.Buffer != NULL, "Buffer should not have been NULL\n");
1931     ok(!StubMsg.BufferStart, "BufferStart should have been NULL instead of %p\n", StubMsg.BufferStart);
1932     ok(!StubMsg.BufferEnd, "BufferEnd should have been NULL instead of %p\n", StubMsg.BufferEnd);
1933 todo_wine
1934     ok(StubMsg.BufferLength == 0, "BufferLength should have left as 0 instead of being set to %d\n", StubMsg.BufferLength);
1935     old_buffer_valid_location = !StubMsg.fBufferValid;
1936     if (old_buffer_valid_location)
1937         ok(broken(StubMsg.CorrDespIncrement == TRUE), "fBufferValid should have been TRUE instead of 0x%x\n", StubMsg.CorrDespIncrement);
1938     else
1939         ok(StubMsg.fBufferValid, "fBufferValid should have been non-zero instead of 0x%x\n", StubMsg.fBufferValid);
1940
1941     prev_buffer_length = RpcMessage.BufferLength;
1942     StubMsg.BufferLength = 1;
1943     NdrFreeBuffer(&StubMsg);
1944     ok(RpcMessage.Handle != NULL, "RpcMessage.Handle should not have been NULL\n");
1945     ok(RpcMessage.Buffer != NULL, "RpcMessage.Buffer should not have been NULL\n");
1946     ok(RpcMessage.BufferLength == prev_buffer_length, "RpcMessage.BufferLength should have been left as %d instead of %d\n", prev_buffer_length, RpcMessage.BufferLength);
1947     ok(StubMsg.Buffer != NULL, "Buffer should not have been NULL\n");
1948     ok(StubMsg.BufferLength == 1, "BufferLength should have left as 1 instead of being set to %d\n", StubMsg.BufferLength);
1949     if (old_buffer_valid_location)
1950         ok(broken(StubMsg.CorrDespIncrement == FALSE), "fBufferValid should have been FALSE instead of 0x%x\n", StubMsg.CorrDespIncrement);
1951     else
1952         ok(!StubMsg.fBufferValid, "fBufferValid should have been FALSE instead of %d\n", StubMsg.fBufferValid);
1953
1954     /* attempt double-free */
1955     NdrFreeBuffer(&StubMsg);
1956
1957     RpcBindingFree(&Handle);
1958
1959     status = RpcServerUnregisterIf(NULL, NULL, FALSE);
1960     ok(status == RPC_S_OK, "RpcServerUnregisterIf failed (%u)\n", status);
1961 }
1962
1963 static void test_NdrMapCommAndFaultStatus(void)
1964 {
1965     RPC_STATUS rpc_status;
1966     MIDL_STUB_MESSAGE StubMsg;
1967     RPC_MESSAGE RpcMessage;
1968
1969     NdrClientInitializeNew(&RpcMessage, &StubMsg, &Object_StubDesc, 5);
1970
1971     for (rpc_status = 0; rpc_status < 10000; rpc_status++)
1972     {
1973         RPC_STATUS status;
1974         ULONG comm_status = 0;
1975         ULONG fault_status = 0;
1976         ULONG expected_comm_status = 0;
1977         ULONG expected_fault_status = 0;
1978         status = NdrMapCommAndFaultStatus(&StubMsg, &comm_status, &fault_status, rpc_status);
1979         ok(status == RPC_S_OK, "NdrMapCommAndFaultStatus failed with error %d\n", status);
1980         switch (rpc_status)
1981         {
1982         case ERROR_INVALID_HANDLE:
1983         case RPC_S_INVALID_BINDING:
1984         case RPC_S_UNKNOWN_IF:
1985         case RPC_S_SERVER_UNAVAILABLE:
1986         case RPC_S_SERVER_TOO_BUSY:
1987         case RPC_S_CALL_FAILED_DNE:
1988         case RPC_S_PROTOCOL_ERROR:
1989         case RPC_S_UNSUPPORTED_TRANS_SYN:
1990         case RPC_S_UNSUPPORTED_TYPE:
1991         case RPC_S_PROCNUM_OUT_OF_RANGE:
1992         case EPT_S_NOT_REGISTERED:
1993         case RPC_S_COMM_FAILURE:
1994             expected_comm_status = rpc_status;
1995             break;
1996         default:
1997             expected_fault_status = rpc_status;
1998         }
1999         ok(comm_status == expected_comm_status, "NdrMapCommAndFaultStatus should have mapped %d to comm status %d instead of %d\n",
2000             rpc_status, expected_comm_status, comm_status);
2001         ok(fault_status == expected_fault_status, "NdrMapCommAndFaultStatus should have mapped %d to fault status %d instead of %d\n",
2002             rpc_status, expected_fault_status, fault_status);
2003     }
2004 }
2005
2006 static void test_NdrGetUserMarshalInfo(void)
2007 {
2008     RPC_STATUS status;
2009     MIDL_STUB_MESSAGE stubmsg;
2010     USER_MARSHAL_CB umcb;
2011     NDR_USER_MARSHAL_INFO umi;
2012     unsigned char buffer[16];
2013     void *rpc_channel_buffer = (void *)(ULONG_PTR)0xcafebabe;
2014     RPC_MESSAGE rpc_msg;
2015     RPC_STATUS (RPC_ENTRY *pNdrGetUserMarshalInfo)(ULONG *,ULONG,NDR_USER_MARSHAL_INFO *);
2016
2017     pNdrGetUserMarshalInfo = (void *)GetProcAddress(GetModuleHandle("rpcrt4.dll"), "NdrGetUserMarshalInfo");
2018     if (!pNdrGetUserMarshalInfo)
2019     {
2020         skip("NdrGetUserMarshalInfo not exported\n");
2021         return;
2022     }
2023
2024     /* unmarshall */
2025
2026     memset(&rpc_msg, 0xcc, sizeof(rpc_msg));
2027     rpc_msg.Buffer = buffer;
2028     rpc_msg.BufferLength = 16;
2029
2030     memset(&stubmsg, 0xcc, sizeof(stubmsg));
2031     stubmsg.RpcMsg = &rpc_msg;
2032     stubmsg.dwDestContext = MSHCTX_INPROC;
2033     stubmsg.pvDestContext = NULL;
2034     stubmsg.Buffer = buffer + 15;
2035     stubmsg.BufferLength = 0;
2036     stubmsg.BufferEnd = NULL;
2037     stubmsg.pRpcChannelBuffer = rpc_channel_buffer;
2038     stubmsg.StubDesc = NULL;
2039     stubmsg.pfnAllocate = my_alloc;
2040     stubmsg.pfnFree = my_free;
2041
2042     memset(&umcb, 0xcc, sizeof(umcb));
2043     umcb.Flags = MAKELONG(MSHCTX_INPROC, NDR_LOCAL_DATA_REPRESENTATION);
2044     umcb.pStubMsg = &stubmsg;
2045     umcb.Signature = USER_MARSHAL_CB_SIGNATURE;
2046     umcb.CBType = USER_MARSHAL_CB_UNMARSHALL;
2047
2048     memset(&umi, 0xaa, sizeof(umi));
2049
2050     status = pNdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2051     ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %d\n", status);
2052     ok( umi.InformationLevel == 1,
2053        "umi.InformationLevel was %u instead of 1\n",
2054         umi.InformationLevel);
2055     ok( U1(umi).Level1.Buffer == buffer + 15,
2056        "umi.Level1.Buffer was %p instead of %p\n",
2057         U1(umi).Level1.Buffer, buffer);
2058     ok( U1(umi).Level1.BufferSize == 1,
2059        "umi.Level1.BufferSize was %u instead of 1\n",
2060         U1(umi).Level1.BufferSize);
2061     ok( U1(umi).Level1.pfnAllocate == my_alloc,
2062        "umi.Level1.pfnAllocate was %p instead of %p\n",
2063         U1(umi).Level1.pfnAllocate, my_alloc);
2064     ok( U1(umi).Level1.pfnFree == my_free,
2065        "umi.Level1.pfnFree was %p instead of %p\n",
2066         U1(umi).Level1.pfnFree, my_free);
2067     ok( U1(umi).Level1.pRpcChannelBuffer == rpc_channel_buffer,
2068        "umi.Level1.pRpcChannelBuffer was %p instead of %p\n",
2069         U1(umi).Level1.pRpcChannelBuffer, rpc_channel_buffer);
2070
2071     /* buffer size */
2072
2073     rpc_msg.Buffer = buffer;
2074     rpc_msg.BufferLength = 16;
2075
2076     stubmsg.Buffer = buffer;
2077     stubmsg.BufferLength = 16;
2078     stubmsg.BufferEnd = NULL;
2079
2080     umcb.CBType = USER_MARSHAL_CB_BUFFER_SIZE;
2081
2082     memset(&umi, 0xaa, sizeof(umi));
2083
2084     status = pNdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2085     ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %d\n", status);
2086     ok( umi.InformationLevel == 1,
2087        "umi.InformationLevel was %u instead of 1\n",
2088         umi.InformationLevel);
2089     ok( U1(umi).Level1.Buffer == NULL,
2090        "umi.Level1.Buffer was %p instead of NULL\n",
2091         U1(umi).Level1.Buffer);
2092     ok( U1(umi).Level1.BufferSize == 0,
2093        "umi.Level1.BufferSize was %u instead of 0\n",
2094         U1(umi).Level1.BufferSize);
2095     ok( U1(umi).Level1.pfnAllocate == my_alloc,
2096        "umi.Level1.pfnAllocate was %p instead of %p\n",
2097         U1(umi).Level1.pfnAllocate, my_alloc);
2098     ok( U1(umi).Level1.pfnFree == my_free,
2099        "umi.Level1.pfnFree was %p instead of %p\n",
2100         U1(umi).Level1.pfnFree, my_free);
2101     ok( U1(umi).Level1.pRpcChannelBuffer == rpc_channel_buffer,
2102        "umi.Level1.pRpcChannelBuffer was %p instead of %p\n",
2103         U1(umi).Level1.pRpcChannelBuffer, rpc_channel_buffer);
2104
2105     /* marshall */
2106
2107     rpc_msg.Buffer = buffer;
2108     rpc_msg.BufferLength = 16;
2109
2110     stubmsg.Buffer = buffer + 15;
2111     stubmsg.BufferLength = 0;
2112     stubmsg.BufferEnd = NULL;
2113
2114     umcb.CBType = USER_MARSHAL_CB_MARSHALL;
2115
2116     memset(&umi, 0xaa, sizeof(umi));
2117
2118     status = pNdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2119     ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %d\n", status);
2120     ok( umi.InformationLevel == 1,
2121        "umi.InformationLevel was %u instead of 1\n",
2122         umi.InformationLevel);
2123     ok( U1(umi).Level1.Buffer == buffer + 15,
2124        "umi.Level1.Buffer was %p instead of %p\n",
2125         U1(umi).Level1.Buffer, buffer);
2126     ok( U1(umi).Level1.BufferSize == 1,
2127        "umi.Level1.BufferSize was %u instead of 1\n",
2128         U1(umi).Level1.BufferSize);
2129     ok( U1(umi).Level1.pfnAllocate == my_alloc,
2130        "umi.Level1.pfnAllocate was %p instead of %p\n",
2131         U1(umi).Level1.pfnAllocate, my_alloc);
2132     ok( U1(umi).Level1.pfnFree == my_free,
2133        "umi.Level1.pfnFree was %p instead of %p\n",
2134         U1(umi).Level1.pfnFree, my_free);
2135     ok( U1(umi).Level1.pRpcChannelBuffer == rpc_channel_buffer,
2136        "umi.Level1.pRpcChannelBuffer was %p instead of %p\n",
2137         U1(umi).Level1.pRpcChannelBuffer, rpc_channel_buffer);
2138
2139     /* free */
2140
2141     rpc_msg.Buffer = buffer;
2142     rpc_msg.BufferLength = 16;
2143
2144     stubmsg.Buffer = buffer;
2145     stubmsg.BufferLength = 16;
2146     stubmsg.BufferEnd = NULL;
2147
2148     umcb.CBType = USER_MARSHAL_CB_FREE;
2149
2150     memset(&umi, 0xaa, sizeof(umi));
2151
2152     status = pNdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2153     ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %d\n", status);
2154     ok( umi.InformationLevel == 1,
2155        "umi.InformationLevel was %u instead of 1\n",
2156         umi.InformationLevel);
2157     ok( U1(umi).Level1.Buffer == NULL,
2158        "umi.Level1.Buffer was %p instead of NULL\n",
2159         U1(umi).Level1.Buffer);
2160     ok( U1(umi).Level1.BufferSize == 0,
2161        "umi.Level1.BufferSize was %u instead of 0\n",
2162         U1(umi).Level1.BufferSize);
2163     ok( U1(umi).Level1.pfnAllocate == my_alloc,
2164        "umi.Level1.pfnAllocate was %p instead of %p\n",
2165         U1(umi).Level1.pfnAllocate, my_alloc);
2166     ok( U1(umi).Level1.pfnFree == my_free,
2167        "umi.Level1.pfnFree was %p instead of %p\n",
2168         U1(umi).Level1.pfnFree, my_free);
2169     ok( U1(umi).Level1.pRpcChannelBuffer == rpc_channel_buffer,
2170        "umi.Level1.pRpcChannelBuffer was %p instead of %p\n",
2171         U1(umi).Level1.pRpcChannelBuffer, rpc_channel_buffer);
2172
2173     /* boundary test */
2174
2175     rpc_msg.Buffer = buffer;
2176     rpc_msg.BufferLength = 15;
2177
2178     stubmsg.Buffer = buffer + 15;
2179     stubmsg.BufferLength = 0;
2180     stubmsg.BufferEnd = NULL;
2181
2182     umcb.CBType = USER_MARSHAL_CB_MARSHALL;
2183
2184     status = pNdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2185     ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %d\n", status);
2186     ok( U1(umi).Level1.BufferSize == 0,
2187        "umi.Level1.BufferSize was %u instead of 0\n",
2188         U1(umi).Level1.BufferSize);
2189
2190     /* error conditions */
2191
2192     rpc_msg.BufferLength = 14;
2193     status = pNdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2194     ok(status == ERROR_INVALID_USER_BUFFER,
2195         "NdrGetUserMarshalInfo should have failed with ERROR_INVALID_USER_BUFFER instead of %d\n", status);
2196
2197     rpc_msg.BufferLength = 15;
2198     status = pNdrGetUserMarshalInfo(&umcb.Flags, 9999, &umi);
2199     ok(status == RPC_S_INVALID_ARG,
2200         "NdrGetUserMarshalInfo should have failed with RPC_S_INVALID_ARG instead of %d\n", status);
2201
2202     umcb.CBType = 9999;
2203     status = pNdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2204     ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %d\n", status);
2205
2206     umcb.CBType = USER_MARSHAL_CB_MARSHALL;
2207     umcb.Signature = 0;
2208     status = pNdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2209     ok(status == RPC_S_INVALID_ARG,
2210         "NdrGetUserMarshalInfo should have failed with RPC_S_INVALID_ARG instead of %d\n", status);
2211 }
2212
2213 START_TEST( ndr_marshall )
2214 {
2215     determine_pointer_marshalling_style();
2216
2217     test_ndr_simple_type();
2218     test_simple_types();
2219     test_nontrivial_pointer_types();
2220     test_simple_struct();
2221     test_fullpointer_xlat();
2222     test_client_init();
2223     test_server_init();
2224     test_ndr_allocate();
2225     test_conformant_array();
2226     test_conformant_string();
2227     test_nonconformant_string();
2228     test_conf_complex_struct();
2229     test_ndr_buffer();
2230     test_NdrMapCommAndFaultStatus();
2231     test_NdrGetUserMarshalInfo();
2232 }