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
= &ll
;
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
);
728 ok(Pointer
== (void *)0xcafebabe, "Pointer should be 0xcafebabe instead of %p\n", Pointer
);
731 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x4, 0, &Pointer
);
732 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
733 ok(Pointer
== NULL
, "Pointer should be NULL instead of %p\n", Pointer
);
735 NdrFullPointerInsertRefId(pXlatTables
, 0x4, (void *)0xdeadbabe);
737 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x4, 1, &Pointer
);
738 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
740 ok(Pointer
== (void *)0xdeadbabe, "Pointer should be (void *)0xdeadbabe instead of %p\n", Pointer
);
743 NdrFullPointerXlatFree(pXlatTables
);
745 pXlatTables
= NdrFullPointerXlatInit(2, XLAT_SERVER
);
747 /* "unmarshaling" phase */
749 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x2, 1, &Pointer
);
750 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
751 ok(Pointer
== NULL
, "Pointer should be NULL instead of %p\n", Pointer
);
753 NdrFullPointerInsertRefId(pXlatTables
, 0x2, (void *)0xcafebabe);
755 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x2, 0, &Pointer
);
756 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
758 ok(Pointer
== (void *)0xcafebabe, "Pointer should be (void *)0xcafebabe instead of %p\n", Pointer
);
761 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x2, 1, &Pointer
);
763 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
764 ok(Pointer
== (void *)0xcafebabe, "Pointer should be (void *)0xcafebabe instead of %p\n", Pointer
);
767 /* "marshaling" phase */
769 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 1, &RefId
);
770 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
772 ok(RefId
== 0x3, "RefId should be 0x1 instead of 0x%lx\n", RefId
);
775 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 1, &RefId
);
776 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
778 ok(RefId
== 0x3, "RefId should be 0x1 instead of 0x%lx\n", RefId
);
781 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 0, &RefId
);
783 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
784 ok(RefId
== 0x3, "RefId should be 0x1 instead of 0x%lx\n", RefId
);
787 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebabe, 0, &RefId
);
788 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
789 ok(RefId
== 0x2, "RefId should be 0x2 instead of 0x%lx\n", RefId
);
791 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xdeadbeef, 0, &RefId
);
792 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
794 ok(RefId
== 0x4, "RefId should be 0x4 instead of 0x%lx\n", RefId
);
797 /* "freeing" phase */
800 ret
= NdrFullPointerFree(pXlatTables
, (void *)0xcafebeef);
801 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
803 ret
= NdrFullPointerFree(pXlatTables
, (void *)0xcafebabe);
804 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
806 ret
= NdrFullPointerFree(pXlatTables
, (void *)0xdeadbeef);
807 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
810 NdrFullPointerXlatFree(pXlatTables
);
813 START_TEST( ndr_marshall
)
816 test_simple_struct();
817 test_fullpointer_xlat();