ReactOS 0.4.16-dev-1946-g52006dd
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/test.h"
38
39static int my_alloc_called;
40static int my_free_called;
42{
44 return malloc(size);
45}
46
47static void CALLBACK my_free(void *ptr)
48{
50 free(ptr);
51}
52
54 {
55 NULL,
57 my_free,
58 { 0 },
59 0,
60 0,
61 0,
62 0,
63 NULL, /* format string, filled in by tests */
64 1, /* -error bounds_check flag */
65 0x20000, /* Ndr library version */
66 0,
67 0x50100a4, /* MIDL Version 5.1.164 */
68 0,
69 NULL,
70 0, /* notify & notify_flag routine table */
71 1, /* Flags */
72 0, /* Reserved3 */
73 0, /* Reserved4 */
74 0 /* Reserved5 */
75 };
76
78{
79 0
80};
81
83{
84 0,
86};
87
89{
91 {{0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x34}},{0,0}},
92 {{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}},
94 0,
95 0,
96 0,
97 0,
98 0,
99};
100
103
105{
106 RPC_MESSAGE RpcMessage;
107 MIDL_STUB_MESSAGE StubMsg;
108 MIDL_STUB_DESC StubDesc;
109 char ch = 0xde;
110
111 static const unsigned char fmtstr_up_char[] =
112 {
113 0x12, 0x8, /* FC_UP [simple_pointer] */
114 0x2, /* FC_CHAR */
115 0x5c, /* FC_PAD */
116 };
117
118 StubDesc = Object_StubDesc;
119 StubDesc.pFormatTypes = NULL;
120
122 &RpcMessage,
123 &StubMsg,
124 &StubDesc,
125 0);
126
127 StubMsg.BufferLength = 8;
128 StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = NdrOleAllocate(StubMsg.BufferLength);
129 NdrPointerMarshall(&StubMsg, (unsigned char*)&ch, fmtstr_up_char);
130 ok(StubMsg.Buffer == StubMsg.BufferStart + 5, "%p %p\n", StubMsg.Buffer, StubMsg.BufferStart);
131
132 use_pointer_ids = (*(unsigned int *)StubMsg.BufferStart != (UINT_PTR)&ch);
133 trace("Pointer marshalling using %s\n", use_pointer_ids ? "pointer ids" : "pointer value");
134
135 NdrOleFree(StubMsg.BufferStart);
136}
137
138static void test_ndr_simple_type(void)
139{
140 RPC_MESSAGE RpcMessage;
141 MIDL_STUB_MESSAGE StubMsg;
142 MIDL_STUB_DESC StubDesc;
143 LONG l, l2 = 0;
144
145 StubDesc = Object_StubDesc;
146 StubDesc.pFormatTypes = NULL;
147
149 &RpcMessage,
150 &StubMsg,
151 &StubDesc,
152 0);
153
154 StubMsg.BufferLength = 16;
155 StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = NdrOleAllocate(StubMsg.BufferLength);
156 StubMsg.BufferEnd = StubMsg.Buffer + 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, "%ld\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, "%ld\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, "%ld\n", l2);
171
172 NdrOleFree(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 %ld\n", msgpfx, StubMsg.BufferLength);
207
208 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
209 StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = NdrOleAllocate(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 %ld\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 %lu size %lu\n", msgpfx, StubMsg.MemorySize, size);
232 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %ld\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
233 if (formattypes[1] & FC_POINTER_DEREF)
234 ok(size == srcsize + sizeof(void *), "%s: mem size %lu\n", msgpfx, size);
235 else
236 ok(size == srcsize, "%s: mem size %lu\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 %lu size %lu\n", msgpfx, StubMsg.MemorySize, size);
242 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %ld\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
243 if (formattypes[1] & FC_POINTER_DEREF)
244 ok(size == srcsize + sizeof(void *) + 16, "%s: mem size %lu\n", msgpfx, size);
245 else
246 ok(size == srcsize + 16, "%s: mem size %lu\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 %lu size %lu\n", msgpfx, StubMsg.MemorySize, size);
252 ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %ld\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 %lu\n", msgpfx, size);
255 else
256 ok(size == srcsize + (srcsize == 8 ? 8 : sizeof(void *)), "%s: mem size %lu\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 %ld\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
274 ok(StubMsg.MemorySize == 0, "%s: memorysize %ld\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 StubMsg.pfnFree, 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);
284 free(mem);
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;
292 mem_orig = mem = calloc(1, size);
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 %ld\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
301 ok(StubMsg.MemorySize == 0, "%s: memorysize %ld\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);
310 free(mem);
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 %ld\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
326 ok(StubMsg.MemorySize == 0, "%s: memorysize %ld\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 %ld\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
345 ok(StubMsg.MemorySize == 0, "%s: memorysize %ld\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 %ld\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
367 ok(StubMsg.MemorySize == 0, "%s: memorysize %ld\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);
385 free(mem);
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 %ld\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
399 ok(StubMsg.MemorySize == 0, "%s: memorysize %ld\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);
412 free(mem);
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;
423 mem_orig = mem = calloc(1, size);
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 free(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 %ld\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
437 ok(StubMsg.MemorySize == 0, "%s: memorysize %ld\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);
452 free(mem);
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;
460 mem_orig = mem = calloc(1, size);
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 free(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 %ld\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen);
474 ok(StubMsg.MemorySize == 0, "%s: memorysize %ld\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);
489 free(mem);
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 NdrOleFree(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 %ld\n", StubMsg.BufferLength);
757
758 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
759 StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = NdrOleAllocate(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 %ld\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 = malloc(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 free(mem_orig);
867 NdrOleFree(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 %ld\n", msgpfx, StubMsg.BufferLength);
897 StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = NdrOleAllocate(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 %08lx %08lx %08lx\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 %lu\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 %lu\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 = calloc(1, 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 free(mem_orig);
1035 NdrOleFree(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 = calloc(1, 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 = NdrOleAllocate(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 NdrOleFree(StubMsg.RpcMsg->Buffer);
1270 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 = NdrOleAllocate(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 %ld 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 %ld 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 %ld references\n", server_obj.ref);
1390
1391 hr = IPersist_GetClassID(proxy, &clsid);
1392 ok(hr == S_OK, "got hr %#lx\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 %ld references\n", ref);
1397 ok(server_obj.ref == 1, "got %ld 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 %ld 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 %ld 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 %ld references\n", server_obj.ref);
1426 ok(client_obj.ref == 1, "got %ld references\n", client_obj.ref);
1427
1428 hr = IPersist_GetClassID(proxy, &clsid);
1429 ok(hr == S_OK, "got hr %#lx\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 %ld references\n", ref);
1434 ok(server_obj.ref == 1, "got %ld 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 %ld 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 %ld references\n", client_obj.ref);
1458
1459 hr = IPersist_GetClassID(proxy, &clsid);
1460 ok(hr == S_OK, "got hr %#lx\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 %ld references\n", client_obj.ref);
1465 ok(ref == client_obj.ref, "expected %ld references, got %ld\n", client_obj.ref, ref);
1466
1467 NdrInterfacePointerFree(&StubMsg, (unsigned char *)proxy, fmtstr_ip);
1468 ok(client_obj.ref == 1, "got %ld 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 %ld 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 %ld references\n", client_obj.ref);
1492
1493 NdrInterfacePointerFree(&StubMsg, (unsigned char *)proxy, fmtstr_ip);
1494 ok(client_obj.ref > 1, "got %ld references\n", client_obj.ref);
1495
1496 hr = IPersist_GetClassID(proxy, &clsid);
1497 ok(hr == S_OK, "got hr %#lx\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 %ld references\n", ref);
1502 ok(client_obj.ref == 1, "got %ld 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 %ld 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 %ld references\n", client_obj.ref);
1528 ok(server_obj.ref == 2, "got %ld 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 %#lx\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 %ld references\n", client_obj.ref);
1537 ok(ref == client_obj.ref, "expected %ld references, got %ld\n", client_obj.ref, ref);
1538
1539 NdrInterfacePointerFree(&StubMsg, (unsigned char *)proxy, fmtstr_ip);
1540 ok(client_obj.ref == 1, "got %ld references\n", client_obj.ref);
1541
1542 NdrOleFree(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%lx\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%lx\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%lx\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%lx\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%lx\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%lx\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%lx\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%lx\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%lx\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%lx\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%lx\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%lx\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%lx\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%lx\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%lx\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%lx\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%Ix\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, "%ld");
1716 ok( stubMsg->PointerLength == 0 ||
1717 broken(stubMsg->PointerLength == 1), /* win9x, nt4 */
1718 "%s: pAsyncMsg should have been set to zero instead of %ld\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->fUnused2 == 0 ||
1732 stubMsg->fUnused2 == -2, /* Vista */
1733 "%s: fUnused2 should have been set to 0 or -2 instead of %d\n", prefix, stubMsg->fUnused2);
1734 ok(stubMsg->fUnused3 == 0xffffcccc, "%s: fUnused3 should have been 0xffffcccc instead of 0x%x\n",
1735 prefix, stubMsg->fUnused3);
1736 ok(stubMsg->dwDestContext == MSHCTX_DIFFERENTMACHINE,
1737 "%s: dwDestContext should have been MSHCTX_DIFFERENTMACHINE instead of %ld\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, "%ld");
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%Ix\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%lx\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 %lu\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);
1846 todo_wine
1847 ok(stubMsg.BufferLength == 0, "stubMsg.BufferLength should have been 0 instead of %lu\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 %08lx\n", mem_list_v2->magic);
1889 ok(mem_list_v2->size == 24, "wrong size for p2 %ld\n", mem_list_v2->size);
1890 ok(mem_list_v2->unknown == 0, "wrong unknown for p2 0x%lx\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 %08lx\n", mem_list_v2->magic);
1897 ok(mem_list_v2->size == 16, "wrong size for p1 %ld\n", mem_list_v2->size);
1898 ok(mem_list_v2->unknown == 0, "wrong unknown for p1 0x%lx\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 %ld\n", StubMsg.BufferLength);
1948
1949 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
1950 StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = NdrOleAllocate(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 NdrOleFree(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 %ld\n", StubMsg.BufferLength);
2059
2060 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
2061 StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = NdrOleAllocate(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 %ld\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 = malloc(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 free(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 = malloc(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 free(mem_orig);
2149 NdrOleFree(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 %ld\n", StubMsg.BufferLength);
2184
2185 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
2186 StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = NdrOleAllocate(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 %ld\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 = malloc(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 free(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 free(mem_orig);
2244 NdrOleFree(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 %ld\n", StubMsg.BufferLength);
2257
2258 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
2259 StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = NdrOleAllocate(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 %ld\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 = malloc(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 free(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 free(mem_orig);
2317 NdrOleFree(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 enum {dummy} enum16;
2330 unsigned int size;
2331 unsigned int array[1];
2332 };
2333 struct conf_complex *memsrc;
2334 struct conf_complex *mem;
2335
2336 /*
2337 struct conf_complex
2338 {
2339 enum {dummy} enum16;
2340 int size;
2341 [size_is(size), unique] int array[];
2342 };
2343 */
2344 static const unsigned char fmtstr_complex_struct[] =
2345 {
2346 NdrFcShort(0x0),
2347/* 2 (int[]) */
2348 0x1b, /* FC_CARRAY */
2349 0x3, /* 3 */
2350 NdrFcShort(0x4), /* 4 */
2351 0x8, /* Corr desc: field size, FC_LONG */
2352 0x0, /* no operators */
2353 NdrFcShort(0xfffc), /* offset = -4 */
2354 0x08, /* FC_LONG */
2355 0x5b, /* FC_END */
2356/* 12 (struct conf_complex) */
2357 0x1a, /* FC_BOGUS_STRUCT */
2358 0x3, /* 3 */
2359 NdrFcShort(0x8), /* 8 */
2360 NdrFcShort(0xfff2), /* Offset= -14 (2) */
2361 NdrFcShort(0x0), /* Offset= 0 (18) */
2362 0x0d, /* FC_ENUM16 */
2363 0x08, /* FC_LONG */
2364 0x5c, /* FC_PAD */
2365 0x5b, /* FC_END */
2366 };
2367
2368 memsrc = calloc(1, FIELD_OFFSET(struct conf_complex, array[20]));
2369 memsrc->size = 20;
2370
2371 StubDesc = Object_StubDesc;
2372 StubDesc.pFormatTypes = fmtstr_complex_struct;
2373
2375 &RpcMessage,
2376 &StubMsg,
2377 &StubDesc,
2378 0);
2379
2380 StubMsg.BufferLength = 0;
2381 NdrComplexStructBufferSize(&StubMsg, (unsigned char *)memsrc, &fmtstr_complex_struct[12]);
2382 ok(StubMsg.BufferLength >= 92, "length %ld\n", StubMsg.BufferLength);
2383
2384 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
2385 StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = NdrOleAllocate(StubMsg.BufferLength);
2386 StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
2387
2388 ptr = NdrComplexStructMarshall(&StubMsg, (unsigned char *)memsrc, &fmtstr_complex_struct[12]);
2389 ok(ptr == NULL, "ret %p\n", ptr);
2390 ok(*(unsigned int *)StubMsg.BufferStart == 20, "Conformance should have been 20 instead of %u\n",
2391 *(unsigned int *)StubMsg.BufferStart);
2392 todo_wine
2393 ok(*(unsigned int *)(StubMsg.BufferStart + 8) == 20, "conf_complex.size should have been 20 instead of %u\n",
2394 *(unsigned int *)(StubMsg.BufferStart + 8));
2395 for (i = 0; i < 20; i++)
2396 ok(*(unsigned int *)(StubMsg.BufferStart + 12 + i * 4) == 0,
2397 "pointer id for conf_complex.array[%u] should have been 0 instead of 0x%x\n", i,
2398 *(unsigned int *)(StubMsg.BufferStart + 12 + i * 4));
2399
2400 /* Server */
2401 my_alloc_called = 0;
2402 StubMsg.IsClient = 0;
2403 mem = NULL;
2404 StubMsg.Buffer = StubMsg.BufferStart;
2405 ptr = NdrComplexStructUnmarshall(&StubMsg, (unsigned char **)&mem, &fmtstr_complex_struct[12], 0);
2406 ok(ptr == NULL, "ret %p\n", ptr);
2407 ok(mem->size == 20, "mem->size wasn't unmarshalled correctly (%d)\n", mem->size);
2408 ok(mem->array[0] == 0, "mem->array[0] wasn't unmarshalled correctly (%u)\n", mem->array[0]);
2409 StubMsg.pfnFree(mem);
2410
2411 NdrOleFree(StubMsg.RpcMsg->Buffer);
2412 free(memsrc);
2413}
2414
2415
2417{
2418 RPC_MESSAGE RpcMessage;
2419 MIDL_STUB_MESSAGE StubMsg;
2420 MIDL_STUB_DESC StubDesc;
2421 void *ptr;
2422 unsigned int i, j;
2423 struct conf_complex
2424 {
2425 unsigned int dim1, dim2;
2426 DWORD **array;
2427 };
2428 struct conf_complex memsrc;
2429 struct conf_complex *mem;
2430 DWORD *buf, expected_length;
2431
2432 static const unsigned char fmtstr_complex_array[] =
2433 {
2434
2435/* 0 */ 0x21, /* FC_BOGUS_ARRAY */
2436 0x3, /* 3 */
2437/* 2 */ NdrFcShort( 0x0 ), /* 0 */
2438/* 4 */ 0x19, 0x0, /* Corr desc: field pointer, FC_ULONG */
2439/* 6 */ NdrFcShort( 0x4 ), /* 4 */
2440/* 8 */ NdrFcLong( 0xffffffff ), /* -1 */
2441/* 12 */ 0x8, /* FC_LONG */
2442 0x5b, /* FC_END */
2443/* 14 */
2444 0x21, /* FC_BOGUS_ARRAY */
2445 0x3, /* 3 */
2446/* 16 */ NdrFcShort( 0x0 ), /* 0 */
2447/* 18 */ 0x19, /* Corr desc: field pointer, FC_ULONG */
2448 0x0, /* */
2449/* 20 */ NdrFcShort( 0x0 ), /* 0 */
2450/* 22 */ NdrFcLong( 0xffffffff ), /* -1 */
2451/* 26 */ 0x12, 0x0, /* FC_UP */
2452/* 28 */ NdrFcShort( 0xffe4 ), /* Offset= -28 (0) */
2453/* 30 */ 0x5c, /* FC_PAD */
2454 0x5b, /* FC_END */
2455
2456#ifdef _WIN64
2457/* 32 */ 0x1a, /* FC_BOGUS_STRUCT */
2458 0x3, /* 3 */
2459/* 34 */ NdrFcShort( 0x10 ), /* 16 */
2460/* 36 */ NdrFcShort( 0x0 ), /* 0 */
2461/* 38 */ NdrFcShort( 0x6 ), /* Offset= 6 (44) */
2462/* 40 */ 0x8, /* FC_LONG */
2463 0x8, /* FC_LONG */
2464/* 42 */ 0x36, /* FC_POINTER */
2465 0x5b, /* FC_END */
2466/* 44 */
2467 0x12, 0x0, /* FC_UP */
2468/* 46 */ NdrFcShort( 0xffe0 ), /* Offset= -32 (14) */
2469#else
2470/* 32 */
2471 0x16, /* FC_PSTRUCT */
2472 0x3, /* 3 */
2473/* 34 */ NdrFcShort( 0xc ), /* 12 */
2474/* 36 */ 0x4b, /* FC_PP */
2475 0x5c, /* FC_PAD */
2476/* 38 */ 0x46, /* FC_NO_REPEAT */
2477 0x5c, /* FC_PAD */
2478/* 40 */ NdrFcShort( 0x8 ), /* 8 */
2479/* 42 */ NdrFcShort( 0x8 ), /* 8 */
2480/* 44 */ 0x12, 0x0, /* FC_UP */
2481/* 46 */ NdrFcShort( 0xffe0 ), /* Offset= -32 (14) */
2482/* 48 */ 0x5b, /* FC_END */
2483 0x8, /* FC_LONG */
2484/* 50 */ 0x8, /* FC_LONG */
2485 0x8, /* FC_LONG */
2486/* 52 */ 0x5c, /* FC_PAD */
2487 0x5b, /* FC_END */
2488#endif
2489 };
2490
2491 memsrc.dim1 = 5;
2492 memsrc.dim2 = 3;
2493
2494 memsrc.array = calloc(memsrc.dim1, sizeof(DWORD *));
2495
2496 for(i = 0; i < memsrc.dim1; i++)
2497 {
2498 memsrc.array[i] = calloc(memsrc.dim2, sizeof(DWORD));
2499 for(j = 0; j < memsrc.dim2; j++)
2500 memsrc.array[i][j] = i * memsrc.dim2 + j;
2501 }
2502
2503 StubDesc = Object_StubDesc;
2504 StubDesc.pFormatTypes = fmtstr_complex_array;
2505
2507 &RpcMessage,
2508 &StubMsg,
2509 &StubDesc,
2510 0);
2511
2512 StubMsg.BufferLength = 0;
2513
2514#ifdef _WIN64
2516 (unsigned char *)&memsrc,
2517 &fmtstr_complex_array[32] );
2518#else
2519 NdrSimpleStructBufferSize( &StubMsg,
2520 (unsigned char *)&memsrc,
2521 &fmtstr_complex_array[32] );
2522#endif
2523
2524 expected_length = (4 + memsrc.dim1 * (2 + memsrc.dim2)) * 4;
2525 ok(StubMsg.BufferLength >= expected_length, "length %ld\n", StubMsg.BufferLength);
2526
2527 /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
2528 StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = NdrOleAllocate(StubMsg.BufferLength);
2529 StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
2530
2531#ifdef _WIN64
2532 ptr = NdrComplexStructMarshall( &StubMsg, (unsigned char *)&memsrc,
2533 &fmtstr_complex_array[32] );
2534#else
2535 ptr = NdrSimpleStructMarshall( &StubMsg, (unsigned char *)&memsrc,
2536 &fmtstr_complex_array[32] );
2537#endif
2538
2539 ok(ptr == NULL, "ret %p\n", ptr);
2540 ok((char*)StubMsg.Buffer == (char*)StubMsg.BufferStart + expected_length, "not at expected length\n");
2541
2542 buf = (DWORD *)StubMsg.BufferStart;
2543
2544 ok(*buf == memsrc.dim1, "dim1 should have been %d instead of %08lx\n", memsrc.dim1, *buf);
2545 buf++;
2546 ok(*buf == memsrc.dim2, "dim2 should have been %d instead of %08lx\n", memsrc.dim2, *buf);
2547 buf++;
2548 ok(*buf != 0, "pointer id should be non-zero\n");
2549 buf++;
2550 ok(*buf == memsrc.dim1, "Conformance should have been %d instead of %08lx\n", memsrc.dim1, *buf);
2551 buf++;
2552 for(i = 0; i < memsrc.dim1; i++)
2553 {
2554 ok(*buf != 0, "pointer id[%d] should be non-zero\n", i);
2555 buf++;
2556 }
2557 for(i = 0; i < memsrc.dim1; i++)
2558 {
2559 ok(*buf == memsrc.dim2, "Conformance should have been %d instead of %08lx\n", memsrc.dim2, *buf);
2560 buf++;
2561 for(j = 0; j < memsrc.dim2; j++)
2562 {
2563 ok(*buf == i * memsrc.dim2 + j, "got %08lx\n", *buf);
2564 buf++;
2565 }
2566 }
2567
2568 ok((void*)buf == StubMsg.Buffer, "not at end of buffer\n");
2569
2570 /* Server */
2571 my_alloc_called = 0;
2572 StubMsg.IsClient = 0;
2573 mem = NULL;
2574 StubMsg.Buffer = StubMsg.BufferStart;
2575#ifdef _WIN64
2576 ptr = NdrComplexStructUnmarshall( &StubMsg, (unsigned char **)&mem, &fmtstr_complex_array[32], 0);
2577#else
2578 ptr = NdrSimpleStructUnmarshall( &StubMsg, (unsigned char **)&mem, &fmtstr_complex_array[32], 0);
2579#endif
2580 ok(ptr == NULL, "ret %p\n", ptr);
2581 ok(mem->dim1 == memsrc.dim1, "mem->dim1 wasn't unmarshalled correctly (%d)\n", mem->dim1);
2582 ok(mem->dim2 == memsrc.dim2, "mem->dim2 wasn't unmarshalled correctly (%d)\n", mem->dim2);
2583 ok(mem->array[1][0] == memsrc.dim2, "mem->array[1][0] wasn't unmarshalled correctly (%ld)\n", mem->array[1][0]);
2584
2585 StubMsg.Buffer = StubMsg.BufferStart;
2586#ifdef _WIN64
2587 NdrComplexStructFree( &StubMsg, (unsigned char*)mem, &fmtstr_complex_array[32]);
2588#else
2589 NdrSimpleStructFree( &StubMsg, (unsigned char*)mem, &fmtstr_complex_array[32]);
2590#endif
2591
2592 NdrOleFree(StubMsg.RpcMsg->Buffer);
2593
2594 for(i = 0; i < memsrc.dim1; i++)
2595 free(memsrc.array[i]);
2596 free(memsrc.array);
2597}
2598
2599static void test_ndr_buffer(void)
2600{
2601 static unsigned char ncalrpc[] = "ncalrpc";
2602 static unsigned char endpoint[] = "winetest:test_ndr_buffer";
2603 RPC_MESSAGE RpcMessage;
2604 MIDL_STUB_MESSAGE StubMsg;
2606 unsigned char *ret;
2607 unsigned char *binding;
2610 ULONG prev_buffer_length;
2611 BOOL old_buffer_valid_location;
2612
2614
2615 status = RpcServerUseProtseqEpA(ncalrpc, 20, endpoint, NULL);
2616 ok(RPC_S_OK == status, "RpcServerUseProtseqEp failed with status %lu\n", status);
2618 ok(RPC_S_OK == status, "RpcServerRegisterIf failed with status %lu\n", status);
2619 status = RpcServerListen(1, 20, TRUE);
2620 ok(RPC_S_OK == status, "RpcServerListen failed with status %lu\n", status);
2621 if (status != RPC_S_OK)
2622 {
2623 /* Failed to create a server, running client tests is useless */
2624 return;
2625 }
2626
2628 ok(status == RPC_S_OK, "RpcStringBindingCompose failed (%lu)\n", status);
2629
2631 ok(status == RPC_S_OK, "RpcBindingFromStringBinding failed (%lu)\n", status);
2633
2634 NdrClientInitializeNew(&RpcMessage, &StubMsg, &StubDesc, 5);
2635
2636 my_alloc_called = 0;
2637 ret = NdrGetBuffer(&StubMsg, 10, Handle);
2638 ok(!my_alloc_called, "my_alloc got called\n");
2639 ok(ret == StubMsg.Buffer, "NdrGetBuffer should have returned the same value as StubMsg.Buffer instead of %p\n", ret);
2640 ok(RpcMessage.Handle != NULL, "RpcMessage.Handle should not have been NULL\n");
2641 ok(RpcMessage.Buffer != NULL, "RpcMessage.Buffer should not have been NULL\n");
2642 ok(RpcMessage.BufferLength == 10 ||
2643 broken(RpcMessage.BufferLength == 12), /* win2k */
2644 "RpcMessage.BufferLength should have been 10 instead of %d\n", RpcMessage.BufferLength);
2645 ok(RpcMessage.RpcFlags == 0, "RpcMessage.RpcFlags should have been 0x0 instead of 0x%lx\n", RpcMessage.RpcFlags);
2646 ok(StubMsg.Buffer != NULL, "Buffer should not have been NULL\n");
2647 ok(!StubMsg.BufferStart, "BufferStart should have been NULL instead of %p\n", StubMsg.BufferStart);
2648 ok(!StubMsg.BufferEnd, "BufferEnd should have been NULL instead of %p\n", StubMsg.BufferEnd);
2649 todo_wine
2650 ok(StubMsg.BufferLength == 0, "BufferLength should have left as 0 instead of being set to %ld\n", StubMsg.BufferLength);
2651 old_buffer_valid_location = !StubMsg.fBufferValid;
2652 if (old_buffer_valid_location)
2653 ok(broken(StubMsg.CorrDespIncrement == TRUE), "fBufferValid should have been TRUE instead of 0x%x\n", StubMsg.CorrDespIncrement);
2654 else
2655 ok(StubMsg.fBufferValid, "fBufferValid should have been non-zero instead of 0x%x\n", StubMsg.fBufferValid);
2656
2657 prev_buffer_length = RpcMessage.BufferLength;
2658 StubMsg.BufferLength = 1;
2659 my_free_called = 0;
2660 NdrFreeBuffer(&StubMsg);
2661 ok(!my_free_called, "my_free got called\n");
2662 ok(RpcMessage.Handle != NULL, "RpcMessage.Handle should not have been NULL\n");
2663 ok(RpcMessage.Buffer != NULL, "RpcMessage.Buffer should not have been NULL\n");
2664 ok(RpcMessage.BufferLength == prev_buffer_length, "RpcMessage.BufferLength should have been left as %ld instead of %d\n", prev_buffer_length, RpcMessage.BufferLength);
2665 ok(StubMsg.Buffer != NULL, "Buffer should not have been NULL\n");
2666 ok(StubMsg.BufferLength == 1, "BufferLength should have left as 1 instead of being set to %ld\n", StubMsg.BufferLength);
2667 if (old_buffer_valid_location)
2668 ok(broken(StubMsg.CorrDespIncrement == FALSE), "fBufferValid should have been FALSE instead of 0x%x\n", StubMsg.CorrDespIncrement);
2669 else
2670 ok(!StubMsg.fBufferValid, "fBufferValid should have been FALSE instead of %d\n", StubMsg.fBufferValid);
2671
2672 /* attempt double-free */
2673 NdrFreeBuffer(&StubMsg);
2674
2676
2678 ok(status == RPC_S_OK, "RpcServerUnregisterIf failed (%lu)\n", status);
2679}
2680
2682{
2683 RPC_STATUS rpc_status;
2684 MIDL_STUB_MESSAGE StubMsg;
2685 RPC_MESSAGE RpcMessage;
2686
2687 NdrClientInitializeNew(&RpcMessage, &StubMsg, &Object_StubDesc, 5);
2688
2689 for (rpc_status = 0; rpc_status < 10000; rpc_status++)
2690 {
2692 ULONG comm_status = 0;
2693 ULONG fault_status = 0;
2694 ULONG expected_comm_status = 0;
2695 ULONG expected_fault_status = 0;
2696 status = NdrMapCommAndFaultStatus(&StubMsg, &comm_status, &fault_status, rpc_status);
2697 ok(status == RPC_S_OK, "NdrMapCommAndFaultStatus failed with error %ld\n", status);
2698 switch (rpc_status)
2699 {
2702 case RPC_S_UNKNOWN_IF:
2711 case RPC_S_COMM_FAILURE:
2712 expected_comm_status = rpc_status;
2713 break;
2714 default:
2715 expected_fault_status = rpc_status;
2716 }
2717 ok(comm_status == expected_comm_status, "NdrMapCommAndFaultStatus should have mapped %ld to comm status %ld instead of %ld\n",
2718 rpc_status, expected_comm_status, comm_status);
2719 ok(fault_status == expected_fault_status, "NdrMapCommAndFaultStatus should have mapped %ld to fault status %ld instead of %ld\n",
2720 rpc_status, expected_fault_status, fault_status);
2721 }
2722}
2723
2725{
2727 MIDL_STUB_MESSAGE stubmsg;
2728 USER_MARSHAL_CB umcb;
2730 unsigned char buffer[16];
2731 void *rpc_channel_buffer = (void *)(ULONG_PTR)0xcafebabe;
2733
2734 /* unmarshall */
2735
2736 memset(&rpc_msg, 0xcc, sizeof(rpc_msg));
2737 rpc_msg.Buffer = buffer;
2738 rpc_msg.BufferLength = 16;
2739
2740 memset(&stubmsg, 0xcc, sizeof(stubmsg));
2741 stubmsg.RpcMsg = &rpc_msg;
2742 stubmsg.dwDestContext = MSHCTX_INPROC;
2743 stubmsg.pvDestContext = NULL;
2744 stubmsg.Buffer = buffer + 15;
2745 stubmsg.BufferLength = 0;
2746 stubmsg.BufferEnd = NULL;
2747 stubmsg.pRpcChannelBuffer = rpc_channel_buffer;
2748 stubmsg.StubDesc = NULL;
2749 stubmsg.pfnAllocate = my_alloc;
2750 stubmsg.pfnFree = my_free;
2751
2752 memset(&umcb, 0xcc, sizeof(umcb));
2753 umcb.Flags = MAKELONG(MSHCTX_INPROC, NDR_LOCAL_DATA_REPRESENTATION);
2754 umcb.pStubMsg = &stubmsg;
2757
2758 memset(&umi, 0xaa, sizeof(umi));
2759
2760 status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2761 ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %ld\n", status);
2762 ok( umi.InformationLevel == 1,
2763 "umi.InformationLevel was %lu instead of 1\n",
2764 umi.InformationLevel);
2765 ok( umi.Level1.Buffer == buffer + 15,
2766 "umi.Level1.Buffer was %p instead of %p\n",
2767 umi.Level1.Buffer, buffer);
2768 ok( umi.Level1.BufferSize == 1,
2769 "umi.Level1.BufferSize was %lu instead of 1\n",
2770 umi.Level1.BufferSize);
2771 ok( umi.Level1.pfnAllocate == my_alloc,
2772 "umi.Level1.pfnAllocate was %p instead of %p\n",
2773 umi.Level1.pfnAllocate, my_alloc);
2774 ok( umi.Level1.pfnFree == my_free,
2775 "umi.Level1.pfnFree was %p instead of %p\n",
2776 umi.Level1.pfnFree, my_free);
2777 ok( umi.Level1.pRpcChannelBuffer == rpc_channel_buffer,
2778 "umi.Level1.pRpcChannelBuffer was %p instead of %p\n",
2779 umi.Level1.pRpcChannelBuffer, rpc_channel_buffer);
2780
2781 /* buffer size */
2782
2783 rpc_msg.Buffer = buffer;
2784 rpc_msg.BufferLength = 16;
2785
2786 stubmsg.Buffer = buffer;
2787 stubmsg.BufferLength = 16;
2788 stubmsg.BufferEnd = NULL;
2789
2791
2792 memset(&umi, 0xaa, sizeof(umi));
2793
2794 status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2795 ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %ld\n", status);
2796 ok( umi.InformationLevel == 1,
2797 "umi.InformationLevel was %lu instead of 1\n",
2798 umi.InformationLevel);
2799 ok( umi.Level1.Buffer == NULL,
2800 "umi.Level1.Buffer was %p instead of NULL\n",
2801 umi.Level1.Buffer);
2802 ok( umi.Level1.BufferSize == 0,
2803 "umi.Level1.BufferSize was %lu instead of 0\n",
2804 umi.Level1.BufferSize);
2805 ok( umi.Level1.pfnAllocate == my_alloc,
2806 "umi.Level1.pfnAllocate was %p instead of %p\n",
2807 umi.Level1.pfnAllocate, my_alloc);
2808 ok( umi.Level1.pfnFree == my_free,
2809 "umi.Level1.pfnFree was %p instead of %p\n",
2810 umi.Level1.pfnFree, my_free);
2811 ok( umi.Level1.pRpcChannelBuffer == rpc_channel_buffer,
2812 "umi.Level1.pRpcChannelBuffer was %p instead of %p\n",
2813 umi.Level1.pRpcChannelBuffer, rpc_channel_buffer);
2814
2815 /* marshall */
2816
2817 rpc_msg.Buffer = buffer;
2818 rpc_msg.BufferLength = 16;
2819
2820 stubmsg.Buffer = buffer + 15;
2821 stubmsg.BufferLength = 0;
2822 stubmsg.BufferEnd = NULL;
2823
2825
2826 memset(&umi, 0xaa, sizeof(umi));
2827
2828 status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2829 ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %ld\n", status);
2830 ok( umi.InformationLevel == 1,
2831 "umi.InformationLevel was %lu instead of 1\n",
2832 umi.InformationLevel);
2833 ok( umi.Level1.Buffer == buffer + 15,
2834 "umi.Level1.Buffer was %p instead of %p\n",
2835 umi.Level1.Buffer, buffer);
2836 ok( umi.Level1.BufferSize == 1,
2837 "umi.Level1.BufferSize was %lu instead of 1\n",
2838 umi.Level1.BufferSize);
2839 ok( umi.Level1.pfnAllocate == my_alloc,
2840 "umi.Level1.pfnAllocate was %p instead of %p\n",
2841 umi.Level1.pfnAllocate, my_alloc);
2842 ok( umi.Level1.pfnFree == my_free,
2843 "umi.Level1.pfnFree was %p instead of %p\n",
2844 umi.Level1.pfnFree, my_free);
2845 ok( umi.Level1.pRpcChannelBuffer == rpc_channel_buffer,
2846 "umi.Level1.pRpcChannelBuffer was %p instead of %p\n",
2847 umi.Level1.pRpcChannelBuffer, rpc_channel_buffer);
2848
2849 /* free */
2850
2851 rpc_msg.Buffer = buffer;
2852 rpc_msg.BufferLength = 16;
2853
2854 stubmsg.Buffer = buffer;
2855 stubmsg.BufferLength = 16;
2856 stubmsg.BufferEnd = NULL;
2857
2859
2860 memset(&umi, 0xaa, sizeof(umi));
2861
2862 status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2863 ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %ld\n", status);
2864 ok( umi.InformationLevel == 1,
2865 "umi.InformationLevel was %lu instead of 1\n",
2866 umi.InformationLevel);
2867 ok( umi.Level1.Buffer == NULL,
2868 "umi.Level1.Buffer was %p instead of NULL\n",
2869 umi.Level1.Buffer);
2870 ok( umi.Level1.BufferSize == 0,
2871 "umi.Level1.BufferSize was %lu instead of 0\n",
2872 umi.Level1.BufferSize);
2873 ok( umi.Level1.pfnAllocate == my_alloc,
2874 "umi.Level1.pfnAllocate was %p instead of %p\n",
2875 umi.Level1.pfnAllocate, my_alloc);
2876 ok( umi.Level1.pfnFree == my_free,
2877 "umi.Level1.pfnFree was %p instead of %p\n",
2878 umi.Level1.pfnFree, my_free);
2879 ok( umi.Level1.pRpcChannelBuffer == rpc_channel_buffer,
2880 "umi.Level1.pRpcChannelBuffer was %p instead of %p\n",
2881 umi.Level1.pRpcChannelBuffer, rpc_channel_buffer);
2882
2883 /* boundary test */
2884
2885 rpc_msg.Buffer = buffer;
2886 rpc_msg.BufferLength = 15;
2887
2888 stubmsg.Buffer = buffer + 15;
2889 stubmsg.BufferLength = 0;
2890 stubmsg.BufferEnd = NULL;
2891
2893
2894 status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2895 ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %ld\n", status);
2896 ok( umi.Level1.BufferSize == 0,
2897 "umi.Level1.BufferSize was %lu instead of 0\n",
2898 umi.Level1.BufferSize);
2899
2900 /* error conditions */
2901
2902 rpc_msg.BufferLength = 14;
2903 status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2905 "NdrGetUserMarshalInfo should have failed with ERROR_INVALID_USER_BUFFER instead of %ld\n", status);
2906
2907 rpc_msg.BufferLength = 15;
2908 status = NdrGetUserMarshalInfo(&umcb.Flags, 9999, &umi);
2910 "NdrGetUserMarshalInfo should have failed with RPC_S_INVALID_ARG instead of %ld\n", status);
2911
2912 umcb.CBType = 9999;
2913 status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2914 ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %ld\n", status);
2915
2917 umcb.Signature = 0;
2918 status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi);
2920 "NdrGetUserMarshalInfo should have failed with RPC_S_INVALID_ARG instead of %ld\n", status);
2921}
2922
2924{
2925 ULONG encoded_size;
2928 char *buffer;
2929
2931 ok(status == RPC_S_INVALID_ARG, "got %ld\n", status);
2932
2934 ok(status == RPC_S_INVALID_ARG, "got %ld\n", status);
2935
2936 status = MesEncodeFixedBufferHandleCreate((char*)0xdeadbeef, 0, NULL, &handle);
2937 ok(status == RPC_X_INVALID_BUFFER, "got %ld\n", status);
2938
2939 buffer = (void*)((0xdeadbeef + 7) & ~7);
2941 ok(status == RPC_S_INVALID_ARG, "got %ld\n", status);
2942
2944 todo_wine
2945 ok(status == RPC_S_INVALID_ARG, "got %ld\n", status);
2946if (status == RPC_S_OK) {
2948}
2950 ok(status == RPC_S_INVALID_ARG, "got %ld\n", status);
2951
2952 status = MesEncodeFixedBufferHandleCreate(buffer, 32, &encoded_size, &handle);
2953 ok(status == RPC_S_OK, "got %ld\n", status);
2954
2956 &buffer, 32, &encoded_size);
2957 ok(status == RPC_S_INVALID_ARG, "got %ld\n", status);
2958
2959 /* convert to dynamic buffer handle */
2961 &buffer, 32, &encoded_size);
2962 ok(status == RPC_S_OK, "got %ld\n", status);
2963
2965 NULL, 32, &encoded_size);
2966 ok(status == RPC_S_INVALID_ARG, "got %ld\n", status);
2967
2969 &buffer, 32, NULL);
2970 ok(status == RPC_S_INVALID_ARG, "got %ld\n", status);
2971
2972 /* invalid handle type */
2974 &buffer, 32, &encoded_size);
2975 ok(status == RPC_S_INVALID_ARG, "got %ld\n", status);
2976
2978 ok(status == RPC_S_OK, "got %ld\n", status);
2979}
2980
2982{
2983 MIDL_STUB_MESSAGE stub_msg;
2984 BYTE buf[256];
2985
2986 memset( &stub_msg, 0, sizeof(stub_msg) );
2987 memset( buf, 0, sizeof(buf) );
2988
2989 NdrCorrelationInitialize( &stub_msg, buf, sizeof(buf), 0 );
2990 ok( stub_msg.CorrDespIncrement == 2 ||
2991 broken(stub_msg.CorrDespIncrement == 0), /* <= Win 2003 */
2992 "got %d\n", stub_msg.CorrDespIncrement );
2993
2994 memset( &stub_msg, 0, sizeof(stub_msg) );
2995 memset( buf, 0, sizeof(buf) );
2996
2997 stub_msg.CorrDespIncrement = 1;
2998 NdrCorrelationInitialize( &stub_msg, buf, sizeof(buf), 0 );
2999 ok( stub_msg.CorrDespIncrement == 1, "got %d\n", stub_msg.CorrDespIncrement );
3000}
3001
3002START_TEST( ndr_marshall )
3003{
3005
3026}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#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 free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#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 ERROR_INVALID_HANDLE
Definition: compat.h:98
#define CALLBACK
Definition: compat.h:35
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:418
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)
return ret
Definition: mutex.c:146
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
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
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
@ MES_ENCODE
Definition: midles.h:32
@ MES_DYNAMIC_BUFFER_HANDLE
Definition: midles.h:41
#define win_skip
Definition: minitest.h:67
#define todo_wine
Definition: minitest.h:80
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
#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:138
static void test_ndr_allocate(void)
static void test_NdrGetUserMarshalInfo(void)
static BOOL use_pointer_ids
Definition: ndr_marshall.c:102
static const MIDL_STUB_DESC Object_StubDesc
Definition: ndr_marshall.c:53
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:88
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:40
#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:77
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:41
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:39
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:101
static void test_struct_align(void)
static void CALLBACK my_free(void *ptr)
Definition: ndr_marshall.c:47
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:82
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:104
static void test_NdrMapCommAndFaultStatus(void)
static void test_fullpointer_xlat(void)
static void test_conf_complex_array(void)
static RPC_BINDING_HANDLE binding
Definition: server.c:166
const CLSID * clsid
Definition: msctf.cpp:50
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:163
RPC_STATUS WINAPI MesBufferHandleReset(handle_t Handle, ULONG HandleStyle, MIDL_ES_CODE Operation, char **Buffer, ULONG BufferSize, ULONG *EncodedSize)
Definition: ndr_es.c:129
RPC_STATUS RPC_ENTRY MesEncodeFixedBufferHandleCreate(char *Buffer, ULONG BufferSize, ULONG *pEncodedSize, handle_t *pHandle)
Definition: ndr_es.c:184
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:391
unsigned char *WINAPI NdrInterfacePointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
Definition: ndr_ole.c:277
unsigned char *WINAPI NdrInterfacePointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc)
Definition: ndr_ole.c:306
void WINAPI NdrOleFree(void *NodeToFree)
Definition: ndr_ole.c:399
void WINAPI NdrInterfacePointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
Definition: ndr_ole.c:342
void WINAPI NdrInterfacePointerFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
Definition: ndr_ole.c:379
_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
#define calloc
Definition: rosglue.h:14
RPC_STATUS WINAPI RpcBindingFree(RPC_BINDING_HANDLE *Binding)
Definition: rpc_binding.c:769
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:440
RPC_STATUS WINAPI RpcBindingFromStringBindingA(RPC_CSTR StringBinding, RPC_BINDING_HANDLE *Binding)
Definition: rpc_binding.c:822
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:68
@ USER_MARSHAL_CB_BUFFER_SIZE
Definition: rpcndr.h:307
@ USER_MARSHAL_CB_UNMARSHALL
Definition: rpcndr.h:309
@ USER_MARSHAL_CB_FREE
Definition: rpcndr.h:310
@ USER_MARSHAL_CB_MARSHALL
Definition: rpcndr.h:308
#define USER_MARSHAL_CB_SIGNATURE
Definition: rpcndr.h:301
@ XLAT_CLIENT
Definition: rpcndr.h:500
@ XLAT_SERVER
Definition: rpcndr.h:499
#define NdrFcShort(s)
Definition: rpcndr.h:99
#define NdrFcLong(s)
Definition: rpcndr.h:100
#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:164
long RPC_STATUS
Definition: rpc.h:48
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:197
#define memset(x, y, z)
Definition: compat.h:39
PCWSTR s2
Definition: shell32_main.h:38
HRESULT hr
Definition: shlfolder.c:183
void * RpcInterfaceInformation
Definition: rpcndr.h:378
const unsigned char * pFormatTypes
Definition: rpcndr.h:390
ULONG PointerLength
Definition: rpcndr.h:216
PNDR_CORRELATION_INFO pCorrInfo
Definition: rpcndr.h:245
unsigned char CorrDespIncrement
Definition: rpcndr.h:201
unsigned int fIsIn
Definition: rpcndr.h:223
unsigned int fBufferValid
Definition: rpcndr.h:226
struct NDR_POINTER_QUEUE_STATE * pPointerQueueState
Definition: rpcndr.h:198
void * pvDestContext
Definition: rpcndr.h:233
struct IRpcChannelBuffer * pRpcChannelBuffer
Definition: rpcndr.h:236
void * pMemoryList
Definition: rpcndr.h:247
PNDR_ASYNC_MESSAGE pAsyncMsg
Definition: rpcndr.h:244
unsigned int fHasReturn
Definition: rpcndr.h:220
unsigned char * Buffer
Definition: rpcndr.h:186
struct _FULL_PTR_XLAT_TABLES * FullPtrXlatTables
Definition: rpcndr.h:214
ULONG BufferLength
Definition: rpcndr.h:190
INT_PTR Unused
Definition: rpcndr.h:251
ULONG MemorySize
Definition: rpcndr.h:191
unsigned char * BufferEnd
Definition: rpcndr.h:188
DWORD dwDestContext
Definition: rpcndr.h:232
unsigned char * pCorrMemory
Definition: rpcndr.h:246
unsigned char uFlags
Definition: rpcndr.h:202
PRPC_MESSAGE RpcMsg
Definition: rpcndr.h:185
const struct _MIDL_STUB_DESC * StubDesc
Definition: rpcndr.h:213
unsigned char IsClient
Definition: rpcndr.h:193
void * LowStackMark
Definition: rpcndr.h:243
unsigned char * BufferStart
Definition: rpcndr.h:187
struct IRpcChannelBuffer * pRpcChannelBuffer
Definition: rpcndr.h:543
NDR_USER_MARSHAL_INFO_LEVEL1 Level1
Definition: rpcndr.h:552
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:319
ULONG Signature
Definition: rpcndr.h:318
PMIDL_STUB_MESSAGE pStubMsg
Definition: rpcndr.h:316
LONGLONG b
struct define * next
Definition: compiler.c:65
Definition: nis.h:10
Definition: mem.c:349
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
Character const *const prefix
Definition: tempnam.cpp:195
#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
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
_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:1390
#define RPC_S_CALL_FAILED_DNE
Definition: winerror.h:1394
#define EPT_S_NOT_REGISTERED
Definition: winerror.h:1418
#define RPC_S_UNSUPPORTED_TRANS_SYN
Definition: winerror.h:1397
#define E_NOINTERFACE
Definition: winerror.h:3479
#define ERROR_INVALID_USER_BUFFER
Definition: winerror.h:1448
#define RPC_S_UNSUPPORTED_TYPE
Definition: winerror.h:1398
#define RPC_S_UNKNOWN_IF
Definition: winerror.h:1384
#define RPC_S_PROTOCOL_ERROR
Definition: winerror.h:1395
#define RPC_S_SERVER_UNAVAILABLE
Definition: winerror.h:1389
#define RPC_S_INVALID_BINDING
Definition: winerror.h:1369
#define RPC_S_COMM_FAILURE
Definition: winerror.h:1484
#define RPC_S_PROCNUM_OUT_OF_RANGE
Definition: winerror.h:1410
unsigned char BYTE
Definition: xxhash.c:193