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
);
251 ok(mem
== StubMsg
.BufferStart
+ wiredatalen
- srcsize
, "%s: mem doesn't point to buffer %p %p\n", msgpfx
, mem
, StubMsg
.BufferStart
);
253 ok(!cmp(mem
, memsrc
, size
), "%s: incorrecly unmarshaled\n", msgpfx
);
254 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
255 ok(StubMsg
.MemorySize
== 0, "%s: memorysize %d\n", msgpfx
, StubMsg
.MemorySize
);
257 ok(my_alloc_called
== num_additional_allocs
, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
261 HeapFree(GetProcessHeap(), 0, mem_orig
);
262 HeapFree(GetProcessHeap(), 0, StubMsg
.BufferStart
);
265 static int deref_cmp(const void *s1
, const void *s2
, size_t num
)
267 return memcmp(*(const void *const *)s1
, *(const void *const *)s2
, num
);
271 static void test_simple_types(void)
273 unsigned char wiredata
[16];
275 unsigned char *ch_ptr
;
283 static const unsigned char fmtstr_up_char
[] =
285 0x12, 0x8, /* FC_UP [simple_pointer] */
289 static const unsigned char fmtstr_up_byte
[] =
291 0x12, 0x8, /* FC_UP [simple_pointer] */
295 static const unsigned char fmtstr_up_small
[] =
297 0x12, 0x8, /* FC_UP [simple_pointer] */
301 static const unsigned char fmtstr_up_usmall
[] =
303 0x12, 0x8, /* FC_UP [simple_pointer] */
307 static const unsigned char fmtstr_rp_char
[] =
309 0x11, 0x8, /* FC_RP [simple_pointer] */
313 static const unsigned char fmtstr_rpup_char
[] =
315 0x11, 0x14, /* FC_RP [alloced_on_stack] */
316 NdrFcShort( 0x2 ), /* Offset= 2 (4) */
317 0x12, 0x8, /* FC_UP [simple_pointer] */
321 static const unsigned char fmtstr_rpup_char2
[] =
323 0x11, 0x04, /* FC_RP [alloced_on_stack] */
324 NdrFcShort( 0x2 ), /* Offset= 2 (4) */
325 0x12, 0x8, /* FC_UP [simple_pointer] */
330 static const unsigned char fmtstr_up_wchar
[] =
332 0x12, 0x8, /* FC_UP [simple_pointer] */
336 static const unsigned char fmtstr_up_short
[] =
338 0x12, 0x8, /* FC_UP [simple_pointer] */
342 static const unsigned char fmtstr_up_ushort
[] =
344 0x12, 0x8, /* FC_UP [simple_pointer] */
348 static const unsigned char fmtstr_up_enum16
[] =
350 0x12, 0x8, /* FC_UP [simple_pointer] */
354 static const unsigned char fmtstr_up_long
[] =
356 0x12, 0x8, /* FC_UP [simple_pointer] */
360 static const unsigned char fmtstr_up_ulong
[] =
362 0x12, 0x8, /* FC_UP [simple_pointer] */
366 static const unsigned char fmtstr_up_enum32
[] =
368 0x12, 0x8, /* FC_UP [simple_pointer] */
372 static const unsigned char fmtstr_up_errorstatus
[] =
374 0x12, 0x8, /* FC_UP [simple_pointer] */
375 0x10, /* FC_ERROR_STATUS_T */
379 static const unsigned char fmtstr_up_longlong
[] =
381 0x12, 0x8, /* FC_UP [simple_pointer] */
385 static const unsigned char fmtstr_up_float
[] =
387 0x12, 0x8, /* FC_UP [simple_pointer] */
391 static const unsigned char fmtstr_up_double
[] =
393 0x12, 0x8, /* FC_UP [simple_pointer] */
400 *(void**)wiredata
= ch_ptr
;
401 wiredata
[sizeof(void*)] = ch
;
403 test_pointer_marshal(fmtstr_up_char
, ch_ptr
, 1, wiredata
, 5, NULL
, 0, "up_char");
404 test_pointer_marshal(fmtstr_up_byte
, ch_ptr
, 1, wiredata
, 5, NULL
, 0, "up_byte");
405 test_pointer_marshal(fmtstr_up_small
, ch_ptr
, 1, wiredata
, 5, NULL
, 0, "up_small");
406 test_pointer_marshal(fmtstr_up_usmall
, ch_ptr
, 1, wiredata
, 5, NULL
, 0, "up_usmall");
408 test_pointer_marshal(fmtstr_rp_char
, ch_ptr
, 1, &ch
, 1, NULL
, 0, "rp_char");
410 test_pointer_marshal(fmtstr_rpup_char
, &ch_ptr
, 1, wiredata
, 5, deref_cmp
, 1, "rpup_char");
411 test_pointer_marshal(fmtstr_rpup_char2
, ch_ptr
, 1, wiredata
, 5, NULL
, 0, "rpup_char2");
414 *(void**)wiredata
= &s
;
415 *(unsigned short*)(wiredata
+ sizeof(void*)) = s
;
417 test_pointer_marshal(fmtstr_up_wchar
, &s
, 2, wiredata
, 6, NULL
, 0, "up_wchar");
418 test_pointer_marshal(fmtstr_up_short
, &s
, 2, wiredata
, 6, NULL
, 0, "up_short");
419 test_pointer_marshal(fmtstr_up_ushort
, &s
, 2, wiredata
, 6, NULL
, 0, "up_ushort");
422 *(void**)wiredata
= &i
;
423 test_pointer_marshal(fmtstr_up_enum16
, &i
, 2, wiredata
, 6, NULL
, 0, "up_enum16");
426 *(void**)wiredata
= &l
;
427 *(unsigned long*)(wiredata
+ sizeof(void*)) = l
;
429 test_pointer_marshal(fmtstr_up_long
, &l
, 4, wiredata
, 8, NULL
, 0, "up_long");
430 test_pointer_marshal(fmtstr_up_ulong
, &l
, 4, wiredata
, 8, NULL
, 0, "up_ulong");
431 test_pointer_marshal(fmtstr_up_enum32
, &l
, 4, wiredata
, 8, NULL
, 0, "up_emun32");
432 test_pointer_marshal(fmtstr_up_errorstatus
, &l
, 4, wiredata
, 8, NULL
, 0, "up_errorstatus");
434 ll
= ((ULONGLONG
)0xcafebabe) << 32 | 0xdeadbeef;
435 *(void**)wiredata
= &ll
;
436 *(void**)(wiredata
+ sizeof(void*)) = NULL
;
437 *(ULONGLONG
*)(wiredata
+ 2 * sizeof(void*)) = ll
;
438 test_pointer_marshal(fmtstr_up_longlong
, &ll
, 8, wiredata
, 16, NULL
, 0, "up_longlong");
441 *(void**)wiredata
= &f
;
442 *(float*)(wiredata
+ sizeof(void*)) = f
;
443 test_pointer_marshal(fmtstr_up_float
, &f
, 4, wiredata
, 8, NULL
, 0, "up_float");
446 *(void**)wiredata
= &d
;
447 *(void**)(wiredata
+ sizeof(void*)) = NULL
;
448 *(double*)(wiredata
+ 2 * sizeof(void*)) = d
;
449 test_pointer_marshal(fmtstr_up_double
, &d
, 8, wiredata
, 16, NULL
, 0, "up_double");
453 static void test_simple_struct_marshal(const unsigned char *formattypes
,
456 const void *wiredata
,
458 int(*cmp
)(const void*,const void*,size_t),
459 long num_additional_allocs
,
462 RPC_MESSAGE RpcMessage
;
463 MIDL_STUB_MESSAGE StubMsg
;
464 MIDL_STUB_DESC StubDesc
;
467 unsigned char *mem
, *mem_orig
;
469 my_alloc_called
= my_free_called
= 0;
473 StubDesc
= Object_StubDesc
;
474 StubDesc
.pFormatTypes
= formattypes
;
476 NdrClientInitializeNew(&RpcMessage
, &StubMsg
, &StubDesc
, 0);
478 StubMsg
.BufferLength
= 0;
479 NdrSimpleStructBufferSize( &StubMsg
, (unsigned char *)memsrc
, formattypes
);
480 ok(StubMsg
.BufferLength
>= wiredatalen
, "%s: length %d\n", msgpfx
, StubMsg
.BufferLength
);
481 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
482 StubMsg
.BufferEnd
= StubMsg
.BufferStart
+ StubMsg
.BufferLength
;
483 ptr
= NdrSimpleStructMarshall( &StubMsg
, (unsigned char*)memsrc
, formattypes
);
484 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
485 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
);
486 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));
490 /* FIXME: Causes Wine to crash */
491 StubMsg
.Buffer
= StubMsg
.BufferStart
;
492 StubMsg
.MemorySize
= 0;
493 size
= NdrSimpleStructMemorySize( &StubMsg
, formattypes
);
494 ok(size
== StubMsg
.MemorySize
, "%s: size != MemorySize\n", msgpfx
);
495 ok(size
== srcsize
, "%s: mem size %u\n", msgpfx
, size
);
496 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
);
498 StubMsg
.Buffer
= StubMsg
.BufferStart
;
499 size
= NdrSimpleStructMemorySize( &StubMsg
, formattypes
);
501 ok(size
== StubMsg
.MemorySize
, "%s: size != MemorySize\n", msgpfx
);
503 ok(StubMsg
.MemorySize
== ((srcsize
+ 3) & ~3) + srcsize
, "%s: mem size %u\n", msgpfx
, size
);
504 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
);
507 /*** Unmarshalling first with must_alloc false ***/
509 StubMsg
.Buffer
= StubMsg
.BufferStart
;
510 StubMsg
.MemorySize
= 0;
511 mem_orig
= mem
= HeapAlloc(GetProcessHeap(), 0, srcsize
);
512 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, 0 );
513 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
514 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
);
515 ok(mem
== mem_orig
, "%s: mem has changed %p %p\n", msgpfx
, mem
, mem_orig
);
516 ok(!cmp(mem
, memsrc
, srcsize
), "%s: incorrectly unmarshaled\n", msgpfx
);
517 ok(my_alloc_called
== num_additional_allocs
, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
519 ok(StubMsg
.MemorySize
== 0, "%s: memorysize touched in unmarshal\n", msgpfx
);
521 /* if we're a server we still use the suppiled memory */
522 StubMsg
.Buffer
= StubMsg
.BufferStart
;
523 StubMsg
.IsClient
= 0;
524 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, 0 );
525 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
526 ok(mem
== mem_orig
, "%s: mem has changed %p %p\n", msgpfx
, mem
, mem_orig
);
527 ok(!cmp(mem
, memsrc
, srcsize
), "%s: incorrectly unmarshaled\n", msgpfx
);
528 ok(my_alloc_called
== num_additional_allocs
, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
530 ok(StubMsg
.MemorySize
== 0, "%s: memorysize touched in unmarshal\n", msgpfx
);
532 /* ...unless we pass a NULL ptr, then the buffer is used.
533 Passing a NULL ptr while we're a client && !must_alloc
534 crashes on Windows, so we won't do that. */
537 StubMsg
.IsClient
= 0;
538 StubMsg
.Buffer
= StubMsg
.BufferStart
;
539 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, 0 );
540 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
541 ok(mem
== StubMsg
.BufferStart
, "%s: mem not equal buffer\n", msgpfx
);
542 ok(!cmp(mem
, memsrc
, srcsize
), "%s: incorrectly unmarshaled\n", msgpfx
);
543 ok(my_alloc_called
== num_additional_allocs
, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
545 ok(StubMsg
.MemorySize
== 0, "%s: memorysize touched in unmarshal\n", msgpfx
);
547 /*** now must_alloc is true ***/
549 /* with must_alloc set we always allocate new memory whether or not we're
550 a server and also when passing NULL */
552 StubMsg
.IsClient
= 1;
553 StubMsg
.Buffer
= StubMsg
.BufferStart
;
554 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, 1 );
555 ok(ptr
== NULL
, "ret %p\n", ptr
);
556 ok(mem
!= mem_orig
, "mem not changed %p %p\n", mem
, mem_orig
);
557 ok(!cmp(mem
, memsrc
, srcsize
), "incorrectly unmarshaled\n");
558 ok(my_alloc_called
== num_additional_allocs
+ 1, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
560 ok(StubMsg
.MemorySize
== 0, "memorysize touched in unmarshal\n");
563 StubMsg
.Buffer
= StubMsg
.BufferStart
;
564 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, 1 );
565 ok(ptr
== NULL
, "ret %p\n", ptr
);
566 ok(mem
!= mem_orig
, "mem not changed %p %p\n", mem
, mem_orig
);
567 ok(!cmp(mem
, memsrc
, srcsize
), "incorrectly unmarshaled\n");
568 ok(my_alloc_called
== num_additional_allocs
+ 1, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
570 ok(StubMsg
.MemorySize
== 0, "memorysize touched in unmarshal\n");
573 StubMsg
.Buffer
= StubMsg
.BufferStart
;
574 StubMsg
.IsClient
= 0;
575 StubMsg
.ReuseBuffer
= 1;
576 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, 1 );
577 ok(ptr
== NULL
, "ret %p\n", ptr
);
578 ok(mem
!= mem_orig
, "mem not changed %p %p\n", mem
, mem_orig
);
579 ok(mem
!= StubMsg
.BufferStart
, "mem is buffer mem\n");
580 ok(!cmp(mem
, memsrc
, srcsize
), "incorrectly unmarshaled\n");
581 ok(my_alloc_called
== num_additional_allocs
+ 1, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
583 ok(StubMsg
.MemorySize
== 0, "memorysize touched in unmarshal\n");
586 StubMsg
.Buffer
= StubMsg
.BufferStart
;
587 StubMsg
.IsClient
= 0;
588 StubMsg
.ReuseBuffer
= 1;
589 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, 1 );
590 ok(ptr
== NULL
, "ret %p\n", ptr
);
591 ok(mem
!= StubMsg
.BufferStart
, "mem is buffer mem\n");
592 ok(!cmp(mem
, memsrc
, srcsize
), "incorrectly unmarshaled\n");
593 ok(my_alloc_called
== num_additional_allocs
+ 1, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
595 ok(StubMsg
.MemorySize
== 0, "memorysize touched in unmarshal\n");
606 static int ps1_cmp(const void *s1
, const void *s2
, size_t num
)
608 const ps1_t
*p1
, *p2
;
616 if(p1
->pl1
&& p2
->pl1
)
618 if(*p1
->pl1
!= *p2
->pl1
)
621 else if(p1
->pl1
|| p1
->pl1
)
624 if(p1
->pc1
&& p2
->pc1
)
626 if(*p1
->pc1
!= *p2
->pc1
)
629 else if(p1
->pc1
|| p1
->pc1
)
635 static void test_simple_struct(void)
637 unsigned char wiredata
[28];
638 unsigned long wiredatalen
;
643 static const unsigned char fmtstr_simple_struct
[] =
645 0x12, 0x0, /* FC_UP */
646 NdrFcShort( 0x2 ), /* Offset=2 */
647 0x15, 0x3, /* FC_STRUCT [align 4] */
648 NdrFcShort( 0x18 ), /* [size 24] */
651 0x38, /* FC_ALIGNM4 */
654 0x39, /* FC_ALIGNM8 */
665 static const unsigned char fmtstr_pointer_struct
[] =
667 0x12, 0x0, /* FC_UP */
668 NdrFcShort( 0x2 ), /* Offset=2 */
669 0x16, 0x3, /* FC_PSTRUCT [align 4] */
670 NdrFcShort( 0xc ), /* [size 12] */
673 0x46, /* FC_NO_REPEAT */
675 NdrFcShort( 0x4 ), /* 4 */
676 NdrFcShort( 0x4 ), /* 4 */
677 0x13, 0x8, /* FC_OP [simple_pointer] */
680 0x46, /* FC_NO_REPEAT */
682 NdrFcShort( 0x8 ), /* 8 */
683 NdrFcShort( 0x8 ), /* 8 */
684 0x13, 0x8, /* FC_OP [simple_pointer] */
701 s1
.ll
= ((LONGLONG
) 0xbadefeed << 32) | 0x2468ace0;
704 memcpy(wiredata
, &s1
, wiredatalen
);
705 test_simple_struct_marshal(fmtstr_simple_struct
+ 4, &s1
, 24, wiredata
, 24, NULL
, 0, "struct");
707 *(void**)wiredata
= &s1
;
708 memcpy(wiredata
+ 4, &s1
, wiredatalen
);
711 /* one of the unmarshallings crashes Wine */
712 test_pointer_marshal(fmtstr_simple_struct
, &s1
, 24, wiredata
, 28, NULL
, 0, "struct");
721 memcpy(wiredata
+ 4, &ps1
, 12);
722 memcpy(wiredata
+ 16, &l
, 4);
723 memcpy(wiredata
+ 20, &c
, 1);
725 test_simple_struct_marshal(fmtstr_pointer_struct
+ 4, &ps1
, 17, wiredata
+ 4, 17, ps1_cmp
, 2, "pointer_struct");
726 *(void**)wiredata
= &ps1
;
729 /* one of the unmarshallings crashes Wine */
730 test_pointer_marshal(fmtstr_pointer_struct
, &ps1
, 17, wiredata
, 21, ps1_cmp
, 2, "pointer_struct");
734 static void test_fullpointer_xlat(void)
736 PFULL_PTR_XLAT_TABLES pXlatTables
;
741 pXlatTables
= NdrFullPointerXlatInit(2, XLAT_CLIENT
);
743 /* "marshaling" phase */
745 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 1, &RefId
);
746 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
747 ok(RefId
== 0x1, "RefId should be 0x1 instead of 0x%x\n", RefId
);
749 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 0, &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 *)0xcafebabe, 0, &RefId
);
754 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
755 ok(RefId
== 0x2, "RefId should be 0x2 instead of 0x%x\n", RefId
);
757 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xdeadbeef, 0, &RefId
);
758 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
759 ok(RefId
== 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId
);
761 ret
= NdrFullPointerQueryPointer(pXlatTables
, NULL
, 0, &RefId
);
762 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
763 ok(RefId
== 0, "RefId should be 0 instead of 0x%x\n", RefId
);
765 /* "unmarshaling" phase */
767 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x2, 0, &Pointer
);
768 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
769 ok(Pointer
== (void *)0xcafebabe, "Pointer should be 0xcafebabe instead of %p\n", Pointer
);
771 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x4, 0, &Pointer
);
772 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
773 ok(Pointer
== NULL
, "Pointer should be NULL instead of %p\n", Pointer
);
775 NdrFullPointerInsertRefId(pXlatTables
, 0x4, (void *)0xdeadbabe);
777 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x4, 1, &Pointer
);
778 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
779 ok(Pointer
== (void *)0xdeadbabe, "Pointer should be (void *)0xdeadbabe instead of %p\n", Pointer
);
781 NdrFullPointerXlatFree(pXlatTables
);
783 pXlatTables
= NdrFullPointerXlatInit(2, XLAT_SERVER
);
785 /* "unmarshaling" phase */
787 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x2, 1, &Pointer
);
788 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
789 ok(Pointer
== NULL
, "Pointer should be NULL instead of %p\n", Pointer
);
791 NdrFullPointerInsertRefId(pXlatTables
, 0x2, (void *)0xcafebabe);
793 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x2, 0, &Pointer
);
794 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
795 ok(Pointer
== (void *)0xcafebabe, "Pointer should be (void *)0xcafebabe instead of %p\n", Pointer
);
797 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x2, 1, &Pointer
);
798 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
799 ok(Pointer
== (void *)0xcafebabe, "Pointer should be (void *)0xcafebabe instead of %p\n", Pointer
);
801 /* "marshaling" phase */
803 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 1, &RefId
);
804 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
805 ok(RefId
== 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId
);
807 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 1, &RefId
);
808 ok(ret
== 1, "ret should be 1 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, 0, &RefId
);
812 ok(ret
== 0, "ret should be 0 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 *)0xcafebabe, 0, &RefId
);
816 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
817 ok(RefId
== 0x2, "RefId should be 0x2 instead of 0x%x\n", RefId
);
819 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xdeadbeef, 0, &RefId
);
820 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
821 ok(RefId
== 0x4, "RefId should be 0x4 instead of 0x%x\n", RefId
);
823 /* "freeing" phase */
825 ret
= NdrFullPointerFree(pXlatTables
, (void *)0xcafebeef);
826 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
828 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 0x20, &RefId
);
829 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
830 ok(RefId
== 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId
);
832 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 1, &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
= NdrFullPointerFree(pXlatTables
, (void *)0xcafebabe);
837 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
839 ret
= NdrFullPointerFree(pXlatTables
, (void *)0xdeadbeef);
840 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
842 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xdeadbeef, 0x20, &RefId
);
843 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
844 ok(RefId
== 0x4, "RefId should be 0x4 instead of 0x%x\n", RefId
);
846 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xdeadbeef, 1, &RefId
);
847 ok(ret
== 0, "ret should be 0 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
== 1, "ret should be 1 instead of 0x%x\n", ret
);
852 ok(RefId
== 0x4, "RefId should be 0x4 instead of 0x%x\n", RefId
);
854 ret
= NdrFullPointerFree(pXlatTables
, (void *)0xdeadbeef);
855 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
857 NdrFullPointerXlatFree(pXlatTables
);
860 static void test_client_init(void)
862 MIDL_STUB_MESSAGE stubMsg
;
865 memset(&stubMsg
, 0xcc, sizeof(stubMsg
));
867 NdrClientInitializeNew(&rpcMsg
, &stubMsg
, &Object_StubDesc
, 1);
869 #define TEST_ZERO(field, fmt) ok(stubMsg.field == 0, #field " should have be set to zero instead of " fmt "\n", stubMsg.field)
870 #define TEST_POINTER_UNSET(field) ok(stubMsg.field == (void *)0xcccccccc, #field " should have be unset instead of %p\n", stubMsg.field)
871 #define TEST_ULONG_UNSET(field) ok(stubMsg.field == 0xcccccccc, #field " should have be unset instead of 0x%x\n", stubMsg.field)
872 #define TEST_ULONG_PTR_UNSET(field) ok(stubMsg.field == 0xcccccccc, #field " should have be unset instead of 0x%lx\n", stubMsg.field)
874 ok(stubMsg
.RpcMsg
== &rpcMsg
, "stubMsg.RpcMsg should have been %p instead of %p\n", &rpcMsg
, stubMsg
.RpcMsg
);
875 TEST_POINTER_UNSET(Buffer
);
876 TEST_ZERO(BufferStart
, "%p");
877 TEST_ZERO(BufferEnd
, "%p");
878 TEST_POINTER_UNSET(BufferMark
);
879 TEST_ZERO(BufferLength
, "%d");
880 TEST_ULONG_UNSET(MemorySize
);
881 TEST_POINTER_UNSET(Memory
);
882 ok(stubMsg
.IsClient
== 1, "stubMsg.IsClient should have been 1 instead of %u\n", stubMsg
.IsClient
);
883 TEST_ZERO(ReuseBuffer
, "%d");
884 TEST_ZERO(pAllocAllNodesContext
, "%p");
885 TEST_ZERO(pPointerQueueState
, "%p");
886 TEST_ZERO(IgnoreEmbeddedPointers
, "%d");
887 TEST_ZERO(PointerBufferMark
, "%p");
888 TEST_ZERO(fBufferValid
, "%d");
889 TEST_ZERO(uFlags
, "%d");
890 /* FIXME: UniquePtrCount */
891 TEST_ULONG_PTR_UNSET(MaxCount
);
892 TEST_ULONG_UNSET(Offset
);
893 TEST_ULONG_UNSET(ActualCount
);
894 ok(stubMsg
.pfnAllocate
== my_alloc
, "stubMsg.pfnAllocate should have been %p instead of %p\n", my_alloc
, stubMsg
.pfnAllocate
);
895 ok(stubMsg
.pfnFree
== my_free
, "stubMsg.pfnFree should have been %p instead of %p\n", my_free
, stubMsg
.pfnFree
);
896 TEST_ZERO(StackTop
, "%p");
897 TEST_POINTER_UNSET(pPresentedType
);
898 TEST_POINTER_UNSET(pTransmitType
);
899 TEST_POINTER_UNSET(SavedHandle
);
900 ok(stubMsg
.StubDesc
== &Object_StubDesc
, "stubMsg.StubDesc should have been %p instead of %p\n", &Object_StubDesc
, stubMsg
.StubDesc
);
901 TEST_POINTER_UNSET(FullPtrXlatTables
);
902 TEST_ZERO(FullPtrRefId
, "%d");
903 TEST_ZERO(PointerLength
, "%d");
904 TEST_ZERO(fInDontFree
, "%d");
905 TEST_ZERO(fDontCallFreeInst
, "%d");
906 TEST_ZERO(fInOnlyParam
, "%d");
907 TEST_ZERO(fHasReturn
, "%d");
908 TEST_ZERO(fHasExtensions
, "%d");
909 TEST_ZERO(fHasNewCorrDesc
, "%d");
910 TEST_ZERO(fUnused
, "%d");
911 ok(stubMsg
.fUnused2
== 0xffffcccc, "stubMsg.fUnused2 should have been 0xcccc instead of 0x%x\n", stubMsg
.fUnused2
);
912 ok(stubMsg
.dwDestContext
== MSHCTX_DIFFERENTMACHINE
, "stubMsg.dwDestContext should have been MSHCTX_DIFFERENTMACHINE instead of %d\n", stubMsg
.dwDestContext
);
913 TEST_ZERO(pvDestContext
, "%p");
914 TEST_POINTER_UNSET(SavedContextHandles
);
915 TEST_ULONG_UNSET(ParamNumber
);
916 TEST_ZERO(pRpcChannelBuffer
, "%p");
917 TEST_ZERO(pArrayInfo
, "%p");
918 TEST_POINTER_UNSET(SizePtrCountArray
);
919 TEST_POINTER_UNSET(SizePtrOffsetArray
);
920 TEST_POINTER_UNSET(SizePtrLengthArray
);
921 TEST_POINTER_UNSET(pArgQueue
);
922 TEST_ZERO(dwStubPhase
, "%d");
923 /* FIXME: where does this value come from? */
924 trace("LowStackMark is %p\n", stubMsg
.LowStackMark
);
925 TEST_ZERO(pAsyncMsg
, "%p");
926 TEST_ZERO(pCorrInfo
, "%p");
927 TEST_ZERO(pCorrMemory
, "%p");
928 TEST_ZERO(pMemoryList
, "%p");
929 TEST_POINTER_UNSET(pCSInfo
);
930 TEST_POINTER_UNSET(ConformanceMark
);
931 TEST_POINTER_UNSET(VarianceMark
);
932 ok(stubMsg
.Unused
== 0xcccccccc, "Unused should have be unset instead of 0x%lx\n", stubMsg
.Unused
);
933 TEST_POINTER_UNSET(pContext
);
934 TEST_POINTER_UNSET(ContextHandleHash
);
935 TEST_POINTER_UNSET(pUserMarshalList
);
936 TEST_ULONG_PTR_UNSET(Reserved51_3
);
937 TEST_ULONG_PTR_UNSET(Reserved51_4
);
938 TEST_ULONG_PTR_UNSET(Reserved51_5
);
939 #undef TEST_ULONG_UNSET
940 #undef TEST_POINTER_UNSET
945 static void test_ndr_allocate(void)
947 RPC_MESSAGE RpcMessage
;
948 MIDL_STUB_MESSAGE StubMsg
;
949 MIDL_STUB_DESC StubDesc
;
951 struct tag_mem_list_t
955 struct tag_mem_list_t
*next
;
957 const DWORD magic_MEML
= 'M' << 24 | 'E' << 16 | 'M' << 8 | 'L';
959 StubDesc
= Object_StubDesc
;
960 NdrClientInitializeNew(&RpcMessage
, &StubMsg
, &StubDesc
, 0);
962 ok(StubMsg
.pMemoryList
== NULL
, "memlist %p\n", StubMsg
.pMemoryList
);
963 my_alloc_called
= my_free_called
= 0;
964 p1
= NdrAllocate(&StubMsg
, 10);
965 p2
= NdrAllocate(&StubMsg
, 20);
966 ok(my_alloc_called
== 2, "alloc called %d\n", my_alloc_called
);
967 mem_list
= StubMsg
.pMemoryList
;
969 ok(mem_list
!= NULL
, "mem_list NULL\n");
973 ok(mem_list
->magic
== magic_MEML
, "magic %08x\n", mem_list
->magic
);
974 ok(mem_list
->ptr
== p2
, "ptr != p2\n");
975 ok(mem_list
->next
!= NULL
, "next NULL\n");
976 mem_list
= mem_list
->next
;
979 ok(mem_list
->magic
== magic_MEML
, "magic %08x\n", mem_list
->magic
);
980 ok(mem_list
->ptr
== p1
, "ptr != p2\n");
981 ok(mem_list
->next
== NULL
, "next %p\n", mem_list
->next
);
984 /* NdrFree isn't exported so we can't test free'ing */
987 static void test_conformant_array(void)
989 RPC_MESSAGE RpcMessage
;
990 MIDL_STUB_MESSAGE StubMsg
;
991 MIDL_STUB_DESC StubDesc
;
993 unsigned char *mem
, *mem_orig
;
994 unsigned char memsrc
[20];
996 static const unsigned char fmtstr_conf_array
[] =
998 0x1b, /* FC_CARRAY */
1000 NdrFcShort( 0x1 ), /* elem size */
1001 0x40, /* Corr desc: const */
1003 NdrFcShort(0x10), /* const = 0x10 */
1008 StubDesc
= Object_StubDesc
;
1009 StubDesc
.pFormatTypes
= fmtstr_conf_array
;
1011 NdrClientInitializeNew(
1017 StubMsg
.BufferLength
= 0;
1018 NdrConformantArrayBufferSize( &StubMsg
,
1020 fmtstr_conf_array
);
1021 ok(StubMsg
.BufferLength
>= 20, "length %d\n", StubMsg
.BufferLength
);
1023 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
1024 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
1025 StubMsg
.BufferEnd
= StubMsg
.BufferStart
+ StubMsg
.BufferLength
;
1027 ptr
= NdrConformantArrayMarshall( &StubMsg
, memsrc
, fmtstr_conf_array
);
1028 ok(ptr
== NULL
, "ret %p\n", ptr
);
1029 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== 20, "Buffer %p Start %p len %d\n", StubMsg
.Buffer
, StubMsg
.BufferStart
, 20);
1030 ok(!memcmp(StubMsg
.BufferStart
+ 4, memsrc
, 16), "incorrectly marshaled\n");
1032 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1033 StubMsg
.MemorySize
= 0;
1037 my_alloc_called
= 0;
1038 /* passing mem == NULL with must_alloc == 0 crashes under Windows */
1039 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 1);
1040 ok(mem
!= NULL
, "mem not alloced\n");
1041 ok(mem
!= StubMsg
.BufferStart
+ 4, "mem pointing at buffer\n");
1042 ok(my_alloc_called
== 1, "alloc called %d\n", my_alloc_called
);
1044 my_alloc_called
= 0;
1045 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1047 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 0);
1048 ok(mem
== mem_orig
, "mem alloced\n");
1049 ok(mem
!= StubMsg
.BufferStart
+ 4, "mem pointing at buffer\n");
1050 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1052 my_alloc_called
= 0;
1053 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1054 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 1);
1055 ok(mem
!= mem_orig
, "mem not alloced\n");
1056 ok(mem
!= StubMsg
.BufferStart
+ 4, "mem pointing at buffer\n");
1057 ok(my_alloc_called
== 1, "alloc called %d\n", my_alloc_called
);
1060 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1061 NdrConformantArrayFree( &StubMsg
, mem
, fmtstr_conf_array
);
1062 ok(my_free_called
== 0, "free called %d\n", my_free_called
);
1063 StubMsg
.pfnFree(mem
);
1066 my_alloc_called
= 0;
1067 StubMsg
.IsClient
= 0;
1069 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1070 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 0);
1072 ok(mem
== StubMsg
.BufferStart
+ 4, "mem not pointing at buffer\n");
1073 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1075 my_alloc_called
= 0;
1077 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1078 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 1);
1079 ok(mem
!= StubMsg
.BufferStart
+ 4, "mem pointing at buffer\n");
1080 ok(my_alloc_called
== 1, "alloc called %d\n", my_alloc_called
);
1081 StubMsg
.pfnFree(mem
);
1083 my_alloc_called
= 0;
1085 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1086 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 0);
1087 ok(mem
== mem_orig
, "mem alloced\n");
1088 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1090 my_alloc_called
= 0;
1092 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1093 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 1);
1094 ok(mem
!= StubMsg
.BufferStart
+ 4, "mem pointing at buffer\n");
1095 ok(my_alloc_called
== 1, "alloc called %d\n", my_alloc_called
);
1096 StubMsg
.pfnFree(mem
);
1097 StubMsg
.pfnFree(mem_orig
);
1099 HeapFree(GetProcessHeap(), 0, StubMsg
.RpcMsg
->Buffer
);
1102 START_TEST( ndr_marshall
)
1104 test_ndr_simple_type();
1105 test_simple_types();
1106 test_simple_struct();
1107 test_fullpointer_xlat();
1109 test_ndr_allocate();
1110 test_conformant_array();