ReactOS 0.4.16-dev-109-gf4cb10f
ndr_marshall.c
Go to the documentation of this file.
1/*
2 * Unit test suite for ndr marshalling functions
3 *
4 * Copyright 2006 Huw Davies
5 *
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.
10 *
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.
15 *
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
19 */
20
21#define COBJMACROS
22
23#include <stdarg.h>
24
25#include <windef.h>
26#include <winbase.h>
27#include <winnt.h>
28#include <winerror.h>
29#include <ole2.h>
30
31#include "rpc.h"
32#include "rpcdce.h"
33#include "rpcproxy.h"
34#include "midles.h"
35#include "ndrtypes.h"
36
37#include "wine/heap.h"
38#include "wine/test.h"
39
40static int my_alloc_called;
41static int my_free_called;
43{
45 return NdrOleAllocate(size);
46}
47
48static void CALLBACK my_free(void *ptr)
49{
52}
53
55 {
56 NULL,
58 my_free,
59 { 0 },
60 0,
61 0,
62 0,
63 0,
64 NULL, /* format string, filled in by tests */
65 1, /* -error bounds_check flag */
66 0x20000, /* Ndr library version */
67 0,
68 0x50100a4, /* MIDL Version 5.1.164 */
69 0,
70 NULL,
71 0, /* notify & notify_flag routine table */
72 1, /* Flags */
73 0, /* Reserved3 */
74 0, /* Reserved4 */
75 0 /* Reserved5 */
76 };
77
79{
80 0
81};
82
84{
85 0,
87};
88
90{
92 {{0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x34}},{0,0}},
93 {{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}},
95 0,
96 0,
97 0,
98 0,
99 0,
100};
101
104
106{
107 RPC_MESSAGE RpcMessage;
108 MIDL_STUB_MESSAGE StubMsg;
109 MIDL_STUB_DESC StubDesc;
110 char ch = 0xde;
111
112 static const unsigned char fmtstr_up_char[] =
113 {
114 0x12, 0x8, /* FC_UP [simple_pointer] */
115 0x2, /* FC_CHAR */
116 0x5c, /* FC_PAD */
117 };
118
119 StubDesc = Object_StubDesc;
120 StubDesc.pFormatTypes = NULL;
121
123 &RpcMessage,
124 &StubMsg,
125 &StubDesc,
126 0);
127
128 StubMsg.BufferLength = 8;
129 StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
130 NdrPointerMarshall(&StubMsg, (unsigned char*)&ch, fmtstr_up_char);
131 ok(StubMsg.Buffer == StubMsg.BufferStart + 5, "%p %p\n", StubMsg.Buffer, StubMsg.BufferStart);
132
133 use_pointer_ids = (*(unsigned int *)StubMsg.BufferStart != (UINT_PTR)&ch);
134 trace("Pointer marshalling using %s\n", use_pointer_ids ? "pointer ids" : "pointer value");
135
136 HeapFree(GetProcessHeap(), 0, StubMsg.BufferStart);
137}
138
139static void test_ndr_simple_type(void)
140{
141 RPC_MESSAGE RpcMessage;
142 MIDL_STUB_MESSAGE StubMsg;
143 MIDL_STUB_DESC StubDesc;
144 LONG l, l2 = 0;
145
146 StubDesc = Object_StubDesc;
147 StubDesc.pFormatTypes = NULL;
148
150 &RpcMessage,
151 &StubMsg,
152 &StubDesc,
153 0);
154
155 StubMsg.BufferLength = 16;
156 StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
157 l = 0xcafebabe;
158 NdrSimpleTypeMarshall(&StubMsg, (unsigned char*)&l, FC_LONG);
159 ok(StubMsg.Buffer == StubMsg.BufferStart + 4, "%p %p\n", StubMsg.Buffer, StubMsg.BufferStart);
160 ok(*(LONG*)StubMsg.BufferStart == l, "%d\n", *(LONG*)StubMsg.BufferStart);
161
162 StubMsg.Buffer = StubMsg.BufferStart + 1;
163 NdrSimpleTypeMarshall(&StubMsg, (unsigned char*)&l, FC_LONG);
164 ok(StubMsg.Buffer == StubMsg.BufferStart + 8, "%p %p\n", StubMsg.Buffer, StubMsg.BufferStart);
165 ok(*(LONG*)(StubMsg.BufferStart + 4) == l, "%d\n", *(LONG*)StubMsg.BufferStart);
166
167 StubMsg.Buffer = StubMsg.BufferStart + 1;
168 NdrSimpleTypeUnmarshall(&StubMsg, (unsigned char*)&l2, FC_LONG);
169 ok(StubMsg.Buffer == StubMsg.BufferStart + 8, "%p %p\n", StubMsg.Buffer, StubMsg.BufferStart);
170 ok(l2 == l, "%d\n", l2);
171
172 HeapFree(GetProcessHeap(), 0, StubMsg.BufferStart);
173}
174
175static void test_pointer_marshal(const unsigned char *formattypes,
176 void *memsrc, DWORD srcsize,
177 const void *wiredata,
178 ULONG wiredatalen,
179 int(*cmp)(const void*,const void*,size_t),
180 int num_additional_allocs,
181 const char *msgpfx)
182{
183 RPC_MESSAGE RpcMessage;
184 MIDL_STUB_MESSAGE StubMsg;
185 MIDL_STUB_DESC StubDesc;
186 DWORD size;
187 void *ptr;
188 unsigned char *mem, *mem_orig;
189
190 if(!cmp)
191 cmp = memcmp;
192
193 StubDesc = Object_StubDesc;
194 StubDesc.pFormatTypes = formattypes;
195
197 &RpcMessage,
198 &StubMsg,
199 &StubDesc,
200 0);
201
202 StubMsg.BufferLength = 0;
203 NdrPointerBufferSize( &StubMsg,
204 memsrc,
205 formattypes );
206 ok(StubMsg.BufferLength >= wiredatalen, "%s: length %d\n", msgpfx, StubMsg.BufferLength);
207
208 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
209 StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
210 StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
211
212 memset(StubMsg.BufferStart, 0x0, StubMsg.BufferLength); /* This is a hack to clear the padding between the ptr and longlong/double */
213
214 ptr = NdrPointerMarshall( &StubMsg, memsrc, formattypes );
215 ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
216 if (srcsize == 8 && wiredatalen == 16 && StubMsg.Buffer - StubMsg.BufferStart == 12)
217 {
218 /* win9x doesn't align 8-byte types properly */
219 wiredatalen = 12;
220 }
221 else
222 {
223 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
224 ok(!memcmp(StubMsg.BufferStart, wiredata, wiredatalen), "%s: incorrectly marshaled\n", msgpfx);
225 }
226
227 StubMsg.Buffer = StubMsg.BufferStart;
228 StubMsg.MemorySize = 0;
229
230 size = NdrPointerMemorySize( &StubMsg, formattypes );
231 ok(size == StubMsg.MemorySize, "%s: mem size %u size %u\n", msgpfx, StubMsg.MemorySize, size);
232 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
233 if (formattypes[1] & FC_POINTER_DEREF)
234 ok(size == srcsize + sizeof(void *), "%s: mem size %u\n", msgpfx, size);
235 else
236 ok(size == srcsize, "%s: mem size %u\n", msgpfx, size);
237
238 StubMsg.Buffer = StubMsg.BufferStart;
239 StubMsg.MemorySize = 16;
240 size = NdrPointerMemorySize( &StubMsg, formattypes );
241 ok(size == StubMsg.MemorySize, "%s: mem size %u size %u\n", msgpfx, StubMsg.MemorySize, size);
242 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
243 if (formattypes[1] & FC_POINTER_DEREF)
244 ok(size == srcsize + sizeof(void *) + 16, "%s: mem size %u\n", msgpfx, size);
245 else
246 ok(size == srcsize + 16, "%s: mem size %u\n", msgpfx, size);
247
248 StubMsg.Buffer = StubMsg.BufferStart;
249 StubMsg.MemorySize = 1;
250 size = NdrPointerMemorySize( &StubMsg, formattypes );
251 ok(size == StubMsg.MemorySize, "%s: mem size %u size %u\n", msgpfx, StubMsg.MemorySize, size);
252 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
253 if (formattypes[1] & FC_POINTER_DEREF)
254 ok(size == srcsize + sizeof(void *) + (srcsize == 8 ? 8 : sizeof(void *)), "%s: mem size %u\n", msgpfx, size);
255 else
256 ok(size == srcsize + (srcsize == 8 ? 8 : sizeof(void *)), "%s: mem size %u\n", msgpfx, size);
257
258 size = srcsize;
259 if (formattypes[1] & FC_POINTER_DEREF) size += 4;
260
261 StubMsg.Buffer = StubMsg.BufferStart;
262 StubMsg.MemorySize = 0;
263 /* Using my_alloc() here is necessary to prevent a crash in Windows 7+. */
264 mem_orig = mem = my_alloc(size);
265 memset(mem, 0, size);
267 if (formattypes[1] & FC_POINTER_DEREF)
268 *(void**)mem = NULL;
269 ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 0 );
270 ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
271 ok(mem == mem_orig, "%s: mem has changed %p %p\n", msgpfx, mem, mem_orig);
272 ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx);
273 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
274 ok(StubMsg.MemorySize == 0, "%s: memorysize %d\n", msgpfx, StubMsg.MemorySize);
275 ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
276 /* On Windows 7+ unmarshalling may involve calls to NdrFree, for unclear reasons. */
277 my_free_called = 0;
278
279 NdrPointerFree(&StubMsg, mem, formattypes);
280 if ((formattypes[1] & FC_ALLOCED_ON_STACK) && (formattypes[1] & FC_POINTER_DEREF))
281 {
282 /* In this case the top-level pointer is not freed. */
283 ok(my_free_called == num_additional_allocs, "%s: my_free got called %d times\n", msgpfx, my_free_called);
285 }
286 else
287 ok(my_free_called == 1 + num_additional_allocs, "%s: my_free got called %d times\n", msgpfx, my_free_called);
288
289 /* reset the buffer and call with must alloc */
291 StubMsg.Buffer = StubMsg.BufferStart;
293 if (formattypes[1] & FC_POINTER_DEREF)
294 *(void**)mem = NULL;
295 ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 1 );
296 ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
297 /* doesn't allocate mem in this case */
298 ok(mem == mem_orig, "%s: mem has changed %p %p\n", msgpfx, mem, mem_orig);
299 ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx);
300 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
301 ok(StubMsg.MemorySize == 0, "%s: memorysize %d\n", msgpfx, StubMsg.MemorySize);
302 ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
303 ok(!my_free_called, "%s: my_free got called %d times\n", msgpfx, my_free_called);
304
305 NdrPointerFree(&StubMsg, mem, formattypes);
306 if ((formattypes[1] & FC_ALLOCED_ON_STACK) && (formattypes[1] & FC_POINTER_DEREF))
307 {
308 /* In this case the top-level pointer is not freed. */
309 ok(my_free_called == num_additional_allocs, "%s: my_free got called %d times\n", msgpfx, my_free_called);
311 }
312 else
313 ok(my_free_called == 1 + num_additional_allocs, "%s: my_free got called %d times\n", msgpfx, my_free_called);
314
315 if (formattypes[0] != FC_RP)
316 {
317 /* now pass the address of a NULL ptr */
318 mem = NULL;
320 StubMsg.Buffer = StubMsg.BufferStart;
321 ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 0 );
322 ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
323 ok(mem != StubMsg.BufferStart + wiredatalen - srcsize, "%s: mem points to buffer %p %p\n", msgpfx, mem, StubMsg.BufferStart);
324 ok(!cmp(mem, memsrc, size), "%s: incorrectly unmarshaled\n", msgpfx);
325 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
326 ok(StubMsg.MemorySize == 0, "%s: memorysize %d\n", msgpfx, StubMsg.MemorySize);
327 ok(my_alloc_called == num_additional_allocs + 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
328 my_alloc_called = 0;
329 NdrPointerFree(&StubMsg, mem, formattypes);
330
331 /* again pass address of NULL ptr, but pretend we're a server */
332 if (0) /* crashes on Win9x and NT4 */
333 {
334 mem = NULL;
335 StubMsg.Buffer = StubMsg.BufferStart;
336 StubMsg.IsClient = 0;
337 ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 0 );
338 ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
339 if (formattypes[2] == FC_ENUM16)
340 ok(mem != StubMsg.BufferStart + wiredatalen - srcsize, "%s: mem points to buffer %p %p\n", msgpfx, mem, StubMsg.BufferStart);
341 else
342 ok(mem == StubMsg.BufferStart + wiredatalen - srcsize, "%s: mem doesn't point to buffer %p %p\n", msgpfx, mem, StubMsg.BufferStart);
343 ok(!cmp(mem, memsrc, size), "%s: incorrectly unmarshaled\n", msgpfx);
344 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
345 ok(StubMsg.MemorySize == 0, "%s: memorysize %d\n", msgpfx, StubMsg.MemorySize);
346 if (formattypes[2] != FC_ENUM16)
347 {
348 ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
349 my_alloc_called = 0;
350 }
351 }
352 }
353
354 /* Server */
355 StubMsg.IsClient = 0;
356
357 /* For most basetypes (but not enum16), memory will not be allocated but
358 * instead point directly to the buffer. */
360 StubMsg.Buffer = StubMsg.BufferStart;
361 mem = NULL;
362 ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 0 );
363 ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
364 ok(!!mem, "%s: mem was not allocated\n", msgpfx);
365 ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx);
366 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
367 ok(StubMsg.MemorySize == 0, "%s: memorysize %d\n", msgpfx, StubMsg.MemorySize);
368 if (formattypes[2] == FC_ENUM16)
369 ok(my_alloc_called == 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
370 else
371 ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
372 ok(!my_free_called, "%s: my_free got called %d times\n", msgpfx, my_free_called);
373
374 NdrPointerFree(&StubMsg, mem, formattypes);
375 if (formattypes[2] == FC_ENUM16)
376 ok(my_free_called == 1, "%s: my_free got called %d times\n", msgpfx, my_free_called);
377 else if ((formattypes[1] & FC_ALLOCED_ON_STACK) && (formattypes[1] & FC_POINTER_DEREF))
378 {
379 /* In theory this should be freed to correspond with the allocation, but
380 * FC_ALLOCED_ON_STACK is set, and NdrPointerFree() has no way of
381 * knowing that the memory allocated by NdrPointerUnmarshall() isn't
382 * stack memory. In practice it always *is* stack memory if ON_STACK is
383 * set, so this leak isn't a concern. */
384 ok(my_free_called == 0, "%s: my_free got called %d times\n", msgpfx, my_free_called);
386 }
387 else
388 ok(my_free_called == num_additional_allocs, "%s: my_free got called %d times\n", msgpfx, my_free_called);
389
390 /* reset the buffer and call with must alloc */
392 StubMsg.Buffer = StubMsg.BufferStart;
393 mem = NULL;
394 ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 1 );
395 ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
396 ok(!!mem, "%s: mem was not allocated\n", msgpfx);
397 ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx);
398 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
399 ok(StubMsg.MemorySize == 0, "%s: memorysize %d\n", msgpfx, StubMsg.MemorySize);
400 if (formattypes[2] == FC_ENUM16)
401 ok(my_alloc_called == 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
402 else
403 ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
404 ok(!my_free_called, "%s: my_free got called %d times\n", msgpfx, my_free_called);
405
406 NdrPointerFree(&StubMsg, mem, formattypes);
407 if (formattypes[2] == FC_ENUM16)
408 ok(my_free_called == 1, "%s: my_free got called %d times\n", msgpfx, my_free_called);
409 else if ((formattypes[1] & FC_ALLOCED_ON_STACK) && (formattypes[1] & FC_POINTER_DEREF))
410 {
411 ok(my_free_called == 0, "%s: my_free got called %d times\n", msgpfx, my_free_called);
413 }
414 else
415 ok(my_free_called == num_additional_allocs, "%s: my_free got called %d times\n", msgpfx, my_free_called);
416
417 /* Τest with an existing pointer. Unless it's a stack pointer (and deref'd)
418 * a new pointer will be allocated anyway (in fact, an invalid pointer works
419 * in every such case). */
420
422 StubMsg.Buffer = StubMsg.BufferStart;
424 if (formattypes[1] & FC_POINTER_DEREF)
425 *(void**)mem = NULL;
426 ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 0 );
427 ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
428 if ((formattypes[1] & FC_ALLOCED_ON_STACK) && (formattypes[1] & FC_POINTER_DEREF))
429 ok(mem == mem_orig, "%s: mem has changed %p %p\n", msgpfx, mem, mem_orig);
430 else
431 {
432 ok(mem != mem_orig, "%s: mem has not changed\n", msgpfx);
433 HeapFree(GetProcessHeap(), 0, mem_orig);
434 }
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);
442 else
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);
445
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))
450 {
451 ok(my_free_called == 0, "%s: my_free got called %d times\n", msgpfx, my_free_called);
453 }
454 else
455 ok(my_free_called == num_additional_allocs, "%s: my_free got called %d times\n", msgpfx, my_free_called);
456
457 /* reset the buffer and call with must alloc */
459 StubMsg.Buffer = StubMsg.BufferStart;
461 if (formattypes[1] & FC_POINTER_DEREF)
462 *(void**)mem = NULL;
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);
467 else
468 {
469 ok(mem != mem_orig, "%s: mem has not changed\n", msgpfx);
470 HeapFree(GetProcessHeap(), 0, mem_orig);
471 }
472 ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx);
473 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
474 ok(StubMsg.MemorySize == 0, "%s: memorysize %d\n", msgpfx, StubMsg.MemorySize);
475 if (formattypes[2] == FC_ENUM16)
476 ok(my_alloc_called == 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
477 else if ((formattypes[1] & FC_ALLOCED_ON_STACK) && (formattypes[1] & FC_POINTER_DEREF))
478 ok(my_alloc_called == 0, "%s: my_alloc got called %d times\n", msgpfx, my_free_called);
479 else
480 ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
481 ok(!my_free_called, "%s: my_free got called %d times\n", msgpfx, my_free_called);
482
483 NdrPointerFree(&StubMsg, mem, formattypes);
484 if (formattypes[2] == FC_ENUM16)
485 ok(my_free_called == 1, "%s: my_free got called %d times\n", msgpfx, my_free_called);
486 else if ((formattypes[1] & FC_ALLOCED_ON_STACK) && (formattypes[1] & FC_POINTER_DEREF))
487 {
488 ok(my_free_called == 0, "%s: my_free got called %d times\n", msgpfx, my_free_called);
490 }
491 else
492 ok(my_free_called == num_additional_allocs, "%s: my_free got called %d times\n", msgpfx, my_free_called);
493
494 HeapFree(GetProcessHeap(), 0, StubMsg.BufferStart);
495}
496
497static int deref_cmp(const void *s1, const void *s2, size_t num)
498{
499 return memcmp(*(const void *const *)s1, *(const void *const *)s2, num);
500}
501
502
503static void test_simple_types(void)
504{
505 unsigned char wiredata[16];
506 unsigned char ch;
507 unsigned char *ch_ptr;
508 unsigned short s;
509 unsigned int i;
510 ULONG l;
512 float f;
513 double d;
514
515 static const unsigned char fmtstr_up_char[] =
516 {
517 0x12, 0x8, /* FC_UP [simple_pointer] */
518 0x2, /* FC_CHAR */
519 0x5c, /* FC_PAD */
520 };
521 static const unsigned char fmtstr_up_byte[] =
522 {
523 0x12, 0x8, /* FC_UP [simple_pointer] */
524 0x1, /* FC_BYTE */
525 0x5c, /* FC_PAD */
526 };
527 static const unsigned char fmtstr_up_small[] =
528 {
529 0x12, 0x8, /* FC_UP [simple_pointer] */
530 0x3, /* FC_SMALL */
531 0x5c, /* FC_PAD */
532 };
533 static const unsigned char fmtstr_up_usmall[] =
534 {
535 0x12, 0x8, /* FC_UP [simple_pointer] */
536 0x4, /* FC_USMALL */
537 0x5c, /* FC_PAD */
538 };
539 static const unsigned char fmtstr_rp_char[] =
540 {
541 0x11, 0x8, /* FC_RP [simple_pointer] */
542 0x2, /* FC_CHAR */
543 0x5c, /* FC_PAD */
544 };
545 static const unsigned char fmtstr_rpup_char_onstack_deref[] =
546 {
547 0x11, 0x14, /* FC_RP [alloced_on_stack] [pointer_deref] */
548 NdrFcShort( 0x2 ), /* Offset= 2 (4) */
549 0x12, 0x8, /* FC_UP [simple_pointer] */
550 0x2, /* FC_CHAR */
551 0x5c, /* FC_PAD */
552 };
553 static const unsigned char fmtstr_rpup_char_onstack[] =
554 {
555 0x11, 0x04, /* FC_RP [alloced_on_stack] */
556 NdrFcShort( 0x2 ), /* Offset= 2 (4) */
557 0x12, 0x8, /* FC_UP [simple_pointer] */
558 0x2, /* FC_CHAR */
559 0x5c, /* FC_PAD */
560 };
561 static const unsigned char fmtstr_rpup_char_deref[] =
562 {
563 0x11, 0x10, /* FC_RP [pointer_deref] */
564 NdrFcShort( 0x2 ), /* Offset= 2 (4) */
565 0x12, 0x8, /* FC_UP [simple_pointer] */
566 0x2, /* FC_CHAR */
567 0x5c, /* FC_PAD */
568 };
569
570 static const unsigned char fmtstr_up_wchar[] =
571 {
572 0x12, 0x8, /* FC_UP [simple_pointer] */
573 0x5, /* FC_WCHAR */
574 0x5c, /* FC_PAD */
575 };
576 static const unsigned char fmtstr_up_short[] =
577 {
578 0x12, 0x8, /* FC_UP [simple_pointer] */
579 0x6, /* FC_SHORT */
580 0x5c, /* FC_PAD */
581 };
582 static const unsigned char fmtstr_up_ushort[] =
583 {
584 0x12, 0x8, /* FC_UP [simple_pointer] */
585 0x7, /* FC_USHORT */
586 0x5c, /* FC_PAD */
587 };
588 static const unsigned char fmtstr_up_enum16[] =
589 {
590 0x12, 0x8, /* FC_UP [simple_pointer] */
591 0xd, /* FC_ENUM16 */
592 0x5c, /* FC_PAD */
593 };
594 static const unsigned char fmtstr_up_long[] =
595 {
596 0x12, 0x8, /* FC_UP [simple_pointer] */
597 0x8, /* FC_LONG */
598 0x5c, /* FC_PAD */
599 };
600 static const unsigned char fmtstr_up_ulong[] =
601 {
602 0x12, 0x8, /* FC_UP [simple_pointer] */
603 0x9, /* FC_ULONG */
604 0x5c, /* FC_PAD */
605 };
606 static const unsigned char fmtstr_up_enum32[] =
607 {
608 0x12, 0x8, /* FC_UP [simple_pointer] */
609 0xe, /* FC_ENUM32 */
610 0x5c, /* FC_PAD */
611 };
612 static const unsigned char fmtstr_up_errorstatus[] =
613 {
614 0x12, 0x8, /* FC_UP [simple_pointer] */
615 0x10, /* FC_ERROR_STATUS_T */
616 0x5c, /* FC_PAD */
617 };
618
619 static const unsigned char fmtstr_up_longlong[] =
620 {
621 0x12, 0x8, /* FC_UP [simple_pointer] */
622 0xb, /* FC_HYPER */
623 0x5c, /* FC_PAD */
624 };
625 static const unsigned char fmtstr_up_float[] =
626 {
627 0x12, 0x8, /* FC_UP [simple_pointer] */
628 0xa, /* FC_FLOAT */
629 0x5c, /* FC_PAD */
630 };
631 static const unsigned char fmtstr_up_double[] =
632 {
633 0x12, 0x8, /* FC_UP [simple_pointer] */
634 0xc, /* FC_DOUBLE */
635 0x5c, /* FC_PAD */
636 };
637
638 ch = 0xa5;
639 ch_ptr = &ch;
640 if (use_pointer_ids)
641 *(unsigned int *)wiredata = 0x20000;
642 else
643 *(unsigned int *)wiredata = (UINT_PTR)ch_ptr;
644 wiredata[4] = ch;
645
646 test_pointer_marshal(fmtstr_up_char, ch_ptr, 1, wiredata, 5, NULL, 0, "up_char");
647 test_pointer_marshal(fmtstr_up_byte, ch_ptr, 1, wiredata, 5, NULL, 0, "up_byte");
648 test_pointer_marshal(fmtstr_up_small, ch_ptr, 1, wiredata, 5, NULL, 0, "up_small");
649 test_pointer_marshal(fmtstr_up_usmall, ch_ptr, 1, wiredata, 5, NULL, 0, "up_usmall");
650
651 test_pointer_marshal(fmtstr_rp_char, ch_ptr, 1, &ch, 1, NULL, 0, "rp_char");
652
653 test_pointer_marshal(fmtstr_rpup_char_onstack_deref, &ch_ptr, 1, wiredata, 5, deref_cmp, 1, "rpup_char_onstack_deref");
654 test_pointer_marshal(fmtstr_rpup_char_onstack, ch_ptr, 1, wiredata, 5, NULL, 0, "rpup_char_onstack");
655 test_pointer_marshal(fmtstr_rpup_char_deref, &ch_ptr, 1, wiredata, 5, deref_cmp, 1, "rpup_char_deref");
656
657 s = 0xa597;
658 if (use_pointer_ids)
659 *(unsigned int *)wiredata = 0x20000;
660 else
661 *(unsigned int *)wiredata = (UINT_PTR)&s;
662 *(unsigned short*)(wiredata + 4) = s;
663
664 test_pointer_marshal(fmtstr_up_wchar, &s, 2, wiredata, 6, NULL, 0, "up_wchar");
665 test_pointer_marshal(fmtstr_up_short, &s, 2, wiredata, 6, NULL, 0, "up_short");
666 test_pointer_marshal(fmtstr_up_ushort, &s, 2, wiredata, 6, NULL, 0, "up_ushort");
667
668 i = 0x7fff;
669 if (use_pointer_ids)
670 *(unsigned int *)wiredata = 0x20000;
671 else
672 *(unsigned int *)wiredata = (UINT_PTR)&i;
673 *(unsigned short*)(wiredata + 4) = i;
674 test_pointer_marshal(fmtstr_up_enum16, &i, 4, wiredata, 6, NULL, 0, "up_enum16");
675
676 l = 0xcafebabe;
677 if (use_pointer_ids)
678 *(unsigned int *)wiredata = 0x20000;
679 else
680 *(unsigned int *)wiredata = (UINT_PTR)&l;
681 *(ULONG*)(wiredata + 4) = l;
682
683 test_pointer_marshal(fmtstr_up_long, &l, 4, wiredata, 8, NULL, 0, "up_long");
684 test_pointer_marshal(fmtstr_up_ulong, &l, 4, wiredata, 8, NULL, 0, "up_ulong");
685 test_pointer_marshal(fmtstr_up_enum32, &l, 4, wiredata, 8, NULL, 0, "up_emun32");
686 test_pointer_marshal(fmtstr_up_errorstatus, &l, 4, wiredata, 8, NULL, 0, "up_errorstatus");
687
688 ll = ((ULONGLONG)0xcafebabe) << 32 | 0xdeadbeef;
689 if (use_pointer_ids)
690 *(unsigned int *)wiredata = 0x20000;
691 else
692 *(unsigned int *)wiredata = (UINT_PTR)&ll;
693 *(unsigned int *)(wiredata + 4) = 0;
694 *(ULONGLONG*)(wiredata + 8) = ll;
695 test_pointer_marshal(fmtstr_up_longlong, &ll, 8, wiredata, 16, NULL, 0, "up_longlong");
696
697 f = 3.1415f;
698 if (use_pointer_ids)
699 *(unsigned int *)wiredata = 0x20000;
700 else
701 *(unsigned int *)wiredata = (UINT_PTR)&f;
702 *(float*)(wiredata + 4) = f;
703 test_pointer_marshal(fmtstr_up_float, &f, 4, wiredata, 8, NULL, 0, "up_float");
704
705 d = 3.1415;
706 if (use_pointer_ids)
707 *(unsigned int *)wiredata = 0x20000;
708 else
709 *(unsigned int *)wiredata = (UINT_PTR)&d;
710 *(unsigned int *)(wiredata + 4) = 0;
711 *(double*)(wiredata + 8) = d;
712 test_pointer_marshal(fmtstr_up_double, &d, 8, wiredata, 16, NULL, 0, "up_double");
713
714}
715
717{
718 RPC_MESSAGE RpcMessage;
719 MIDL_STUB_MESSAGE StubMsg;
720 MIDL_STUB_DESC StubDesc;
721 DWORD size;
722 void *ptr;
723 char **p1;
724 char *p2;
725 char ch;
726 unsigned char *mem, *mem_orig;
727
728 static const unsigned char fmtstr_ref_unique_out[] =
729 {
730 0x12, 0x8, /* FC_UP [simple_pointer] */
731 0x2, /* FC_CHAR */
732 0x5c, /* FC_PAD */
733 0x11, 0x14, /* FC_RP [alloced_on_stack] [pointer_deref] */
734 NdrFcShort( 0xfffffffa ), /* Offset= -6 (0) */
735 };
736
737 p1 = &p2;
738 p2 = &ch;
739 ch = 0x22;
740
741 StubDesc = Object_StubDesc;
742 StubDesc.pFormatTypes = fmtstr_ref_unique_out;
743
745 &RpcMessage,
746 &StubMsg,
747 &StubDesc,
748 0);
749
750 StubMsg.BufferLength = 0;
751 NdrPointerBufferSize( &StubMsg,
752 (unsigned char *)p1,
753 &fmtstr_ref_unique_out[4] );
754
755 /* Windows overestimates the buffer size */
756 ok(StubMsg.BufferLength >= 5, "length %d\n", StubMsg.BufferLength);
757
758 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
759 StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
760 StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
761
762 ptr = NdrPointerMarshall( &StubMsg, (unsigned char *)p1, &fmtstr_ref_unique_out[4] );
763 ok(ptr == NULL, "ret %p\n", ptr);
764 size = StubMsg.Buffer - StubMsg.BufferStart;
765 ok(size == 5, "Buffer %p Start %p len %d\n", StubMsg.Buffer, StubMsg.BufferStart, size);
766 ok(*(unsigned int *)StubMsg.BufferStart != 0, "pointer ID marshalled incorrectly\n");
767 ok(*(unsigned char *)(StubMsg.BufferStart + 4) == 0x22, "char data marshalled incorrectly: 0x%x\n",
768 *(unsigned char *)(StubMsg.BufferStart + 4));
769
770 StubMsg.Buffer = StubMsg.BufferStart;
771 StubMsg.MemorySize = 0;
772 mem = NULL;
773
774 /* Client */
775 my_alloc_called = 0;
776 StubMsg.Buffer = StubMsg.BufferStart;
777 mem = mem_orig = HeapAlloc(GetProcessHeap(), 0, sizeof(void *));
778 *(void **)mem = NULL;
779 NdrPointerUnmarshall( &StubMsg, &mem, &fmtstr_ref_unique_out[4], 0);
780 ok(mem == mem_orig, "mem alloced\n");
781 ok(my_alloc_called == 1, "alloc called %d\n", my_alloc_called);
782
783 my_alloc_called = 0;
784 StubMsg.Buffer = StubMsg.BufferStart;
785 NdrPointerUnmarshall( &StubMsg, &mem, &fmtstr_ref_unique_out[4], 1);
786 ok(mem == mem_orig, "mem alloced\n");
787 ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
788
789 my_free_called = 0;
790 StubMsg.Buffer = StubMsg.BufferStart;
791 NdrPointerFree( &StubMsg, mem, &fmtstr_ref_unique_out[4] );
792 ok(my_free_called == 1, "free called %d\n", my_free_called);
793
794 mem = my_alloc(sizeof(void *));
795 *(void **)mem = NULL;
796 my_free_called = 0;
797 StubMsg.Buffer = StubMsg.BufferStart;
798 NdrPointerFree( &StubMsg, mem, &fmtstr_ref_unique_out[4] );
799 ok(my_free_called == 0, "free called %d\n", my_free_called);
800 my_free(mem);
801
802 mem = my_alloc(sizeof(void *));
803 *(void **)mem = my_alloc(sizeof(char));
804 my_free_called = 0;
805 StubMsg.Buffer = StubMsg.BufferStart;
806 NdrPointerFree( &StubMsg, mem, &fmtstr_ref_unique_out[4] );
807 ok(my_free_called == 1, "free called %d\n", my_free_called);
808 my_free(mem);
809
810 /* Server */
811 my_alloc_called = 0;
812 my_free_called = 0;
813 StubMsg.IsClient = 0;
814 mem = NULL;
815 StubMsg.Buffer = StubMsg.BufferStart;
816 NdrPointerUnmarshall( &StubMsg, &mem, &fmtstr_ref_unique_out[4], 0);
817 ok(mem != StubMsg.BufferStart, "mem pointing at buffer\n");
818 ok(my_alloc_called == 1, "alloc called %d\n", my_alloc_called);
819 NdrPointerFree( &StubMsg, mem, &fmtstr_ref_unique_out[4] );
820 ok(my_free_called == 0, "free called %d\n", my_free_called);
821 my_free(mem);
822
823 my_alloc_called = 0;
824 my_free_called = 0;
825 mem = NULL;
826 StubMsg.Buffer = StubMsg.BufferStart;
827 NdrPointerUnmarshall( &StubMsg, &mem, &fmtstr_ref_unique_out[4], 1);
828 ok(mem != StubMsg.BufferStart, "mem pointing at buffer\n");
829 ok(my_alloc_called == 1, "alloc called %d\n", my_alloc_called);
830 NdrPointerFree( &StubMsg, mem, &fmtstr_ref_unique_out[4] );
831 ok(my_free_called == 0, "free called %d\n", my_free_called);
832 my_free(mem);
833
834 my_alloc_called = 0;
835 mem = mem_orig;
836 *(void **)mem = NULL;
837 StubMsg.Buffer = StubMsg.BufferStart;
838 NdrPointerUnmarshall( &StubMsg, &mem, &fmtstr_ref_unique_out[4], 0);
839 ok(mem == mem_orig, "mem alloced\n");
840 ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
841
842 my_alloc_called = 0;
843 mem = mem_orig;
844 *(void **)mem = NULL;
845 StubMsg.Buffer = StubMsg.BufferStart;
846 NdrPointerUnmarshall( &StubMsg, &mem, &fmtstr_ref_unique_out[4], 1);
847 ok(mem == mem_orig, "mem alloced\n");
848 ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
849
850 mem = my_alloc(sizeof(void *));
851 *(void **)mem = NULL;
852 my_free_called = 0;
853 StubMsg.Buffer = StubMsg.BufferStart;
854 NdrPointerFree( &StubMsg, mem, &fmtstr_ref_unique_out[4] );
855 ok(my_free_called == 0, "free called %d\n", my_free_called);
856 my_free(mem);
857
858 mem = my_alloc(sizeof(void *));
859 *(void **)mem = my_alloc(sizeof(char));
860 my_free_called = 0;
861 StubMsg.Buffer = StubMsg.BufferStart;
862 NdrPointerFree( &StubMsg, mem, &fmtstr_ref_unique_out[4] );
863 ok(my_free_called == 1, "free called %d\n", my_free_called);
864 my_free(mem);
865
866 HeapFree(GetProcessHeap(), 0, mem_orig);
867 HeapFree(GetProcessHeap(), 0, StubMsg.RpcMsg->Buffer);
868}
869
870static void test_simple_struct_marshal(const unsigned char *formattypes,
871 void *memsrc, DWORD srcsize,
872 const void *wiredata,
873 ULONG wiredatalen,
874 int(*cmp)(const void*,const void*,size_t),
875 int num_additional_allocs,
876 const char *msgpfx)
877{
878 RPC_MESSAGE RpcMessage;
879 MIDL_STUB_MESSAGE StubMsg;
880 MIDL_STUB_DESC StubDesc;
881 DWORD size;
882 void *ptr;
883 unsigned char *mem, *mem_orig;
884
886 if(!cmp)
887 cmp = memcmp;
888
889 StubDesc = Object_StubDesc;
890 StubDesc.pFormatTypes = formattypes;
891
892 NdrClientInitializeNew(&RpcMessage, &StubMsg, &StubDesc, 0);
893
894 StubMsg.BufferLength = 0;
895 NdrSimpleStructBufferSize( &StubMsg, memsrc, formattypes );
896 ok(StubMsg.BufferLength >= wiredatalen, "%s: length %d\n", msgpfx, StubMsg.BufferLength);
897 StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
898 StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
899 ptr = NdrSimpleStructMarshall( &StubMsg, memsrc, formattypes );
900 ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
901 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart);
902 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));
903
904 StubMsg.Buffer = StubMsg.BufferStart;
905 StubMsg.MemorySize = 0;
906 size = NdrSimpleStructMemorySize( &StubMsg, formattypes );
907 ok(size == StubMsg.MemorySize, "%s: size != MemorySize\n", msgpfx);
908 ok(size == srcsize, "%s: mem size %u\n", msgpfx, size);
909 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart);
910
911 StubMsg.Buffer = StubMsg.BufferStart;
912 size = NdrSimpleStructMemorySize( &StubMsg, formattypes );
913 ok(size == StubMsg.MemorySize, "%s: size != MemorySize\n", msgpfx);
914 ok(StubMsg.MemorySize == ((srcsize + 3) & ~3) + srcsize, "%s: mem size %u\n", msgpfx, size);
915 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart);
916 size = srcsize;
917 /*** Unmarshalling first with must_alloc false ***/
918
919 StubMsg.Buffer = StubMsg.BufferStart;
920 StubMsg.MemorySize = 0;
921 mem_orig = mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, srcsize);
922 ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, 0 );
923 ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
924 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart);
925 ok(mem == mem_orig, "%s: mem has changed %p %p\n", msgpfx, mem, mem_orig);
926 ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx);
927 ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
928 my_alloc_called = 0;
929 my_free_called = 0;
930 ok(StubMsg.MemorySize == 0, "%s: memorysize touched in unmarshal\n", msgpfx);
931 NdrSimpleStructFree(&StubMsg, mem, formattypes );
932 ok(my_free_called == num_additional_allocs, "free called %d\n", my_free_called);
933
934 /* If we're a server we still use the supplied memory */
935 StubMsg.Buffer = StubMsg.BufferStart;
936 StubMsg.IsClient = 0;
937 ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, 0 );
938 ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
939 ok(mem == mem_orig, "%s: mem has changed %p %p\n", msgpfx, mem, mem_orig);
940 ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx);
941 ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
942 my_alloc_called = 0;
943 my_free_called = 0;
944 ok(StubMsg.MemorySize == 0, "%s: memorysize touched in unmarshal\n", msgpfx);
945 NdrSimpleStructFree(&StubMsg, mem, formattypes );
946 ok(my_free_called == num_additional_allocs, "free called %d\n", my_free_called);
947
948 /* ...unless we pass a NULL ptr, then the buffer is used.
949 Passing a NULL ptr while we're a client && !must_alloc
950 crashes on Windows, so we won't do that. */
951
952 if (0) /* crashes on Win9x and NT4 */
953 {
954 mem = NULL;
955 StubMsg.IsClient = 0;
956 StubMsg.Buffer = StubMsg.BufferStart;
957 ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, FALSE );
958 ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr);
959 ok(mem == StubMsg.BufferStart, "%s: mem not equal buffer\n", msgpfx);
960 ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx);
961 ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
962 my_alloc_called = 0;
963 ok(StubMsg.MemorySize == 0, "%s: memorysize touched in unmarshal\n", msgpfx);
964 NdrSimpleStructFree(&StubMsg, mem, formattypes );
965 ok(my_free_called == num_additional_allocs, "free called %d\n", my_free_called);
966 }
967
968 /*** now must_alloc is true ***/
969
970 /* with must_alloc set we always allocate new memory whether or not we're
971 a server and also when passing NULL */
972 mem = mem_orig;
973 StubMsg.IsClient = 1;
974 StubMsg.Buffer = StubMsg.BufferStart;
975 ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, 1 );
976 ok(ptr == NULL, "ret %p\n", ptr);
977 ok(mem != mem_orig, "mem not changed %p %p\n", mem, mem_orig);
978 ok(!cmp(mem, memsrc, srcsize), "incorrectly unmarshaled\n");
979 ok(my_alloc_called == num_additional_allocs + 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
980 my_alloc_called = 0;
981 my_free_called = 0;
982 ok(StubMsg.MemorySize == 0, "memorysize touched in unmarshal\n");
983 NdrSimpleStructFree(&StubMsg, mem, formattypes );
984 ok(my_free_called == num_additional_allocs, "free called %d\n", my_free_called);
985 my_free(mem);
986
987 mem = NULL;
988 StubMsg.Buffer = StubMsg.BufferStart;
989 ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, 1 );
990 ok(ptr == NULL, "ret %p\n", ptr);
991 ok(mem != mem_orig, "mem not changed %p %p\n", mem, mem_orig);
992 ok(!cmp(mem, memsrc, srcsize), "incorrectly unmarshaled\n");
993 ok(my_alloc_called == num_additional_allocs + 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
994 my_alloc_called = 0;
995 my_free_called = 0;
996 ok(StubMsg.MemorySize == 0, "memorysize touched in unmarshal\n");
997 NdrSimpleStructFree(&StubMsg, mem, formattypes );
998 ok(my_free_called == num_additional_allocs, "free called %d\n", my_free_called);
999 my_free(mem);
1000
1001 mem = mem_orig;
1002 StubMsg.Buffer = StubMsg.BufferStart;
1003 StubMsg.IsClient = 0;
1004 StubMsg.ReuseBuffer = 1;
1005 ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, 1 );
1006 ok(ptr == NULL, "ret %p\n", ptr);
1007 ok(mem != mem_orig, "mem not changed %p %p\n", mem, mem_orig);
1008 ok(mem != StubMsg.BufferStart, "mem is buffer mem\n");
1009 ok(!cmp(mem, memsrc, srcsize), "incorrectly unmarshaled\n");
1010 ok(my_alloc_called == num_additional_allocs + 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
1011 my_alloc_called = 0;
1012 my_free_called = 0;
1013 ok(StubMsg.MemorySize == 0, "memorysize touched in unmarshal\n");
1014 NdrSimpleStructFree(&StubMsg, mem, formattypes );
1015 ok(my_free_called == num_additional_allocs, "free called %d\n", my_free_called);
1016 my_free(mem);
1017
1018 mem = NULL;
1019 StubMsg.Buffer = StubMsg.BufferStart;
1020 StubMsg.IsClient = 0;
1021 StubMsg.ReuseBuffer = 1;
1022 ptr = NdrSimpleStructUnmarshall( &StubMsg, &mem, formattypes, 1 );
1023 ok(ptr == NULL, "ret %p\n", ptr);
1024 ok(mem != StubMsg.BufferStart, "mem is buffer mem\n");
1025 ok(!cmp(mem, memsrc, srcsize), "incorrectly unmarshaled\n");
1026 ok(my_alloc_called == num_additional_allocs + 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called);
1027 my_alloc_called = 0;
1028 my_free_called = 0;
1029 ok(StubMsg.MemorySize == 0, "memorysize touched in unmarshal\n");
1030 NdrSimpleStructFree(&StubMsg, mem, formattypes );
1031 ok(my_free_called == num_additional_allocs, "free called %d\n", my_free_called);
1032 my_free(mem);
1033
1034 HeapFree(GetProcessHeap(), 0, mem_orig);
1035 HeapFree(GetProcessHeap(), 0, StubMsg.BufferStart);
1036}
1037
1038typedef struct
1039{
1042 char *pc1;
1043} ps1_t;
1044
1045static int ps1_cmp(const void *s1, const void *s2, size_t num)
1046{
1047 const ps1_t *p1, *p2;
1048
1049 p1 = s1;
1050 p2 = s2;
1051
1052 if(p1->l1 != p2->l1)
1053 return 1;
1054
1055 if(p1->pl1 && p2->pl1)
1056 {
1057 if(*p1->pl1 != *p2->pl1)
1058 return 1;
1059 }
1060 else if(p1->pl1 || p2->pl1)
1061 return 1;
1062
1063 if(p1->pc1 && p2->pc1)
1064 {
1065 if(*p1->pc1 != *p2->pc1)
1066 return 1;
1067 }
1068 else if(p1->pc1 || p2->pc1)
1069 return 1;
1070
1071 return 0;
1072}
1073
1074static void test_simple_struct(void)
1075{
1076 unsigned char wiredata[28];
1077 ULONG wiredatalen;
1078 LONG l;
1079 char c;
1080 ps1_t ps1;
1081
1082 static const unsigned char fmtstr_simple_struct[] =
1083 {
1084 0x12, 0x0, /* FC_UP */
1085 NdrFcShort( 0x2 ), /* Offset=2 */
1086 0x15, 0x3, /* FC_STRUCT [align 4] */
1087 NdrFcShort( 0x18 ), /* [size 24] */
1088 0x6, /* FC_SHORT */
1089 0x2, /* FC_CHAR */
1090 0x38, /* FC_ALIGNM4 */
1091 0x8, /* FC_LONG */
1092 0x8, /* FC_LONG */
1093 0x39, /* FC_ALIGNM8 */
1094 0xb, /* FC_HYPER */
1095 0x5b, /* FC_END */
1096 };
1097 struct {
1098 short s;
1099 char c;
1100 LONG l1, l2;
1101 LONGLONG ll;
1102 } s1;
1103
1104 static const unsigned char fmtstr_pointer_struct[] =
1105 {
1106 0x12, 0x0, /* FC_UP */
1107 NdrFcShort( 0x2 ), /* Offset=2 */
1108#ifdef _WIN64
1109 0x1a, /* FC_BOGUS_STRUCT */
1110 0x3, /* 3 */
1111 NdrFcShort(0x18), /* [size 24] */
1112 NdrFcShort(0x0),
1113 NdrFcShort(0x8), /* Offset= 8 (266) */
1114 0x08, /* FC_LONG */
1115 0x39, /* FC_ALIGNM8 */
1116 0x36, /* FC_POINTER */
1117 0x36, /* FC_POINTER */
1118 0x5c, /* FC_PAD */
1119 0x5b, /* FC_END */
1120 0x12, 0x8, /* FC_UP [simple_pointer] */
1121 0x08, /* FC_LONG */
1122 0x5c, /* FC_PAD */
1123 0x12, 0x8, /* FC_UP [simple_pointer] */
1124 0x02, /* FC_CHAR */
1125 0x5c, /* FC_PAD */
1126#else
1127 0x16, 0x3, /* FC_PSTRUCT [align 4] */
1128 NdrFcShort( 0xc ), /* [size 12] */
1129 0x4b, /* FC_PP */
1130 0x5c, /* FC_PAD */
1131 0x46, /* FC_NO_REPEAT */
1132 0x5c, /* FC_PAD */
1133 NdrFcShort( 0x4 ), /* 4 */
1134 NdrFcShort( 0x4 ), /* 4 */
1135 0x13, 0x8, /* FC_OP [simple_pointer] */
1136 0x8, /* FC_LONG */
1137 0x5c, /* FC_PAD */
1138 0x46, /* FC_NO_REPEAT */
1139 0x5c, /* FC_PAD */
1140 NdrFcShort( 0x8 ), /* 8 */
1141 NdrFcShort( 0x8 ), /* 8 */
1142 0x13, 0x8, /* FC_OP [simple_pointer] */
1143 0x2, /* FC_CHAR */
1144 0x5c, /* FC_PAD */
1145 0x5b, /* FC_END */
1146 0x8, /* FC_LONG */
1147 0x8, /* FC_LONG */
1148 0x8, /* FC_LONG */
1149 0x5c, /* FC_PAD */
1150 0x5b, /* FC_END */
1151#endif
1152 };
1153
1154 /* zero the entire structure, including the holes */
1155 memset(&s1, 0, sizeof(s1));
1156
1157 /* FC_STRUCT */
1158 s1.s = 0x1234;
1159 s1.c = 0xa5;
1160 s1.l1 = 0xdeadbeef;
1161 s1.l2 = 0xcafebabe;
1162 s1.ll = ((ULONGLONG) 0xbadefeed << 32) | 0x2468ace0;
1163
1164 wiredatalen = 24;
1165 memcpy(wiredata, &s1, wiredatalen);
1166 test_simple_struct_marshal(fmtstr_simple_struct + 4, &s1, 24, wiredata, 24, NULL, 0, "struct");
1167
1168 if (use_pointer_ids)
1169 *(unsigned int *)wiredata = 0x20000;
1170 else
1171 *(unsigned int *)wiredata = (UINT_PTR)&s1;
1172 memcpy(wiredata + 4, &s1, wiredatalen);
1173 test_pointer_marshal(fmtstr_simple_struct, &s1, 24, wiredata, 28, NULL, 0, "struct");
1174
1175 if (sizeof(void *) == 8) return; /* it cannot be represented as a simple struct on Win64 */
1176
1177 /* zero the entire structure, including the hole */
1178 memset(&ps1, 0, sizeof(ps1));
1179
1180 /* FC_PSTRUCT */
1181 ps1.l1 = 0xdeadbeef;
1182 l = 0xcafebabe;
1183 ps1.pl1 = &l;
1184 c = 'a';
1185 ps1.pc1 = &c;
1186 *(unsigned int *)(wiredata + 4) = 0xdeadbeef;
1187 if (use_pointer_ids)
1188 {
1189 *(unsigned int *)(wiredata + 8) = 0x20000;
1190 *(unsigned int *)(wiredata + 12) = 0x20004;
1191 }
1192 else
1193 {
1194 *(unsigned int *)(wiredata + 8) = (UINT_PTR)&l;
1195 *(unsigned int *)(wiredata + 12) = (UINT_PTR)&c;
1196 }
1197 memcpy(wiredata + 16, &l, 4);
1198 memcpy(wiredata + 20, &c, 1);
1199
1200 test_simple_struct_marshal(fmtstr_pointer_struct + 4, &ps1, 17, wiredata + 4, 17, ps1_cmp, 2, "pointer_struct");
1201 if (use_pointer_ids)
1202 {
1203 *(unsigned int *)wiredata = 0x20000;
1204 *(unsigned int *)(wiredata + 8) = 0x20004;
1205 *(unsigned int *)(wiredata + 12) = 0x20008;
1206 }
1207 else
1208 *(unsigned int *)wiredata = (UINT_PTR)&ps1;
1209 test_pointer_marshal(fmtstr_pointer_struct, &ps1, 17, wiredata, 21, ps1_cmp, 2, "pointer_struct");
1210}
1211
1213{
1214 int a;
1216};
1217
1218static void test_struct_align(void)
1219{
1220 RPC_MESSAGE RpcMessage;
1221 MIDL_STUB_MESSAGE StubMsg;
1222 MIDL_STUB_DESC StubDesc;
1223 void *ptr;
1224 struct aligned *memsrc_orig, *memsrc, *mem;
1225
1226 /* force bogus struct so that members are marshalled individually */
1227 static const unsigned char fmtstr[] =
1228 {
1229 0x1a, /* FC_BOGUS_STRUCT */
1230 0x7, /* alignment 8 */
1231 NdrFcShort(0x10), /* memory size 16 */
1232 NdrFcShort(0x0),
1233 NdrFcShort(0x0),
1234 0x08, /* FC_LONG */
1235 0x39, /* FC_ALIGNM8 */
1236 0x0b, /* FC_HYPER */
1237 0x5b, /* FC_END */
1238 };
1239
1240 memsrc_orig = heap_alloc_zero(sizeof(struct aligned) + 8);
1241 /* intentionally mis-align memsrc */
1242 memsrc = (struct aligned *)((((ULONG_PTR)memsrc_orig + 7) & ~7) + 4);
1243
1244 memsrc->a = 0xdeadbeef;
1245 memsrc->b = ((ULONGLONG) 0xbadefeed << 32) | 0x2468ace0;
1246
1247 StubDesc = Object_StubDesc;
1248 StubDesc.pFormatTypes = fmtstr;
1249 NdrClientInitializeNew(&RpcMessage, &StubMsg, &StubDesc, 0);
1250
1251 StubMsg.BufferLength = 0;
1252 NdrComplexStructBufferSize(&StubMsg, (unsigned char *)memsrc, fmtstr);
1253
1254 StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = heap_alloc(StubMsg.BufferLength);
1255 StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
1256
1257 ptr = NdrComplexStructMarshall(&StubMsg, (unsigned char *)memsrc, fmtstr);
1258 ok(ptr == NULL, "ret %p\n", ptr);
1259
1260 /* Server */
1261 StubMsg.IsClient = 0;
1262 mem = NULL;
1263 StubMsg.Buffer = StubMsg.BufferStart;
1264 ptr = NdrComplexStructUnmarshall(&StubMsg, (unsigned char **)&mem, fmtstr, 0);
1265 ok(ptr == NULL, "ret %p\n", ptr);
1266 ok(!memcmp(mem, memsrc, sizeof(*memsrc)), "struct wasn't unmarshalled correctly\n");
1267 StubMsg.pfnFree(mem);
1268
1269 heap_free(StubMsg.RpcMsg->Buffer);
1270 heap_free(memsrc_orig);
1271}
1272
1274{
1277};
1278
1280{
1281 return CONTAINING_RECORD(iface, struct testiface, IPersist_iface);
1282}
1283
1285{
1286 if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IPersist))
1287 {
1288 *out = iface;
1289 IPersist_AddRef(iface);
1290 return S_OK;
1291 }
1292
1293 *out = NULL;
1294 return E_NOINTERFACE;
1295}
1296
1298{
1299 struct testiface *unk = impl_from_IPersist(iface);
1300 return ++unk->ref;
1301}
1302
1304{
1305 struct testiface *unk = impl_from_IPersist(iface);
1306 return --unk->ref;
1307}
1308
1310{
1312 return S_OK;
1313}
1314
1315static IPersistVtbl testiface_vtbl = {
1320};
1321
1322static void test_iface_ptr(void)
1323{
1324 struct testiface server_obj = {{&testiface_vtbl}, 1};
1325 struct testiface client_obj = {{&testiface_vtbl}, 1};
1326
1327 MIDL_STUB_MESSAGE StubMsg;
1328 MIDL_STUB_DESC StubDesc;
1329 RPC_MESSAGE RpcMessage;
1330 IPersist *proxy;
1331 HRESULT hr;
1332 GUID clsid;
1333 void *ptr;
1334 LONG ref;
1335
1336 static const unsigned char fmtstr_ip[] =
1337 {
1338 FC_IP,
1340 NdrFcLong(0x0000010c),
1341 NdrFcShort(0x0000),
1342 NdrFcShort(0x0000),
1343 0xc0,
1344 0x00,
1345 0x00,
1346 0x00,
1347 0x00,
1348 0x00,
1349 0x00,
1350 0x46,
1351 };
1352
1354
1355 StubDesc = Object_StubDesc;
1356 StubDesc.pFormatTypes = fmtstr_ip;
1357
1358 NdrClientInitializeNew(&RpcMessage, &StubMsg, &StubDesc, 0);
1359 StubMsg.BufferLength = 0;
1360 NdrInterfacePointerBufferSize(&StubMsg, (unsigned char *)&client_obj.IPersist_iface, fmtstr_ip);
1361
1362 StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
1363 StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
1364
1365 /* server -> client */
1366
1367 StubMsg.IsClient = 0;
1369 StubMsg.Buffer = StubMsg.BufferStart;
1370 IPersist_AddRef(&server_obj.IPersist_iface);
1371 ptr = NdrInterfacePointerMarshall(&StubMsg, (unsigned char *)&server_obj.IPersist_iface, fmtstr_ip);
1372 ok(!ptr, "ret %p\n", ptr);
1373 ok(server_obj.ref > 2, "got %d references\n", server_obj.ref);
1374 ok(!my_alloc_called, "alloc called %d\n", my_alloc_called);
1375 ok(!my_free_called, "free called %d\n", my_free_called);
1376
1377 NdrInterfacePointerFree(&StubMsg, (unsigned char *)&server_obj.IPersist_iface, fmtstr_ip);
1378 ok(server_obj.ref > 1, "got %d references\n", server_obj.ref);
1379
1380 StubMsg.IsClient = 1;
1382 StubMsg.Buffer = StubMsg.BufferStart;
1383 proxy = NULL;
1384 ptr = NdrInterfacePointerUnmarshall(&StubMsg, (unsigned char **)&proxy, fmtstr_ip, 0);
1385 ok(!ptr, "ret %p\n", ptr);
1386 ok(!!proxy, "mem not alloced\n");
1387 ok(!my_alloc_called, "alloc called %d\n", my_alloc_called);
1388 ok(!my_free_called, "free called %d\n", my_free_called);
1389 ok(server_obj.ref > 1, "got %d references\n", server_obj.ref);
1390
1391 hr = IPersist_GetClassID(proxy, &clsid);
1392 ok(hr == S_OK, "got hr %#x\n", hr);
1393 ok(IsEqualGUID(&clsid, &IID_IPersist), "wrong clsid %s\n", wine_dbgstr_guid(&clsid));
1394
1395 ref = IPersist_Release(proxy);
1396 ok(ref == 1, "got %d references\n", ref);
1397 ok(server_obj.ref == 1, "got %d references\n", server_obj.ref);
1398
1399 /* An existing interface pointer is released; this is necessary so that an
1400 * [in, out] pointer which changes does not leak references. */
1401
1402 StubMsg.IsClient = 0;
1404 StubMsg.Buffer = StubMsg.BufferStart;
1405 IPersist_AddRef(&server_obj.IPersist_iface);
1406 ptr = NdrInterfacePointerMarshall(&StubMsg, (unsigned char *)&server_obj.IPersist_iface, fmtstr_ip);
1407 ok(!ptr, "ret %p\n", ptr);
1408 ok(server_obj.ref > 2, "got %d references\n", server_obj.ref);
1409 ok(!my_alloc_called, "alloc called %d\n", my_alloc_called);
1410 ok(!my_free_called, "free called %d\n", my_free_called);
1411
1412 NdrInterfacePointerFree(&StubMsg, (unsigned char *)&server_obj.IPersist_iface, fmtstr_ip);
1413 ok(server_obj.ref > 1, "got %d references\n", server_obj.ref);
1414
1415 StubMsg.IsClient = 1;
1417 StubMsg.Buffer = StubMsg.BufferStart;
1418 proxy = &client_obj.IPersist_iface;
1419 IPersist_AddRef(proxy);
1420 ptr = NdrInterfacePointerUnmarshall(&StubMsg, (unsigned char **)&proxy, fmtstr_ip, 0);
1421 ok(!ptr, "ret %p\n", ptr);
1422 ok(!!proxy && proxy != &client_obj.IPersist_iface, "mem not alloced\n");
1423 ok(!my_alloc_called, "alloc called %d\n", my_alloc_called);
1424 ok(!my_free_called, "free called %d\n", my_free_called);
1425 ok(server_obj.ref > 1, "got %d references\n", server_obj.ref);
1426 ok(client_obj.ref == 1, "got %d references\n", client_obj.ref);
1427
1428 hr = IPersist_GetClassID(proxy, &clsid);
1429 ok(hr == S_OK, "got hr %#x\n", hr);
1430 ok(IsEqualGUID(&clsid, &IID_IPersist), "wrong clsid %s\n", wine_dbgstr_guid(&clsid));
1431
1432 ref = IPersist_Release(proxy);
1433 ok(ref == 1, "got %d references\n", ref);
1434 ok(server_obj.ref == 1, "got %d references\n", server_obj.ref);
1435
1436 /* client -> server */
1437
1438 StubMsg.IsClient = 1;
1440 StubMsg.Buffer = StubMsg.BufferStart;
1441 IPersist_AddRef(&client_obj.IPersist_iface);
1442 ptr = NdrInterfacePointerMarshall(&StubMsg, (unsigned char *)&client_obj.IPersist_iface, fmtstr_ip);
1443 ok(!ptr, "ret %p\n", ptr);
1444 ok(client_obj.ref > 2, "got %d references\n", client_obj.ref);
1445 ok(!my_alloc_called, "alloc called %d\n", my_alloc_called);
1446 ok(!my_free_called, "free called %d\n", my_free_called);
1447
1448 StubMsg.IsClient = 0;
1450 StubMsg.Buffer = StubMsg.BufferStart;
1451 proxy = NULL;
1452 ptr = NdrInterfacePointerUnmarshall(&StubMsg, (unsigned char **)&proxy, fmtstr_ip, 0);
1453 ok(!ptr, "ret %p\n", ptr);
1454 ok(!!proxy, "mem not alloced\n");
1455 ok(!my_alloc_called, "alloc called %d\n", my_alloc_called);
1456 ok(!my_free_called, "free called %d\n", my_free_called);
1457 ok(client_obj.ref > 2, "got %d references\n", client_obj.ref);
1458
1459 hr = IPersist_GetClassID(proxy, &clsid);
1460 ok(hr == S_OK, "got hr %#x\n", hr);
1461 ok(IsEqualGUID(&clsid, &IID_IPersist), "wrong clsid %s\n", wine_dbgstr_guid(&clsid));
1462
1463 ref = IPersist_Release(proxy);
1464 ok(client_obj.ref > 1, "got %d references\n", client_obj.ref);
1465 ok(ref == client_obj.ref, "expected %d references, got %d\n", client_obj.ref, ref);
1466
1467 NdrInterfacePointerFree(&StubMsg, (unsigned char *)proxy, fmtstr_ip);
1468 ok(client_obj.ref == 1, "got %d references\n", client_obj.ref);
1469
1470 /* same, but free the interface after calling NdrInterfacePointerFree */
1471
1472 StubMsg.IsClient = 1;
1474 StubMsg.Buffer = StubMsg.BufferStart;
1475 IPersist_AddRef(&client_obj.IPersist_iface);
1476 ptr = NdrInterfacePointerMarshall(&StubMsg, (unsigned char *)&client_obj.IPersist_iface, fmtstr_ip);
1477 ok(!ptr, "ret %p\n", ptr);
1478 ok(client_obj.ref > 2, "got %d references\n", client_obj.ref);
1479 ok(!my_alloc_called, "alloc called %d\n", my_alloc_called);
1480 ok(!my_free_called, "free called %d\n", my_free_called);
1481
1482 StubMsg.IsClient = 0;
1484 StubMsg.Buffer = StubMsg.BufferStart;
1485 proxy = NULL;
1486 ptr = NdrInterfacePointerUnmarshall(&StubMsg, (unsigned char **)&proxy, fmtstr_ip, 0);
1487 ok(!ptr, "ret %p\n", ptr);
1488 ok(!!proxy, "mem not alloced\n");
1489 ok(!my_alloc_called, "alloc called %d\n", my_alloc_called);
1490 ok(!my_free_called, "free called %d\n", my_free_called);
1491 ok(client_obj.ref > 2, "got %d references\n", client_obj.ref);
1492
1493 NdrInterfacePointerFree(&StubMsg, (unsigned char *)proxy, fmtstr_ip);
1494 ok(client_obj.ref > 1, "got %d references\n", client_obj.ref);
1495
1496 hr = IPersist_GetClassID(proxy, &clsid);
1497 ok(hr == S_OK, "got hr %#x\n", hr);
1498 ok(IsEqualGUID(&clsid, &IID_IPersist), "wrong clsid %s\n", wine_dbgstr_guid(&clsid));
1499
1500 ref = IPersist_Release(proxy);
1501 ok(ref == 1, "got %d references\n", ref);
1502 ok(client_obj.ref == 1, "got %d references\n", client_obj.ref);
1503
1504 /* An existing interface pointer is *not* released (in fact, it is ignored
1505 * and may be invalid). In practice it will always be NULL anyway. */
1506
1507 StubMsg.IsClient = 1;
1509 StubMsg.Buffer = StubMsg.BufferStart;
1510 IPersist_AddRef(&client_obj.IPersist_iface);
1511 ptr = NdrInterfacePointerMarshall(&StubMsg, (unsigned char *)&client_obj.IPersist_iface, fmtstr_ip);
1512 ok(!ptr, "ret %p\n", ptr);
1513 ok(client_obj.ref > 2, "got %d references\n", client_obj.ref);
1514 ok(!my_alloc_called, "alloc called %d\n", my_alloc_called);
1515 ok(!my_free_called, "free called %d\n", my_free_called);
1516
1517 StubMsg.IsClient = 0;
1519 StubMsg.Buffer = StubMsg.BufferStart;
1520 proxy = &server_obj.IPersist_iface;
1521 IPersist_AddRef(proxy);
1522 ptr = NdrInterfacePointerUnmarshall(&StubMsg, (unsigned char **)&proxy, fmtstr_ip, 0);
1523 ok(!ptr, "ret %p\n", ptr);
1524 ok(!!proxy && proxy != &server_obj.IPersist_iface, "mem not alloced\n");
1525 ok(!my_alloc_called, "alloc called %d\n", my_alloc_called);
1526 ok(!my_free_called, "free called %d\n", my_free_called);
1527 ok(client_obj.ref > 2, "got %d references\n", client_obj.ref);
1528 ok(server_obj.ref == 2, "got %d references\n", server_obj.ref);
1529 IPersist_Release(&server_obj.IPersist_iface);
1530
1531 hr = IPersist_GetClassID(proxy, &clsid);
1532 ok(hr == S_OK, "got hr %#x\n", hr);
1533 ok(IsEqualGUID(&clsid, &IID_IPersist), "wrong clsid %s\n", wine_dbgstr_guid(&clsid));
1534
1535 ref = IPersist_Release(proxy);
1536 ok(client_obj.ref > 1, "got %d references\n", client_obj.ref);
1537 ok(ref == client_obj.ref, "expected %d references, got %d\n", client_obj.ref, ref);
1538
1539 NdrInterfacePointerFree(&StubMsg, (unsigned char *)proxy, fmtstr_ip);
1540 ok(client_obj.ref == 1, "got %d references\n", client_obj.ref);
1541
1542 HeapFree(GetProcessHeap(), 0, StubMsg.BufferStart);
1543
1545}
1546
1547static void test_fullpointer_xlat(void)
1548{
1549 PFULL_PTR_XLAT_TABLES pXlatTables;
1550 ULONG RefId;
1551 int ret;
1552 void *Pointer;
1553
1554 pXlatTables = NdrFullPointerXlatInit(2, XLAT_CLIENT);
1555
1556 /* "marshaling" phase */
1557
1558 ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebeef, 1, &RefId);
1559 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1560 ok(RefId == 0x1, "RefId should be 0x1 instead of 0x%x\n", RefId);
1561
1562 ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebeef, 0, &RefId);
1563 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1564 ok(RefId == 0x1, "RefId should be 0x1 instead of 0x%x\n", RefId);
1565
1566 ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebabe, 0, &RefId);
1567 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1568 ok(RefId == 0x2, "RefId should be 0x2 instead of 0x%x\n", RefId);
1569
1570 ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xdeadbeef, 0, &RefId);
1571 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1572 ok(RefId == 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId);
1573
1574 ret = NdrFullPointerQueryPointer(pXlatTables, NULL, 0, &RefId);
1575 ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1576 ok(RefId == 0, "RefId should be 0 instead of 0x%x\n", RefId);
1577
1578 /* "unmarshaling" phase */
1579
1580 ret = NdrFullPointerQueryRefId(pXlatTables, 0x0, 0, &Pointer);
1581 ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1582
1583 ret = NdrFullPointerQueryRefId(pXlatTables, 0x2, 0, &Pointer);
1584 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1585 ok(Pointer == (void *)0xcafebabe, "Pointer should be 0xcafebabe instead of %p\n", Pointer);
1586
1587 ret = NdrFullPointerQueryRefId(pXlatTables, 0x4, 0, &Pointer);
1588 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1589 ok(Pointer == NULL, "Pointer should be NULL instead of %p\n", Pointer);
1590
1591 NdrFullPointerInsertRefId(pXlatTables, 0x4, (void *)0xdeadbabe);
1592
1593 ret = NdrFullPointerQueryRefId(pXlatTables, 0x4, 1, &Pointer);
1594 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1595 ok(Pointer == (void *)0xdeadbabe, "Pointer should be (void *)0xdeadbabe instead of %p\n", Pointer);
1596
1597 NdrFullPointerXlatFree(pXlatTables);
1598
1599 pXlatTables = NdrFullPointerXlatInit(2, XLAT_SERVER);
1600
1601 /* "unmarshaling" phase */
1602
1603 ret = NdrFullPointerQueryRefId(pXlatTables, 0x2, 1, &Pointer);
1604 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1605 ok(Pointer == NULL, "Pointer should be NULL instead of %p\n", Pointer);
1606
1607 NdrFullPointerInsertRefId(pXlatTables, 0x2, (void *)0xcafebabe);
1608
1609 ret = NdrFullPointerQueryRefId(pXlatTables, 0x2, 0, &Pointer);
1610 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1611 ok(Pointer == (void *)0xcafebabe, "Pointer should be (void *)0xcafebabe instead of %p\n", Pointer);
1612
1613 ret = NdrFullPointerQueryRefId(pXlatTables, 0x2, 1, &Pointer);
1614 ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1615 ok(Pointer == (void *)0xcafebabe, "Pointer should be (void *)0xcafebabe instead of %p\n", Pointer);
1616
1617 /* "marshaling" phase */
1618
1619 ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebeef, 1, &RefId);
1620 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1621 ok(RefId == 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId);
1622
1623 ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebeef, 1, &RefId);
1624 ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1625 ok(RefId == 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId);
1626
1627 ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebeef, 0, &RefId);
1628 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1629 ok(RefId == 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId);
1630
1631 ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebabe, 0, &RefId);
1632 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1633 ok(RefId == 0x2, "RefId should be 0x2 instead of 0x%x\n", RefId);
1634
1635 ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xdeadbeef, 0, &RefId);
1636 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1637 ok(RefId == 0x4, "RefId should be 0x4 instead of 0x%x\n", RefId);
1638
1639 /* "freeing" phase */
1640
1641 ret = NdrFullPointerFree(pXlatTables, (void *)0xcafebeef);
1642 ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1643
1644 ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebeef, 0x20, &RefId);
1645 ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1646 ok(RefId == 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId);
1647
1648 ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xcafebeef, 1, &RefId);
1649 ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1650 ok(RefId == 0x3, "RefId should be 0x3 instead of 0x%x\n", RefId);
1651
1652 ret = NdrFullPointerFree(pXlatTables, (void *)0xcafebabe);
1653 ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1654
1655 ret = NdrFullPointerFree(pXlatTables, (void *)0xdeadbeef);
1656 ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1657
1658 ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xdeadbeef, 0x20, &RefId);
1659 ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1660 ok(RefId == 0x4, "RefId should be 0x4 instead of 0x%x\n", RefId);
1661
1662 ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xdeadbeef, 1, &RefId);
1663 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1664 ok(RefId == 0x4, "RefId should be 0x4 instead of 0x%x\n", RefId);
1665
1666 ret = NdrFullPointerQueryPointer(pXlatTables, (void *)0xdeadbeef, 1, &RefId);
1667 ok(ret == 1, "ret should be 1 instead of 0x%x\n", ret);
1668 ok(RefId == 0x4, "RefId should be 0x4 instead of 0x%x\n", RefId);
1669
1670 ret = NdrFullPointerFree(pXlatTables, (void *)0xdeadbeef);
1671 ok(ret == 0, "ret should be 0 instead of 0x%x\n", ret);
1672
1673 NdrFullPointerXlatFree(pXlatTables);
1674}
1675
1676/* verify stub data that is identical between client and server */
1677static void test_common_stub_data( const char *prefix, const MIDL_STUB_MESSAGE *stubMsg )
1678{
1679 void *unset_ptr;
1680
1681 memset(&unset_ptr, 0xcc, sizeof(unset_ptr));
1682
1683#define TEST_ZERO(field, fmt) ok(stubMsg->field == 0, "%s: " #field " should have been set to zero instead of " fmt "\n", prefix, stubMsg->field)
1684#define TEST_POINTER_UNSET(field) ok(stubMsg->field == unset_ptr, "%s: " #field " should have been unset instead of %p\n", prefix, stubMsg->field)
1685#define TEST_ULONG_UNSET(field) ok(stubMsg->field == 0xcccccccc, "%s: " #field " should have been unset instead of 0x%x\n", prefix, stubMsg->field)
1686#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)
1687
1688 TEST_POINTER_UNSET(BufferMark);
1691 TEST_ZERO(pAllocAllNodesContext, "%p");
1692 ok(stubMsg->pPointerQueueState == 0 ||
1693 broken(stubMsg->pPointerQueueState == unset_ptr), /* win2k */
1694 "%s: pPointerQueueState should have been unset instead of %p\n",
1695 prefix, stubMsg->pPointerQueueState);
1696 TEST_ZERO(IgnoreEmbeddedPointers, "%d");
1697 TEST_ZERO(PointerBufferMark, "%p");
1698 ok( stubMsg->uFlags == 0 ||
1699 broken(stubMsg->uFlags == 0xcc), /* win9x */
1700 "%s: uFlags should have been set to zero instead of 0x%x\n", prefix, stubMsg->uFlags );
1701 /* FIXME: UniquePtrCount */
1702 TEST_ULONG_PTR_UNSET(MaxCount);
1704 TEST_ULONG_UNSET(ActualCount);
1705 ok(stubMsg->pfnAllocate == my_alloc, "%s: pfnAllocate should have been %p instead of %p\n",
1706 prefix, my_alloc, stubMsg->pfnAllocate);
1707 ok(stubMsg->pfnFree == my_free, "%s: pfnFree should have been %p instead of %p\n",
1708 prefix, my_free, stubMsg->pfnFree);
1709 TEST_ZERO(StackTop, "%p");
1710 TEST_POINTER_UNSET(pPresentedType);
1711 TEST_POINTER_UNSET(pTransmitType);
1712 TEST_POINTER_UNSET(SavedHandle);
1713 ok(stubMsg->StubDesc == &Object_StubDesc, "%s: StubDesc should have been %p instead of %p\n",
1714 prefix, &Object_StubDesc, stubMsg->StubDesc);
1715 TEST_ZERO(FullPtrRefId, "%d");
1716 ok( stubMsg->PointerLength == 0 ||
1717 broken(stubMsg->PointerLength == 1), /* win9x, nt4 */
1718 "%s: pAsyncMsg should have been set to zero instead of %d\n", prefix, stubMsg->PointerLength );
1719 TEST_ZERO(fInDontFree, "%d");
1720 TEST_ZERO(fDontCallFreeInst, "%d");
1721 ok( stubMsg->fHasReturn == 0 || broken(stubMsg->fHasReturn), /* win9x, nt4 */
1722 "%s: fHasReturn should have been set to zero instead of %d\n", prefix, stubMsg->fHasReturn );
1723 TEST_ZERO(fHasExtensions, "%d");
1724 TEST_ZERO(fHasNewCorrDesc, "%d");
1725 ok(stubMsg->fIsIn == 0 || broken(stubMsg->fIsIn), /* win9x, nt4 */
1726 "%s: fIsIn should have been set to 0 instead of %d\n", prefix, stubMsg->fIsIn);
1727 TEST_ZERO(fIsOicf, "%d");
1728 ok(stubMsg->fBufferValid == 0,
1729 "%s: fBufferValid should have been set to 0 instead of %d\n", prefix, stubMsg->fBufferValid);
1730 TEST_ZERO(fNeedMCCP, "%d");
1731 ok(stubMsg->fUnused == 0 ||
1732 stubMsg->fUnused == -2, /* Vista */
1733 "%s: fUnused should have been set to 0 or -2 instead of %d\n", prefix, stubMsg->fUnused);
1734 ok(stubMsg->fUnused2 == 0xffffcccc, "%s: fUnused2 should have been 0xffffcccc instead of 0x%x\n",
1735 prefix, stubMsg->fUnused2);
1736 ok(stubMsg->dwDestContext == MSHCTX_DIFFERENTMACHINE,
1737 "%s: dwDestContext should have been MSHCTX_DIFFERENTMACHINE instead of %d\n",
1738 prefix, stubMsg->dwDestContext);
1739 TEST_ZERO(pvDestContext, "%p");
1740 TEST_POINTER_UNSET(SavedContextHandles);
1742 TEST_ZERO(pRpcChannelBuffer, "%p");
1743 TEST_ZERO(pArrayInfo, "%p");
1744 TEST_POINTER_UNSET(SizePtrCountArray);
1745 TEST_POINTER_UNSET(SizePtrOffsetArray);
1746 TEST_POINTER_UNSET(SizePtrLengthArray);
1747 TEST_POINTER_UNSET(pArgQueue);
1748 TEST_ZERO(dwStubPhase, "%d");
1749 /* FIXME: where does this value come from? */
1750 trace("%s: LowStackMark is %p\n", prefix, stubMsg->LowStackMark);
1751 ok( stubMsg->pAsyncMsg == 0 || broken(stubMsg->pAsyncMsg == unset_ptr), /* win9x, nt4 */
1752 "%s: pAsyncMsg should have been set to zero instead of %p\n", prefix, stubMsg->pAsyncMsg );
1753 ok( stubMsg->pCorrInfo == 0 || broken(stubMsg->pCorrInfo == unset_ptr), /* win9x, nt4 */
1754 "%s: pCorrInfo should have been set to zero instead of %p\n", prefix, stubMsg->pCorrInfo );
1755 ok( stubMsg->pCorrMemory == 0 || broken(stubMsg->pCorrMemory == unset_ptr), /* win9x, nt4 */
1756 "%s: pCorrMemory should have been set to zero instead of %p\n", prefix, stubMsg->pCorrMemory );
1757 ok( stubMsg->pMemoryList == 0 || broken(stubMsg->pMemoryList == unset_ptr), /* win9x, nt4 */
1758 "%s: pMemoryList should have been set to zero instead of %p\n", prefix, stubMsg->pMemoryList );
1759 TEST_POINTER_UNSET(pCSInfo);
1760 TEST_POINTER_UNSET(ConformanceMark);
1761 TEST_POINTER_UNSET(VarianceMark);
1762 ok(stubMsg->Unused == (ULONG_PTR)unset_ptr, "%s: Unused should have be unset instead of 0x%lx\n",
1763 prefix, stubMsg->Unused);
1764 TEST_POINTER_UNSET(pContext);
1765 TEST_POINTER_UNSET(ContextHandleHash);
1766 TEST_POINTER_UNSET(pUserMarshalList);
1767 TEST_ULONG_PTR_UNSET(Reserved51_3);
1768 TEST_ULONG_PTR_UNSET(Reserved51_4);
1769 TEST_ULONG_PTR_UNSET(Reserved51_5);
1770
1771#undef TEST_ULONG_PTR_UNSET
1772#undef TEST_ULONG_UNSET
1773#undef TEST_POINTER_UNSET
1774#undef TEST_ZERO
1775}
1776
1777static void test_client_init(void)
1778{
1779 MIDL_STUB_MESSAGE stubMsg;
1780 RPC_MESSAGE rpcMsg;
1781 void *unset_ptr;
1782
1783 memset(&rpcMsg, 0xcc, sizeof(rpcMsg));
1784 memset(&stubMsg, 0xcc, sizeof(stubMsg));
1785 memset(&unset_ptr, 0xcc, sizeof(unset_ptr));
1786
1787 NdrClientInitializeNew(&rpcMsg, &stubMsg, &Object_StubDesc, 1);
1788
1789 test_common_stub_data( "NdrClientInitializeNew", &stubMsg );
1790
1791 ok(stubMsg.RpcMsg == &rpcMsg, "stubMsg.RpcMsg should have been %p instead of %p\n", &rpcMsg, stubMsg.RpcMsg);
1792 ok(rpcMsg.Handle == NULL, "rpcMsg.Handle should have been NULL instead of %p\n", rpcMsg.Handle);
1793 ok(rpcMsg.Buffer == unset_ptr, "rpcMsg.Buffer should have been unset instead of %p\n",
1794 rpcMsg.Buffer);
1795 ok(rpcMsg.BufferLength == 0xcccccccc, "rpcMsg.BufferLength should have been unset instead of %d\n", rpcMsg.BufferLength);
1796 ok(rpcMsg.ProcNum == 0x8001, "rpcMsg.ProcNum should have been 0x8001 instead of 0x%x\n", rpcMsg.ProcNum);
1797 ok(rpcMsg.TransferSyntax == unset_ptr, "rpcMsg.TransferSyntax should have been unset instead of %p\n", rpcMsg.TransferSyntax);
1799 "rpcMsg.RpcInterfaceInformation should have been %p instead of %p\n",
1801 /* Note: ReservedForRuntime not tested */
1802 ok(rpcMsg.ManagerEpv == unset_ptr, "rpcMsg.ManagerEpv should have been unset instead of %p\n", rpcMsg.ManagerEpv);
1803 ok(rpcMsg.ImportContext == unset_ptr, "rpcMsg.ImportContext should have been unset instead of %p\n", rpcMsg.ImportContext);
1804 ok(rpcMsg.RpcFlags == 0, "rpcMsg.RpcFlags should have been 0 instead of 0x%x\n", rpcMsg.RpcFlags);
1805
1806 ok(stubMsg.Buffer == unset_ptr, "stubMsg.Buffer should have been unset instead of %p\n",
1807 stubMsg.Buffer);
1808 ok(stubMsg.BufferStart == NULL, "stubMsg.BufferStart should have been NULL instead of %p\n",
1809 stubMsg.BufferStart);
1810 ok(stubMsg.BufferEnd == NULL, "stubMsg.BufferEnd should have been NULL instead of %p\n",
1811 stubMsg.BufferEnd);
1812 ok(stubMsg.BufferLength == 0, "stubMsg.BufferLength should have been 0 instead of %u\n",
1813 stubMsg.BufferLength);
1814 ok(stubMsg.IsClient == 1, "stubMsg.IsClient should have been 1 instead of %u\n", stubMsg.IsClient);
1815 ok(stubMsg.ReuseBuffer == 0, "stubMsg.ReuseBuffer should have been 0 instead of %d\n",
1816 stubMsg.ReuseBuffer);
1817 ok(stubMsg.CorrDespIncrement == 0, "stubMsg.CorrDespIncrement should have been 0 instead of %d\n",
1818 stubMsg.CorrDespIncrement);
1819 ok(stubMsg.FullPtrXlatTables == unset_ptr, "stubMsg.FullPtrXlatTables should have been unset instead of %p\n",
1820 stubMsg.FullPtrXlatTables);
1821}
1822
1823static void test_server_init(void)
1824{
1825 MIDL_STUB_MESSAGE stubMsg;
1826 RPC_MESSAGE rpcMsg;
1827 unsigned char *ret;
1828 unsigned char buffer[256];
1829
1830 memset(&rpcMsg, 0, sizeof(rpcMsg));
1831 rpcMsg.Buffer = buffer;
1832 rpcMsg.BufferLength = sizeof(buffer);
1834
1835 memset(&stubMsg, 0xcc, sizeof(stubMsg));
1836
1837 ret = NdrServerInitializeNew(&rpcMsg, &stubMsg, &Object_StubDesc);
1838 ok(ret == NULL, "NdrServerInitializeNew should have returned NULL instead of %p\n", ret);
1839
1840 test_common_stub_data( "NdrServerInitializeNew", &stubMsg );
1841
1842 ok(stubMsg.RpcMsg == &rpcMsg, "stubMsg.RpcMsg should have been %p instead of %p\n", &rpcMsg, stubMsg.RpcMsg);
1843 ok(stubMsg.Buffer == buffer, "stubMsg.Buffer should have been %p instead of %p\n", buffer, stubMsg.Buffer);
1844 ok(stubMsg.BufferStart == buffer, "stubMsg.BufferStart should have been %p instead of %p\n", buffer, stubMsg.BufferStart);
1845 ok(stubMsg.BufferEnd == buffer + sizeof(buffer), "stubMsg.BufferEnd should have been %p instead of %p\n", buffer + sizeof(buffer), stubMsg.BufferEnd);
1847 ok(stubMsg.BufferLength == 0, "stubMsg.BufferLength should have been 0 instead of %u\n", stubMsg.BufferLength);
1848 ok(stubMsg.IsClient == 0, "stubMsg.IsClient should have been 0 instead of %u\n", stubMsg.IsClient);
1849 ok(stubMsg.ReuseBuffer == 0 ||
1850 broken(stubMsg.ReuseBuffer == 1), /* win2k */
1851 "stubMsg.ReuseBuffer should have been set to zero instead of %d\n", stubMsg.ReuseBuffer);
1852 ok(stubMsg.CorrDespIncrement == 0 ||
1853 broken(stubMsg.CorrDespIncrement == 0xcc), /* <= Win 2003 */
1854 "CorrDespIncrement should have been set to zero instead of 0x%x\n", stubMsg.CorrDespIncrement);
1855 ok(stubMsg.FullPtrXlatTables == 0, "stubMsg.BufferLength should have been 0 instead of %p\n", stubMsg.FullPtrXlatTables);
1856}
1857
1858static void test_ndr_allocate(void)
1859{
1860 RPC_MESSAGE RpcMessage;
1861 MIDL_STUB_MESSAGE StubMsg;
1862 MIDL_STUB_DESC StubDesc;
1863 void *p1, *p2;
1864 struct tag_mem_list_v2_t
1865 {
1866 DWORD magic;
1867 DWORD size;
1868 DWORD unknown;
1869 struct tag_mem_list_v2_t *next;
1870 } *mem_list_v2;
1871 const DWORD magic_MEML = 'M' << 24 | 'E' << 16 | 'M' << 8 | 'L';
1872
1873 StubDesc = Object_StubDesc;
1874 NdrClientInitializeNew(&RpcMessage, &StubMsg, &StubDesc, 0);
1875
1877 p1 = NdrAllocate(&StubMsg, 10);
1878 p2 = NdrAllocate(&StubMsg, 24);
1879 ok(my_alloc_called == 2, "alloc called %d\n", my_alloc_called);
1880 ok(StubMsg.pMemoryList != NULL, "StubMsg.pMemoryList NULL\n");
1881 if(StubMsg.pMemoryList)
1882 {
1883 mem_list_v2 = StubMsg.pMemoryList;
1884 if (mem_list_v2->size == 24)
1885 {
1886 trace("v2 mem list format\n");
1887 ok((char *)mem_list_v2 == (char *)p2 + 24, "expected mem_list_v2 pointer %p, but got %p\n", (char *)p2 + 24, mem_list_v2);
1888 ok(mem_list_v2->magic == magic_MEML, "magic %08x\n", mem_list_v2->magic);
1889 ok(mem_list_v2->size == 24, "wrong size for p2 %d\n", mem_list_v2->size);
1890 ok(mem_list_v2->unknown == 0, "wrong unknown for p2 0x%x\n", mem_list_v2->unknown);
1891 ok(mem_list_v2->next != NULL, "next NULL\n");
1892 mem_list_v2 = mem_list_v2->next;
1893 if(mem_list_v2)
1894 {
1895 ok((char *)mem_list_v2 == (char *)p1 + 16, "expected mem_list_v2 pointer %p, but got %p\n", (char *)p1 + 16, mem_list_v2);
1896 ok(mem_list_v2->magic == magic_MEML, "magic %08x\n", mem_list_v2->magic);
1897 ok(mem_list_v2->size == 16, "wrong size for p1 %d\n", mem_list_v2->size);
1898 ok(mem_list_v2->unknown == 0, "wrong unknown for p1 0x%x\n", mem_list_v2->unknown);
1899 ok(mem_list_v2->next == NULL, "next %p\n", mem_list_v2->next);
1900 }
1901 }
1902 else win_skip("v1 mem list format\n");
1903 }
1904 /* NdrFree isn't exported so we can't test free'ing */
1905 my_free(p1);
1906 my_free(p2);
1907}
1908
1909static void test_conformant_array(void)
1910{
1911 RPC_MESSAGE RpcMessage;
1912 MIDL_STUB_MESSAGE StubMsg;
1913 MIDL_STUB_DESC StubDesc;
1914 void *ptr;
1915 unsigned char *mem, *mem_orig;
1916 unsigned char memsrc[20];
1917 unsigned int i;
1918
1919 static const unsigned char fmtstr_conf_array[] =
1920 {
1921 0x1b, /* FC_CARRAY */
1922 0x0, /* align */
1923 NdrFcShort( 0x1 ), /* elem size */
1924 0x40, /* Corr desc: const */
1925 0x0,
1926 NdrFcShort(0x10), /* const = 0x10 */
1927 0x1, /* FC_BYTE */
1928 0x5b /* FC_END */
1929 };
1930
1931 for (i = 0; i < sizeof(memsrc); i++)
1932 memsrc[i] = i * i;
1933
1934 StubDesc = Object_StubDesc;
1935 StubDesc.pFormatTypes = fmtstr_conf_array;
1936
1938 &RpcMessage,
1939 &StubMsg,
1940 &StubDesc,
1941 0);
1942
1943 StubMsg.BufferLength = 0;
1945 memsrc,
1946 fmtstr_conf_array );
1947 ok(StubMsg.BufferLength >= 20, "length %d\n", StubMsg.BufferLength);
1948
1949 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
1950 StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
1951 StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
1952
1953 ptr = NdrConformantArrayMarshall( &StubMsg, memsrc, fmtstr_conf_array );
1954 ok(ptr == NULL, "ret %p\n", ptr);
1955 ok(StubMsg.Buffer - StubMsg.BufferStart == 20, "Buffer %p Start %p len %d\n", StubMsg.Buffer, StubMsg.BufferStart, 20);
1956 ok(!memcmp(StubMsg.BufferStart + 4, memsrc, 16), "incorrectly marshaled\n");
1957
1958 StubMsg.Buffer = StubMsg.BufferStart;
1959 StubMsg.MemorySize = 0;
1960 mem = NULL;
1961
1962 /* Client */
1963 my_alloc_called = 0;
1964 /* passing mem == NULL with must_alloc == 0 crashes under Windows */
1965 NdrConformantArrayUnmarshall( &StubMsg, &mem, fmtstr_conf_array, 1);
1966 ok(mem != NULL, "mem not alloced\n");
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
1970 my_alloc_called = 0;
1971 StubMsg.Buffer = StubMsg.BufferStart;
1972 mem_orig = mem;
1973 NdrConformantArrayUnmarshall( &StubMsg, &mem, fmtstr_conf_array, 0);
1974 ok(mem == mem_orig, "mem alloced\n");
1975 ok(mem != StubMsg.BufferStart + 4, "mem pointing at buffer\n");
1976 ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
1977
1978 my_alloc_called = 0;
1979 StubMsg.Buffer = StubMsg.BufferStart;
1980 NdrConformantArrayUnmarshall( &StubMsg, &mem, fmtstr_conf_array, 1);
1981 ok(mem != mem_orig, "mem not alloced\n");
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
1985 my_free_called = 0;
1986 StubMsg.Buffer = StubMsg.BufferStart;
1987 NdrConformantArrayFree( &StubMsg, mem, fmtstr_conf_array );
1988 ok(my_free_called == 0, "free called %d\n", my_free_called);
1989 StubMsg.pfnFree(mem);
1990
1991 /* Server */
1992 my_alloc_called = 0;
1993 StubMsg.IsClient = 0;
1994 mem = NULL;
1995 StubMsg.Buffer = StubMsg.BufferStart;
1996 NdrConformantArrayUnmarshall( &StubMsg, &mem, fmtstr_conf_array, 0);
1997 ok(mem == StubMsg.BufferStart + 4 || broken(!mem), /* win9x, nt4 */
1998 "mem not pointing at buffer %p/%p\n", mem, StubMsg.BufferStart + 4);
1999 ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2000 my_alloc_called = 0;
2001 mem = NULL;
2002 StubMsg.Buffer = StubMsg.BufferStart;
2003 NdrConformantArrayUnmarshall( &StubMsg, &mem, fmtstr_conf_array, 1);
2004 ok(mem != StubMsg.BufferStart + 4, "mem pointing at buffer\n");
2005 ok(my_alloc_called == 1, "alloc called %d\n", my_alloc_called);
2006 StubMsg.pfnFree(mem);
2007
2008 my_alloc_called = 0;
2009 mem = mem_orig;
2010 StubMsg.Buffer = StubMsg.BufferStart;
2011 NdrConformantArrayUnmarshall( &StubMsg, &mem, fmtstr_conf_array, 0);
2012 ok(mem == mem_orig, "mem alloced\n");
2013 ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2014
2015 my_alloc_called = 0;
2016 mem = mem_orig;
2017 StubMsg.Buffer = StubMsg.BufferStart;
2018 NdrConformantArrayUnmarshall( &StubMsg, &mem, fmtstr_conf_array, 1);
2019 ok(mem != StubMsg.BufferStart + 4, "mem pointing at buffer\n");
2020 ok(my_alloc_called == 1, "alloc called %d\n", my_alloc_called);
2021 StubMsg.pfnFree(mem);
2022 StubMsg.pfnFree(mem_orig);
2023
2024 HeapFree(GetProcessHeap(), 0, StubMsg.RpcMsg->Buffer);
2025}
2026
2027static void test_conformant_string(void)
2028{
2029 RPC_MESSAGE RpcMessage;
2030 MIDL_STUB_MESSAGE StubMsg;
2031 MIDL_STUB_DESC StubDesc;
2032 DWORD size;
2033 void *ptr;
2034 unsigned char *mem, *mem_orig;
2035 char memsrc[] = "This is a test string";
2036
2037 static const unsigned char fmtstr_conf_str[] =
2038 {
2039 0x11, 0x8, /* FC_RP [simple_pointer] */
2040 0x22, /* FC_C_CSTRING */
2041 0x5c, /* FC_PAD */
2042 };
2043
2044 StubDesc = Object_StubDesc;
2045 StubDesc.pFormatTypes = fmtstr_conf_str;
2046
2047 memset( &StubMsg, 0, sizeof(StubMsg) ); /* needed on win9x and nt4 */
2049 &RpcMessage,
2050 &StubMsg,
2051 &StubDesc,
2052 0);
2053
2054 StubMsg.BufferLength = 0;
2055 NdrPointerBufferSize( &StubMsg,
2056 (unsigned char *)memsrc,
2057 fmtstr_conf_str );
2058 ok(StubMsg.BufferLength >= sizeof(memsrc) + 12, "length %d\n", StubMsg.BufferLength);
2059
2060 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
2061 StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
2062 StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
2063
2064 ptr = NdrPointerMarshall( &StubMsg, (unsigned char *)memsrc, fmtstr_conf_str );
2065 ok(ptr == NULL, "ret %p\n", ptr);
2066 size = StubMsg.Buffer - StubMsg.BufferStart;
2067 ok(size == sizeof(memsrc) + 12, "Buffer %p Start %p len %d\n",
2068 StubMsg.Buffer, StubMsg.BufferStart, size);
2069 ok(!memcmp(StubMsg.BufferStart + 12, memsrc, sizeof(memsrc)), "incorrectly marshaled\n");
2070
2071 StubMsg.Buffer = StubMsg.BufferStart;
2072 StubMsg.MemorySize = 0;
2073 mem = NULL;
2074
2075 /* Client */
2076 my_alloc_called = 0;
2077 StubMsg.Buffer = StubMsg.BufferStart;
2078 mem = mem_orig = HeapAlloc(GetProcessHeap(), 0, sizeof(memsrc));
2079 /* Windows apparently checks string length on the output buffer to determine its size... */
2080 memset( mem, 'x', sizeof(memsrc) - 1 );
2081 mem[sizeof(memsrc) - 1] = 0;
2082 NdrPointerUnmarshall( &StubMsg, &mem, fmtstr_conf_str, 0);
2083 ok(mem == mem_orig, "mem not alloced\n");
2084 ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2085
2086 my_alloc_called = 0;
2087 StubMsg.Buffer = StubMsg.BufferStart;
2088 NdrPointerUnmarshall( &StubMsg, &mem, fmtstr_conf_str, 1);
2089 ok(mem == mem_orig, "mem not alloced\n");
2090 ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2091
2092 /* Prevent a memory leak when running with Wine.
2093 Remove once the todo_wine block above is fixed. */
2094 if (mem != mem_orig)
2095 HeapFree(GetProcessHeap(), 0, mem_orig);
2096
2097 my_free_called = 0;
2098 StubMsg.Buffer = StubMsg.BufferStart;
2099 NdrPointerFree( &StubMsg, mem, fmtstr_conf_str );
2100 ok(my_free_called == 1, "free called %d\n", my_free_called);
2101
2102 mem = my_alloc(10);
2103 my_free_called = 0;
2104 StubMsg.Buffer = StubMsg.BufferStart;
2105 NdrPointerFree( &StubMsg, mem, fmtstr_conf_str );
2106 ok(my_free_called == 1, "free called %d\n", my_free_called);
2107
2108 /* Server */
2109 my_alloc_called = 0;
2110 StubMsg.IsClient = 0;
2111 mem = NULL;
2112 StubMsg.Buffer = StubMsg.BufferStart;
2113 NdrPointerUnmarshall( &StubMsg, &mem, fmtstr_conf_str, 0);
2114 ok(mem == StubMsg.BufferStart + 12 || broken(!mem), /* win9x, nt4 */
2115 "mem not pointing at buffer %p/%p\n", mem, StubMsg.BufferStart + 12 );
2116 ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2117
2118 my_alloc_called = 0;
2119 mem = NULL;
2120 StubMsg.Buffer = StubMsg.BufferStart;
2121 NdrPointerUnmarshall( &StubMsg, &mem, fmtstr_conf_str, 1);
2122 ok(mem == StubMsg.BufferStart + 12 || broken(!mem), /* win9x, nt4 */
2123 "mem not pointing at buffer %p/%p\n", mem, StubMsg.BufferStart + 12 );
2124 ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2125
2126 my_alloc_called = 0;
2127 mem = mem_orig = HeapAlloc(GetProcessHeap(), 0, sizeof(memsrc));
2128 StubMsg.Buffer = StubMsg.BufferStart;
2129 NdrPointerUnmarshall( &StubMsg, &mem, fmtstr_conf_str, 0);
2130 ok(mem == StubMsg.BufferStart + 12 || broken(!mem), /* win9x, nt4 */
2131 "mem not pointing at buffer %p/%p\n", mem, StubMsg.BufferStart + 12 );
2132 ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2133
2134 my_alloc_called = 0;
2135 mem = mem_orig;
2136 StubMsg.Buffer = StubMsg.BufferStart;
2137 NdrPointerUnmarshall( &StubMsg, &mem, fmtstr_conf_str, 1);
2138 ok(mem == StubMsg.BufferStart + 12 || broken(!mem), /* win9x, nt4 */
2139 "mem not pointing at buffer %p/%p\n", mem, StubMsg.BufferStart + 12 );
2140 ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2141
2142 mem = my_alloc(10);
2143 my_free_called = 0;
2144 StubMsg.Buffer = StubMsg.BufferStart;
2145 NdrPointerFree( &StubMsg, mem, fmtstr_conf_str );
2146 ok(my_free_called == 1, "free called %d\n", my_free_called);
2147
2148 HeapFree(GetProcessHeap(), 0, mem_orig);
2149 HeapFree(GetProcessHeap(), 0, StubMsg.RpcMsg->Buffer);
2150}
2151
2153{
2154 RPC_MESSAGE RpcMessage;
2155 MIDL_STUB_MESSAGE StubMsg;
2156 MIDL_STUB_DESC StubDesc;
2157 DWORD size;
2158 void *ptr;
2159 unsigned char *mem, *mem_orig;
2160 unsigned char memsrc[10] = "This is";
2161 unsigned char memsrc2[10] = "This is a";
2162
2163 static const unsigned char fmtstr_nonconf_str[] =
2164 {
2165 0x26, /* FC_CSTRING */
2166 0x5c, /* FC_PAD */
2167 NdrFcShort( 0xa ), /* 10 */
2168 };
2169
2170 StubDesc = Object_StubDesc;
2171 StubDesc.pFormatTypes = fmtstr_nonconf_str;
2172
2173 /* length < size */
2175 &RpcMessage,
2176 &StubMsg,
2177 &StubDesc,
2178 0);
2179
2180 StubMsg.BufferLength = 0;
2181
2182 NdrNonConformantStringBufferSize( &StubMsg, memsrc, fmtstr_nonconf_str );
2183 ok(StubMsg.BufferLength >= strlen((char *)memsrc) + 1 + 8, "length %d\n", StubMsg.BufferLength);
2184
2185 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
2186 StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
2187 StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
2188
2189 ptr = NdrNonConformantStringMarshall( &StubMsg, memsrc, fmtstr_nonconf_str );
2190 ok(ptr == NULL, "ret %p\n", ptr);
2191 size = StubMsg.Buffer - StubMsg.BufferStart;
2192 ok(size == strlen((char *)memsrc) + 1 + 8, "Buffer %p Start %p len %d\n",
2193 StubMsg.Buffer, StubMsg.BufferStart, size);
2194 ok(!memcmp(StubMsg.BufferStart + 8, memsrc, strlen((char *)memsrc) + 1), "incorrectly marshaled\n");
2195
2196 StubMsg.Buffer = StubMsg.BufferStart;
2197 StubMsg.MemorySize = 0;
2198 mem = NULL;
2199
2200 /* Client */
2201 my_alloc_called = 0;
2202 StubMsg.Buffer = StubMsg.BufferStart;
2203 mem = mem_orig = HeapAlloc(GetProcessHeap(), 0, sizeof(memsrc));
2204 NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 0);
2205 ok(mem == mem_orig, "mem alloced\n");
2206 ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2207
2208 my_alloc_called = 0;
2209 StubMsg.Buffer = StubMsg.BufferStart;
2210 NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 1);
2211 todo_wine
2212 ok(mem == mem_orig, "mem alloced\n");
2213 todo_wine
2214 ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2215
2216 /* Server */
2217 my_alloc_called = 0;
2218 StubMsg.IsClient = 0;
2219 mem = NULL;
2220 StubMsg.Buffer = StubMsg.BufferStart;
2221 NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 0);
2222 ok(mem != mem_orig, "mem not alloced\n");
2223 ok(mem != StubMsg.BufferStart + 8, "mem pointing at buffer\n");
2224 ok(my_alloc_called == 1, "alloc called %d\n", my_alloc_called);
2225 NdrOleFree(mem);
2226
2227 my_alloc_called = 0;
2228 mem = mem_orig;
2229 StubMsg.Buffer = StubMsg.BufferStart;
2230 NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 0);
2231 ok(mem == mem_orig, "mem alloced\n");
2232 ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2233
2234 my_alloc_called = 0;
2235 mem = mem_orig;
2236 StubMsg.Buffer = StubMsg.BufferStart;
2237 NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 1);
2238 todo_wine
2239 ok(mem == mem_orig, "mem alloced\n");
2240 todo_wine
2241 ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2242
2243 HeapFree(GetProcessHeap(), 0, mem_orig);
2244 HeapFree(GetProcessHeap(), 0, StubMsg.RpcMsg->Buffer);
2245
2246 /* length = size */
2248 &RpcMessage,
2249 &StubMsg,
2250 &StubDesc,
2251 0);
2252
2253 StubMsg.BufferLength = 0;
2254
2255 NdrNonConformantStringBufferSize( &StubMsg, memsrc2, fmtstr_nonconf_str );
2256 ok(StubMsg.BufferLength >= strlen((char *)memsrc2) + 1 + 8, "length %d\n", StubMsg.BufferLength);
2257
2258 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
2259 StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
2260 StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
2261
2262 ptr = NdrNonConformantStringMarshall( &StubMsg, memsrc2, fmtstr_nonconf_str );
2263 ok(ptr == NULL, "ret %p\n", ptr);
2264 size = StubMsg.Buffer - StubMsg.BufferStart;
2265 ok(size == strlen((char *)memsrc2) + 1 + 8, "Buffer %p Start %p len %d\n",
2266 StubMsg.Buffer, StubMsg.BufferStart, size);
2267 ok(!memcmp(StubMsg.BufferStart + 8, memsrc2, strlen((char *)memsrc2) + 1), "incorrectly marshaled\n");
2268
2269 StubMsg.Buffer = StubMsg.BufferStart;
2270 StubMsg.MemorySize = 0;
2271 mem = NULL;
2272
2273 /* Client */
2274 my_alloc_called = 0;
2275 StubMsg.Buffer = StubMsg.BufferStart;
2276 mem = mem_orig = HeapAlloc(GetProcessHeap(), 0, sizeof(memsrc));
2277 NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 0);
2278 ok(mem == mem_orig, "mem alloced\n");
2279 ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2280
2281 my_alloc_called = 0;
2282 StubMsg.Buffer = StubMsg.BufferStart;
2283 NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 1);
2284 todo_wine
2285 ok(mem == mem_orig, "mem alloced\n");
2286 todo_wine
2287 ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2288
2289 /* Server */
2290 my_alloc_called = 0;
2291 StubMsg.IsClient = 0;
2292 mem = NULL;
2293 StubMsg.Buffer = StubMsg.BufferStart;
2294 NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 0);
2295 ok(mem != mem_orig, "mem not alloced\n");
2296 ok(mem != StubMsg.BufferStart + 8, "mem pointing at buffer\n");
2297 ok(my_alloc_called == 1, "alloc called %d\n", my_alloc_called);
2298 NdrOleFree(mem);
2299
2300 my_alloc_called = 0;
2301 mem = mem_orig;
2302 StubMsg.Buffer = StubMsg.BufferStart;
2303 NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 0);
2304 ok(mem == mem_orig, "mem alloced\n");
2305 ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2306
2307 my_alloc_called = 0;
2308 mem = mem_orig;
2309 StubMsg.Buffer = StubMsg.BufferStart;
2310 NdrNonConformantStringUnmarshall( &StubMsg, &mem, fmtstr_nonconf_str, 1);
2311 todo_wine
2312 ok(mem == mem_orig, "mem alloced\n");
2313 todo_wine
2314 ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called);
2315
2316 HeapFree(GetProcessHeap(), 0, mem_orig);
2317 HeapFree(GetProcessHeap(), 0, StubMsg.RpcMsg->Buffer);
2318}
2319
2321{
2322 RPC_MESSAGE RpcMessage;
2323 MIDL_STUB_MESSAGE StubMsg;
2324 MIDL_STUB_DESC StubDesc;
2325 void *ptr;
2326 unsigned int i;
2327 struct conf_complex
2328 {
2329 unsigned int size;
2330 unsigned int *array[1];
2331 };
2332 struct conf_complex *memsrc;
2333 struct conf_complex *mem;
2334
2335 static const unsigned char fmtstr_complex_struct[] =
2336 {
2337/* 0 */
2338 0x1b, /* FC_CARRAY */
2339 0x3, /* 3 */
2340/* 2 */ NdrFcShort( 0x4 ), /* 4 */
2341/* 4 */ 0x8, /* Corr desc: FC_LONG */
2342 0x0, /* */
2343/* 6 */ NdrFcShort( 0xfffc ), /* -4 */
2344/* 8 */
2345 0x4b, /* FC_PP */
2346 0x5c, /* FC_PAD */
2347/* 10 */
2348 0x48, /* FC_VARIABLE_REPEAT */
2349 0x49, /* FC_FIXED_OFFSET */
2350/* 12 */ NdrFcShort( 0x4 ), /* 4 */
2351/* 14 */ NdrFcShort( 0x0 ), /* 0 */
2352/* 16 */ NdrFcShort( 0x1 ), /* 1 */
2353/* 18 */ NdrFcShort( 0x0 ), /* 0 */
2354/* 20 */ NdrFcShort( 0x0 ), /* 0 */
2355/* 22 */ 0x12, 0x8, /* FC_UP [simple_pointer] */
2356/* 24 */ 0x8, /* FC_LONG */
2357 0x5c, /* FC_PAD */
2358/* 26 */
2359 0x5b, /* FC_END */
2360
2361 0x8, /* FC_LONG */
2362/* 28 */ 0x5c, /* FC_PAD */
2363 0x5b, /* FC_END */
2364/* 30 */
2365 0x1a, /* FC_BOGUS_STRUCT */
2366 0x3, /* 3 */
2367/* 32 */ NdrFcShort( 0x4 ), /* 4 */
2368/* 34 */ NdrFcShort( 0xffffffde ), /* Offset= -34 (0) */
2369/* 36 */ NdrFcShort( 0x0 ), /* Offset= 0 (36) */
2370/* 38 */ 0x8, /* FC_LONG */
2371 0x5b, /* FC_END */
2372 };
2373
2375 FIELD_OFFSET(struct conf_complex, array[20]));
2376 memsrc->size = 20;
2377
2378 StubDesc = Object_StubDesc;
2379 StubDesc.pFormatTypes = fmtstr_complex_struct;
2380
2382 &RpcMessage,
2383 &StubMsg,
2384 &StubDesc,
2385 0);
2386
2387 StubMsg.BufferLength = 0;
2389 (unsigned char *)memsrc,
2390 &fmtstr_complex_struct[30] );
2391 ok(StubMsg.BufferLength >= 28, "length %d\n", StubMsg.BufferLength);
2392
2393 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
2394 StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
2395 StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
2396
2397 ptr = NdrComplexStructMarshall( &StubMsg, (unsigned char *)memsrc,
2398 &fmtstr_complex_struct[30] );
2399 ok(ptr == NULL, "ret %p\n", ptr);
2400 ok(*(unsigned int *)StubMsg.BufferStart == 20, "Conformance should have been 20 instead of %d\n", *(unsigned int *)StubMsg.BufferStart);
2401 ok(*(unsigned int *)(StubMsg.BufferStart + 4) == 20, "conf_complex.size should have been 20 instead of %d\n", *(unsigned int *)(StubMsg.BufferStart + 4));
2402 for (i = 0; i < 20; i++)
2403 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));
2404
2405 /* Server */
2406 my_alloc_called = 0;
2407 StubMsg.IsClient = 0;
2408 mem = NULL;
2409 StubMsg.Buffer = StubMsg.BufferStart;
2410 ptr = NdrComplexStructUnmarshall( &StubMsg, (unsigned char **)&mem, &fmtstr_complex_struct[30], 0);
2411 ok(ptr == NULL, "ret %p\n", ptr);
2412 ok(mem->size == 20, "mem->size wasn't unmarshalled correctly (%d)\n", mem->size);
2413 ok(mem->array[0] == NULL, "mem->array[0] wasn't unmarshalled correctly (%p)\n", mem->array[0]);
2414 StubMsg.pfnFree(mem);
2415
2416 HeapFree(GetProcessHeap(), 0, StubMsg.RpcMsg->Buffer);
2417 HeapFree(GetProcessHeap(), 0, memsrc);
2418}
2419
2420
2422{
2423 RPC_MESSAGE RpcMessage;
2424 MIDL_STUB_MESSAGE StubMsg;
2425 MIDL_STUB_DESC StubDesc;
2426 void *ptr;
2427 unsigned int i, j;
2428 struct conf_complex
2429 {
2430 unsigned int dim1, dim2;
2431 DWORD **array;
2432 };
2433 struct conf_complex memsrc;
2434 struct conf_complex *mem;
2435 DWORD *buf, expected_length;
2436
2437 static const unsigned char fmtstr_complex_array[] =
2438 {
2439
2440/* 0 */ 0x21, /* FC_BOGUS_ARRAY */
2441 0x3, /* 3 */
2442/* 2 */ NdrFcShort( 0x0 ), /* 0 */
2443/* 4 */ 0x19, 0x0, /* Corr desc: field pointer, FC_ULONG */
2444/* 6 */ NdrFcShort( 0x4 ), /* 4 */
2445/* 8 */ NdrFcLong( 0xffffffff ), /* -1 */
2446/* 12 */ 0x8, /* FC_LONG */
2447 0x5b, /* FC_END */
2448/* 14 */
2449 0x21, /* FC_BOGUS_ARRAY */
2450 0x3, /* 3 */
2451/* 16 */ NdrFcShort( 0x0 ), /* 0 */
2452/* 18 */ 0x19, /* Corr desc: field pointer, FC_ULONG */
2453 0x0, /* */
2454/* 20 */ NdrFcShort( 0x0 ), /* 0 */
2455/* 22 */ NdrFcLong( 0xffffffff ), /* -1 */
2456/* 26 */ 0x12, 0x0, /* FC_UP */
2457/* 28 */ NdrFcShort( 0xffe4 ), /* Offset= -28 (0) */
2458/* 30 */ 0x5c, /* FC_PAD */
2459 0x5b, /* FC_END */
2460
2461#ifdef _WIN64
2462/* 32 */ 0x1a, /* FC_BOGUS_STRUCT */
2463 0x3, /* 3 */
2464/* 34 */ NdrFcShort( 0x10 ), /* 16 */
2465/* 36 */ NdrFcShort( 0x0 ), /* 0 */
2466/* 38 */ NdrFcShort( 0x6 ), /* Offset= 6 (44) */
2467/* 40 */ 0x8, /* FC_LONG */
2468 0x8, /* FC_LONG */
2469/* 42 */ 0x36, /* FC_POINTER */
2470 0x5b, /* FC_END */
2471/* 44 */
2472 0x12, 0x0, /* FC_UP */
2473/* 46 */ NdrFcShort( 0xffe0 ), /* Offset= -32 (14) */
2474#else
2475/* 32 */
2476 0x16, /* FC_PSTRUCT */
2477 0x3, /* 3 */
2478/* 34 */ NdrFcShort( 0xc ), /* 12 */
2479/* 36 */ 0x4b, /* FC_PP */
2480 0x5c, /* FC_PAD */
2481/* 38 */ 0x46, /* FC_NO_REPEAT */
2482 0x5c, /* FC_PAD */
2483/* 40 */ NdrFcShort( 0x8 ), /* 8 */
2484/* 42 */ NdrFcShort( 0x8 ), /* 8 */
2485/* 44 */ 0x12, 0x0, /* FC_UP */
2486/* 46 */ NdrFcShort( 0xffe0 ), /* Offset= -32 (14) */
2487/* 48 */ 0x5b, /* FC_END */
2488 0x8, /* FC_LONG */
2489/* 50 */ 0x8, /* FC_LONG */
2490 0x8, /* FC_LONG */
2491/* 52 */ 0x5c, /* FC_PAD */
2492 0x5b, /* FC_END */
2493#endif
2494 };
2495
2496 memsrc.dim1 = 5;
2497 memsrc.dim2 = 3;
2498
2499 memsrc.array = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, memsrc.dim1 * sizeof(DWORD*));
2500
2501 for(i = 0; i < memsrc.dim1; i++)
2502 {
2503 memsrc.array[i] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, memsrc.dim2 * sizeof(DWORD));
2504 for(j = 0; j < memsrc.dim2; j++)
2505 memsrc.array[i][j] = i * memsrc.dim2 + j;
2506 }
2507
2508 StubDesc = Object_StubDesc;
2509 StubDesc.pFormatTypes = fmtstr_complex_array;
2510
2512 &RpcMessage,
2513 &StubMsg,
2514 &StubDesc,
2515 0);
2516
2517 StubMsg.BufferLength = 0;
2518
2519#ifdef _WIN64
2521 (unsigned char *)&memsrc,
2522 &fmtstr_complex_array[32] );
2523#else
2524 NdrSimpleStructBufferSize( &StubMsg,
2525 (unsigned char *)&memsrc,
2526 &fmtstr_complex_array[32] );
2527#endif
2528
2529 expected_length = (4 + memsrc.dim1 * (2 + memsrc.dim2)) * 4;
2530 ok(StubMsg.BufferLength >= expected_length, "length %d\n", StubMsg.BufferLength);
2531
2532 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
2533 StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
2534 StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
2535
2536#ifdef _WIN64
2537 ptr = NdrComplexStructMarshall( &StubMsg, (unsigned char *)&memsrc,
2538 &fmtstr_complex_array[32] );
2539#else
2540 ptr = NdrSimpleStructMarshall( &StubMsg, (unsigned char *)&memsrc,
2541 &fmtstr_complex_array[32] );
2542#endif
2543
2544 ok(ptr == NULL, "ret %p\n", ptr);
2545 ok((char*)StubMsg.Buffer == (char*)StubMsg.BufferStart + expected_length, "not at expected length\n");
2546
2547 buf = (DWORD *)StubMsg.BufferStart;
2548
2549 ok(*buf == memsrc.dim1, "dim1 should have been %d instead of %08x\n", memsrc.dim1, *buf);
2550 buf++;
2551 ok(*buf == memsrc.dim2, "dim2 should have been %d instead of %08x\n", memsrc.dim2, *buf);
2552 buf++;
2553 ok(*buf != 0, "pointer id should be non-zero\n");
2554 buf++;
2555 ok(*buf == memsrc.dim1, "Conformance should have been %d instead of %08x\n", memsrc.dim1, *buf);
2556 buf++;
2557 for(i = 0; i < memsrc.dim1; i++)
2558 {
2559 ok(*buf != 0, "pointer id[%d] should be non-zero\n", i);
2560 buf++;
2561 }
2562 for(i = 0; i < memsrc.dim1; i++)
2563 {
2564 ok(*buf == memsrc.dim2, "Conformance should have been %d instead of %08x\n", memsrc.dim2, *buf);
2565 buf++;
2566 for(j = 0; j < memsrc.dim2; j++)
2567 {
2568 ok(*buf == i * memsrc.dim2 + j, "got %08x\n", *buf);
2569 buf++;
2570 }
2571 }
2572
2573 ok((void*)buf == StubMsg.Buffer, "not at end of buffer\n");
2574
2575 /* Server */
2576 my_alloc_called = 0;
2577 StubMsg.IsClient = 0;
2578 mem = NULL;
2579 StubMsg.Buffer = StubMsg.BufferStart;
2580#ifdef _WIN64
2581 ptr = NdrComplexStructUnmarshall( &StubMsg, (unsigned char **)&mem, &fmtstr_complex_array[32], 0);
2582#else
2583 ptr = NdrSimpleStructUnmarshall( &StubMsg, (unsigned char **)&mem, &fmtstr_complex_array[32], 0);
2584#endif
2585 ok(ptr == NULL, "ret %p\n", ptr);
2586 ok(mem->dim1 == memsrc.dim1, "mem->dim1 wasn't unmarshalled correctly (%d)\n", mem->dim1);
2587 ok(mem->dim2 == memsrc.dim2, "mem->dim2 wasn't unmarshalled correctly (%d)\n", mem->dim2);
2588 ok(mem->array[1][0] == memsrc.dim2, "mem->array[1][0] wasn't unmarshalled correctly (%d)\n", mem->array[1][0]);
2589
2590 StubMsg.Buffer = StubMsg.BufferStart;
2591#ifdef _WIN64
2592 NdrComplexStructFree( &StubMsg, (unsigned char*)mem, &fmtstr_complex_array[32]);
2593#else
2594 NdrSimpleStructFree( &StubMsg, (unsigned char*)mem, &fmtstr_complex_array[32]);
2595#endif
2596
2597 HeapFree(GetProcessHeap(), 0, StubMsg.RpcMsg->Buffer);
2598
2599 for(i = 0; i < memsrc.dim1; i++)
2600 HeapFree(GetProcessHeap(), 0, memsrc.array[i]);
2601 HeapFree(GetProcessHeap(), 0, memsrc.array);
2602}
2603
2604static void test_ndr_buffer(void)
2605{
2606 static unsigned char ncalrpc[] = "ncalrpc";
2607 static unsigned char endpoint[] = "winetest:test_ndr_buffer";
2608 RPC_MESSAGE RpcMessage;
2609 MIDL_STUB_MESSAGE StubMsg;
2611 unsigned char *ret;
2612 unsigned char *binding;
2615 ULONG prev_buffer_length;
2616 BOOL old_buffer_valid_location;
2617
2619
2620 status = RpcServerUseProtseqEpA(ncalrpc, 20, endpoint, NULL);
2621 ok(RPC_S_OK == status, "RpcServerUseProtseqEp failed with status %u\n", status);
2623 ok(RPC_S_OK == status, "RpcServerRegisterIf failed with status %u\n", status);
2624 status = RpcServerListen(1, 20, TRUE);
2625 ok(RPC_S_OK == status, "RpcServerListen failed with status %u\n", status);
2626 if (status != RPC_S_OK)
2627 {
2628 /* Failed to create a server, running client tests is useless */
2629 return;
2630 }
2631
2632 status = RpcStringBindingComposeA(NULL, ncalrpc, NULL, endpoint, NULL, &binding);
2633 ok(status == RPC_S_OK, "RpcStringBindingCompose failed (%u)\n", status);
2634
2636 ok(status == RPC_S_OK, "RpcBindingFromStringBinding failed (%u)\n", status);
2637 RpcStringFreeA(&binding);
2638
2639 NdrClientInitializeNew(&RpcMessage, &StubMsg, &StubDesc, 5);
2640
2641 ret = NdrGetBuffer(&StubMsg, 10, Handle);
2642 ok(ret == StubMsg.Buffer, "NdrGetBuffer should have returned the same value as StubMsg.Buffer instead of %p\n", ret);
2643 ok(RpcMessage.Handle != NULL, "RpcMessage.Handle should not have been NULL\n");
2644 ok(RpcMessage.Buffer != NULL, "RpcMessage.Buffer should not have been NULL\n");
2645 ok(RpcMessage.BufferLength == 10 ||
2646 broken(RpcMessage.BufferLength == 12), /* win2k */
2647 "RpcMessage.BufferLength should have been 10 instead of %d\n", RpcMessage.BufferLength);
2648 ok(RpcMessage.RpcFlags == 0, "RpcMessage.RpcFlags should have been 0x0 instead of 0x%x\n", RpcMessage.RpcFlags);
2649 ok(StubMsg.Buffer != NULL, "Buffer should not have been NULL\n");
2650 ok(!StubMsg.BufferStart, "BufferStart should have been NULL instead of %p\n", StubMsg.BufferStart);
2651 ok(!StubMsg.BufferEnd, "BufferEnd should have been NULL instead of %p\n", StubMsg.BufferEnd);
2653 ok(StubMsg.BufferLength == 0, "BufferLength should have left as 0 instead of being set to %d\n", StubMsg.BufferLength);
2654 old_buffer_valid_location = !StubMsg.fBufferValid;
2655 if (old_buffer_valid_location)
2656 ok(broken(StubMsg.CorrDespIncrement == TRUE), "fBufferValid should have been TRUE instead of 0x%x\n", StubMsg.CorrDespIncrement);
2657 else
2658 ok(StubMsg.fBufferValid, "fBufferValid should have been non-zero instead of 0x%x\n", StubMsg.fBufferValid);
2659
2660 prev_buffer_length = RpcMessage.BufferLength;
2661 StubMsg.BufferLength = 1;
2662 NdrFreeBuffer(&StubMsg);
2663 ok(RpcMessage.Handle != NULL, "RpcMessage.Handle should not have been NULL\n");
2664 ok(RpcMessage.Buffer != NULL, "RpcMessage.Buffer should not have been NULL\n");
2665 ok(RpcMessage.BufferLength == prev_buffer_length, "RpcMessage.BufferLength should have been left as %d instead of %d\n", prev_buffer_length, RpcMessage.BufferLength);
2666 ok(StubMsg.Buffer != NULL, "Buffer should not have been NULL\n");
2667 ok(StubMsg.BufferLength == 1, "BufferLength should have left as 1 instead of being set to %d\n", StubMsg.BufferLength);
2668 if (old_buffer_valid_location)
2669 ok(broken(StubMsg.CorrDespIncrement == FALSE), "fBufferValid should have been FALSE instead of 0x%x\n", StubMsg.CorrDespIncrement);
2670 else
2671 ok(!StubMsg.fBufferValid, "fBufferValid should have been FALSE instead of %d\n", StubMsg.fBufferValid);
2672
2673 /* attempt double-free */
2674 NdrFreeBuffer(&StubMsg);
2675
2677
2679 ok(status == RPC_S_OK, "RpcServerUnregisterIf failed (%u)\n", status);
2680}
2681
2683{
2684 RPC_STATUS rpc_status;
2685 MIDL_STUB_MESSAGE StubMsg;
2686 RPC_MESSAGE RpcMessage;
2687
2688 NdrClientInitializeNew(&RpcMessage, &StubMsg, &Object_StubDesc, 5);
2689
2690 for (rpc_status = 0; rpc_status < 10000; rpc_status++)
2691 {
2693 ULONG comm_status = 0;
2694 ULONG fault_status = 0;
2695 ULONG expected_comm_status = 0;
2696 ULONG expected_fault_status = 0;
2697 status = NdrMapCommAndFaultStatus(&StubMsg, &comm_status, &fault_status, rpc_status);
2698 ok(status == RPC_S_OK, "NdrMapCommAndFaultStatus failed with error %d\n", status);
2699 switch (rpc_status)
2700 {
2703 case RPC_S_UNKNOWN_IF:
2712 case RPC_S_COMM_FAILURE:
2713 expected_comm_status = rpc_status;
2714 break;
2715 default:
2716 expected_fault_status = rpc_status;
2717 }
2718 ok(comm_status == expected_comm_status, "NdrMapCommAndFaultStatus should have mapped %d to comm status %d instead of %d\n",
2719 rpc_status, expected_comm_status, comm_status);
2720 ok(fault_status == expected_fault_status, "NdrMapCommAndFaultStatus should have mapped %d to fault status %d instead of %d\n",
2721 rpc_status, expected_fault_status, fault_status);
2722 }
2723}
2724
2726{
2728 MIDL_STUB_MESSAGE stubmsg;
2729 USER_MARSHAL_CB umcb;
2731 unsigned char buffer[16];
2732 void *rpc_channel_buffer = (void *)(ULONG_PTR)0xcafebabe;
2734
2735 /* unmarshall */
2736
2737 memset(&rpc_msg, 0xcc, sizeof(rpc_msg));
2738 rpc_msg.Buffer = buffer;
2739 rpc_msg.BufferLength = 16;
2740
2741 memset(&stubmsg, 0xcc, sizeof(stubmsg));
2742 stubmsg.RpcMsg = &rpc_msg;
2743 stubmsg.dwDestContext = MSHCTX_INPROC;
2744 stubmsg.pvDestContext = NULL;
2745 stubmsg.Buffer = buffer + 15;
2746 stubmsg.BufferLength = 0;
2747 stubmsg.BufferEnd = NULL;
2748 stubmsg.pRpcChannelBuffer = rpc_channel_buffer;
2749 stubmsg.StubDesc = NULL;
2750 stubmsg.pfnAllocate = my_alloc;
2751 stubmsg.pfnFree = my_free;
2752
2753 memset(&umcb, 0xcc, sizeof(umcb));
2754 umcb.Flags = MAKELONG(MSHCTX_INPROC, NDR_LOCAL_DATA_REPRESENTATION);
2755 umcb.pStubMsg = &stubmsg;
2758
2759 memset(&umi, 0xaa, sizeof(umi));
2760
2761 status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2762 ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %d\n", status);
2763 ok( umi.InformationLevel == 1,
2764 "umi.InformationLevel was %u instead of 1\n",
2765 umi.InformationLevel);
2766 ok( U1(umi).Level1.Buffer == buffer + 15,
2767 "umi.Level1.Buffer was %p instead of %p\n",
2768 U1(umi).Level1.Buffer, buffer);
2769 ok( U1(umi).Level1.BufferSize == 1,
2770 "umi.Level1.BufferSize was %u instead of 1\n",
2771 U1(umi).Level1.BufferSize);
2772 ok( U1(umi).Level1.pfnAllocate == my_alloc,
2773 "umi.Level1.pfnAllocate was %p instead of %p\n",
2774 U1(umi).Level1.pfnAllocate, my_alloc);
2775 ok( U1(umi).Level1.pfnFree == my_free,
2776 "umi.Level1.pfnFree was %p instead of %p\n",
2777 U1(umi).Level1.pfnFree, my_free);
2778 ok( U1(umi).Level1.pRpcChannelBuffer == rpc_channel_buffer,
2779 "umi.Level1.pRpcChannelBuffer was %p instead of %p\n",
2780 U1(umi).Level1.pRpcChannelBuffer, rpc_channel_buffer);
2781
2782 /* buffer size */
2783
2784 rpc_msg.Buffer = buffer;
2785 rpc_msg.BufferLength = 16;
2786
2787 stubmsg.Buffer = buffer;
2788 stubmsg.BufferLength = 16;
2789 stubmsg.BufferEnd = NULL;
2790
2792
2793 memset(&umi, 0xaa, sizeof(umi));
2794
2795 status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2796 ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %d\n", status);
2797 ok( umi.InformationLevel == 1,
2798 "umi.InformationLevel was %u instead of 1\n",
2799 umi.InformationLevel);
2800 ok( U1(umi).Level1.Buffer == NULL,
2801 "umi.Level1.Buffer was %p instead of NULL\n",
2802 U1(umi).Level1.Buffer);
2803 ok( U1(umi).Level1.BufferSize == 0,
2804 "umi.Level1.BufferSize was %u instead of 0\n",
2805 U1(umi).Level1.BufferSize);
2806 ok( U1(umi).Level1.pfnAllocate == my_alloc,
2807 "umi.Level1.pfnAllocate was %p instead of %p\n",
2808 U1(umi).Level1.pfnAllocate, my_alloc);
2809 ok( U1(umi).Level1.pfnFree == my_free,
2810 "umi.Level1.pfnFree was %p instead of %p\n",
2811 U1(umi).Level1.pfnFree, my_free);
2812 ok( U1(umi).Level1.pRpcChannelBuffer == rpc_channel_buffer,
2813 "umi.Level1.pRpcChannelBuffer was %p instead of %p\n",
2814 U1(umi).Level1.pRpcChannelBuffer, rpc_channel_buffer);
2815
2816 /* marshall */
2817
2818 rpc_msg.Buffer = buffer;
2819 rpc_msg.BufferLength = 16;
2820
2821 stubmsg.Buffer = buffer + 15;
2822 stubmsg.BufferLength = 0;
2823 stubmsg.BufferEnd = NULL;
2824
2826
2827 memset(&umi, 0xaa, sizeof(umi));
2828
2829 status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2830 ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %d\n", status);
2831 ok( umi.InformationLevel == 1,
2832 "umi.InformationLevel was %u instead of 1\n",
2833 umi.InformationLevel);
2834 ok( U1(umi).Level1.Buffer == buffer + 15,
2835 "umi.Level1.Buffer was %p instead of %p\n",
2836 U1(umi).Level1.Buffer, buffer);
2837 ok( U1(umi).Level1.BufferSize == 1,
2838 "umi.Level1.BufferSize was %u instead of 1\n",
2839 U1(umi).Level1.BufferSize);
2840 ok( U1(umi).Level1.pfnAllocate == my_alloc,
2841 "umi.Level1.pfnAllocate was %p instead of %p\n",
2842 U1(umi).Level1.pfnAllocate, my_alloc);
2843 ok( U1(umi).Level1.pfnFree == my_free,
2844 "umi.Level1.pfnFree was %p instead of %p\n",
2845 U1(umi).Level1.pfnFree, my_free);
2846 ok( U1(umi).Level1.pRpcChannelBuffer == rpc_channel_buffer,
2847 "umi.Level1.pRpcChannelBuffer was %p instead of %p\n",
2848 U1(umi).Level1.pRpcChannelBuffer, rpc_channel_buffer);
2849
2850 /* free */
2851
2852 rpc_msg.Buffer = buffer;
2853 rpc_msg.BufferLength = 16;
2854
2855 stubmsg.Buffer = buffer;
2856 stubmsg.BufferLength = 16;
2857 stubmsg.BufferEnd = NULL;
2858
2860
2861 memset(&umi, 0xaa, sizeof(umi));
2862
2863 status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2864 ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %d\n", status);
2865 ok( umi.InformationLevel == 1,
2866 "umi.InformationLevel was %u instead of 1\n",
2867 umi.InformationLevel);
2868 ok( U1(umi).Level1.Buffer == NULL,
2869 "umi.Level1.Buffer was %p instead of NULL\n",
2870 U1(umi).Level1.Buffer);
2871 ok( U1(umi).Level1.BufferSize == 0,
2872 "umi.Level1.BufferSize was %u instead of 0\n",
2873 U1(umi).Level1.BufferSize);
2874 ok( U1(umi).Level1.pfnAllocate == my_alloc,
2875 "umi.Level1.pfnAllocate was %p instead of %p\n",
2876 U1(umi).Level1.pfnAllocate, my_alloc);
2877 ok( U1(umi).Level1.pfnFree == my_free,
2878 "umi.Level1.pfnFree was %p instead of %p\n",
2879 U1(umi).Level1.pfnFree, my_free);
2880 ok( U1(umi).Level1.pRpcChannelBuffer == rpc_channel_buffer,
2881 "umi.Level1.pRpcChannelBuffer was %p instead of %p\n",
2882 U1(umi).Level1.pRpcChannelBuffer, rpc_channel_buffer);
2883
2884 /* boundary test */
2885
2886 rpc_msg.Buffer = buffer;
2887 rpc_msg.BufferLength = 15;
2888
2889 stubmsg.Buffer = buffer + 15;
2890 stubmsg.BufferLength = 0;
2891 stubmsg.BufferEnd = NULL;
2892
2894
2895 status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2896 ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %d\n", status);
2897 ok( U1(umi).Level1.BufferSize == 0,
2898 "umi.Level1.BufferSize was %u instead of 0\n",
2899 U1(umi).Level1.BufferSize);
2900
2901 /* error conditions */
2902
2903 rpc_msg.BufferLength = 14;
2904 status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2906 "NdrGetUserMarshalInfo should have failed with ERROR_INVALID_USER_BUFFER instead of %d\n", status);
2907
2908 rpc_msg.BufferLength = 15;
2909 status = NdrGetUserMarshalInfo(&umcb.Flags, 9999, &umi);
2911 "NdrGetUserMarshalInfo should have failed with RPC_S_INVALID_ARG instead of %d\n", status);
2912
2913 umcb.CBType = 9999;
2914 status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2915 ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %d\n", status);
2916
2918 umcb.Signature = 0;
2919 status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2921 "NdrGetUserMarshalInfo should have failed with RPC_S_INVALID_ARG instead of %d\n", status);
2922}
2923
2925{
2926 ULONG encoded_size;
2929 char *buffer;
2930
2932 ok(status == RPC_S_INVALID_ARG, "got %d\n", status);
2933
2935 ok(status == RPC_S_INVALID_ARG, "got %d\n", status);
2936
2937 status = MesEncodeFixedBufferHandleCreate((char*)0xdeadbeef, 0, NULL, &handle);
2938 ok(status == RPC_X_INVALID_BUFFER, "got %d\n", status);
2939
2940 buffer = (void*)((0xdeadbeef + 7) & ~7);
2942 ok(status == RPC_S_INVALID_ARG, "got %d\n", status);
2943
2946 ok(status == RPC_S_INVALID_ARG, "got %d\n", status);
2947if (status == RPC_S_OK) {
2949}
2951 ok(status == RPC_S_INVALID_ARG, "got %d\n", status);
2952
2953 status = MesEncodeFixedBufferHandleCreate(buffer, 32, &encoded_size, &handle);
2954 ok(status == RPC_S_OK, "got %d\n", status);
2955
2957 &buffer, 32, &encoded_size);
2958 ok(status == RPC_S_INVALID_ARG, "got %d\n", status);
2959
2960 /* convert to dynamic buffer handle */
2962 &buffer, 32, &encoded_size);
2963 ok(status == RPC_S_OK, "got %d\n", status);
2964
2966 NULL, 32, &encoded_size);
2967 ok(status == RPC_S_INVALID_ARG, "got %d\n", status);
2968
2970 &buffer, 32, NULL);
2971 ok(status == RPC_S_INVALID_ARG, "got %d\n", status);
2972
2973 /* invalid handle type */
2975 &buffer, 32, &encoded_size);
2976 ok(status == RPC_S_INVALID_ARG, "got %d\n", status);
2977
2979 ok(status == RPC_S_OK, "got %d\n", status);
2980}
2981
2983{
2984 MIDL_STUB_MESSAGE stub_msg;
2985 BYTE buf[256];
2986
2987 memset( &stub_msg, 0, sizeof(stub_msg) );
2988 memset( buf, 0, sizeof(buf) );
2989
2990 NdrCorrelationInitialize( &stub_msg, buf, sizeof(buf), 0 );
2991 ok( stub_msg.CorrDespIncrement == 2 ||
2992 broken(stub_msg.CorrDespIncrement == 0), /* <= Win 2003 */
2993 "got %d\n", stub_msg.CorrDespIncrement );
2994
2995 memset( &stub_msg, 0, sizeof(stub_msg) );
2996 memset( buf, 0, sizeof(buf) );
2997
2998 stub_msg.CorrDespIncrement = 1;
2999 NdrCorrelationInitialize( &stub_msg, buf, sizeof(buf), 0 );
3000 ok( stub_msg.CorrDespIncrement == 1, "got %d\n", stub_msg.CorrDespIncrement );
3001}
3002
3003START_TEST( ndr_marshall )
3004{
3006
3027}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
const GUID IID_IUnknown
w ll
Definition: byte_order.h:167
r l[0]
Definition: byte_order.h:168
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static WCHAR unknown[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1605
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define CALLBACK
Definition: compat.h:35
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
unsigned char *WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
unsigned char *WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
unsigned char *WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi)
unsigned char *WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc)
unsigned char *WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc)
void WINAPI NdrSimpleTypeUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, unsigned char FormatChar)
void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
unsigned char *WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc)
unsigned char *WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
unsigned char *WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc)
void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
unsigned char *WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc)
ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
void *WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, SIZE_T len)
Definition: ndr_marshall.c:419
void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
void WINAPI NdrSimpleTypeMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, unsigned char FormatChar)
void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
unsigned char *WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
int proxy
Definition: main.c:67
ULONG Handle
Definition: gdb_input.c:15
GLdouble s
Definition: gl.h:2039
GLsizeiptr size
Definition: glext.h:5919
GLuint buffer
Definition: glext.h:5915
const GLubyte * c
Definition: glext.h:8905
GLfloat f
Definition: glext.h:7540
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint GLuint num
Definition: glext.h:9618
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define S_OK
Definition: intsafe.h:52
#define d
Definition: ke_i.h:81
#define f
Definition: ke_i.h:83
#define c
Definition: ke_i.h:80
struct S1 s1
struct S2 s2
@ MES_ENCODE
Definition: midles.h:32
@ MES_DYNAMIC_BUFFER_HANDLE
Definition: midles.h:41
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
#define todo_wine
Definition: custom.c:89
#define cmp(status, error)
Definition: error.c:114
#define TEST_POINTER_UNSET(field)
#define TEST_ULONG_PTR_UNSET(field)
static int deref_cmp(const void *s1, const void *s2, size_t num)
Definition: ndr_marshall.c:497
static IPersistVtbl testiface_vtbl
static void test_simple_struct(void)
static void test_conformant_string(void)
static void test_ndr_simple_type(void)
Definition: ndr_marshall.c:139
static void test_ndr_allocate(void)
static void test_NdrGetUserMarshalInfo(void)
static BOOL use_pointer_ids
Definition: ndr_marshall.c:103
static const MIDL_STUB_DESC Object_StubDesc
Definition: ndr_marshall.c:54
static struct testiface * impl_from_IPersist(IPersist *iface)
static void test_conf_complex_struct(void)
static void test_ndr_buffer(void)
static const RPC_SERVER_INTERFACE IFoo___RpcServerInterface
Definition: ndr_marshall.c:89
static void test_server_init(void)
static void test_nontrivial_pointer_types(void)
Definition: ndr_marshall.c:716
static void test_pointer_marshal(const unsigned char *formattypes, void *memsrc, DWORD srcsize, const void *wiredata, ULONG wiredatalen, int(*cmp)(const void *, const void *, size_t), int num_additional_allocs, const char *msgpfx)
Definition: ndr_marshall.c:175
static void test_MesEncodeFixedBufferHandleCreate(void)
static int my_free_called
Definition: ndr_marshall.c:41
#define TEST_ZERO(field, fmt)
static int ps1_cmp(const void *s1, const void *s2, size_t num)
static RPC_DISPATCH_FUNCTION IFoo_table[]
Definition: ndr_marshall.c:78
static void test_common_stub_data(const char *prefix, const MIDL_STUB_MESSAGE *stubMsg)
static void test_conformant_array(void)
static void test_nonconformant_string(void)
static void *CALLBACK my_alloc(SIZE_T size)
Definition: ndr_marshall.c:42
static void test_simple_struct_marshal(const unsigned char *formattypes, void *memsrc, DWORD srcsize, const void *wiredata, ULONG wiredatalen, int(*cmp)(const void *, const void *, size_t), int num_additional_allocs, const char *msgpfx)
Definition: ndr_marshall.c:870
static int my_alloc_called
Definition: ndr_marshall.c:40
static void test_client_init(void)
static ULONG WINAPI test_persist_Release(IPersist *iface)
static RPC_IF_HANDLE IFoo_v0_0_s_ifspec
Definition: ndr_marshall.c:102
static void test_struct_align(void)
static void CALLBACK my_free(void *ptr)
Definition: ndr_marshall.c:48
static void test_iface_ptr(void)
static void test_simple_types(void)
Definition: ndr_marshall.c:503
static HRESULT WINAPI test_persist_QueryInterface(IPersist *iface, REFIID iid, void **out)
static RPC_DISPATCH_TABLE IFoo_v0_0_DispatchTable
Definition: ndr_marshall.c:83
static HRESULT WINAPI test_persist_GetClassId(IPersist *iface, GUID *clsid)
static void test_NdrCorrelationInitialize(void)
static ULONG WINAPI test_persist_AddRef(IPersist *iface)
#define TEST_ULONG_UNSET(field)
static void determine_pointer_marshalling_style(void)
Definition: ndr_marshall.c:105
static void test_NdrMapCommAndFaultStatus(void)
static void test_fullpointer_xlat(void)
static void test_conf_complex_array(void)
REFCLSID clsid
Definition: msctf.c:82
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
void WINAPI NdrClientInitializeNew(PRPC_MESSAGE pRpcMessage, PMIDL_STUB_MESSAGE pStubMsg, PMIDL_STUB_DESC pStubDesc, unsigned int ProcNum)
unsigned char *WINAPI NdrServerInitializeNew(PRPC_MESSAGE pRpcMsg, PMIDL_STUB_MESSAGE pStubMsg, PMIDL_STUB_DESC pStubDesc)
RPC_STATUS RPC_ENTRY NdrMapCommAndFaultStatus(PMIDL_STUB_MESSAGE pStubMsg, ULONG *pCommStatus, ULONG *pFaultStatus, RPC_STATUS Status)
void WINAPI NdrFreeBuffer(PMIDL_STUB_MESSAGE pStubMsg)
unsigned char *WINAPI NdrGetBuffer(PMIDL_STUB_MESSAGE stubmsg, ULONG buflen, RPC_BINDING_HANDLE handle)
RPC_STATUS WINAPI MesHandleFree(handle_t Handle)
Definition: ndr_es.c:162
RPC_STATUS WINAPI MesBufferHandleReset(handle_t Handle, ULONG HandleStyle, MIDL_ES_CODE Operation, char **Buffer, ULONG BufferSize, ULONG *EncodedSize)
Definition: ndr_es.c:128
RPC_STATUS RPC_ENTRY MesEncodeFixedBufferHandleCreate(char *Buffer, ULONG BufferSize, ULONG *pEncodedSize, handle_t *pHandle)
Definition: ndr_es.c:183
int WINAPI NdrFullPointerFree(PFULL_PTR_XLAT_TABLES pXlatTables, void *Pointer)
int WINAPI NdrFullPointerQueryRefId(PFULL_PTR_XLAT_TABLES pXlatTables, ULONG RefId, unsigned char QueryType, void **ppPointer)
void WINAPI NdrFullPointerXlatFree(PFULL_PTR_XLAT_TABLES pXlatTables)
int WINAPI NdrFullPointerQueryPointer(PFULL_PTR_XLAT_TABLES pXlatTables, void *pPointer, unsigned char QueryType, ULONG *pRefId)
PFULL_PTR_XLAT_TABLES WINAPI NdrFullPointerXlatInit(ULONG NumberOfPointers, XLAT_SIDE XlatSide)
void WINAPI NdrFullPointerInsertRefId(PFULL_PTR_XLAT_TABLES pXlatTables, ULONG RefId, void *pPointer)
void *WINAPI NdrOleAllocate(SIZE_T Size)
Definition: ndr_ole.c:423
unsigned char *WINAPI NdrInterfacePointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
Definition: ndr_ole.c:306
unsigned char *WINAPI NdrInterfacePointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc)
Definition: ndr_ole.c:336
void WINAPI NdrOleFree(void *NodeToFree)
Definition: ndr_ole.c:432
void WINAPI NdrInterfacePointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
Definition: ndr_ole.c:373
void WINAPI NdrInterfacePointerFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
Definition: ndr_ole.c:411
u32_t magic(void)
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
long LONG
Definition: pedump.c:60
const GUID IID_IPersist
Definition: proxy.cpp:14
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
#define FC_POINTER_DEREF
Definition: ndrtypes.h:276
@ FC_ENUM16
Definition: ndrtypes.h:147
@ FC_LONG
Definition: ndrtypes.h:142
@ FC_CONSTANT_IID
Definition: ndrtypes.h:251
@ FC_RP
Definition: ndrtypes.h:152
@ FC_IP
Definition: ndrtypes.h:189
#define FC_ALLOCED_ON_STACK
Definition: ndrtypes.h:274
static unsigned __int64 next
Definition: rand_nt.c:6
@ ParamNumber
Definition: rassapi.h:55
static FILE * out
Definition: regtests2xml.c:44
RPC_STATUS WINAPI RpcBindingFree(RPC_BINDING_HANDLE *Binding)
Definition: rpc_binding.c:787
RPC_STATUS WINAPI RpcStringBindingComposeA(RPC_CSTR ObjUuid, RPC_CSTR Protseq, RPC_CSTR NetworkAddr, RPC_CSTR Endpoint, RPC_CSTR Options, RPC_CSTR *StringBinding)
Definition: rpc_binding.c:457
RPC_STATUS WINAPI RpcBindingFromStringBindingA(RPC_CSTR StringBinding, RPC_BINDING_HANDLE *Binding)
Definition: rpc_binding.c:840
RPC_STATUS WINAPI RpcServerListen(UINT MinimumCallThreads, UINT MaxCalls, UINT DontWait)
Definition: rpc_server.c:1520
RPC_STATUS WINAPI RpcServerRegisterIf(RPC_IF_HANDLE IfSpec, UUID *MgrTypeUuid, RPC_MGR_EPV *MgrEpv)
Definition: rpc_server.c:1116
RPC_STATUS WINAPI RpcServerUseProtseqEpA(RPC_CSTR Protseq, UINT MaxCalls, RPC_CSTR Endpoint, LPVOID SecurityDescriptor)
Definition: rpc_server.c:910
RPC_STATUS WINAPI RpcServerUnregisterIf(RPC_IF_HANDLE IfSpec, UUID *MgrTypeUuid, UINT WaitForCallsToComplete)
Definition: rpc_server.c:1202
void * RPC_IF_HANDLE
Definition: rpcdce.h:49
void(__RPC_STUB * RPC_DISPATCH_FUNCTION)(PRPC_MESSAGE Message)
Definition: rpcdcep.h:82
#define RPC_BUFFER_COMPLETE
Definition: rpcdcep.h:67
struct _RPC_SERVER_INTERFACE RPC_SERVER_INTERFACE
#define NDR_LOCAL_DATA_REPRESENTATION
Definition: rpcndr.h:107
@ USER_MARSHAL_CB_BUFFER_SIZE
Definition: rpcndr.h:324
@ USER_MARSHAL_CB_UNMARSHALL
Definition: rpcndr.h:326
@ USER_MARSHAL_CB_FREE
Definition: rpcndr.h:327
@ USER_MARSHAL_CB_MARSHALL
Definition: rpcndr.h:325
#define USER_MARSHAL_CB_SIGNATURE
Definition: rpcndr.h:318
@ XLAT_CLIENT
Definition: rpcndr.h:464
@ XLAT_SERVER
Definition: rpcndr.h:463
#define NdrFcShort(s)
Definition: rpcndr.h:134
#define NdrFcLong(s)
Definition: rpcndr.h:135
#define RPC_S_INVALID_ARG
Definition: rpcnterr.h:23
#define RPC_X_INVALID_BUFFER
Definition: rpcnterr.h:40
#define RPC_S_OK
Definition: rpcnterr.h:22
RPC_STATUS WINAPI RpcStringFreeA(RPC_CSTR *String)
Definition: rpcrt4_main.c:158
long RPC_STATUS
Definition: rpc.h:52
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:197
#define U1(x)
Definition: test.h:202
#define win_skip
Definition: test.h:163
#define memset(x, y, z)
Definition: compat.h:39
HRESULT hr
Definition: shlfolder.c:183
void * RpcInterfaceInformation
Definition: rpcndr.h:362
const unsigned char * pFormatTypes
Definition: rpcndr.h:374
ULONG PointerLength
Definition: rpcndr.h:233
PNDR_CORRELATION_INFO pCorrInfo
Definition: rpcndr.h:262
unsigned char CorrDespIncrement
Definition: rpcndr.h:218
unsigned int fIsIn
Definition: rpcndr.h:240
unsigned int fBufferValid
Definition: rpcndr.h:243
struct NDR_POINTER_QUEUE_STATE * pPointerQueueState
Definition: rpcndr.h:215
void * pvDestContext
Definition: rpcndr.h:250
struct IRpcChannelBuffer * pRpcChannelBuffer
Definition: rpcndr.h:253
void * pMemoryList
Definition: rpcndr.h:264
PNDR_ASYNC_MESSAGE pAsyncMsg
Definition: rpcndr.h:261
unsigned int fHasReturn
Definition: rpcndr.h:237
unsigned char * Buffer
Definition: rpcndr.h:203
struct _FULL_PTR_XLAT_TABLES * FullPtrXlatTables
Definition: rpcndr.h:231
ULONG BufferLength
Definition: rpcndr.h:207
INT_PTR Unused
Definition: rpcndr.h:268
ULONG MemorySize
Definition: rpcndr.h:208
unsigned char * BufferEnd
Definition: rpcndr.h:205
DWORD dwDestContext
Definition: rpcndr.h:249
unsigned char * pCorrMemory
Definition: rpcndr.h:263
unsigned char uFlags
Definition: rpcndr.h:219
PRPC_MESSAGE RpcMsg
Definition: rpcndr.h:202
const struct _MIDL_STUB_DESC * StubDesc
Definition: rpcndr.h:230
unsigned char IsClient
Definition: rpcndr.h:210
void * LowStackMark
Definition: rpcndr.h:260
unsigned char * BufferStart
Definition: rpcndr.h:204
unsigned int BufferLength
Definition: rpcdcep.h:41
void * ImportContext
Definition: rpcdcep.h:47
unsigned int ProcNum
Definition: rpcdcep.h:42
PRPC_SYNTAX_IDENTIFIER TransferSyntax
Definition: rpcdcep.h:43
void * RpcInterfaceInformation
Definition: rpcdcep.h:44
void * Buffer
Definition: rpcdcep.h:40
RPC_BINDING_HANDLE Handle
Definition: rpcdcep.h:38
ULONG RpcFlags
Definition: rpcdcep.h:48
RPC_MGR_EPV * ManagerEpv
Definition: rpcdcep.h:46
USER_MARSHAL_CB_TYPE CBType
Definition: rpcndr.h:336
ULONG Signature
Definition: rpcndr.h:335
PMIDL_STUB_MESSAGE pStubMsg
Definition: rpcndr.h:333
LONGLONG b
struct define * next
Definition: compiler.c:65
Definition: nis.h:10
Definition: mem.c:156
LONG l1
LONG * pl1
char * pc1
Definition: send.c:48
Definition: ps.c:97
IPersist IPersist_iface
static CONST DWORD MemorySize[]
Definition: svga.c:32
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
int64_t LONGLONG
Definition: typedefs.h:68
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
int ret
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ _Strict_type_match_ POOL_TYPE _In_opt_ ULONG _In_ _Out_ WDFMEMORY * Memory
Definition: wdfmemory.h:169
#define WINAPI
Definition: msvc.h:6
#define RPC_S_SERVER_TOO_BUSY
Definition: winerror.h:1034
#define RPC_S_CALL_FAILED_DNE
Definition: winerror.h:1038
#define EPT_S_NOT_REGISTERED
Definition: winerror.h:1061
#define RPC_S_UNSUPPORTED_TRANS_SYN
Definition: winerror.h:1040
#define E_NOINTERFACE
Definition: winerror.h:2364
#define ERROR_INVALID_USER_BUFFER
Definition: winerror.h:1091
#define RPC_S_UNSUPPORTED_TYPE
Definition: winerror.h:1041
#define RPC_S_UNKNOWN_IF
Definition: winerror.h:1028
#define RPC_S_PROTOCOL_ERROR
Definition: winerror.h:1039
#define RPC_S_SERVER_UNAVAILABLE
Definition: winerror.h:1033
#define RPC_S_INVALID_BINDING
Definition: winerror.h:1013
#define RPC_S_COMM_FAILURE
Definition: winerror.h:1127
#define RPC_S_PROCNUM_OUT_OF_RANGE
Definition: winerror.h:1053
unsigned char BYTE
Definition: xxhash.c:193