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 */
75 static RPC_DISPATCH_FUNCTION IFoo_table
[] =
80 static RPC_DISPATCH_TABLE IFoo_v0_0_DispatchTable
=
86 static const RPC_SERVER_INTERFACE IFoo___RpcServerInterface
=
88 sizeof(RPC_SERVER_INTERFACE
),
89 {{0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x34}},{0,0}},
90 {{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}},
91 &IFoo_v0_0_DispatchTable
,
99 static RPC_IF_HANDLE IFoo_v0_0_s_ifspec
= (RPC_IF_HANDLE
)& IFoo___RpcServerInterface
;
100 static BOOL use_pointer_ids
= FALSE
;
102 static void determine_pointer_marshalling_style(void)
104 RPC_MESSAGE RpcMessage
;
105 MIDL_STUB_MESSAGE StubMsg
;
106 MIDL_STUB_DESC StubDesc
;
109 static const unsigned char fmtstr_up_char
[] =
111 0x12, 0x8, /* FC_UP [simple_pointer] */
116 StubDesc
= Object_StubDesc
;
117 StubDesc
.pFormatTypes
= NULL
;
119 NdrClientInitializeNew(
125 StubMsg
.BufferLength
= 8;
126 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
127 NdrPointerMarshall(&StubMsg
, (unsigned char*)&ch
, fmtstr_up_char
);
128 ok(StubMsg
.Buffer
== StubMsg
.BufferStart
+ 5, "%p %p\n", StubMsg
.Buffer
, StubMsg
.BufferStart
);
130 use_pointer_ids
= (*(unsigned int *)StubMsg
.BufferStart
!= (UINT_PTR
)&ch
);
131 trace("Pointer marshalling using %s\n", use_pointer_ids
? "pointer ids" : "pointer value");
133 HeapFree(GetProcessHeap(), 0, StubMsg
.BufferStart
);
136 static void test_ndr_simple_type(void)
138 RPC_MESSAGE RpcMessage
;
139 MIDL_STUB_MESSAGE StubMsg
;
140 MIDL_STUB_DESC StubDesc
;
143 StubDesc
= Object_StubDesc
;
144 StubDesc
.pFormatTypes
= NULL
;
146 NdrClientInitializeNew(
152 StubMsg
.BufferLength
= 16;
153 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
155 NdrSimpleTypeMarshall(&StubMsg
, (unsigned char*)&l
, 8 /* FC_LONG */);
156 ok(StubMsg
.Buffer
== StubMsg
.BufferStart
+ 4, "%p %p\n", StubMsg
.Buffer
, StubMsg
.BufferStart
);
157 ok(*(LONG
*)StubMsg
.BufferStart
== l
, "%d\n", *(LONG
*)StubMsg
.BufferStart
);
159 StubMsg
.Buffer
= StubMsg
.BufferStart
+ 1;
160 NdrSimpleTypeMarshall(&StubMsg
, (unsigned char*)&l
, 8 /* FC_LONG */);
161 ok(StubMsg
.Buffer
== StubMsg
.BufferStart
+ 8, "%p %p\n", StubMsg
.Buffer
, StubMsg
.BufferStart
);
162 ok(*(LONG
*)(StubMsg
.BufferStart
+ 4) == l
, "%d\n", *(LONG
*)StubMsg
.BufferStart
);
164 StubMsg
.Buffer
= StubMsg
.BufferStart
+ 1;
165 NdrSimpleTypeUnmarshall(&StubMsg
, (unsigned char*)&l2
, 8 /* FC_LONG */);
166 ok(StubMsg
.Buffer
== StubMsg
.BufferStart
+ 8, "%p %p\n", StubMsg
.Buffer
, StubMsg
.BufferStart
);
167 ok(l2
== l
, "%d\n", l2
);
169 HeapFree(GetProcessHeap(), 0, StubMsg
.BufferStart
);
172 static void test_pointer_marshal(const unsigned char *formattypes
,
173 void *memsrc
, DWORD srcsize
,
174 const void *wiredata
,
176 int(*cmp
)(const void*,const void*,size_t),
177 int num_additional_allocs
,
180 RPC_MESSAGE RpcMessage
;
181 MIDL_STUB_MESSAGE StubMsg
;
182 MIDL_STUB_DESC StubDesc
;
185 unsigned char *mem
, *mem_orig
;
187 my_alloc_called
= my_free_called
= 0;
191 StubDesc
= Object_StubDesc
;
192 StubDesc
.pFormatTypes
= formattypes
;
194 NdrClientInitializeNew(
200 StubMsg
.BufferLength
= 0;
201 NdrPointerBufferSize( &StubMsg
,
204 ok(StubMsg
.BufferLength
>= wiredatalen
, "%s: length %d\n", msgpfx
, StubMsg
.BufferLength
);
206 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
207 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
208 StubMsg
.BufferEnd
= StubMsg
.BufferStart
+ StubMsg
.BufferLength
;
210 memset(StubMsg
.BufferStart
, 0x0, StubMsg
.BufferLength
); /* This is a hack to clear the padding between the ptr and longlong/double */
212 ptr
= NdrPointerMarshall( &StubMsg
, memsrc
, formattypes
);
213 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
214 if (srcsize
== 8 && wiredatalen
== 16 && StubMsg
.Buffer
- StubMsg
.BufferStart
== 12)
216 /* win9x doesn't align 8-byte types properly */
221 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
222 ok(!memcmp(StubMsg
.BufferStart
, wiredata
, wiredatalen
), "%s: incorrectly marshaled\n", msgpfx
);
225 StubMsg
.Buffer
= StubMsg
.BufferStart
;
226 StubMsg
.MemorySize
= 0;
228 size
= NdrPointerMemorySize( &StubMsg
, formattypes
);
229 ok(size
== StubMsg
.MemorySize
, "%s: mem size %u size %u\n", msgpfx
, StubMsg
.MemorySize
, size
);
230 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
231 if(formattypes
[1] & 0x10 /* FC_POINTER_DEREF */)
232 ok(size
== srcsize
+ sizeof(void *), "%s: mem size %u\n", msgpfx
, size
);
234 ok(size
== srcsize
, "%s: mem size %u\n", msgpfx
, size
);
236 StubMsg
.Buffer
= StubMsg
.BufferStart
;
237 StubMsg
.MemorySize
= 16;
238 size
= NdrPointerMemorySize( &StubMsg
, formattypes
);
239 ok(size
== StubMsg
.MemorySize
, "%s: mem size %u size %u\n", msgpfx
, StubMsg
.MemorySize
, size
);
240 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
241 if(formattypes
[1] & 0x10 /* FC_POINTER_DEREF */)
242 ok(size
== srcsize
+ sizeof(void *) + 16, "%s: mem size %u\n", msgpfx
, size
);
244 ok(size
== srcsize
+ 16, "%s: mem size %u\n", msgpfx
, size
);
246 StubMsg
.Buffer
= StubMsg
.BufferStart
;
247 StubMsg
.MemorySize
= 1;
248 size
= NdrPointerMemorySize( &StubMsg
, formattypes
);
249 ok(size
== StubMsg
.MemorySize
, "%s: mem size %u size %u\n", msgpfx
, StubMsg
.MemorySize
, size
);
250 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
251 if(formattypes
[1] & 0x10 /* FC_POINTER_DEREF */)
252 ok(size
== srcsize
+ sizeof(void *) + (srcsize
== 8 ? 8 : sizeof(void *)), "%s: mem size %u\n", msgpfx
, size
);
254 ok(size
== srcsize
+ (srcsize
== 8 ? 8 : sizeof(void *)), "%s: mem size %u\n", msgpfx
, size
);
257 if(formattypes
[1] & 0x10) size
+= 4;
259 StubMsg
.Buffer
= StubMsg
.BufferStart
;
260 StubMsg
.MemorySize
= 0;
261 mem_orig
= mem
= HeapAlloc(GetProcessHeap(), 0, size
);
263 if(formattypes
[1] & 0x10 /* FC_POINTER_DEREF */)
265 ptr
= NdrPointerUnmarshall( &StubMsg
, &mem
, formattypes
, 0 );
266 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
267 ok(mem
== mem_orig
, "%s: mem has changed %p %p\n", msgpfx
, mem
, mem_orig
);
268 ok(!cmp(mem
, memsrc
, srcsize
), "%s: incorrectly unmarshaled\n", msgpfx
);
269 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
270 ok(StubMsg
.MemorySize
== 0, "%s: memorysize %d\n", msgpfx
, StubMsg
.MemorySize
);
271 ok(my_alloc_called
== num_additional_allocs
, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
274 /* reset the buffer and call with must alloc */
275 StubMsg
.Buffer
= StubMsg
.BufferStart
;
276 if(formattypes
[1] & 0x10 /* FC_POINTER_DEREF */)
278 ptr
= NdrPointerUnmarshall( &StubMsg
, &mem
, formattypes
, 1 );
279 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
280 /* doesn't allocate mem in this case */
282 ok(mem
== mem_orig
, "%s: mem has changed %p %p\n", msgpfx
, mem
, mem_orig
);
284 ok(!cmp(mem
, memsrc
, srcsize
), "%s: incorrectly unmarshaled\n", msgpfx
);
285 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
286 ok(StubMsg
.MemorySize
== 0, "%s: memorysize %d\n", msgpfx
, StubMsg
.MemorySize
);
289 ok(my_alloc_called
== num_additional_allocs
, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
292 if(formattypes
[0] != 0x11 /* FC_RP */)
294 /* now pass the address of a NULL ptr */
296 StubMsg
.Buffer
= StubMsg
.BufferStart
;
297 ptr
= NdrPointerUnmarshall( &StubMsg
, &mem
, formattypes
, 0 );
298 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
299 ok(mem
!= StubMsg
.BufferStart
+ wiredatalen
- srcsize
, "%s: mem points to buffer %p %p\n", msgpfx
, mem
, StubMsg
.BufferStart
);
300 ok(!cmp(mem
, memsrc
, size
), "%s: incorrectly unmarshaled\n", msgpfx
);
301 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
302 ok(StubMsg
.MemorySize
== 0, "%s: memorysize %d\n", msgpfx
, StubMsg
.MemorySize
);
303 ok(my_alloc_called
== num_additional_allocs
+ 1, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
305 NdrPointerFree(&StubMsg
, mem
, formattypes
);
307 /* again pass address of NULL ptr, but pretend we're a server */
308 if (0) /* crashes on Win9x and NT4 */
311 StubMsg
.Buffer
= StubMsg
.BufferStart
;
312 StubMsg
.IsClient
= 0;
313 ptr
= NdrPointerUnmarshall( &StubMsg
, &mem
, formattypes
, 0 );
314 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
315 if (formattypes
[2] == 0xd /* FC_ENUM16 */)
316 ok(mem
!= StubMsg
.BufferStart
+ wiredatalen
- srcsize
, "%s: mem points to buffer %p %p\n", msgpfx
, mem
, StubMsg
.BufferStart
);
318 ok(mem
== StubMsg
.BufferStart
+ wiredatalen
- srcsize
, "%s: mem doesn't point to buffer %p %p\n", msgpfx
, mem
, StubMsg
.BufferStart
);
319 ok(!cmp(mem
, memsrc
, size
), "%s: incorrectly unmarshaled\n", msgpfx
);
320 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
321 ok(StubMsg
.MemorySize
== 0, "%s: memorysize %d\n", msgpfx
, StubMsg
.MemorySize
);
322 if (formattypes
[2] != 0xd /* FC_ENUM16 */) {
323 ok(my_alloc_called
== num_additional_allocs
, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
328 HeapFree(GetProcessHeap(), 0, mem_orig
);
329 HeapFree(GetProcessHeap(), 0, StubMsg
.BufferStart
);
332 static int deref_cmp(const void *s1
, const void *s2
, size_t num
)
334 return memcmp(*(const void *const *)s1
, *(const void *const *)s2
, num
);
338 static void test_simple_types(void)
340 unsigned char wiredata
[16];
342 unsigned char *ch_ptr
;
350 static const unsigned char fmtstr_up_char
[] =
352 0x12, 0x8, /* FC_UP [simple_pointer] */
356 static const unsigned char fmtstr_up_byte
[] =
358 0x12, 0x8, /* FC_UP [simple_pointer] */
362 static const unsigned char fmtstr_up_small
[] =
364 0x12, 0x8, /* FC_UP [simple_pointer] */
368 static const unsigned char fmtstr_up_usmall
[] =
370 0x12, 0x8, /* FC_UP [simple_pointer] */
374 static const unsigned char fmtstr_rp_char
[] =
376 0x11, 0x8, /* FC_RP [simple_pointer] */
380 static const unsigned char fmtstr_rpup_char
[] =
382 0x11, 0x14, /* FC_RP [alloced_on_stack] */
383 NdrFcShort( 0x2 ), /* Offset= 2 (4) */
384 0x12, 0x8, /* FC_UP [simple_pointer] */
388 static const unsigned char fmtstr_rpup_char2
[] =
390 0x11, 0x04, /* FC_RP [alloced_on_stack] */
391 NdrFcShort( 0x2 ), /* Offset= 2 (4) */
392 0x12, 0x8, /* FC_UP [simple_pointer] */
397 static const unsigned char fmtstr_up_wchar
[] =
399 0x12, 0x8, /* FC_UP [simple_pointer] */
403 static const unsigned char fmtstr_up_short
[] =
405 0x12, 0x8, /* FC_UP [simple_pointer] */
409 static const unsigned char fmtstr_up_ushort
[] =
411 0x12, 0x8, /* FC_UP [simple_pointer] */
415 static const unsigned char fmtstr_up_enum16
[] =
417 0x12, 0x8, /* FC_UP [simple_pointer] */
421 static const unsigned char fmtstr_up_long
[] =
423 0x12, 0x8, /* FC_UP [simple_pointer] */
427 static const unsigned char fmtstr_up_ulong
[] =
429 0x12, 0x8, /* FC_UP [simple_pointer] */
433 static const unsigned char fmtstr_up_enum32
[] =
435 0x12, 0x8, /* FC_UP [simple_pointer] */
439 static const unsigned char fmtstr_up_errorstatus
[] =
441 0x12, 0x8, /* FC_UP [simple_pointer] */
442 0x10, /* FC_ERROR_STATUS_T */
446 static const unsigned char fmtstr_up_longlong
[] =
448 0x12, 0x8, /* FC_UP [simple_pointer] */
452 static const unsigned char fmtstr_up_float
[] =
454 0x12, 0x8, /* FC_UP [simple_pointer] */
458 static const unsigned char fmtstr_up_double
[] =
460 0x12, 0x8, /* FC_UP [simple_pointer] */
468 *(unsigned int *)wiredata
= 0x20000;
470 *(unsigned int *)wiredata
= (UINT_PTR
)ch_ptr
;
473 test_pointer_marshal(fmtstr_up_char
, ch_ptr
, 1, wiredata
, 5, NULL
, 0, "up_char");
474 test_pointer_marshal(fmtstr_up_byte
, ch_ptr
, 1, wiredata
, 5, NULL
, 0, "up_byte");
475 test_pointer_marshal(fmtstr_up_small
, ch_ptr
, 1, wiredata
, 5, NULL
, 0, "up_small");
476 test_pointer_marshal(fmtstr_up_usmall
, ch_ptr
, 1, wiredata
, 5, NULL
, 0, "up_usmall");
478 test_pointer_marshal(fmtstr_rp_char
, ch_ptr
, 1, &ch
, 1, NULL
, 0, "rp_char");
480 test_pointer_marshal(fmtstr_rpup_char
, &ch_ptr
, 1, wiredata
, 5, deref_cmp
, 1, "rpup_char");
481 test_pointer_marshal(fmtstr_rpup_char2
, ch_ptr
, 1, wiredata
, 5, NULL
, 0, "rpup_char2");
485 *(unsigned int *)wiredata
= 0x20000;
487 *(unsigned int *)wiredata
= (UINT_PTR
)&s
;
488 *(unsigned short*)(wiredata
+ 4) = s
;
490 test_pointer_marshal(fmtstr_up_wchar
, &s
, 2, wiredata
, 6, NULL
, 0, "up_wchar");
491 test_pointer_marshal(fmtstr_up_short
, &s
, 2, wiredata
, 6, NULL
, 0, "up_short");
492 test_pointer_marshal(fmtstr_up_ushort
, &s
, 2, wiredata
, 6, NULL
, 0, "up_ushort");
496 *(unsigned int *)wiredata
= 0x20000;
498 *(unsigned int *)wiredata
= (UINT_PTR
)&i
;
499 *(unsigned short*)(wiredata
+ 4) = i
;
500 test_pointer_marshal(fmtstr_up_enum16
, &i
, 4, wiredata
, 6, NULL
, 0, "up_enum16");
504 *(unsigned int *)wiredata
= 0x20000;
506 *(unsigned int *)wiredata
= (UINT_PTR
)&l
;
507 *(ULONG
*)(wiredata
+ 4) = l
;
509 test_pointer_marshal(fmtstr_up_long
, &l
, 4, wiredata
, 8, NULL
, 0, "up_long");
510 test_pointer_marshal(fmtstr_up_ulong
, &l
, 4, wiredata
, 8, NULL
, 0, "up_ulong");
511 test_pointer_marshal(fmtstr_up_enum32
, &l
, 4, wiredata
, 8, NULL
, 0, "up_emun32");
512 test_pointer_marshal(fmtstr_up_errorstatus
, &l
, 4, wiredata
, 8, NULL
, 0, "up_errorstatus");
514 ll
= ((ULONGLONG
)0xcafebabe) << 32 | 0xdeadbeef;
516 *(unsigned int *)wiredata
= 0x20000;
518 *(unsigned int *)wiredata
= (UINT_PTR
)&ll
;
519 *(unsigned int *)(wiredata
+ 4) = 0;
520 *(ULONGLONG
*)(wiredata
+ 8) = ll
;
521 test_pointer_marshal(fmtstr_up_longlong
, &ll
, 8, wiredata
, 16, NULL
, 0, "up_longlong");
525 *(unsigned int *)wiredata
= 0x20000;
527 *(unsigned int *)wiredata
= (UINT_PTR
)&f
;
528 *(float*)(wiredata
+ 4) = f
;
529 test_pointer_marshal(fmtstr_up_float
, &f
, 4, wiredata
, 8, NULL
, 0, "up_float");
533 *(unsigned int *)wiredata
= 0x20000;
535 *(unsigned int *)wiredata
= (UINT_PTR
)&d
;
536 *(unsigned int *)(wiredata
+ 4) = 0;
537 *(double*)(wiredata
+ 8) = d
;
538 test_pointer_marshal(fmtstr_up_double
, &d
, 8, wiredata
, 16, NULL
, 0, "up_double");
542 static void test_nontrivial_pointer_types(void)
544 RPC_MESSAGE RpcMessage
;
545 MIDL_STUB_MESSAGE StubMsg
;
546 MIDL_STUB_DESC StubDesc
;
552 unsigned char *mem
, *mem_orig
;
554 static const unsigned char fmtstr_ref_unique_out
[] =
556 0x12, 0x8, /* FC_UP [simple_pointer] */
559 0x11, 0x14, /* FC_RP [alloced_on_stack] [pointer_deref] */
560 NdrFcShort( 0xfffffffa ), /* Offset= -6 (0) */
567 StubDesc
= Object_StubDesc
;
568 StubDesc
.pFormatTypes
= fmtstr_ref_unique_out
;
570 NdrClientInitializeNew(
576 StubMsg
.BufferLength
= 0;
577 NdrPointerBufferSize( &StubMsg
,
579 &fmtstr_ref_unique_out
[4] );
581 /* Windows overestimates the buffer size */
582 ok(StubMsg
.BufferLength
>= 5, "length %d\n", StubMsg
.BufferLength
);
584 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
585 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
586 StubMsg
.BufferEnd
= StubMsg
.BufferStart
+ StubMsg
.BufferLength
;
588 ptr
= NdrPointerMarshall( &StubMsg
, (unsigned char *)p1
, &fmtstr_ref_unique_out
[4] );
589 ok(ptr
== NULL
, "ret %p\n", ptr
);
590 size
= StubMsg
.Buffer
- StubMsg
.BufferStart
;
591 ok(size
== 5, "Buffer %p Start %p len %d\n", StubMsg
.Buffer
, StubMsg
.BufferStart
, size
);
592 ok(*(unsigned int *)StubMsg
.BufferStart
!= 0, "pointer ID marshalled incorrectly\n");
593 ok(*(unsigned char *)(StubMsg
.BufferStart
+ 4) == 0x22, "char data marshalled incorrectly: 0x%x\n",
594 *(unsigned char *)(StubMsg
.BufferStart
+ 4));
596 StubMsg
.Buffer
= StubMsg
.BufferStart
;
597 StubMsg
.MemorySize
= 0;
602 StubMsg
.Buffer
= StubMsg
.BufferStart
;
603 mem
= mem_orig
= HeapAlloc(GetProcessHeap(), 0, sizeof(void *));
604 *(void **)mem
= NULL
;
605 NdrPointerUnmarshall( &StubMsg
, &mem
, &fmtstr_ref_unique_out
[4], 0);
606 ok(mem
== mem_orig
, "mem alloced\n");
607 ok(my_alloc_called
== 1, "alloc called %d\n", my_alloc_called
);
610 StubMsg
.Buffer
= StubMsg
.BufferStart
;
611 NdrPointerUnmarshall( &StubMsg
, &mem
, &fmtstr_ref_unique_out
[4], 1);
613 ok(mem
== mem_orig
, "mem alloced\n");
614 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
618 StubMsg
.Buffer
= StubMsg
.BufferStart
;
619 NdrPointerFree( &StubMsg
, mem
, &fmtstr_ref_unique_out
[4] );
620 ok(my_free_called
== 1, "free called %d\n", my_free_called
);
622 mem
= my_alloc(sizeof(void *));
623 *(void **)mem
= NULL
;
625 StubMsg
.Buffer
= StubMsg
.BufferStart
;
626 NdrPointerFree( &StubMsg
, mem
, &fmtstr_ref_unique_out
[4] );
627 ok(my_free_called
== 0, "free called %d\n", my_free_called
);
630 mem
= my_alloc(sizeof(void *));
631 *(void **)mem
= my_alloc(sizeof(char));
633 StubMsg
.Buffer
= StubMsg
.BufferStart
;
634 NdrPointerFree( &StubMsg
, mem
, &fmtstr_ref_unique_out
[4] );
635 ok(my_free_called
== 1, "free called %d\n", my_free_called
);
640 StubMsg
.IsClient
= 0;
642 StubMsg
.Buffer
= StubMsg
.BufferStart
;
643 NdrPointerUnmarshall( &StubMsg
, &mem
, &fmtstr_ref_unique_out
[4], 0);
644 ok(mem
!= StubMsg
.BufferStart
, "mem pointing at buffer\n");
646 ok(my_alloc_called
== 1, "alloc called %d\n", my_alloc_called
);
647 NdrPointerFree( &StubMsg
, mem
, &fmtstr_ref_unique_out
[4] );
651 StubMsg
.Buffer
= StubMsg
.BufferStart
;
652 NdrPointerUnmarshall( &StubMsg
, &mem
, &fmtstr_ref_unique_out
[4], 1);
653 ok(mem
!= StubMsg
.BufferStart
, "mem pointing at buffer\n");
655 ok(my_alloc_called
== 1, "alloc called %d\n", my_alloc_called
);
656 NdrPointerFree( &StubMsg
, mem
, &fmtstr_ref_unique_out
[4] );
660 *(void **)mem
= NULL
;
661 StubMsg
.Buffer
= StubMsg
.BufferStart
;
662 NdrPointerUnmarshall( &StubMsg
, &mem
, &fmtstr_ref_unique_out
[4], 0);
664 ok(mem
== mem_orig
, "mem alloced\n");
665 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
670 *(void **)mem
= NULL
;
671 StubMsg
.Buffer
= StubMsg
.BufferStart
;
672 NdrPointerUnmarshall( &StubMsg
, &mem
, &fmtstr_ref_unique_out
[4], 1);
674 ok(mem
== mem_orig
, "mem alloced\n");
675 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
678 mem
= my_alloc(sizeof(void *));
679 *(void **)mem
= NULL
;
681 StubMsg
.Buffer
= StubMsg
.BufferStart
;
682 NdrPointerFree( &StubMsg
, mem
, &fmtstr_ref_unique_out
[4] );
683 ok(my_free_called
== 0, "free called %d\n", my_free_called
);
686 mem
= my_alloc(sizeof(void *));
687 *(void **)mem
= my_alloc(sizeof(char));
689 StubMsg
.Buffer
= StubMsg
.BufferStart
;
690 NdrPointerFree( &StubMsg
, mem
, &fmtstr_ref_unique_out
[4] );
691 ok(my_free_called
== 1, "free called %d\n", my_free_called
);
694 HeapFree(GetProcessHeap(), 0, mem_orig
);
695 HeapFree(GetProcessHeap(), 0, StubMsg
.RpcMsg
->Buffer
);
698 static void test_simple_struct_marshal(const unsigned char *formattypes
,
699 void *memsrc
, DWORD srcsize
,
700 const void *wiredata
,
702 int(*cmp
)(const void*,const void*,size_t),
703 int num_additional_allocs
,
706 RPC_MESSAGE RpcMessage
;
707 MIDL_STUB_MESSAGE StubMsg
;
708 MIDL_STUB_DESC StubDesc
;
711 unsigned char *mem
, *mem_orig
;
713 my_alloc_called
= my_free_called
= 0;
717 StubDesc
= Object_StubDesc
;
718 StubDesc
.pFormatTypes
= formattypes
;
720 NdrClientInitializeNew(&RpcMessage
, &StubMsg
, &StubDesc
, 0);
722 StubMsg
.BufferLength
= 0;
723 NdrSimpleStructBufferSize( &StubMsg
, memsrc
, formattypes
);
724 ok(StubMsg
.BufferLength
>= wiredatalen
, "%s: length %d\n", msgpfx
, StubMsg
.BufferLength
);
725 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
726 StubMsg
.BufferEnd
= StubMsg
.BufferStart
+ StubMsg
.BufferLength
;
727 ptr
= NdrSimpleStructMarshall( &StubMsg
, memsrc
, formattypes
);
728 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
729 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
);
730 ok(!memcmp(StubMsg
.BufferStart
, wiredata
, wiredatalen
), "%s: incorrectly marshaled %08x %08x %08x\n", msgpfx
, *(DWORD
*)StubMsg
.BufferStart
,*((DWORD
*)StubMsg
.BufferStart
+1),*((DWORD
*)StubMsg
.BufferStart
+2));
732 StubMsg
.Buffer
= StubMsg
.BufferStart
;
733 StubMsg
.MemorySize
= 0;
734 size
= NdrSimpleStructMemorySize( &StubMsg
, formattypes
);
735 ok(size
== StubMsg
.MemorySize
, "%s: size != MemorySize\n", msgpfx
);
736 ok(size
== srcsize
, "%s: mem size %u\n", msgpfx
, size
);
737 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
);
739 StubMsg
.Buffer
= StubMsg
.BufferStart
;
740 size
= NdrSimpleStructMemorySize( &StubMsg
, formattypes
);
741 ok(size
== StubMsg
.MemorySize
, "%s: size != MemorySize\n", msgpfx
);
742 ok(StubMsg
.MemorySize
== ((srcsize
+ 3) & ~3) + srcsize
, "%s: mem size %u\n", msgpfx
, size
);
743 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
);
745 /*** Unmarshalling first with must_alloc false ***/
747 StubMsg
.Buffer
= StubMsg
.BufferStart
;
748 StubMsg
.MemorySize
= 0;
749 mem_orig
= mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, srcsize
);
750 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, 0 );
751 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
752 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
);
753 ok(mem
== mem_orig
, "%s: mem has changed %p %p\n", msgpfx
, mem
, mem_orig
);
754 ok(!cmp(mem
, memsrc
, srcsize
), "%s: incorrectly unmarshaled\n", msgpfx
);
755 ok(my_alloc_called
== num_additional_allocs
, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
757 ok(StubMsg
.MemorySize
== 0, "%s: memorysize touched in unmarshal\n", msgpfx
);
759 /* If we're a server we still use the supplied memory */
760 StubMsg
.Buffer
= StubMsg
.BufferStart
;
761 StubMsg
.IsClient
= 0;
762 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, 0 );
763 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
764 ok(mem
== mem_orig
, "%s: mem has changed %p %p\n", msgpfx
, mem
, mem_orig
);
765 ok(!cmp(mem
, memsrc
, srcsize
), "%s: incorrectly unmarshaled\n", msgpfx
);
766 ok(my_alloc_called
== num_additional_allocs
, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
768 ok(StubMsg
.MemorySize
== 0, "%s: memorysize touched in unmarshal\n", msgpfx
);
770 /* ...unless we pass a NULL ptr, then the buffer is used.
771 Passing a NULL ptr while we're a client && !must_alloc
772 crashes on Windows, so we won't do that. */
774 if (0) /* crashes on Win9x and NT4 */
777 StubMsg
.IsClient
= 0;
778 StubMsg
.Buffer
= StubMsg
.BufferStart
;
779 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, FALSE
);
780 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
781 ok(mem
== StubMsg
.BufferStart
, "%s: mem not equal buffer\n", msgpfx
);
782 ok(!cmp(mem
, memsrc
, srcsize
), "%s: incorrectly unmarshaled\n", msgpfx
);
783 ok(my_alloc_called
== num_additional_allocs
, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
785 ok(StubMsg
.MemorySize
== 0, "%s: memorysize touched in unmarshal\n", msgpfx
);
788 /*** now must_alloc is true ***/
790 /* with must_alloc set we always allocate new memory whether or not we're
791 a server and also when passing NULL */
793 StubMsg
.IsClient
= 1;
794 StubMsg
.Buffer
= StubMsg
.BufferStart
;
795 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, 1 );
796 ok(ptr
== NULL
, "ret %p\n", ptr
);
797 ok(mem
!= mem_orig
, "mem not changed %p %p\n", mem
, mem_orig
);
798 ok(!cmp(mem
, memsrc
, srcsize
), "incorrectly unmarshaled\n");
799 ok(my_alloc_called
== num_additional_allocs
+ 1, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
801 ok(StubMsg
.MemorySize
== 0, "memorysize touched in unmarshal\n");
804 StubMsg
.Buffer
= StubMsg
.BufferStart
;
805 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, 1 );
806 ok(ptr
== NULL
, "ret %p\n", ptr
);
807 ok(mem
!= mem_orig
, "mem not changed %p %p\n", mem
, mem_orig
);
808 ok(!cmp(mem
, memsrc
, srcsize
), "incorrectly unmarshaled\n");
809 ok(my_alloc_called
== num_additional_allocs
+ 1, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
811 ok(StubMsg
.MemorySize
== 0, "memorysize touched in unmarshal\n");
814 StubMsg
.Buffer
= StubMsg
.BufferStart
;
815 StubMsg
.IsClient
= 0;
816 StubMsg
.ReuseBuffer
= 1;
817 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, 1 );
818 ok(ptr
== NULL
, "ret %p\n", ptr
);
819 ok(mem
!= mem_orig
, "mem not changed %p %p\n", mem
, mem_orig
);
820 ok(mem
!= StubMsg
.BufferStart
, "mem is buffer mem\n");
821 ok(!cmp(mem
, memsrc
, srcsize
), "incorrectly unmarshaled\n");
822 ok(my_alloc_called
== num_additional_allocs
+ 1, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
824 ok(StubMsg
.MemorySize
== 0, "memorysize touched in unmarshal\n");
827 StubMsg
.Buffer
= StubMsg
.BufferStart
;
828 StubMsg
.IsClient
= 0;
829 StubMsg
.ReuseBuffer
= 1;
830 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, 1 );
831 ok(ptr
== NULL
, "ret %p\n", ptr
);
832 ok(mem
!= StubMsg
.BufferStart
, "mem is buffer mem\n");
833 ok(!cmp(mem
, memsrc
, srcsize
), "incorrectly unmarshaled\n");
834 ok(my_alloc_called
== num_additional_allocs
+ 1, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
836 ok(StubMsg
.MemorySize
== 0, "memorysize touched in unmarshal\n");
838 HeapFree(GetProcessHeap(), 0, mem_orig
);
839 HeapFree(GetProcessHeap(), 0, StubMsg
.BufferStart
);
849 static int ps1_cmp(const void *s1
, const void *s2
, size_t num
)
851 const ps1_t
*p1
, *p2
;
859 if(p1
->pl1
&& p2
->pl1
)
861 if(*p1
->pl1
!= *p2
->pl1
)
864 else if(p1
->pl1
|| p1
->pl1
)
867 if(p1
->pc1
&& p2
->pc1
)
869 if(*p1
->pc1
!= *p2
->pc1
)
872 else if(p1
->pc1
|| p1
->pc1
)
878 static void test_simple_struct(void)
880 unsigned char wiredata
[28];
886 static const unsigned char fmtstr_simple_struct
[] =
888 0x12, 0x0, /* FC_UP */
889 NdrFcShort( 0x2 ), /* Offset=2 */
890 0x15, 0x3, /* FC_STRUCT [align 4] */
891 NdrFcShort( 0x18 ), /* [size 24] */
894 0x38, /* FC_ALIGNM4 */
897 0x39, /* FC_ALIGNM8 */
908 static const unsigned char fmtstr_pointer_struct
[] =
910 0x12, 0x0, /* FC_UP */
911 NdrFcShort( 0x2 ), /* Offset=2 */
913 0x1a, /* FC_BOGUS_STRUCT */
915 NdrFcShort(0x18), /* [size 24] */
917 NdrFcShort(0x8), /* Offset= 8 (266) */
919 0x39, /* FC_ALIGNM8 */
920 0x36, /* FC_POINTER */
921 0x36, /* FC_POINTER */
924 0x12, 0x8, /* FC_UP [simple_pointer] */
927 0x12, 0x8, /* FC_UP [simple_pointer] */
931 0x16, 0x3, /* FC_PSTRUCT [align 4] */
932 NdrFcShort( 0xc ), /* [size 12] */
935 0x46, /* FC_NO_REPEAT */
937 NdrFcShort( 0x4 ), /* 4 */
938 NdrFcShort( 0x4 ), /* 4 */
939 0x13, 0x8, /* FC_OP [simple_pointer] */
942 0x46, /* FC_NO_REPEAT */
944 NdrFcShort( 0x8 ), /* 8 */
945 NdrFcShort( 0x8 ), /* 8 */
946 0x13, 0x8, /* FC_OP [simple_pointer] */
958 /* zero the entire structure, including the holes */
959 memset(&s1
, 0, sizeof(s1
));
966 s1
.ll
= ((LONGLONG
) 0xbadefeed << 32) | 0x2468ace0;
969 memcpy(wiredata
, &s1
, wiredatalen
);
970 test_simple_struct_marshal(fmtstr_simple_struct
+ 4, &s1
, 24, wiredata
, 24, NULL
, 0, "struct");
973 *(unsigned int *)wiredata
= 0x20000;
975 *(unsigned int *)wiredata
= (UINT_PTR
)&s1
;
976 memcpy(wiredata
+ 4, &s1
, wiredatalen
);
977 test_pointer_marshal(fmtstr_simple_struct
, &s1
, 24, wiredata
, 28, NULL
, 0, "struct");
979 if (sizeof(void *) == 8) return; /* it cannot be represented as a simple struct on Win64 */
981 /* zero the entire structure, including the hole */
982 memset(&ps1
, 0, sizeof(ps1
));
990 *(unsigned int *)(wiredata
+ 4) = 0xdeadbeef;
993 *(unsigned int *)(wiredata
+ 8) = 0x20000;
994 *(unsigned int *)(wiredata
+ 12) = 0x20004;
998 *(unsigned int *)(wiredata
+ 8) = (UINT_PTR
)&l
;
999 *(unsigned int *)(wiredata
+ 12) = (UINT_PTR
)&c
;
1001 memcpy(wiredata
+ 16, &l
, 4);
1002 memcpy(wiredata
+ 20, &c
, 1);
1004 test_simple_struct_marshal(fmtstr_pointer_struct
+ 4, &ps1
, 17, wiredata
+ 4, 17, ps1_cmp
, 2, "pointer_struct");
1005 if (use_pointer_ids
)
1007 *(unsigned int *)wiredata
= 0x20000;
1008 *(unsigned int *)(wiredata
+ 8) = 0x20004;
1009 *(unsigned int *)(wiredata
+ 12) = 0x20008;
1012 *(unsigned int *)wiredata
= (UINT_PTR
)&ps1
;
1013 test_pointer_marshal(fmtstr_pointer_struct
, &ps1
, 17, wiredata
, 21, ps1_cmp
, 2, "pointer_struct");
1016 static void test_fullpointer_xlat(void)
1018 PFULL_PTR_XLAT_TABLES pXlatTables
;
1023 pXlatTables
= NdrFullPointerXlatInit(2, XLAT_CLIENT
);
1025 /* "marshaling" phase */
1027 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 1, &RefId
);
1028 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1029 ok(RefId
== 0x1, "RefId should be 0x1 instead of 0x%x\n", RefId
);
1031 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 0, &RefId
);
1032 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1033 ok(RefId
== 0x1, "RefId should be 0x1 instead of 0x%x\n", RefId
);
1035 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebabe, 0, &RefId
);
1036 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1037 ok(RefId
== 0x2, "RefId should be 0x2 instead of 0x%x\n", RefId
);
1039 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xdeadbeef, 0, &RefId
);
1040 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1041 ok(RefId
== 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId
);
1043 ret
= NdrFullPointerQueryPointer(pXlatTables
, NULL
, 0, &RefId
);
1044 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
1045 ok(RefId
== 0, "RefId should be 0 instead of 0x%x\n", RefId
);
1047 /* "unmarshaling" phase */
1049 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x2, 0, &Pointer
);
1050 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1051 ok(Pointer
== (void *)0xcafebabe, "Pointer should be 0xcafebabe instead of %p\n", Pointer
);
1053 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x4, 0, &Pointer
);
1054 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1055 ok(Pointer
== NULL
, "Pointer should be NULL instead of %p\n", Pointer
);
1057 NdrFullPointerInsertRefId(pXlatTables
, 0x4, (void *)0xdeadbabe);
1059 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x4, 1, &Pointer
);
1060 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1061 ok(Pointer
== (void *)0xdeadbabe, "Pointer should be (void *)0xdeadbabe instead of %p\n", Pointer
);
1063 NdrFullPointerXlatFree(pXlatTables
);
1065 pXlatTables
= NdrFullPointerXlatInit(2, XLAT_SERVER
);
1067 /* "unmarshaling" phase */
1069 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x2, 1, &Pointer
);
1070 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1071 ok(Pointer
== NULL
, "Pointer should be NULL instead of %p\n", Pointer
);
1073 NdrFullPointerInsertRefId(pXlatTables
, 0x2, (void *)0xcafebabe);
1075 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x2, 0, &Pointer
);
1076 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1077 ok(Pointer
== (void *)0xcafebabe, "Pointer should be (void *)0xcafebabe instead of %p\n", Pointer
);
1079 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x2, 1, &Pointer
);
1080 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
1081 ok(Pointer
== (void *)0xcafebabe, "Pointer should be (void *)0xcafebabe instead of %p\n", Pointer
);
1083 /* "marshaling" phase */
1085 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 1, &RefId
);
1086 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1087 ok(RefId
== 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId
);
1089 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 1, &RefId
);
1090 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
1091 ok(RefId
== 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId
);
1093 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 0, &RefId
);
1094 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1095 ok(RefId
== 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId
);
1097 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebabe, 0, &RefId
);
1098 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1099 ok(RefId
== 0x2, "RefId should be 0x2 instead of 0x%x\n", RefId
);
1101 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xdeadbeef, 0, &RefId
);
1102 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1103 ok(RefId
== 0x4, "RefId should be 0x4 instead of 0x%x\n", RefId
);
1105 /* "freeing" phase */
1107 ret
= NdrFullPointerFree(pXlatTables
, (void *)0xcafebeef);
1108 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
1110 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 0x20, &RefId
);
1111 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
1112 ok(RefId
== 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId
);
1114 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 1, &RefId
);
1115 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
1116 ok(RefId
== 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId
);
1118 ret
= NdrFullPointerFree(pXlatTables
, (void *)0xcafebabe);
1119 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
1121 ret
= NdrFullPointerFree(pXlatTables
, (void *)0xdeadbeef);
1122 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
1124 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xdeadbeef, 0x20, &RefId
);
1125 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
1126 ok(RefId
== 0x4, "RefId should be 0x4 instead of 0x%x\n", RefId
);
1128 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xdeadbeef, 1, &RefId
);
1129 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1130 ok(RefId
== 0x4, "RefId should be 0x4 instead of 0x%x\n", RefId
);
1132 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xdeadbeef, 1, &RefId
);
1133 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
1134 ok(RefId
== 0x4, "RefId should be 0x4 instead of 0x%x\n", RefId
);
1136 ret
= NdrFullPointerFree(pXlatTables
, (void *)0xdeadbeef);
1137 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1139 NdrFullPointerXlatFree(pXlatTables
);
1142 /* verify stub data that is identical between client and server */
1143 static void test_common_stub_data( const char *prefix
, const MIDL_STUB_MESSAGE
*stubMsg
)
1147 memset(&unset_ptr
, 0xcc, sizeof(unset_ptr
));
1149 #define TEST_ZERO(field, fmt) ok(stubMsg->field == 0, "%s: " #field " should have been set to zero instead of " fmt "\n", prefix, stubMsg->field)
1150 #define TEST_POINTER_UNSET(field) ok(stubMsg->field == unset_ptr, "%s: " #field " should have been unset instead of %p\n", prefix, stubMsg->field)
1151 #define TEST_ULONG_UNSET(field) ok(stubMsg->field == 0xcccccccc, "%s: " #field " should have been unset instead of 0x%x\n", prefix, stubMsg->field)
1152 #define TEST_ULONG_PTR_UNSET(field) ok(stubMsg->field == (ULONG_PTR)unset_ptr, "%s: " #field " should have been unset instead of 0x%lx\n", prefix, stubMsg->field)
1154 TEST_POINTER_UNSET(BufferMark
);
1155 TEST_ULONG_UNSET(MemorySize
);
1156 TEST_POINTER_UNSET(Memory
);
1157 TEST_ZERO(pAllocAllNodesContext
, "%p");
1158 ok(stubMsg
->pPointerQueueState
== 0 ||
1159 broken(stubMsg
->pPointerQueueState
== unset_ptr
), /* win2k */
1160 "%s: pPointerQueueState should have been unset instead of %p\n",
1161 prefix
, stubMsg
->pPointerQueueState
);
1162 TEST_ZERO(IgnoreEmbeddedPointers
, "%d");
1163 TEST_ZERO(PointerBufferMark
, "%p");
1164 ok( stubMsg
->uFlags
== 0 ||
1165 broken(stubMsg
->uFlags
== 0xcc), /* win9x */
1166 "%s: uFlags should have been set to zero instead of 0x%x\n", prefix
, stubMsg
->uFlags
);
1167 /* FIXME: UniquePtrCount */
1168 TEST_ULONG_PTR_UNSET(MaxCount
);
1169 TEST_ULONG_UNSET(Offset
);
1170 TEST_ULONG_UNSET(ActualCount
);
1171 ok(stubMsg
->pfnAllocate
== my_alloc
, "%s: pfnAllocate should have been %p instead of %p\n",
1172 prefix
, my_alloc
, stubMsg
->pfnAllocate
);
1173 ok(stubMsg
->pfnFree
== my_free
, "%s: pfnFree should have been %p instead of %p\n",
1174 prefix
, my_free
, stubMsg
->pfnFree
);
1175 TEST_ZERO(StackTop
, "%p");
1176 TEST_POINTER_UNSET(pPresentedType
);
1177 TEST_POINTER_UNSET(pTransmitType
);
1178 TEST_POINTER_UNSET(SavedHandle
);
1179 ok(stubMsg
->StubDesc
== &Object_StubDesc
, "%s: StubDesc should have been %p instead of %p\n",
1180 prefix
, &Object_StubDesc
, stubMsg
->StubDesc
);
1181 TEST_ZERO(FullPtrRefId
, "%d");
1182 ok( stubMsg
->PointerLength
== 0 ||
1183 broken(stubMsg
->PointerLength
== 1), /* win9x, nt4 */
1184 "%s: pAsyncMsg should have been set to zero instead of %d\n", prefix
, stubMsg
->PointerLength
);
1185 TEST_ZERO(fInDontFree
, "%d");
1186 TEST_ZERO(fDontCallFreeInst
, "%d");
1187 ok(stubMsg
->fInOnlyParam
== 0 ||
1188 stubMsg
->fInOnlyParam
== -1, /* Vista */
1189 "%s: fInOnlyParam should have been set to 0 or -1 instead of %d\n", prefix
, stubMsg
->fInOnlyParam
);
1190 ok( stubMsg
->fHasReturn
== 0 ||
1191 broken(stubMsg
->fHasReturn
== -1), /* win9x, nt4 */
1192 "%s: fHasReturn should have been set to zero instead of %d\n", prefix
, stubMsg
->fHasReturn
);
1193 TEST_ZERO(fHasExtensions
, "%d");
1194 TEST_ZERO(fHasNewCorrDesc
, "%d");
1195 ok(stubMsg
->fIsIn
== 0 ||
1196 broken(stubMsg
->fIsIn
== -1), /* win9x, nt4 */
1197 "%s: fIsIn should have been set to 0 instead of %d\n", prefix
, stubMsg
->fIsIn
);
1198 ok(stubMsg
->fIsOut
== 0 ||
1199 stubMsg
->fIsOut
== -1, /* XP-SP3 */
1200 "%s: fIsOut should have been set to 0 or -1 instead of %d\n", prefix
, stubMsg
->fIsOut
);
1201 TEST_ZERO(fIsOicf
, "%d");
1202 ok(stubMsg
->fBufferValid
== 0,
1203 "%s: fBufferValid should have been set to 0 instead of %d\n", prefix
, stubMsg
->fBufferValid
);
1204 ok(stubMsg
->fHasMemoryValidateCallback
== 0 ||
1205 stubMsg
->fHasMemoryValidateCallback
== -1, /* XP-SP3 */
1206 "%s: fHasMemoryValidateCallback should have been set to 0 or -1 instead of %d\n",
1207 prefix
, stubMsg
->fHasMemoryValidateCallback
);
1208 ok(stubMsg
->fInFree
== 0 ||
1209 stubMsg
->fInFree
== -1, /* XP-SP3 */
1210 "%s: fInFree should have been set to 0 or -1 instead of %d\n", prefix
, stubMsg
->fInFree
);
1211 TEST_ZERO(fNeedMCCP
, "%d");
1212 ok(stubMsg
->fUnused
== 0 ||
1213 stubMsg
->fUnused
== -2, /* Vista */
1214 "%s: fUnused should have been set to 0 or -2 instead of %d\n", prefix
, stubMsg
->fUnused
);
1215 ok(stubMsg
->fUnused2
== 0xffffcccc, "%s: fUnused2 should have been 0xffffcccc instead of 0x%x\n",
1216 prefix
, stubMsg
->fUnused2
);
1217 ok(stubMsg
->dwDestContext
== MSHCTX_DIFFERENTMACHINE
,
1218 "%s: dwDestContext should have been MSHCTX_DIFFERENTMACHINE instead of %d\n",
1219 prefix
, stubMsg
->dwDestContext
);
1220 TEST_ZERO(pvDestContext
, "%p");
1221 TEST_POINTER_UNSET(SavedContextHandles
);
1222 TEST_ULONG_UNSET(ParamNumber
);
1223 TEST_ZERO(pRpcChannelBuffer
, "%p");
1224 TEST_ZERO(pArrayInfo
, "%p");
1225 TEST_POINTER_UNSET(SizePtrCountArray
);
1226 TEST_POINTER_UNSET(SizePtrOffsetArray
);
1227 TEST_POINTER_UNSET(SizePtrLengthArray
);
1228 TEST_POINTER_UNSET(pArgQueue
);
1229 TEST_ZERO(dwStubPhase
, "%d");
1230 /* FIXME: where does this value come from? */
1231 trace("%s: LowStackMark is %p\n", prefix
, stubMsg
->LowStackMark
);
1232 ok( stubMsg
->pAsyncMsg
== 0 || broken(stubMsg
->pAsyncMsg
== unset_ptr
), /* win9x, nt4 */
1233 "%s: pAsyncMsg should have been set to zero instead of %p\n", prefix
, stubMsg
->pAsyncMsg
);
1234 ok( stubMsg
->pCorrInfo
== 0 || broken(stubMsg
->pCorrInfo
== unset_ptr
), /* win9x, nt4 */
1235 "%s: pCorrInfo should have been set to zero instead of %p\n", prefix
, stubMsg
->pCorrInfo
);
1236 ok( stubMsg
->pCorrMemory
== 0 || broken(stubMsg
->pCorrMemory
== unset_ptr
), /* win9x, nt4 */
1237 "%s: pCorrMemory should have been set to zero instead of %p\n", prefix
, stubMsg
->pCorrMemory
);
1238 ok( stubMsg
->pMemoryList
== 0 || broken(stubMsg
->pMemoryList
== unset_ptr
), /* win9x, nt4 */
1239 "%s: pMemoryList should have been set to zero instead of %p\n", prefix
, stubMsg
->pMemoryList
);
1240 TEST_POINTER_UNSET(pCSInfo
);
1241 TEST_POINTER_UNSET(ConformanceMark
);
1242 TEST_POINTER_UNSET(VarianceMark
);
1243 ok(stubMsg
->Unused
== (ULONG_PTR
)unset_ptr
, "%s: Unused should have be unset instead of 0x%lx\n",
1244 prefix
, stubMsg
->Unused
);
1245 TEST_POINTER_UNSET(pContext
);
1246 TEST_POINTER_UNSET(ContextHandleHash
);
1247 TEST_POINTER_UNSET(pUserMarshalList
);
1248 TEST_ULONG_PTR_UNSET(Reserved51_3
);
1249 TEST_ULONG_PTR_UNSET(Reserved51_4
);
1250 TEST_ULONG_PTR_UNSET(Reserved51_5
);
1252 #undef TEST_ULONG_PTR_UNSET
1253 #undef TEST_ULONG_UNSET
1254 #undef TEST_POINTER_UNSET
1258 static void test_client_init(void)
1260 MIDL_STUB_MESSAGE stubMsg
;
1264 memset(&rpcMsg
, 0xcc, sizeof(rpcMsg
));
1265 memset(&stubMsg
, 0xcc, sizeof(stubMsg
));
1266 memset(&unset_ptr
, 0xcc, sizeof(unset_ptr
));
1268 NdrClientInitializeNew(&rpcMsg
, &stubMsg
, &Object_StubDesc
, 1);
1270 test_common_stub_data( "NdrClientInitializeNew", &stubMsg
);
1272 ok(stubMsg
.RpcMsg
== &rpcMsg
, "stubMsg.RpcMsg should have been %p instead of %p\n", &rpcMsg
, stubMsg
.RpcMsg
);
1273 ok(rpcMsg
.Handle
== NULL
, "rpcMsg.Handle should have been NULL instead of %p\n", rpcMsg
.Handle
);
1274 ok(rpcMsg
.Buffer
== unset_ptr
, "rpcMsg.Buffer should have been unset instead of %p\n",
1276 ok(rpcMsg
.BufferLength
== 0xcccccccc, "rpcMsg.BufferLength should have been unset instead of %d\n", rpcMsg
.BufferLength
);
1277 ok(rpcMsg
.ProcNum
== 0x8001, "rpcMsg.ProcNum should have been 0x8001 instead of 0x%x\n", rpcMsg
.ProcNum
);
1278 ok(rpcMsg
.TransferSyntax
== unset_ptr
, "rpcMsg.TransferSyntax should have been unset instead of %p\n", rpcMsg
.TransferSyntax
);
1279 ok(rpcMsg
.RpcInterfaceInformation
== Object_StubDesc
.RpcInterfaceInformation
,
1280 "rpcMsg.RpcInterfaceInformation should have been %p instead of %p\n",
1281 Object_StubDesc
.RpcInterfaceInformation
, rpcMsg
.RpcInterfaceInformation
);
1282 /* Note: ReservedForRuntime not tested */
1283 ok(rpcMsg
.ManagerEpv
== unset_ptr
, "rpcMsg.ManagerEpv should have been unset instead of %p\n", rpcMsg
.ManagerEpv
);
1284 ok(rpcMsg
.ImportContext
== unset_ptr
, "rpcMsg.ImportContext should have been unset instead of %p\n", rpcMsg
.ImportContext
);
1285 ok(rpcMsg
.RpcFlags
== 0, "rpcMsg.RpcFlags should have been 0 instead of 0x%x\n", rpcMsg
.RpcFlags
);
1287 ok(stubMsg
.Buffer
== unset_ptr
, "stubMsg.Buffer should have been unset instead of %p\n",
1289 ok(stubMsg
.BufferStart
== NULL
, "stubMsg.BufferStart should have been NULL instead of %p\n",
1290 stubMsg
.BufferStart
);
1291 ok(stubMsg
.BufferEnd
== NULL
, "stubMsg.BufferEnd should have been NULL instead of %p\n",
1293 ok(stubMsg
.BufferLength
== 0, "stubMsg.BufferLength should have been 0 instead of %u\n",
1294 stubMsg
.BufferLength
);
1295 ok(stubMsg
.IsClient
== 1, "stubMsg.IsClient should have been 1 instead of %u\n", stubMsg
.IsClient
);
1296 ok(stubMsg
.ReuseBuffer
== 0, "stubMsg.ReuseBuffer should have been 0 instead of %d\n",
1297 stubMsg
.ReuseBuffer
);
1298 ok(stubMsg
.CorrDespIncrement
== 0, "stubMsg.CorrDespIncrement should have been 0 instead of %d\n",
1299 stubMsg
.CorrDespIncrement
);
1300 ok(stubMsg
.FullPtrXlatTables
== unset_ptr
, "stubMsg.FullPtrXlatTables should have been unset instead of %p\n",
1301 stubMsg
.FullPtrXlatTables
);
1304 static void test_server_init(void)
1306 MIDL_STUB_MESSAGE stubMsg
;
1309 unsigned char buffer
[256];
1311 memset(&rpcMsg
, 0, sizeof(rpcMsg
));
1312 rpcMsg
.Buffer
= buffer
;
1313 rpcMsg
.BufferLength
= sizeof(buffer
);
1314 rpcMsg
.RpcFlags
= RPC_BUFFER_COMPLETE
;
1316 memset(&stubMsg
, 0xcc, sizeof(stubMsg
));
1318 ret
= NdrServerInitializeNew(&rpcMsg
, &stubMsg
, &Object_StubDesc
);
1319 ok(ret
== NULL
, "NdrServerInitializeNew should have returned NULL instead of %p\n", ret
);
1321 test_common_stub_data( "NdrServerInitializeNew", &stubMsg
);
1323 ok(stubMsg
.RpcMsg
== &rpcMsg
, "stubMsg.RpcMsg should have been %p instead of %p\n", &rpcMsg
, stubMsg
.RpcMsg
);
1324 ok(stubMsg
.Buffer
== buffer
, "stubMsg.Buffer should have been %p instead of %p\n", buffer
, stubMsg
.Buffer
);
1325 ok(stubMsg
.BufferStart
== buffer
, "stubMsg.BufferStart should have been %p instead of %p\n", buffer
, stubMsg
.BufferStart
);
1326 ok(stubMsg
.BufferEnd
== buffer
+ sizeof(buffer
), "stubMsg.BufferEnd should have been %p instead of %p\n", buffer
+ sizeof(buffer
), stubMsg
.BufferEnd
);
1328 ok(stubMsg
.BufferLength
== 0, "stubMsg.BufferLength should have been 0 instead of %u\n", stubMsg
.BufferLength
);
1329 ok(stubMsg
.IsClient
== 0, "stubMsg.IsClient should have been 0 instead of %u\n", stubMsg
.IsClient
);
1330 ok(stubMsg
.ReuseBuffer
== 0 ||
1331 broken(stubMsg
.ReuseBuffer
== 1), /* win2k */
1332 "stubMsg.ReuseBuffer should have been set to zero instead of %d\n", stubMsg
.ReuseBuffer
);
1333 ok(stubMsg
.CorrDespIncrement
== 0xcc ||
1334 stubMsg
.CorrDespIncrement
== 0,
1335 "CorrDespIncrement should have been unset instead of 0x%x\n", stubMsg
.CorrDespIncrement
);
1336 ok(stubMsg
.FullPtrXlatTables
== 0, "stubMsg.BufferLength should have been 0 instead of %p\n", stubMsg
.FullPtrXlatTables
);
1339 static void test_ndr_allocate(void)
1341 RPC_MESSAGE RpcMessage
;
1342 MIDL_STUB_MESSAGE StubMsg
;
1343 MIDL_STUB_DESC StubDesc
;
1345 struct tag_mem_list_v2_t
1350 struct tag_mem_list_v2_t
*next
;
1352 const DWORD magic_MEML
= 'M' << 24 | 'E' << 16 | 'M' << 8 | 'L';
1354 StubDesc
= Object_StubDesc
;
1355 NdrClientInitializeNew(&RpcMessage
, &StubMsg
, &StubDesc
, 0);
1357 my_alloc_called
= my_free_called
= 0;
1358 p1
= NdrAllocate(&StubMsg
, 10);
1359 p2
= NdrAllocate(&StubMsg
, 24);
1360 ok(my_alloc_called
== 2, "alloc called %d\n", my_alloc_called
);
1361 ok(StubMsg
.pMemoryList
!= NULL
, "StubMsg.pMemoryList NULL\n");
1362 if(StubMsg
.pMemoryList
)
1364 mem_list_v2
= StubMsg
.pMemoryList
;
1365 if (mem_list_v2
->size
== 24)
1367 trace("v2 mem list format\n");
1368 ok((char *)mem_list_v2
== (char *)p2
+ 24, "expected mem_list_v2 pointer %p, but got %p\n", (char *)p2
+ 24, mem_list_v2
);
1369 ok(mem_list_v2
->magic
== magic_MEML
, "magic %08x\n", mem_list_v2
->magic
);
1370 ok(mem_list_v2
->size
== 24, "wrong size for p2 %d\n", mem_list_v2
->size
);
1371 ok(mem_list_v2
->unknown
== 0, "wrong unknown for p2 0x%x\n", mem_list_v2
->unknown
);
1372 ok(mem_list_v2
->next
!= NULL
, "next NULL\n");
1373 mem_list_v2
= mem_list_v2
->next
;
1376 ok((char *)mem_list_v2
== (char *)p1
+ 16, "expected mem_list_v2 pointer %p, but got %p\n", (char *)p1
+ 16, mem_list_v2
);
1377 ok(mem_list_v2
->magic
== magic_MEML
, "magic %08x\n", mem_list_v2
->magic
);
1378 ok(mem_list_v2
->size
== 16, "wrong size for p1 %d\n", mem_list_v2
->size
);
1379 ok(mem_list_v2
->unknown
== 0, "wrong unknown for p1 0x%x\n", mem_list_v2
->unknown
);
1380 ok(mem_list_v2
->next
== NULL
, "next %p\n", mem_list_v2
->next
);
1383 else win_skip("v1 mem list format\n");
1385 /* NdrFree isn't exported so we can't test free'ing */
1388 static void test_conformant_array(void)
1390 RPC_MESSAGE RpcMessage
;
1391 MIDL_STUB_MESSAGE StubMsg
;
1392 MIDL_STUB_DESC StubDesc
;
1394 unsigned char *mem
, *mem_orig
;
1395 unsigned char memsrc
[20];
1398 static const unsigned char fmtstr_conf_array
[] =
1400 0x1b, /* FC_CARRAY */
1402 NdrFcShort( 0x1 ), /* elem size */
1403 0x40, /* Corr desc: const */
1405 NdrFcShort(0x10), /* const = 0x10 */
1410 for (i
= 0; i
< sizeof(memsrc
); i
++)
1413 StubDesc
= Object_StubDesc
;
1414 StubDesc
.pFormatTypes
= fmtstr_conf_array
;
1416 NdrClientInitializeNew(
1422 StubMsg
.BufferLength
= 0;
1423 NdrConformantArrayBufferSize( &StubMsg
,
1425 fmtstr_conf_array
);
1426 ok(StubMsg
.BufferLength
>= 20, "length %d\n", StubMsg
.BufferLength
);
1428 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
1429 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
1430 StubMsg
.BufferEnd
= StubMsg
.BufferStart
+ StubMsg
.BufferLength
;
1432 ptr
= NdrConformantArrayMarshall( &StubMsg
, memsrc
, fmtstr_conf_array
);
1433 ok(ptr
== NULL
, "ret %p\n", ptr
);
1434 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== 20, "Buffer %p Start %p len %d\n", StubMsg
.Buffer
, StubMsg
.BufferStart
, 20);
1435 ok(!memcmp(StubMsg
.BufferStart
+ 4, memsrc
, 16), "incorrectly marshaled\n");
1437 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1438 StubMsg
.MemorySize
= 0;
1442 my_alloc_called
= 0;
1443 /* passing mem == NULL with must_alloc == 0 crashes under Windows */
1444 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 1);
1445 ok(mem
!= NULL
, "mem not alloced\n");
1446 ok(mem
!= StubMsg
.BufferStart
+ 4, "mem pointing at buffer\n");
1447 ok(my_alloc_called
== 1, "alloc called %d\n", my_alloc_called
);
1449 my_alloc_called
= 0;
1450 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1452 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 0);
1453 ok(mem
== mem_orig
, "mem alloced\n");
1454 ok(mem
!= StubMsg
.BufferStart
+ 4, "mem pointing at buffer\n");
1455 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1457 my_alloc_called
= 0;
1458 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1459 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 1);
1460 ok(mem
!= mem_orig
, "mem not alloced\n");
1461 ok(mem
!= StubMsg
.BufferStart
+ 4, "mem pointing at buffer\n");
1462 ok(my_alloc_called
== 1, "alloc called %d\n", my_alloc_called
);
1465 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1466 NdrConformantArrayFree( &StubMsg
, mem
, fmtstr_conf_array
);
1467 ok(my_free_called
== 0, "free called %d\n", my_free_called
);
1468 StubMsg
.pfnFree(mem
);
1471 my_alloc_called
= 0;
1472 StubMsg
.IsClient
= 0;
1474 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1475 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 0);
1476 ok(mem
== StubMsg
.BufferStart
+ 4 || broken(!mem
), /* win9x, nt4 */
1477 "mem not pointing at buffer %p/%p\n", mem
, StubMsg
.BufferStart
+ 4);
1478 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1479 my_alloc_called
= 0;
1481 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1482 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 1);
1483 ok(mem
!= StubMsg
.BufferStart
+ 4, "mem pointing at buffer\n");
1484 ok(my_alloc_called
== 1, "alloc called %d\n", my_alloc_called
);
1485 StubMsg
.pfnFree(mem
);
1487 my_alloc_called
= 0;
1489 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1490 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 0);
1491 ok(mem
== mem_orig
, "mem alloced\n");
1492 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1494 my_alloc_called
= 0;
1496 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1497 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 1);
1498 ok(mem
!= StubMsg
.BufferStart
+ 4, "mem pointing at buffer\n");
1499 ok(my_alloc_called
== 1, "alloc called %d\n", my_alloc_called
);
1500 StubMsg
.pfnFree(mem
);
1501 StubMsg
.pfnFree(mem_orig
);
1503 HeapFree(GetProcessHeap(), 0, StubMsg
.RpcMsg
->Buffer
);
1506 static void test_conformant_string(void)
1508 RPC_MESSAGE RpcMessage
;
1509 MIDL_STUB_MESSAGE StubMsg
;
1510 MIDL_STUB_DESC StubDesc
;
1513 unsigned char *mem
, *mem_orig
;
1514 char memsrc
[] = "This is a test string";
1516 static const unsigned char fmtstr_conf_str
[] =
1518 0x11, 0x8, /* FC_RP [simple_pointer] */
1519 0x22, /* FC_C_CSTRING */
1523 StubDesc
= Object_StubDesc
;
1524 StubDesc
.pFormatTypes
= fmtstr_conf_str
;
1526 memset( &StubMsg
, 0, sizeof(StubMsg
) ); /* needed on win9x and nt4 */
1527 NdrClientInitializeNew(
1533 StubMsg
.BufferLength
= 0;
1534 NdrPointerBufferSize( &StubMsg
,
1535 (unsigned char *)memsrc
,
1537 ok(StubMsg
.BufferLength
>= sizeof(memsrc
) + 12, "length %d\n", StubMsg
.BufferLength
);
1539 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
1540 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
1541 StubMsg
.BufferEnd
= StubMsg
.BufferStart
+ StubMsg
.BufferLength
;
1543 ptr
= NdrPointerMarshall( &StubMsg
, (unsigned char *)memsrc
, fmtstr_conf_str
);
1544 ok(ptr
== NULL
, "ret %p\n", ptr
);
1545 size
= StubMsg
.Buffer
- StubMsg
.BufferStart
;
1546 ok(size
== sizeof(memsrc
) + 12, "Buffer %p Start %p len %d\n",
1547 StubMsg
.Buffer
, StubMsg
.BufferStart
, size
);
1548 ok(!memcmp(StubMsg
.BufferStart
+ 12, memsrc
, sizeof(memsrc
)), "incorrectly marshaled\n");
1550 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1551 StubMsg
.MemorySize
= 0;
1555 my_alloc_called
= 0;
1556 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1557 mem
= mem_orig
= HeapAlloc(GetProcessHeap(), 0, sizeof(memsrc
));
1558 NdrPointerUnmarshall( &StubMsg
, &mem
, fmtstr_conf_str
, 0);
1559 ok(mem
== mem_orig
, "mem not alloced\n");
1560 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1562 my_alloc_called
= 0;
1563 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1564 NdrPointerUnmarshall( &StubMsg
, &mem
, fmtstr_conf_str
, 1);
1566 ok(mem
== mem_orig
, "mem not alloced\n");
1567 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1571 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1572 NdrPointerFree( &StubMsg
, mem
, fmtstr_conf_str
);
1573 ok(my_free_called
== 1, "free called %d\n", my_free_called
);
1577 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1578 NdrPointerFree( &StubMsg
, mem
, fmtstr_conf_str
);
1579 ok(my_free_called
== 1, "free called %d\n", my_free_called
);
1582 my_alloc_called
= 0;
1583 StubMsg
.IsClient
= 0;
1585 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1586 NdrPointerUnmarshall( &StubMsg
, &mem
, fmtstr_conf_str
, 0);
1587 ok(mem
== StubMsg
.BufferStart
+ 12 || broken(!mem
), /* win9x, nt4 */
1588 "mem not pointing at buffer %p/%p\n", mem
, StubMsg
.BufferStart
+ 12 );
1589 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1591 my_alloc_called
= 0;
1593 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1594 NdrPointerUnmarshall( &StubMsg
, &mem
, fmtstr_conf_str
, 1);
1596 ok(mem
== StubMsg
.BufferStart
+ 12 || broken(!mem
), /* win9x, nt4 */
1597 "mem not pointing at buffer %p/%p\n", mem
, StubMsg
.BufferStart
+ 12 );
1598 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1601 my_alloc_called
= 0;
1602 mem
= mem_orig
= HeapAlloc(GetProcessHeap(), 0, sizeof(memsrc
));
1603 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1604 NdrPointerUnmarshall( &StubMsg
, &mem
, fmtstr_conf_str
, 0);
1605 ok(mem
== StubMsg
.BufferStart
+ 12 || broken(!mem
), /* win9x, nt4 */
1606 "mem not pointing at buffer %p/%p\n", mem
, StubMsg
.BufferStart
+ 12 );
1607 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1609 my_alloc_called
= 0;
1611 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1612 NdrPointerUnmarshall( &StubMsg
, &mem
, fmtstr_conf_str
, 1);
1614 ok(mem
== StubMsg
.BufferStart
+ 12 || broken(!mem
), /* win9x, nt4 */
1615 "mem not pointing at buffer %p/%p\n", mem
, StubMsg
.BufferStart
+ 12 );
1616 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1621 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1622 NdrPointerFree( &StubMsg
, mem
, fmtstr_conf_str
);
1623 ok(my_free_called
== 1, "free called %d\n", my_free_called
);
1625 HeapFree(GetProcessHeap(), 0, mem_orig
);
1626 HeapFree(GetProcessHeap(), 0, StubMsg
.RpcMsg
->Buffer
);
1629 static void test_nonconformant_string(void)
1631 RPC_MESSAGE RpcMessage
;
1632 MIDL_STUB_MESSAGE StubMsg
;
1633 MIDL_STUB_DESC StubDesc
;
1636 unsigned char *mem
, *mem_orig
;
1637 unsigned char memsrc
[10] = "This is";
1638 unsigned char memsrc2
[10] = "This is a";
1640 static const unsigned char fmtstr_nonconf_str
[] =
1642 0x26, /* FC_CSTRING */
1644 NdrFcShort( 0xa ), /* 10 */
1647 StubDesc
= Object_StubDesc
;
1648 StubDesc
.pFormatTypes
= fmtstr_nonconf_str
;
1651 NdrClientInitializeNew(
1657 StubMsg
.BufferLength
= 0;
1659 NdrNonConformantStringBufferSize( &StubMsg
, memsrc
, fmtstr_nonconf_str
);
1660 ok(StubMsg
.BufferLength
>= strlen((char *)memsrc
) + 1 + 8, "length %d\n", StubMsg
.BufferLength
);
1662 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
1663 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
1664 StubMsg
.BufferEnd
= StubMsg
.BufferStart
+ StubMsg
.BufferLength
;
1666 ptr
= NdrNonConformantStringMarshall( &StubMsg
, memsrc
, fmtstr_nonconf_str
);
1667 ok(ptr
== NULL
, "ret %p\n", ptr
);
1668 size
= StubMsg
.Buffer
- StubMsg
.BufferStart
;
1669 ok(size
== strlen((char *)memsrc
) + 1 + 8, "Buffer %p Start %p len %d\n",
1670 StubMsg
.Buffer
, StubMsg
.BufferStart
, size
);
1671 ok(!memcmp(StubMsg
.BufferStart
+ 8, memsrc
, strlen((char *)memsrc
) + 1), "incorrectly marshaled\n");
1673 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1674 StubMsg
.MemorySize
= 0;
1678 my_alloc_called
= 0;
1679 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1680 mem
= mem_orig
= HeapAlloc(GetProcessHeap(), 0, sizeof(memsrc
));
1681 NdrNonConformantStringUnmarshall( &StubMsg
, &mem
, fmtstr_nonconf_str
, 0);
1682 ok(mem
== mem_orig
, "mem alloced\n");
1683 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1685 my_alloc_called
= 0;
1686 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1687 NdrNonConformantStringUnmarshall( &StubMsg
, &mem
, fmtstr_nonconf_str
, 1);
1689 ok(mem
== mem_orig
, "mem alloced\n");
1691 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1694 my_alloc_called
= 0;
1695 StubMsg
.IsClient
= 0;
1697 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1698 NdrNonConformantStringUnmarshall( &StubMsg
, &mem
, fmtstr_nonconf_str
, 0);
1699 ok(mem
!= mem_orig
, "mem not alloced\n");
1700 ok(mem
!= StubMsg
.BufferStart
+ 8, "mem pointing at buffer\n");
1701 ok(my_alloc_called
== 1, "alloc called %d\n", my_alloc_called
);
1704 my_alloc_called
= 0;
1706 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1707 NdrNonConformantStringUnmarshall( &StubMsg
, &mem
, fmtstr_nonconf_str
, 0);
1708 ok(mem
== mem_orig
, "mem alloced\n");
1709 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1711 my_alloc_called
= 0;
1713 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1714 NdrNonConformantStringUnmarshall( &StubMsg
, &mem
, fmtstr_nonconf_str
, 1);
1716 ok(mem
== mem_orig
, "mem alloced\n");
1718 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1720 HeapFree(GetProcessHeap(), 0, mem_orig
);
1721 HeapFree(GetProcessHeap(), 0, StubMsg
.RpcMsg
->Buffer
);
1724 NdrClientInitializeNew(
1730 StubMsg
.BufferLength
= 0;
1732 NdrNonConformantStringBufferSize( &StubMsg
, memsrc2
, fmtstr_nonconf_str
);
1733 ok(StubMsg
.BufferLength
>= strlen((char *)memsrc2
) + 1 + 8, "length %d\n", StubMsg
.BufferLength
);
1735 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
1736 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
1737 StubMsg
.BufferEnd
= StubMsg
.BufferStart
+ StubMsg
.BufferLength
;
1739 ptr
= NdrNonConformantStringMarshall( &StubMsg
, memsrc2
, fmtstr_nonconf_str
);
1740 ok(ptr
== NULL
, "ret %p\n", ptr
);
1741 size
= StubMsg
.Buffer
- StubMsg
.BufferStart
;
1742 ok(size
== strlen((char *)memsrc2
) + 1 + 8, "Buffer %p Start %p len %d\n",
1743 StubMsg
.Buffer
, StubMsg
.BufferStart
, size
);
1744 ok(!memcmp(StubMsg
.BufferStart
+ 8, memsrc2
, strlen((char *)memsrc2
) + 1), "incorrectly marshaled\n");
1746 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1747 StubMsg
.MemorySize
= 0;
1751 my_alloc_called
= 0;
1752 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1753 mem
= mem_orig
= HeapAlloc(GetProcessHeap(), 0, sizeof(memsrc
));
1754 NdrNonConformantStringUnmarshall( &StubMsg
, &mem
, fmtstr_nonconf_str
, 0);
1755 ok(mem
== mem_orig
, "mem alloced\n");
1756 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1758 my_alloc_called
= 0;
1759 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1760 NdrNonConformantStringUnmarshall( &StubMsg
, &mem
, fmtstr_nonconf_str
, 1);
1762 ok(mem
== mem_orig
, "mem alloced\n");
1764 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1767 my_alloc_called
= 0;
1768 StubMsg
.IsClient
= 0;
1770 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1771 NdrNonConformantStringUnmarshall( &StubMsg
, &mem
, fmtstr_nonconf_str
, 0);
1772 ok(mem
!= mem_orig
, "mem not alloced\n");
1773 ok(mem
!= StubMsg
.BufferStart
+ 8, "mem pointing at buffer\n");
1774 ok(my_alloc_called
== 1, "alloc called %d\n", my_alloc_called
);
1777 my_alloc_called
= 0;
1779 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1780 NdrNonConformantStringUnmarshall( &StubMsg
, &mem
, fmtstr_nonconf_str
, 0);
1781 ok(mem
== mem_orig
, "mem alloced\n");
1782 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1784 my_alloc_called
= 0;
1786 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1787 NdrNonConformantStringUnmarshall( &StubMsg
, &mem
, fmtstr_nonconf_str
, 1);
1789 ok(mem
== mem_orig
, "mem alloced\n");
1791 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1793 HeapFree(GetProcessHeap(), 0, mem_orig
);
1794 HeapFree(GetProcessHeap(), 0, StubMsg
.RpcMsg
->Buffer
);
1797 static void test_conf_complex_struct(void)
1799 RPC_MESSAGE RpcMessage
;
1800 MIDL_STUB_MESSAGE StubMsg
;
1801 MIDL_STUB_DESC StubDesc
;
1807 unsigned int *array
[1];
1809 struct conf_complex
*memsrc
;
1810 struct conf_complex
*mem
;
1812 static const unsigned char fmtstr_complex_struct
[] =
1815 0x1b, /* FC_CARRAY */
1817 /* 2 */ NdrFcShort( 0x4 ), /* 4 */
1818 /* 4 */ 0x8, /* Corr desc: FC_LONG */
1820 /* 6 */ NdrFcShort( 0xfffc ), /* -4 */
1825 0x48, /* FC_VARIABLE_REPEAT */
1826 0x49, /* FC_FIXED_OFFSET */
1827 /* 12 */ NdrFcShort( 0x4 ), /* 4 */
1828 /* 14 */ NdrFcShort( 0x0 ), /* 0 */
1829 /* 16 */ NdrFcShort( 0x1 ), /* 1 */
1830 /* 18 */ NdrFcShort( 0x0 ), /* 0 */
1831 /* 20 */ NdrFcShort( 0x0 ), /* 0 */
1832 /* 22 */ 0x12, 0x8, /* FC_UP [simple_pointer] */
1833 /* 24 */ 0x8, /* FC_LONG */
1839 /* 28 */ 0x5c, /* FC_PAD */
1842 0x1a, /* FC_BOGUS_STRUCT */
1844 /* 32 */ NdrFcShort( 0x4 ), /* 4 */
1845 /* 34 */ NdrFcShort( 0xffffffde ), /* Offset= -34 (0) */
1846 /* 36 */ NdrFcShort( 0x0 ), /* Offset= 0 (36) */
1847 /* 38 */ 0x8, /* FC_LONG */
1851 memsrc
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1852 FIELD_OFFSET(struct conf_complex
, array
[20]));
1855 StubDesc
= Object_StubDesc
;
1856 StubDesc
.pFormatTypes
= fmtstr_complex_struct
;
1858 NdrClientInitializeNew(
1864 StubMsg
.BufferLength
= 0;
1865 NdrComplexStructBufferSize( &StubMsg
,
1866 (unsigned char *)memsrc
,
1867 &fmtstr_complex_struct
[30] );
1868 ok(StubMsg
.BufferLength
>= 28, "length %d\n", StubMsg
.BufferLength
);
1870 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
1871 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
1872 StubMsg
.BufferEnd
= StubMsg
.BufferStart
+ StubMsg
.BufferLength
;
1874 ptr
= NdrComplexStructMarshall( &StubMsg
, (unsigned char *)memsrc
,
1875 &fmtstr_complex_struct
[30] );
1876 ok(ptr
== NULL
, "ret %p\n", ptr
);
1877 ok(*(unsigned int *)StubMsg
.BufferStart
== 20, "Conformance should have been 20 instead of %d\n", *(unsigned int *)StubMsg
.BufferStart
);
1878 ok(*(unsigned int *)(StubMsg
.BufferStart
+ 4) == 20, "conf_complex.size should have been 20 instead of %d\n", *(unsigned int *)(StubMsg
.BufferStart
+ 4));
1879 for (i
= 0; i
< 20; i
++)
1880 ok(*(unsigned int *)(StubMsg
.BufferStart
+ 8 + i
* 4) == 0, "pointer id for conf_complex.array[%d] should have been 0 instead of 0x%x\n", i
, *(unsigned int *)(StubMsg
.BufferStart
+ 8 + i
* 4));
1883 my_alloc_called
= 0;
1884 StubMsg
.IsClient
= 0;
1886 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1887 ptr
= NdrComplexStructUnmarshall( &StubMsg
, (unsigned char **)&mem
, &fmtstr_complex_struct
[30], 0);
1888 ok(ptr
== NULL
, "ret %p\n", ptr
);
1889 ok(mem
->size
== 20, "mem->size wasn't unmarshalled correctly (%d)\n", mem
->size
);
1890 ok(mem
->array
[0] == NULL
, "mem->array[0] wasn't unmarshalled correctly (%p)\n", mem
->array
[0]);
1891 StubMsg
.pfnFree(mem
);
1893 HeapFree(GetProcessHeap(), 0, StubMsg
.RpcMsg
->Buffer
);
1896 static void test_ndr_buffer(void)
1898 static unsigned char ncalrpc
[] = "ncalrpc";
1899 static unsigned char endpoint
[] = "winetest:test_ndr_buffer";
1900 RPC_MESSAGE RpcMessage
;
1901 MIDL_STUB_MESSAGE StubMsg
;
1902 MIDL_STUB_DESC StubDesc
= Object_StubDesc
;
1904 unsigned char *binding
;
1905 RPC_BINDING_HANDLE Handle
;
1907 ULONG prev_buffer_length
;
1908 BOOL old_buffer_valid_location
;
1910 StubDesc
.RpcInterfaceInformation
= (void *)&IFoo___RpcServerInterface
;
1912 status
= RpcServerUseProtseqEp(ncalrpc
, 20, endpoint
, NULL
);
1913 ok(RPC_S_OK
== status
, "RpcServerUseProtseqEp failed with status %u\n", status
);
1914 status
= RpcServerRegisterIf(IFoo_v0_0_s_ifspec
, NULL
, NULL
);
1915 ok(RPC_S_OK
== status
, "RpcServerRegisterIf failed with status %u\n", status
);
1916 status
= RpcServerListen(1, 20, TRUE
);
1917 ok(RPC_S_OK
== status
, "RpcServerListen failed with status %u\n", status
);
1918 if (status
!= RPC_S_OK
)
1920 /* Failed to create a server, running client tests is useless */
1924 status
= RpcStringBindingCompose(NULL
, ncalrpc
, NULL
, endpoint
, NULL
, &binding
);
1925 ok(status
== RPC_S_OK
, "RpcStringBindingCompose failed (%u)\n", status
);
1927 status
= RpcBindingFromStringBinding(binding
, &Handle
);
1928 ok(status
== RPC_S_OK
, "RpcBindingFromStringBinding failed (%u)\n", status
);
1929 RpcStringFree(&binding
);
1931 NdrClientInitializeNew(&RpcMessage
, &StubMsg
, &StubDesc
, 5);
1933 ret
= NdrGetBuffer(&StubMsg
, 10, Handle
);
1934 ok(ret
== StubMsg
.Buffer
, "NdrGetBuffer should have returned the same value as StubMsg.Buffer instead of %p\n", ret
);
1935 ok(RpcMessage
.Handle
!= NULL
, "RpcMessage.Handle should not have been NULL\n");
1936 ok(RpcMessage
.Buffer
!= NULL
, "RpcMessage.Buffer should not have been NULL\n");
1937 ok(RpcMessage
.BufferLength
== 10 ||
1938 broken(RpcMessage
.BufferLength
== 12), /* win2k */
1939 "RpcMessage.BufferLength should have been 10 instead of %d\n", RpcMessage
.BufferLength
);
1940 ok(RpcMessage
.RpcFlags
== 0, "RpcMessage.RpcFlags should have been 0x0 instead of 0x%x\n", RpcMessage
.RpcFlags
);
1941 ok(StubMsg
.Buffer
!= NULL
, "Buffer should not have been NULL\n");
1942 ok(!StubMsg
.BufferStart
, "BufferStart should have been NULL instead of %p\n", StubMsg
.BufferStart
);
1943 ok(!StubMsg
.BufferEnd
, "BufferEnd should have been NULL instead of %p\n", StubMsg
.BufferEnd
);
1945 ok(StubMsg
.BufferLength
== 0, "BufferLength should have left as 0 instead of being set to %d\n", StubMsg
.BufferLength
);
1946 old_buffer_valid_location
= !StubMsg
.fBufferValid
;
1947 if (old_buffer_valid_location
)
1948 ok(broken(StubMsg
.CorrDespIncrement
== TRUE
), "fBufferValid should have been TRUE instead of 0x%x\n", StubMsg
.CorrDespIncrement
);
1950 ok(StubMsg
.fBufferValid
, "fBufferValid should have been non-zero instead of 0x%x\n", StubMsg
.fBufferValid
);
1952 prev_buffer_length
= RpcMessage
.BufferLength
;
1953 StubMsg
.BufferLength
= 1;
1954 NdrFreeBuffer(&StubMsg
);
1955 ok(RpcMessage
.Handle
!= NULL
, "RpcMessage.Handle should not have been NULL\n");
1956 ok(RpcMessage
.Buffer
!= NULL
, "RpcMessage.Buffer should not have been NULL\n");
1957 ok(RpcMessage
.BufferLength
== prev_buffer_length
, "RpcMessage.BufferLength should have been left as %d instead of %d\n", prev_buffer_length
, RpcMessage
.BufferLength
);
1958 ok(StubMsg
.Buffer
!= NULL
, "Buffer should not have been NULL\n");
1959 ok(StubMsg
.BufferLength
== 1, "BufferLength should have left as 1 instead of being set to %d\n", StubMsg
.BufferLength
);
1960 if (old_buffer_valid_location
)
1961 ok(broken(StubMsg
.CorrDespIncrement
== FALSE
), "fBufferValid should have been FALSE instead of 0x%x\n", StubMsg
.CorrDespIncrement
);
1963 ok(!StubMsg
.fBufferValid
, "fBufferValid should have been FALSE instead of %d\n", StubMsg
.fBufferValid
);
1965 /* attempt double-free */
1966 NdrFreeBuffer(&StubMsg
);
1968 RpcBindingFree(&Handle
);
1970 status
= RpcServerUnregisterIf(NULL
, NULL
, FALSE
);
1971 ok(status
== RPC_S_OK
, "RpcServerUnregisterIf failed (%u)\n", status
);
1974 static void test_NdrMapCommAndFaultStatus(void)
1976 RPC_STATUS rpc_status
;
1977 MIDL_STUB_MESSAGE StubMsg
;
1978 RPC_MESSAGE RpcMessage
;
1980 NdrClientInitializeNew(&RpcMessage
, &StubMsg
, &Object_StubDesc
, 5);
1982 for (rpc_status
= 0; rpc_status
< 10000; rpc_status
++)
1985 ULONG comm_status
= 0;
1986 ULONG fault_status
= 0;
1987 ULONG expected_comm_status
= 0;
1988 ULONG expected_fault_status
= 0;
1989 status
= NdrMapCommAndFaultStatus(&StubMsg
, &comm_status
, &fault_status
, rpc_status
);
1990 ok(status
== RPC_S_OK
, "NdrMapCommAndFaultStatus failed with error %d\n", status
);
1993 case ERROR_INVALID_HANDLE
:
1994 case RPC_S_INVALID_BINDING
:
1995 case RPC_S_UNKNOWN_IF
:
1996 case RPC_S_SERVER_UNAVAILABLE
:
1997 case RPC_S_SERVER_TOO_BUSY
:
1998 case RPC_S_CALL_FAILED_DNE
:
1999 case RPC_S_PROTOCOL_ERROR
:
2000 case RPC_S_UNSUPPORTED_TRANS_SYN
:
2001 case RPC_S_UNSUPPORTED_TYPE
:
2002 case RPC_S_PROCNUM_OUT_OF_RANGE
:
2003 case EPT_S_NOT_REGISTERED
:
2004 case RPC_S_COMM_FAILURE
:
2005 expected_comm_status
= rpc_status
;
2008 expected_fault_status
= rpc_status
;
2010 ok(comm_status
== expected_comm_status
, "NdrMapCommAndFaultStatus should have mapped %d to comm status %d instead of %d\n",
2011 rpc_status
, expected_comm_status
, comm_status
);
2012 ok(fault_status
== expected_fault_status
, "NdrMapCommAndFaultStatus should have mapped %d to fault status %d instead of %d\n",
2013 rpc_status
, expected_fault_status
, fault_status
);
2017 static void test_NdrGetUserMarshalInfo(void)
2020 MIDL_STUB_MESSAGE stubmsg
;
2021 USER_MARSHAL_CB umcb
;
2022 NDR_USER_MARSHAL_INFO umi
;
2023 unsigned char buffer
[16];
2024 void *rpc_channel_buffer
= (void *)(ULONG_PTR
)0xcafebabe;
2025 RPC_MESSAGE rpc_msg
;
2026 RPC_STATUS (RPC_ENTRY
*pNdrGetUserMarshalInfo
)(ULONG
*,ULONG
,NDR_USER_MARSHAL_INFO
*);
2028 pNdrGetUserMarshalInfo
= (void *)GetProcAddress(GetModuleHandle("rpcrt4.dll"), "NdrGetUserMarshalInfo");
2029 if (!pNdrGetUserMarshalInfo
)
2031 skip("NdrGetUserMarshalInfo not exported\n");
2037 memset(&rpc_msg
, 0xcc, sizeof(rpc_msg
));
2038 rpc_msg
.Buffer
= buffer
;
2039 rpc_msg
.BufferLength
= 16;
2041 memset(&stubmsg
, 0xcc, sizeof(stubmsg
));
2042 stubmsg
.RpcMsg
= &rpc_msg
;
2043 stubmsg
.dwDestContext
= MSHCTX_INPROC
;
2044 stubmsg
.pvDestContext
= NULL
;
2045 stubmsg
.Buffer
= buffer
+ 15;
2046 stubmsg
.BufferLength
= 0;
2047 stubmsg
.BufferEnd
= NULL
;
2048 stubmsg
.pRpcChannelBuffer
= rpc_channel_buffer
;
2049 stubmsg
.StubDesc
= NULL
;
2050 stubmsg
.pfnAllocate
= my_alloc
;
2051 stubmsg
.pfnFree
= my_free
;
2053 memset(&umcb
, 0xcc, sizeof(umcb
));
2054 umcb
.Flags
= MAKELONG(MSHCTX_INPROC
, NDR_LOCAL_DATA_REPRESENTATION
);
2055 umcb
.pStubMsg
= &stubmsg
;
2056 umcb
.Signature
= USER_MARSHAL_CB_SIGNATURE
;
2057 umcb
.CBType
= USER_MARSHAL_CB_UNMARSHALL
;
2059 memset(&umi
, 0xaa, sizeof(umi
));
2061 status
= pNdrGetUserMarshalInfo(&umcb
.Flags
, 1, &umi
);
2062 ok(status
== RPC_S_OK
, "NdrGetUserMarshalInfo failed with error %d\n", status
);
2063 ok( umi
.InformationLevel
== 1,
2064 "umi.InformationLevel was %u instead of 1\n",
2065 umi
.InformationLevel
);
2066 ok( U(umi
.Level1
).Buffer
== buffer
+ 15,
2067 "U(umi.Level1).Buffer was %p instead of %p\n",
2068 U(umi
.Level1
).Buffer
, buffer
);
2069 ok( U(umi
.Level1
).BufferSize
== 1,
2070 "U(umi.Level1).BufferSize was %u instead of 1\n",
2071 U(umi
.Level1
).BufferSize
);
2072 ok( U(umi
.Level1
).pfnAllocate
== my_alloc
,
2073 "U(umi.Level1).pfnAllocate was %p instead of %p\n",
2074 U(umi
.Level1
).pfnAllocate
, my_alloc
);
2075 ok( U(umi
.Level1
).pfnFree
== my_free
,
2076 "U(umi.Level1).pfnFree was %p instead of %p\n",
2077 U(umi
.Level1
).pfnFree
, my_free
);
2078 ok( U(umi
.Level1
).pRpcChannelBuffer
== rpc_channel_buffer
,
2079 "U(umi.Level1).pRpcChannelBuffer was %p instead of %p\n",
2080 U(umi
.Level1
).pRpcChannelBuffer
, rpc_channel_buffer
);
2084 rpc_msg
.Buffer
= buffer
;
2085 rpc_msg
.BufferLength
= 16;
2087 stubmsg
.Buffer
= buffer
;
2088 stubmsg
.BufferLength
= 16;
2089 stubmsg
.BufferEnd
= NULL
;
2091 umcb
.CBType
= USER_MARSHAL_CB_BUFFER_SIZE
;
2093 memset(&umi
, 0xaa, sizeof(umi
));
2095 status
= pNdrGetUserMarshalInfo(&umcb
.Flags
, 1, &umi
);
2096 ok(status
== RPC_S_OK
, "NdrGetUserMarshalInfo failed with error %d\n", status
);
2097 ok( umi
.InformationLevel
== 1,
2098 "umi.InformationLevel was %u instead of 1\n",
2099 umi
.InformationLevel
);
2100 ok( U(umi
.Level1
).Buffer
== NULL
,
2101 "U(umi.Level1).Buffer was %p instead of NULL\n",
2102 U(umi
.Level1
).Buffer
);
2103 ok( U(umi
.Level1
).BufferSize
== 0,
2104 "U(umi.Level1).BufferSize was %u instead of 0\n",
2105 U(umi
.Level1
).BufferSize
);
2106 ok( U(umi
.Level1
).pfnAllocate
== my_alloc
,
2107 "U(umi.Level1).pfnAllocate was %p instead of %p\n",
2108 U(umi
.Level1
).pfnAllocate
, my_alloc
);
2109 ok( U(umi
.Level1
).pfnFree
== my_free
,
2110 "U(umi.Level1).pfnFree was %p instead of %p\n",
2111 U(umi
.Level1
).pfnFree
, my_free
);
2112 ok( U(umi
.Level1
).pRpcChannelBuffer
== rpc_channel_buffer
,
2113 "U(umi.Level1).pRpcChannelBuffer was %p instead of %p\n",
2114 U(umi
.Level1
).pRpcChannelBuffer
, rpc_channel_buffer
);
2118 rpc_msg
.Buffer
= buffer
;
2119 rpc_msg
.BufferLength
= 16;
2121 stubmsg
.Buffer
= buffer
+ 15;
2122 stubmsg
.BufferLength
= 0;
2123 stubmsg
.BufferEnd
= NULL
;
2125 umcb
.CBType
= USER_MARSHAL_CB_MARSHALL
;
2127 memset(&umi
, 0xaa, sizeof(umi
));
2129 status
= pNdrGetUserMarshalInfo(&umcb
.Flags
, 1, &umi
);
2130 ok(status
== RPC_S_OK
, "NdrGetUserMarshalInfo failed with error %d\n", status
);
2131 ok( umi
.InformationLevel
== 1,
2132 "umi.InformationLevel was %u instead of 1\n",
2133 umi
.InformationLevel
);
2134 ok( U(umi
.Level1
).Buffer
== buffer
+ 15,
2135 "U(umi.Level1).Buffer was %p instead of %p\n",
2136 U(umi
.Level1
).Buffer
, buffer
);
2137 ok( U(umi
.Level1
).BufferSize
== 1,
2138 "U(umi.Level1).BufferSize was %u instead of 1\n",
2139 U(umi
.Level1
).BufferSize
);
2140 ok( U(umi
.Level1
).pfnAllocate
== my_alloc
,
2141 "U(umi.Level1).pfnAllocate was %p instead of %p\n",
2142 U(umi
.Level1
).pfnAllocate
, my_alloc
);
2143 ok( U(umi
.Level1
).pfnFree
== my_free
,
2144 "U(umi.Level1).pfnFree was %p instead of %p\n",
2145 U(umi
.Level1
).pfnFree
, my_free
);
2146 ok( U(umi
.Level1
).pRpcChannelBuffer
== rpc_channel_buffer
,
2147 "U(umi.Level1).pRpcChannelBuffer was %p instead of %p\n",
2148 U(umi
.Level1
).pRpcChannelBuffer
, rpc_channel_buffer
);
2152 rpc_msg
.Buffer
= buffer
;
2153 rpc_msg
.BufferLength
= 16;
2155 stubmsg
.Buffer
= buffer
;
2156 stubmsg
.BufferLength
= 16;
2157 stubmsg
.BufferEnd
= NULL
;
2159 umcb
.CBType
= USER_MARSHAL_CB_FREE
;
2161 memset(&umi
, 0xaa, sizeof(umi
));
2163 status
= pNdrGetUserMarshalInfo(&umcb
.Flags
, 1, &umi
);
2164 ok(status
== RPC_S_OK
, "NdrGetUserMarshalInfo failed with error %d\n", status
);
2165 ok( umi
.InformationLevel
== 1,
2166 "umi.InformationLevel was %u instead of 1\n",
2167 umi
.InformationLevel
);
2168 ok( U(umi
.Level1
).Buffer
== NULL
,
2169 "U(umi.Level1).Buffer was %p instead of NULL\n",
2170 U(umi
.Level1
).Buffer
);
2171 ok( U(umi
.Level1
).BufferSize
== 0,
2172 "U(umi.Level1).BufferSize was %u instead of 0\n",
2173 U(umi
.Level1
).BufferSize
);
2174 ok( U(umi
.Level1
).pfnAllocate
== my_alloc
,
2175 "U(umi.Level1).pfnAllocate was %p instead of %p\n",
2176 U(umi
.Level1
).pfnAllocate
, my_alloc
);
2177 ok( U(umi
.Level1
).pfnFree
== my_free
,
2178 "U(umi.Level1).pfnFree was %p instead of %p\n",
2179 U(umi
.Level1
).pfnFree
, my_free
);
2180 ok( U(umi
.Level1
).pRpcChannelBuffer
== rpc_channel_buffer
,
2181 "U(umi.Level1).pRpcChannelBuffer was %p instead of %p\n",
2182 U(umi
.Level1
).pRpcChannelBuffer
, rpc_channel_buffer
);
2186 rpc_msg
.Buffer
= buffer
;
2187 rpc_msg
.BufferLength
= 15;
2189 stubmsg
.Buffer
= buffer
+ 15;
2190 stubmsg
.BufferLength
= 0;
2191 stubmsg
.BufferEnd
= NULL
;
2193 umcb
.CBType
= USER_MARSHAL_CB_MARSHALL
;
2195 status
= pNdrGetUserMarshalInfo(&umcb
.Flags
, 1, &umi
);
2196 ok(status
== RPC_S_OK
, "NdrGetUserMarshalInfo failed with error %d\n", status
);
2197 ok( U(umi
.Level1
).BufferSize
== 0,
2198 "U(umi.Level1).BufferSize was %u instead of 0\n",
2199 U(umi
.Level1
).BufferSize
);
2201 /* error conditions */
2203 rpc_msg
.BufferLength
= 14;
2204 status
= pNdrGetUserMarshalInfo(&umcb
.Flags
, 1, &umi
);
2205 ok(status
== ERROR_INVALID_USER_BUFFER
,
2206 "NdrGetUserMarshalInfo should have failed with ERROR_INVALID_USER_BUFFER instead of %d\n", status
);
2208 rpc_msg
.BufferLength
= 15;
2209 status
= pNdrGetUserMarshalInfo(&umcb
.Flags
, 9999, &umi
);
2210 ok(status
== RPC_S_INVALID_ARG
,
2211 "NdrGetUserMarshalInfo should have failed with RPC_S_INVALID_ARG instead of %d\n", status
);
2214 status
= pNdrGetUserMarshalInfo(&umcb
.Flags
, 1, &umi
);
2215 ok(status
== RPC_S_OK
, "NdrGetUserMarshalInfo failed with error %d\n", status
);
2217 umcb
.CBType
= USER_MARSHAL_CB_MARSHALL
;
2219 status
= pNdrGetUserMarshalInfo(&umcb
.Flags
, 1, &umi
);
2220 ok(status
== RPC_S_INVALID_ARG
,
2221 "NdrGetUserMarshalInfo should have failed with RPC_S_INVALID_ARG instead of %d\n", status
);
2224 START_TEST( ndr_marshall
)
2226 determine_pointer_marshalling_style();
2228 test_ndr_simple_type();
2229 test_simple_types();
2230 test_nontrivial_pointer_types();
2231 test_simple_struct();
2232 test_fullpointer_xlat();
2235 test_ndr_allocate();
2236 test_conformant_array();
2237 test_conformant_string();
2238 test_nonconformant_string();
2239 test_conf_complex_struct();
2241 test_NdrMapCommAndFaultStatus();
2242 test_NdrGetUserMarshalInfo();