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
21 #define _WIN32_WINNT 0x0500
22 #define NTDDI_WIN2K 0x05000000
23 #define NTDDI_VERSION NTDDI_WIN2K /* for some MIDL_STUB_MESSAGE fields */
40 #include "wine/heap.h"
41 #include "wine/test.h"
43 static int my_alloc_called
;
44 static int my_free_called
;
45 static void * CALLBACK
my_alloc(SIZE_T size
)
48 return NdrOleAllocate(size
);
51 static void CALLBACK
my_free(void *ptr
)
57 static const MIDL_STUB_DESC Object_StubDesc
=
67 NULL
, /* format string, filled in by tests */
68 1, /* -error bounds_check flag */
69 0x20000, /* Ndr library version */
71 0x50100a4, /* MIDL Version 5.1.164 */
74 0, /* notify & notify_flag routine table */
81 static RPC_DISPATCH_FUNCTION IFoo_table
[] =
86 static RPC_DISPATCH_TABLE IFoo_v0_0_DispatchTable
=
92 static const RPC_SERVER_INTERFACE IFoo___RpcServerInterface
=
94 sizeof(RPC_SERVER_INTERFACE
),
95 {{0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x34}},{0,0}},
96 {{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}},
97 &IFoo_v0_0_DispatchTable
,
105 static RPC_IF_HANDLE IFoo_v0_0_s_ifspec
= (RPC_IF_HANDLE
)& IFoo___RpcServerInterface
;
106 static BOOL use_pointer_ids
= FALSE
;
108 static void determine_pointer_marshalling_style(void)
110 RPC_MESSAGE RpcMessage
;
111 MIDL_STUB_MESSAGE StubMsg
;
112 MIDL_STUB_DESC StubDesc
;
115 static const unsigned char fmtstr_up_char
[] =
117 0x12, 0x8, /* FC_UP [simple_pointer] */
122 StubDesc
= Object_StubDesc
;
123 StubDesc
.pFormatTypes
= NULL
;
125 NdrClientInitializeNew(
131 StubMsg
.BufferLength
= 8;
132 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
133 NdrPointerMarshall(&StubMsg
, (unsigned char*)&ch
, fmtstr_up_char
);
134 ok(StubMsg
.Buffer
== StubMsg
.BufferStart
+ 5, "%p %p\n", StubMsg
.Buffer
, StubMsg
.BufferStart
);
136 use_pointer_ids
= (*(unsigned int *)StubMsg
.BufferStart
!= (UINT_PTR
)&ch
);
137 trace("Pointer marshalling using %s\n", use_pointer_ids
? "pointer ids" : "pointer value");
139 HeapFree(GetProcessHeap(), 0, StubMsg
.BufferStart
);
142 static void test_ndr_simple_type(void)
144 RPC_MESSAGE RpcMessage
;
145 MIDL_STUB_MESSAGE StubMsg
;
146 MIDL_STUB_DESC StubDesc
;
149 StubDesc
= Object_StubDesc
;
150 StubDesc
.pFormatTypes
= NULL
;
152 NdrClientInitializeNew(
158 StubMsg
.BufferLength
= 16;
159 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
161 NdrSimpleTypeMarshall(&StubMsg
, (unsigned char*)&l
, FC_LONG
);
162 ok(StubMsg
.Buffer
== StubMsg
.BufferStart
+ 4, "%p %p\n", StubMsg
.Buffer
, StubMsg
.BufferStart
);
163 ok(*(LONG
*)StubMsg
.BufferStart
== l
, "%d\n", *(LONG
*)StubMsg
.BufferStart
);
165 StubMsg
.Buffer
= StubMsg
.BufferStart
+ 1;
166 NdrSimpleTypeMarshall(&StubMsg
, (unsigned char*)&l
, FC_LONG
);
167 ok(StubMsg
.Buffer
== StubMsg
.BufferStart
+ 8, "%p %p\n", StubMsg
.Buffer
, StubMsg
.BufferStart
);
168 ok(*(LONG
*)(StubMsg
.BufferStart
+ 4) == l
, "%d\n", *(LONG
*)StubMsg
.BufferStart
);
170 StubMsg
.Buffer
= StubMsg
.BufferStart
+ 1;
171 NdrSimpleTypeUnmarshall(&StubMsg
, (unsigned char*)&l2
, FC_LONG
);
172 ok(StubMsg
.Buffer
== StubMsg
.BufferStart
+ 8, "%p %p\n", StubMsg
.Buffer
, StubMsg
.BufferStart
);
173 ok(l2
== l
, "%d\n", l2
);
175 HeapFree(GetProcessHeap(), 0, StubMsg
.BufferStart
);
178 static void test_pointer_marshal(const unsigned char *formattypes
,
179 void *memsrc
, DWORD srcsize
,
180 const void *wiredata
,
182 int(*cmp
)(const void*,const void*,size_t),
183 int num_additional_allocs
,
186 RPC_MESSAGE RpcMessage
;
187 MIDL_STUB_MESSAGE StubMsg
;
188 MIDL_STUB_DESC StubDesc
;
191 unsigned char *mem
, *mem_orig
;
196 StubDesc
= Object_StubDesc
;
197 StubDesc
.pFormatTypes
= formattypes
;
199 NdrClientInitializeNew(
205 StubMsg
.BufferLength
= 0;
206 NdrPointerBufferSize( &StubMsg
,
209 ok(StubMsg
.BufferLength
>= wiredatalen
, "%s: length %d\n", msgpfx
, StubMsg
.BufferLength
);
211 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
212 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
213 StubMsg
.BufferEnd
= StubMsg
.BufferStart
+ StubMsg
.BufferLength
;
215 memset(StubMsg
.BufferStart
, 0x0, StubMsg
.BufferLength
); /* This is a hack to clear the padding between the ptr and longlong/double */
217 ptr
= NdrPointerMarshall( &StubMsg
, memsrc
, formattypes
);
218 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
219 if (srcsize
== 8 && wiredatalen
== 16 && StubMsg
.Buffer
- StubMsg
.BufferStart
== 12)
221 /* win9x doesn't align 8-byte types properly */
226 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
227 ok(!memcmp(StubMsg
.BufferStart
, wiredata
, wiredatalen
), "%s: incorrectly marshaled\n", msgpfx
);
230 StubMsg
.Buffer
= StubMsg
.BufferStart
;
231 StubMsg
.MemorySize
= 0;
233 size
= NdrPointerMemorySize( &StubMsg
, formattypes
);
234 ok(size
== StubMsg
.MemorySize
, "%s: mem size %u size %u\n", msgpfx
, StubMsg
.MemorySize
, size
);
235 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
236 if (formattypes
[1] & FC_POINTER_DEREF
)
237 ok(size
== srcsize
+ sizeof(void *), "%s: mem size %u\n", msgpfx
, size
);
239 ok(size
== srcsize
, "%s: mem size %u\n", msgpfx
, size
);
241 StubMsg
.Buffer
= StubMsg
.BufferStart
;
242 StubMsg
.MemorySize
= 16;
243 size
= NdrPointerMemorySize( &StubMsg
, formattypes
);
244 ok(size
== StubMsg
.MemorySize
, "%s: mem size %u size %u\n", msgpfx
, StubMsg
.MemorySize
, size
);
245 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
246 if (formattypes
[1] & FC_POINTER_DEREF
)
247 ok(size
== srcsize
+ sizeof(void *) + 16, "%s: mem size %u\n", msgpfx
, size
);
249 ok(size
== srcsize
+ 16, "%s: mem size %u\n", msgpfx
, size
);
251 StubMsg
.Buffer
= StubMsg
.BufferStart
;
252 StubMsg
.MemorySize
= 1;
253 size
= NdrPointerMemorySize( &StubMsg
, formattypes
);
254 ok(size
== StubMsg
.MemorySize
, "%s: mem size %u size %u\n", msgpfx
, StubMsg
.MemorySize
, size
);
255 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
256 if (formattypes
[1] & FC_POINTER_DEREF
)
257 ok(size
== srcsize
+ sizeof(void *) + (srcsize
== 8 ? 8 : sizeof(void *)), "%s: mem size %u\n", msgpfx
, size
);
259 ok(size
== srcsize
+ (srcsize
== 8 ? 8 : sizeof(void *)), "%s: mem size %u\n", msgpfx
, size
);
262 if (formattypes
[1] & FC_POINTER_DEREF
) size
+= 4;
264 StubMsg
.Buffer
= StubMsg
.BufferStart
;
265 StubMsg
.MemorySize
= 0;
266 /* Using my_alloc() here is necessary to prevent a crash in Windows 7+. */
267 mem_orig
= mem
= my_alloc(size
);
268 memset(mem
, 0, size
);
269 my_alloc_called
= my_free_called
= 0;
270 if (formattypes
[1] & FC_POINTER_DEREF
)
272 ptr
= NdrPointerUnmarshall( &StubMsg
, &mem
, formattypes
, 0 );
273 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
274 ok(mem
== mem_orig
, "%s: mem has changed %p %p\n", msgpfx
, mem
, mem_orig
);
275 ok(!cmp(mem
, memsrc
, srcsize
), "%s: incorrectly unmarshaled\n", msgpfx
);
276 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
277 ok(StubMsg
.MemorySize
== 0, "%s: memorysize %d\n", msgpfx
, StubMsg
.MemorySize
);
278 ok(my_alloc_called
== num_additional_allocs
, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
279 /* On Windows 7+ unmarshalling may involve calls to NdrFree, for unclear reasons. */
282 NdrPointerFree(&StubMsg
, mem
, formattypes
);
283 if ((formattypes
[1] & FC_ALLOCED_ON_STACK
) && (formattypes
[1] & FC_POINTER_DEREF
))
285 /* In this case the top-level pointer is not freed. */
286 ok(my_free_called
== num_additional_allocs
, "%s: my_free got called %d times\n", msgpfx
, my_free_called
);
287 HeapFree(GetProcessHeap(), 0, mem
);
290 ok(my_free_called
== 1 + num_additional_allocs
, "%s: my_free got called %d times\n", msgpfx
, my_free_called
);
292 /* reset the buffer and call with must alloc */
293 my_alloc_called
= my_free_called
= 0;
294 StubMsg
.Buffer
= StubMsg
.BufferStart
;
295 mem_orig
= mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
296 if (formattypes
[1] & FC_POINTER_DEREF
)
298 ptr
= NdrPointerUnmarshall( &StubMsg
, &mem
, formattypes
, 1 );
299 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
300 /* doesn't allocate mem in this case */
301 ok(mem
== mem_orig
, "%s: mem has changed %p %p\n", msgpfx
, mem
, mem_orig
);
302 ok(!cmp(mem
, memsrc
, srcsize
), "%s: incorrectly unmarshaled\n", msgpfx
);
303 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
304 ok(StubMsg
.MemorySize
== 0, "%s: memorysize %d\n", msgpfx
, StubMsg
.MemorySize
);
305 ok(my_alloc_called
== num_additional_allocs
, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
306 ok(!my_free_called
, "%s: my_free got called %d times\n", msgpfx
, my_free_called
);
308 NdrPointerFree(&StubMsg
, mem
, formattypes
);
309 if ((formattypes
[1] & FC_ALLOCED_ON_STACK
) && (formattypes
[1] & FC_POINTER_DEREF
))
311 /* In this case the top-level pointer is not freed. */
312 ok(my_free_called
== num_additional_allocs
, "%s: my_free got called %d times\n", msgpfx
, my_free_called
);
313 HeapFree(GetProcessHeap(), 0, mem
);
316 ok(my_free_called
== 1 + num_additional_allocs
, "%s: my_free got called %d times\n", msgpfx
, my_free_called
);
318 if (formattypes
[0] != FC_RP
)
320 /* now pass the address of a NULL ptr */
322 my_alloc_called
= my_free_called
= 0;
323 StubMsg
.Buffer
= StubMsg
.BufferStart
;
324 ptr
= NdrPointerUnmarshall( &StubMsg
, &mem
, formattypes
, 0 );
325 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
326 ok(mem
!= StubMsg
.BufferStart
+ wiredatalen
- srcsize
, "%s: mem points to buffer %p %p\n", msgpfx
, mem
, StubMsg
.BufferStart
);
327 ok(!cmp(mem
, memsrc
, size
), "%s: incorrectly unmarshaled\n", msgpfx
);
328 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
329 ok(StubMsg
.MemorySize
== 0, "%s: memorysize %d\n", msgpfx
, StubMsg
.MemorySize
);
330 ok(my_alloc_called
== num_additional_allocs
+ 1, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
332 NdrPointerFree(&StubMsg
, mem
, formattypes
);
334 /* again pass address of NULL ptr, but pretend we're a server */
335 if (0) /* crashes on Win9x and NT4 */
338 StubMsg
.Buffer
= StubMsg
.BufferStart
;
339 StubMsg
.IsClient
= 0;
340 ptr
= NdrPointerUnmarshall( &StubMsg
, &mem
, formattypes
, 0 );
341 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
342 if (formattypes
[2] == FC_ENUM16
)
343 ok(mem
!= StubMsg
.BufferStart
+ wiredatalen
- srcsize
, "%s: mem points to buffer %p %p\n", msgpfx
, mem
, StubMsg
.BufferStart
);
345 ok(mem
== StubMsg
.BufferStart
+ wiredatalen
- srcsize
, "%s: mem doesn't point to buffer %p %p\n", msgpfx
, mem
, StubMsg
.BufferStart
);
346 ok(!cmp(mem
, memsrc
, size
), "%s: incorrectly unmarshaled\n", msgpfx
);
347 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
348 ok(StubMsg
.MemorySize
== 0, "%s: memorysize %d\n", msgpfx
, StubMsg
.MemorySize
);
349 if (formattypes
[2] != FC_ENUM16
)
351 ok(my_alloc_called
== num_additional_allocs
, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
358 StubMsg
.IsClient
= 0;
360 /* For most basetypes (but not enum16), memory will not be allocated but
361 * instead point directly to the buffer. */
362 my_alloc_called
= my_free_called
= 0;
363 StubMsg
.Buffer
= StubMsg
.BufferStart
;
365 ptr
= NdrPointerUnmarshall( &StubMsg
, &mem
, formattypes
, 0 );
366 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
367 ok(!!mem
, "%s: mem was not allocated\n", msgpfx
);
368 ok(!cmp(mem
, memsrc
, srcsize
), "%s: incorrectly unmarshaled\n", msgpfx
);
369 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
370 ok(StubMsg
.MemorySize
== 0, "%s: memorysize %d\n", msgpfx
, StubMsg
.MemorySize
);
371 if (formattypes
[2] == FC_ENUM16
)
372 ok(my_alloc_called
== 1, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
374 ok(my_alloc_called
== num_additional_allocs
, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
375 ok(!my_free_called
, "%s: my_free got called %d times\n", msgpfx
, my_free_called
);
377 NdrPointerFree(&StubMsg
, mem
, formattypes
);
378 if (formattypes
[2] == FC_ENUM16
)
379 ok(my_free_called
== 1, "%s: my_free got called %d times\n", msgpfx
, my_free_called
);
380 else if ((formattypes
[1] & FC_ALLOCED_ON_STACK
) && (formattypes
[1] & FC_POINTER_DEREF
))
382 /* In theory this should be freed to correspond with the allocation, but
383 * FC_ALLOCED_ON_STACK is set, and NdrPointerFree() has no way of
384 * knowing that the memory allocated by NdrPointerUnmarshall() isn't
385 * stack memory. In practice it always *is* stack memory if ON_STACK is
386 * set, so this leak isn't a concern. */
387 ok(my_free_called
== 0, "%s: my_free got called %d times\n", msgpfx
, my_free_called
);
388 HeapFree(GetProcessHeap(), 0, mem
);
391 ok(my_free_called
== num_additional_allocs
, "%s: my_free got called %d times\n", msgpfx
, my_free_called
);
393 /* reset the buffer and call with must alloc */
394 my_alloc_called
= my_free_called
= 0;
395 StubMsg
.Buffer
= StubMsg
.BufferStart
;
397 ptr
= NdrPointerUnmarshall( &StubMsg
, &mem
, formattypes
, 1 );
398 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
399 ok(!!mem
, "%s: mem was not allocated\n", msgpfx
);
400 ok(!cmp(mem
, memsrc
, srcsize
), "%s: incorrectly unmarshaled\n", msgpfx
);
401 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
402 ok(StubMsg
.MemorySize
== 0, "%s: memorysize %d\n", msgpfx
, StubMsg
.MemorySize
);
403 if (formattypes
[2] == FC_ENUM16
)
404 ok(my_alloc_called
== 1, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
406 ok(my_alloc_called
== num_additional_allocs
, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
407 ok(!my_free_called
, "%s: my_free got called %d times\n", msgpfx
, my_free_called
);
409 NdrPointerFree(&StubMsg
, mem
, formattypes
);
410 if (formattypes
[2] == FC_ENUM16
)
411 ok(my_free_called
== 1, "%s: my_free got called %d times\n", msgpfx
, my_free_called
);
412 else if ((formattypes
[1] & FC_ALLOCED_ON_STACK
) && (formattypes
[1] & FC_POINTER_DEREF
))
414 ok(my_free_called
== 0, "%s: my_free got called %d times\n", msgpfx
, my_free_called
);
415 HeapFree(GetProcessHeap(), 0, mem
);
418 ok(my_free_called
== num_additional_allocs
, "%s: my_free got called %d times\n", msgpfx
, my_free_called
);
420 /* Τest with an existing pointer. Unless it's a stack pointer (and deref'd)
421 * a new pointer will be allocated anyway (in fact, an invalid pointer works
422 * in every such case). */
424 my_alloc_called
= my_free_called
= 0;
425 StubMsg
.Buffer
= StubMsg
.BufferStart
;
426 mem_orig
= mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
427 if (formattypes
[1] & FC_POINTER_DEREF
)
429 ptr
= NdrPointerUnmarshall( &StubMsg
, &mem
, formattypes
, 0 );
430 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
431 if ((formattypes
[1] & FC_ALLOCED_ON_STACK
) && (formattypes
[1] & FC_POINTER_DEREF
))
432 ok(mem
== mem_orig
, "%s: mem has changed %p %p\n", msgpfx
, mem
, mem_orig
);
434 ok(mem
!= mem_orig
, "%s: mem has not changed\n", msgpfx
);
435 ok(!cmp(mem
, memsrc
, srcsize
), "%s: incorrectly unmarshaled\n", msgpfx
);
436 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
437 ok(StubMsg
.MemorySize
== 0, "%s: memorysize %d\n", msgpfx
, StubMsg
.MemorySize
);
438 if (formattypes
[2] == FC_ENUM16
)
439 ok(my_alloc_called
== 1, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
440 else if ((formattypes
[1] & FC_ALLOCED_ON_STACK
) && (formattypes
[1] & FC_POINTER_DEREF
))
441 ok(my_alloc_called
== 0, "%s: my_alloc got called %d times\n", msgpfx
, my_free_called
);
443 ok(my_alloc_called
== num_additional_allocs
, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
444 ok(!my_free_called
, "%s: my_free got called %d times\n", msgpfx
, my_free_called
);
446 NdrPointerFree(&StubMsg
, mem
, formattypes
);
447 if (formattypes
[2] == FC_ENUM16
)
448 ok(my_free_called
== 1, "%s: my_free got called %d times\n", msgpfx
, my_free_called
);
449 else if ((formattypes
[1] & FC_ALLOCED_ON_STACK
) && (formattypes
[1] & FC_POINTER_DEREF
))
451 ok(my_free_called
== 0, "%s: my_free got called %d times\n", msgpfx
, my_free_called
);
452 HeapFree(GetProcessHeap(), 0, mem
);
455 ok(my_free_called
== num_additional_allocs
, "%s: my_free got called %d times\n", msgpfx
, my_free_called
);
457 /* reset the buffer and call with must alloc */
458 my_alloc_called
= my_free_called
= 0;
459 StubMsg
.Buffer
= StubMsg
.BufferStart
;
460 mem_orig
= mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
461 if (formattypes
[1] & FC_POINTER_DEREF
)
463 ptr
= NdrPointerUnmarshall( &StubMsg
, &mem
, formattypes
, 1 );
464 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
465 if ((formattypes
[1] & FC_ALLOCED_ON_STACK
) && (formattypes
[1] & FC_POINTER_DEREF
))
466 ok(mem
== mem_orig
, "%s: mem has changed %p %p\n", msgpfx
, mem
, mem_orig
);
468 ok(mem
!= mem_orig
, "%s: mem has not changed\n", msgpfx
);
469 ok(!cmp(mem
, memsrc
, srcsize
), "%s: incorrectly unmarshaled\n", msgpfx
);
470 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p len %d\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
, wiredatalen
);
471 ok(StubMsg
.MemorySize
== 0, "%s: memorysize %d\n", msgpfx
, StubMsg
.MemorySize
);
472 if (formattypes
[2] == FC_ENUM16
)
473 ok(my_alloc_called
== 1, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
474 else if ((formattypes
[1] & FC_ALLOCED_ON_STACK
) && (formattypes
[1] & FC_POINTER_DEREF
))
475 ok(my_alloc_called
== 0, "%s: my_alloc got called %d times\n", msgpfx
, my_free_called
);
477 ok(my_alloc_called
== num_additional_allocs
, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
478 ok(!my_free_called
, "%s: my_free got called %d times\n", msgpfx
, my_free_called
);
480 NdrPointerFree(&StubMsg
, mem
, formattypes
);
481 if (formattypes
[2] == FC_ENUM16
)
482 ok(my_free_called
== 1, "%s: my_free got called %d times\n", msgpfx
, my_free_called
);
483 else if ((formattypes
[1] & FC_ALLOCED_ON_STACK
) && (formattypes
[1] & FC_POINTER_DEREF
))
485 ok(my_free_called
== 0, "%s: my_free got called %d times\n", msgpfx
, my_free_called
);
486 HeapFree(GetProcessHeap(), 0, mem
);
489 ok(my_free_called
== num_additional_allocs
, "%s: my_free got called %d times\n", msgpfx
, my_free_called
);
491 HeapFree(GetProcessHeap(), 0, StubMsg
.BufferStart
);
494 static int deref_cmp(const void *s1
, const void *s2
, size_t num
)
496 return memcmp(*(const void *const *)s1
, *(const void *const *)s2
, num
);
500 static void test_simple_types(void)
502 unsigned char wiredata
[16];
504 unsigned char *ch_ptr
;
512 static const unsigned char fmtstr_up_char
[] =
514 0x12, 0x8, /* FC_UP [simple_pointer] */
518 static const unsigned char fmtstr_up_byte
[] =
520 0x12, 0x8, /* FC_UP [simple_pointer] */
524 static const unsigned char fmtstr_up_small
[] =
526 0x12, 0x8, /* FC_UP [simple_pointer] */
530 static const unsigned char fmtstr_up_usmall
[] =
532 0x12, 0x8, /* FC_UP [simple_pointer] */
536 static const unsigned char fmtstr_rp_char
[] =
538 0x11, 0x8, /* FC_RP [simple_pointer] */
542 static const unsigned char fmtstr_rpup_char_onstack_deref
[] =
544 0x11, 0x14, /* FC_RP [alloced_on_stack] [pointer_deref] */
545 NdrFcShort( 0x2 ), /* Offset= 2 (4) */
546 0x12, 0x8, /* FC_UP [simple_pointer] */
550 static const unsigned char fmtstr_rpup_char_onstack
[] =
552 0x11, 0x04, /* FC_RP [alloced_on_stack] */
553 NdrFcShort( 0x2 ), /* Offset= 2 (4) */
554 0x12, 0x8, /* FC_UP [simple_pointer] */
558 static const unsigned char fmtstr_rpup_char_deref
[] =
560 0x11, 0x10, /* FC_RP [pointer_deref] */
561 NdrFcShort( 0x2 ), /* Offset= 2 (4) */
562 0x12, 0x8, /* FC_UP [simple_pointer] */
567 static const unsigned char fmtstr_up_wchar
[] =
569 0x12, 0x8, /* FC_UP [simple_pointer] */
573 static const unsigned char fmtstr_up_short
[] =
575 0x12, 0x8, /* FC_UP [simple_pointer] */
579 static const unsigned char fmtstr_up_ushort
[] =
581 0x12, 0x8, /* FC_UP [simple_pointer] */
585 static const unsigned char fmtstr_up_enum16
[] =
587 0x12, 0x8, /* FC_UP [simple_pointer] */
591 static const unsigned char fmtstr_up_long
[] =
593 0x12, 0x8, /* FC_UP [simple_pointer] */
597 static const unsigned char fmtstr_up_ulong
[] =
599 0x12, 0x8, /* FC_UP [simple_pointer] */
603 static const unsigned char fmtstr_up_enum32
[] =
605 0x12, 0x8, /* FC_UP [simple_pointer] */
609 static const unsigned char fmtstr_up_errorstatus
[] =
611 0x12, 0x8, /* FC_UP [simple_pointer] */
612 0x10, /* FC_ERROR_STATUS_T */
616 static const unsigned char fmtstr_up_longlong
[] =
618 0x12, 0x8, /* FC_UP [simple_pointer] */
622 static const unsigned char fmtstr_up_float
[] =
624 0x12, 0x8, /* FC_UP [simple_pointer] */
628 static const unsigned char fmtstr_up_double
[] =
630 0x12, 0x8, /* FC_UP [simple_pointer] */
638 *(unsigned int *)wiredata
= 0x20000;
640 *(unsigned int *)wiredata
= (UINT_PTR
)ch_ptr
;
643 test_pointer_marshal(fmtstr_up_char
, ch_ptr
, 1, wiredata
, 5, NULL
, 0, "up_char");
644 test_pointer_marshal(fmtstr_up_byte
, ch_ptr
, 1, wiredata
, 5, NULL
, 0, "up_byte");
645 test_pointer_marshal(fmtstr_up_small
, ch_ptr
, 1, wiredata
, 5, NULL
, 0, "up_small");
646 test_pointer_marshal(fmtstr_up_usmall
, ch_ptr
, 1, wiredata
, 5, NULL
, 0, "up_usmall");
648 test_pointer_marshal(fmtstr_rp_char
, ch_ptr
, 1, &ch
, 1, NULL
, 0, "rp_char");
650 test_pointer_marshal(fmtstr_rpup_char_onstack_deref
, &ch_ptr
, 1, wiredata
, 5, deref_cmp
, 1, "rpup_char_onstack_deref");
651 test_pointer_marshal(fmtstr_rpup_char_onstack
, ch_ptr
, 1, wiredata
, 5, NULL
, 0, "rpup_char_onstack");
652 test_pointer_marshal(fmtstr_rpup_char_deref
, &ch_ptr
, 1, wiredata
, 5, deref_cmp
, 1, "rpup_char_deref");
656 *(unsigned int *)wiredata
= 0x20000;
658 *(unsigned int *)wiredata
= (UINT_PTR
)&s
;
659 *(unsigned short*)(wiredata
+ 4) = s
;
661 test_pointer_marshal(fmtstr_up_wchar
, &s
, 2, wiredata
, 6, NULL
, 0, "up_wchar");
662 test_pointer_marshal(fmtstr_up_short
, &s
, 2, wiredata
, 6, NULL
, 0, "up_short");
663 test_pointer_marshal(fmtstr_up_ushort
, &s
, 2, wiredata
, 6, NULL
, 0, "up_ushort");
667 *(unsigned int *)wiredata
= 0x20000;
669 *(unsigned int *)wiredata
= (UINT_PTR
)&i
;
670 *(unsigned short*)(wiredata
+ 4) = i
;
671 test_pointer_marshal(fmtstr_up_enum16
, &i
, 4, wiredata
, 6, NULL
, 0, "up_enum16");
675 *(unsigned int *)wiredata
= 0x20000;
677 *(unsigned int *)wiredata
= (UINT_PTR
)&l
;
678 *(ULONG
*)(wiredata
+ 4) = l
;
680 test_pointer_marshal(fmtstr_up_long
, &l
, 4, wiredata
, 8, NULL
, 0, "up_long");
681 test_pointer_marshal(fmtstr_up_ulong
, &l
, 4, wiredata
, 8, NULL
, 0, "up_ulong");
682 test_pointer_marshal(fmtstr_up_enum32
, &l
, 4, wiredata
, 8, NULL
, 0, "up_emun32");
683 test_pointer_marshal(fmtstr_up_errorstatus
, &l
, 4, wiredata
, 8, NULL
, 0, "up_errorstatus");
685 ll
= ((ULONGLONG
)0xcafebabe) << 32 | 0xdeadbeef;
687 *(unsigned int *)wiredata
= 0x20000;
689 *(unsigned int *)wiredata
= (UINT_PTR
)&ll
;
690 *(unsigned int *)(wiredata
+ 4) = 0;
691 *(ULONGLONG
*)(wiredata
+ 8) = ll
;
692 test_pointer_marshal(fmtstr_up_longlong
, &ll
, 8, wiredata
, 16, NULL
, 0, "up_longlong");
696 *(unsigned int *)wiredata
= 0x20000;
698 *(unsigned int *)wiredata
= (UINT_PTR
)&f
;
699 *(float*)(wiredata
+ 4) = f
;
700 test_pointer_marshal(fmtstr_up_float
, &f
, 4, wiredata
, 8, NULL
, 0, "up_float");
704 *(unsigned int *)wiredata
= 0x20000;
706 *(unsigned int *)wiredata
= (UINT_PTR
)&d
;
707 *(unsigned int *)(wiredata
+ 4) = 0;
708 *(double*)(wiredata
+ 8) = d
;
709 test_pointer_marshal(fmtstr_up_double
, &d
, 8, wiredata
, 16, NULL
, 0, "up_double");
713 static void test_nontrivial_pointer_types(void)
715 RPC_MESSAGE RpcMessage
;
716 MIDL_STUB_MESSAGE StubMsg
;
717 MIDL_STUB_DESC StubDesc
;
723 unsigned char *mem
, *mem_orig
;
725 static const unsigned char fmtstr_ref_unique_out
[] =
727 0x12, 0x8, /* FC_UP [simple_pointer] */
730 0x11, 0x14, /* FC_RP [alloced_on_stack] [pointer_deref] */
731 NdrFcShort( 0xfffffffa ), /* Offset= -6 (0) */
738 StubDesc
= Object_StubDesc
;
739 StubDesc
.pFormatTypes
= fmtstr_ref_unique_out
;
741 NdrClientInitializeNew(
747 StubMsg
.BufferLength
= 0;
748 NdrPointerBufferSize( &StubMsg
,
750 &fmtstr_ref_unique_out
[4] );
752 /* Windows overestimates the buffer size */
753 ok(StubMsg
.BufferLength
>= 5, "length %d\n", StubMsg
.BufferLength
);
755 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
756 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
757 StubMsg
.BufferEnd
= StubMsg
.BufferStart
+ StubMsg
.BufferLength
;
759 ptr
= NdrPointerMarshall( &StubMsg
, (unsigned char *)p1
, &fmtstr_ref_unique_out
[4] );
760 ok(ptr
== NULL
, "ret %p\n", ptr
);
761 size
= StubMsg
.Buffer
- StubMsg
.BufferStart
;
762 ok(size
== 5, "Buffer %p Start %p len %d\n", StubMsg
.Buffer
, StubMsg
.BufferStart
, size
);
763 ok(*(unsigned int *)StubMsg
.BufferStart
!= 0, "pointer ID marshalled incorrectly\n");
764 ok(*(unsigned char *)(StubMsg
.BufferStart
+ 4) == 0x22, "char data marshalled incorrectly: 0x%x\n",
765 *(unsigned char *)(StubMsg
.BufferStart
+ 4));
767 StubMsg
.Buffer
= StubMsg
.BufferStart
;
768 StubMsg
.MemorySize
= 0;
773 StubMsg
.Buffer
= StubMsg
.BufferStart
;
774 mem
= mem_orig
= HeapAlloc(GetProcessHeap(), 0, sizeof(void *));
775 *(void **)mem
= NULL
;
776 NdrPointerUnmarshall( &StubMsg
, &mem
, &fmtstr_ref_unique_out
[4], 0);
777 ok(mem
== mem_orig
, "mem alloced\n");
778 ok(my_alloc_called
== 1, "alloc called %d\n", my_alloc_called
);
781 StubMsg
.Buffer
= StubMsg
.BufferStart
;
782 NdrPointerUnmarshall( &StubMsg
, &mem
, &fmtstr_ref_unique_out
[4], 1);
783 ok(mem
== mem_orig
, "mem alloced\n");
784 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
787 StubMsg
.Buffer
= StubMsg
.BufferStart
;
788 NdrPointerFree( &StubMsg
, mem
, &fmtstr_ref_unique_out
[4] );
789 ok(my_free_called
== 1, "free called %d\n", my_free_called
);
791 mem
= my_alloc(sizeof(void *));
792 *(void **)mem
= NULL
;
794 StubMsg
.Buffer
= StubMsg
.BufferStart
;
795 NdrPointerFree( &StubMsg
, mem
, &fmtstr_ref_unique_out
[4] );
796 ok(my_free_called
== 0, "free called %d\n", my_free_called
);
799 mem
= my_alloc(sizeof(void *));
800 *(void **)mem
= my_alloc(sizeof(char));
802 StubMsg
.Buffer
= StubMsg
.BufferStart
;
803 NdrPointerFree( &StubMsg
, mem
, &fmtstr_ref_unique_out
[4] );
804 ok(my_free_called
== 1, "free called %d\n", my_free_called
);
809 StubMsg
.IsClient
= 0;
811 StubMsg
.Buffer
= StubMsg
.BufferStart
;
812 NdrPointerUnmarshall( &StubMsg
, &mem
, &fmtstr_ref_unique_out
[4], 0);
813 ok(mem
!= StubMsg
.BufferStart
, "mem pointing at buffer\n");
814 ok(my_alloc_called
== 1, "alloc called %d\n", my_alloc_called
);
815 NdrPointerFree( &StubMsg
, mem
, &fmtstr_ref_unique_out
[4] );
819 StubMsg
.Buffer
= StubMsg
.BufferStart
;
820 NdrPointerUnmarshall( &StubMsg
, &mem
, &fmtstr_ref_unique_out
[4], 1);
821 ok(mem
!= StubMsg
.BufferStart
, "mem pointing at buffer\n");
822 ok(my_alloc_called
== 1, "alloc called %d\n", my_alloc_called
);
823 NdrPointerFree( &StubMsg
, mem
, &fmtstr_ref_unique_out
[4] );
827 *(void **)mem
= NULL
;
828 StubMsg
.Buffer
= StubMsg
.BufferStart
;
829 NdrPointerUnmarshall( &StubMsg
, &mem
, &fmtstr_ref_unique_out
[4], 0);
830 ok(mem
== mem_orig
, "mem alloced\n");
831 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
835 *(void **)mem
= NULL
;
836 StubMsg
.Buffer
= StubMsg
.BufferStart
;
837 NdrPointerUnmarshall( &StubMsg
, &mem
, &fmtstr_ref_unique_out
[4], 1);
838 ok(mem
== mem_orig
, "mem alloced\n");
839 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
841 mem
= my_alloc(sizeof(void *));
842 *(void **)mem
= NULL
;
844 StubMsg
.Buffer
= StubMsg
.BufferStart
;
845 NdrPointerFree( &StubMsg
, mem
, &fmtstr_ref_unique_out
[4] );
846 ok(my_free_called
== 0, "free called %d\n", my_free_called
);
849 mem
= my_alloc(sizeof(void *));
850 *(void **)mem
= my_alloc(sizeof(char));
852 StubMsg
.Buffer
= StubMsg
.BufferStart
;
853 NdrPointerFree( &StubMsg
, mem
, &fmtstr_ref_unique_out
[4] );
854 ok(my_free_called
== 1, "free called %d\n", my_free_called
);
857 HeapFree(GetProcessHeap(), 0, mem_orig
);
858 HeapFree(GetProcessHeap(), 0, StubMsg
.RpcMsg
->Buffer
);
861 static void test_simple_struct_marshal(const unsigned char *formattypes
,
862 void *memsrc
, DWORD srcsize
,
863 const void *wiredata
,
865 int(*cmp
)(const void*,const void*,size_t),
866 int num_additional_allocs
,
869 RPC_MESSAGE RpcMessage
;
870 MIDL_STUB_MESSAGE StubMsg
;
871 MIDL_STUB_DESC StubDesc
;
874 unsigned char *mem
, *mem_orig
;
876 my_alloc_called
= my_free_called
= 0;
880 StubDesc
= Object_StubDesc
;
881 StubDesc
.pFormatTypes
= formattypes
;
883 NdrClientInitializeNew(&RpcMessage
, &StubMsg
, &StubDesc
, 0);
885 StubMsg
.BufferLength
= 0;
886 NdrSimpleStructBufferSize( &StubMsg
, memsrc
, formattypes
);
887 ok(StubMsg
.BufferLength
>= wiredatalen
, "%s: length %d\n", msgpfx
, StubMsg
.BufferLength
);
888 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
889 StubMsg
.BufferEnd
= StubMsg
.BufferStart
+ StubMsg
.BufferLength
;
890 ptr
= NdrSimpleStructMarshall( &StubMsg
, memsrc
, formattypes
);
891 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
892 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
);
893 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));
895 StubMsg
.Buffer
= StubMsg
.BufferStart
;
896 StubMsg
.MemorySize
= 0;
897 size
= NdrSimpleStructMemorySize( &StubMsg
, formattypes
);
898 ok(size
== StubMsg
.MemorySize
, "%s: size != MemorySize\n", msgpfx
);
899 ok(size
== srcsize
, "%s: mem size %u\n", msgpfx
, size
);
900 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
);
902 StubMsg
.Buffer
= StubMsg
.BufferStart
;
903 size
= NdrSimpleStructMemorySize( &StubMsg
, formattypes
);
904 ok(size
== StubMsg
.MemorySize
, "%s: size != MemorySize\n", msgpfx
);
905 ok(StubMsg
.MemorySize
== ((srcsize
+ 3) & ~3) + srcsize
, "%s: mem size %u\n", msgpfx
, size
);
906 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
);
908 /*** Unmarshalling first with must_alloc false ***/
910 StubMsg
.Buffer
= StubMsg
.BufferStart
;
911 StubMsg
.MemorySize
= 0;
912 mem_orig
= mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, srcsize
);
913 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, 0 );
914 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
915 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== wiredatalen
, "%s: Buffer %p Start %p\n", msgpfx
, StubMsg
.Buffer
, StubMsg
.BufferStart
);
916 ok(mem
== mem_orig
, "%s: mem has changed %p %p\n", msgpfx
, mem
, mem_orig
);
917 ok(!cmp(mem
, memsrc
, srcsize
), "%s: incorrectly unmarshaled\n", msgpfx
);
918 ok(my_alloc_called
== num_additional_allocs
, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
920 ok(StubMsg
.MemorySize
== 0, "%s: memorysize touched in unmarshal\n", msgpfx
);
922 /* If we're a server we still use the supplied memory */
923 StubMsg
.Buffer
= StubMsg
.BufferStart
;
924 StubMsg
.IsClient
= 0;
925 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, 0 );
926 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
927 ok(mem
== mem_orig
, "%s: mem has changed %p %p\n", msgpfx
, mem
, mem_orig
);
928 ok(!cmp(mem
, memsrc
, srcsize
), "%s: incorrectly unmarshaled\n", msgpfx
);
929 ok(my_alloc_called
== num_additional_allocs
, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
931 ok(StubMsg
.MemorySize
== 0, "%s: memorysize touched in unmarshal\n", msgpfx
);
933 /* ...unless we pass a NULL ptr, then the buffer is used.
934 Passing a NULL ptr while we're a client && !must_alloc
935 crashes on Windows, so we won't do that. */
937 if (0) /* crashes on Win9x and NT4 */
940 StubMsg
.IsClient
= 0;
941 StubMsg
.Buffer
= StubMsg
.BufferStart
;
942 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, FALSE
);
943 ok(ptr
== NULL
, "%s: ret %p\n", msgpfx
, ptr
);
944 ok(mem
== StubMsg
.BufferStart
, "%s: mem not equal buffer\n", msgpfx
);
945 ok(!cmp(mem
, memsrc
, srcsize
), "%s: incorrectly unmarshaled\n", msgpfx
);
946 ok(my_alloc_called
== num_additional_allocs
, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
948 ok(StubMsg
.MemorySize
== 0, "%s: memorysize touched in unmarshal\n", msgpfx
);
951 /*** now must_alloc is true ***/
953 /* with must_alloc set we always allocate new memory whether or not we're
954 a server and also when passing NULL */
956 StubMsg
.IsClient
= 1;
957 StubMsg
.Buffer
= StubMsg
.BufferStart
;
958 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, 1 );
959 ok(ptr
== NULL
, "ret %p\n", ptr
);
960 ok(mem
!= mem_orig
, "mem not changed %p %p\n", mem
, mem_orig
);
961 ok(!cmp(mem
, memsrc
, srcsize
), "incorrectly unmarshaled\n");
962 ok(my_alloc_called
== num_additional_allocs
+ 1, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
964 ok(StubMsg
.MemorySize
== 0, "memorysize touched in unmarshal\n");
967 StubMsg
.Buffer
= StubMsg
.BufferStart
;
968 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, 1 );
969 ok(ptr
== NULL
, "ret %p\n", ptr
);
970 ok(mem
!= mem_orig
, "mem not changed %p %p\n", mem
, mem_orig
);
971 ok(!cmp(mem
, memsrc
, srcsize
), "incorrectly unmarshaled\n");
972 ok(my_alloc_called
== num_additional_allocs
+ 1, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
974 ok(StubMsg
.MemorySize
== 0, "memorysize touched in unmarshal\n");
977 StubMsg
.Buffer
= StubMsg
.BufferStart
;
978 StubMsg
.IsClient
= 0;
979 StubMsg
.ReuseBuffer
= 1;
980 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, 1 );
981 ok(ptr
== NULL
, "ret %p\n", ptr
);
982 ok(mem
!= mem_orig
, "mem not changed %p %p\n", mem
, mem_orig
);
983 ok(mem
!= StubMsg
.BufferStart
, "mem is buffer mem\n");
984 ok(!cmp(mem
, memsrc
, srcsize
), "incorrectly unmarshaled\n");
985 ok(my_alloc_called
== num_additional_allocs
+ 1, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
987 ok(StubMsg
.MemorySize
== 0, "memorysize touched in unmarshal\n");
990 StubMsg
.Buffer
= StubMsg
.BufferStart
;
991 StubMsg
.IsClient
= 0;
992 StubMsg
.ReuseBuffer
= 1;
993 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, &mem
, formattypes
, 1 );
994 ok(ptr
== NULL
, "ret %p\n", ptr
);
995 ok(mem
!= StubMsg
.BufferStart
, "mem is buffer mem\n");
996 ok(!cmp(mem
, memsrc
, srcsize
), "incorrectly unmarshaled\n");
997 ok(my_alloc_called
== num_additional_allocs
+ 1, "%s: my_alloc got called %d times\n", msgpfx
, my_alloc_called
);
999 ok(StubMsg
.MemorySize
== 0, "memorysize touched in unmarshal\n");
1001 HeapFree(GetProcessHeap(), 0, mem_orig
);
1002 HeapFree(GetProcessHeap(), 0, StubMsg
.BufferStart
);
1012 static int ps1_cmp(const void *s1
, const void *s2
, size_t num
)
1014 const ps1_t
*p1
, *p2
;
1019 if(p1
->l1
!= p2
->l1
)
1022 if(p1
->pl1
&& p2
->pl1
)
1024 if(*p1
->pl1
!= *p2
->pl1
)
1027 else if(p1
->pl1
|| p2
->pl1
)
1030 if(p1
->pc1
&& p2
->pc1
)
1032 if(*p1
->pc1
!= *p2
->pc1
)
1035 else if(p1
->pc1
|| p2
->pc1
)
1041 static void test_simple_struct(void)
1043 unsigned char wiredata
[28];
1049 static const unsigned char fmtstr_simple_struct
[] =
1051 0x12, 0x0, /* FC_UP */
1052 NdrFcShort( 0x2 ), /* Offset=2 */
1053 0x15, 0x3, /* FC_STRUCT [align 4] */
1054 NdrFcShort( 0x18 ), /* [size 24] */
1057 0x38, /* FC_ALIGNM4 */
1060 0x39, /* FC_ALIGNM8 */
1071 static const unsigned char fmtstr_pointer_struct
[] =
1073 0x12, 0x0, /* FC_UP */
1074 NdrFcShort( 0x2 ), /* Offset=2 */
1076 0x1a, /* FC_BOGUS_STRUCT */
1078 NdrFcShort(0x18), /* [size 24] */
1080 NdrFcShort(0x8), /* Offset= 8 (266) */
1082 0x39, /* FC_ALIGNM8 */
1083 0x36, /* FC_POINTER */
1084 0x36, /* FC_POINTER */
1087 0x12, 0x8, /* FC_UP [simple_pointer] */
1090 0x12, 0x8, /* FC_UP [simple_pointer] */
1094 0x16, 0x3, /* FC_PSTRUCT [align 4] */
1095 NdrFcShort( 0xc ), /* [size 12] */
1098 0x46, /* FC_NO_REPEAT */
1100 NdrFcShort( 0x4 ), /* 4 */
1101 NdrFcShort( 0x4 ), /* 4 */
1102 0x13, 0x8, /* FC_OP [simple_pointer] */
1105 0x46, /* FC_NO_REPEAT */
1107 NdrFcShort( 0x8 ), /* 8 */
1108 NdrFcShort( 0x8 ), /* 8 */
1109 0x13, 0x8, /* FC_OP [simple_pointer] */
1121 /* zero the entire structure, including the holes */
1122 memset(&s1
, 0, sizeof(s1
));
1129 s1
.ll
= ((ULONGLONG
) 0xbadefeed << 32) | 0x2468ace0;
1132 memcpy(wiredata
, &s1
, wiredatalen
);
1133 test_simple_struct_marshal(fmtstr_simple_struct
+ 4, &s1
, 24, wiredata
, 24, NULL
, 0, "struct");
1135 if (use_pointer_ids
)
1136 *(unsigned int *)wiredata
= 0x20000;
1138 *(unsigned int *)wiredata
= (UINT_PTR
)&s1
;
1139 memcpy(wiredata
+ 4, &s1
, wiredatalen
);
1140 test_pointer_marshal(fmtstr_simple_struct
, &s1
, 24, wiredata
, 28, NULL
, 0, "struct");
1142 if (sizeof(void *) == 8) return; /* it cannot be represented as a simple struct on Win64 */
1144 /* zero the entire structure, including the hole */
1145 memset(&ps1
, 0, sizeof(ps1
));
1148 ps1
.l1
= 0xdeadbeef;
1153 *(unsigned int *)(wiredata
+ 4) = 0xdeadbeef;
1154 if (use_pointer_ids
)
1156 *(unsigned int *)(wiredata
+ 8) = 0x20000;
1157 *(unsigned int *)(wiredata
+ 12) = 0x20004;
1161 *(unsigned int *)(wiredata
+ 8) = (UINT_PTR
)&l
;
1162 *(unsigned int *)(wiredata
+ 12) = (UINT_PTR
)&c
;
1164 memcpy(wiredata
+ 16, &l
, 4);
1165 memcpy(wiredata
+ 20, &c
, 1);
1167 test_simple_struct_marshal(fmtstr_pointer_struct
+ 4, &ps1
, 17, wiredata
+ 4, 17, ps1_cmp
, 2, "pointer_struct");
1168 if (use_pointer_ids
)
1170 *(unsigned int *)wiredata
= 0x20000;
1171 *(unsigned int *)(wiredata
+ 8) = 0x20004;
1172 *(unsigned int *)(wiredata
+ 12) = 0x20008;
1175 *(unsigned int *)wiredata
= (UINT_PTR
)&ps1
;
1176 test_pointer_marshal(fmtstr_pointer_struct
, &ps1
, 17, wiredata
, 21, ps1_cmp
, 2, "pointer_struct");
1185 static void test_struct_align(void)
1187 RPC_MESSAGE RpcMessage
;
1188 MIDL_STUB_MESSAGE StubMsg
;
1189 MIDL_STUB_DESC StubDesc
;
1191 struct aligned
*memsrc_orig
, *memsrc
, *mem
;
1193 /* force bogus struct so that members are marshalled individually */
1194 static const unsigned char fmtstr
[] =
1196 0x1a, /* FC_BOGUS_STRUCT */
1197 0x7, /* alignment 8 */
1198 NdrFcShort(0x10), /* memory size 16 */
1202 0x39, /* FC_ALIGNM8 */
1203 0x0b, /* FC_HYPER */
1207 memsrc_orig
= heap_alloc_zero(sizeof(struct aligned
) + 8);
1208 /* intentionally mis-align memsrc */
1209 memsrc
= (struct aligned
*)((((ULONG_PTR
)memsrc_orig
+ 7) & ~7) + 4);
1211 memsrc
->a
= 0xdeadbeef;
1212 memsrc
->b
= ((ULONGLONG
) 0xbadefeed << 32) | 0x2468ace0;
1214 StubDesc
= Object_StubDesc
;
1215 StubDesc
.pFormatTypes
= fmtstr
;
1216 NdrClientInitializeNew(&RpcMessage
, &StubMsg
, &StubDesc
, 0);
1218 StubMsg
.BufferLength
= 0;
1219 NdrComplexStructBufferSize(&StubMsg
, (unsigned char *)memsrc
, fmtstr
);
1221 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= heap_alloc(StubMsg
.BufferLength
);
1222 StubMsg
.BufferEnd
= StubMsg
.BufferStart
+ StubMsg
.BufferLength
;
1224 ptr
= NdrComplexStructMarshall(&StubMsg
, (unsigned char *)memsrc
, fmtstr
);
1225 ok(ptr
== NULL
, "ret %p\n", ptr
);
1228 StubMsg
.IsClient
= 0;
1230 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1231 ptr
= NdrComplexStructUnmarshall(&StubMsg
, (unsigned char **)&mem
, fmtstr
, 0);
1232 ok(ptr
== NULL
, "ret %p\n", ptr
);
1233 ok(!memcmp(mem
, memsrc
, sizeof(*memsrc
)), "struct wasn't unmarshalled correctly\n");
1234 StubMsg
.pfnFree(mem
);
1236 heap_free(StubMsg
.RpcMsg
->Buffer
);
1237 heap_free(memsrc_orig
);
1242 IPersist IPersist_iface
;
1246 static struct testiface
*impl_from_IPersist(IPersist
*iface
)
1248 return CONTAINING_RECORD(iface
, struct testiface
, IPersist_iface
);
1251 static HRESULT WINAPI
test_persist_QueryInterface(IPersist
*iface
, REFIID iid
, void **out
)
1253 if (IsEqualGUID(iid
, &IID_IUnknown
) || IsEqualGUID(iid
, &IID_IPersist
))
1256 IPersist_AddRef(iface
);
1261 return E_NOINTERFACE
;
1264 static ULONG WINAPI
test_persist_AddRef(IPersist
*iface
)
1266 struct testiface
*unk
= impl_from_IPersist(iface
);
1270 static ULONG WINAPI
test_persist_Release(IPersist
*iface
)
1272 struct testiface
*unk
= impl_from_IPersist(iface
);
1276 static HRESULT WINAPI
test_persist_GetClassId(IPersist
*iface
, GUID
*clsid
)
1278 *clsid
= IID_IPersist
;
1282 static IPersistVtbl testiface_vtbl
= {
1283 test_persist_QueryInterface
,
1284 test_persist_AddRef
,
1285 test_persist_Release
,
1286 test_persist_GetClassId
,
1289 static void test_iface_ptr(void)
1291 struct testiface server_obj
= {{&testiface_vtbl
}, 1};
1292 struct testiface client_obj
= {{&testiface_vtbl
}, 1};
1294 MIDL_STUB_MESSAGE StubMsg
;
1295 MIDL_STUB_DESC StubDesc
;
1296 RPC_MESSAGE RpcMessage
;
1303 static const unsigned char fmtstr_ip
[] =
1307 NdrFcLong(0x0000010c),
1322 StubDesc
= Object_StubDesc
;
1323 StubDesc
.pFormatTypes
= fmtstr_ip
;
1325 NdrClientInitializeNew(&RpcMessage
, &StubMsg
, &StubDesc
, 0);
1326 StubMsg
.BufferLength
= 0;
1327 NdrInterfacePointerBufferSize(&StubMsg
, (unsigned char *)&client_obj
.IPersist_iface
, fmtstr_ip
);
1329 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
1330 StubMsg
.BufferEnd
= StubMsg
.BufferStart
+ StubMsg
.BufferLength
;
1332 /* server -> client */
1334 StubMsg
.IsClient
= 0;
1335 my_alloc_called
= my_free_called
= 0;
1336 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1337 IPersist_AddRef(&server_obj
.IPersist_iface
);
1338 ptr
= NdrInterfacePointerMarshall(&StubMsg
, (unsigned char *)&server_obj
.IPersist_iface
, fmtstr_ip
);
1339 ok(!ptr
, "ret %p\n", ptr
);
1340 ok(server_obj
.ref
> 2, "got %d references\n", server_obj
.ref
);
1341 ok(!my_alloc_called
, "alloc called %d\n", my_alloc_called
);
1342 ok(!my_free_called
, "free called %d\n", my_free_called
);
1344 NdrInterfacePointerFree(&StubMsg
, (unsigned char *)&server_obj
.IPersist_iface
, fmtstr_ip
);
1345 ok(server_obj
.ref
> 1, "got %d references\n", server_obj
.ref
);
1347 StubMsg
.IsClient
= 1;
1348 my_alloc_called
= my_free_called
= 0;
1349 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1351 ptr
= NdrInterfacePointerUnmarshall(&StubMsg
, (unsigned char **)&proxy
, fmtstr_ip
, 0);
1352 ok(!ptr
, "ret %p\n", ptr
);
1353 ok(!!proxy
, "mem not alloced\n");
1354 ok(!my_alloc_called
, "alloc called %d\n", my_alloc_called
);
1355 ok(!my_free_called
, "free called %d\n", my_free_called
);
1356 ok(server_obj
.ref
> 1, "got %d references\n", server_obj
.ref
);
1358 hr
= IPersist_GetClassID(proxy
, &clsid
);
1359 ok(hr
== S_OK
, "got hr %#x\n", hr
);
1360 ok(IsEqualGUID(&clsid
, &IID_IPersist
), "wrong clsid %s\n", wine_dbgstr_guid(&clsid
));
1362 ref
= IPersist_Release(proxy
);
1363 ok(ref
== 1, "got %d references\n", ref
);
1364 ok(server_obj
.ref
== 1, "got %d references\n", server_obj
.ref
);
1366 /* An existing interface pointer is released; this is necessary so that an
1367 * [in, out] pointer which changes does not leak references. */
1369 StubMsg
.IsClient
= 0;
1370 my_alloc_called
= my_free_called
= 0;
1371 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1372 IPersist_AddRef(&server_obj
.IPersist_iface
);
1373 ptr
= NdrInterfacePointerMarshall(&StubMsg
, (unsigned char *)&server_obj
.IPersist_iface
, fmtstr_ip
);
1374 ok(!ptr
, "ret %p\n", ptr
);
1375 ok(server_obj
.ref
> 2, "got %d references\n", server_obj
.ref
);
1376 ok(!my_alloc_called
, "alloc called %d\n", my_alloc_called
);
1377 ok(!my_free_called
, "free called %d\n", my_free_called
);
1379 NdrInterfacePointerFree(&StubMsg
, (unsigned char *)&server_obj
.IPersist_iface
, fmtstr_ip
);
1380 ok(server_obj
.ref
> 1, "got %d references\n", server_obj
.ref
);
1382 StubMsg
.IsClient
= 1;
1383 my_alloc_called
= my_free_called
= 0;
1384 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1385 proxy
= &client_obj
.IPersist_iface
;
1386 IPersist_AddRef(proxy
);
1387 ptr
= NdrInterfacePointerUnmarshall(&StubMsg
, (unsigned char **)&proxy
, fmtstr_ip
, 0);
1388 ok(!ptr
, "ret %p\n", ptr
);
1389 ok(!!proxy
&& proxy
!= &client_obj
.IPersist_iface
, "mem not alloced\n");
1390 ok(!my_alloc_called
, "alloc called %d\n", my_alloc_called
);
1391 ok(!my_free_called
, "free called %d\n", my_free_called
);
1392 ok(server_obj
.ref
> 1, "got %d references\n", server_obj
.ref
);
1393 ok(client_obj
.ref
== 1, "got %d references\n", client_obj
.ref
);
1395 hr
= IPersist_GetClassID(proxy
, &clsid
);
1396 ok(hr
== S_OK
, "got hr %#x\n", hr
);
1397 ok(IsEqualGUID(&clsid
, &IID_IPersist
), "wrong clsid %s\n", wine_dbgstr_guid(&clsid
));
1399 ref
= IPersist_Release(proxy
);
1400 ok(ref
== 1, "got %d references\n", ref
);
1401 ok(server_obj
.ref
== 1, "got %d references\n", server_obj
.ref
);
1403 /* client -> server */
1405 StubMsg
.IsClient
= 1;
1406 my_alloc_called
= my_free_called
= 0;
1407 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1408 IPersist_AddRef(&client_obj
.IPersist_iface
);
1409 ptr
= NdrInterfacePointerMarshall(&StubMsg
, (unsigned char *)&client_obj
.IPersist_iface
, fmtstr_ip
);
1410 ok(!ptr
, "ret %p\n", ptr
);
1411 ok(client_obj
.ref
> 2, "got %d references\n", client_obj
.ref
);
1412 ok(!my_alloc_called
, "alloc called %d\n", my_alloc_called
);
1413 ok(!my_free_called
, "free called %d\n", my_free_called
);
1415 StubMsg
.IsClient
= 0;
1416 my_alloc_called
= my_free_called
= 0;
1417 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1419 ptr
= NdrInterfacePointerUnmarshall(&StubMsg
, (unsigned char **)&proxy
, fmtstr_ip
, 0);
1420 ok(!ptr
, "ret %p\n", ptr
);
1421 ok(!!proxy
, "mem not alloced\n");
1422 ok(!my_alloc_called
, "alloc called %d\n", my_alloc_called
);
1423 ok(!my_free_called
, "free called %d\n", my_free_called
);
1424 ok(client_obj
.ref
> 2, "got %d references\n", client_obj
.ref
);
1426 hr
= IPersist_GetClassID(proxy
, &clsid
);
1427 ok(hr
== S_OK
, "got hr %#x\n", hr
);
1428 ok(IsEqualGUID(&clsid
, &IID_IPersist
), "wrong clsid %s\n", wine_dbgstr_guid(&clsid
));
1430 ref
= IPersist_Release(proxy
);
1431 ok(client_obj
.ref
> 1, "got %d references\n", client_obj
.ref
);
1432 ok(ref
== client_obj
.ref
, "expected %d references, got %d\n", client_obj
.ref
, ref
);
1434 NdrInterfacePointerFree(&StubMsg
, (unsigned char *)proxy
, fmtstr_ip
);
1435 ok(client_obj
.ref
== 1, "got %d references\n", client_obj
.ref
);
1437 /* same, but free the interface after calling NdrInterfacePointerFree */
1439 StubMsg
.IsClient
= 1;
1440 my_alloc_called
= my_free_called
= 0;
1441 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1442 IPersist_AddRef(&client_obj
.IPersist_iface
);
1443 ptr
= NdrInterfacePointerMarshall(&StubMsg
, (unsigned char *)&client_obj
.IPersist_iface
, fmtstr_ip
);
1444 ok(!ptr
, "ret %p\n", ptr
);
1445 ok(client_obj
.ref
> 2, "got %d references\n", client_obj
.ref
);
1446 ok(!my_alloc_called
, "alloc called %d\n", my_alloc_called
);
1447 ok(!my_free_called
, "free called %d\n", my_free_called
);
1449 StubMsg
.IsClient
= 0;
1450 my_alloc_called
= my_free_called
= 0;
1451 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1453 ptr
= NdrInterfacePointerUnmarshall(&StubMsg
, (unsigned char **)&proxy
, fmtstr_ip
, 0);
1454 ok(!ptr
, "ret %p\n", ptr
);
1455 ok(!!proxy
, "mem not alloced\n");
1456 ok(!my_alloc_called
, "alloc called %d\n", my_alloc_called
);
1457 ok(!my_free_called
, "free called %d\n", my_free_called
);
1458 ok(client_obj
.ref
> 2, "got %d references\n", client_obj
.ref
);
1460 NdrInterfacePointerFree(&StubMsg
, (unsigned char *)proxy
, fmtstr_ip
);
1461 ok(client_obj
.ref
> 1, "got %d references\n", client_obj
.ref
);
1463 hr
= IPersist_GetClassID(proxy
, &clsid
);
1464 ok(hr
== S_OK
, "got hr %#x\n", hr
);
1465 ok(IsEqualGUID(&clsid
, &IID_IPersist
), "wrong clsid %s\n", wine_dbgstr_guid(&clsid
));
1467 ref
= IPersist_Release(proxy
);
1468 ok(ref
== 1, "got %d references\n", ref
);
1469 ok(client_obj
.ref
== 1, "got %d references\n", client_obj
.ref
);
1471 /* An existing interface pointer is *not* released (in fact, it is ignored
1472 * and may be invalid). In practice it will always be NULL anyway. */
1474 StubMsg
.IsClient
= 1;
1475 my_alloc_called
= my_free_called
= 0;
1476 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1477 IPersist_AddRef(&client_obj
.IPersist_iface
);
1478 ptr
= NdrInterfacePointerMarshall(&StubMsg
, (unsigned char *)&client_obj
.IPersist_iface
, fmtstr_ip
);
1479 ok(!ptr
, "ret %p\n", ptr
);
1480 ok(client_obj
.ref
> 2, "got %d references\n", client_obj
.ref
);
1481 ok(!my_alloc_called
, "alloc called %d\n", my_alloc_called
);
1482 ok(!my_free_called
, "free called %d\n", my_free_called
);
1484 StubMsg
.IsClient
= 0;
1485 my_alloc_called
= my_free_called
= 0;
1486 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1487 proxy
= &server_obj
.IPersist_iface
;
1488 IPersist_AddRef(proxy
);
1489 ptr
= NdrInterfacePointerUnmarshall(&StubMsg
, (unsigned char **)&proxy
, fmtstr_ip
, 0);
1490 ok(!ptr
, "ret %p\n", ptr
);
1491 ok(!!proxy
&& proxy
!= &server_obj
.IPersist_iface
, "mem not alloced\n");
1492 ok(!my_alloc_called
, "alloc called %d\n", my_alloc_called
);
1493 ok(!my_free_called
, "free called %d\n", my_free_called
);
1494 ok(client_obj
.ref
> 2, "got %d references\n", client_obj
.ref
);
1495 ok(server_obj
.ref
== 2, "got %d references\n", server_obj
.ref
);
1496 IPersist_Release(&server_obj
.IPersist_iface
);
1498 hr
= IPersist_GetClassID(proxy
, &clsid
);
1499 ok(hr
== S_OK
, "got hr %#x\n", hr
);
1500 ok(IsEqualGUID(&clsid
, &IID_IPersist
), "wrong clsid %s\n", wine_dbgstr_guid(&clsid
));
1502 ref
= IPersist_Release(proxy
);
1503 ok(client_obj
.ref
> 1, "got %d references\n", client_obj
.ref
);
1504 ok(ref
== client_obj
.ref
, "expected %d references, got %d\n", client_obj
.ref
, ref
);
1506 NdrInterfacePointerFree(&StubMsg
, (unsigned char *)proxy
, fmtstr_ip
);
1507 ok(client_obj
.ref
== 1, "got %d references\n", client_obj
.ref
);
1512 static void test_fullpointer_xlat(void)
1514 PFULL_PTR_XLAT_TABLES pXlatTables
;
1519 pXlatTables
= NdrFullPointerXlatInit(2, XLAT_CLIENT
);
1521 /* "marshaling" phase */
1523 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 1, &RefId
);
1524 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1525 ok(RefId
== 0x1, "RefId should be 0x1 instead of 0x%x\n", RefId
);
1527 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 0, &RefId
);
1528 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1529 ok(RefId
== 0x1, "RefId should be 0x1 instead of 0x%x\n", RefId
);
1531 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebabe, 0, &RefId
);
1532 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1533 ok(RefId
== 0x2, "RefId should be 0x2 instead of 0x%x\n", RefId
);
1535 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xdeadbeef, 0, &RefId
);
1536 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1537 ok(RefId
== 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId
);
1539 ret
= NdrFullPointerQueryPointer(pXlatTables
, NULL
, 0, &RefId
);
1540 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
1541 ok(RefId
== 0, "RefId should be 0 instead of 0x%x\n", RefId
);
1543 /* "unmarshaling" phase */
1545 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x0, 0, &Pointer
);
1546 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
1548 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x2, 0, &Pointer
);
1549 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1550 ok(Pointer
== (void *)0xcafebabe, "Pointer should be 0xcafebabe instead of %p\n", Pointer
);
1552 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x4, 0, &Pointer
);
1553 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1554 ok(Pointer
== NULL
, "Pointer should be NULL instead of %p\n", Pointer
);
1556 NdrFullPointerInsertRefId(pXlatTables
, 0x4, (void *)0xdeadbabe);
1558 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x4, 1, &Pointer
);
1559 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1560 ok(Pointer
== (void *)0xdeadbabe, "Pointer should be (void *)0xdeadbabe instead of %p\n", Pointer
);
1562 NdrFullPointerXlatFree(pXlatTables
);
1564 pXlatTables
= NdrFullPointerXlatInit(2, XLAT_SERVER
);
1566 /* "unmarshaling" phase */
1568 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x2, 1, &Pointer
);
1569 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1570 ok(Pointer
== NULL
, "Pointer should be NULL instead of %p\n", Pointer
);
1572 NdrFullPointerInsertRefId(pXlatTables
, 0x2, (void *)0xcafebabe);
1574 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x2, 0, &Pointer
);
1575 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1576 ok(Pointer
== (void *)0xcafebabe, "Pointer should be (void *)0xcafebabe instead of %p\n", Pointer
);
1578 ret
= NdrFullPointerQueryRefId(pXlatTables
, 0x2, 1, &Pointer
);
1579 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
1580 ok(Pointer
== (void *)0xcafebabe, "Pointer should be (void *)0xcafebabe instead of %p\n", Pointer
);
1582 /* "marshaling" phase */
1584 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 1, &RefId
);
1585 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1586 ok(RefId
== 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId
);
1588 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 1, &RefId
);
1589 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
1590 ok(RefId
== 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId
);
1592 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 0, &RefId
);
1593 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1594 ok(RefId
== 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId
);
1596 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebabe, 0, &RefId
);
1597 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1598 ok(RefId
== 0x2, "RefId should be 0x2 instead of 0x%x\n", RefId
);
1600 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xdeadbeef, 0, &RefId
);
1601 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1602 ok(RefId
== 0x4, "RefId should be 0x4 instead of 0x%x\n", RefId
);
1604 /* "freeing" phase */
1606 ret
= NdrFullPointerFree(pXlatTables
, (void *)0xcafebeef);
1607 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
1609 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 0x20, &RefId
);
1610 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
1611 ok(RefId
== 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId
);
1613 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xcafebeef, 1, &RefId
);
1614 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
1615 ok(RefId
== 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId
);
1617 ret
= NdrFullPointerFree(pXlatTables
, (void *)0xcafebabe);
1618 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
1620 ret
= NdrFullPointerFree(pXlatTables
, (void *)0xdeadbeef);
1621 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
1623 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xdeadbeef, 0x20, &RefId
);
1624 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
1625 ok(RefId
== 0x4, "RefId should be 0x4 instead of 0x%x\n", RefId
);
1627 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xdeadbeef, 1, &RefId
);
1628 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1629 ok(RefId
== 0x4, "RefId should be 0x4 instead of 0x%x\n", RefId
);
1631 ret
= NdrFullPointerQueryPointer(pXlatTables
, (void *)0xdeadbeef, 1, &RefId
);
1632 ok(ret
== 1, "ret should be 1 instead of 0x%x\n", ret
);
1633 ok(RefId
== 0x4, "RefId should be 0x4 instead of 0x%x\n", RefId
);
1635 ret
= NdrFullPointerFree(pXlatTables
, (void *)0xdeadbeef);
1636 ok(ret
== 0, "ret should be 0 instead of 0x%x\n", ret
);
1638 NdrFullPointerXlatFree(pXlatTables
);
1641 /* verify stub data that is identical between client and server */
1642 static void test_common_stub_data( const char *prefix
, const MIDL_STUB_MESSAGE
*stubMsg
)
1646 memset(&unset_ptr
, 0xcc, sizeof(unset_ptr
));
1648 #define TEST_ZERO(field, fmt) ok(stubMsg->field == 0, "%s: " #field " should have been set to zero instead of " fmt "\n", prefix, stubMsg->field)
1649 #define TEST_POINTER_UNSET(field) ok(stubMsg->field == unset_ptr, "%s: " #field " should have been unset instead of %p\n", prefix, stubMsg->field)
1650 #define TEST_ULONG_UNSET(field) ok(stubMsg->field == 0xcccccccc, "%s: " #field " should have been unset instead of 0x%x\n", prefix, stubMsg->field)
1651 #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)
1653 TEST_POINTER_UNSET(BufferMark
);
1654 TEST_ULONG_UNSET(MemorySize
);
1655 TEST_POINTER_UNSET(Memory
);
1656 TEST_ZERO(pAllocAllNodesContext
, "%p");
1657 ok(stubMsg
->pPointerQueueState
== 0 ||
1658 broken(stubMsg
->pPointerQueueState
== unset_ptr
), /* win2k */
1659 "%s: pPointerQueueState should have been unset instead of %p\n",
1660 prefix
, stubMsg
->pPointerQueueState
);
1661 TEST_ZERO(IgnoreEmbeddedPointers
, "%d");
1662 TEST_ZERO(PointerBufferMark
, "%p");
1663 ok( stubMsg
->uFlags
== 0 ||
1664 broken(stubMsg
->uFlags
== 0xcc), /* win9x */
1665 "%s: uFlags should have been set to zero instead of 0x%x\n", prefix
, stubMsg
->uFlags
);
1666 /* FIXME: UniquePtrCount */
1667 TEST_ULONG_PTR_UNSET(MaxCount
);
1668 TEST_ULONG_UNSET(Offset
);
1669 TEST_ULONG_UNSET(ActualCount
);
1670 ok(stubMsg
->pfnAllocate
== my_alloc
, "%s: pfnAllocate should have been %p instead of %p\n",
1671 prefix
, my_alloc
, stubMsg
->pfnAllocate
);
1672 ok(stubMsg
->pfnFree
== my_free
, "%s: pfnFree should have been %p instead of %p\n",
1673 prefix
, my_free
, stubMsg
->pfnFree
);
1674 TEST_ZERO(StackTop
, "%p");
1675 TEST_POINTER_UNSET(pPresentedType
);
1676 TEST_POINTER_UNSET(pTransmitType
);
1677 TEST_POINTER_UNSET(SavedHandle
);
1678 ok(stubMsg
->StubDesc
== &Object_StubDesc
, "%s: StubDesc should have been %p instead of %p\n",
1679 prefix
, &Object_StubDesc
, stubMsg
->StubDesc
);
1680 TEST_ZERO(FullPtrRefId
, "%d");
1681 ok( stubMsg
->PointerLength
== 0 ||
1682 broken(stubMsg
->PointerLength
== 1), /* win9x, nt4 */
1683 "%s: pAsyncMsg should have been set to zero instead of %d\n", prefix
, stubMsg
->PointerLength
);
1684 TEST_ZERO(fInDontFree
, "%d");
1685 TEST_ZERO(fDontCallFreeInst
, "%d");
1686 ok( stubMsg
->fHasReturn
== 0 || broken(stubMsg
->fHasReturn
), /* win9x, nt4 */
1687 "%s: fHasReturn should have been set to zero instead of %d\n", prefix
, stubMsg
->fHasReturn
);
1688 TEST_ZERO(fHasExtensions
, "%d");
1689 TEST_ZERO(fHasNewCorrDesc
, "%d");
1690 ok(stubMsg
->fIsIn
== 0 || broken(stubMsg
->fIsIn
), /* win9x, nt4 */
1691 "%s: fIsIn should have been set to 0 instead of %d\n", prefix
, stubMsg
->fIsIn
);
1692 TEST_ZERO(fIsOicf
, "%d");
1693 ok(stubMsg
->fBufferValid
== 0,
1694 "%s: fBufferValid should have been set to 0 instead of %d\n", prefix
, stubMsg
->fBufferValid
);
1695 TEST_ZERO(fNeedMCCP
, "%d");
1696 ok(stubMsg
->fUnused
== 0 ||
1697 stubMsg
->fUnused
== -2, /* Vista */
1698 "%s: fUnused should have been set to 0 or -2 instead of %d\n", prefix
, stubMsg
->fUnused
);
1699 ok(stubMsg
->fUnused2
== 0xffffcccc, "%s: fUnused2 should have been 0xffffcccc instead of 0x%x\n",
1700 prefix
, stubMsg
->fUnused2
);
1701 ok(stubMsg
->dwDestContext
== MSHCTX_DIFFERENTMACHINE
,
1702 "%s: dwDestContext should have been MSHCTX_DIFFERENTMACHINE instead of %d\n",
1703 prefix
, stubMsg
->dwDestContext
);
1704 TEST_ZERO(pvDestContext
, "%p");
1705 TEST_POINTER_UNSET(SavedContextHandles
);
1706 TEST_ULONG_UNSET(ParamNumber
);
1707 TEST_ZERO(pRpcChannelBuffer
, "%p");
1708 TEST_ZERO(pArrayInfo
, "%p");
1709 TEST_POINTER_UNSET(SizePtrCountArray
);
1710 TEST_POINTER_UNSET(SizePtrOffsetArray
);
1711 TEST_POINTER_UNSET(SizePtrLengthArray
);
1712 TEST_POINTER_UNSET(pArgQueue
);
1713 TEST_ZERO(dwStubPhase
, "%d");
1714 /* FIXME: where does this value come from? */
1715 trace("%s: LowStackMark is %p\n", prefix
, stubMsg
->LowStackMark
);
1716 ok( stubMsg
->pAsyncMsg
== 0 || broken(stubMsg
->pAsyncMsg
== unset_ptr
), /* win9x, nt4 */
1717 "%s: pAsyncMsg should have been set to zero instead of %p\n", prefix
, stubMsg
->pAsyncMsg
);
1718 ok( stubMsg
->pCorrInfo
== 0 || broken(stubMsg
->pCorrInfo
== unset_ptr
), /* win9x, nt4 */
1719 "%s: pCorrInfo should have been set to zero instead of %p\n", prefix
, stubMsg
->pCorrInfo
);
1720 ok( stubMsg
->pCorrMemory
== 0 || broken(stubMsg
->pCorrMemory
== unset_ptr
), /* win9x, nt4 */
1721 "%s: pCorrMemory should have been set to zero instead of %p\n", prefix
, stubMsg
->pCorrMemory
);
1722 ok( stubMsg
->pMemoryList
== 0 || broken(stubMsg
->pMemoryList
== unset_ptr
), /* win9x, nt4 */
1723 "%s: pMemoryList should have been set to zero instead of %p\n", prefix
, stubMsg
->pMemoryList
);
1724 TEST_POINTER_UNSET(pCSInfo
);
1725 TEST_POINTER_UNSET(ConformanceMark
);
1726 TEST_POINTER_UNSET(VarianceMark
);
1727 ok(stubMsg
->Unused
== (ULONG_PTR
)unset_ptr
, "%s: Unused should have be unset instead of 0x%lx\n",
1728 prefix
, stubMsg
->Unused
);
1729 TEST_POINTER_UNSET(pContext
);
1730 TEST_POINTER_UNSET(ContextHandleHash
);
1731 TEST_POINTER_UNSET(pUserMarshalList
);
1732 TEST_ULONG_PTR_UNSET(Reserved51_3
);
1733 TEST_ULONG_PTR_UNSET(Reserved51_4
);
1734 TEST_ULONG_PTR_UNSET(Reserved51_5
);
1736 #undef TEST_ULONG_PTR_UNSET
1737 #undef TEST_ULONG_UNSET
1738 #undef TEST_POINTER_UNSET
1742 static void test_client_init(void)
1744 MIDL_STUB_MESSAGE stubMsg
;
1748 memset(&rpcMsg
, 0xcc, sizeof(rpcMsg
));
1749 memset(&stubMsg
, 0xcc, sizeof(stubMsg
));
1750 memset(&unset_ptr
, 0xcc, sizeof(unset_ptr
));
1752 NdrClientInitializeNew(&rpcMsg
, &stubMsg
, &Object_StubDesc
, 1);
1754 test_common_stub_data( "NdrClientInitializeNew", &stubMsg
);
1756 ok(stubMsg
.RpcMsg
== &rpcMsg
, "stubMsg.RpcMsg should have been %p instead of %p\n", &rpcMsg
, stubMsg
.RpcMsg
);
1757 ok(rpcMsg
.Handle
== NULL
, "rpcMsg.Handle should have been NULL instead of %p\n", rpcMsg
.Handle
);
1758 ok(rpcMsg
.Buffer
== unset_ptr
, "rpcMsg.Buffer should have been unset instead of %p\n",
1760 ok(rpcMsg
.BufferLength
== 0xcccccccc, "rpcMsg.BufferLength should have been unset instead of %d\n", rpcMsg
.BufferLength
);
1761 ok(rpcMsg
.ProcNum
== 0x8001, "rpcMsg.ProcNum should have been 0x8001 instead of 0x%x\n", rpcMsg
.ProcNum
);
1762 ok(rpcMsg
.TransferSyntax
== unset_ptr
, "rpcMsg.TransferSyntax should have been unset instead of %p\n", rpcMsg
.TransferSyntax
);
1763 ok(rpcMsg
.RpcInterfaceInformation
== Object_StubDesc
.RpcInterfaceInformation
,
1764 "rpcMsg.RpcInterfaceInformation should have been %p instead of %p\n",
1765 Object_StubDesc
.RpcInterfaceInformation
, rpcMsg
.RpcInterfaceInformation
);
1766 /* Note: ReservedForRuntime not tested */
1767 ok(rpcMsg
.ManagerEpv
== unset_ptr
, "rpcMsg.ManagerEpv should have been unset instead of %p\n", rpcMsg
.ManagerEpv
);
1768 ok(rpcMsg
.ImportContext
== unset_ptr
, "rpcMsg.ImportContext should have been unset instead of %p\n", rpcMsg
.ImportContext
);
1769 ok(rpcMsg
.RpcFlags
== 0, "rpcMsg.RpcFlags should have been 0 instead of 0x%x\n", rpcMsg
.RpcFlags
);
1771 ok(stubMsg
.Buffer
== unset_ptr
, "stubMsg.Buffer should have been unset instead of %p\n",
1773 ok(stubMsg
.BufferStart
== NULL
, "stubMsg.BufferStart should have been NULL instead of %p\n",
1774 stubMsg
.BufferStart
);
1775 ok(stubMsg
.BufferEnd
== NULL
, "stubMsg.BufferEnd should have been NULL instead of %p\n",
1777 ok(stubMsg
.BufferLength
== 0, "stubMsg.BufferLength should have been 0 instead of %u\n",
1778 stubMsg
.BufferLength
);
1779 ok(stubMsg
.IsClient
== 1, "stubMsg.IsClient should have been 1 instead of %u\n", stubMsg
.IsClient
);
1780 ok(stubMsg
.ReuseBuffer
== 0, "stubMsg.ReuseBuffer should have been 0 instead of %d\n",
1781 stubMsg
.ReuseBuffer
);
1782 ok(stubMsg
.CorrDespIncrement
== 0, "stubMsg.CorrDespIncrement should have been 0 instead of %d\n",
1783 stubMsg
.CorrDespIncrement
);
1784 ok(stubMsg
.FullPtrXlatTables
== unset_ptr
, "stubMsg.FullPtrXlatTables should have been unset instead of %p\n",
1785 stubMsg
.FullPtrXlatTables
);
1788 static void test_server_init(void)
1790 MIDL_STUB_MESSAGE stubMsg
;
1793 unsigned char buffer
[256];
1795 memset(&rpcMsg
, 0, sizeof(rpcMsg
));
1796 rpcMsg
.Buffer
= buffer
;
1797 rpcMsg
.BufferLength
= sizeof(buffer
);
1798 rpcMsg
.RpcFlags
= RPC_BUFFER_COMPLETE
;
1800 memset(&stubMsg
, 0xcc, sizeof(stubMsg
));
1802 ret
= NdrServerInitializeNew(&rpcMsg
, &stubMsg
, &Object_StubDesc
);
1803 ok(ret
== NULL
, "NdrServerInitializeNew should have returned NULL instead of %p\n", ret
);
1805 test_common_stub_data( "NdrServerInitializeNew", &stubMsg
);
1807 ok(stubMsg
.RpcMsg
== &rpcMsg
, "stubMsg.RpcMsg should have been %p instead of %p\n", &rpcMsg
, stubMsg
.RpcMsg
);
1808 ok(stubMsg
.Buffer
== buffer
, "stubMsg.Buffer should have been %p instead of %p\n", buffer
, stubMsg
.Buffer
);
1809 ok(stubMsg
.BufferStart
== buffer
, "stubMsg.BufferStart should have been %p instead of %p\n", buffer
, stubMsg
.BufferStart
);
1810 ok(stubMsg
.BufferEnd
== buffer
+ sizeof(buffer
), "stubMsg.BufferEnd should have been %p instead of %p\n", buffer
+ sizeof(buffer
), stubMsg
.BufferEnd
);
1812 ok(stubMsg
.BufferLength
== 0, "stubMsg.BufferLength should have been 0 instead of %u\n", stubMsg
.BufferLength
);
1813 ok(stubMsg
.IsClient
== 0, "stubMsg.IsClient should have been 0 instead of %u\n", stubMsg
.IsClient
);
1814 ok(stubMsg
.ReuseBuffer
== 0 ||
1815 broken(stubMsg
.ReuseBuffer
== 1), /* win2k */
1816 "stubMsg.ReuseBuffer should have been set to zero instead of %d\n", stubMsg
.ReuseBuffer
);
1817 ok(stubMsg
.CorrDespIncrement
== 0 ||
1818 broken(stubMsg
.CorrDespIncrement
== 0xcc), /* <= Win 2003 */
1819 "CorrDespIncrement should have been set to zero instead of 0x%x\n", stubMsg
.CorrDespIncrement
);
1820 ok(stubMsg
.FullPtrXlatTables
== 0, "stubMsg.BufferLength should have been 0 instead of %p\n", stubMsg
.FullPtrXlatTables
);
1823 static void test_ndr_allocate(void)
1825 RPC_MESSAGE RpcMessage
;
1826 MIDL_STUB_MESSAGE StubMsg
;
1827 MIDL_STUB_DESC StubDesc
;
1829 struct tag_mem_list_v2_t
1834 struct tag_mem_list_v2_t
*next
;
1836 const DWORD magic_MEML
= 'M' << 24 | 'E' << 16 | 'M' << 8 | 'L';
1838 StubDesc
= Object_StubDesc
;
1839 NdrClientInitializeNew(&RpcMessage
, &StubMsg
, &StubDesc
, 0);
1841 my_alloc_called
= my_free_called
= 0;
1842 p1
= NdrAllocate(&StubMsg
, 10);
1843 p2
= NdrAllocate(&StubMsg
, 24);
1844 ok(my_alloc_called
== 2, "alloc called %d\n", my_alloc_called
);
1845 ok(StubMsg
.pMemoryList
!= NULL
, "StubMsg.pMemoryList NULL\n");
1846 if(StubMsg
.pMemoryList
)
1848 mem_list_v2
= StubMsg
.pMemoryList
;
1849 if (mem_list_v2
->size
== 24)
1851 trace("v2 mem list format\n");
1852 ok((char *)mem_list_v2
== (char *)p2
+ 24, "expected mem_list_v2 pointer %p, but got %p\n", (char *)p2
+ 24, mem_list_v2
);
1853 ok(mem_list_v2
->magic
== magic_MEML
, "magic %08x\n", mem_list_v2
->magic
);
1854 ok(mem_list_v2
->size
== 24, "wrong size for p2 %d\n", mem_list_v2
->size
);
1855 ok(mem_list_v2
->unknown
== 0, "wrong unknown for p2 0x%x\n", mem_list_v2
->unknown
);
1856 ok(mem_list_v2
->next
!= NULL
, "next NULL\n");
1857 mem_list_v2
= mem_list_v2
->next
;
1860 ok((char *)mem_list_v2
== (char *)p1
+ 16, "expected mem_list_v2 pointer %p, but got %p\n", (char *)p1
+ 16, mem_list_v2
);
1861 ok(mem_list_v2
->magic
== magic_MEML
, "magic %08x\n", mem_list_v2
->magic
);
1862 ok(mem_list_v2
->size
== 16, "wrong size for p1 %d\n", mem_list_v2
->size
);
1863 ok(mem_list_v2
->unknown
== 0, "wrong unknown for p1 0x%x\n", mem_list_v2
->unknown
);
1864 ok(mem_list_v2
->next
== NULL
, "next %p\n", mem_list_v2
->next
);
1867 else win_skip("v1 mem list format\n");
1869 /* NdrFree isn't exported so we can't test free'ing */
1872 static void test_conformant_array(void)
1874 RPC_MESSAGE RpcMessage
;
1875 MIDL_STUB_MESSAGE StubMsg
;
1876 MIDL_STUB_DESC StubDesc
;
1878 unsigned char *mem
, *mem_orig
;
1879 unsigned char memsrc
[20];
1882 static const unsigned char fmtstr_conf_array
[] =
1884 0x1b, /* FC_CARRAY */
1886 NdrFcShort( 0x1 ), /* elem size */
1887 0x40, /* Corr desc: const */
1889 NdrFcShort(0x10), /* const = 0x10 */
1894 for (i
= 0; i
< sizeof(memsrc
); i
++)
1897 StubDesc
= Object_StubDesc
;
1898 StubDesc
.pFormatTypes
= fmtstr_conf_array
;
1900 NdrClientInitializeNew(
1906 StubMsg
.BufferLength
= 0;
1907 NdrConformantArrayBufferSize( &StubMsg
,
1909 fmtstr_conf_array
);
1910 ok(StubMsg
.BufferLength
>= 20, "length %d\n", StubMsg
.BufferLength
);
1912 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
1913 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
1914 StubMsg
.BufferEnd
= StubMsg
.BufferStart
+ StubMsg
.BufferLength
;
1916 ptr
= NdrConformantArrayMarshall( &StubMsg
, memsrc
, fmtstr_conf_array
);
1917 ok(ptr
== NULL
, "ret %p\n", ptr
);
1918 ok(StubMsg
.Buffer
- StubMsg
.BufferStart
== 20, "Buffer %p Start %p len %d\n", StubMsg
.Buffer
, StubMsg
.BufferStart
, 20);
1919 ok(!memcmp(StubMsg
.BufferStart
+ 4, memsrc
, 16), "incorrectly marshaled\n");
1921 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1922 StubMsg
.MemorySize
= 0;
1926 my_alloc_called
= 0;
1927 /* passing mem == NULL with must_alloc == 0 crashes under Windows */
1928 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 1);
1929 ok(mem
!= NULL
, "mem not alloced\n");
1930 ok(mem
!= StubMsg
.BufferStart
+ 4, "mem pointing at buffer\n");
1931 ok(my_alloc_called
== 1, "alloc called %d\n", my_alloc_called
);
1933 my_alloc_called
= 0;
1934 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1936 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 0);
1937 ok(mem
== mem_orig
, "mem alloced\n");
1938 ok(mem
!= StubMsg
.BufferStart
+ 4, "mem pointing at buffer\n");
1939 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1941 my_alloc_called
= 0;
1942 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1943 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 1);
1944 ok(mem
!= mem_orig
, "mem not alloced\n");
1945 ok(mem
!= StubMsg
.BufferStart
+ 4, "mem pointing at buffer\n");
1946 ok(my_alloc_called
== 1, "alloc called %d\n", my_alloc_called
);
1949 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1950 NdrConformantArrayFree( &StubMsg
, mem
, fmtstr_conf_array
);
1951 ok(my_free_called
== 0, "free called %d\n", my_free_called
);
1952 StubMsg
.pfnFree(mem
);
1955 my_alloc_called
= 0;
1956 StubMsg
.IsClient
= 0;
1958 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1959 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 0);
1960 ok(mem
== StubMsg
.BufferStart
+ 4 || broken(!mem
), /* win9x, nt4 */
1961 "mem not pointing at buffer %p/%p\n", mem
, StubMsg
.BufferStart
+ 4);
1962 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1963 my_alloc_called
= 0;
1965 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1966 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 1);
1967 ok(mem
!= StubMsg
.BufferStart
+ 4, "mem pointing at buffer\n");
1968 ok(my_alloc_called
== 1, "alloc called %d\n", my_alloc_called
);
1969 StubMsg
.pfnFree(mem
);
1971 my_alloc_called
= 0;
1973 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1974 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 0);
1975 ok(mem
== mem_orig
, "mem alloced\n");
1976 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
1978 my_alloc_called
= 0;
1980 StubMsg
.Buffer
= StubMsg
.BufferStart
;
1981 NdrConformantArrayUnmarshall( &StubMsg
, &mem
, fmtstr_conf_array
, 1);
1982 ok(mem
!= StubMsg
.BufferStart
+ 4, "mem pointing at buffer\n");
1983 ok(my_alloc_called
== 1, "alloc called %d\n", my_alloc_called
);
1984 StubMsg
.pfnFree(mem
);
1985 StubMsg
.pfnFree(mem_orig
);
1987 HeapFree(GetProcessHeap(), 0, StubMsg
.RpcMsg
->Buffer
);
1990 static void test_conformant_string(void)
1992 RPC_MESSAGE RpcMessage
;
1993 MIDL_STUB_MESSAGE StubMsg
;
1994 MIDL_STUB_DESC StubDesc
;
1997 unsigned char *mem
, *mem_orig
;
1998 char memsrc
[] = "This is a test string";
2000 static const unsigned char fmtstr_conf_str
[] =
2002 0x11, 0x8, /* FC_RP [simple_pointer] */
2003 0x22, /* FC_C_CSTRING */
2007 StubDesc
= Object_StubDesc
;
2008 StubDesc
.pFormatTypes
= fmtstr_conf_str
;
2010 memset( &StubMsg
, 0, sizeof(StubMsg
) ); /* needed on win9x and nt4 */
2011 NdrClientInitializeNew(
2017 StubMsg
.BufferLength
= 0;
2018 NdrPointerBufferSize( &StubMsg
,
2019 (unsigned char *)memsrc
,
2021 ok(StubMsg
.BufferLength
>= sizeof(memsrc
) + 12, "length %d\n", StubMsg
.BufferLength
);
2023 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
2024 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
2025 StubMsg
.BufferEnd
= StubMsg
.BufferStart
+ StubMsg
.BufferLength
;
2027 ptr
= NdrPointerMarshall( &StubMsg
, (unsigned char *)memsrc
, fmtstr_conf_str
);
2028 ok(ptr
== NULL
, "ret %p\n", ptr
);
2029 size
= StubMsg
.Buffer
- StubMsg
.BufferStart
;
2030 ok(size
== sizeof(memsrc
) + 12, "Buffer %p Start %p len %d\n",
2031 StubMsg
.Buffer
, StubMsg
.BufferStart
, size
);
2032 ok(!memcmp(StubMsg
.BufferStart
+ 12, memsrc
, sizeof(memsrc
)), "incorrectly marshaled\n");
2034 StubMsg
.Buffer
= StubMsg
.BufferStart
;
2035 StubMsg
.MemorySize
= 0;
2039 my_alloc_called
= 0;
2040 StubMsg
.Buffer
= StubMsg
.BufferStart
;
2041 mem
= mem_orig
= HeapAlloc(GetProcessHeap(), 0, sizeof(memsrc
));
2042 /* Windows apparently checks string length on the output buffer to determine its size... */
2043 memset( mem
, 'x', sizeof(memsrc
) - 1 );
2044 mem
[sizeof(memsrc
) - 1] = 0;
2045 NdrPointerUnmarshall( &StubMsg
, &mem
, fmtstr_conf_str
, 0);
2046 ok(mem
== mem_orig
, "mem not alloced\n");
2047 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
2049 my_alloc_called
= 0;
2050 StubMsg
.Buffer
= StubMsg
.BufferStart
;
2051 NdrPointerUnmarshall( &StubMsg
, &mem
, fmtstr_conf_str
, 1);
2052 ok(mem
== mem_orig
, "mem not alloced\n");
2053 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
2055 /* Prevent a memory leak when running with Wine.
2056 Remove once the todo_wine block above is fixed. */
2057 if (mem
!= mem_orig
)
2058 HeapFree(GetProcessHeap(), 0, mem_orig
);
2061 StubMsg
.Buffer
= StubMsg
.BufferStart
;
2062 NdrPointerFree( &StubMsg
, mem
, fmtstr_conf_str
);
2063 ok(my_free_called
== 1, "free called %d\n", my_free_called
);
2067 StubMsg
.Buffer
= StubMsg
.BufferStart
;
2068 NdrPointerFree( &StubMsg
, mem
, fmtstr_conf_str
);
2069 ok(my_free_called
== 1, "free called %d\n", my_free_called
);
2072 my_alloc_called
= 0;
2073 StubMsg
.IsClient
= 0;
2075 StubMsg
.Buffer
= StubMsg
.BufferStart
;
2076 NdrPointerUnmarshall( &StubMsg
, &mem
, fmtstr_conf_str
, 0);
2077 ok(mem
== StubMsg
.BufferStart
+ 12 || broken(!mem
), /* win9x, nt4 */
2078 "mem not pointing at buffer %p/%p\n", mem
, StubMsg
.BufferStart
+ 12 );
2079 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
2081 my_alloc_called
= 0;
2083 StubMsg
.Buffer
= StubMsg
.BufferStart
;
2084 NdrPointerUnmarshall( &StubMsg
, &mem
, fmtstr_conf_str
, 1);
2085 ok(mem
== StubMsg
.BufferStart
+ 12 || broken(!mem
), /* win9x, nt4 */
2086 "mem not pointing at buffer %p/%p\n", mem
, StubMsg
.BufferStart
+ 12 );
2087 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
2089 my_alloc_called
= 0;
2090 mem
= mem_orig
= HeapAlloc(GetProcessHeap(), 0, sizeof(memsrc
));
2091 StubMsg
.Buffer
= StubMsg
.BufferStart
;
2092 NdrPointerUnmarshall( &StubMsg
, &mem
, fmtstr_conf_str
, 0);
2093 ok(mem
== StubMsg
.BufferStart
+ 12 || broken(!mem
), /* win9x, nt4 */
2094 "mem not pointing at buffer %p/%p\n", mem
, StubMsg
.BufferStart
+ 12 );
2095 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
2097 my_alloc_called
= 0;
2099 StubMsg
.Buffer
= StubMsg
.BufferStart
;
2100 NdrPointerUnmarshall( &StubMsg
, &mem
, fmtstr_conf_str
, 1);
2101 ok(mem
== StubMsg
.BufferStart
+ 12 || broken(!mem
), /* win9x, nt4 */
2102 "mem not pointing at buffer %p/%p\n", mem
, StubMsg
.BufferStart
+ 12 );
2103 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
2107 StubMsg
.Buffer
= StubMsg
.BufferStart
;
2108 NdrPointerFree( &StubMsg
, mem
, fmtstr_conf_str
);
2109 ok(my_free_called
== 1, "free called %d\n", my_free_called
);
2111 HeapFree(GetProcessHeap(), 0, mem_orig
);
2112 HeapFree(GetProcessHeap(), 0, StubMsg
.RpcMsg
->Buffer
);
2115 static void test_nonconformant_string(void)
2117 RPC_MESSAGE RpcMessage
;
2118 MIDL_STUB_MESSAGE StubMsg
;
2119 MIDL_STUB_DESC StubDesc
;
2122 unsigned char *mem
, *mem_orig
;
2123 unsigned char memsrc
[10] = "This is";
2124 unsigned char memsrc2
[10] = "This is a";
2126 static const unsigned char fmtstr_nonconf_str
[] =
2128 0x26, /* FC_CSTRING */
2130 NdrFcShort( 0xa ), /* 10 */
2133 StubDesc
= Object_StubDesc
;
2134 StubDesc
.pFormatTypes
= fmtstr_nonconf_str
;
2137 NdrClientInitializeNew(
2143 StubMsg
.BufferLength
= 0;
2145 NdrNonConformantStringBufferSize( &StubMsg
, memsrc
, fmtstr_nonconf_str
);
2146 ok(StubMsg
.BufferLength
>= strlen((char *)memsrc
) + 1 + 8, "length %d\n", StubMsg
.BufferLength
);
2148 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
2149 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
2150 StubMsg
.BufferEnd
= StubMsg
.BufferStart
+ StubMsg
.BufferLength
;
2152 ptr
= NdrNonConformantStringMarshall( &StubMsg
, memsrc
, fmtstr_nonconf_str
);
2153 ok(ptr
== NULL
, "ret %p\n", ptr
);
2154 size
= StubMsg
.Buffer
- StubMsg
.BufferStart
;
2155 ok(size
== strlen((char *)memsrc
) + 1 + 8, "Buffer %p Start %p len %d\n",
2156 StubMsg
.Buffer
, StubMsg
.BufferStart
, size
);
2157 ok(!memcmp(StubMsg
.BufferStart
+ 8, memsrc
, strlen((char *)memsrc
) + 1), "incorrectly marshaled\n");
2159 StubMsg
.Buffer
= StubMsg
.BufferStart
;
2160 StubMsg
.MemorySize
= 0;
2164 my_alloc_called
= 0;
2165 StubMsg
.Buffer
= StubMsg
.BufferStart
;
2166 mem
= mem_orig
= HeapAlloc(GetProcessHeap(), 0, sizeof(memsrc
));
2167 NdrNonConformantStringUnmarshall( &StubMsg
, &mem
, fmtstr_nonconf_str
, 0);
2168 ok(mem
== mem_orig
, "mem alloced\n");
2169 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
2171 my_alloc_called
= 0;
2172 StubMsg
.Buffer
= StubMsg
.BufferStart
;
2173 NdrNonConformantStringUnmarshall( &StubMsg
, &mem
, fmtstr_nonconf_str
, 1);
2175 ok(mem
== mem_orig
, "mem alloced\n");
2177 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
2180 my_alloc_called
= 0;
2181 StubMsg
.IsClient
= 0;
2183 StubMsg
.Buffer
= StubMsg
.BufferStart
;
2184 NdrNonConformantStringUnmarshall( &StubMsg
, &mem
, fmtstr_nonconf_str
, 0);
2185 ok(mem
!= mem_orig
, "mem not alloced\n");
2186 ok(mem
!= StubMsg
.BufferStart
+ 8, "mem pointing at buffer\n");
2187 ok(my_alloc_called
== 1, "alloc called %d\n", my_alloc_called
);
2190 my_alloc_called
= 0;
2192 StubMsg
.Buffer
= StubMsg
.BufferStart
;
2193 NdrNonConformantStringUnmarshall( &StubMsg
, &mem
, fmtstr_nonconf_str
, 0);
2194 ok(mem
== mem_orig
, "mem alloced\n");
2195 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
2197 my_alloc_called
= 0;
2199 StubMsg
.Buffer
= StubMsg
.BufferStart
;
2200 NdrNonConformantStringUnmarshall( &StubMsg
, &mem
, fmtstr_nonconf_str
, 1);
2202 ok(mem
== mem_orig
, "mem alloced\n");
2204 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
2206 HeapFree(GetProcessHeap(), 0, mem_orig
);
2207 HeapFree(GetProcessHeap(), 0, StubMsg
.RpcMsg
->Buffer
);
2210 NdrClientInitializeNew(
2216 StubMsg
.BufferLength
= 0;
2218 NdrNonConformantStringBufferSize( &StubMsg
, memsrc2
, fmtstr_nonconf_str
);
2219 ok(StubMsg
.BufferLength
>= strlen((char *)memsrc2
) + 1 + 8, "length %d\n", StubMsg
.BufferLength
);
2221 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
2222 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
2223 StubMsg
.BufferEnd
= StubMsg
.BufferStart
+ StubMsg
.BufferLength
;
2225 ptr
= NdrNonConformantStringMarshall( &StubMsg
, memsrc2
, fmtstr_nonconf_str
);
2226 ok(ptr
== NULL
, "ret %p\n", ptr
);
2227 size
= StubMsg
.Buffer
- StubMsg
.BufferStart
;
2228 ok(size
== strlen((char *)memsrc2
) + 1 + 8, "Buffer %p Start %p len %d\n",
2229 StubMsg
.Buffer
, StubMsg
.BufferStart
, size
);
2230 ok(!memcmp(StubMsg
.BufferStart
+ 8, memsrc2
, strlen((char *)memsrc2
) + 1), "incorrectly marshaled\n");
2232 StubMsg
.Buffer
= StubMsg
.BufferStart
;
2233 StubMsg
.MemorySize
= 0;
2237 my_alloc_called
= 0;
2238 StubMsg
.Buffer
= StubMsg
.BufferStart
;
2239 mem
= mem_orig
= HeapAlloc(GetProcessHeap(), 0, sizeof(memsrc
));
2240 NdrNonConformantStringUnmarshall( &StubMsg
, &mem
, fmtstr_nonconf_str
, 0);
2241 ok(mem
== mem_orig
, "mem alloced\n");
2242 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
2244 my_alloc_called
= 0;
2245 StubMsg
.Buffer
= StubMsg
.BufferStart
;
2246 NdrNonConformantStringUnmarshall( &StubMsg
, &mem
, fmtstr_nonconf_str
, 1);
2248 ok(mem
== mem_orig
, "mem alloced\n");
2250 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
2253 my_alloc_called
= 0;
2254 StubMsg
.IsClient
= 0;
2256 StubMsg
.Buffer
= StubMsg
.BufferStart
;
2257 NdrNonConformantStringUnmarshall( &StubMsg
, &mem
, fmtstr_nonconf_str
, 0);
2258 ok(mem
!= mem_orig
, "mem not alloced\n");
2259 ok(mem
!= StubMsg
.BufferStart
+ 8, "mem pointing at buffer\n");
2260 ok(my_alloc_called
== 1, "alloc called %d\n", my_alloc_called
);
2263 my_alloc_called
= 0;
2265 StubMsg
.Buffer
= StubMsg
.BufferStart
;
2266 NdrNonConformantStringUnmarshall( &StubMsg
, &mem
, fmtstr_nonconf_str
, 0);
2267 ok(mem
== mem_orig
, "mem alloced\n");
2268 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
2270 my_alloc_called
= 0;
2272 StubMsg
.Buffer
= StubMsg
.BufferStart
;
2273 NdrNonConformantStringUnmarshall( &StubMsg
, &mem
, fmtstr_nonconf_str
, 1);
2275 ok(mem
== mem_orig
, "mem alloced\n");
2277 ok(my_alloc_called
== 0, "alloc called %d\n", my_alloc_called
);
2279 HeapFree(GetProcessHeap(), 0, mem_orig
);
2280 HeapFree(GetProcessHeap(), 0, StubMsg
.RpcMsg
->Buffer
);
2283 static void test_conf_complex_struct(void)
2285 RPC_MESSAGE RpcMessage
;
2286 MIDL_STUB_MESSAGE StubMsg
;
2287 MIDL_STUB_DESC StubDesc
;
2293 unsigned int *array
[1];
2295 struct conf_complex
*memsrc
;
2296 struct conf_complex
*mem
;
2298 static const unsigned char fmtstr_complex_struct
[] =
2301 0x1b, /* FC_CARRAY */
2303 /* 2 */ NdrFcShort( 0x4 ), /* 4 */
2304 /* 4 */ 0x8, /* Corr desc: FC_LONG */
2306 /* 6 */ NdrFcShort( 0xfffc ), /* -4 */
2311 0x48, /* FC_VARIABLE_REPEAT */
2312 0x49, /* FC_FIXED_OFFSET */
2313 /* 12 */ NdrFcShort( 0x4 ), /* 4 */
2314 /* 14 */ NdrFcShort( 0x0 ), /* 0 */
2315 /* 16 */ NdrFcShort( 0x1 ), /* 1 */
2316 /* 18 */ NdrFcShort( 0x0 ), /* 0 */
2317 /* 20 */ NdrFcShort( 0x0 ), /* 0 */
2318 /* 22 */ 0x12, 0x8, /* FC_UP [simple_pointer] */
2319 /* 24 */ 0x8, /* FC_LONG */
2325 /* 28 */ 0x5c, /* FC_PAD */
2328 0x1a, /* FC_BOGUS_STRUCT */
2330 /* 32 */ NdrFcShort( 0x4 ), /* 4 */
2331 /* 34 */ NdrFcShort( 0xffffffde ), /* Offset= -34 (0) */
2332 /* 36 */ NdrFcShort( 0x0 ), /* Offset= 0 (36) */
2333 /* 38 */ 0x8, /* FC_LONG */
2337 memsrc
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2338 FIELD_OFFSET(struct conf_complex
, array
[20]));
2341 StubDesc
= Object_StubDesc
;
2342 StubDesc
.pFormatTypes
= fmtstr_complex_struct
;
2344 NdrClientInitializeNew(
2350 StubMsg
.BufferLength
= 0;
2351 NdrComplexStructBufferSize( &StubMsg
,
2352 (unsigned char *)memsrc
,
2353 &fmtstr_complex_struct
[30] );
2354 ok(StubMsg
.BufferLength
>= 28, "length %d\n", StubMsg
.BufferLength
);
2356 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
2357 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
2358 StubMsg
.BufferEnd
= StubMsg
.BufferStart
+ StubMsg
.BufferLength
;
2360 ptr
= NdrComplexStructMarshall( &StubMsg
, (unsigned char *)memsrc
,
2361 &fmtstr_complex_struct
[30] );
2362 ok(ptr
== NULL
, "ret %p\n", ptr
);
2363 ok(*(unsigned int *)StubMsg
.BufferStart
== 20, "Conformance should have been 20 instead of %d\n", *(unsigned int *)StubMsg
.BufferStart
);
2364 ok(*(unsigned int *)(StubMsg
.BufferStart
+ 4) == 20, "conf_complex.size should have been 20 instead of %d\n", *(unsigned int *)(StubMsg
.BufferStart
+ 4));
2365 for (i
= 0; i
< 20; i
++)
2366 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));
2369 my_alloc_called
= 0;
2370 StubMsg
.IsClient
= 0;
2372 StubMsg
.Buffer
= StubMsg
.BufferStart
;
2373 ptr
= NdrComplexStructUnmarshall( &StubMsg
, (unsigned char **)&mem
, &fmtstr_complex_struct
[30], 0);
2374 ok(ptr
== NULL
, "ret %p\n", ptr
);
2375 ok(mem
->size
== 20, "mem->size wasn't unmarshalled correctly (%d)\n", mem
->size
);
2376 ok(mem
->array
[0] == NULL
, "mem->array[0] wasn't unmarshalled correctly (%p)\n", mem
->array
[0]);
2377 StubMsg
.pfnFree(mem
);
2379 HeapFree(GetProcessHeap(), 0, StubMsg
.RpcMsg
->Buffer
);
2380 HeapFree(GetProcessHeap(), 0, memsrc
);
2384 static void test_conf_complex_array(void)
2386 RPC_MESSAGE RpcMessage
;
2387 MIDL_STUB_MESSAGE StubMsg
;
2388 MIDL_STUB_DESC StubDesc
;
2393 unsigned int dim1
, dim2
;
2396 struct conf_complex memsrc
;
2397 struct conf_complex
*mem
;
2398 DWORD
*buf
, expected_length
;
2400 static const unsigned char fmtstr_complex_array
[] =
2403 /* 0 */ 0x21, /* FC_BOGUS_ARRAY */
2405 /* 2 */ NdrFcShort( 0x0 ), /* 0 */
2406 /* 4 */ 0x19, 0x0, /* Corr desc: field pointer, FC_ULONG */
2407 /* 6 */ NdrFcShort( 0x4 ), /* 4 */
2408 /* 8 */ NdrFcLong( 0xffffffff ), /* -1 */
2409 /* 12 */ 0x8, /* FC_LONG */
2412 0x21, /* FC_BOGUS_ARRAY */
2414 /* 16 */ NdrFcShort( 0x0 ), /* 0 */
2415 /* 18 */ 0x19, /* Corr desc: field pointer, FC_ULONG */
2417 /* 20 */ NdrFcShort( 0x0 ), /* 0 */
2418 /* 22 */ NdrFcLong( 0xffffffff ), /* -1 */
2419 /* 26 */ 0x12, 0x0, /* FC_UP */
2420 /* 28 */ NdrFcShort( 0xffe4 ), /* Offset= -28 (0) */
2421 /* 30 */ 0x5c, /* FC_PAD */
2425 /* 32 */ 0x1a, /* FC_BOGUS_STRUCT */
2427 /* 34 */ NdrFcShort( 0x10 ), /* 16 */
2428 /* 36 */ NdrFcShort( 0x0 ), /* 0 */
2429 /* 38 */ NdrFcShort( 0x6 ), /* Offset= 6 (44) */
2430 /* 40 */ 0x8, /* FC_LONG */
2432 /* 42 */ 0x36, /* FC_POINTER */
2435 0x12, 0x0, /* FC_UP */
2436 /* 46 */ NdrFcShort( 0xffe0 ), /* Offset= -32 (14) */
2439 0x16, /* FC_PSTRUCT */
2441 /* 34 */ NdrFcShort( 0xc ), /* 12 */
2442 /* 36 */ 0x4b, /* FC_PP */
2444 /* 38 */ 0x46, /* FC_NO_REPEAT */
2446 /* 40 */ NdrFcShort( 0x8 ), /* 8 */
2447 /* 42 */ NdrFcShort( 0x8 ), /* 8 */
2448 /* 44 */ 0x12, 0x0, /* FC_UP */
2449 /* 46 */ NdrFcShort( 0xffe0 ), /* Offset= -32 (14) */
2450 /* 48 */ 0x5b, /* FC_END */
2452 /* 50 */ 0x8, /* FC_LONG */
2454 /* 52 */ 0x5c, /* FC_PAD */
2462 memsrc
.array
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, memsrc
.dim1
* sizeof(DWORD
*));
2464 for(i
= 0; i
< memsrc
.dim1
; i
++)
2466 memsrc
.array
[i
] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, memsrc
.dim2
* sizeof(DWORD
));
2467 for(j
= 0; j
< memsrc
.dim2
; j
++)
2468 memsrc
.array
[i
][j
] = i
* memsrc
.dim2
+ j
;
2471 StubDesc
= Object_StubDesc
;
2472 StubDesc
.pFormatTypes
= fmtstr_complex_array
;
2474 NdrClientInitializeNew(
2480 StubMsg
.BufferLength
= 0;
2483 NdrComplexStructBufferSize( &StubMsg
,
2484 (unsigned char *)&memsrc
,
2485 &fmtstr_complex_array
[32] );
2487 NdrSimpleStructBufferSize( &StubMsg
,
2488 (unsigned char *)&memsrc
,
2489 &fmtstr_complex_array
[32] );
2492 expected_length
= (4 + memsrc
.dim1
* (2 + memsrc
.dim2
)) * 4;
2493 ok(StubMsg
.BufferLength
>= expected_length
, "length %d\n", StubMsg
.BufferLength
);
2495 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
2496 StubMsg
.RpcMsg
->Buffer
= StubMsg
.BufferStart
= StubMsg
.Buffer
= HeapAlloc(GetProcessHeap(), 0, StubMsg
.BufferLength
);
2497 StubMsg
.BufferEnd
= StubMsg
.BufferStart
+ StubMsg
.BufferLength
;
2500 ptr
= NdrComplexStructMarshall( &StubMsg
, (unsigned char *)&memsrc
,
2501 &fmtstr_complex_array
[32] );
2503 ptr
= NdrSimpleStructMarshall( &StubMsg
, (unsigned char *)&memsrc
,
2504 &fmtstr_complex_array
[32] );
2507 ok(ptr
== NULL
, "ret %p\n", ptr
);
2508 ok((char*)StubMsg
.Buffer
== (char*)StubMsg
.BufferStart
+ expected_length
, "not at expected length\n");
2510 buf
= (DWORD
*)StubMsg
.BufferStart
;
2512 ok(*buf
== memsrc
.dim1
, "dim1 should have been %d instead of %08x\n", memsrc
.dim1
, *buf
);
2514 ok(*buf
== memsrc
.dim2
, "dim2 should have been %d instead of %08x\n", memsrc
.dim2
, *buf
);
2516 ok(*buf
!= 0, "pointer id should be non-zero\n");
2518 ok(*buf
== memsrc
.dim1
, "Conformance should have been %d instead of %08x\n", memsrc
.dim1
, *buf
);
2520 for(i
= 0; i
< memsrc
.dim1
; i
++)
2522 ok(*buf
!= 0, "pointer id[%d] should be non-zero\n", i
);
2525 for(i
= 0; i
< memsrc
.dim1
; i
++)
2527 ok(*buf
== memsrc
.dim2
, "Conformance should have been %d instead of %08x\n", memsrc
.dim2
, *buf
);
2529 for(j
= 0; j
< memsrc
.dim2
; j
++)
2531 ok(*buf
== i
* memsrc
.dim2
+ j
, "got %08x\n", *buf
);
2536 ok((void*)buf
== StubMsg
.Buffer
, "not at end of buffer\n");
2539 my_alloc_called
= 0;
2540 StubMsg
.IsClient
= 0;
2542 StubMsg
.Buffer
= StubMsg
.BufferStart
;
2544 ptr
= NdrComplexStructUnmarshall( &StubMsg
, (unsigned char **)&mem
, &fmtstr_complex_array
[32], 0);
2546 ptr
= NdrSimpleStructUnmarshall( &StubMsg
, (unsigned char **)&mem
, &fmtstr_complex_array
[32], 0);
2548 ok(ptr
== NULL
, "ret %p\n", ptr
);
2549 ok(mem
->dim1
== memsrc
.dim1
, "mem->dim1 wasn't unmarshalled correctly (%d)\n", mem
->dim1
);
2550 ok(mem
->dim2
== memsrc
.dim2
, "mem->dim2 wasn't unmarshalled correctly (%d)\n", mem
->dim2
);
2551 ok(mem
->array
[1][0] == memsrc
.dim2
, "mem->array[1][0] wasn't unmarshalled correctly (%d)\n", mem
->array
[1][0]);
2553 StubMsg
.Buffer
= StubMsg
.BufferStart
;
2555 NdrComplexStructFree( &StubMsg
, (unsigned char*)mem
, &fmtstr_complex_array
[32]);
2557 NdrSimpleStructFree( &StubMsg
, (unsigned char*)mem
, &fmtstr_complex_array
[32]);
2560 HeapFree(GetProcessHeap(), 0, StubMsg
.RpcMsg
->Buffer
);
2562 for(i
= 0; i
< memsrc
.dim1
; i
++)
2563 HeapFree(GetProcessHeap(), 0, memsrc
.array
[i
]);
2564 HeapFree(GetProcessHeap(), 0, memsrc
.array
);
2567 static void test_ndr_buffer(void)
2569 static unsigned char ncalrpc
[] = "ncalrpc";
2570 static unsigned char endpoint
[] = "winetest:test_ndr_buffer";
2571 RPC_MESSAGE RpcMessage
;
2572 MIDL_STUB_MESSAGE StubMsg
;
2573 MIDL_STUB_DESC StubDesc
= Object_StubDesc
;
2575 unsigned char *binding
;
2576 RPC_BINDING_HANDLE Handle
;
2578 ULONG prev_buffer_length
;
2579 BOOL old_buffer_valid_location
;
2581 StubDesc
.RpcInterfaceInformation
= (void *)&IFoo___RpcServerInterface
;
2583 status
= RpcServerUseProtseqEpA(ncalrpc
, 20, endpoint
, NULL
);
2584 ok(RPC_S_OK
== status
, "RpcServerUseProtseqEp failed with status %u\n", status
);
2585 status
= RpcServerRegisterIf(IFoo_v0_0_s_ifspec
, NULL
, NULL
);
2586 ok(RPC_S_OK
== status
, "RpcServerRegisterIf failed with status %u\n", status
);
2587 status
= RpcServerListen(1, 20, TRUE
);
2588 ok(RPC_S_OK
== status
, "RpcServerListen failed with status %u\n", status
);
2589 if (status
!= RPC_S_OK
)
2591 /* Failed to create a server, running client tests is useless */
2595 status
= RpcStringBindingComposeA(NULL
, ncalrpc
, NULL
, endpoint
, NULL
, &binding
);
2596 ok(status
== RPC_S_OK
, "RpcStringBindingCompose failed (%u)\n", status
);
2598 status
= RpcBindingFromStringBindingA(binding
, &Handle
);
2599 ok(status
== RPC_S_OK
, "RpcBindingFromStringBinding failed (%u)\n", status
);
2600 RpcStringFreeA(&binding
);
2602 NdrClientInitializeNew(&RpcMessage
, &StubMsg
, &StubDesc
, 5);
2604 ret
= NdrGetBuffer(&StubMsg
, 10, Handle
);
2605 ok(ret
== StubMsg
.Buffer
, "NdrGetBuffer should have returned the same value as StubMsg.Buffer instead of %p\n", ret
);
2606 ok(RpcMessage
.Handle
!= NULL
, "RpcMessage.Handle should not have been NULL\n");
2607 ok(RpcMessage
.Buffer
!= NULL
, "RpcMessage.Buffer should not have been NULL\n");
2608 ok(RpcMessage
.BufferLength
== 10 ||
2609 broken(RpcMessage
.BufferLength
== 12), /* win2k */
2610 "RpcMessage.BufferLength should have been 10 instead of %d\n", RpcMessage
.BufferLength
);
2611 ok(RpcMessage
.RpcFlags
== 0, "RpcMessage.RpcFlags should have been 0x0 instead of 0x%x\n", RpcMessage
.RpcFlags
);
2612 ok(StubMsg
.Buffer
!= NULL
, "Buffer should not have been NULL\n");
2613 ok(!StubMsg
.BufferStart
, "BufferStart should have been NULL instead of %p\n", StubMsg
.BufferStart
);
2614 ok(!StubMsg
.BufferEnd
, "BufferEnd should have been NULL instead of %p\n", StubMsg
.BufferEnd
);
2616 ok(StubMsg
.BufferLength
== 0, "BufferLength should have left as 0 instead of being set to %d\n", StubMsg
.BufferLength
);
2617 old_buffer_valid_location
= !StubMsg
.fBufferValid
;
2618 if (old_buffer_valid_location
)
2619 ok(broken(StubMsg
.CorrDespIncrement
== TRUE
), "fBufferValid should have been TRUE instead of 0x%x\n", StubMsg
.CorrDespIncrement
);
2621 ok(StubMsg
.fBufferValid
, "fBufferValid should have been non-zero instead of 0x%x\n", StubMsg
.fBufferValid
);
2623 prev_buffer_length
= RpcMessage
.BufferLength
;
2624 StubMsg
.BufferLength
= 1;
2625 NdrFreeBuffer(&StubMsg
);
2626 ok(RpcMessage
.Handle
!= NULL
, "RpcMessage.Handle should not have been NULL\n");
2627 ok(RpcMessage
.Buffer
!= NULL
, "RpcMessage.Buffer should not have been NULL\n");
2628 ok(RpcMessage
.BufferLength
== prev_buffer_length
, "RpcMessage.BufferLength should have been left as %d instead of %d\n", prev_buffer_length
, RpcMessage
.BufferLength
);
2629 ok(StubMsg
.Buffer
!= NULL
, "Buffer should not have been NULL\n");
2630 ok(StubMsg
.BufferLength
== 1, "BufferLength should have left as 1 instead of being set to %d\n", StubMsg
.BufferLength
);
2631 if (old_buffer_valid_location
)
2632 ok(broken(StubMsg
.CorrDespIncrement
== FALSE
), "fBufferValid should have been FALSE instead of 0x%x\n", StubMsg
.CorrDespIncrement
);
2634 ok(!StubMsg
.fBufferValid
, "fBufferValid should have been FALSE instead of %d\n", StubMsg
.fBufferValid
);
2636 /* attempt double-free */
2637 NdrFreeBuffer(&StubMsg
);
2639 RpcBindingFree(&Handle
);
2641 status
= RpcServerUnregisterIf(NULL
, NULL
, FALSE
);
2642 ok(status
== RPC_S_OK
, "RpcServerUnregisterIf failed (%u)\n", status
);
2645 static void test_NdrMapCommAndFaultStatus(void)
2647 RPC_STATUS rpc_status
;
2648 MIDL_STUB_MESSAGE StubMsg
;
2649 RPC_MESSAGE RpcMessage
;
2651 NdrClientInitializeNew(&RpcMessage
, &StubMsg
, &Object_StubDesc
, 5);
2653 for (rpc_status
= 0; rpc_status
< 10000; rpc_status
++)
2656 ULONG comm_status
= 0;
2657 ULONG fault_status
= 0;
2658 ULONG expected_comm_status
= 0;
2659 ULONG expected_fault_status
= 0;
2660 status
= NdrMapCommAndFaultStatus(&StubMsg
, &comm_status
, &fault_status
, rpc_status
);
2661 ok(status
== RPC_S_OK
, "NdrMapCommAndFaultStatus failed with error %d\n", status
);
2664 case ERROR_INVALID_HANDLE
:
2665 case RPC_S_INVALID_BINDING
:
2666 case RPC_S_UNKNOWN_IF
:
2667 case RPC_S_SERVER_UNAVAILABLE
:
2668 case RPC_S_SERVER_TOO_BUSY
:
2669 case RPC_S_CALL_FAILED_DNE
:
2670 case RPC_S_PROTOCOL_ERROR
:
2671 case RPC_S_UNSUPPORTED_TRANS_SYN
:
2672 case RPC_S_UNSUPPORTED_TYPE
:
2673 case RPC_S_PROCNUM_OUT_OF_RANGE
:
2674 case EPT_S_NOT_REGISTERED
:
2675 case RPC_S_COMM_FAILURE
:
2676 expected_comm_status
= rpc_status
;
2679 expected_fault_status
= rpc_status
;
2681 ok(comm_status
== expected_comm_status
, "NdrMapCommAndFaultStatus should have mapped %d to comm status %d instead of %d\n",
2682 rpc_status
, expected_comm_status
, comm_status
);
2683 ok(fault_status
== expected_fault_status
, "NdrMapCommAndFaultStatus should have mapped %d to fault status %d instead of %d\n",
2684 rpc_status
, expected_fault_status
, fault_status
);
2688 static void test_NdrGetUserMarshalInfo(void)
2691 MIDL_STUB_MESSAGE stubmsg
;
2692 USER_MARSHAL_CB umcb
;
2693 NDR_USER_MARSHAL_INFO umi
;
2694 unsigned char buffer
[16];
2695 void *rpc_channel_buffer
= (void *)(ULONG_PTR
)0xcafebabe;
2696 RPC_MESSAGE rpc_msg
;
2700 memset(&rpc_msg
, 0xcc, sizeof(rpc_msg
));
2701 rpc_msg
.Buffer
= buffer
;
2702 rpc_msg
.BufferLength
= 16;
2704 memset(&stubmsg
, 0xcc, sizeof(stubmsg
));
2705 stubmsg
.RpcMsg
= &rpc_msg
;
2706 stubmsg
.dwDestContext
= MSHCTX_INPROC
;
2707 stubmsg
.pvDestContext
= NULL
;
2708 stubmsg
.Buffer
= buffer
+ 15;
2709 stubmsg
.BufferLength
= 0;
2710 stubmsg
.BufferEnd
= NULL
;
2711 stubmsg
.pRpcChannelBuffer
= rpc_channel_buffer
;
2712 stubmsg
.StubDesc
= NULL
;
2713 stubmsg
.pfnAllocate
= my_alloc
;
2714 stubmsg
.pfnFree
= my_free
;
2716 memset(&umcb
, 0xcc, sizeof(umcb
));
2717 umcb
.Flags
= MAKELONG(MSHCTX_INPROC
, NDR_LOCAL_DATA_REPRESENTATION
);
2718 umcb
.pStubMsg
= &stubmsg
;
2719 umcb
.Signature
= USER_MARSHAL_CB_SIGNATURE
;
2720 umcb
.CBType
= USER_MARSHAL_CB_UNMARSHALL
;
2722 memset(&umi
, 0xaa, sizeof(umi
));
2724 status
= NdrGetUserMarshalInfo(&umcb
.Flags
, 1, &umi
);
2725 ok(status
== RPC_S_OK
, "NdrGetUserMarshalInfo failed with error %d\n", status
);
2726 ok( umi
.InformationLevel
== 1,
2727 "umi.InformationLevel was %u instead of 1\n",
2728 umi
.InformationLevel
);
2729 ok( U1(umi
).Level1
.Buffer
== buffer
+ 15,
2730 "umi.Level1.Buffer was %p instead of %p\n",
2731 U1(umi
).Level1
.Buffer
, buffer
);
2732 ok( U1(umi
).Level1
.BufferSize
== 1,
2733 "umi.Level1.BufferSize was %u instead of 1\n",
2734 U1(umi
).Level1
.BufferSize
);
2735 ok( U1(umi
).Level1
.pfnAllocate
== my_alloc
,
2736 "umi.Level1.pfnAllocate was %p instead of %p\n",
2737 U1(umi
).Level1
.pfnAllocate
, my_alloc
);
2738 ok( U1(umi
).Level1
.pfnFree
== my_free
,
2739 "umi.Level1.pfnFree was %p instead of %p\n",
2740 U1(umi
).Level1
.pfnFree
, my_free
);
2741 ok( U1(umi
).Level1
.pRpcChannelBuffer
== rpc_channel_buffer
,
2742 "umi.Level1.pRpcChannelBuffer was %p instead of %p\n",
2743 U1(umi
).Level1
.pRpcChannelBuffer
, rpc_channel_buffer
);
2747 rpc_msg
.Buffer
= buffer
;
2748 rpc_msg
.BufferLength
= 16;
2750 stubmsg
.Buffer
= buffer
;
2751 stubmsg
.BufferLength
= 16;
2752 stubmsg
.BufferEnd
= NULL
;
2754 umcb
.CBType
= USER_MARSHAL_CB_BUFFER_SIZE
;
2756 memset(&umi
, 0xaa, sizeof(umi
));
2758 status
= NdrGetUserMarshalInfo(&umcb
.Flags
, 1, &umi
);
2759 ok(status
== RPC_S_OK
, "NdrGetUserMarshalInfo failed with error %d\n", status
);
2760 ok( umi
.InformationLevel
== 1,
2761 "umi.InformationLevel was %u instead of 1\n",
2762 umi
.InformationLevel
);
2763 ok( U1(umi
).Level1
.Buffer
== NULL
,
2764 "umi.Level1.Buffer was %p instead of NULL\n",
2765 U1(umi
).Level1
.Buffer
);
2766 ok( U1(umi
).Level1
.BufferSize
== 0,
2767 "umi.Level1.BufferSize was %u instead of 0\n",
2768 U1(umi
).Level1
.BufferSize
);
2769 ok( U1(umi
).Level1
.pfnAllocate
== my_alloc
,
2770 "umi.Level1.pfnAllocate was %p instead of %p\n",
2771 U1(umi
).Level1
.pfnAllocate
, my_alloc
);
2772 ok( U1(umi
).Level1
.pfnFree
== my_free
,
2773 "umi.Level1.pfnFree was %p instead of %p\n",
2774 U1(umi
).Level1
.pfnFree
, my_free
);
2775 ok( U1(umi
).Level1
.pRpcChannelBuffer
== rpc_channel_buffer
,
2776 "umi.Level1.pRpcChannelBuffer was %p instead of %p\n",
2777 U1(umi
).Level1
.pRpcChannelBuffer
, rpc_channel_buffer
);
2781 rpc_msg
.Buffer
= buffer
;
2782 rpc_msg
.BufferLength
= 16;
2784 stubmsg
.Buffer
= buffer
+ 15;
2785 stubmsg
.BufferLength
= 0;
2786 stubmsg
.BufferEnd
= NULL
;
2788 umcb
.CBType
= USER_MARSHAL_CB_MARSHALL
;
2790 memset(&umi
, 0xaa, sizeof(umi
));
2792 status
= NdrGetUserMarshalInfo(&umcb
.Flags
, 1, &umi
);
2793 ok(status
== RPC_S_OK
, "NdrGetUserMarshalInfo failed with error %d\n", status
);
2794 ok( umi
.InformationLevel
== 1,
2795 "umi.InformationLevel was %u instead of 1\n",
2796 umi
.InformationLevel
);
2797 ok( U1(umi
).Level1
.Buffer
== buffer
+ 15,
2798 "umi.Level1.Buffer was %p instead of %p\n",
2799 U1(umi
).Level1
.Buffer
, buffer
);
2800 ok( U1(umi
).Level1
.BufferSize
== 1,
2801 "umi.Level1.BufferSize was %u instead of 1\n",
2802 U1(umi
).Level1
.BufferSize
);
2803 ok( U1(umi
).Level1
.pfnAllocate
== my_alloc
,
2804 "umi.Level1.pfnAllocate was %p instead of %p\n",
2805 U1(umi
).Level1
.pfnAllocate
, my_alloc
);
2806 ok( U1(umi
).Level1
.pfnFree
== my_free
,
2807 "umi.Level1.pfnFree was %p instead of %p\n",
2808 U1(umi
).Level1
.pfnFree
, my_free
);
2809 ok( U1(umi
).Level1
.pRpcChannelBuffer
== rpc_channel_buffer
,
2810 "umi.Level1.pRpcChannelBuffer was %p instead of %p\n",
2811 U1(umi
).Level1
.pRpcChannelBuffer
, rpc_channel_buffer
);
2815 rpc_msg
.Buffer
= buffer
;
2816 rpc_msg
.BufferLength
= 16;
2818 stubmsg
.Buffer
= buffer
;
2819 stubmsg
.BufferLength
= 16;
2820 stubmsg
.BufferEnd
= NULL
;
2822 umcb
.CBType
= USER_MARSHAL_CB_FREE
;
2824 memset(&umi
, 0xaa, sizeof(umi
));
2826 status
= NdrGetUserMarshalInfo(&umcb
.Flags
, 1, &umi
);
2827 ok(status
== RPC_S_OK
, "NdrGetUserMarshalInfo failed with error %d\n", status
);
2828 ok( umi
.InformationLevel
== 1,
2829 "umi.InformationLevel was %u instead of 1\n",
2830 umi
.InformationLevel
);
2831 ok( U1(umi
).Level1
.Buffer
== NULL
,
2832 "umi.Level1.Buffer was %p instead of NULL\n",
2833 U1(umi
).Level1
.Buffer
);
2834 ok( U1(umi
).Level1
.BufferSize
== 0,
2835 "umi.Level1.BufferSize was %u instead of 0\n",
2836 U1(umi
).Level1
.BufferSize
);
2837 ok( U1(umi
).Level1
.pfnAllocate
== my_alloc
,
2838 "umi.Level1.pfnAllocate was %p instead of %p\n",
2839 U1(umi
).Level1
.pfnAllocate
, my_alloc
);
2840 ok( U1(umi
).Level1
.pfnFree
== my_free
,
2841 "umi.Level1.pfnFree was %p instead of %p\n",
2842 U1(umi
).Level1
.pfnFree
, my_free
);
2843 ok( U1(umi
).Level1
.pRpcChannelBuffer
== rpc_channel_buffer
,
2844 "umi.Level1.pRpcChannelBuffer was %p instead of %p\n",
2845 U1(umi
).Level1
.pRpcChannelBuffer
, rpc_channel_buffer
);
2849 rpc_msg
.Buffer
= buffer
;
2850 rpc_msg
.BufferLength
= 15;
2852 stubmsg
.Buffer
= buffer
+ 15;
2853 stubmsg
.BufferLength
= 0;
2854 stubmsg
.BufferEnd
= NULL
;
2856 umcb
.CBType
= USER_MARSHAL_CB_MARSHALL
;
2858 status
= NdrGetUserMarshalInfo(&umcb
.Flags
, 1, &umi
);
2859 ok(status
== RPC_S_OK
, "NdrGetUserMarshalInfo failed with error %d\n", status
);
2860 ok( U1(umi
).Level1
.BufferSize
== 0,
2861 "umi.Level1.BufferSize was %u instead of 0\n",
2862 U1(umi
).Level1
.BufferSize
);
2864 /* error conditions */
2866 rpc_msg
.BufferLength
= 14;
2867 status
= NdrGetUserMarshalInfo(&umcb
.Flags
, 1, &umi
);
2868 ok(status
== ERROR_INVALID_USER_BUFFER
,
2869 "NdrGetUserMarshalInfo should have failed with ERROR_INVALID_USER_BUFFER instead of %d\n", status
);
2871 rpc_msg
.BufferLength
= 15;
2872 status
= NdrGetUserMarshalInfo(&umcb
.Flags
, 9999, &umi
);
2873 ok(status
== RPC_S_INVALID_ARG
,
2874 "NdrGetUserMarshalInfo should have failed with RPC_S_INVALID_ARG instead of %d\n", status
);
2877 status
= NdrGetUserMarshalInfo(&umcb
.Flags
, 1, &umi
);
2878 ok(status
== RPC_S_OK
, "NdrGetUserMarshalInfo failed with error %d\n", status
);
2880 umcb
.CBType
= USER_MARSHAL_CB_MARSHALL
;
2882 status
= NdrGetUserMarshalInfo(&umcb
.Flags
, 1, &umi
);
2883 ok(status
== RPC_S_INVALID_ARG
,
2884 "NdrGetUserMarshalInfo should have failed with RPC_S_INVALID_ARG instead of %d\n", status
);
2887 static void test_MesEncodeFixedBufferHandleCreate(void)
2894 status
= MesEncodeFixedBufferHandleCreate(NULL
, 0, NULL
, NULL
);
2895 ok(status
== RPC_S_INVALID_ARG
, "got %d\n", status
);
2897 status
= MesEncodeFixedBufferHandleCreate(NULL
, 0, NULL
, &handle
);
2898 ok(status
== RPC_S_INVALID_ARG
, "got %d\n", status
);
2900 status
= MesEncodeFixedBufferHandleCreate((char*)0xdeadbeef, 0, NULL
, &handle
);
2901 ok(status
== RPC_X_INVALID_BUFFER
, "got %d\n", status
);
2903 buffer
= (void*)((0xdeadbeef + 7) & ~7);
2904 status
= MesEncodeFixedBufferHandleCreate(buffer
, 0, NULL
, &handle
);
2905 ok(status
== RPC_S_INVALID_ARG
, "got %d\n", status
);
2907 status
= MesEncodeFixedBufferHandleCreate(buffer
, 0, &encoded_size
, &handle
);
2909 ok(status
== RPC_S_INVALID_ARG
, "got %d\n", status
);
2910 if (status
== RPC_S_OK
) {
2911 MesHandleFree(handle
);
2913 status
= MesEncodeFixedBufferHandleCreate(buffer
, 32, NULL
, &handle
);
2914 ok(status
== RPC_S_INVALID_ARG
, "got %d\n", status
);
2916 status
= MesEncodeFixedBufferHandleCreate(buffer
, 32, &encoded_size
, &handle
);
2917 ok(status
== RPC_S_OK
, "got %d\n", status
);
2919 status
= MesBufferHandleReset(NULL
, MES_DYNAMIC_BUFFER_HANDLE
, MES_ENCODE
,
2920 &buffer
, 32, &encoded_size
);
2921 ok(status
== RPC_S_INVALID_ARG
, "got %d\n", status
);
2923 /* convert to dynamic buffer handle */
2924 status
= MesBufferHandleReset(handle
, MES_DYNAMIC_BUFFER_HANDLE
, MES_ENCODE
,
2925 &buffer
, 32, &encoded_size
);
2926 ok(status
== RPC_S_OK
, "got %d\n", status
);
2928 status
= MesBufferHandleReset(handle
, MES_DYNAMIC_BUFFER_HANDLE
, MES_ENCODE
,
2929 NULL
, 32, &encoded_size
);
2930 ok(status
== RPC_S_INVALID_ARG
, "got %d\n", status
);
2932 status
= MesBufferHandleReset(handle
, MES_DYNAMIC_BUFFER_HANDLE
, MES_ENCODE
,
2934 ok(status
== RPC_S_INVALID_ARG
, "got %d\n", status
);
2936 /* invalid handle type */
2937 status
= MesBufferHandleReset(handle
, MES_DYNAMIC_BUFFER_HANDLE
+1, MES_ENCODE
,
2938 &buffer
, 32, &encoded_size
);
2939 ok(status
== RPC_S_INVALID_ARG
, "got %d\n", status
);
2941 status
= MesHandleFree(handle
);
2942 ok(status
== RPC_S_OK
, "got %d\n", status
);
2945 static void test_NdrCorrelationInitialize(void)
2947 MIDL_STUB_MESSAGE stub_msg
;
2950 memset( &stub_msg
, 0, sizeof(stub_msg
) );
2951 memset( buf
, 0, sizeof(buf
) );
2953 NdrCorrelationInitialize( &stub_msg
, buf
, sizeof(buf
), 0 );
2954 ok( stub_msg
.CorrDespIncrement
== 2 ||
2955 broken(stub_msg
.CorrDespIncrement
== 0), /* <= Win 2003 */
2956 "got %d\n", stub_msg
.CorrDespIncrement
);
2958 memset( &stub_msg
, 0, sizeof(stub_msg
) );
2959 memset( buf
, 0, sizeof(buf
) );
2961 stub_msg
.CorrDespIncrement
= 1;
2962 NdrCorrelationInitialize( &stub_msg
, buf
, sizeof(buf
), 0 );
2963 ok( stub_msg
.CorrDespIncrement
== 1, "got %d\n", stub_msg
.CorrDespIncrement
);
2966 START_TEST( ndr_marshall
)
2968 determine_pointer_marshalling_style();
2970 test_ndr_simple_type();
2971 test_simple_types();
2972 test_nontrivial_pointer_types();
2973 test_simple_struct();
2974 test_struct_align();
2976 test_fullpointer_xlat();
2979 test_ndr_allocate();
2980 test_conformant_array();
2981 test_conformant_string();
2982 test_nonconformant_string();
2983 test_conf_complex_struct();
2984 test_conf_complex_array();
2986 test_NdrMapCommAndFaultStatus();
2987 test_NdrGetUserMarshalInfo();
2988 test_MesEncodeFixedBufferHandleCreate();
2989 test_NdrCorrelationInitialize();