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 #define NTDDI_WIN2K 0x05000000
24 #define NTDDI_VERSION NTDDI_WIN2K /* for some MIDL_STUB_MESSAGE fields */
26 #include "wine/test.h"
37 static int my_alloc_called
;
38 static int my_free_called
;
39 static void * CALLBACK
my_alloc(size_t size
)
42 return NdrOleAllocate(size
);
45 static void CALLBACK
my_free(void *ptr
)
51 static const MIDL_STUB_DESC Object_StubDesc
=
61 NULL
, /* format string, filled in by tests */
62 1, /* -error bounds_check flag */
63 0x20000, /* Ndr library version */
65 0x50100a4, /* MIDL Version 5.1.164 */
68 0, /* notify & notify_flag routine table */
76 static void test_ndr_simple_type(void)
78 RPC_MESSAGE RpcMessage
;
79 MIDL_STUB_MESSAGE StubMsg
;
80 MIDL_STUB_DESC StubDesc
;
83 StubDesc
= Object_StubDesc
;
84 StubDesc
.pFormatTypes
= NULL
;
86 NdrClientInitializeNew(
92 StubMsg
.BufferLength
= 16;
93 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
95 NdrSimpleTypeMarshall(&StubMsg
, (unsigned char*)&l
, 8 /* FC_LONG */);
96 ok(StubMsg
.Buffer
== StubMsg
.BufferStart
+ 4, "%p %p\n", StubMsg
.Buffer
, StubMsg
.BufferStart
);
97 ok(*(long*)StubMsg
.BufferStart
== l
, "%ld\n", *(long*)StubMsg
.BufferStart
);
99 StubMsg
.Buffer
= StubMsg
.BufferStart
+ 1;
100 NdrSimpleTypeMarshall(&StubMsg
, (unsigned char*)&l
, 8 /* FC_LONG */);
101 ok(StubMsg
.Buffer
== StubMsg
.BufferStart
+ 8, "%p %p\n", StubMsg
.Buffer
, StubMsg
.BufferStart
);
102 ok(*(long*)(StubMsg
.BufferStart
+ 4) == l
, "%ld\n", *(long*)StubMsg
.BufferStart
);
104 StubMsg
.Buffer
= StubMsg
.BufferStart
+ 1;
105 NdrSimpleTypeUnmarshall(&StubMsg
, (unsigned char*)&l2
, 8 /* FC_LONG */);
106 ok(StubMsg
.Buffer
== StubMsg
.BufferStart
+ 8, "%p %p\n", StubMsg
.Buffer
, StubMsg
.BufferStart
);
107 ok(l2
== l
, "%ld\n", l2
);
109 HeapFree(GetProcessHeap(), 0, StubMsg
.BufferStart
);
112 static void test_pointer_marshal(const unsigned char *formattypes
,
115 const void *wiredata
,
117 int(*cmp
)(const void*,const void*,size_t),
118 long num_additional_allocs
,
121 RPC_MESSAGE RpcMessage
;
122 MIDL_STUB_MESSAGE StubMsg
;
123 MIDL_STUB_DESC StubDesc
;
126 unsigned char *mem
, *mem_orig
;
128 my_alloc_called
= my_free_called
= 0;
132 StubDesc
= Object_StubDesc
;
133 StubDesc
.pFormatTypes
= formattypes
;
135 NdrClientInitializeNew(
141 StubMsg
.BufferLength
= 0;
142 NdrPointerBufferSize( &StubMsg
,
145 ok(StubMsg
.BufferLength
>= wiredatalen
, "%s: length %d\n", msgpfx
, StubMsg
.BufferLength
);
147 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
148 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
149 StubMsg
.BufferEnd
= StubMsg
.BufferStart
+ StubMsg
.BufferLength
;
151 memset(StubMsg
.BufferStart
, 0x0, StubMsg
.BufferLength
); /* This is a hack to clear the padding between the ptr and longlong/double */
153 ptr
= NdrPointerMarshall( &StubMsg
, memsrc
, formattypes
);
154 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
155 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
156 ok(!memcmp(StubMsg
.BufferStart
, wiredata
, wiredatalen
), "%s: incorrectly marshaled\n", msgpfx
);
158 StubMsg
.Buffer
= StubMsg
.BufferStart
;
159 StubMsg
.MemorySize
= 0;
163 /* NdrPointerMemorySize crashes under Wine */
164 size
= NdrPointerMemorySize( &StubMsg
, formattypes
);
165 ok(size
== StubMsg
.MemorySize
, "%s: mem size %u size %u\n", msgpfx
, StubMsg
.MemorySize
, size
);
166 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
167 if(formattypes
[1] & 0x10 /* FC_POINTER_DEREF */)
168 ok(size
== srcsize
+ 4, "%s: mem size %u\n", msgpfx
, size
);
170 ok(size
== srcsize
, "%s: mem size %u\n", msgpfx
, size
);
172 StubMsg
.Buffer
= StubMsg
.BufferStart
;
173 StubMsg
.MemorySize
= 16;
174 size
= NdrPointerMemorySize( &StubMsg
, formattypes
);
175 ok(size
== StubMsg
.MemorySize
, "%s: mem size %u size %u\n", msgpfx
, StubMsg
.MemorySize
, size
);
176 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
177 if(formattypes
[1] & 0x10 /* FC_POINTER_DEREF */)
178 ok(size
== srcsize
+ 4 + 16, "%s: mem size %u\n", msgpfx
, size
);
180 ok(size
== srcsize
+ 16, "%s: mem size %u\n", msgpfx
, size
);
182 StubMsg
.Buffer
= StubMsg
.BufferStart
;
183 StubMsg
.MemorySize
= 1;
184 size
= NdrPointerMemorySize( &StubMsg
, formattypes
);
185 ok(size
== StubMsg
.MemorySize
, "%s: mem size %u size %u\n", msgpfx
, StubMsg
.MemorySize
, size
);
186 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
187 if(formattypes
[1] & 0x10 /* FC_POINTER_DEREF */)
188 ok(size
== srcsize
+ 4 + (srcsize
== 8 ? 8 : 4), "%s: mem size %u\n", msgpfx
, size
);
190 ok(size
== srcsize
+ (srcsize
== 8 ? 8 : 4), "%s: mem size %u\n", msgpfx
, size
);
194 if(formattypes
[1] & 0x10) size
+= 4;
196 StubMsg
.Buffer
= StubMsg
.BufferStart
;
197 StubMsg
.MemorySize
= 0;
198 mem_orig
= mem
= HeapAlloc(GetProcessHeap(), 0, size
);
200 if(formattypes
[1] & 0x10 /* FC_POINTER_DEREF */)
202 ptr
= NdrPointerUnmarshall( &StubMsg
, &mem
, formattypes
, 0 );
203 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
204 ok(mem
== mem_orig
, "%s: mem has changed %p %p\n", msgpfx
, mem
, mem_orig
);
205 ok(!cmp(mem
, memsrc
, srcsize
), "%s: incorrectly unmarshaled\n", msgpfx
);
206 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
207 ok(StubMsg
.MemorySize
== 0, "%s: memorysize %d\n", msgpfx
, StubMsg
.MemorySize
);
208 ok(my_alloc_called
== num_additional_allocs
, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
211 /* reset the buffer and call with must alloc */
212 StubMsg
.Buffer
= StubMsg
.BufferStart
;
213 if(formattypes
[1] & 0x10 /* FC_POINTER_DEREF */)
215 ptr
= NdrPointerUnmarshall( &StubMsg
, &mem
, formattypes
, 1 );
216 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
217 /* doesn't allocate mem in this case */
219 ok(mem
== mem_orig
, "%s: mem has changed %p %p\n", msgpfx
, mem
, mem_orig
);
221 ok(!cmp(mem
, memsrc
, srcsize
), "%s: incorrectly unmarshaled\n", msgpfx
);
222 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
223 ok(StubMsg
.MemorySize
== 0, "%s: memorysize %d\n", msgpfx
, StubMsg
.MemorySize
);
226 ok(my_alloc_called
== num_additional_allocs
, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
229 if(formattypes
[0] != 0x11 /* FC_RP */)
231 /* now pass the address of a NULL ptr */
233 StubMsg
.Buffer
= StubMsg
.BufferStart
;
234 ptr
= NdrPointerUnmarshall( &StubMsg
, &mem
, formattypes
, 0 );
235 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
236 ok(mem
!= StubMsg
.BufferStart
+ wiredatalen
- srcsize
, "%s: mem points to buffer %p %p\n", msgpfx
, mem
, StubMsg
.BufferStart
);
237 ok(!cmp(mem
, memsrc
, size
), "%s: incorrectly unmarshaled\n", msgpfx
);
238 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
239 ok(StubMsg
.MemorySize
== 0, "%s: memorysize %d\n", msgpfx
, StubMsg
.MemorySize
);
240 ok(my_alloc_called
== num_additional_allocs
+ 1, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
242 NdrPointerFree(&StubMsg
, mem
, formattypes
);
244 /* again pass address of NULL ptr, but pretend we're a server */
246 StubMsg
.Buffer
= StubMsg
.BufferStart
;
247 StubMsg
.IsClient
= 0;
248 ptr
= NdrPointerUnmarshall( &StubMsg
, &mem
, formattypes
, 0 );
249 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
250 if (formattypes
[2] == 0xd /* FC_ENUM16 */)
251 ok(mem
!= StubMsg
.BufferStart
+ wiredatalen
- srcsize
, "%s: mem points to buffer %p %p\n", msgpfx
, mem
, StubMsg
.BufferStart
);
253 ok(mem
== StubMsg
.BufferStart
+ wiredatalen
- srcsize
, "%s: mem doesn't point to buffer %p %p\n", msgpfx
, mem
, StubMsg
.BufferStart
);
254 ok(!cmp(mem
, memsrc
, size
), "%s: incorrecly unmarshaled\n", msgpfx
);
255 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
256 ok(StubMsg
.MemorySize
== 0, "%s: memorysize %d\n", msgpfx
, StubMsg
.MemorySize
);
257 if (formattypes
[2] != 0xd /* FC_ENUM16 */) {
258 ok(my_alloc_called
== num_additional_allocs
, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
262 HeapFree(GetProcessHeap(), 0, mem_orig
);
263 HeapFree(GetProcessHeap(), 0, StubMsg
.BufferStart
);
266 static int deref_cmp(const void *s1
, const void *s2
, size_t num
)
268 return memcmp(*(const void *const *)s1
, *(const void *const *)s2
, num
);
272 static void test_simple_types(void)
274 unsigned char wiredata
[16];
276 unsigned char *ch_ptr
;
284 static const unsigned char fmtstr_up_char
[] =
286 0x12, 0x8, /* FC_UP [simple_pointer] */
290 static const unsigned char fmtstr_up_byte
[] =
292 0x12, 0x8, /* FC_UP [simple_pointer] */
296 static const unsigned char fmtstr_up_small
[] =
298 0x12, 0x8, /* FC_UP [simple_pointer] */
302 static const unsigned char fmtstr_up_usmall
[] =
304 0x12, 0x8, /* FC_UP [simple_pointer] */
308 static const unsigned char fmtstr_rp_char
[] =
310 0x11, 0x8, /* FC_RP [simple_pointer] */
314 static const unsigned char fmtstr_rpup_char
[] =
316 0x11, 0x14, /* FC_RP [alloced_on_stack] */
317 NdrFcShort( 0x2 ), /* Offset= 2 (4) */
318 0x12, 0x8, /* FC_UP [simple_pointer] */
322 static const unsigned char fmtstr_rpup_char2
[] =
324 0x11, 0x04, /* FC_RP [alloced_on_stack] */
325 NdrFcShort( 0x2 ), /* Offset= 2 (4) */
326 0x12, 0x8, /* FC_UP [simple_pointer] */
331 static const unsigned char fmtstr_up_wchar
[] =
333 0x12, 0x8, /* FC_UP [simple_pointer] */
337 static const unsigned char fmtstr_up_short
[] =
339 0x12, 0x8, /* FC_UP [simple_pointer] */
343 static const unsigned char fmtstr_up_ushort
[] =
345 0x12, 0x8, /* FC_UP [simple_pointer] */
349 static const unsigned char fmtstr_up_enum16
[] =
351 0x12, 0x8, /* FC_UP [simple_pointer] */
355 static const unsigned char fmtstr_up_long
[] =
357 0x12, 0x8, /* FC_UP [simple_pointer] */
361 static const unsigned char fmtstr_up_ulong
[] =
363 0x12, 0x8, /* FC_UP [simple_pointer] */
367 static const unsigned char fmtstr_up_enum32
[] =
369 0x12, 0x8, /* FC_UP [simple_pointer] */
373 static const unsigned char fmtstr_up_errorstatus
[] =
375 0x12, 0x8, /* FC_UP [simple_pointer] */
376 0x10, /* FC_ERROR_STATUS_T */
380 static const unsigned char fmtstr_up_longlong
[] =
382 0x12, 0x8, /* FC_UP [simple_pointer] */
386 static const unsigned char fmtstr_up_float
[] =
388 0x12, 0x8, /* FC_UP [simple_pointer] */
392 static const unsigned char fmtstr_up_double
[] =
394 0x12, 0x8, /* FC_UP [simple_pointer] */
401 *(void**)wiredata
= ch_ptr
;
402 wiredata
[sizeof(void*)] = ch
;
404 test_pointer_marshal(fmtstr_up_char
, ch_ptr
, 1, wiredata
, 5, NULL
, 0, "up_char");
405 test_pointer_marshal(fmtstr_up_byte
, ch_ptr
, 1, wiredata
, 5, NULL
, 0, "up_byte");
406 test_pointer_marshal(fmtstr_up_small
, ch_ptr
, 1, wiredata
, 5, NULL
, 0, "up_small");
407 test_pointer_marshal(fmtstr_up_usmall
, ch_ptr
, 1, wiredata
, 5, NULL
, 0, "up_usmall");
409 test_pointer_marshal(fmtstr_rp_char
, ch_ptr
, 1, &ch
, 1, NULL
, 0, "rp_char");
411 test_pointer_marshal(fmtstr_rpup_char
, &ch_ptr
, 1, wiredata
, 5, deref_cmp
, 1, "rpup_char");
412 test_pointer_marshal(fmtstr_rpup_char2
, ch_ptr
, 1, wiredata
, 5, NULL
, 0, "rpup_char2");
415 *(void**)wiredata
= &s
;
416 *(unsigned short*)(wiredata
+ sizeof(void*)) = s
;
418 test_pointer_marshal(fmtstr_up_wchar
, &s
, 2, wiredata
, 6, NULL
, 0, "up_wchar");
419 test_pointer_marshal(fmtstr_up_short
, &s
, 2, wiredata
, 6, NULL
, 0, "up_short");
420 test_pointer_marshal(fmtstr_up_ushort
, &s
, 2, wiredata
, 6, NULL
, 0, "up_ushort");
423 *(void**)wiredata
= &i
;
424 *(unsigned short*)(wiredata
+ sizeof(void*)) = i
;
425 test_pointer_marshal(fmtstr_up_enum16
, &i
, 2, wiredata
, 6, NULL
, 0, "up_enum16");
428 *(void**)wiredata
= &l
;
429 *(unsigned long*)(wiredata
+ sizeof(void*)) = l
;
431 test_pointer_marshal(fmtstr_up_long
, &l
, 4, wiredata
, 8, NULL
, 0, "up_long");
432 test_pointer_marshal(fmtstr_up_ulong
, &l
, 4, wiredata
, 8, NULL
, 0, "up_ulong");
433 test_pointer_marshal(fmtstr_up_enum32
, &l
, 4, wiredata
, 8, NULL
, 0, "up_emun32");
434 test_pointer_marshal(fmtstr_up_errorstatus
, &l
, 4, wiredata
, 8, NULL
, 0, "up_errorstatus");
436 ll
= ((ULONGLONG
)0xcafebabe) << 32 | 0xdeadbeef;
437 *(void**)wiredata
= &ll
;
438 *(void**)(wiredata
+ sizeof(void*)) = NULL
;
439 *(ULONGLONG
*)(wiredata
+ 2 * sizeof(void*)) = ll
;
440 test_pointer_marshal(fmtstr_up_longlong
, &ll
, 8, wiredata
, 16, NULL
, 0, "up_longlong");
443 *(void**)wiredata
= &f
;
444 *(float*)(wiredata
+ sizeof(void*)) = f
;
445 test_pointer_marshal(fmtstr_up_float
, &f
, 4, wiredata
, 8, NULL
, 0, "up_float");
448 *(void**)wiredata
= &d
;
449 *(void**)(wiredata
+ sizeof(void*)) = NULL
;
450 *(double*)(wiredata
+ 2 * sizeof(void*)) = d
;
451 test_pointer_marshal(fmtstr_up_double
, &d
, 8, wiredata
, 16, NULL
, 0, "up_double");
455 static void test_simple_struct_marshal(const unsigned char *formattypes
,
458 const void *wiredata
,
460 int(*cmp
)(const void*,const void*,size_t),
461 long num_additional_allocs
,
464 RPC_MESSAGE RpcMessage
;
465 MIDL_STUB_MESSAGE StubMsg
;
466 MIDL_STUB_DESC StubDesc
;
469 unsigned char *mem
, *mem_orig
;
471 my_alloc_called
= my_free_called
= 0;
475 StubDesc
= Object_StubDesc
;
476 StubDesc
.pFormatTypes
= formattypes
;
478 NdrClientInitializeNew(&RpcMessage
, &StubMsg
, &StubDesc
, 0);
480 StubMsg
.BufferLength
= 0;
481 NdrSimpleStructBufferSize( &StubMsg
, (unsigned char *)memsrc
, formattypes
);
482 ok(StubMsg
.BufferLength
>= wiredatalen
, "%s: length %d\n", msgpfx
, StubMsg
.BufferLength
);
483 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
484 StubMsg
.BufferEnd
= StubMsg
.BufferStart
+ StubMsg
.BufferLength
;
485 ptr
= NdrSimpleStructMarshall( &StubMsg
, (unsigned char*)memsrc
, formattypes
);
486 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
487 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
);
488 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));
492 /* FIXME: Causes Wine to crash */
493 StubMsg
.Buffer
= StubMsg
.BufferStart
;
494 StubMsg
.MemorySize
= 0;
495 size
= NdrSimpleStructMemorySize( &StubMsg
, formattypes
);
496 ok(size
== StubMsg
.MemorySize
, "%s: size != MemorySize\n", msgpfx
);
497 ok(size
== srcsize
, "%s: mem size %u\n", msgpfx
, size
);
498 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
);
500 StubMsg
.Buffer
= StubMsg
.BufferStart
;
501 size
= NdrSimpleStructMemorySize( &StubMsg
, formattypes
);
503 ok(size
== StubMsg
.MemorySize
, "%s: size != MemorySize\n", msgpfx
);
505 ok(StubMsg
.MemorySize
== ((srcsize
+ 3) & ~3) + srcsize
, "%s: mem size %u\n", msgpfx
, size
);
506 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
);
509 /*** Unmarshalling first with must_alloc false ***/
511 StubMsg
.Buffer
= StubMsg
.BufferStart
;
512 StubMsg
.MemorySize
= 0;
513 mem_orig
= mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, srcsize
);
514 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, 0 );
515 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
516 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
);
517 ok(mem
== mem_orig
, "%s: mem has changed %p %p\n", msgpfx
, mem
, mem_orig
);
518 ok(!cmp(mem
, memsrc
, srcsize
), "%s: incorrectly unmarshaled\n", msgpfx
);
519 ok(my_alloc_called
== num_additional_allocs
, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
521 ok(StubMsg
.MemorySize
== 0, "%s: memorysize touched in unmarshal\n", msgpfx
);
523 /* if we're a server we still use the suppiled memory */
524 StubMsg
.Buffer
= StubMsg
.BufferStart
;
525 StubMsg
.IsClient
= 0;
526 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, 0 );
527 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
528 ok(mem
== mem_orig
, "%s: mem has changed %p %p\n", msgpfx
, mem
, mem_orig
);
529 ok(!cmp(mem
, memsrc
, srcsize
), "%s: incorrectly unmarshaled\n", msgpfx
);
530 ok(my_alloc_called
== num_additional_allocs
, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
532 ok(StubMsg
.MemorySize
== 0, "%s: memorysize touched in unmarshal\n", msgpfx
);
534 /* ...unless we pass a NULL ptr, then the buffer is used.
535 Passing a NULL ptr while we're a client && !must_alloc
536 crashes on Windows, so we won't do that. */
539 StubMsg
.IsClient
= 0;
540 StubMsg
.Buffer
= StubMsg
.BufferStart
;
541 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, 0 );
542 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
543 ok(mem
== StubMsg
.BufferStart
, "%s: mem not equal buffer\n", msgpfx
);
544 ok(!cmp(mem
, memsrc
, srcsize
), "%s: incorrectly unmarshaled\n", msgpfx
);
545 ok(my_alloc_called
== num_additional_allocs
, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
547 ok(StubMsg
.MemorySize
== 0, "%s: memorysize touched in unmarshal\n", msgpfx
);
549 /*** now must_alloc is true ***/
551 /* with must_alloc set we always allocate new memory whether or not we're
552 a server and also when passing NULL */
554 StubMsg
.IsClient
= 1;
555 StubMsg
.Buffer
= StubMsg
.BufferStart
;
556 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, 1 );
557 ok(ptr
== NULL
, "ret %p\n", ptr
);
558 ok(mem
!= mem_orig
, "mem not changed %p %p\n", mem
, mem_orig
);
559 ok(!cmp(mem
, memsrc
, srcsize
), "incorrectly unmarshaled\n");
560 ok(my_alloc_called
== num_additional_allocs
+ 1, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
562 ok(StubMsg
.MemorySize
== 0, "memorysize touched in unmarshal\n");
565 StubMsg
.Buffer
= StubMsg
.BufferStart
;
566 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, 1 );
567 ok(ptr
== NULL
, "ret %p\n", ptr
);
568 ok(mem
!= mem_orig
, "mem not changed %p %p\n", mem
, mem_orig
);
569 ok(!cmp(mem
, memsrc
, srcsize
), "incorrectly unmarshaled\n");
570 ok(my_alloc_called
== num_additional_allocs
+ 1, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
572 ok(StubMsg
.MemorySize
== 0, "memorysize touched in unmarshal\n");
575 StubMsg
.Buffer
= StubMsg
.BufferStart
;
576 StubMsg
.IsClient
= 0;
577 StubMsg
.ReuseBuffer
= 1;
578 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, 1 );
579 ok(ptr
== NULL
, "ret %p\n", ptr
);
580 ok(mem
!= mem_orig
, "mem not changed %p %p\n", mem
, mem_orig
);
581 ok(mem
!= StubMsg
.BufferStart
, "mem is buffer mem\n");
582 ok(!cmp(mem
, memsrc
, srcsize
), "incorrectly unmarshaled\n");
583 ok(my_alloc_called
== num_additional_allocs
+ 1, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
585 ok(StubMsg
.MemorySize
== 0, "memorysize touched in unmarshal\n");
588 StubMsg
.Buffer
= StubMsg
.BufferStart
;
589 StubMsg
.IsClient
= 0;
590 StubMsg
.ReuseBuffer
= 1;
591 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, 1 );
592 ok(ptr
== NULL
, "ret %p\n", ptr
);
593 ok(mem
!= StubMsg
.BufferStart
, "mem is buffer mem\n");
594 ok(!cmp(mem
, memsrc
, srcsize
), "incorrectly unmarshaled\n");
595 ok(my_alloc_called
== num_additional_allocs
+ 1, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
597 ok(StubMsg
.MemorySize
== 0, "memorysize touched in unmarshal\n");
599 HeapFree(GetProcessHeap(), 0, mem_orig
);
600 HeapFree(GetProcessHeap(), 0, StubMsg
.BufferStart
);
610 static int ps1_cmp(const void *s1
, const void *s2
, size_t num
)
612 const ps1_t
*p1
, *p2
;
620 if(p1
->pl1
&& p2
->pl1
)
622 if(*p1
->pl1
!= *p2
->pl1
)
625 else if(p1
->pl1
|| p1
->pl1
)
628 if(p1
->pc1
&& p2
->pc1
)
630 if(*p1
->pc1
!= *p2
->pc1
)
633 else if(p1
->pc1
|| p1
->pc1
)
639 static void test_simple_struct(void)
641 unsigned char wiredata
[28];
642 unsigned long wiredatalen
;
647 static const unsigned char fmtstr_simple_struct
[] =
649 0x12, 0x0, /* FC_UP */
650 NdrFcShort( 0x2 ), /* Offset=2 */
651 0x15, 0x3, /* FC_STRUCT [align 4] */
652 NdrFcShort( 0x18 ), /* [size 24] */
655 0x38, /* FC_ALIGNM4 */
658 0x39, /* FC_ALIGNM8 */
669 static const unsigned char fmtstr_pointer_struct
[] =
671 0x12, 0x0, /* FC_UP */
672 NdrFcShort( 0x2 ), /* Offset=2 */
673 0x16, 0x3, /* FC_PSTRUCT [align 4] */
674 NdrFcShort( 0xc ), /* [size 12] */
677 0x46, /* FC_NO_REPEAT */
679 NdrFcShort( 0x4 ), /* 4 */
680 NdrFcShort( 0x4 ), /* 4 */
681 0x13, 0x8, /* FC_OP [simple_pointer] */
684 0x46, /* FC_NO_REPEAT */
686 NdrFcShort( 0x8 ), /* 8 */
687 NdrFcShort( 0x8 ), /* 8 */
688 0x13, 0x8, /* FC_OP [simple_pointer] */
705 s1
.ll
= ((LONGLONG
) 0xbadefeed << 32) | 0x2468ace0;
708 memcpy(wiredata
, &s1
, wiredatalen
);
709 test_simple_struct_marshal(fmtstr_simple_struct
+ 4, &s1
, 24, wiredata
, 24, NULL
, 0, "struct");
711 *(void**)wiredata
= &s1
;
712 memcpy(wiredata
+ 4, &s1
, wiredatalen
);
715 /* one of the unmarshallings crashes Wine */
716 test_pointer_marshal(fmtstr_simple_struct
, &s1
, 24, wiredata
, 28, NULL
, 0, "struct");
725 memcpy(wiredata
+ 4, &ps1
, 12);
726 memcpy(wiredata
+ 16, &l
, 4);
727 memcpy(wiredata
+ 20, &c
, 1);
729 test_simple_struct_marshal(fmtstr_pointer_struct
+ 4, &ps1
, 17, wiredata
+ 4, 17, ps1_cmp
, 2, "pointer_struct");
730 *(void**)wiredata
= &ps1
;
733 /* one of the unmarshallings crashes Wine */
734 test_pointer_marshal(fmtstr_pointer_struct
, &ps1
, 17, wiredata
, 21, ps1_cmp
, 2, "pointer_struct");
738 static void test_fullpointer_xlat(void)
740 PFULL_PTR_XLAT_TABLES pXlatTables
;
745 pXlatTables
= NdrFullPointerXlatInit(2, XLAT_CLIENT
);
747 /* "marshaling" phase */
749 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 1, &RefId
);
750 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
751 ok(RefId
== 0x1, "RefId should be 0x1 instead of 0x%x\n", RefId
);
753 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 0, &RefId
);
754 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
755 ok(RefId
== 0x1, "RefId should be 0x1 instead of 0x%x\n", RefId
);
757 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebabe, 0, &RefId
);
758 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
759 ok(RefId
== 0x2, "RefId should be 0x2 instead of 0x%x\n", RefId
);
761 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xdeadbeef, 0, &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%x\n", RefId
);
765 ret
= NdrFullPointerQueryPointer(pXlatTables
, NULL
, 0, &RefId
);
766 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
767 ok(RefId
== 0, "RefId should be 0 instead of 0x%x\n", RefId
);
769 /* "unmarshaling" phase */
771 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x2, 0, &Pointer
);
772 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
773 ok(Pointer
== (void *)0xcafebabe, "Pointer should be 0xcafebabe instead of %p\n", Pointer
);
775 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x4, 0, &Pointer
);
776 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
777 ok(Pointer
== NULL
, "Pointer should be NULL instead of %p\n", Pointer
);
779 NdrFullPointerInsertRefId(pXlatTables
, 0x4, (void *)0xdeadbabe);
781 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x4, 1, &Pointer
);
782 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
783 ok(Pointer
== (void *)0xdeadbabe, "Pointer should be (void *)0xdeadbabe instead of %p\n", Pointer
);
785 NdrFullPointerXlatFree(pXlatTables
);
787 pXlatTables
= NdrFullPointerXlatInit(2, XLAT_SERVER
);
789 /* "unmarshaling" phase */
791 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x2, 1, &Pointer
);
792 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
793 ok(Pointer
== NULL
, "Pointer should be NULL instead of %p\n", Pointer
);
795 NdrFullPointerInsertRefId(pXlatTables
, 0x2, (void *)0xcafebabe);
797 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x2, 0, &Pointer
);
798 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
799 ok(Pointer
== (void *)0xcafebabe, "Pointer should be (void *)0xcafebabe instead of %p\n", Pointer
);
801 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x2, 1, &Pointer
);
802 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
803 ok(Pointer
== (void *)0xcafebabe, "Pointer should be (void *)0xcafebabe instead of %p\n", Pointer
);
805 /* "marshaling" phase */
807 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 1, &RefId
);
808 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
809 ok(RefId
== 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId
);
811 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 1, &RefId
);
812 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
813 ok(RefId
== 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId
);
815 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 0, &RefId
);
816 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
817 ok(RefId
== 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId
);
819 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebabe, 0, &RefId
);
820 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
821 ok(RefId
== 0x2, "RefId should be 0x2 instead of 0x%x\n", RefId
);
823 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xdeadbeef, 0, &RefId
);
824 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
825 ok(RefId
== 0x4, "RefId should be 0x4 instead of 0x%x\n", RefId
);
827 /* "freeing" phase */
829 ret
= NdrFullPointerFree(pXlatTables
, (void *)0xcafebeef);
830 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
832 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 0x20, &RefId
);
833 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
834 ok(RefId
== 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId
);
836 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 1, &RefId
);
837 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
838 ok(RefId
== 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId
);
840 ret
= NdrFullPointerFree(pXlatTables
, (void *)0xcafebabe);
841 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
843 ret
= NdrFullPointerFree(pXlatTables
, (void *)0xdeadbeef);
844 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
846 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xdeadbeef, 0x20, &RefId
);
847 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
848 ok(RefId
== 0x4, "RefId should be 0x4 instead of 0x%x\n", RefId
);
850 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xdeadbeef, 1, &RefId
);
851 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
852 ok(RefId
== 0x4, "RefId should be 0x4 instead of 0x%x\n", RefId
);
854 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xdeadbeef, 1, &RefId
);
855 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
856 ok(RefId
== 0x4, "RefId should be 0x4 instead of 0x%x\n", RefId
);
858 ret
= NdrFullPointerFree(pXlatTables
, (void *)0xdeadbeef);
859 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
861 NdrFullPointerXlatFree(pXlatTables
);
864 static void test_client_init(void)
866 MIDL_STUB_MESSAGE stubMsg
;
869 memset(&stubMsg
, 0xcc, sizeof(stubMsg
));
871 NdrClientInitializeNew(&rpcMsg
, &stubMsg
, &Object_StubDesc
, 1);
873 #define TEST_ZERO(field, fmt) ok(stubMsg.field == 0, #field " should have be set to zero instead of " fmt "\n", stubMsg.field)
874 #define TEST_POINTER_UNSET(field) ok(stubMsg.field == (void *)0xcccccccc, #field " should have be unset instead of %p\n", stubMsg.field)
875 #define TEST_ULONG_UNSET(field) ok(stubMsg.field == 0xcccccccc, #field " should have be unset instead of 0x%x\n", stubMsg.field)
876 #define TEST_ULONG_PTR_UNSET(field) ok(stubMsg.field == 0xcccccccc, #field " should have be unset instead of 0x%lx\n", stubMsg.field)
878 ok(stubMsg
.RpcMsg
== &rpcMsg
, "stubMsg.RpcMsg should have been %p instead of %p\n", &rpcMsg
, stubMsg
.RpcMsg
);
879 TEST_POINTER_UNSET(Buffer
);
880 TEST_ZERO(BufferStart
, "%p");
881 TEST_ZERO(BufferEnd
, "%p");
882 TEST_POINTER_UNSET(BufferMark
);
883 TEST_ZERO(BufferLength
, "%d");
884 TEST_ULONG_UNSET(MemorySize
);
885 TEST_POINTER_UNSET(Memory
);
886 ok(stubMsg
.IsClient
== 1, "stubMsg.IsClient should have been 1 instead of %u\n", stubMsg
.IsClient
);
887 TEST_ZERO(ReuseBuffer
, "%d");
888 TEST_ZERO(pAllocAllNodesContext
, "%p");
889 TEST_ZERO(pPointerQueueState
, "%p");
890 TEST_ZERO(IgnoreEmbeddedPointers
, "%d");
891 TEST_ZERO(PointerBufferMark
, "%p");
892 TEST_ZERO(fBufferValid
, "%d");
893 TEST_ZERO(uFlags
, "%d");
894 /* FIXME: UniquePtrCount */
895 TEST_ULONG_PTR_UNSET(MaxCount
);
896 TEST_ULONG_UNSET(Offset
);
897 TEST_ULONG_UNSET(ActualCount
);
898 ok(stubMsg
.pfnAllocate
== my_alloc
, "stubMsg.pfnAllocate should have been %p instead of %p\n", my_alloc
, stubMsg
.pfnAllocate
);
899 ok(stubMsg
.pfnFree
== my_free
, "stubMsg.pfnFree should have been %p instead of %p\n", my_free
, stubMsg
.pfnFree
);
900 TEST_ZERO(StackTop
, "%p");
901 TEST_POINTER_UNSET(pPresentedType
);
902 TEST_POINTER_UNSET(pTransmitType
);
903 TEST_POINTER_UNSET(SavedHandle
);
904 ok(stubMsg
.StubDesc
== &Object_StubDesc
, "stubMsg.StubDesc should have been %p instead of %p\n", &Object_StubDesc
, stubMsg
.StubDesc
);
905 TEST_POINTER_UNSET(FullPtrXlatTables
);
906 TEST_ZERO(FullPtrRefId
, "%d");
907 TEST_ZERO(PointerLength
, "%d");
908 TEST_ZERO(fInDontFree
, "%d");
909 TEST_ZERO(fDontCallFreeInst
, "%d");
910 TEST_ZERO(fInOnlyParam
, "%d");
911 TEST_ZERO(fHasReturn
, "%d");
912 TEST_ZERO(fHasExtensions
, "%d");
913 TEST_ZERO(fHasNewCorrDesc
, "%d");
914 TEST_ZERO(fUnused
, "%d");
915 ok(stubMsg
.fUnused2
== 0xffffcccc, "stubMsg.fUnused2 should have been 0xcccc instead of 0x%x\n", stubMsg
.fUnused2
);
916 ok(stubMsg
.dwDestContext
== MSHCTX_DIFFERENTMACHINE
, "stubMsg.dwDestContext should have been MSHCTX_DIFFERENTMACHINE instead of %d\n", stubMsg
.dwDestContext
);
917 TEST_ZERO(pvDestContext
, "%p");
918 TEST_POINTER_UNSET(SavedContextHandles
);
919 TEST_ULONG_UNSET(ParamNumber
);
920 TEST_ZERO(pRpcChannelBuffer
, "%p");
921 TEST_ZERO(pArrayInfo
, "%p");
922 TEST_POINTER_UNSET(SizePtrCountArray
);
923 TEST_POINTER_UNSET(SizePtrOffsetArray
);
924 TEST_POINTER_UNSET(SizePtrLengthArray
);
925 TEST_POINTER_UNSET(pArgQueue
);
926 TEST_ZERO(dwStubPhase
, "%d");
927 /* FIXME: where does this value come from? */
928 trace("LowStackMark is %p\n", stubMsg
.LowStackMark
);
929 TEST_ZERO(pAsyncMsg
, "%p");
930 TEST_ZERO(pCorrInfo
, "%p");
931 TEST_ZERO(pCorrMemory
, "%p");
932 TEST_ZERO(pMemoryList
, "%p");
933 TEST_POINTER_UNSET(pCSInfo
);
934 TEST_POINTER_UNSET(ConformanceMark
);
935 TEST_POINTER_UNSET(VarianceMark
);
936 ok(stubMsg
.Unused
== 0xcccccccc, "Unused should have be unset instead of 0x%lx\n", stubMsg
.Unused
);
937 TEST_POINTER_UNSET(pContext
);
938 TEST_POINTER_UNSET(ContextHandleHash
);
939 TEST_POINTER_UNSET(pUserMarshalList
);
940 TEST_ULONG_PTR_UNSET(Reserved51_3
);
941 TEST_ULONG_PTR_UNSET(Reserved51_4
);
942 TEST_ULONG_PTR_UNSET(Reserved51_5
);
943 #undef TEST_ULONG_UNSET
944 #undef TEST_POINTER_UNSET
949 static void test_ndr_allocate(void)
951 RPC_MESSAGE RpcMessage
;
952 MIDL_STUB_MESSAGE StubMsg
;
953 MIDL_STUB_DESC StubDesc
;
955 struct tag_mem_list_v1_t
959 struct tag_mem_list_v1_t
*next
;
961 struct tag_mem_list_v2_t
966 struct tag_mem_list_v2_t
*next
;
968 const DWORD magic_MEML
= 'M' << 24 | 'E' << 16 | 'M' << 8 | 'L';
970 StubDesc
= Object_StubDesc
;
971 NdrClientInitializeNew(&RpcMessage
, &StubMsg
, &StubDesc
, 0);
973 ok(StubMsg
.pMemoryList
== NULL
, "memlist %p\n", StubMsg
.pMemoryList
);
974 my_alloc_called
= my_free_called
= 0;
975 p1
= NdrAllocate(&StubMsg
, 10);
976 p2
= NdrAllocate(&StubMsg
, 24);
977 ok(my_alloc_called
== 2, "alloc called %d\n", my_alloc_called
);
978 ok(StubMsg
.pMemoryList
!= NULL
, "StubMsg.pMemoryList NULL\n");
979 if(StubMsg
.pMemoryList
)
981 mem_list_v2
= StubMsg
.pMemoryList
;
982 if (mem_list_v2
->size
== 24)
984 trace("v2 mem list format\n");
985 ok((char *)mem_list_v2
== (char *)p2
+ 24, "expected mem_list_v2 pointer %p, but got %p\n", (char *)p2
+ 24, mem_list_v2
);
986 ok(mem_list_v2
->magic
== magic_MEML
, "magic %08x\n", mem_list_v2
->magic
);
987 ok(mem_list_v2
->size
== 24, "wrong size for p2 %d\n", mem_list_v2
->size
);
988 ok(mem_list_v2
->unknown
== 0, "wrong unknown for p2 0x%x\n", mem_list_v2
->unknown
);
989 ok(mem_list_v2
->next
!= NULL
, "next NULL\n");
990 mem_list_v2
= mem_list_v2
->next
;
993 ok((char *)mem_list_v2
== (char *)p1
+ 16, "expected mem_list_v2 pointer %p, but got %p\n", (char *)p1
+ 16, mem_list_v2
);
994 ok(mem_list_v2
->magic
== magic_MEML
, "magic %08x\n", mem_list_v2
->magic
);
995 ok(mem_list_v2
->size
== 16, "wrong size for p1 %d\n", mem_list_v2
->size
);
996 ok(mem_list_v2
->unknown
== 0, "wrong unknown for p1 0x%x\n", mem_list_v2
->unknown
);
997 ok(mem_list_v2
->next
== NULL
, "next %p\n", mem_list_v2
->next
);
1002 trace("v1 mem list format\n");
1003 mem_list_v1
= StubMsg
.pMemoryList
;
1004 ok(mem_list_v1
->magic
== magic_MEML
, "magic %08x\n", mem_list_v1
->magic
);
1005 ok(mem_list_v1
->ptr
== p2
, "ptr != p2\n");
1006 ok(mem_list_v1
->next
!= NULL
, "next NULL\n");
1007 mem_list_v1
= mem_list_v1
->next
;
1010 ok(mem_list_v1
->magic
== magic_MEML
, "magic %08x\n", mem_list_v1
->magic
);
1011 ok(mem_list_v1
->ptr
== p1
, "ptr != p1\n");
1012 ok(mem_list_v1
->next
== NULL
, "next %p\n", mem_list_v1
->next
);
1016 /* NdrFree isn't exported so we can't test free'ing */
1019 static void test_conformant_array(void)
1021 RPC_MESSAGE RpcMessage
;
1022 MIDL_STUB_MESSAGE StubMsg
;
1023 MIDL_STUB_DESC StubDesc
;
1025 unsigned char *mem
, *mem_orig
;
1026 unsigned char memsrc
[20];
1028 static const unsigned char fmtstr_conf_array
[] =
1030 0x1b, /* FC_CARRAY */
1032 NdrFcShort( 0x1 ), /* elem size */
1033 0x40, /* Corr desc: const */
1035 NdrFcShort(0x10), /* const = 0x10 */
1040 StubDesc
= Object_StubDesc
;
1041 StubDesc
.pFormatTypes
= fmtstr_conf_array
;
1043 NdrClientInitializeNew(
1049 StubMsg
.BufferLength
= 0;
1050 NdrConformantArrayBufferSize( &StubMsg
,
1052 fmtstr_conf_array
);
1053 ok(StubMsg
.BufferLength
>= 20, "length %d\n", StubMsg
.BufferLength
);
1055 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
1056 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
1057 StubMsg
.BufferEnd
= StubMsg
.BufferStart
+ StubMsg
.BufferLength
;
1059 ptr
= NdrConformantArrayMarshall( &StubMsg
, memsrc
, fmtstr_conf_array
);
1060 ok(ptr
== NULL
, "ret %p\n", ptr
);
1061 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== 20, "Buffer %p Start %p len %d\n", StubMsg
.Buffer
, StubMsg
.BufferStart
, 20);
1062 ok(!memcmp(StubMsg
.BufferStart
+ 4, memsrc
, 16), "incorrectly marshaled\n");
1064 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1065 StubMsg
.MemorySize
= 0;
1069 my_alloc_called
= 0;
1070 /* passing mem == NULL with must_alloc == 0 crashes under Windows */
1071 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 1);
1072 ok(mem
!= NULL
, "mem not alloced\n");
1073 ok(mem
!= StubMsg
.BufferStart
+ 4, "mem pointing at buffer\n");
1074 ok(my_alloc_called
== 1, "alloc called %d\n", my_alloc_called
);
1076 my_alloc_called
= 0;
1077 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1079 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 0);
1080 ok(mem
== mem_orig
, "mem alloced\n");
1081 ok(mem
!= StubMsg
.BufferStart
+ 4, "mem pointing at buffer\n");
1082 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1084 my_alloc_called
= 0;
1085 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1086 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 1);
1087 ok(mem
!= mem_orig
, "mem not alloced\n");
1088 ok(mem
!= StubMsg
.BufferStart
+ 4, "mem pointing at buffer\n");
1089 ok(my_alloc_called
== 1, "alloc called %d\n", my_alloc_called
);
1092 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1093 NdrConformantArrayFree( &StubMsg
, mem
, fmtstr_conf_array
);
1094 ok(my_free_called
== 0, "free called %d\n", my_free_called
);
1095 StubMsg
.pfnFree(mem
);
1098 my_alloc_called
= 0;
1099 StubMsg
.IsClient
= 0;
1101 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1102 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 0);
1103 ok(mem
== StubMsg
.BufferStart
+ 4, "mem not pointing at buffer\n");
1104 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1105 my_alloc_called
= 0;
1107 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1108 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 1);
1109 ok(mem
!= StubMsg
.BufferStart
+ 4, "mem pointing at buffer\n");
1110 ok(my_alloc_called
== 1, "alloc called %d\n", my_alloc_called
);
1111 StubMsg
.pfnFree(mem
);
1113 my_alloc_called
= 0;
1115 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1116 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 0);
1117 ok(mem
== mem_orig
, "mem alloced\n");
1118 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1120 my_alloc_called
= 0;
1122 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1123 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 1);
1124 ok(mem
!= StubMsg
.BufferStart
+ 4, "mem pointing at buffer\n");
1125 ok(my_alloc_called
== 1, "alloc called %d\n", my_alloc_called
);
1126 StubMsg
.pfnFree(mem
);
1127 StubMsg
.pfnFree(mem_orig
);
1129 HeapFree(GetProcessHeap(), 0, StubMsg
.RpcMsg
->Buffer
);
1132 static void test_conformant_string(void)
1134 RPC_MESSAGE RpcMessage
;
1135 MIDL_STUB_MESSAGE StubMsg
;
1136 MIDL_STUB_DESC StubDesc
;
1138 unsigned char *mem
, *mem_orig
;
1139 char memsrc
[] = "This is a test string";
1141 static const unsigned char fmtstr_conf_str
[] =
1143 0x11, 0x8, /* FC_RP [simple_pointer] */
1144 0x22, /* FC_C_CSTRING */
1148 StubDesc
= Object_StubDesc
;
1149 StubDesc
.pFormatTypes
= fmtstr_conf_str
;
1151 NdrClientInitializeNew(
1157 StubMsg
.BufferLength
= 0;
1158 NdrPointerBufferSize( &StubMsg
,
1159 (unsigned char *)memsrc
,
1161 ok(StubMsg
.BufferLength
>= sizeof(memsrc
) + 12, "length %d\n", StubMsg
.BufferLength
);
1163 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
1164 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
1165 StubMsg
.BufferEnd
= StubMsg
.BufferStart
+ StubMsg
.BufferLength
;
1167 ptr
= NdrPointerMarshall( &StubMsg
, (unsigned char *)memsrc
, fmtstr_conf_str
);
1168 ok(ptr
== NULL
, "ret %p\n", ptr
);
1169 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== sizeof(memsrc
) + 12, "Buffer %p Start %p len %d\n",
1170 StubMsg
.Buffer
, StubMsg
.BufferStart
, StubMsg
.Buffer
- StubMsg
.BufferStart
);
1171 ok(!memcmp(StubMsg
.BufferStart
+ 12, memsrc
, sizeof(memsrc
)), "incorrectly marshaled\n");
1173 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1174 StubMsg
.MemorySize
= 0;
1178 my_alloc_called
= 0;
1179 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1180 mem
= mem_orig
= HeapAlloc(GetProcessHeap(), 0, sizeof(memsrc
));
1181 NdrPointerUnmarshall( &StubMsg
, &mem
, fmtstr_conf_str
, 0);
1182 ok(mem
== mem_orig
, "mem not alloced\n");
1183 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1185 my_alloc_called
= 0;
1186 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1187 NdrPointerUnmarshall( &StubMsg
, &mem
, fmtstr_conf_str
, 1);
1189 ok(mem
== mem_orig
, "mem not alloced\n");
1190 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1194 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1195 NdrPointerFree( &StubMsg
, mem
, fmtstr_conf_str
);
1196 ok(my_free_called
== 1, "free called %d\n", my_free_called
);
1200 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1201 NdrPointerFree( &StubMsg
, mem
, fmtstr_conf_str
);
1203 ok(my_free_called
== 1, "free called %d\n", my_free_called
);
1207 my_alloc_called
= 0;
1208 StubMsg
.IsClient
= 0;
1210 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1211 NdrPointerUnmarshall( &StubMsg
, &mem
, fmtstr_conf_str
, 0);
1213 ok(mem
== StubMsg
.BufferStart
+ 12, "mem not pointing at buffer\n");
1214 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1216 my_alloc_called
= 0;
1218 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1219 NdrPointerUnmarshall( &StubMsg
, &mem
, fmtstr_conf_str
, 1);
1221 ok(mem
== StubMsg
.BufferStart
+ 12, "mem not pointing at buffer\n");
1222 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1225 my_alloc_called
= 0;
1227 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1228 NdrPointerUnmarshall( &StubMsg
, &mem
, fmtstr_conf_str
, 0);
1230 ok(mem
== StubMsg
.BufferStart
+ 12, "mem not pointing at buffer\n");
1231 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1234 my_alloc_called
= 0;
1236 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1237 NdrPointerUnmarshall( &StubMsg
, &mem
, fmtstr_conf_str
, 1);
1239 ok(mem
== StubMsg
.BufferStart
+ 12, "mem not pointing at buffer\n");
1240 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1245 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1246 NdrPointerFree( &StubMsg
, mem
, fmtstr_conf_str
);
1248 ok(my_free_called
== 1, "free called %d\n", my_free_called
);
1251 HeapFree(GetProcessHeap(), 0, mem_orig
);
1252 HeapFree(GetProcessHeap(), 0, StubMsg
.RpcMsg
->Buffer
);
1255 START_TEST( ndr_marshall
)
1257 test_ndr_simple_type();
1258 test_simple_types();
1259 test_simple_struct();
1260 test_fullpointer_xlat();
1262 test_ndr_allocate();
1263 test_conformant_array();
1264 test_conformant_string();