2 * Unit test suite for ndr marshalling functions
4 * Copyright 2006 Huw Davies
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.
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.
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
23 #include "wine/test.h"
34 static int my_alloc_called;
35 static int my_free_called;
36 void * CALLBACK my_alloc(size_t size)
39 return NdrOleAllocate(size);
42 void CALLBACK my_free(void *ptr)
45 return NdrOleFree(ptr);
48 static const MIDL_STUB_DESC Object_StubDesc =
58 NULL, /* format string, filled in by tests */
59 1, /* -error bounds_check flag */
60 0x20000, /* Ndr library version */
62 0x50100a4, /* MIDL Version 5.1.164 */
65 0, /* notify & notify_flag routine table */
73 static void test_pointer_marshal(const unsigned char *formattypes,
78 int(*cmp)(const void*,const void*,size_t),
79 long num_additional_allocs,
82 RPC_MESSAGE RpcMessage;
83 MIDL_STUB_MESSAGE StubMsg;
84 MIDL_STUB_DESC StubDesc;
87 unsigned char *mem, *mem_orig;
89 my_alloc_called = my_free_called = 0;
93 StubDesc = Object_StubDesc;
94 StubDesc.pFormatTypes = formattypes;
96 NdrClientInitializeNew(
102 StubMsg.BufferLength = 0;
103 NdrPointerBufferSize( &StubMsg,
106 ok(StubMsg.BufferLength >= wiredatalen, "%s: length %ld\n", msgpfx, StubMsg.BufferLength);
108 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
109 StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
110 StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
112 memset(StubMsg.BufferStart, 0x0, StubMsg.BufferLength); /* This is a hack to clear the padding between the ptr and longlong/double */
114 ptr = NdrPointerMarshall( &StubMsg, memsrc, formattypes );
115 ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
116 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %ld\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
117 ok(!memcmp(StubMsg.BufferStart, wiredata, wiredatalen), "%s: incorrectly marshaled\n", msgpfx);
119 StubMsg.Buffer = StubMsg.BufferStart;
120 StubMsg.MemorySize = 0;
122 #if 0 /* NdrPointerMemorySize crashes under Wine, remove #if 0 when this is fixed */
123 size = NdrPointerMemorySize( &StubMsg, formattypes );
124 ok(size == StubMsg.MemorySize, "%s: mem size %ld size %ld\n", msgpfx, StubMsg.MemorySize, size);
125 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %ld\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
126 if(formattypes[1] & 0x10 /* FC_POINTER_DEREF */)
127 ok(size == srcsize + 4, "%s: mem size %ld\n", msgpfx, size);
129 ok(size == srcsize, "%s: mem size %ld\n", msgpfx, size);
131 StubMsg.Buffer = StubMsg.BufferStart;
132 StubMsg.MemorySize = 16;
133 size = NdrPointerMemorySize( &StubMsg, formattypes );
134 ok(size == StubMsg.MemorySize, "%s: mem size %ld size %ld\n", msgpfx, StubMsg.MemorySize, size);
135 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %ld\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
136 if(formattypes[1] & 0x10 /* FC_POINTER_DEREF */)
137 ok(size == srcsize + 4 + 16, "%s: mem size %ld\n", msgpfx, size);
139 ok(size == srcsize + 16, "%s: mem size %ld\n", msgpfx, size);
141 StubMsg.Buffer = StubMsg.BufferStart;
142 StubMsg.MemorySize = 1;
143 size = NdrPointerMemorySize( &StubMsg, formattypes );
144 ok(size == StubMsg.MemorySize, "%s: mem size %ld size %ld\n", msgpfx, StubMsg.MemorySize, size);
145 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %ld\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
146 if(formattypes[1] & 0x10 /* FC_POINTER_DEREF */)
147 ok(size == srcsize + 4 + (srcsize == 8 ? 8 : 4), "%s: mem size %ld\n", msgpfx, size);
149 ok(size == srcsize + (srcsize == 8 ? 8 : 4), "%s: mem size %ld\n", msgpfx, size);
154 if(formattypes[1] & 0x10) size += 4;
156 StubMsg.Buffer = StubMsg.BufferStart;
157 StubMsg.MemorySize = 0;
158 mem_orig = mem = HeapAlloc(GetProcessHeap(), 0, size);
160 if(formattypes[1] & 0x10 /* FC_POINTER_DEREF */)
162 ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 0 );
163 ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
164 ok(mem == mem_orig, "%s: mem has changed %p %p\n", msgpfx, mem, mem_orig);
165 ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx);
166 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %ld\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
167 ok(StubMsg.MemorySize == 0, "%s: memorysize %ld\n", msgpfx, StubMsg.MemorySize);
168 ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
171 /* reset the buffer and call with must alloc */
172 StubMsg.Buffer = StubMsg.BufferStart;
173 if(formattypes[1] & 0x10 /* FC_POINTER_DEREF */)
175 ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 1 );
176 ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
177 /* doesn't allocate mem in this case */
179 ok(mem == mem_orig, "%s: mem has changed %p %p\n", msgpfx, mem, mem_orig);
181 ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx);
182 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %ld\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
183 ok(StubMsg.MemorySize == 0, "%s: memorysize %ld\n", msgpfx, StubMsg.MemorySize);
186 ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
189 if(formattypes[0] != 0x11 /* FC_RP */)
191 /* now pass the address of a NULL ptr */
193 StubMsg.Buffer = StubMsg.BufferStart;
194 ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 0 );
195 ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
196 ok(mem != StubMsg.BufferStart + wiredatalen - srcsize, "%s: mem points to buffer %p %p\n", msgpfx, mem, StubMsg.BufferStart);
197 ok(!cmp(mem, memsrc, size), "%s: incorrectly unmarshaled\n", msgpfx);
198 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %ld\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
199 ok(StubMsg.MemorySize == 0, "%s: memorysize %ld\n", msgpfx, StubMsg.MemorySize);
200 ok(my_alloc_called == num_additional_allocs + 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
202 NdrPointerFree(&StubMsg, mem, formattypes);
204 /* again pass address of NULL ptr, but pretend we're a server */
206 StubMsg.Buffer = StubMsg.BufferStart;
207 StubMsg.IsClient = 0;
208 ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 0 );
209 ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
211 ok(mem == StubMsg.BufferStart + wiredatalen - srcsize, "%s: mem doesn't point to buffer %p %p\n", msgpfx, mem, StubMsg.BufferStart);
213 ok(!cmp(mem, memsrc, size), "%s: incorrecly unmarshaled\n", msgpfx);
214 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %ld\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
215 ok(StubMsg.MemorySize == 0, "%s: memorysize %ld\n", msgpfx, StubMsg.MemorySize);
217 ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
221 HeapFree(GetProcessHeap(), 0, mem_orig);
222 HeapFree(GetProcessHeap(), 0, StubMsg.BufferStart);
225 static int deref_cmp(const void *s1, const void *s2, size_t num)
227 return memcmp(*(void**)s1, *(void**)s2, num);
231 static void test_simple_types()
233 unsigned char wiredata[16];
235 unsigned char *ch_ptr;
243 static const unsigned char fmtstr_up_char[] =
245 0x12, 0x8, /* FC_UP [simple_pointer] */
249 static const unsigned char fmtstr_up_byte[] =
251 0x12, 0x8, /* FC_UP [simple_pointer] */
255 static const unsigned char fmtstr_up_small[] =
257 0x12, 0x8, /* FC_UP [simple_pointer] */
261 static const unsigned char fmtstr_up_usmall[] =
263 0x12, 0x8, /* FC_UP [simple_pointer] */
267 static const unsigned char fmtstr_rp_char[] =
269 0x11, 0x8, /* FC_RP [simple_pointer] */
273 static const unsigned char fmtstr_rpup_char[] =
275 0x11, 0x14, /* FC_RP [alloced_on_stack] */
276 NdrFcShort( 0x2 ), /* Offset= 2 (4) */
277 0x12, 0x8, /* FC_UP [simple_pointer] */
281 static const unsigned char fmtstr_rpup_char2[] =
283 0x11, 0x04, /* FC_RP [alloced_on_stack] */
284 NdrFcShort( 0x2 ), /* Offset= 2 (4) */
285 0x12, 0x8, /* FC_UP [simple_pointer] */
290 static const unsigned char fmtstr_up_wchar[] =
292 0x12, 0x8, /* FC_UP [simple_pointer] */
296 static const unsigned char fmtstr_up_short[] =
298 0x12, 0x8, /* FC_UP [simple_pointer] */
302 static const unsigned char fmtstr_up_ushort[] =
304 0x12, 0x8, /* FC_UP [simple_pointer] */
309 static const unsigned char fmtstr_up_enum16[] =
311 0x12, 0x8, /* FC_UP [simple_pointer] */
316 static const unsigned char fmtstr_up_long[] =
318 0x12, 0x8, /* FC_UP [simple_pointer] */
322 static const unsigned char fmtstr_up_ulong[] =
324 0x12, 0x8, /* FC_UP [simple_pointer] */
328 static const unsigned char fmtstr_up_enum32[] =
330 0x12, 0x8, /* FC_UP [simple_pointer] */
334 static const unsigned char fmtstr_up_errorstatus[] =
336 0x12, 0x8, /* FC_UP [simple_pointer] */
337 0x10, /* FC_ERROR_STATUS_T */
341 static const unsigned char fmtstr_up_longlong[] =
343 0x12, 0x8, /* FC_UP [simple_pointer] */
347 static const unsigned char fmtstr_up_float[] =
349 0x12, 0x8, /* FC_UP [simple_pointer] */
353 static const unsigned char fmtstr_up_double[] =
355 0x12, 0x8, /* FC_UP [simple_pointer] */
362 *(void**)wiredata = ch_ptr;
363 wiredata[sizeof(void*)] = ch;
365 test_pointer_marshal(fmtstr_up_char, ch_ptr, 1, wiredata, 5, NULL, 0, "up_char");
366 test_pointer_marshal(fmtstr_up_byte, ch_ptr, 1, wiredata, 5, NULL, 0, "up_byte");
367 test_pointer_marshal(fmtstr_up_small, ch_ptr, 1, wiredata, 5, NULL, 0, "up_small");
368 test_pointer_marshal(fmtstr_up_usmall, ch_ptr, 1, wiredata, 5, NULL, 0, "up_usmall");
370 test_pointer_marshal(fmtstr_rp_char, ch_ptr, 1, &ch, 1, NULL, 0, "rp_char");
372 test_pointer_marshal(fmtstr_rpup_char, &ch_ptr, 1, wiredata, 5, deref_cmp, 1, "rpup_char");
373 test_pointer_marshal(fmtstr_rpup_char2, ch_ptr, 1, wiredata, 5, NULL, 0, "rpup_char2");
376 *(void**)wiredata = &s;
377 *(unsigned short*)(wiredata + sizeof(void*)) = s;
379 test_pointer_marshal(fmtstr_up_wchar, &s, 2, wiredata, 6, NULL, 0, "up_wchar");
380 test_pointer_marshal(fmtstr_up_short, &s, 2, wiredata, 6, NULL, 0, "up_short");
381 test_pointer_marshal(fmtstr_up_ushort, &s, 2, wiredata, 6, NULL, 0, "up_ushort");
384 *(void**)wiredata = &i;
385 #if 0 /* Not sure why this crashes under Windows */
386 test_pointer_marshal(fmtstr_up_enum16, &i, 2, wiredata, 6, NULL, 0, "up_enum16");
390 *(void**)wiredata = &l;
391 *(unsigned long*)(wiredata + sizeof(void*)) = l;
393 test_pointer_marshal(fmtstr_up_long, &l, 4, wiredata, 8, NULL, 0, "up_long");
394 test_pointer_marshal(fmtstr_up_ulong, &l, 4, wiredata, 8, NULL, 0, "up_ulong");
395 test_pointer_marshal(fmtstr_up_enum32, &l, 4, wiredata, 8, NULL, 0, "up_emun32");
396 test_pointer_marshal(fmtstr_up_errorstatus, &l, 4, wiredata, 8, NULL, 0, "up_errorstatus");
398 ll = ((ULONGLONG)0xcafebabe) << 32 | 0xdeadbeef;
399 *(void**)wiredata = ≪
400 *(void**)(wiredata + sizeof(void*)) = NULL;
401 *(ULONGLONG*)(wiredata + 2 * sizeof(void*)) = ll;
402 test_pointer_marshal(fmtstr_up_longlong, &ll, 8, wiredata, 16, NULL, 0, "up_longlong");
405 *(void**)wiredata = &f;
406 *(float*)(wiredata + sizeof(void*)) = f;
407 test_pointer_marshal(fmtstr_up_float, &f, 4, wiredata, 8, NULL, 0, "up_float");
410 *(void**)wiredata = &d;
411 *(void**)(wiredata + sizeof(void*)) = NULL;
412 *(double*)(wiredata + 2 * sizeof(void*)) = d;
413 test_pointer_marshal(fmtstr_up_double, &d, 8, wiredata, 16, NULL, 0, "up_double");
417 static void test_simple_struct_marshal(const unsigned char *formattypes,
420 const void *wiredata,
422 int(*cmp)(const void*,const void*,size_t),
423 long num_additional_allocs,
426 RPC_MESSAGE RpcMessage;
427 MIDL_STUB_MESSAGE StubMsg;
428 MIDL_STUB_DESC StubDesc;
431 unsigned char *mem, *mem_orig;
433 my_alloc_called = my_free_called = 0;
437 StubDesc = Object_StubDesc;
438 StubDesc.pFormatTypes = formattypes;
440 NdrClientInitializeNew(&RpcMessage, &StubMsg, &StubDesc, 0);
442 StubMsg.BufferLength = 0;
443 NdrSimpleStructBufferSize( &StubMsg, (unsigned char *)memsrc, formattypes );
444 ok(StubMsg.BufferLength >= wiredatalen, "%s: length %ld\n", msgpfx, StubMsg.BufferLength);
445 StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
446 StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
447 ptr = NdrSimpleStructMarshall( &StubMsg, (unsigned char*)memsrc, formattypes );
448 ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
449 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart);
450 ok(!memcmp(StubMsg.BufferStart, wiredata, wiredatalen), "%s: incorrectly marshaled %08lx %08lx %08lx\n", msgpfx, *(DWORD*)StubMsg.BufferStart,*((DWORD*)StubMsg.BufferStart+1),*((DWORD*)StubMsg.BufferStart+2));
453 StubMsg.Buffer = StubMsg.BufferStart;
454 StubMsg.MemorySize = 0;
455 size = NdrSimpleStructMemorySize( &StubMsg, formattypes );
456 ok(size == StubMsg.MemorySize, "%s: size != MemorySize\n", msgpfx);
457 ok(size == srcsize, "%s: mem size %ld\n", msgpfx, size);
458 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart);
460 StubMsg.Buffer = StubMsg.BufferStart;
461 size = NdrSimpleStructMemorySize( &StubMsg, formattypes );
463 ok(size == StubMsg.MemorySize, "%s: size != MemorySize\n", msgpfx);
465 ok(StubMsg.MemorySize == ((srcsize + 3) & ~3) + srcsize, "%s: mem size %ld\n", msgpfx, size);
466 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart);
469 /*** Unmarshalling first with must_alloc false ***/
471 StubMsg.Buffer = StubMsg.BufferStart;
472 StubMsg.MemorySize = 0;
473 mem_orig = mem = HeapAlloc(GetProcessHeap(), 0, srcsize);
474 ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, 0 );
475 ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
476 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart);
477 ok(mem == mem_orig, "%s: mem has changed %p %p\n", msgpfx, mem, mem_orig);
478 ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx);
479 ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
481 ok(StubMsg.MemorySize == 0, "%s: memorysize touched in unmarshal\n", msgpfx);
483 /* if we're a server we still use the suppiled memory */
484 StubMsg.Buffer = StubMsg.BufferStart;
485 StubMsg.IsClient = 0;
486 ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, 0 );
487 ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
488 ok(mem == mem_orig, "%s: mem has changed %p %p\n", msgpfx, mem, mem_orig);
489 ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx);
490 ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
492 ok(StubMsg.MemorySize == 0, "%s: memorysize touched in unmarshal\n", msgpfx);
494 /* ...unless we pass a NULL ptr, then the buffer is used.
495 Passing a NULL ptr while we're a client && !must_alloc
496 crashes on Windows, so we won't do that. */
499 StubMsg.IsClient = 0;
500 StubMsg.Buffer = StubMsg.BufferStart;
501 ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, 0 );
502 ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
503 ok(mem == StubMsg.BufferStart, "%s: mem not equal buffer\n", msgpfx);
504 ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx);
505 ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
507 ok(StubMsg.MemorySize == 0, "%s: memorysize touched in unmarshal\n", msgpfx);
509 /*** now must_alloc is true ***/
511 /* with must_alloc set we always allocate new memory whether or not we're
512 a server and also when passing NULL */
514 StubMsg.IsClient = 1;
515 StubMsg.Buffer = StubMsg.BufferStart;
516 ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, 1 );
517 ok(ptr == NULL, "ret %p\n", ptr);
518 ok(mem != mem_orig, "mem not changed %p %p\n", mem, mem_orig);
519 ok(!cmp(mem, memsrc, srcsize), "incorrectly unmarshaled\n");
520 ok(my_alloc_called == num_additional_allocs + 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
522 ok(StubMsg.MemorySize == 0, "memorysize touched in unmarshal\n");
525 StubMsg.Buffer = StubMsg.BufferStart;
526 ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, 1 );
527 ok(ptr == NULL, "ret %p\n", ptr);
528 ok(mem != mem_orig, "mem not changed %p %p\n", mem, mem_orig);
529 ok(!cmp(mem, memsrc, srcsize), "incorrectly unmarshaled\n");
530 ok(my_alloc_called == num_additional_allocs + 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
532 ok(StubMsg.MemorySize == 0, "memorysize touched in unmarshal\n");
535 StubMsg.Buffer = StubMsg.BufferStart;
536 StubMsg.IsClient = 0;
537 StubMsg.ReuseBuffer = 1;
538 ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, 1 );
539 ok(ptr == NULL, "ret %p\n", ptr);
540 ok(mem != mem_orig, "mem not changed %p %p\n", mem, mem_orig);
541 ok(mem != StubMsg.BufferStart, "mem is buffer mem\n");
542 ok(!cmp(mem, memsrc, srcsize), "incorrectly unmarshaled\n");
543 ok(my_alloc_called == num_additional_allocs + 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
545 ok(StubMsg.MemorySize == 0, "memorysize touched in unmarshal\n");
548 StubMsg.Buffer = StubMsg.BufferStart;
549 StubMsg.IsClient = 0;
550 StubMsg.ReuseBuffer = 1;
551 ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, 1 );
552 ok(ptr == NULL, "ret %p\n", ptr);
553 ok(mem != StubMsg.BufferStart, "mem is buffer mem\n");
554 ok(!cmp(mem, memsrc, srcsize), "incorrectly unmarshaled\n");
555 ok(my_alloc_called == num_additional_allocs + 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
557 ok(StubMsg.MemorySize == 0, "memorysize touched in unmarshal\n");
568 static int ps1_cmp(const void *s1, const void *s2, size_t num)
570 const ps1_t *p1, *p2;
578 if(p1->pl1 && p2->pl1)
580 if(*p1->pl1 != *p2->pl1)
583 else if(p1->pl1 || p1->pl1)
586 if(p1->pc1 && p2->pc1)
588 if(*p1->pc1 != *p2->pc1)
591 else if(p1->pc1 || p1->pc1)
597 static void test_simple_struct(void)
599 unsigned char wiredata[28];
600 unsigned long wiredatalen;
605 static const unsigned char fmtstr_simple_struct[] =
607 0x12, 0x0, /* FC_UP */
608 NdrFcShort( 0x2 ), /* Offset=2 */
609 0x15, 0x3, /* FC_STRUCT [align 4] */
610 NdrFcShort( 0x18 ), /* [size 24] */
613 0x38, /* FC_ALIGNM4 */
616 0x39, /* FC_ALIGNM8 */
627 static const unsigned char fmtstr_pointer_struct[] =
629 0x12, 0x0, /* FC_UP */
630 NdrFcShort( 0x2 ), /* Offset=2 */
631 0x16, 0x3, /* FC_PSTRUCT [align 4] */
632 NdrFcShort( 0xc ), /* [size 12] */
635 0x46, /* FC_NO_REPEAT */
637 NdrFcShort( 0x4 ), /* 4 */
638 NdrFcShort( 0x4 ), /* 4 */
639 0x13, 0x8, /* FC_OP [simple_pointer] */
642 0x46, /* FC_NO_REPEAT */
644 NdrFcShort( 0x8 ), /* 8 */
645 NdrFcShort( 0x8 ), /* 8 */
646 0x13, 0x8, /* FC_OP [simple_pointer] */
663 s1.ll = ((LONGLONG) 0xbadefeed << 32) || 0x2468ace0;
666 memcpy(wiredata, &s1, wiredatalen);
667 test_simple_struct_marshal(fmtstr_simple_struct + 4, &s1, 24, wiredata, 24, NULL, 0, "struct");
669 *(void**)wiredata = &s1;
670 memcpy(wiredata + 4, &s1, wiredatalen);
671 #if 0 /* one of the unmarshallings crashes Wine */
672 test_pointer_marshal(fmtstr_simple_struct, &s1, 24, wiredata, 28, NULL, 0, "struct");
681 memcpy(wiredata + 4, &ps1, 12);
682 memcpy(wiredata + 16, &l, 4);
683 memcpy(wiredata + 20, &c, 1);
685 test_simple_struct_marshal(fmtstr_pointer_struct + 4, &ps1, 17, wiredata + 4, 17, ps1_cmp, 2, "pointer_struct");
686 *(void**)wiredata = &ps1;
687 #if 0 /* one of the unmarshallings crashes Wine */
688 test_pointer_marshal(fmtstr_pointer_struct, &ps1, 17, wiredata, 21, ps1_cmp, 2, "pointer_struct");
692 static void test_fullpointer_xlat(void)
694 PFULL_PTR_XLAT_TABLES pXlatTables;
699 pXlatTables = NdrFullPointerXlatInit(2, XLAT_CLIENT);
701 /* "marshaling" phase */
703 ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebeef, 1, &RefId);
704 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
705 ok(RefId == 0x1, "RefId should be 0x1 instead of 0x%lx\n", RefId);
707 ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebeef, 0, &RefId);
708 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
709 ok(RefId == 0x1, "RefId should be 0x1 instead of 0x%lx\n", RefId);
711 ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebabe, 0, &RefId);
712 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
713 ok(RefId == 0x2, "RefId should be 0x2 instead of 0x%lx\n", RefId);
715 ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xdeadbeef, 0, &RefId);
716 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
717 ok(RefId == 0x3, "RefId should be 0x3 instead of 0x%lx\n", RefId);
719 ret = NdrFullPointerQueryPointer(pXlatTables, NULL, 0, &RefId);
720 ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
721 ok(RefId == 0, "RefId should be 0 instead of 0x%lx\n", RefId);
723 /* "unmarshaling" phase */
725 ret = NdrFullPointerQueryRefId(pXlatTables, 0x2, 0, &Pointer);
726 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
727 ok(Pointer == (void *)0xcafebabe, "Pointer should be 0xcafebabe instead of %p\n", Pointer);
729 ret = NdrFullPointerQueryRefId(pXlatTables, 0x4, 0, &Pointer);
730 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
731 ok(Pointer == NULL, "Pointer should be NULL instead of %p\n", Pointer);
733 NdrFullPointerInsertRefId(pXlatTables, 0x4, (void *)0xdeadbabe);
735 ret = NdrFullPointerQueryRefId(pXlatTables, 0x4, 1, &Pointer);
736 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
737 ok(Pointer == (void *)0xdeadbabe, "Pointer should be (void *)0xdeadbabe instead of %p\n", Pointer);
739 NdrFullPointerXlatFree(pXlatTables);
741 pXlatTables = NdrFullPointerXlatInit(2, XLAT_SERVER);
743 /* "unmarshaling" phase */
745 ret = NdrFullPointerQueryRefId(pXlatTables, 0x2, 1, &Pointer);
746 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
747 ok(Pointer == NULL, "Pointer should be NULL instead of %p\n", Pointer);
749 NdrFullPointerInsertRefId(pXlatTables, 0x2, (void *)0xcafebabe);
751 ret = NdrFullPointerQueryRefId(pXlatTables, 0x2, 0, &Pointer);
752 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
753 ok(Pointer == (void *)0xcafebabe, "Pointer should be (void *)0xcafebabe instead of %p\n", Pointer);
755 ret = NdrFullPointerQueryRefId(pXlatTables, 0x2, 1, &Pointer);
756 ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
757 ok(Pointer == (void *)0xcafebabe, "Pointer should be (void *)0xcafebabe instead of %p\n", Pointer);
759 /* "marshaling" phase */
761 ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebeef, 1, &RefId);
762 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
763 ok(RefId == 0x3, "RefId should be 0x3 instead of 0x%lx\n", RefId);
765 ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebeef, 1, &RefId);
766 ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
767 ok(RefId == 0x3, "RefId should be 0x3 instead of 0x%lx\n", RefId);
769 ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebeef, 0, &RefId);
771 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
773 ok(RefId == 0x3, "RefId should be 0x3 instead of 0x%lx\n", RefId);
775 ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebabe, 0, &RefId);
776 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
777 ok(RefId == 0x2, "RefId should be 0x2 instead of 0x%lx\n", RefId);
779 ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xdeadbeef, 0, &RefId);
780 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
781 ok(RefId == 0x4, "RefId should be 0x4 instead of 0x%lx\n", RefId);
783 /* "freeing" phase */
785 ret = NdrFullPointerFree(pXlatTables, (void *)0xcafebeef);
786 ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
788 ret = NdrFullPointerFree(pXlatTables, (void *)0xcafebabe);
789 ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
791 ret = NdrFullPointerFree(pXlatTables, (void *)0xdeadbeef);
792 ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
794 NdrFullPointerXlatFree(pXlatTables);
797 START_TEST( ndr_marshall )
800 test_simple_struct();
801 test_fullpointer_xlat();