Sync to Wine-20050725:
[reactos.git] / reactos / lib / rpcrt4 / ndr_marshall.c
1 /*
2 * NDR data marshalling
3 *
4 * Copyright 2002 Greg Turner
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * TODO:
21 * - figure out whether we *really* got this right
22 * - check for errors and throw exceptions
23 */
24
25 #include <stdarg.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <assert.h>
29
30 #include "windef.h"
31 #include "winbase.h"
32 #include "winerror.h"
33 #include "winreg.h"
34
35 #include "ndr_misc.h"
36 #include "rpcndr.h"
37
38 #include "wine/unicode.h"
39 #include "wine/rpcfc.h"
40
41 #include "wine/debug.h"
42
43 WINE_DEFAULT_DEBUG_CHANNEL(ole);
44
45 #define BUFFER_PARANOIA 20
46
47 #if defined(__i386__)
48 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
49 (*((UINT32 *)(pchar)) = (uint32))
50
51 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
52 (*((UINT32 *)(pchar)))
53 #else
54 /* these would work for i386 too, but less efficient */
55 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
56 (*(pchar) = LOBYTE(LOWORD(uint32)), \
57 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
58 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
59 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
60 (uint32)) /* allow as r-value */
61
62 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
63 (MAKELONG( \
64 MAKEWORD(*(pchar), *((pchar)+1)), \
65 MAKEWORD(*((pchar)+2), *((pchar)+3))))
66 #endif
67
68 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
69 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
70 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
71 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
72 *(pchar) = HIBYTE(HIWORD(uint32)), \
73 (uint32)) /* allow as r-value */
74
75 #define BIG_ENDIAN_UINT32_READ(pchar) \
76 (MAKELONG( \
77 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
78 MAKEWORD(*((pchar)+1), *(pchar))))
79
80 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
81 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
82 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
83 # define NDR_LOCAL_UINT32_READ(pchar) \
84 BIG_ENDIAN_UINT32_READ(pchar)
85 #else
86 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
87 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
88 # define NDR_LOCAL_UINT32_READ(pchar) \
89 LITTLE_ENDIAN_UINT32_READ(pchar)
90 #endif
91
92 /* _Align must be the desired alignment minus 1,
93 * e.g. ALIGN_LENGTH(len, 3) to align on a dword boundary. */
94 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align))&~(_Align))
95 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
96 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
97 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
98
99 #define STD_OVERFLOW_CHECK(_Msg) do { \
100 TRACE("buffer=%d/%ld\n", _Msg->Buffer - _Msg->BufferStart, _Msg->BufferLength); \
101 if (_Msg->Buffer > _Msg->BufferEnd) ERR("buffer overflow %d bytes\n", _Msg->Buffer - _Msg->BufferEnd); \
102 } while (0)
103
104 #define NDR_TABLE_SIZE 128
105 #define NDR_TABLE_MASK 127
106
107 NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
108 0, 0, 0, 0, 0, 0, 0, 0,
109 0, 0, 0, 0, 0, 0, 0, 0,
110 /* 0x10 */
111 0,
112 /* 0x11 */
113 NdrPointerMarshall, NdrPointerMarshall,
114 NdrPointerMarshall, NdrPointerMarshall,
115 /* 0x15 */
116 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
117 NdrConformantStructMarshall, NdrConformantStructMarshall,
118 NdrConformantVaryingStructMarshall,
119 NdrComplexStructMarshall,
120 /* 0x1b */
121 NdrConformantArrayMarshall,
122 NdrConformantVaryingArrayMarshall,
123 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
124 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
125 NdrComplexArrayMarshall,
126 /* 0x22 */
127 NdrConformantStringMarshall, 0, 0,
128 NdrConformantStringMarshall, 0, 0, 0, 0,
129 /* 0x2a */
130 NdrEncapsulatedUnionMarshall,
131 NdrNonEncapsulatedUnionMarshall,
132 0,
133 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
134 /* 0x2f */
135 NdrInterfacePointerMarshall,
136 /* 0xb0 */
137 0, 0, 0, 0,
138 NdrUserMarshalMarshall
139 };
140 NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
141 0, 0, 0, 0, 0, 0, 0, 0,
142 0, 0, 0, 0, 0, 0, 0, 0,
143 /* 0x10 */
144 0,
145 /* 0x11 */
146 NdrPointerUnmarshall, NdrPointerUnmarshall,
147 NdrPointerUnmarshall, NdrPointerUnmarshall,
148 /* 0x15 */
149 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
150 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
151 NdrConformantVaryingStructUnmarshall,
152 NdrComplexStructUnmarshall,
153 /* 0x1b */
154 NdrConformantArrayUnmarshall,
155 NdrConformantVaryingArrayUnmarshall,
156 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
157 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
158 NdrComplexArrayUnmarshall,
159 /* 0x22 */
160 NdrConformantStringUnmarshall, 0, 0,
161 NdrConformantStringUnmarshall, 0, 0, 0, 0,
162 /* 0x2a */
163 NdrEncapsulatedUnionUnmarshall,
164 NdrNonEncapsulatedUnionUnmarshall,
165 0,
166 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
167 /* 0x2f */
168 NdrInterfacePointerUnmarshall,
169 /* 0xb0 */
170 0, 0, 0, 0,
171 NdrUserMarshalUnmarshall
172 };
173 NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
174 0, 0, 0, 0, 0, 0, 0, 0,
175 0, 0, 0, 0, 0, 0, 0, 0,
176 /* 0x10 */
177 0,
178 /* 0x11 */
179 NdrPointerBufferSize, NdrPointerBufferSize,
180 NdrPointerBufferSize, NdrPointerBufferSize,
181 /* 0x15 */
182 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
183 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
184 NdrConformantVaryingStructBufferSize,
185 NdrComplexStructBufferSize,
186 /* 0x1b */
187 NdrConformantArrayBufferSize,
188 NdrConformantVaryingArrayBufferSize,
189 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
190 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
191 NdrComplexArrayBufferSize,
192 /* 0x22 */
193 NdrConformantStringBufferSize, 0, 0,
194 NdrConformantStringBufferSize, 0, 0, 0, 0,
195 /* 0x2a */
196 NdrEncapsulatedUnionBufferSize,
197 NdrNonEncapsulatedUnionBufferSize,
198 0,
199 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
200 /* 0x2f */
201 NdrInterfacePointerBufferSize,
202 /* 0xb0 */
203 0, 0, 0, 0,
204 NdrUserMarshalBufferSize
205 };
206 NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
207 0, 0, 0, 0, 0, 0, 0, 0,
208 0, 0, 0, 0, 0, 0, 0, 0,
209 /* 0x10 */
210 0,
211 /* 0x11 */
212 NdrPointerMemorySize, NdrPointerMemorySize,
213 NdrPointerMemorySize, NdrPointerMemorySize,
214 /* 0x15 */
215 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
216 0, 0, 0,
217 NdrComplexStructMemorySize,
218 /* 0x1b */
219 NdrConformantArrayMemorySize, 0, 0, 0, 0, 0,
220 NdrComplexArrayMemorySize,
221 /* 0x22 */
222 NdrConformantStringMemorySize, 0, 0,
223 NdrConformantStringMemorySize, 0, 0, 0, 0,
224 /* 0x2a */
225 0, 0, 0, 0, 0,
226 /* 0x2f */
227 NdrInterfacePointerMemorySize,
228 /* 0xb0 */
229 0, 0, 0, 0,
230 NdrUserMarshalMemorySize
231 };
232 NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
233 0, 0, 0, 0, 0, 0, 0, 0,
234 0, 0, 0, 0, 0, 0, 0, 0,
235 /* 0x10 */
236 0,
237 /* 0x11 */
238 NdrPointerFree, NdrPointerFree,
239 NdrPointerFree, NdrPointerFree,
240 /* 0x15 */
241 NdrSimpleStructFree, NdrSimpleStructFree,
242 NdrConformantStructFree, NdrConformantStructFree,
243 NdrConformantVaryingStructFree,
244 NdrComplexStructFree,
245 /* 0x1b */
246 NdrConformantArrayFree,
247 NdrConformantVaryingArrayFree,
248 NdrFixedArrayFree, NdrFixedArrayFree,
249 NdrVaryingArrayFree, NdrVaryingArrayFree,
250 NdrComplexArrayFree,
251 /* 0x22 */
252 0, 0, 0,
253 0, 0, 0, 0, 0,
254 /* 0x2a */
255 NdrEncapsulatedUnionFree,
256 NdrNonEncapsulatedUnionFree,
257 0,
258 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
259 /* 0x2f */
260 NdrInterfacePointerFree,
261 /* 0xb0 */
262 0, 0, 0, 0,
263 NdrUserMarshalFree
264 };
265
266 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
267 {
268 /* hmm, this is probably supposed to do more? */
269 return pStubMsg->pfnAllocate(len);
270 }
271
272 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
273 {
274 pStubMsg->pfnFree(Pointer);
275 }
276
277 PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
278 {
279 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
280 pStubMsg->Buffer += 4;
281 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
282 return pFormat+4;
283 }
284
285 PFORMAT_STRING ComputeConformance(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
286 PFORMAT_STRING pFormat, ULONG_PTR def)
287 {
288 BYTE dtype = pFormat[0] & 0xf;
289 DWORD ofs = (DWORD)pFormat[2] | ((DWORD)pFormat[3] << 8);
290 LPVOID ptr = NULL;
291 DWORD data = 0;
292
293 if (pFormat[0] == 0xff) {
294 /* null descriptor */
295 pStubMsg->MaxCount = def;
296 goto finish_conf;
297 }
298
299 switch (pFormat[0] & 0xf0) {
300 case RPC_FC_NORMAL_CONFORMANCE:
301 TRACE("normal conformance, ofs=%ld\n", ofs);
302 ptr = pMemory + ofs;
303 break;
304 case RPC_FC_POINTER_CONFORMANCE:
305 TRACE("pointer conformance, ofs=%ld\n", ofs);
306 ptr = pStubMsg->Memory + ofs;
307 break;
308 case RPC_FC_TOP_LEVEL_CONFORMANCE:
309 TRACE("toplevel conformance, ofs=%ld\n", ofs);
310 if (pStubMsg->StackTop) {
311 ptr = pStubMsg->StackTop + ofs;
312 }
313 else {
314 /* -Os mode, MaxCount is already set */
315 goto finish_conf;
316 }
317 break;
318 case RPC_FC_CONSTANT_CONFORMANCE:
319 data = ofs | ((DWORD)pFormat[1] << 16);
320 TRACE("constant conformance, val=%ld\n", data);
321 pStubMsg->MaxCount = data;
322 goto finish_conf;
323 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
324 FIXME("toplevel multidimensional conformance, ofs=%ld\n", ofs);
325 if (pStubMsg->StackTop) {
326 ptr = pStubMsg->StackTop + ofs;
327 }
328 else {
329 /* ? */
330 goto done_conf_grab;
331 }
332 break;
333 default:
334 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
335 }
336
337 switch (pFormat[1]) {
338 case RPC_FC_DEREFERENCE:
339 ptr = *(LPVOID*)ptr;
340 break;
341 case RPC_FC_CALLBACK:
342 /* ofs is index into StubDesc->apfnExprEval */
343 FIXME("handle callback\n");
344 goto finish_conf;
345 default:
346 break;
347 }
348
349 switch (dtype) {
350 case RPC_FC_LONG:
351 case RPC_FC_ULONG:
352 data = *(DWORD*)ptr;
353 break;
354 case RPC_FC_SHORT:
355 data = *(SHORT*)ptr;
356 break;
357 case RPC_FC_USHORT:
358 data = *(USHORT*)ptr;
359 break;
360 case RPC_FC_SMALL:
361 data = *(CHAR*)ptr;
362 break;
363 case RPC_FC_USMALL:
364 data = *(UCHAR*)ptr;
365 break;
366 default:
367 FIXME("unknown conformance data type %x\n", dtype);
368 goto done_conf_grab;
369 }
370 TRACE("dereferenced data type %x at %p, got %ld\n", dtype, ptr, data);
371
372 done_conf_grab:
373 switch (pFormat[1]) {
374 case 0: /* no op */
375 pStubMsg->MaxCount = data;
376 break;
377 case RPC_FC_DEREFERENCE:
378 /* already handled */
379 break;
380 default:
381 FIXME("unknown conformance op %d\n", pFormat[1]);
382 goto finish_conf;
383 }
384
385 finish_conf:
386 TRACE("resulting conformance is %ld\n", pStubMsg->MaxCount);
387 return pFormat+4;
388 }
389
390
391 /*
392 * NdrConformantString:
393 *
394 * What MS calls a ConformantString is, in DCE terminology,
395 * a Varying-Conformant String.
396 * [
397 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
398 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
399 * into unmarshalled string)
400 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
401 * [
402 * data: CHARTYPE[maxlen]
403 * ]
404 * ], where CHARTYPE is the appropriate character type (specified externally)
405 *
406 */
407
408 /***********************************************************************
409 * NdrConformantStringMarshall [RPCRT4.@]
410 */
411 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
412 unsigned char *pszMessage, PFORMAT_STRING pFormat)
413 {
414 unsigned long len, esize;
415 unsigned char *c;
416
417 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
418
419 assert(pFormat);
420 if (pszMessage == NULL) {
421 TRACE("string=%s\n", debugstr_a(pszMessage));
422 len = 0;
423 esize = 0;
424 }
425 else if (*pFormat == RPC_FC_C_CSTRING) {
426 TRACE("string=%s\n", debugstr_a(pszMessage));
427 len = strlen(pszMessage)+1;
428 esize = 1;
429 }
430 else if (*pFormat == RPC_FC_C_WSTRING) {
431 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
432 len = strlenW((LPWSTR)pszMessage)+1;
433 esize = 2;
434 }
435 else {
436 ERR("Unhandled string type: %#x\n", *pFormat);
437 /* FIXME: raise an exception. */
438 return NULL;
439 }
440
441 if (pFormat[1] != RPC_FC_PAD) {
442 FIXME("sized string format=%d\n", pFormat[1]);
443 }
444
445 assert( (pStubMsg->BufferLength >= (len*esize + 13)) && (pStubMsg->Buffer != NULL) );
446
447 c = pStubMsg->Buffer;
448 memset(c, 0, 12);
449 NDR_LOCAL_UINT32_WRITE(c, len); /* max length: strlen + 1 (for '\0') */
450 c += 8; /* offset: 0 */
451 NDR_LOCAL_UINT32_WRITE(c, len); /* actual length: (same) */
452 c += 4;
453 if (len != 0) {
454 memcpy(c, pszMessage, len*esize); /* the string itself */
455 c += len*esize;
456 }
457 pStubMsg->Buffer = c;
458
459 STD_OVERFLOW_CHECK(pStubMsg);
460
461 /* success */
462 return NULL; /* is this always right? */
463 }
464
465 /***********************************************************************
466 * NdrConformantStringBufferSize [RPCRT4.@]
467 */
468 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
469 unsigned char* pMemory, PFORMAT_STRING pFormat)
470 {
471 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
472
473 assert(pFormat);
474 if (pMemory == NULL) {
475 /* we need 12 octets for the [maxlen, offset, len] DWORDS */
476 TRACE("string=NULL\n");
477 pStubMsg->BufferLength += 12 + BUFFER_PARANOIA;
478 }
479 else if (*pFormat == RPC_FC_C_CSTRING) {
480 /* we need 12 octets for the [maxlen, offset, len] DWORDS, + 1 octet for '\0' */
481 TRACE("string=%s\n", debugstr_a(pMemory));
482 pStubMsg->BufferLength += strlen(pMemory) + 13 + BUFFER_PARANOIA;
483 }
484 else if (*pFormat == RPC_FC_C_WSTRING) {
485 /* we need 12 octets for the [maxlen, offset, len] DWORDS, + 2 octets for L'\0' */
486 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
487 pStubMsg->BufferLength += strlenW((LPWSTR)pMemory)*2 + 14 + BUFFER_PARANOIA;
488 }
489 else {
490 ERR("Unhandled string type: %#x\n", *pFormat);
491 /* FIXME: raise an exception */
492 }
493
494 if (pFormat[1] != RPC_FC_PAD) {
495 FIXME("sized string format=%d\n", pFormat[1]);
496 }
497 }
498
499 /************************************************************************
500 * NdrConformantStringMemorySize [RPCRT4.@]
501 */
502 unsigned long WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
503 PFORMAT_STRING pFormat )
504 {
505 unsigned long rslt = 0;
506
507 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
508
509 assert(pStubMsg && pFormat);
510
511 if (*pFormat == RPC_FC_C_CSTRING) {
512 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
513 }
514 else if (*pFormat == RPC_FC_C_WSTRING) {
515 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
516 }
517 else {
518 ERR("Unhandled string type: %#x\n", *pFormat);
519 /* FIXME: raise an exception */
520 }
521
522 if (pFormat[1] != RPC_FC_PAD) {
523 FIXME("sized string format=%d\n", pFormat[1]);
524 }
525
526 TRACE(" --> %lu\n", rslt);
527 return rslt;
528 }
529
530 /************************************************************************
531 * NdrConformantStringUnmarshall [RPCRT4.@]
532 */
533 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
534 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
535 {
536 unsigned long len, esize, ofs;
537 unsigned char *pMem;
538
539 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
540 pStubMsg, *ppMemory, pFormat, fMustAlloc);
541
542 assert(pFormat && ppMemory && pStubMsg);
543
544 pStubMsg->Buffer += 4;
545 ofs = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
546 pStubMsg->Buffer += 4;
547 len = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
548 pStubMsg->Buffer += 4;
549
550 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
551 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
552 else {
553 ERR("Unhandled string type: %#x\n", *pFormat);
554 /* FIXME: raise an exception */
555 esize = 0;
556 }
557
558 if (pFormat[1] != RPC_FC_PAD) {
559 FIXME("sized string format=%d\n", pFormat[1]);
560 }
561
562 if (fMustAlloc) {
563 *ppMemory = NdrAllocate(pStubMsg, len*esize + BUFFER_PARANOIA);
564 } else {
565 if (pStubMsg->ReuseBuffer && !*ppMemory)
566 /* for servers, we may just point straight into the RPC buffer, I think
567 * (I guess that's what MS does since MIDL code doesn't try to free) */
568 *ppMemory = pStubMsg->Buffer - ofs*esize;
569 /* for clients, memory should be provided by caller */
570 }
571
572 if (len == 0) {
573 *ppMemory = NULL;
574 return NULL;
575 }
576
577 pMem = *ppMemory + ofs*esize;
578
579 if (pMem != pStubMsg->Buffer)
580 memcpy(pMem, pStubMsg->Buffer, len*esize);
581
582 pStubMsg->Buffer += len*esize;
583
584 if (*pFormat == RPC_FC_C_CSTRING) {
585 TRACE("string=%s\n", debugstr_a(pMem));
586 }
587 else if (*pFormat == RPC_FC_C_WSTRING) {
588 TRACE("string=%s\n", debugstr_w((LPWSTR)pMem));
589 }
590
591 return NULL; /* FIXME: is this always right? */
592 }
593
594 static inline void dump_pointer_attr(unsigned char attr)
595 {
596 if (attr & RPC_FC_P_ALLOCALLNODES)
597 TRACE(" RPC_FC_P_ALLOCALLNODES");
598 if (attr & RPC_FC_P_DONTFREE)
599 TRACE(" RPC_FC_P_DONTFREE");
600 if (attr & RPC_FC_P_ONSTACK)
601 TRACE(" RPC_FC_P_ONSTACK");
602 if (attr & RPC_FC_P_SIMPLEPOINTER)
603 TRACE(" RPC_FC_P_SIMPLEPOINTER");
604 if (attr & RPC_FC_P_DEREF)
605 TRACE(" RPC_FC_P_DEREF");
606 TRACE("\n");
607 }
608
609 /***********************************************************************
610 * PointerMarshall
611 */
612 void WINAPI PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
613 unsigned char *Buffer,
614 unsigned char *Pointer,
615 PFORMAT_STRING pFormat)
616 {
617 unsigned type = pFormat[0], attr = pFormat[1];
618 PFORMAT_STRING desc;
619 NDR_MARSHALL m;
620
621 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
622 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
623 pFormat += 2;
624 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
625 else desc = pFormat + *(const SHORT*)pFormat;
626 if (attr & RPC_FC_P_DEREF) {
627 Pointer = *(unsigned char**)Pointer;
628 TRACE("deref => %p\n", Pointer);
629 }
630
631 switch (type) {
632 case RPC_FC_RP: /* ref pointer (always non-null) */
633 #if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
634 if (!Pointer)
635 RpcRaiseException(RPC_X_NULL_REF_POINTER);
636 #endif
637 break;
638 case RPC_FC_UP: /* unique pointer */
639 case RPC_FC_OP: /* object pointer - same as unique here */
640 TRACE("writing %p to buffer\n", Pointer);
641 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, (unsigned long)Pointer);
642 pStubMsg->Buffer += 4;
643 break;
644 case RPC_FC_FP:
645 default:
646 FIXME("unhandled ptr type=%02x\n", type);
647 RpcRaiseException(RPC_X_BAD_STUB_DATA);
648 }
649
650 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
651
652 if (Pointer) {
653 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
654 if (m) m(pStubMsg, Pointer, desc);
655 else FIXME("no marshaller for data type=%02x\n", *desc);
656 }
657
658 STD_OVERFLOW_CHECK(pStubMsg);
659 }
660
661 /***********************************************************************
662 * PointerUnmarshall
663 */
664 void WINAPI PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
665 unsigned char *Buffer,
666 unsigned char **pPointer,
667 PFORMAT_STRING pFormat,
668 unsigned char fMustAlloc)
669 {
670 unsigned type = pFormat[0], attr = pFormat[1];
671 PFORMAT_STRING desc;
672 NDR_UNMARSHALL m;
673 DWORD pointer_id = 0;
674
675 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pFormat, fMustAlloc);
676 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
677 pFormat += 2;
678 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
679 else desc = pFormat + *(const SHORT*)pFormat;
680 if (attr & RPC_FC_P_DEREF) {
681 pPointer = *(unsigned char***)pPointer;
682 TRACE("deref => %p\n", pPointer);
683 }
684
685 switch (type) {
686 case RPC_FC_RP: /* ref pointer (always non-null) */
687 pointer_id = ~0UL;
688 break;
689 case RPC_FC_UP: /* unique pointer */
690 pointer_id = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
691 pStubMsg->Buffer += 4;
692 break;
693 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
694 case RPC_FC_FP:
695 default:
696 FIXME("unhandled ptr type=%02x\n", type);
697 RpcRaiseException(RPC_X_BAD_STUB_DATA);
698 }
699
700 *pPointer = NULL;
701
702 if (pointer_id) {
703 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
704 if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
705 else FIXME("no unmarshaller for data type=%02x\n", *desc);
706 }
707
708 TRACE("pointer=%p\n", *pPointer);
709 }
710
711 /***********************************************************************
712 * PointerBufferSize
713 */
714 void WINAPI PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
715 unsigned char *Pointer,
716 PFORMAT_STRING pFormat)
717 {
718 unsigned type = pFormat[0], attr = pFormat[1];
719 PFORMAT_STRING desc;
720 NDR_BUFFERSIZE m;
721
722 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
723 TRACE("type=%d, attr=%d\n", type, attr);
724 pFormat += 2;
725 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
726 else desc = pFormat + *(const SHORT*)pFormat;
727 if (attr & RPC_FC_P_DEREF) {
728 Pointer = *(unsigned char**)Pointer;
729 TRACE("deref => %p\n", Pointer);
730 }
731
732 switch (type) {
733 case RPC_FC_RP: /* ref pointer (always non-null) */
734 break;
735 case RPC_FC_OP:
736 case RPC_FC_UP:
737 pStubMsg->BufferLength += 4;
738 /* NULL pointer has no further representation */
739 if (!Pointer)
740 return;
741 break;
742 case RPC_FC_FP:
743 default:
744 FIXME("unhandled ptr type=%02x\n", type);
745 RpcRaiseException(RPC_X_BAD_STUB_DATA);
746 }
747
748 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
749 if (m) m(pStubMsg, Pointer, desc);
750 else FIXME("no buffersizer for data type=%02x\n", *desc);
751 }
752
753 /***********************************************************************
754 * PointerMemorySize [RPCRT4.@]
755 */
756 unsigned long WINAPI PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
757 unsigned char *Buffer,
758 PFORMAT_STRING pFormat)
759 {
760 unsigned type = pFormat[0], attr = pFormat[1];
761 PFORMAT_STRING desc;
762 NDR_MEMORYSIZE m;
763
764 FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat);
765 TRACE("type=%d, attr=", type); dump_pointer_attr(attr);
766 pFormat += 2;
767 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
768 else desc = pFormat + *(const SHORT*)pFormat;
769 if (attr & RPC_FC_P_DEREF) {
770 TRACE("deref\n");
771 }
772
773 switch (type) {
774 case RPC_FC_RP: /* ref pointer (always non-null) */
775 break;
776 default:
777 FIXME("unhandled ptr type=%02x\n", type);
778 RpcRaiseException(RPC_X_BAD_STUB_DATA);
779 }
780
781 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
782 if (m) m(pStubMsg, desc);
783 else FIXME("no memorysizer for data type=%02x\n", *desc);
784
785 return 0;
786 }
787
788 /***********************************************************************
789 * PointerFree [RPCRT4.@]
790 */
791 void WINAPI PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
792 unsigned char *Pointer,
793 PFORMAT_STRING pFormat)
794 {
795 unsigned type = pFormat[0], attr = pFormat[1];
796 PFORMAT_STRING desc;
797 NDR_FREE m;
798
799 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
800 TRACE("type=%d, attr=", type); dump_pointer_attr(attr);
801 if (attr & RPC_FC_P_DONTFREE) return;
802 pFormat += 2;
803 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
804 else desc = pFormat + *(const SHORT*)pFormat;
805 if (attr & RPC_FC_P_DEREF) {
806 Pointer = *(unsigned char**)Pointer;
807 TRACE("deref => %p\n", Pointer);
808 }
809
810 if (!Pointer) return;
811
812 m = NdrFreer[*desc & NDR_TABLE_MASK];
813 if (m) m(pStubMsg, Pointer, desc);
814
815 /* hmm... is this sensible?
816 * perhaps we should check if the memory comes from NdrAllocate,
817 * and deallocate only if so - checking if the pointer is between
818 * BufferStart and BufferEnd is probably no good since the buffer
819 * may be reallocated when the server wants to marshal the reply */
820 switch (*desc) {
821 case RPC_FC_BOGUS_STRUCT:
822 case RPC_FC_BOGUS_ARRAY:
823 case RPC_FC_USER_MARSHAL:
824 break;
825 default:
826 FIXME("unhandled data type=%02x\n", *desc);
827 case RPC_FC_CARRAY:
828 case RPC_FC_C_CSTRING:
829 case RPC_FC_C_WSTRING:
830 if (pStubMsg->ReuseBuffer) goto notfree;
831 break;
832 case RPC_FC_IP:
833 goto notfree;
834 }
835
836 if (attr & RPC_FC_P_ONSTACK) {
837 TRACE("not freeing stack ptr %p\n", Pointer);
838 return;
839 }
840 TRACE("freeing %p\n", Pointer);
841 NdrFree(pStubMsg, Pointer);
842 return;
843 notfree:
844 TRACE("not freeing %p\n", Pointer);
845 }
846
847 /***********************************************************************
848 * EmbeddedPointerMarshall
849 */
850 unsigned char * WINAPI EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
851 unsigned char *pMemory,
852 PFORMAT_STRING pFormat)
853 {
854 unsigned char *Mark = pStubMsg->BufferMark;
855 unsigned long Offset = pStubMsg->Offset;
856 unsigned ofs, rep, count, stride, xofs;
857
858 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
859
860 if (*pFormat != RPC_FC_PP) return NULL;
861 pFormat += 2;
862
863 while (pFormat[0] != RPC_FC_END) {
864 switch (pFormat[0]) {
865 default:
866 FIXME("unknown repeat type %d\n", pFormat[0]);
867 case RPC_FC_NO_REPEAT:
868 rep = 1;
869 stride = 0;
870 ofs = 0;
871 count = 1;
872 xofs = 0;
873 pFormat += 2;
874 break;
875 case RPC_FC_FIXED_REPEAT:
876 rep = *(const WORD*)&pFormat[2];
877 stride = *(const WORD*)&pFormat[4];
878 ofs = *(const WORD*)&pFormat[6];
879 count = *(const WORD*)&pFormat[8];
880 xofs = 0;
881 pFormat += 10;
882 break;
883 case RPC_FC_VARIABLE_REPEAT:
884 rep = pStubMsg->MaxCount;
885 stride = *(const WORD*)&pFormat[2];
886 ofs = *(const WORD*)&pFormat[4];
887 count = *(const WORD*)&pFormat[6];
888 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
889 pFormat += 8;
890 break;
891 }
892 /* ofs doesn't seem to matter in this context */
893 while (rep) {
894 PFORMAT_STRING info = pFormat;
895 unsigned char *membase = pMemory + xofs;
896 unsigned u;
897 for (u=0; u<count; u++,info+=8) {
898 unsigned char *memptr = membase + *(const SHORT*)&info[0];
899 unsigned char *bufptr = Mark + *(const SHORT*)&info[2];
900 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
901 }
902 rep--;
903 }
904 pFormat += 8 * count;
905 }
906
907 STD_OVERFLOW_CHECK(pStubMsg);
908
909 return NULL;
910 }
911
912 /***********************************************************************
913 * EmbeddedPointerUnmarshall
914 */
915 unsigned char * WINAPI EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
916 unsigned char **ppMemory,
917 PFORMAT_STRING pFormat,
918 unsigned char fMustAlloc)
919 {
920 unsigned char *Mark = pStubMsg->BufferMark;
921 unsigned long Offset = pStubMsg->Offset;
922 unsigned ofs, rep, count, stride, xofs;
923
924 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
925
926 if (*pFormat != RPC_FC_PP) return NULL;
927 pFormat += 2;
928
929 while (pFormat[0] != RPC_FC_END) {
930 switch (pFormat[0]) {
931 default:
932 FIXME("unknown repeat type %d\n", pFormat[0]);
933 case RPC_FC_NO_REPEAT:
934 rep = 1;
935 stride = 0;
936 ofs = 0;
937 count = 1;
938 xofs = 0;
939 pFormat += 2;
940 break;
941 case RPC_FC_FIXED_REPEAT:
942 rep = *(const WORD*)&pFormat[2];
943 stride = *(const WORD*)&pFormat[4];
944 ofs = *(const WORD*)&pFormat[6];
945 count = *(const WORD*)&pFormat[8];
946 xofs = 0;
947 pFormat += 10;
948 break;
949 case RPC_FC_VARIABLE_REPEAT:
950 rep = pStubMsg->MaxCount;
951 stride = *(const WORD*)&pFormat[2];
952 ofs = *(const WORD*)&pFormat[4];
953 count = *(const WORD*)&pFormat[6];
954 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
955 pFormat += 8;
956 break;
957 }
958 /* ofs doesn't seem to matter in this context */
959 while (rep) {
960 PFORMAT_STRING info = pFormat;
961 unsigned char *membase = *ppMemory + xofs;
962 unsigned u;
963 for (u=0; u<count; u++,info+=8) {
964 unsigned char *memptr = membase + *(const SHORT*)&info[0];
965 unsigned char *bufptr = Mark + *(const SHORT*)&info[2];
966 PointerUnmarshall(pStubMsg, bufptr, (unsigned char**)memptr, info+4, fMustAlloc);
967 }
968 rep--;
969 }
970 pFormat += 8 * count;
971 }
972
973 return NULL;
974 }
975
976 /***********************************************************************
977 * EmbeddedPointerBufferSize
978 */
979 void WINAPI EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
980 unsigned char *pMemory,
981 PFORMAT_STRING pFormat)
982 {
983 unsigned long Offset = pStubMsg->Offset;
984 unsigned ofs, rep, count, stride, xofs;
985
986 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
987 if (*pFormat != RPC_FC_PP) return;
988 pFormat += 2;
989
990 while (pFormat[0] != RPC_FC_END) {
991 switch (pFormat[0]) {
992 default:
993 FIXME("unknown repeat type %d\n", pFormat[0]);
994 case RPC_FC_NO_REPEAT:
995 rep = 1;
996 stride = 0;
997 ofs = 0;
998 count = 1;
999 xofs = 0;
1000 pFormat += 2;
1001 break;
1002 case RPC_FC_FIXED_REPEAT:
1003 rep = *(const WORD*)&pFormat[2];
1004 stride = *(const WORD*)&pFormat[4];
1005 ofs = *(const WORD*)&pFormat[6];
1006 count = *(const WORD*)&pFormat[8];
1007 xofs = 0;
1008 pFormat += 10;
1009 break;
1010 case RPC_FC_VARIABLE_REPEAT:
1011 rep = pStubMsg->MaxCount;
1012 stride = *(const WORD*)&pFormat[2];
1013 ofs = *(const WORD*)&pFormat[4];
1014 count = *(const WORD*)&pFormat[6];
1015 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1016 pFormat += 8;
1017 break;
1018 }
1019 /* ofs doesn't seem to matter in this context */
1020 while (rep) {
1021 PFORMAT_STRING info = pFormat;
1022 unsigned char *membase = pMemory + xofs;
1023 unsigned u;
1024 for (u=0; u<count; u++,info+=8) {
1025 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1026 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1027 }
1028 rep--;
1029 }
1030 pFormat += 8 * count;
1031 }
1032 }
1033
1034 /***********************************************************************
1035 * EmbeddedPointerMemorySize
1036 */
1037 unsigned long WINAPI EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1038 PFORMAT_STRING pFormat)
1039 {
1040 unsigned long Offset = pStubMsg->Offset;
1041 unsigned char *Mark = pStubMsg->BufferMark;
1042 unsigned ofs, rep, count, stride, xofs;
1043
1044 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1045 if (*pFormat != RPC_FC_PP) return 0;
1046 pFormat += 2;
1047
1048 while (pFormat[0] != RPC_FC_END) {
1049 switch (pFormat[0]) {
1050 default:
1051 FIXME("unknown repeat type %d\n", pFormat[0]);
1052 case RPC_FC_NO_REPEAT:
1053 rep = 1;
1054 stride = 0;
1055 ofs = 0;
1056 count = 1;
1057 xofs = 0;
1058 pFormat += 2;
1059 break;
1060 case RPC_FC_FIXED_REPEAT:
1061 rep = *(const WORD*)&pFormat[2];
1062 stride = *(const WORD*)&pFormat[4];
1063 ofs = *(const WORD*)&pFormat[6];
1064 count = *(const WORD*)&pFormat[8];
1065 xofs = 0;
1066 pFormat += 10;
1067 break;
1068 case RPC_FC_VARIABLE_REPEAT:
1069 rep = pStubMsg->MaxCount;
1070 stride = *(const WORD*)&pFormat[2];
1071 ofs = *(const WORD*)&pFormat[4];
1072 count = *(const WORD*)&pFormat[6];
1073 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1074 pFormat += 8;
1075 break;
1076 }
1077 /* ofs doesn't seem to matter in this context */
1078 while (rep) {
1079 PFORMAT_STRING info = pFormat;
1080 unsigned u;
1081 for (u=0; u<count; u++,info+=8) {
1082 unsigned char *bufptr = Mark + *(const SHORT*)&info[2];
1083 PointerMemorySize(pStubMsg, bufptr, info+4);
1084 }
1085 rep--;
1086 }
1087 pFormat += 8 * count;
1088 }
1089
1090 return 0;
1091 }
1092
1093 /***********************************************************************
1094 * EmbeddedPointerFree
1095 */
1096 void WINAPI EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1097 unsigned char *pMemory,
1098 PFORMAT_STRING pFormat)
1099 {
1100 unsigned long Offset = pStubMsg->Offset;
1101 unsigned ofs, rep, count, stride, xofs;
1102
1103 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1104 if (*pFormat != RPC_FC_PP) return;
1105 pFormat += 2;
1106
1107 while (pFormat[0] != RPC_FC_END) {
1108 switch (pFormat[0]) {
1109 default:
1110 FIXME("unknown repeat type %d\n", pFormat[0]);
1111 case RPC_FC_NO_REPEAT:
1112 rep = 1;
1113 stride = 0;
1114 ofs = 0;
1115 count = 1;
1116 xofs = 0;
1117 pFormat += 2;
1118 break;
1119 case RPC_FC_FIXED_REPEAT:
1120 rep = *(const WORD*)&pFormat[2];
1121 stride = *(const WORD*)&pFormat[4];
1122 ofs = *(const WORD*)&pFormat[6];
1123 count = *(const WORD*)&pFormat[8];
1124 xofs = 0;
1125 pFormat += 10;
1126 break;
1127 case RPC_FC_VARIABLE_REPEAT:
1128 rep = pStubMsg->MaxCount;
1129 stride = *(const WORD*)&pFormat[2];
1130 ofs = *(const WORD*)&pFormat[4];
1131 count = *(const WORD*)&pFormat[6];
1132 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1133 pFormat += 8;
1134 break;
1135 }
1136 /* ofs doesn't seem to matter in this context */
1137 while (rep) {
1138 PFORMAT_STRING info = pFormat;
1139 unsigned char *membase = pMemory + xofs;
1140 unsigned u;
1141 for (u=0; u<count; u++,info+=8) {
1142 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1143 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1144 }
1145 rep--;
1146 }
1147 pFormat += 8 * count;
1148 }
1149 }
1150
1151 /***********************************************************************
1152 * NdrPointerMarshall [RPCRT4.@]
1153 */
1154 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1155 unsigned char *pMemory,
1156 PFORMAT_STRING pFormat)
1157 {
1158 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1159
1160 pStubMsg->BufferMark = pStubMsg->Buffer;
1161 PointerMarshall(pStubMsg, pStubMsg->Buffer, pMemory, pFormat);
1162
1163 STD_OVERFLOW_CHECK(pStubMsg);
1164
1165 return NULL;
1166 }
1167
1168 /***********************************************************************
1169 * NdrPointerUnmarshall [RPCRT4.@]
1170 */
1171 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1172 unsigned char **ppMemory,
1173 PFORMAT_STRING pFormat,
1174 unsigned char fMustAlloc)
1175 {
1176 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1177
1178 pStubMsg->BufferMark = pStubMsg->Buffer;
1179 PointerUnmarshall(pStubMsg, pStubMsg->Buffer, ppMemory, pFormat, fMustAlloc);
1180
1181 return NULL;
1182 }
1183
1184 /***********************************************************************
1185 * NdrPointerBufferSize [RPCRT4.@]
1186 */
1187 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1188 unsigned char *pMemory,
1189 PFORMAT_STRING pFormat)
1190 {
1191 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1192 PointerBufferSize(pStubMsg, pMemory, pFormat);
1193 }
1194
1195 /***********************************************************************
1196 * NdrPointerMemorySize [RPCRT4.@]
1197 */
1198 unsigned long WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1199 PFORMAT_STRING pFormat)
1200 {
1201 /* unsigned size = *(LPWORD)(pFormat+2); */
1202 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1203 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1204 return 0;
1205 }
1206
1207 /***********************************************************************
1208 * NdrPointerFree [RPCRT4.@]
1209 */
1210 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1211 unsigned char *pMemory,
1212 PFORMAT_STRING pFormat)
1213 {
1214 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1215 PointerFree(pStubMsg, pMemory, pFormat);
1216 }
1217
1218 /***********************************************************************
1219 * NdrSimpleStructMarshall [RPCRT4.@]
1220 */
1221 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1222 unsigned char *pMemory,
1223 PFORMAT_STRING pFormat)
1224 {
1225 unsigned size = *(const WORD*)(pFormat+2);
1226 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1227
1228 memcpy(pStubMsg->Buffer, pMemory, size);
1229 pStubMsg->BufferMark = pStubMsg->Buffer;
1230 pStubMsg->Buffer += size;
1231
1232 if (pFormat[0] != RPC_FC_STRUCT)
1233 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1234
1235 /*
1236 * This test does not work when NdrSimpleStructMarshall is called
1237 * by an rpc-server to marshall data to return to the client because
1238 * BufferStart and BufferEnd are bogus. MIDL does not update them
1239 * when a new buffer is allocated in order to return data to the caller.
1240 */
1241 #if 0
1242 STD_OVERFLOW_CHECK(pStubMsg);
1243 #endif
1244
1245 return NULL;
1246 }
1247
1248 /***********************************************************************
1249 * NdrSimpleStructUnmarshall [RPCRT4.@]
1250 */
1251 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1252 unsigned char **ppMemory,
1253 PFORMAT_STRING pFormat,
1254 unsigned char fMustAlloc)
1255 {
1256 unsigned size = *(const WORD*)(pFormat+2);
1257 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1258
1259 if (fMustAlloc) {
1260 *ppMemory = NdrAllocate(pStubMsg, size);
1261 memcpy(*ppMemory, pStubMsg->Buffer, size);
1262 } else {
1263 if (pStubMsg->ReuseBuffer && !*ppMemory)
1264 /* for servers, we may just point straight into the RPC buffer, I think
1265 * (I guess that's what MS does since MIDL code doesn't try to free) */
1266 *ppMemory = pStubMsg->Buffer;
1267 else
1268 /* for clients, memory should be provided by caller */
1269 memcpy(*ppMemory, pStubMsg->Buffer, size);
1270 }
1271
1272 pStubMsg->BufferMark = pStubMsg->Buffer;
1273 pStubMsg->Buffer += size;
1274
1275 if (pFormat[0] != RPC_FC_STRUCT)
1276 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat+4, fMustAlloc);
1277
1278 return NULL;
1279 }
1280
1281
1282 /***********************************************************************
1283 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1284 */
1285 void WINAPI NdrSimpleTypeMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1286 unsigned char *pMemory,
1287 unsigned char FormatChar)
1288 {
1289 FIXME("stub\n");
1290 }
1291
1292
1293 /***********************************************************************
1294 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1295 */
1296 void WINAPI NdrSimpleTypeUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1297 unsigned char *pMemory,
1298 unsigned char FormatChar)
1299 {
1300 FIXME("stub\n");
1301 }
1302
1303
1304 /***********************************************************************
1305 * NdrSimpleStructBufferSize [RPCRT4.@]
1306 */
1307 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1308 unsigned char *pMemory,
1309 PFORMAT_STRING pFormat)
1310 {
1311 unsigned size = *(const WORD*)(pFormat+2);
1312 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1313 pStubMsg->BufferLength += size;
1314 if (pFormat[0] != RPC_FC_STRUCT)
1315 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1316 }
1317
1318 /***********************************************************************
1319 * NdrSimpleStructMemorySize [RPCRT4.@]
1320 */
1321 unsigned long WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1322 PFORMAT_STRING pFormat)
1323 {
1324 /* unsigned size = *(LPWORD)(pFormat+2); */
1325 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1326 if (pFormat[0] != RPC_FC_STRUCT)
1327 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1328 return 0;
1329 }
1330
1331 /***********************************************************************
1332 * NdrSimpleStructFree [RPCRT4.@]
1333 */
1334 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1335 unsigned char *pMemory,
1336 PFORMAT_STRING pFormat)
1337 {
1338 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1339 if (pFormat[0] != RPC_FC_STRUCT)
1340 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1341 }
1342
1343
1344 unsigned long WINAPI EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg,
1345 PFORMAT_STRING pFormat)
1346 {
1347 switch (*pFormat) {
1348 case RPC_FC_STRUCT:
1349 case RPC_FC_PSTRUCT:
1350 case RPC_FC_CSTRUCT:
1351 case RPC_FC_BOGUS_STRUCT:
1352 return *(const WORD*)&pFormat[2];
1353 case RPC_FC_USER_MARSHAL:
1354 return *(const WORD*)&pFormat[4];
1355 default:
1356 FIXME("unhandled embedded type %02x\n", *pFormat);
1357 }
1358 return 0;
1359 }
1360
1361
1362 unsigned char * WINAPI ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1363 unsigned char *pMemory,
1364 PFORMAT_STRING pFormat,
1365 PFORMAT_STRING pPointer)
1366 {
1367 PFORMAT_STRING desc;
1368 NDR_MARSHALL m;
1369 unsigned long size;
1370
1371 while (*pFormat != RPC_FC_END) {
1372 switch (*pFormat) {
1373 case RPC_FC_SHORT:
1374 case RPC_FC_USHORT:
1375 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1376 memcpy(pStubMsg->Buffer, pMemory, 2);
1377 pStubMsg->Buffer += 2;
1378 pMemory += 2;
1379 break;
1380 case RPC_FC_LONG:
1381 case RPC_FC_ULONG:
1382 TRACE("long=%ld <= %p\n", *(DWORD*)pMemory, pMemory);
1383 memcpy(pStubMsg->Buffer, pMemory, 4);
1384 pStubMsg->Buffer += 4;
1385 pMemory += 4;
1386 break;
1387 case RPC_FC_POINTER:
1388 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1389 NdrPointerMarshall(pStubMsg, *(unsigned char**)pMemory, pPointer);
1390 pPointer += 4;
1391 pMemory += 4;
1392 break;
1393 case RPC_FC_ALIGNM4:
1394 ALIGN_POINTER(pMemory, 3);
1395 break;
1396 case RPC_FC_ALIGNM8:
1397 ALIGN_POINTER(pMemory, 7);
1398 break;
1399 case RPC_FC_EMBEDDED_COMPLEX:
1400 pMemory += pFormat[1];
1401 pFormat += 2;
1402 desc = pFormat + *(const SHORT*)pFormat;
1403 size = EmbeddedComplexSize(pStubMsg, desc);
1404 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1405 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1406 if (m) m(pStubMsg, pMemory, desc);
1407 else FIXME("no marshaller for embedded type %02x\n", *desc);
1408 pMemory += size;
1409 pFormat += 2;
1410 continue;
1411 case RPC_FC_PAD:
1412 break;
1413 default:
1414 FIXME("unhandled format %02x\n", *pFormat);
1415 }
1416 pFormat++;
1417 }
1418
1419 return pMemory;
1420 }
1421
1422 unsigned char * WINAPI ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1423 unsigned char *pMemory,
1424 PFORMAT_STRING pFormat,
1425 PFORMAT_STRING pPointer,
1426 unsigned char fMustAlloc)
1427 {
1428 PFORMAT_STRING desc;
1429 NDR_UNMARSHALL m;
1430 unsigned long size;
1431
1432 while (*pFormat != RPC_FC_END) {
1433 switch (*pFormat) {
1434 case RPC_FC_SHORT:
1435 case RPC_FC_USHORT:
1436 memcpy(pMemory, pStubMsg->Buffer, 2);
1437 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1438 pStubMsg->Buffer += 2;
1439 pMemory += 2;
1440 break;
1441 case RPC_FC_LONG:
1442 case RPC_FC_ULONG:
1443 memcpy(pMemory, pStubMsg->Buffer, 4);
1444 TRACE("long=%ld => %p\n", *(DWORD*)pMemory, pMemory);
1445 pStubMsg->Buffer += 4;
1446 pMemory += 4;
1447 break;
1448 case RPC_FC_POINTER:
1449 *(unsigned char**)pMemory = NULL;
1450 TRACE("pointer => %p\n", pMemory);
1451 NdrPointerUnmarshall(pStubMsg, (unsigned char**)pMemory, pPointer, fMustAlloc);
1452 pPointer += 4;
1453 pMemory += 4;
1454 break;
1455 case RPC_FC_ALIGNM4:
1456 ALIGN_POINTER(pMemory, 3);
1457 break;
1458 case RPC_FC_ALIGNM8:
1459 ALIGN_POINTER(pMemory, 7);
1460 break;
1461 case RPC_FC_EMBEDDED_COMPLEX:
1462 pMemory += pFormat[1];
1463 pFormat += 2;
1464 desc = pFormat + *(const SHORT*)pFormat;
1465 size = EmbeddedComplexSize(pStubMsg, desc);
1466 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
1467 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1468 memset(pMemory, 0, size); /* just in case */
1469 if (m) m(pStubMsg, &pMemory, desc, fMustAlloc);
1470 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
1471 pMemory += size;
1472 pFormat += 2;
1473 continue;
1474 case RPC_FC_PAD:
1475 break;
1476 default:
1477 FIXME("unhandled format %d\n", *pFormat);
1478 }
1479 pFormat++;
1480 }
1481
1482 return pMemory;
1483 }
1484
1485 unsigned char * WINAPI ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1486 unsigned char *pMemory,
1487 PFORMAT_STRING pFormat,
1488 PFORMAT_STRING pPointer)
1489 {
1490 PFORMAT_STRING desc;
1491 NDR_BUFFERSIZE m;
1492 unsigned long size;
1493
1494 while (*pFormat != RPC_FC_END) {
1495 switch (*pFormat) {
1496 case RPC_FC_SHORT:
1497 case RPC_FC_USHORT:
1498 pStubMsg->BufferLength += 2;
1499 pMemory += 2;
1500 break;
1501 case RPC_FC_LONG:
1502 case RPC_FC_ULONG:
1503 pStubMsg->BufferLength += 4;
1504 pMemory += 4;
1505 break;
1506 case RPC_FC_POINTER:
1507 NdrPointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
1508 pPointer += 4;
1509 pMemory += 4;
1510 break;
1511 case RPC_FC_ALIGNM4:
1512 ALIGN_POINTER(pMemory, 3);
1513 break;
1514 case RPC_FC_ALIGNM8:
1515 ALIGN_POINTER(pMemory, 7);
1516 break;
1517 case RPC_FC_EMBEDDED_COMPLEX:
1518 pMemory += pFormat[1];
1519 pFormat += 2;
1520 desc = pFormat + *(const SHORT*)pFormat;
1521 size = EmbeddedComplexSize(pStubMsg, desc);
1522 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1523 if (m) m(pStubMsg, pMemory, desc);
1524 else FIXME("no buffersizer for embedded type %02x\n", *desc);
1525 pMemory += size;
1526 pFormat += 2;
1527 continue;
1528 case RPC_FC_PAD:
1529 break;
1530 default:
1531 FIXME("unhandled format %d\n", *pFormat);
1532 }
1533 pFormat++;
1534 }
1535
1536 return pMemory;
1537 }
1538
1539 unsigned char * WINAPI ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
1540 unsigned char *pMemory,
1541 PFORMAT_STRING pFormat,
1542 PFORMAT_STRING pPointer)
1543 {
1544 PFORMAT_STRING desc;
1545 NDR_FREE m;
1546 unsigned long size;
1547
1548 while (*pFormat != RPC_FC_END) {
1549 switch (*pFormat) {
1550 case RPC_FC_SHORT:
1551 case RPC_FC_USHORT:
1552 pMemory += 2;
1553 break;
1554 case RPC_FC_LONG:
1555 case RPC_FC_ULONG:
1556 pMemory += 4;
1557 break;
1558 case RPC_FC_POINTER:
1559 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
1560 pPointer += 4;
1561 pMemory += 4;
1562 break;
1563 case RPC_FC_ALIGNM4:
1564 ALIGN_POINTER(pMemory, 3);
1565 break;
1566 case RPC_FC_ALIGNM8:
1567 ALIGN_POINTER(pMemory, 7);
1568 break;
1569 case RPC_FC_EMBEDDED_COMPLEX:
1570 pMemory += pFormat[1];
1571 pFormat += 2;
1572 desc = pFormat + *(const SHORT*)pFormat;
1573 size = EmbeddedComplexSize(pStubMsg, desc);
1574 m = NdrFreer[*desc & NDR_TABLE_MASK];
1575 if (m) m(pStubMsg, pMemory, desc);
1576 else FIXME("no freer for embedded type %02x\n", *desc);
1577 pMemory += size;
1578 pFormat += 2;
1579 continue;
1580 case RPC_FC_PAD:
1581 break;
1582 default:
1583 FIXME("unhandled format %d\n", *pFormat);
1584 }
1585 pFormat++;
1586 }
1587
1588 return pMemory;
1589 }
1590
1591 unsigned long WINAPI ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg,
1592 PFORMAT_STRING pFormat)
1593 {
1594 PFORMAT_STRING desc;
1595 unsigned long size = 0;
1596
1597 while (*pFormat != RPC_FC_END) {
1598 switch (*pFormat) {
1599 case RPC_FC_SHORT:
1600 case RPC_FC_USHORT:
1601 size += 2;
1602 break;
1603 case RPC_FC_LONG:
1604 case RPC_FC_ULONG:
1605 size += 4;
1606 break;
1607 case RPC_FC_POINTER:
1608 size += 4;
1609 break;
1610 case RPC_FC_ALIGNM4:
1611 ALIGN_LENGTH(size, 3);
1612 break;
1613 case RPC_FC_ALIGNM8:
1614 ALIGN_LENGTH(size, 7);
1615 break;
1616 case RPC_FC_EMBEDDED_COMPLEX:
1617 size += pFormat[1];
1618 pFormat += 2;
1619 desc = pFormat + *(const SHORT*)pFormat;
1620 size += EmbeddedComplexSize(pStubMsg, desc);
1621 pFormat += 2;
1622 continue;
1623 case RPC_FC_PAD:
1624 break;
1625 default:
1626 FIXME("unhandled format %d\n", *pFormat);
1627 }
1628 pFormat++;
1629 }
1630
1631 return size;
1632 }
1633
1634 /***********************************************************************
1635 * NdrComplexStructMarshall [RPCRT4.@]
1636 */
1637 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1638 unsigned char *pMemory,
1639 PFORMAT_STRING pFormat)
1640 {
1641 PFORMAT_STRING conf_array = NULL;
1642 PFORMAT_STRING pointer_desc = NULL;
1643 unsigned char *OldMemory = pStubMsg->Memory;
1644
1645 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1646
1647 pFormat += 4;
1648 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1649 pFormat += 2;
1650 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1651 pFormat += 2;
1652
1653 pStubMsg->Memory = pMemory;
1654
1655 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
1656
1657 if (conf_array)
1658 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
1659
1660 pStubMsg->Memory = OldMemory;
1661
1662 STD_OVERFLOW_CHECK(pStubMsg);
1663
1664 return NULL;
1665 }
1666
1667 /***********************************************************************
1668 * NdrComplexStructUnmarshall [RPCRT4.@]
1669 */
1670 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1671 unsigned char **ppMemory,
1672 PFORMAT_STRING pFormat,
1673 unsigned char fMustAlloc)
1674 {
1675 unsigned size = *(const WORD*)(pFormat+2);
1676 PFORMAT_STRING conf_array = NULL;
1677 PFORMAT_STRING pointer_desc = NULL;
1678 unsigned char *pMemory;
1679
1680 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1681
1682 if (fMustAlloc || !*ppMemory)
1683 *ppMemory = NdrAllocate(pStubMsg, size);
1684
1685 pFormat += 4;
1686 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1687 pFormat += 2;
1688 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1689 pFormat += 2;
1690
1691 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
1692
1693 if (conf_array)
1694 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
1695
1696 return NULL;
1697 }
1698
1699 /***********************************************************************
1700 * NdrComplexStructBufferSize [RPCRT4.@]
1701 */
1702 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1703 unsigned char *pMemory,
1704 PFORMAT_STRING pFormat)
1705 {
1706 PFORMAT_STRING conf_array = NULL;
1707 PFORMAT_STRING pointer_desc = NULL;
1708 unsigned char *OldMemory = pStubMsg->Memory;
1709
1710 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1711
1712 pFormat += 4;
1713 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1714 pFormat += 2;
1715 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1716 pFormat += 2;
1717
1718 pStubMsg->Memory = pMemory;
1719
1720 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
1721
1722 if (conf_array)
1723 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
1724
1725 pStubMsg->Memory = OldMemory;
1726 }
1727
1728 /***********************************************************************
1729 * NdrComplexStructMemorySize [RPCRT4.@]
1730 */
1731 unsigned long WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1732 PFORMAT_STRING pFormat)
1733 {
1734 /* unsigned size = *(LPWORD)(pFormat+2); */
1735 PFORMAT_STRING conf_array = NULL;
1736 PFORMAT_STRING pointer_desc = NULL;
1737
1738 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1739
1740 pFormat += 4;
1741 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1742 pFormat += 2;
1743 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1744 pFormat += 2;
1745
1746 return 0;
1747 }
1748
1749 /***********************************************************************
1750 * NdrComplexStructFree [RPCRT4.@]
1751 */
1752 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1753 unsigned char *pMemory,
1754 PFORMAT_STRING pFormat)
1755 {
1756 PFORMAT_STRING conf_array = NULL;
1757 PFORMAT_STRING pointer_desc = NULL;
1758 unsigned char *OldMemory = pStubMsg->Memory;
1759
1760 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1761
1762 pFormat += 4;
1763 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1764 pFormat += 2;
1765 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1766 pFormat += 2;
1767
1768 pStubMsg->Memory = pMemory;
1769
1770 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
1771
1772 if (conf_array)
1773 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
1774
1775 pStubMsg->Memory = OldMemory;
1776 }
1777
1778 /***********************************************************************
1779 * NdrConformantArrayMarshall [RPCRT4.@]
1780 */
1781 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1782 unsigned char *pMemory,
1783 PFORMAT_STRING pFormat)
1784 {
1785 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
1786 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1787 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1788
1789 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1790 size = pStubMsg->MaxCount;
1791
1792 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, size);
1793 pStubMsg->Buffer += 4;
1794
1795 memcpy(pStubMsg->Buffer, pMemory, size*esize);
1796 pStubMsg->BufferMark = pStubMsg->Buffer;
1797 pStubMsg->Buffer += size*esize;
1798
1799 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1800
1801 STD_OVERFLOW_CHECK(pStubMsg);
1802
1803 return NULL;
1804 }
1805
1806 /***********************************************************************
1807 * NdrConformantArrayUnmarshall [RPCRT4.@]
1808 */
1809 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1810 unsigned char **ppMemory,
1811 PFORMAT_STRING pFormat,
1812 unsigned char fMustAlloc)
1813 {
1814 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
1815 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1816 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1817
1818 pFormat = ReadConformance(pStubMsg, pFormat+4);
1819 size = pStubMsg->MaxCount;
1820
1821 if (fMustAlloc) {
1822 *ppMemory = NdrAllocate(pStubMsg, size*esize);
1823 memcpy(*ppMemory, pStubMsg->Buffer, size*esize);
1824 } else {
1825 if (pStubMsg->ReuseBuffer && !*ppMemory)
1826 /* for servers, we may just point straight into the RPC buffer, I think
1827 * (I guess that's what MS does since MIDL code doesn't try to free) */
1828 *ppMemory = pStubMsg->Buffer;
1829 else
1830 /* for clients, memory should be provided by caller */
1831 memcpy(*ppMemory, pStubMsg->Buffer, size*esize);
1832 }
1833
1834 pStubMsg->BufferMark = pStubMsg->Buffer;
1835 pStubMsg->Buffer += size*esize;
1836
1837 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
1838
1839 return NULL;
1840 }
1841
1842 /***********************************************************************
1843 * NdrConformantArrayBufferSize [RPCRT4.@]
1844 */
1845 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1846 unsigned char *pMemory,
1847 PFORMAT_STRING pFormat)
1848 {
1849 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
1850 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1851 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1852
1853 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1854 size = pStubMsg->MaxCount;
1855
1856 pStubMsg->BufferLength += size*esize;
1857
1858 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1859 }
1860
1861 /***********************************************************************
1862 * NdrConformantArrayMemorySize [RPCRT4.@]
1863 */
1864 unsigned long WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1865 PFORMAT_STRING pFormat)
1866 {
1867 DWORD size = 0;
1868 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1869 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1870
1871 pFormat = ReadConformance(pStubMsg, pFormat+4);
1872 size = pStubMsg->MaxCount;
1873
1874 EmbeddedPointerMemorySize(pStubMsg, pFormat);
1875
1876 return 0;
1877 }
1878
1879 /***********************************************************************
1880 * NdrConformantArrayFree [RPCRT4.@]
1881 */
1882 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
1883 unsigned char *pMemory,
1884 PFORMAT_STRING pFormat)
1885 {
1886 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1887 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1888
1889 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
1890 }
1891
1892
1893 /***********************************************************************
1894 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
1895 */
1896 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
1897 unsigned char* pMemory,
1898 PFORMAT_STRING pFormat )
1899 {
1900 FIXME( "stub\n" );
1901 return NULL;
1902 }
1903
1904
1905 /***********************************************************************
1906 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
1907 */
1908 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
1909 unsigned char** ppMemory,
1910 PFORMAT_STRING pFormat,
1911 unsigned char fMustAlloc )
1912 {
1913 FIXME( "stub\n" );
1914 return NULL;
1915 }
1916
1917
1918 /***********************************************************************
1919 * NdrConformantVaryingArrayFree [RPCRT4.@]
1920 */
1921 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
1922 unsigned char* pMemory,
1923 PFORMAT_STRING pFormat )
1924 {
1925 FIXME( "stub\n" );
1926 }
1927
1928
1929 /***********************************************************************
1930 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
1931 */
1932 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
1933 unsigned char* pMemory, PFORMAT_STRING pFormat )
1934 {
1935 FIXME( "stub\n" );
1936 }
1937
1938
1939 /***********************************************************************
1940 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
1941 */
1942 unsigned long WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
1943 PFORMAT_STRING pFormat )
1944 {
1945 FIXME( "stub\n" );
1946 return 0;
1947 }
1948
1949
1950 /***********************************************************************
1951 * NdrComplexArrayMarshall [RPCRT4.@]
1952 */
1953 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1954 unsigned char *pMemory,
1955 PFORMAT_STRING pFormat)
1956 {
1957 DWORD size = 0, count, def;
1958 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1959
1960 def = *(const WORD*)&pFormat[2];
1961 pFormat += 4;
1962
1963 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
1964 size = pStubMsg->MaxCount;
1965 TRACE("conformance=%ld\n", size);
1966
1967 if (*(const DWORD*)pFormat != 0xffffffff)
1968 FIXME("compute variance\n");
1969 pFormat += 4;
1970
1971 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, size);
1972 pStubMsg->Buffer += 4;
1973
1974 for (count=0; count<size; count++)
1975 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
1976
1977 STD_OVERFLOW_CHECK(pStubMsg);
1978
1979 return NULL;
1980 }
1981
1982 /***********************************************************************
1983 * NdrComplexArrayUnmarshall [RPCRT4.@]
1984 */
1985 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1986 unsigned char **ppMemory,
1987 PFORMAT_STRING pFormat,
1988 unsigned char fMustAlloc)
1989 {
1990 DWORD size = 0, count, esize;
1991 unsigned char *pMemory;
1992 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1993
1994 pFormat += 4;
1995
1996 pFormat = ReadConformance(pStubMsg, pFormat);
1997 size = pStubMsg->MaxCount;
1998 TRACE("conformance=%ld\n", size);
1999
2000 pFormat += 4;
2001
2002 esize = ComplexStructSize(pStubMsg, pFormat);
2003
2004 if (fMustAlloc || !*ppMemory)
2005 *ppMemory = NdrAllocate(pStubMsg, size*esize);
2006
2007 pMemory = *ppMemory;
2008 for (count=0; count<size; count++)
2009 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
2010
2011 return NULL;
2012 }
2013
2014 /***********************************************************************
2015 * NdrComplexArrayBufferSize [RPCRT4.@]
2016 */
2017 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2018 unsigned char *pMemory,
2019 PFORMAT_STRING pFormat)
2020 {
2021 DWORD size = 0, count, def;
2022 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2023
2024 def = *(const WORD*)&pFormat[2];
2025 pFormat += 4;
2026
2027 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2028 size = pStubMsg->MaxCount;
2029 TRACE("conformance=%ld\n", size);
2030
2031 if (*(const DWORD*)pFormat != 0xffffffff)
2032 FIXME("compute variance\n");
2033 pFormat += 4;
2034
2035 for (count=0; count<size; count++)
2036 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
2037 }
2038
2039 /***********************************************************************
2040 * NdrComplexArrayMemorySize [RPCRT4.@]
2041 */
2042 unsigned long WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2043 PFORMAT_STRING pFormat)
2044 {
2045 DWORD size = 0;
2046 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
2047
2048 pFormat += 4;
2049
2050 pFormat = ReadConformance(pStubMsg, pFormat);
2051 size = pStubMsg->MaxCount;
2052 TRACE("conformance=%ld\n", size);
2053
2054 pFormat += 4;
2055
2056 return 0;
2057 }
2058
2059 /***********************************************************************
2060 * NdrComplexArrayFree [RPCRT4.@]
2061 */
2062 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2063 unsigned char *pMemory,
2064 PFORMAT_STRING pFormat)
2065 {
2066 DWORD size = 0, count, def;
2067 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2068
2069 def = *(const WORD*)&pFormat[2];
2070 pFormat += 4;
2071
2072 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2073 size = pStubMsg->MaxCount;
2074 TRACE("conformance=%ld\n", size);
2075
2076 if (*(const DWORD*)pFormat != 0xffffffff)
2077 FIXME("compute variance\n");
2078 pFormat += 4;
2079
2080 for (count=0; count<size; count++)
2081 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2082 }
2083
2084 unsigned long UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
2085 {
2086 return MAKELONG(pStubMsg->dwDestContext,
2087 pStubMsg->RpcMsg->DataRepresentation);
2088 }
2089
2090 /***********************************************************************
2091 * NdrUserMarshalMarshall [RPCRT4.@]
2092 */
2093 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2094 unsigned char *pMemory,
2095 PFORMAT_STRING pFormat)
2096 {
2097 /* unsigned flags = pFormat[1]; */
2098 unsigned index = *(const WORD*)&pFormat[2];
2099 unsigned long uflag = UserMarshalFlags(pStubMsg);
2100 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2101 TRACE("index=%d\n", index);
2102
2103 pStubMsg->Buffer =
2104 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
2105 &uflag, pStubMsg->Buffer, pMemory);
2106
2107 STD_OVERFLOW_CHECK(pStubMsg);
2108
2109 return NULL;
2110 }
2111
2112 /***********************************************************************
2113 * NdrUserMarshalUnmarshall [RPCRT4.@]
2114 */
2115 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2116 unsigned char **ppMemory,
2117 PFORMAT_STRING pFormat,
2118 unsigned char fMustAlloc)
2119 {
2120 /* unsigned flags = pFormat[1];*/
2121 unsigned index = *(const WORD*)&pFormat[2];
2122 DWORD memsize = *(const WORD*)&pFormat[4];
2123 unsigned long uflag = UserMarshalFlags(pStubMsg);
2124 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2125 TRACE("index=%d\n", index);
2126
2127 if (fMustAlloc || !*ppMemory)
2128 *ppMemory = NdrAllocate(pStubMsg, memsize);
2129
2130 pStubMsg->Buffer =
2131 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
2132 &uflag, pStubMsg->Buffer, *ppMemory);
2133
2134 return NULL;
2135 }
2136
2137 /***********************************************************************
2138 * NdrUserMarshalBufferSize [RPCRT4.@]
2139 */
2140 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2141 unsigned char *pMemory,
2142 PFORMAT_STRING pFormat)
2143 {
2144 /* unsigned flags = pFormat[1];*/
2145 unsigned index = *(const WORD*)&pFormat[2];
2146 DWORD bufsize = *(const WORD*)&pFormat[6];
2147 unsigned long uflag = UserMarshalFlags(pStubMsg);
2148 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2149 TRACE("index=%d\n", index);
2150
2151 if (bufsize) {
2152 TRACE("size=%ld\n", bufsize);
2153 pStubMsg->BufferLength += bufsize;
2154 return;
2155 }
2156
2157 pStubMsg->BufferLength =
2158 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
2159 &uflag, pStubMsg->BufferLength, pMemory);
2160 }
2161
2162 /***********************************************************************
2163 * NdrUserMarshalMemorySize [RPCRT4.@]
2164 */
2165 unsigned long WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2166 PFORMAT_STRING pFormat)
2167 {
2168 unsigned index = *(const WORD*)&pFormat[2];
2169 /* DWORD memsize = *(const WORD*)&pFormat[4]; */
2170 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
2171 TRACE("index=%d\n", index);
2172
2173 return 0;
2174 }
2175
2176 /***********************************************************************
2177 * NdrUserMarshalFree [RPCRT4.@]
2178 */
2179 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
2180 unsigned char *pMemory,
2181 PFORMAT_STRING pFormat)
2182 {
2183 /* unsigned flags = pFormat[1]; */
2184 unsigned index = *(const WORD*)&pFormat[2];
2185 unsigned long uflag = UserMarshalFlags(pStubMsg);
2186 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2187 TRACE("index=%d\n", index);
2188
2189 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
2190 &uflag, pMemory);
2191 }
2192
2193 /***********************************************************************
2194 * NdrClearOutParameters [RPCRT4.@]
2195 */
2196 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
2197 PFORMAT_STRING pFormat,
2198 void *ArgAddr)
2199 {
2200 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
2201 }
2202
2203 /***********************************************************************
2204 * NdrConvert [RPCRT4.@]
2205 */
2206 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
2207 {
2208 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
2209 /* FIXME: since this stub doesn't do any converting, the proper behavior
2210 is to raise an exception */
2211 }
2212
2213 /***********************************************************************
2214 * NdrConvert2 [RPCRT4.@]
2215 */
2216 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, long NumberParams )
2217 {
2218 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %ld): stub.\n",
2219 pStubMsg, pFormat, NumberParams);
2220 /* FIXME: since this stub doesn't do any converting, the proper behavior
2221 is to raise an exception */
2222 }
2223
2224 /***********************************************************************
2225 * NdrConformantStructMarshall [RPCRT4.@]
2226 */
2227 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2228 unsigned char *pMemory,
2229 PFORMAT_STRING pFormat)
2230 {
2231 FIXME("stub\n");
2232 return NULL;
2233 }
2234
2235 /***********************************************************************
2236 * NdrConformantStructUnmarshall [RPCRT4.@]
2237 */
2238 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2239 unsigned char **ppMemory,
2240 PFORMAT_STRING pFormat,
2241 unsigned char fMustAlloc)
2242 {
2243 FIXME("stub\n");
2244 return NULL;
2245 }
2246
2247 /***********************************************************************
2248 * NdrConformantStructBufferSize [RPCRT4.@]
2249 */
2250 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2251 unsigned char *pMemory,
2252 PFORMAT_STRING pFormat)
2253 {
2254 FIXME("stub\n");
2255 }
2256
2257 /***********************************************************************
2258 * NdrConformantStructMemorySize [RPCRT4.@]
2259 */
2260 unsigned long WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2261 PFORMAT_STRING pFormat)
2262 {
2263 FIXME("stub\n");
2264 return 0;
2265 }
2266
2267 /***********************************************************************
2268 * NdrConformantStructFree [RPCRT4.@]
2269 */
2270 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2271 unsigned char *pMemory,
2272 PFORMAT_STRING pFormat)
2273 {
2274 FIXME("stub\n");
2275 }
2276
2277 /***********************************************************************
2278 * NdrConformantVaryingStructMarshall [RPCRT4.@]
2279 */
2280 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2281 unsigned char *pMemory,
2282 PFORMAT_STRING pFormat)
2283 {
2284 FIXME("stub\n");
2285 return NULL;
2286 }
2287
2288 /***********************************************************************
2289 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
2290 */
2291 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2292 unsigned char **ppMemory,
2293 PFORMAT_STRING pFormat,
2294 unsigned char fMustAlloc)
2295 {
2296 FIXME("stub\n");
2297 return NULL;
2298 }
2299
2300 /***********************************************************************
2301 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
2302 */
2303 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2304 unsigned char *pMemory,
2305 PFORMAT_STRING pFormat)
2306 {
2307 FIXME("stub\n");
2308 }
2309
2310 /***********************************************************************
2311 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
2312 */
2313 unsigned long WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2314 PFORMAT_STRING pFormat)
2315 {
2316 FIXME("stub\n");
2317 return 0;
2318 }
2319
2320 /***********************************************************************
2321 * NdrConformantVaryingStructFree [RPCRT4.@]
2322 */
2323 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2324 unsigned char *pMemory,
2325 PFORMAT_STRING pFormat)
2326 {
2327 FIXME("stub\n");
2328 }
2329
2330 /***********************************************************************
2331 * NdrFixedArrayMarshall [RPCRT4.@]
2332 */
2333 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2334 unsigned char *pMemory,
2335 PFORMAT_STRING pFormat)
2336 {
2337 FIXME("stub\n");
2338 return NULL;
2339 }
2340
2341 /***********************************************************************
2342 * NdrFixedArrayUnmarshall [RPCRT4.@]
2343 */
2344 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2345 unsigned char **ppMemory,
2346 PFORMAT_STRING pFormat,
2347 unsigned char fMustAlloc)
2348 {
2349 FIXME("stub\n");
2350 return NULL;
2351 }
2352
2353 /***********************************************************************
2354 * NdrFixedArrayBufferSize [RPCRT4.@]
2355 */
2356 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2357 unsigned char *pMemory,
2358 PFORMAT_STRING pFormat)
2359 {
2360 FIXME("stub\n");
2361 }
2362
2363 /***********************************************************************
2364 * NdrFixedArrayMemorySize [RPCRT4.@]
2365 */
2366 unsigned long WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2367 PFORMAT_STRING pFormat)
2368 {
2369 FIXME("stub\n");
2370 return 0;
2371 }
2372
2373 /***********************************************************************
2374 * NdrFixedArrayFree [RPCRT4.@]
2375 */
2376 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2377 unsigned char *pMemory,
2378 PFORMAT_STRING pFormat)
2379 {
2380 FIXME("stub\n");
2381 }
2382
2383 /***********************************************************************
2384 * NdrVaryingArrayMarshall [RPCRT4.@]
2385 */
2386 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2387 unsigned char *pMemory,
2388 PFORMAT_STRING pFormat)
2389 {
2390 FIXME("stub\n");
2391 return NULL;
2392 }
2393
2394 /***********************************************************************
2395 * NdrVaryingArrayUnmarshall [RPCRT4.@]
2396 */
2397 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2398 unsigned char **ppMemory,
2399 PFORMAT_STRING pFormat,
2400 unsigned char fMustAlloc)
2401 {
2402 FIXME("stub\n");
2403 return NULL;
2404 }
2405
2406 /***********************************************************************
2407 * NdrVaryingArrayBufferSize [RPCRT4.@]
2408 */
2409 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2410 unsigned char *pMemory,
2411 PFORMAT_STRING pFormat)
2412 {
2413 FIXME("stub\n");
2414 }
2415
2416 /***********************************************************************
2417 * NdrVaryingArrayMemorySize [RPCRT4.@]
2418 */
2419 unsigned long WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2420 PFORMAT_STRING pFormat)
2421 {
2422 FIXME("stub\n");
2423 return 0;
2424 }
2425
2426 /***********************************************************************
2427 * NdrVaryingArrayFree [RPCRT4.@]
2428 */
2429 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2430 unsigned char *pMemory,
2431 PFORMAT_STRING pFormat)
2432 {
2433 FIXME("stub\n");
2434 }
2435
2436 /***********************************************************************
2437 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
2438 */
2439 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2440 unsigned char *pMemory,
2441 PFORMAT_STRING pFormat)
2442 {
2443 FIXME("stub\n");
2444 return NULL;
2445 }
2446
2447 /***********************************************************************
2448 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
2449 */
2450 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2451 unsigned char **ppMemory,
2452 PFORMAT_STRING pFormat,
2453 unsigned char fMustAlloc)
2454 {
2455 FIXME("stub\n");
2456 return NULL;
2457 }
2458
2459 /***********************************************************************
2460 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
2461 */
2462 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2463 unsigned char *pMemory,
2464 PFORMAT_STRING pFormat)
2465 {
2466 FIXME("stub\n");
2467 }
2468
2469 /***********************************************************************
2470 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
2471 */
2472 unsigned long WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2473 PFORMAT_STRING pFormat)
2474 {
2475 FIXME("stub\n");
2476 return 0;
2477 }
2478
2479 /***********************************************************************
2480 * NdrEncapsulatedUnionFree [RPCRT4.@]
2481 */
2482 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
2483 unsigned char *pMemory,
2484 PFORMAT_STRING pFormat)
2485 {
2486 FIXME("stub\n");
2487 }
2488
2489 /***********************************************************************
2490 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
2491 */
2492 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2493 unsigned char *pMemory,
2494 PFORMAT_STRING pFormat)
2495 {
2496 FIXME("stub\n");
2497 return NULL;
2498 }
2499
2500 /***********************************************************************
2501 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
2502 */
2503 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2504 unsigned char **ppMemory,
2505 PFORMAT_STRING pFormat,
2506 unsigned char fMustAlloc)
2507 {
2508 FIXME("stub\n");
2509 return NULL;
2510 }
2511
2512 /***********************************************************************
2513 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
2514 */
2515 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2516 unsigned char *pMemory,
2517 PFORMAT_STRING pFormat)
2518 {
2519 FIXME("stub\n");
2520 }
2521
2522 /***********************************************************************
2523 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
2524 */
2525 unsigned long WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2526 PFORMAT_STRING pFormat)
2527 {
2528 FIXME("stub\n");
2529 return 0;
2530 }
2531
2532 /***********************************************************************
2533 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
2534 */
2535 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
2536 unsigned char *pMemory,
2537 PFORMAT_STRING pFormat)
2538 {
2539 FIXME("stub\n");
2540 }
2541
2542 /***********************************************************************
2543 * NdrByteCountPointerMarshall [RPCRT4.@]
2544 */
2545 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2546 unsigned char *pMemory,
2547 PFORMAT_STRING pFormat)
2548 {
2549 FIXME("stub\n");
2550 return NULL;
2551 }
2552
2553 /***********************************************************************
2554 * NdrByteCountPointerUnmarshall [RPCRT4.@]
2555 */
2556 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2557 unsigned char **ppMemory,
2558 PFORMAT_STRING pFormat,
2559 unsigned char fMustAlloc)
2560 {
2561 FIXME("stub\n");
2562 return NULL;
2563 }
2564
2565 /***********************************************************************
2566 * NdrByteCountPointerBufferSize [RPCRT4.@]
2567 */
2568 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2569 unsigned char *pMemory,
2570 PFORMAT_STRING pFormat)
2571 {
2572 FIXME("stub\n");
2573 }
2574
2575 /***********************************************************************
2576 * NdrByteCountPointerMemorySize [RPCRT4.@]
2577 */
2578 unsigned long WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2579 PFORMAT_STRING pFormat)
2580 {
2581 FIXME("stub\n");
2582 return 0;
2583 }
2584
2585 /***********************************************************************
2586 * NdrByteCountPointerFree [RPCRT4.@]
2587 */
2588 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
2589 unsigned char *pMemory,
2590 PFORMAT_STRING pFormat)
2591 {
2592 FIXME("stub\n");
2593 }
2594
2595 /***********************************************************************
2596 * NdrXmitOrRepAsMarshall [RPCRT4.@]
2597 */
2598 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2599 unsigned char *pMemory,
2600 PFORMAT_STRING pFormat)
2601 {
2602 FIXME("stub\n");
2603 return NULL;
2604 }
2605
2606 /***********************************************************************
2607 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
2608 */
2609 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2610 unsigned char **ppMemory,
2611 PFORMAT_STRING pFormat,
2612 unsigned char fMustAlloc)
2613 {
2614 FIXME("stub\n");
2615 return NULL;
2616 }
2617
2618 /***********************************************************************
2619 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
2620 */
2621 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2622 unsigned char *pMemory,
2623 PFORMAT_STRING pFormat)
2624 {
2625 FIXME("stub\n");
2626 }
2627
2628 /***********************************************************************
2629 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
2630 */
2631 unsigned long WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2632 PFORMAT_STRING pFormat)
2633 {
2634 FIXME("stub\n");
2635 return 0;
2636 }
2637
2638 /***********************************************************************
2639 * NdrXmitOrRepAsFree [RPCRT4.@]
2640 */
2641 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
2642 unsigned char *pMemory,
2643 PFORMAT_STRING pFormat)
2644 {
2645 FIXME("stub\n");
2646 }
2647
2648 /***********************************************************************
2649 * NdrClientContextMarshall
2650 */
2651 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2652 NDR_CCONTEXT ContextHandle,
2653 int fCheck)
2654 {
2655 FIXME("(%p, %p, %d): stub\n", pStubMsg, ContextHandle, fCheck);
2656 }
2657
2658 /***********************************************************************
2659 * NdrClientContextUnmarshall
2660 */
2661 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2662 NDR_CCONTEXT * pContextHandle,
2663 RPC_BINDING_HANDLE BindHandle)
2664 {
2665 FIXME("(%p, %p, %p): stub\n", pStubMsg, pContextHandle, BindHandle);
2666 }