rpcrt4: Make UserMarshalFlags static.
[wine/hacks.git] / dlls / rpcrt4 / ndr_marshall.c
blob438d9e5774e3de00013ae352bfd1d634022e8461
1 /*
2 * NDR data marshalling
4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 * TODO:
22 * - Non-conformant strings
23 * - String structs
24 * - Varying arrays
25 * - Encapsulated unions
26 * - Byte count pointers
27 * - transmit_as/represent as
28 * - Multi-dimensional arrays
29 * - Conversion functions (NdrConvert)
30 * - Checks for integer overflow when calculating array sizes
31 * - Checks for out-of-memory conditions
34 #include <stdarg.h>
35 #include <stdio.h>
36 #include <string.h>
37 #include <assert.h>
38 #include <limits.h>
40 #include "windef.h"
41 #include "winbase.h"
42 #include "winerror.h"
43 #include "winreg.h"
45 #include "ndr_misc.h"
46 #include "rpcndr.h"
48 #include "wine/unicode.h"
49 #include "wine/rpcfc.h"
51 #include "wine/debug.h"
53 WINE_DEFAULT_DEBUG_CHANNEL(ole);
55 #if defined(__i386__)
56 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
57 (*((UINT32 *)(pchar)) = (uint32))
59 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
60 (*((UINT32 *)(pchar)))
61 #else
62 /* these would work for i386 too, but less efficient */
63 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
64 (*(pchar) = LOBYTE(LOWORD(uint32)), \
65 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
66 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
67 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
68 (uint32)) /* allow as r-value */
70 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
71 (MAKELONG( \
72 MAKEWORD(*(pchar), *((pchar)+1)), \
73 MAKEWORD(*((pchar)+2), *((pchar)+3))))
74 #endif
76 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
77 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
78 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
79 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
80 *(pchar) = HIBYTE(HIWORD(uint32)), \
81 (uint32)) /* allow as r-value */
83 #define BIG_ENDIAN_UINT32_READ(pchar) \
84 (MAKELONG( \
85 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
86 MAKEWORD(*((pchar)+1), *(pchar))))
88 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
89 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
90 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
91 # define NDR_LOCAL_UINT32_READ(pchar) \
92 BIG_ENDIAN_UINT32_READ(pchar)
93 #else
94 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
95 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
96 # define NDR_LOCAL_UINT32_READ(pchar) \
97 LITTLE_ENDIAN_UINT32_READ(pchar)
98 #endif
100 /* _Align must be the desired alignment,
101 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
102 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
103 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
104 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
105 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
107 #define STD_OVERFLOW_CHECK(_Msg) do { \
108 TRACE("buffer=%d/%ld\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
109 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
110 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
111 } while (0)
113 #define NDR_TABLE_SIZE 128
114 #define NDR_TABLE_MASK 127
116 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
117 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
118 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
119 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
120 static unsigned long WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
122 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
124 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
125 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
126 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
127 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
128 /* 0x10 */
129 NdrBaseTypeMarshall,
130 /* 0x11 */
131 NdrPointerMarshall, NdrPointerMarshall,
132 NdrPointerMarshall, NdrPointerMarshall,
133 /* 0x15 */
134 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
135 NdrConformantStructMarshall, NdrConformantStructMarshall,
136 NdrConformantVaryingStructMarshall,
137 NdrComplexStructMarshall,
138 /* 0x1b */
139 NdrConformantArrayMarshall,
140 NdrConformantVaryingArrayMarshall,
141 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
142 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
143 NdrComplexArrayMarshall,
144 /* 0x22 */
145 NdrConformantStringMarshall, 0, 0,
146 NdrConformantStringMarshall,
147 NdrNonConformantStringMarshall, 0, 0, 0,
148 /* 0x2a */
149 NdrEncapsulatedUnionMarshall,
150 NdrNonEncapsulatedUnionMarshall,
151 NdrByteCountPointerMarshall,
152 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
153 /* 0x2f */
154 NdrInterfacePointerMarshall,
155 /* 0xb0 */
156 0, 0, 0, 0,
157 NdrUserMarshalMarshall
159 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
161 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
162 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
163 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
164 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
165 /* 0x10 */
166 NdrBaseTypeUnmarshall,
167 /* 0x11 */
168 NdrPointerUnmarshall, NdrPointerUnmarshall,
169 NdrPointerUnmarshall, NdrPointerUnmarshall,
170 /* 0x15 */
171 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
172 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
173 NdrConformantVaryingStructUnmarshall,
174 NdrComplexStructUnmarshall,
175 /* 0x1b */
176 NdrConformantArrayUnmarshall,
177 NdrConformantVaryingArrayUnmarshall,
178 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
179 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
180 NdrComplexArrayUnmarshall,
181 /* 0x22 */
182 NdrConformantStringUnmarshall, 0, 0,
183 NdrConformantStringUnmarshall,
184 NdrNonConformantStringUnmarshall, 0, 0, 0,
185 /* 0x2a */
186 NdrEncapsulatedUnionUnmarshall,
187 NdrNonEncapsulatedUnionUnmarshall,
188 NdrByteCountPointerUnmarshall,
189 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
190 /* 0x2f */
191 NdrInterfacePointerUnmarshall,
192 /* 0xb0 */
193 0, 0, 0, 0,
194 NdrUserMarshalUnmarshall
196 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
198 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
199 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
200 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
201 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
202 /* 0x10 */
203 NdrBaseTypeBufferSize,
204 /* 0x11 */
205 NdrPointerBufferSize, NdrPointerBufferSize,
206 NdrPointerBufferSize, NdrPointerBufferSize,
207 /* 0x15 */
208 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
209 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
210 NdrConformantVaryingStructBufferSize,
211 NdrComplexStructBufferSize,
212 /* 0x1b */
213 NdrConformantArrayBufferSize,
214 NdrConformantVaryingArrayBufferSize,
215 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
216 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
217 NdrComplexArrayBufferSize,
218 /* 0x22 */
219 NdrConformantStringBufferSize, 0, 0,
220 NdrConformantStringBufferSize,
221 NdrNonConformantStringBufferSize, 0, 0, 0,
222 /* 0x2a */
223 NdrEncapsulatedUnionBufferSize,
224 NdrNonEncapsulatedUnionBufferSize,
225 NdrByteCountPointerBufferSize,
226 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
227 /* 0x2f */
228 NdrInterfacePointerBufferSize,
229 /* 0xb0 */
230 0, 0, 0, 0,
231 NdrUserMarshalBufferSize
233 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
235 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
236 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
237 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
238 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
239 /* 0x10 */
240 NdrBaseTypeMemorySize,
241 /* 0x11 */
242 NdrPointerMemorySize, NdrPointerMemorySize,
243 NdrPointerMemorySize, NdrPointerMemorySize,
244 /* 0x15 */
245 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
246 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
247 NdrConformantVaryingStructMemorySize,
248 NdrComplexStructMemorySize,
249 /* 0x1b */
250 NdrConformantArrayMemorySize,
251 NdrConformantVaryingArrayMemorySize,
252 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
253 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
254 NdrComplexArrayMemorySize,
255 /* 0x22 */
256 NdrConformantStringMemorySize, 0, 0,
257 NdrConformantStringMemorySize,
258 NdrNonConformantStringMemorySize, 0, 0, 0,
259 /* 0x2a */
260 NdrEncapsulatedUnionMemorySize,
261 NdrNonEncapsulatedUnionMemorySize,
262 NdrByteCountPointerMemorySize,
263 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
264 /* 0x2f */
265 NdrInterfacePointerMemorySize,
266 /* 0xb0 */
267 0, 0, 0, 0,
268 NdrUserMarshalMemorySize
270 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
272 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
273 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
274 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
275 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
276 /* 0x10 */
277 NdrBaseTypeFree,
278 /* 0x11 */
279 NdrPointerFree, NdrPointerFree,
280 NdrPointerFree, NdrPointerFree,
281 /* 0x15 */
282 NdrSimpleStructFree, NdrSimpleStructFree,
283 NdrConformantStructFree, NdrConformantStructFree,
284 NdrConformantVaryingStructFree,
285 NdrComplexStructFree,
286 /* 0x1b */
287 NdrConformantArrayFree,
288 NdrConformantVaryingArrayFree,
289 NdrFixedArrayFree, NdrFixedArrayFree,
290 NdrVaryingArrayFree, NdrVaryingArrayFree,
291 NdrComplexArrayFree,
292 /* 0x22 */
293 0, 0, 0,
294 0, 0, 0, 0, 0,
295 /* 0x2a */
296 NdrEncapsulatedUnionFree,
297 NdrNonEncapsulatedUnionFree,
299 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
300 /* 0x2f */
301 NdrInterfacePointerFree,
302 /* 0xb0 */
303 0, 0, 0, 0,
304 NdrUserMarshalFree
307 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
309 /* hmm, this is probably supposed to do more? */
310 return pStubMsg->pfnAllocate(len);
313 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
315 pStubMsg->pfnFree(Pointer);
318 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
320 return (*(const ULONG *)pFormat != -1);
323 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
325 ALIGN_POINTER(pStubMsg->Buffer, 4);
326 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
327 pStubMsg->Buffer += 4;
328 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
329 if (pStubMsg->fHasNewCorrDesc)
330 return pFormat+6;
331 else
332 return pFormat+4;
335 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
337 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
339 pStubMsg->Offset = 0;
340 pStubMsg->ActualCount = pStubMsg->MaxCount;
341 goto done;
344 ALIGN_POINTER(pStubMsg->Buffer, 4);
345 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
346 pStubMsg->Buffer += 4;
347 TRACE("offset is %ld\n", pStubMsg->Offset);
348 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
349 pStubMsg->Buffer += 4;
350 TRACE("variance is %ld\n", pStubMsg->ActualCount);
352 done:
353 if (pStubMsg->fHasNewCorrDesc)
354 return pFormat+6;
355 else
356 return pFormat+4;
359 /* writes the conformance value to the buffer */
360 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
362 ALIGN_POINTER(pStubMsg->Buffer, 4);
363 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
364 pStubMsg->Buffer += 4;
367 /* writes the variance values to the buffer */
368 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
370 ALIGN_POINTER(pStubMsg->Buffer, 4);
371 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
372 pStubMsg->Buffer += 4;
373 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
374 pStubMsg->Buffer += 4;
377 /* requests buffer space for the conformance value */
378 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
380 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
381 pStubMsg->BufferLength += 4;
384 /* requests buffer space for the variance values */
385 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
387 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
388 pStubMsg->BufferLength += 8;
391 PFORMAT_STRING ComputeConformanceOrVariance(
392 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
393 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG *pCount)
395 BYTE dtype = pFormat[0] & 0xf;
396 short ofs = *(short *)&pFormat[2];
397 LPVOID ptr = NULL;
398 DWORD data = 0;
400 if (!IsConformanceOrVariancePresent(pFormat)) {
401 /* null descriptor */
402 *pCount = def;
403 goto finish_conf;
406 switch (pFormat[0] & 0xf0) {
407 case RPC_FC_NORMAL_CONFORMANCE:
408 TRACE("normal conformance, ofs=%d\n", ofs);
409 ptr = pMemory;
410 break;
411 case RPC_FC_POINTER_CONFORMANCE:
412 TRACE("pointer conformance, ofs=%d\n", ofs);
413 ptr = pStubMsg->Memory;
414 break;
415 case RPC_FC_TOP_LEVEL_CONFORMANCE:
416 TRACE("toplevel conformance, ofs=%d\n", ofs);
417 if (pStubMsg->StackTop) {
418 ptr = pStubMsg->StackTop;
420 else {
421 /* -Os mode, *pCount is already set */
422 goto finish_conf;
424 break;
425 case RPC_FC_CONSTANT_CONFORMANCE:
426 data = ofs | ((DWORD)pFormat[1] << 16);
427 TRACE("constant conformance, val=%ld\n", data);
428 *pCount = data;
429 goto finish_conf;
430 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
431 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
432 if (pStubMsg->StackTop) {
433 ptr = pStubMsg->StackTop;
435 else {
436 /* ? */
437 goto done_conf_grab;
439 break;
440 default:
441 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
444 switch (pFormat[1]) {
445 case RPC_FC_DEREFERENCE:
446 ptr = *(LPVOID*)((char *)ptr + ofs);
447 break;
448 case RPC_FC_CALLBACK:
450 unsigned char *old_stack_top = pStubMsg->StackTop;
451 pStubMsg->StackTop = ptr;
453 /* ofs is index into StubDesc->apfnExprEval */
454 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
455 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
457 pStubMsg->StackTop = old_stack_top;
458 goto finish_conf;
460 default:
461 ptr = (char *)ptr + ofs;
462 break;
465 switch (dtype) {
466 case RPC_FC_LONG:
467 case RPC_FC_ULONG:
468 data = *(DWORD*)ptr;
469 break;
470 case RPC_FC_SHORT:
471 data = *(SHORT*)ptr;
472 break;
473 case RPC_FC_USHORT:
474 data = *(USHORT*)ptr;
475 break;
476 case RPC_FC_CHAR:
477 case RPC_FC_SMALL:
478 data = *(CHAR*)ptr;
479 break;
480 case RPC_FC_BYTE:
481 case RPC_FC_USMALL:
482 data = *(UCHAR*)ptr;
483 break;
484 default:
485 FIXME("unknown conformance data type %x\n", dtype);
486 goto done_conf_grab;
488 TRACE("dereferenced data type %x at %p, got %ld\n", dtype, ptr, data);
490 done_conf_grab:
491 switch (pFormat[1]) {
492 case RPC_FC_DEREFERENCE: /* already handled */
493 case 0: /* no op */
494 *pCount = data;
495 break;
496 case RPC_FC_ADD_1:
497 *pCount = data + 1;
498 break;
499 case RPC_FC_SUB_1:
500 *pCount = data - 1;
501 break;
502 case RPC_FC_MULT_2:
503 *pCount = data * 2;
504 break;
505 case RPC_FC_DIV_2:
506 *pCount = data / 2;
507 break;
508 default:
509 FIXME("unknown conformance op %d\n", pFormat[1]);
510 goto finish_conf;
513 finish_conf:
514 TRACE("resulting conformance is %ld\n", *pCount);
515 if (pStubMsg->fHasNewCorrDesc)
516 return pFormat+6;
517 else
518 return pFormat+4;
523 * NdrConformantString:
525 * What MS calls a ConformantString is, in DCE terminology,
526 * a Varying-Conformant String.
528 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
529 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
530 * into unmarshalled string)
531 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
532 * [
533 * data: CHARTYPE[maxlen]
534 * ]
535 * ], where CHARTYPE is the appropriate character type (specified externally)
539 /***********************************************************************
540 * NdrConformantStringMarshall [RPCRT4.@]
542 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
543 unsigned char *pszMessage, PFORMAT_STRING pFormat)
545 unsigned long esize;
547 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
549 if (*pFormat == RPC_FC_C_CSTRING) {
550 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
551 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
552 esize = 1;
554 else if (*pFormat == RPC_FC_C_WSTRING) {
555 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
556 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
557 esize = 2;
559 else {
560 ERR("Unhandled string type: %#x\n", *pFormat);
561 /* FIXME: raise an exception. */
562 return NULL;
565 if (pFormat[1] == RPC_FC_STRING_SIZED)
566 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
567 else
568 pStubMsg->MaxCount = pStubMsg->ActualCount;
569 pStubMsg->Offset = 0;
570 WriteConformance(pStubMsg);
571 WriteVariance(pStubMsg);
573 memcpy(pStubMsg->Buffer, pszMessage, pStubMsg->ActualCount*esize); /* the string itself */
574 pStubMsg->Buffer += pStubMsg->ActualCount*esize;
576 STD_OVERFLOW_CHECK(pStubMsg);
578 /* success */
579 return NULL; /* is this always right? */
582 /***********************************************************************
583 * NdrConformantStringBufferSize [RPCRT4.@]
585 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
586 unsigned char* pMemory, PFORMAT_STRING pFormat)
588 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
590 SizeConformance(pStubMsg);
591 SizeVariance(pStubMsg);
593 if (*pFormat == RPC_FC_C_CSTRING) {
594 /* we need + 1 octet for '\0' */
595 TRACE("string=%s\n", debugstr_a((char*)pMemory));
596 pStubMsg->BufferLength += strlen((char*)pMemory) + 1;
598 else if (*pFormat == RPC_FC_C_WSTRING) {
599 /* we need + 2 octets for L'\0' */
600 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
601 pStubMsg->BufferLength += strlenW((LPWSTR)pMemory)*2 + 2;
603 else {
604 ERR("Unhandled string type: %#x\n", *pFormat);
605 /* FIXME: raise an exception */
609 /************************************************************************
610 * NdrConformantStringMemorySize [RPCRT4.@]
612 unsigned long WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
613 PFORMAT_STRING pFormat )
615 unsigned long rslt = 0;
617 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
619 assert(pStubMsg && pFormat);
621 if (*pFormat == RPC_FC_C_CSTRING) {
622 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
624 else if (*pFormat == RPC_FC_C_WSTRING) {
625 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
627 else {
628 ERR("Unhandled string type: %#x\n", *pFormat);
629 /* FIXME: raise an exception */
632 if (pFormat[1] != RPC_FC_PAD) {
633 FIXME("sized string format=%d\n", pFormat[1]);
636 TRACE(" --> %lu\n", rslt);
637 return rslt;
640 /************************************************************************
641 * NdrConformantStringUnmarshall [RPCRT4.@]
643 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
644 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
646 unsigned long len, esize;
648 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
649 pStubMsg, *ppMemory, pFormat, fMustAlloc);
651 assert(pFormat && ppMemory && pStubMsg);
653 ReadConformance(pStubMsg, NULL);
654 ReadVariance(pStubMsg, NULL);
656 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
657 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
658 else {
659 ERR("Unhandled string type: %#x\n", *pFormat);
660 /* FIXME: raise an exception */
661 esize = 0;
664 len = pStubMsg->ActualCount;
666 if (fMustAlloc || !*ppMemory)
667 *ppMemory = NdrAllocate(pStubMsg, len*esize);
669 memcpy(*ppMemory, pStubMsg->Buffer, len*esize);
671 pStubMsg->Buffer += len*esize;
673 if (*pFormat == RPC_FC_C_CSTRING) {
674 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
676 else if (*pFormat == RPC_FC_C_WSTRING) {
677 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
680 return NULL; /* FIXME: is this always right? */
683 /***********************************************************************
684 * NdrNonConformantStringMarshall [RPCRT4.@]
686 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
687 unsigned char *pMemory,
688 PFORMAT_STRING pFormat)
690 FIXME("stub\n");
691 return NULL;
694 /***********************************************************************
695 * NdrNonConformantStringUnmarshall [RPCRT4.@]
697 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
698 unsigned char **ppMemory,
699 PFORMAT_STRING pFormat,
700 unsigned char fMustAlloc)
702 FIXME("stub\n");
703 return NULL;
706 /***********************************************************************
707 * NdrNonConformantStringBufferSize [RPCRT4.@]
709 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
710 unsigned char *pMemory,
711 PFORMAT_STRING pFormat)
713 FIXME("stub\n");
716 /***********************************************************************
717 * NdrNonConformantStringMemorySize [RPCRT4.@]
719 unsigned long WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
720 PFORMAT_STRING pFormat)
722 FIXME("stub\n");
723 return 0;
726 static inline void dump_pointer_attr(unsigned char attr)
728 if (attr & RPC_FC_P_ALLOCALLNODES)
729 TRACE(" RPC_FC_P_ALLOCALLNODES");
730 if (attr & RPC_FC_P_DONTFREE)
731 TRACE(" RPC_FC_P_DONTFREE");
732 if (attr & RPC_FC_P_ONSTACK)
733 TRACE(" RPC_FC_P_ONSTACK");
734 if (attr & RPC_FC_P_SIMPLEPOINTER)
735 TRACE(" RPC_FC_P_SIMPLEPOINTER");
736 if (attr & RPC_FC_P_DEREF)
737 TRACE(" RPC_FC_P_DEREF");
738 TRACE("\n");
741 /***********************************************************************
742 * PointerMarshall
744 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
745 unsigned char *Buffer,
746 unsigned char *Pointer,
747 PFORMAT_STRING pFormat)
749 unsigned type = pFormat[0], attr = pFormat[1];
750 PFORMAT_STRING desc;
751 NDR_MARSHALL m;
752 unsigned long pointer_id;
753 int pointer_needs_marshaling;
755 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
756 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
757 pFormat += 2;
758 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
759 else desc = pFormat + *(const SHORT*)pFormat;
761 switch (type) {
762 case RPC_FC_RP: /* ref pointer (always non-null) */
763 #if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
764 if (!Pointer)
765 RpcRaiseException(RPC_X_NULL_REF_POINTER);
766 #endif
767 pointer_needs_marshaling = 1;
768 break;
769 case RPC_FC_UP: /* unique pointer */
770 case RPC_FC_OP: /* object pointer - same as unique here */
771 if (Pointer)
772 pointer_needs_marshaling = 1;
773 else
774 pointer_needs_marshaling = 0;
775 pointer_id = (unsigned long)Pointer;
776 TRACE("writing 0x%08lx to buffer\n", pointer_id);
777 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
778 break;
779 case RPC_FC_FP:
780 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
781 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
782 TRACE("writing 0x%08lx to buffer\n", pointer_id);
783 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
784 break;
785 default:
786 FIXME("unhandled ptr type=%02x\n", type);
787 RpcRaiseException(RPC_X_BAD_STUB_DATA);
788 return;
791 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
793 if (pointer_needs_marshaling) {
794 if (attr & RPC_FC_P_DEREF) {
795 Pointer = *(unsigned char**)Pointer;
796 TRACE("deref => %p\n", Pointer);
798 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
799 if (m) m(pStubMsg, Pointer, desc);
800 else FIXME("no marshaller for data type=%02x\n", *desc);
803 STD_OVERFLOW_CHECK(pStubMsg);
806 /***********************************************************************
807 * PointerUnmarshall
809 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
810 unsigned char *Buffer,
811 unsigned char **pPointer,
812 PFORMAT_STRING pFormat,
813 unsigned char fMustAlloc)
815 unsigned type = pFormat[0], attr = pFormat[1];
816 PFORMAT_STRING desc;
817 NDR_UNMARSHALL m;
818 DWORD pointer_id = 0;
819 int pointer_needs_unmarshaling;
821 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pFormat, fMustAlloc);
822 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
823 pFormat += 2;
824 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
825 else desc = pFormat + *(const SHORT*)pFormat;
827 switch (type) {
828 case RPC_FC_RP: /* ref pointer (always non-null) */
829 pointer_needs_unmarshaling = 1;
830 break;
831 case RPC_FC_UP: /* unique pointer */
832 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
833 TRACE("pointer_id is 0x%08lx\n", pointer_id);
834 if (pointer_id)
835 pointer_needs_unmarshaling = 1;
836 else {
837 *pPointer = NULL;
838 pointer_needs_unmarshaling = 0;
840 break;
841 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
842 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
843 TRACE("pointer_id is 0x%08lx\n", pointer_id);
844 if (!fMustAlloc && *pPointer)
845 FIXME("free object pointer %p\n", *pPointer);
846 if (pointer_id)
847 pointer_needs_unmarshaling = 1;
848 else
849 pointer_needs_unmarshaling = 0;
850 break;
851 case RPC_FC_FP:
852 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
853 TRACE("pointer_id is 0x%08lx\n", pointer_id);
854 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
855 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
856 break;
857 default:
858 FIXME("unhandled ptr type=%02x\n", type);
859 RpcRaiseException(RPC_X_BAD_STUB_DATA);
860 return;
863 if (pointer_needs_unmarshaling) {
864 if (attr & RPC_FC_P_DEREF) {
865 if (!*pPointer || fMustAlloc)
866 *pPointer = NdrAllocate(pStubMsg, sizeof(void *));
867 pPointer = *(unsigned char***)pPointer;
868 TRACE("deref => %p\n", pPointer);
870 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
871 if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
872 else FIXME("no unmarshaller for data type=%02x\n", *desc);
874 if (type == RPC_FC_FP)
875 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
876 *pPointer);
879 TRACE("pointer=%p\n", *pPointer);
882 /***********************************************************************
883 * PointerBufferSize
885 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
886 unsigned char *Pointer,
887 PFORMAT_STRING pFormat)
889 unsigned type = pFormat[0], attr = pFormat[1];
890 PFORMAT_STRING desc;
891 NDR_BUFFERSIZE m;
892 int pointer_needs_sizing;
893 unsigned long pointer_id;
895 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
896 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
897 pFormat += 2;
898 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
899 else desc = pFormat + *(const SHORT*)pFormat;
901 switch (type) {
902 case RPC_FC_RP: /* ref pointer (always non-null) */
903 break;
904 case RPC_FC_OP:
905 case RPC_FC_UP:
906 /* NULL pointer has no further representation */
907 if (!Pointer)
908 return;
909 break;
910 case RPC_FC_FP:
911 pointer_needs_sizing = !NdrFullPointerQueryPointer(
912 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
913 if (!pointer_needs_sizing)
914 return;
915 break;
916 default:
917 FIXME("unhandled ptr type=%02x\n", type);
918 RpcRaiseException(RPC_X_BAD_STUB_DATA);
919 return;
922 if (attr & RPC_FC_P_DEREF) {
923 Pointer = *(unsigned char**)Pointer;
924 TRACE("deref => %p\n", Pointer);
927 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
928 if (m) m(pStubMsg, Pointer, desc);
929 else FIXME("no buffersizer for data type=%02x\n", *desc);
932 /***********************************************************************
933 * PointerMemorySize [RPCRT4.@]
935 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
936 unsigned char *Buffer,
937 PFORMAT_STRING pFormat)
939 unsigned type = pFormat[0], attr = pFormat[1];
940 PFORMAT_STRING desc;
941 NDR_MEMORYSIZE m;
943 FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat);
944 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
945 pFormat += 2;
946 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
947 else desc = pFormat + *(const SHORT*)pFormat;
949 switch (type) {
950 case RPC_FC_RP: /* ref pointer (always non-null) */
951 break;
952 default:
953 FIXME("unhandled ptr type=%02x\n", type);
954 RpcRaiseException(RPC_X_BAD_STUB_DATA);
957 if (attr & RPC_FC_P_DEREF) {
958 TRACE("deref\n");
961 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
962 if (m) m(pStubMsg, desc);
963 else FIXME("no memorysizer for data type=%02x\n", *desc);
965 return 0;
968 /***********************************************************************
969 * PointerFree [RPCRT4.@]
971 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
972 unsigned char *Pointer,
973 PFORMAT_STRING pFormat)
975 unsigned type = pFormat[0], attr = pFormat[1];
976 PFORMAT_STRING desc;
977 NDR_FREE m;
979 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
980 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
981 if (attr & RPC_FC_P_DONTFREE) return;
982 pFormat += 2;
983 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
984 else desc = pFormat + *(const SHORT*)pFormat;
986 if (!Pointer) return;
988 if (type == RPC_FC_FP) {
989 int pointer_needs_freeing = NdrFullPointerFree(
990 pStubMsg->FullPtrXlatTables, Pointer);
991 if (!pointer_needs_freeing)
992 return;
995 if (attr & RPC_FC_P_DEREF) {
996 Pointer = *(unsigned char**)Pointer;
997 TRACE("deref => %p\n", Pointer);
1000 m = NdrFreer[*desc & NDR_TABLE_MASK];
1001 if (m) m(pStubMsg, Pointer, desc);
1003 /* hmm... is this sensible?
1004 * perhaps we should check if the memory comes from NdrAllocate,
1005 * and deallocate only if so - checking if the pointer is between
1006 * BufferStart and BufferEnd is probably no good since the buffer
1007 * may be reallocated when the server wants to marshal the reply */
1008 switch (*desc) {
1009 case RPC_FC_BOGUS_STRUCT:
1010 case RPC_FC_BOGUS_ARRAY:
1011 case RPC_FC_USER_MARSHAL:
1012 case RPC_FC_CARRAY:
1013 case RPC_FC_CVARRAY:
1014 break;
1015 default:
1016 FIXME("unhandled data type=%02x\n", *desc);
1017 break;
1018 case RPC_FC_C_CSTRING:
1019 case RPC_FC_C_WSTRING:
1020 if (pStubMsg->ReuseBuffer) goto notfree;
1021 break;
1022 case RPC_FC_IP:
1023 goto notfree;
1026 if (attr & RPC_FC_P_ONSTACK) {
1027 TRACE("not freeing stack ptr %p\n", Pointer);
1028 return;
1030 TRACE("freeing %p\n", Pointer);
1031 NdrFree(pStubMsg, Pointer);
1032 return;
1033 notfree:
1034 TRACE("not freeing %p\n", Pointer);
1037 /***********************************************************************
1038 * EmbeddedPointerMarshall
1040 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1041 unsigned char *pMemory,
1042 PFORMAT_STRING pFormat)
1044 unsigned char *Mark = pStubMsg->BufferMark;
1045 unsigned long Offset = pStubMsg->Offset;
1046 unsigned ofs, rep, count, stride, xofs;
1047 unsigned i;
1049 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1051 if (*pFormat != RPC_FC_PP) return NULL;
1052 pFormat += 2;
1054 while (pFormat[0] != RPC_FC_END) {
1055 switch (pFormat[0]) {
1056 default:
1057 FIXME("unknown repeat type %d\n", pFormat[0]);
1058 case RPC_FC_NO_REPEAT:
1059 rep = 1;
1060 stride = 0;
1061 ofs = 0;
1062 count = 1;
1063 xofs = 0;
1064 pFormat += 2;
1065 break;
1066 case RPC_FC_FIXED_REPEAT:
1067 rep = *(const WORD*)&pFormat[2];
1068 stride = *(const WORD*)&pFormat[4];
1069 ofs = *(const WORD*)&pFormat[6];
1070 count = *(const WORD*)&pFormat[8];
1071 xofs = 0;
1072 pFormat += 10;
1073 break;
1074 case RPC_FC_VARIABLE_REPEAT:
1075 rep = pStubMsg->MaxCount;
1076 stride = *(const WORD*)&pFormat[2];
1077 ofs = *(const WORD*)&pFormat[4];
1078 count = *(const WORD*)&pFormat[6];
1079 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1080 pFormat += 8;
1081 break;
1083 for (i = 0; i < rep; i++) {
1084 PFORMAT_STRING info = pFormat;
1085 unsigned char *membase = pMemory + (i * stride);
1086 unsigned char *bufbase = Mark + (i * stride);
1087 unsigned u;
1088 /* ofs doesn't seem to matter in this context */
1089 for (u=0; u<count; u++,info+=8) {
1090 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1091 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1092 unsigned char *saved_memory = pStubMsg->Memory;
1094 pStubMsg->Memory = pMemory;
1095 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1096 pStubMsg->Memory = saved_memory;
1099 pFormat += 8 * count;
1102 STD_OVERFLOW_CHECK(pStubMsg);
1104 return NULL;
1107 /***********************************************************************
1108 * EmbeddedPointerUnmarshall
1110 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1111 unsigned char **ppMemory,
1112 PFORMAT_STRING pFormat,
1113 unsigned char fMustAlloc)
1115 unsigned char *Mark = pStubMsg->BufferMark;
1116 unsigned long Offset = pStubMsg->Offset;
1117 unsigned ofs, rep, count, stride, xofs;
1118 unsigned i;
1120 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1122 if (*pFormat != RPC_FC_PP) return NULL;
1123 pFormat += 2;
1125 while (pFormat[0] != RPC_FC_END) {
1126 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1127 switch (pFormat[0]) {
1128 default:
1129 FIXME("unknown repeat type %d\n", pFormat[0]);
1130 case RPC_FC_NO_REPEAT:
1131 rep = 1;
1132 stride = 0;
1133 ofs = 0;
1134 count = 1;
1135 xofs = 0;
1136 pFormat += 2;
1137 break;
1138 case RPC_FC_FIXED_REPEAT:
1139 rep = *(const WORD*)&pFormat[2];
1140 stride = *(const WORD*)&pFormat[4];
1141 ofs = *(const WORD*)&pFormat[6];
1142 count = *(const WORD*)&pFormat[8];
1143 xofs = 0;
1144 pFormat += 10;
1145 break;
1146 case RPC_FC_VARIABLE_REPEAT:
1147 rep = pStubMsg->MaxCount;
1148 stride = *(const WORD*)&pFormat[2];
1149 ofs = *(const WORD*)&pFormat[4];
1150 count = *(const WORD*)&pFormat[6];
1151 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1152 pFormat += 8;
1153 break;
1155 /* ofs doesn't seem to matter in this context */
1156 for (i = 0; i < rep; i++) {
1157 PFORMAT_STRING info = pFormat;
1158 unsigned char *membase = *ppMemory + (i * stride);
1159 unsigned char *bufbase = Mark + (i * stride);
1160 unsigned u;
1161 for (u=0; u<count; u++,info+=8) {
1162 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1163 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1164 PointerUnmarshall(pStubMsg, bufptr, (unsigned char**)memptr, info+4, TRUE);
1167 pFormat += 8 * count;
1170 return NULL;
1173 /***********************************************************************
1174 * EmbeddedPointerBufferSize
1176 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1177 unsigned char *pMemory,
1178 PFORMAT_STRING pFormat)
1180 unsigned long Offset = pStubMsg->Offset;
1181 unsigned ofs, rep, count, stride, xofs;
1182 unsigned i;
1184 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1186 if (pStubMsg->IgnoreEmbeddedPointers) return;
1188 if (*pFormat != RPC_FC_PP) return;
1189 pFormat += 2;
1191 while (pFormat[0] != RPC_FC_END) {
1192 switch (pFormat[0]) {
1193 default:
1194 FIXME("unknown repeat type %d\n", pFormat[0]);
1195 case RPC_FC_NO_REPEAT:
1196 rep = 1;
1197 stride = 0;
1198 ofs = 0;
1199 count = 1;
1200 xofs = 0;
1201 pFormat += 2;
1202 break;
1203 case RPC_FC_FIXED_REPEAT:
1204 rep = *(const WORD*)&pFormat[2];
1205 stride = *(const WORD*)&pFormat[4];
1206 ofs = *(const WORD*)&pFormat[6];
1207 count = *(const WORD*)&pFormat[8];
1208 xofs = 0;
1209 pFormat += 10;
1210 break;
1211 case RPC_FC_VARIABLE_REPEAT:
1212 rep = pStubMsg->MaxCount;
1213 stride = *(const WORD*)&pFormat[2];
1214 ofs = *(const WORD*)&pFormat[4];
1215 count = *(const WORD*)&pFormat[6];
1216 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1217 pFormat += 8;
1218 break;
1220 /* ofs doesn't seem to matter in this context */
1221 for (i = 0; i < rep; i++) {
1222 PFORMAT_STRING info = pFormat;
1223 unsigned char *membase = pMemory + (i * stride);
1224 unsigned u;
1225 for (u=0; u<count; u++,info+=8) {
1226 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1227 unsigned char *saved_memory = pStubMsg->Memory;
1229 pStubMsg->Memory = pMemory;
1230 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1231 pStubMsg->Memory = saved_memory;
1234 pFormat += 8 * count;
1238 /***********************************************************************
1239 * EmbeddedPointerMemorySize
1241 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1242 PFORMAT_STRING pFormat)
1244 unsigned long Offset = pStubMsg->Offset;
1245 unsigned char *Mark = pStubMsg->BufferMark;
1246 unsigned ofs, rep, count, stride, xofs;
1247 unsigned i;
1249 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1251 if (*pFormat != RPC_FC_PP) return 0;
1252 pFormat += 2;
1254 while (pFormat[0] != RPC_FC_END) {
1255 switch (pFormat[0]) {
1256 default:
1257 FIXME("unknown repeat type %d\n", pFormat[0]);
1258 case RPC_FC_NO_REPEAT:
1259 rep = 1;
1260 stride = 0;
1261 ofs = 0;
1262 count = 1;
1263 xofs = 0;
1264 pFormat += 2;
1265 break;
1266 case RPC_FC_FIXED_REPEAT:
1267 rep = *(const WORD*)&pFormat[2];
1268 stride = *(const WORD*)&pFormat[4];
1269 ofs = *(const WORD*)&pFormat[6];
1270 count = *(const WORD*)&pFormat[8];
1271 xofs = 0;
1272 pFormat += 10;
1273 break;
1274 case RPC_FC_VARIABLE_REPEAT:
1275 rep = pStubMsg->MaxCount;
1276 stride = *(const WORD*)&pFormat[2];
1277 ofs = *(const WORD*)&pFormat[4];
1278 count = *(const WORD*)&pFormat[6];
1279 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1280 pFormat += 8;
1281 break;
1283 /* ofs doesn't seem to matter in this context */
1284 for (i = 0; i < rep; i++) {
1285 PFORMAT_STRING info = pFormat;
1286 unsigned char *bufbase = Mark + (i * stride);
1287 unsigned u;
1288 for (u=0; u<count; u++,info+=8) {
1289 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1290 PointerMemorySize(pStubMsg, bufptr, info+4);
1293 pFormat += 8 * count;
1296 return 0;
1299 /***********************************************************************
1300 * EmbeddedPointerFree
1302 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1303 unsigned char *pMemory,
1304 PFORMAT_STRING pFormat)
1306 unsigned long Offset = pStubMsg->Offset;
1307 unsigned ofs, rep, count, stride, xofs;
1308 unsigned i;
1310 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1311 if (*pFormat != RPC_FC_PP) return;
1312 pFormat += 2;
1314 while (pFormat[0] != RPC_FC_END) {
1315 switch (pFormat[0]) {
1316 default:
1317 FIXME("unknown repeat type %d\n", pFormat[0]);
1318 case RPC_FC_NO_REPEAT:
1319 rep = 1;
1320 stride = 0;
1321 ofs = 0;
1322 count = 1;
1323 xofs = 0;
1324 pFormat += 2;
1325 break;
1326 case RPC_FC_FIXED_REPEAT:
1327 rep = *(const WORD*)&pFormat[2];
1328 stride = *(const WORD*)&pFormat[4];
1329 ofs = *(const WORD*)&pFormat[6];
1330 count = *(const WORD*)&pFormat[8];
1331 xofs = 0;
1332 pFormat += 10;
1333 break;
1334 case RPC_FC_VARIABLE_REPEAT:
1335 rep = pStubMsg->MaxCount;
1336 stride = *(const WORD*)&pFormat[2];
1337 ofs = *(const WORD*)&pFormat[4];
1338 count = *(const WORD*)&pFormat[6];
1339 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1340 pFormat += 8;
1341 break;
1343 /* ofs doesn't seem to matter in this context */
1344 for (i = 0; i < rep; i++) {
1345 PFORMAT_STRING info = pFormat;
1346 unsigned char *membase = pMemory + (i * stride);
1347 unsigned u;
1348 for (u=0; u<count; u++,info+=8) {
1349 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1350 unsigned char *saved_memory = pStubMsg->Memory;
1352 pStubMsg->Memory = pMemory;
1353 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1354 pStubMsg->Memory = saved_memory;
1357 pFormat += 8 * count;
1361 /***********************************************************************
1362 * NdrPointerMarshall [RPCRT4.@]
1364 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1365 unsigned char *pMemory,
1366 PFORMAT_STRING pFormat)
1368 unsigned char *Buffer;
1370 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1372 /* incremement the buffer here instead of in PointerMarshall,
1373 * as that is used by embedded pointers which already handle the incrementing
1374 * the buffer, and shouldn't write any additional pointer data to the wire */
1375 if (*pFormat != RPC_FC_RP)
1377 ALIGN_POINTER(pStubMsg->Buffer, 4);
1378 Buffer = pStubMsg->Buffer;
1379 pStubMsg->Buffer += 4;
1381 else
1382 Buffer = pStubMsg->Buffer;
1384 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1386 STD_OVERFLOW_CHECK(pStubMsg);
1388 return NULL;
1391 /***********************************************************************
1392 * NdrPointerUnmarshall [RPCRT4.@]
1394 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1395 unsigned char **ppMemory,
1396 PFORMAT_STRING pFormat,
1397 unsigned char fMustAlloc)
1399 unsigned char *Buffer;
1401 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1403 /* incremement the buffer here instead of in PointerUnmarshall,
1404 * as that is used by embedded pointers which already handle the incrementing
1405 * the buffer, and shouldn't read any additional pointer data from the
1406 * buffer */
1407 if (*pFormat != RPC_FC_RP)
1409 ALIGN_POINTER(pStubMsg->Buffer, 4);
1410 Buffer = pStubMsg->Buffer;
1411 pStubMsg->Buffer += 4;
1413 else
1414 Buffer = pStubMsg->Buffer;
1416 PointerUnmarshall(pStubMsg, Buffer, ppMemory, pFormat, fMustAlloc);
1418 return NULL;
1421 /***********************************************************************
1422 * NdrPointerBufferSize [RPCRT4.@]
1424 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1425 unsigned char *pMemory,
1426 PFORMAT_STRING pFormat)
1428 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1430 /* incremement the buffer length here instead of in PointerBufferSize,
1431 * as that is used by embedded pointers which already handle the buffer
1432 * length, and shouldn't write anything more to the wire */
1433 if (*pFormat != RPC_FC_RP)
1435 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1436 pStubMsg->BufferLength += 4;
1439 PointerBufferSize(pStubMsg, pMemory, pFormat);
1442 /***********************************************************************
1443 * NdrPointerMemorySize [RPCRT4.@]
1445 unsigned long WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1446 PFORMAT_STRING pFormat)
1448 /* unsigned size = *(LPWORD)(pFormat+2); */
1449 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1450 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1451 return 0;
1454 /***********************************************************************
1455 * NdrPointerFree [RPCRT4.@]
1457 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1458 unsigned char *pMemory,
1459 PFORMAT_STRING pFormat)
1461 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1462 PointerFree(pStubMsg, pMemory, pFormat);
1465 /***********************************************************************
1466 * NdrSimpleTypeMarshall [RPCRT4.@]
1468 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1469 unsigned char FormatChar )
1471 FIXME("stub\n");
1474 /***********************************************************************
1475 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1477 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1478 unsigned char FormatChar )
1480 FIXME("stub\n");
1483 /***********************************************************************
1484 * NdrSimpleStructMarshall [RPCRT4.@]
1486 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1487 unsigned char *pMemory,
1488 PFORMAT_STRING pFormat)
1490 unsigned size = *(const WORD*)(pFormat+2);
1491 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1493 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1495 memcpy(pStubMsg->Buffer, pMemory, size);
1496 pStubMsg->BufferMark = pStubMsg->Buffer;
1497 pStubMsg->Buffer += size;
1499 if (pFormat[0] != RPC_FC_STRUCT)
1500 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1502 STD_OVERFLOW_CHECK(pStubMsg);
1504 return NULL;
1507 /***********************************************************************
1508 * NdrSimpleStructUnmarshall [RPCRT4.@]
1510 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1511 unsigned char **ppMemory,
1512 PFORMAT_STRING pFormat,
1513 unsigned char fMustAlloc)
1515 unsigned size = *(const WORD*)(pFormat+2);
1516 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1518 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1520 if (fMustAlloc) {
1521 *ppMemory = NdrAllocate(pStubMsg, size);
1522 memcpy(*ppMemory, pStubMsg->Buffer, size);
1523 } else {
1524 if (!pStubMsg->IsClient && !*ppMemory)
1525 /* for servers, we just point straight into the RPC buffer */
1526 *ppMemory = pStubMsg->Buffer;
1527 else
1528 /* for clients, memory should be provided by caller */
1529 memcpy(*ppMemory, pStubMsg->Buffer, size);
1532 pStubMsg->BufferMark = pStubMsg->Buffer;
1533 pStubMsg->Buffer += size;
1535 if (pFormat[0] != RPC_FC_STRUCT)
1536 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat+4, fMustAlloc);
1538 return NULL;
1541 /***********************************************************************
1542 * NdrSimpleStructBufferSize [RPCRT4.@]
1544 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1545 unsigned char *pMemory,
1546 PFORMAT_STRING pFormat)
1548 unsigned size = *(const WORD*)(pFormat+2);
1549 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1551 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1553 pStubMsg->BufferLength += size;
1554 if (pFormat[0] != RPC_FC_STRUCT)
1555 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1558 /***********************************************************************
1559 * NdrSimpleStructMemorySize [RPCRT4.@]
1561 unsigned long WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1562 PFORMAT_STRING pFormat)
1564 unsigned short size = *(LPWORD)(pFormat+2);
1566 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1568 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1569 pStubMsg->MemorySize += size;
1570 pStubMsg->Buffer += size;
1572 if (pFormat[0] != RPC_FC_STRUCT)
1573 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1574 return size;
1577 /***********************************************************************
1578 * NdrSimpleStructFree [RPCRT4.@]
1580 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1581 unsigned char *pMemory,
1582 PFORMAT_STRING pFormat)
1584 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1585 if (pFormat[0] != RPC_FC_STRUCT)
1586 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1590 static unsigned long EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg,
1591 PFORMAT_STRING pFormat)
1593 switch (*pFormat) {
1594 case RPC_FC_STRUCT:
1595 case RPC_FC_PSTRUCT:
1596 case RPC_FC_CSTRUCT:
1597 case RPC_FC_BOGUS_STRUCT:
1598 return *(const WORD*)&pFormat[2];
1599 case RPC_FC_USER_MARSHAL:
1600 return *(const WORD*)&pFormat[4];
1601 case RPC_FC_NON_ENCAPSULATED_UNION:
1602 pFormat += 2;
1603 if (pStubMsg->fHasNewCorrDesc)
1604 pFormat += 6;
1605 else
1606 pFormat += 4;
1608 pFormat += *(const SHORT*)pFormat;
1609 return *(const SHORT*)pFormat;
1610 case RPC_FC_IP:
1611 return sizeof(void *);
1612 default:
1613 FIXME("unhandled embedded type %02x\n", *pFormat);
1615 return 0;
1619 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1620 PFORMAT_STRING pFormat)
1622 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1624 if (!m)
1626 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1627 return 0;
1630 return m(pStubMsg, pFormat);
1634 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1635 unsigned char *pMemory,
1636 PFORMAT_STRING pFormat,
1637 PFORMAT_STRING pPointer)
1639 PFORMAT_STRING desc;
1640 NDR_MARSHALL m;
1641 unsigned long size;
1643 while (*pFormat != RPC_FC_END) {
1644 switch (*pFormat) {
1645 case RPC_FC_SHORT:
1646 case RPC_FC_USHORT:
1647 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1648 memcpy(pStubMsg->Buffer, pMemory, 2);
1649 pStubMsg->Buffer += 2;
1650 pMemory += 2;
1651 break;
1652 case RPC_FC_LONG:
1653 case RPC_FC_ULONG:
1654 case RPC_FC_ENUM32:
1655 TRACE("long=%ld <= %p\n", *(DWORD*)pMemory, pMemory);
1656 memcpy(pStubMsg->Buffer, pMemory, 4);
1657 pStubMsg->Buffer += 4;
1658 pMemory += 4;
1659 break;
1660 case RPC_FC_POINTER:
1661 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1662 NdrPointerMarshall(pStubMsg, *(unsigned char**)pMemory, pPointer);
1663 pPointer += 4;
1664 pMemory += 4;
1665 break;
1666 case RPC_FC_ALIGNM4:
1667 ALIGN_POINTER(pMemory, 4);
1668 break;
1669 case RPC_FC_ALIGNM8:
1670 ALIGN_POINTER(pMemory, 8);
1671 break;
1672 case RPC_FC_STRUCTPAD2:
1673 pMemory += 2;
1674 break;
1675 case RPC_FC_EMBEDDED_COMPLEX:
1676 pMemory += pFormat[1];
1677 pFormat += 2;
1678 desc = pFormat + *(const SHORT*)pFormat;
1679 size = EmbeddedComplexSize(pStubMsg, desc);
1680 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1681 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1682 if (m) m(pStubMsg, pMemory, desc);
1683 else FIXME("no marshaller for embedded type %02x\n", *desc);
1684 pMemory += size;
1685 pFormat += 2;
1686 continue;
1687 case RPC_FC_PAD:
1688 break;
1689 default:
1690 FIXME("unhandled format %02x\n", *pFormat);
1692 pFormat++;
1695 return pMemory;
1698 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1699 unsigned char *pMemory,
1700 PFORMAT_STRING pFormat,
1701 PFORMAT_STRING pPointer)
1703 PFORMAT_STRING desc;
1704 NDR_UNMARSHALL m;
1705 unsigned long size;
1707 while (*pFormat != RPC_FC_END) {
1708 switch (*pFormat) {
1709 case RPC_FC_SHORT:
1710 case RPC_FC_USHORT:
1711 memcpy(pMemory, pStubMsg->Buffer, 2);
1712 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1713 pStubMsg->Buffer += 2;
1714 pMemory += 2;
1715 break;
1716 case RPC_FC_LONG:
1717 case RPC_FC_ULONG:
1718 case RPC_FC_ENUM32:
1719 memcpy(pMemory, pStubMsg->Buffer, 4);
1720 TRACE("long=%ld => %p\n", *(DWORD*)pMemory, pMemory);
1721 pStubMsg->Buffer += 4;
1722 pMemory += 4;
1723 break;
1724 case RPC_FC_POINTER:
1725 TRACE("pointer => %p\n", pMemory);
1726 NdrPointerUnmarshall(pStubMsg, (unsigned char**)pMemory, pPointer, TRUE);
1727 pPointer += 4;
1728 pMemory += 4;
1729 break;
1730 case RPC_FC_ALIGNM4:
1731 ALIGN_POINTER(pMemory, 4);
1732 break;
1733 case RPC_FC_ALIGNM8:
1734 ALIGN_POINTER(pMemory, 8);
1735 break;
1736 case RPC_FC_STRUCTPAD2:
1737 pMemory += 2;
1738 break;
1739 case RPC_FC_EMBEDDED_COMPLEX:
1740 pMemory += pFormat[1];
1741 pFormat += 2;
1742 desc = pFormat + *(const SHORT*)pFormat;
1743 size = EmbeddedComplexSize(pStubMsg, desc);
1744 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
1745 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1746 memset(pMemory, 0, size); /* just in case */
1747 if (m) m(pStubMsg, &pMemory, desc, FALSE);
1748 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
1749 pMemory += size;
1750 pFormat += 2;
1751 continue;
1752 case RPC_FC_PAD:
1753 break;
1754 default:
1755 FIXME("unhandled format %d\n", *pFormat);
1757 pFormat++;
1760 return pMemory;
1763 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1764 unsigned char *pMemory,
1765 PFORMAT_STRING pFormat,
1766 PFORMAT_STRING pPointer)
1768 PFORMAT_STRING desc;
1769 NDR_BUFFERSIZE m;
1770 unsigned long size;
1772 while (*pFormat != RPC_FC_END) {
1773 switch (*pFormat) {
1774 case RPC_FC_SHORT:
1775 case RPC_FC_USHORT:
1776 pStubMsg->BufferLength += 2;
1777 pMemory += 2;
1778 break;
1779 case RPC_FC_LONG:
1780 case RPC_FC_ULONG:
1781 case RPC_FC_ENUM32:
1782 pStubMsg->BufferLength += 4;
1783 pMemory += 4;
1784 break;
1785 case RPC_FC_POINTER:
1786 NdrPointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
1787 pPointer += 4;
1788 pMemory += 4;
1789 break;
1790 case RPC_FC_ALIGNM4:
1791 ALIGN_POINTER(pMemory, 4);
1792 break;
1793 case RPC_FC_ALIGNM8:
1794 ALIGN_POINTER(pMemory, 8);
1795 break;
1796 case RPC_FC_STRUCTPAD2:
1797 pMemory += 2;
1798 break;
1799 case RPC_FC_EMBEDDED_COMPLEX:
1800 pMemory += pFormat[1];
1801 pFormat += 2;
1802 desc = pFormat + *(const SHORT*)pFormat;
1803 size = EmbeddedComplexSize(pStubMsg, desc);
1804 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1805 if (m) m(pStubMsg, pMemory, desc);
1806 else FIXME("no buffersizer for embedded type %02x\n", *desc);
1807 pMemory += size;
1808 pFormat += 2;
1809 continue;
1810 case RPC_FC_PAD:
1811 break;
1812 default:
1813 FIXME("unhandled format %d\n", *pFormat);
1815 pFormat++;
1818 return pMemory;
1821 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
1822 unsigned char *pMemory,
1823 PFORMAT_STRING pFormat,
1824 PFORMAT_STRING pPointer)
1826 PFORMAT_STRING desc;
1827 NDR_FREE m;
1828 unsigned long size;
1830 while (*pFormat != RPC_FC_END) {
1831 switch (*pFormat) {
1832 case RPC_FC_SHORT:
1833 case RPC_FC_USHORT:
1834 pMemory += 2;
1835 break;
1836 case RPC_FC_LONG:
1837 case RPC_FC_ULONG:
1838 case RPC_FC_ENUM32:
1839 pMemory += 4;
1840 break;
1841 case RPC_FC_POINTER:
1842 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
1843 pPointer += 4;
1844 pMemory += 4;
1845 break;
1846 case RPC_FC_ALIGNM4:
1847 ALIGN_POINTER(pMemory, 4);
1848 break;
1849 case RPC_FC_ALIGNM8:
1850 ALIGN_POINTER(pMemory, 8);
1851 break;
1852 case RPC_FC_STRUCTPAD2:
1853 pMemory += 2;
1854 break;
1855 case RPC_FC_EMBEDDED_COMPLEX:
1856 pMemory += pFormat[1];
1857 pFormat += 2;
1858 desc = pFormat + *(const SHORT*)pFormat;
1859 size = EmbeddedComplexSize(pStubMsg, desc);
1860 m = NdrFreer[*desc & NDR_TABLE_MASK];
1861 if (m) m(pStubMsg, pMemory, desc);
1862 else FIXME("no freer for embedded type %02x\n", *desc);
1863 pMemory += size;
1864 pFormat += 2;
1865 continue;
1866 case RPC_FC_PAD:
1867 break;
1868 default:
1869 FIXME("unhandled format %d\n", *pFormat);
1871 pFormat++;
1874 return pMemory;
1877 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1878 PFORMAT_STRING pFormat)
1880 PFORMAT_STRING desc;
1881 unsigned long size = 0;
1883 while (*pFormat != RPC_FC_END) {
1884 switch (*pFormat) {
1885 case RPC_FC_SHORT:
1886 case RPC_FC_USHORT:
1887 size += 2;
1888 pStubMsg->Buffer += 2;
1889 break;
1890 case RPC_FC_LONG:
1891 case RPC_FC_ULONG:
1892 size += 4;
1893 pStubMsg->Buffer += 4;
1894 break;
1895 case RPC_FC_POINTER:
1896 size += 4;
1897 pStubMsg->Buffer += 4;
1898 break;
1899 case RPC_FC_ALIGNM4:
1900 ALIGN_LENGTH(size, 4);
1901 ALIGN_POINTER(pStubMsg->Buffer, 4);
1902 break;
1903 case RPC_FC_ALIGNM8:
1904 ALIGN_LENGTH(size, 8);
1905 ALIGN_POINTER(pStubMsg->Buffer, 8);
1906 break;
1907 case RPC_FC_STRUCTPAD2:
1908 size += 2;
1909 pStubMsg->Buffer += 2;
1910 break;
1911 case RPC_FC_EMBEDDED_COMPLEX:
1912 size += pFormat[1];
1913 pFormat += 2;
1914 desc = pFormat + *(const SHORT*)pFormat;
1915 size += EmbeddedComplexMemorySize(pStubMsg, desc);
1916 pFormat += 2;
1917 continue;
1918 case RPC_FC_PAD:
1919 break;
1920 default:
1921 FIXME("unhandled format %d\n", *pFormat);
1923 pFormat++;
1926 return size;
1929 /***********************************************************************
1930 * NdrComplexStructMarshall [RPCRT4.@]
1932 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1933 unsigned char *pMemory,
1934 PFORMAT_STRING pFormat)
1936 PFORMAT_STRING conf_array = NULL;
1937 PFORMAT_STRING pointer_desc = NULL;
1938 unsigned char *OldMemory = pStubMsg->Memory;
1940 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1942 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1944 pFormat += 4;
1945 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1946 pFormat += 2;
1947 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1948 pFormat += 2;
1950 pStubMsg->Memory = pMemory;
1952 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
1954 if (conf_array)
1955 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
1957 pStubMsg->Memory = OldMemory;
1959 STD_OVERFLOW_CHECK(pStubMsg);
1961 return NULL;
1964 /***********************************************************************
1965 * NdrComplexStructUnmarshall [RPCRT4.@]
1967 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1968 unsigned char **ppMemory,
1969 PFORMAT_STRING pFormat,
1970 unsigned char fMustAlloc)
1972 unsigned size = *(const WORD*)(pFormat+2);
1973 PFORMAT_STRING conf_array = NULL;
1974 PFORMAT_STRING pointer_desc = NULL;
1975 unsigned char *pMemory;
1977 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1979 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1981 if (fMustAlloc || !*ppMemory)
1983 *ppMemory = NdrAllocate(pStubMsg, size);
1984 memset(*ppMemory, 0, size);
1987 pFormat += 4;
1988 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1989 pFormat += 2;
1990 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1991 pFormat += 2;
1993 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
1995 if (conf_array)
1996 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
1998 return NULL;
2001 /***********************************************************************
2002 * NdrComplexStructBufferSize [RPCRT4.@]
2004 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2005 unsigned char *pMemory,
2006 PFORMAT_STRING pFormat)
2008 PFORMAT_STRING conf_array = NULL;
2009 PFORMAT_STRING pointer_desc = NULL;
2010 unsigned char *OldMemory = pStubMsg->Memory;
2012 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2014 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2016 pFormat += 4;
2017 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2018 pFormat += 2;
2019 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2020 pFormat += 2;
2022 pStubMsg->Memory = pMemory;
2024 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2026 if (conf_array)
2027 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2029 pStubMsg->Memory = OldMemory;
2032 /***********************************************************************
2033 * NdrComplexStructMemorySize [RPCRT4.@]
2035 unsigned long WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2036 PFORMAT_STRING pFormat)
2038 unsigned size = *(const WORD*)(pFormat+2);
2039 PFORMAT_STRING conf_array = NULL;
2040 PFORMAT_STRING pointer_desc = NULL;
2042 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2044 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2046 pFormat += 4;
2047 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2048 pFormat += 2;
2049 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2050 pFormat += 2;
2052 ComplexStructMemorySize(pStubMsg, pFormat);
2054 if (conf_array)
2055 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2057 return size;
2060 /***********************************************************************
2061 * NdrComplexStructFree [RPCRT4.@]
2063 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2064 unsigned char *pMemory,
2065 PFORMAT_STRING pFormat)
2067 PFORMAT_STRING conf_array = NULL;
2068 PFORMAT_STRING pointer_desc = NULL;
2069 unsigned char *OldMemory = pStubMsg->Memory;
2071 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2073 pFormat += 4;
2074 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2075 pFormat += 2;
2076 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2077 pFormat += 2;
2079 pStubMsg->Memory = pMemory;
2081 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2083 if (conf_array)
2084 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2086 pStubMsg->Memory = OldMemory;
2089 /***********************************************************************
2090 * NdrConformantArrayMarshall [RPCRT4.@]
2092 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2093 unsigned char *pMemory,
2094 PFORMAT_STRING pFormat)
2096 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2097 unsigned char alignment = pFormat[1] + 1;
2099 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2100 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2102 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2103 size = pStubMsg->MaxCount;
2105 WriteConformance(pStubMsg);
2107 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2109 memcpy(pStubMsg->Buffer, pMemory, size*esize);
2110 pStubMsg->BufferMark = pStubMsg->Buffer;
2111 pStubMsg->Buffer += size*esize;
2113 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2115 STD_OVERFLOW_CHECK(pStubMsg);
2117 return NULL;
2120 /***********************************************************************
2121 * NdrConformantArrayUnmarshall [RPCRT4.@]
2123 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2124 unsigned char **ppMemory,
2125 PFORMAT_STRING pFormat,
2126 unsigned char fMustAlloc)
2128 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2129 unsigned char alignment = pFormat[1] + 1;
2131 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2132 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2134 pFormat = ReadConformance(pStubMsg, pFormat+4);
2135 size = pStubMsg->MaxCount;
2137 if (fMustAlloc || !*ppMemory)
2138 *ppMemory = NdrAllocate(pStubMsg, size*esize);
2140 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2142 memcpy(*ppMemory, pStubMsg->Buffer, size*esize);
2144 pStubMsg->BufferMark = pStubMsg->Buffer;
2145 pStubMsg->Buffer += size*esize;
2147 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2149 return NULL;
2152 /***********************************************************************
2153 * NdrConformantArrayBufferSize [RPCRT4.@]
2155 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2156 unsigned char *pMemory,
2157 PFORMAT_STRING pFormat)
2159 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2160 unsigned char alignment = pFormat[1] + 1;
2162 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2163 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2165 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2166 size = pStubMsg->MaxCount;
2168 SizeConformance(pStubMsg);
2170 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2172 /* conformance value plus array */
2173 pStubMsg->BufferLength += size*esize;
2175 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2178 /***********************************************************************
2179 * NdrConformantArrayMemorySize [RPCRT4.@]
2181 unsigned long WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2182 PFORMAT_STRING pFormat)
2184 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2185 unsigned char alignment = pFormat[1] + 1;
2187 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2188 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2190 pFormat = ReadConformance(pStubMsg, pFormat+4);
2191 size = pStubMsg->MaxCount;
2192 pStubMsg->MemorySize += size*esize;
2194 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2195 pStubMsg->BufferMark = pStubMsg->Buffer;
2196 pStubMsg->Buffer += size*esize;
2198 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2200 return pStubMsg->MemorySize;
2203 /***********************************************************************
2204 * NdrConformantArrayFree [RPCRT4.@]
2206 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2207 unsigned char *pMemory,
2208 PFORMAT_STRING pFormat)
2210 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2211 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2213 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2217 /***********************************************************************
2218 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2220 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2221 unsigned char* pMemory,
2222 PFORMAT_STRING pFormat )
2224 unsigned char alignment = pFormat[1] + 1;
2225 DWORD esize = *(const WORD*)(pFormat+2);
2227 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2229 if (pFormat[0] != RPC_FC_CVARRAY)
2231 ERR("invalid format type %x\n", pFormat[0]);
2232 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2233 return NULL;
2236 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2237 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2239 WriteConformance(pStubMsg);
2240 WriteVariance(pStubMsg);
2242 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2244 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, pStubMsg->ActualCount*esize);
2245 pStubMsg->BufferMark = pStubMsg->Buffer;
2246 pStubMsg->Buffer += pStubMsg->ActualCount*esize;
2248 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2250 STD_OVERFLOW_CHECK(pStubMsg);
2252 return NULL;
2256 /***********************************************************************
2257 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2259 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2260 unsigned char** ppMemory,
2261 PFORMAT_STRING pFormat,
2262 unsigned char fMustAlloc )
2264 unsigned char alignment = pFormat[1] + 1;
2265 DWORD esize = *(const WORD*)(pFormat+2);
2267 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2269 if (pFormat[0] != RPC_FC_CVARRAY)
2271 ERR("invalid format type %x\n", pFormat[0]);
2272 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2273 return NULL;
2276 pFormat = ReadConformance(pStubMsg, pFormat);
2277 pFormat = ReadVariance(pStubMsg, pFormat);
2279 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2281 if (!*ppMemory || fMustAlloc)
2282 *ppMemory = NdrAllocate(pStubMsg, pStubMsg->MaxCount * esize);
2283 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, pStubMsg->ActualCount * esize);
2284 pStubMsg->Buffer += pStubMsg->ActualCount * esize;
2286 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2288 return NULL;
2292 /***********************************************************************
2293 * NdrConformantVaryingArrayFree [RPCRT4.@]
2295 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2296 unsigned char* pMemory,
2297 PFORMAT_STRING pFormat )
2299 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2301 if (pFormat[0] != RPC_FC_CVARRAY)
2303 ERR("invalid format type %x\n", pFormat[0]);
2304 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2305 return;
2308 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2309 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2311 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2315 /***********************************************************************
2316 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2318 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2319 unsigned char* pMemory, PFORMAT_STRING pFormat )
2321 unsigned char alignment = pFormat[1] + 1;
2322 DWORD esize = *(const WORD*)(pFormat+2);
2324 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2326 if (pFormat[0] != RPC_FC_CVARRAY)
2328 ERR("invalid format type %x\n", pFormat[0]);
2329 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2330 return;
2333 /* compute size */
2334 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2335 /* compute length */
2336 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2338 SizeConformance(pStubMsg);
2339 SizeVariance(pStubMsg);
2341 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2343 pStubMsg->BufferLength += pStubMsg->ActualCount*esize;
2345 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2349 /***********************************************************************
2350 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2352 unsigned long WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2353 PFORMAT_STRING pFormat )
2355 FIXME( "stub\n" );
2356 return 0;
2360 /***********************************************************************
2361 * NdrComplexArrayMarshall [RPCRT4.@]
2363 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2364 unsigned char *pMemory,
2365 PFORMAT_STRING pFormat)
2367 ULONG i, count, def;
2368 BOOL variance_present;
2369 unsigned char alignment;
2371 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2373 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2375 ERR("invalid format type %x\n", pFormat[0]);
2376 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2377 return NULL;
2380 alignment = pFormat[1] + 1;
2382 def = *(const WORD*)&pFormat[2];
2383 pFormat += 4;
2385 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2386 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2388 variance_present = IsConformanceOrVariancePresent(pFormat);
2389 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2390 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2392 WriteConformance(pStubMsg);
2393 if (variance_present)
2394 WriteVariance(pStubMsg);
2396 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2398 count = pStubMsg->ActualCount;
2399 for (i = 0; i < count; i++)
2400 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2402 STD_OVERFLOW_CHECK(pStubMsg);
2404 return NULL;
2407 /***********************************************************************
2408 * NdrComplexArrayUnmarshall [RPCRT4.@]
2410 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2411 unsigned char **ppMemory,
2412 PFORMAT_STRING pFormat,
2413 unsigned char fMustAlloc)
2415 ULONG i, count, esize;
2416 unsigned char alignment;
2417 unsigned char *pMemory;
2418 unsigned char *Buffer;
2420 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2422 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2424 ERR("invalid format type %x\n", pFormat[0]);
2425 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2426 return NULL;
2429 alignment = pFormat[1] + 1;
2431 pFormat += 4;
2433 pFormat = ReadConformance(pStubMsg, pFormat);
2434 pFormat = ReadVariance(pStubMsg, pFormat);
2436 Buffer = pStubMsg->Buffer;
2437 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2438 pStubMsg->Buffer = Buffer;
2440 if (fMustAlloc || !*ppMemory)
2442 *ppMemory = NdrAllocate(pStubMsg, pStubMsg->MaxCount * esize);
2443 memset(*ppMemory, 0, pStubMsg->MaxCount * esize);
2446 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2448 pMemory = *ppMemory;
2449 count = pStubMsg->ActualCount;
2450 for (i = 0; i < count; i++)
2451 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
2453 return NULL;
2456 /***********************************************************************
2457 * NdrComplexArrayBufferSize [RPCRT4.@]
2459 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2460 unsigned char *pMemory,
2461 PFORMAT_STRING pFormat)
2463 ULONG i, count, def;
2464 unsigned char alignment;
2465 BOOL variance_present;
2467 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2469 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2471 ERR("invalid format type %x\n", pFormat[0]);
2472 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2473 return;
2476 alignment = pFormat[1] + 1;
2478 def = *(const WORD*)&pFormat[2];
2479 pFormat += 4;
2481 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2482 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2483 SizeConformance(pStubMsg);
2485 variance_present = IsConformanceOrVariancePresent(pFormat);
2486 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2487 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2489 if (variance_present)
2490 SizeVariance(pStubMsg);
2492 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2494 count = pStubMsg->ActualCount;
2495 for (i = 0; i < count; i++)
2496 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
2499 /***********************************************************************
2500 * NdrComplexArrayMemorySize [RPCRT4.@]
2502 unsigned long WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2503 PFORMAT_STRING pFormat)
2505 ULONG i, count, esize;
2506 unsigned char alignment;
2507 unsigned char *Buffer;
2508 unsigned long SavedMemorySize;
2509 unsigned long MemorySize;
2511 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2513 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2515 ERR("invalid format type %x\n", pFormat[0]);
2516 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2517 return 0;
2520 alignment = pFormat[1] + 1;
2522 pFormat += 4;
2524 pFormat = ReadConformance(pStubMsg, pFormat);
2525 pFormat = ReadVariance(pStubMsg, pFormat);
2527 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2529 SavedMemorySize = pStubMsg->MemorySize;
2531 Buffer = pStubMsg->Buffer;
2532 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2533 pStubMsg->Buffer = Buffer;
2535 MemorySize = esize * pStubMsg->MaxCount;
2537 count = pStubMsg->ActualCount;
2538 for (i = 0; i < count; i++)
2539 ComplexStructMemorySize(pStubMsg, pFormat);
2541 pStubMsg->MemorySize = SavedMemorySize;
2543 pStubMsg->MemorySize += MemorySize;
2544 return MemorySize;
2547 /***********************************************************************
2548 * NdrComplexArrayFree [RPCRT4.@]
2550 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2551 unsigned char *pMemory,
2552 PFORMAT_STRING pFormat)
2554 ULONG i, count, def;
2556 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2558 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2560 ERR("invalid format type %x\n", pFormat[0]);
2561 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2562 return;
2565 def = *(const WORD*)&pFormat[2];
2566 pFormat += 4;
2568 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2569 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2571 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2572 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2574 count = pStubMsg->ActualCount;
2575 for (i = 0; i < count; i++)
2576 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2579 static unsigned long UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
2581 return MAKELONG(pStubMsg->dwDestContext,
2582 pStubMsg->RpcMsg->DataRepresentation);
2585 #define USER_MARSHAL_PTR_PREFIX \
2586 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
2587 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
2589 /***********************************************************************
2590 * NdrUserMarshalMarshall [RPCRT4.@]
2592 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2593 unsigned char *pMemory,
2594 PFORMAT_STRING pFormat)
2596 unsigned flags = pFormat[1];
2597 unsigned index = *(const WORD*)&pFormat[2];
2598 unsigned long uflag = UserMarshalFlags(pStubMsg);
2599 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2600 TRACE("index=%d\n", index);
2602 if (flags & USER_MARSHAL_POINTER)
2604 ALIGN_POINTER(pStubMsg->Buffer, 4);
2605 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
2606 pStubMsg->Buffer += 4;
2607 ALIGN_POINTER(pStubMsg->Buffer, 8);
2609 else
2610 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2612 pStubMsg->Buffer =
2613 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
2614 &uflag, pStubMsg->Buffer, pMemory);
2616 STD_OVERFLOW_CHECK(pStubMsg);
2618 return NULL;
2621 /***********************************************************************
2622 * NdrUserMarshalUnmarshall [RPCRT4.@]
2624 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2625 unsigned char **ppMemory,
2626 PFORMAT_STRING pFormat,
2627 unsigned char fMustAlloc)
2629 unsigned flags = pFormat[1];
2630 unsigned index = *(const WORD*)&pFormat[2];
2631 DWORD memsize = *(const WORD*)&pFormat[4];
2632 unsigned long uflag = UserMarshalFlags(pStubMsg);
2633 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2634 TRACE("index=%d\n", index);
2636 if (flags & USER_MARSHAL_POINTER)
2638 ALIGN_POINTER(pStubMsg->Buffer, 4);
2639 /* skip pointer prefix */
2640 pStubMsg->Buffer += 4;
2641 ALIGN_POINTER(pStubMsg->Buffer, 8);
2643 else
2644 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2646 if (fMustAlloc || !*ppMemory)
2647 *ppMemory = NdrAllocate(pStubMsg, memsize);
2649 pStubMsg->Buffer =
2650 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
2651 &uflag, pStubMsg->Buffer, *ppMemory);
2653 return NULL;
2656 /***********************************************************************
2657 * NdrUserMarshalBufferSize [RPCRT4.@]
2659 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2660 unsigned char *pMemory,
2661 PFORMAT_STRING pFormat)
2663 unsigned flags = pFormat[1];
2664 unsigned index = *(const WORD*)&pFormat[2];
2665 DWORD bufsize = *(const WORD*)&pFormat[6];
2666 unsigned long uflag = UserMarshalFlags(pStubMsg);
2667 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2668 TRACE("index=%d\n", index);
2670 if (flags & USER_MARSHAL_POINTER)
2672 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2673 /* skip pointer prefix */
2674 pStubMsg->BufferLength += 4;
2675 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
2677 else
2678 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
2680 if (bufsize) {
2681 TRACE("size=%ld\n", bufsize);
2682 pStubMsg->BufferLength += bufsize;
2683 return;
2686 pStubMsg->BufferLength =
2687 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
2688 &uflag, pStubMsg->BufferLength, pMemory);
2691 /***********************************************************************
2692 * NdrUserMarshalMemorySize [RPCRT4.@]
2694 unsigned long WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2695 PFORMAT_STRING pFormat)
2697 unsigned flags = pFormat[1];
2698 unsigned index = *(const WORD*)&pFormat[2];
2699 DWORD memsize = *(const WORD*)&pFormat[4];
2700 DWORD bufsize = *(const WORD*)&pFormat[6];
2702 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2703 TRACE("index=%d\n", index);
2705 pStubMsg->MemorySize += memsize;
2707 if (flags & USER_MARSHAL_POINTER)
2709 ALIGN_POINTER(pStubMsg->Buffer, 4);
2710 /* skip pointer prefix */
2711 pStubMsg->Buffer += 4;
2712 ALIGN_POINTER(pStubMsg->Buffer, 8);
2714 else
2715 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2717 pStubMsg->Buffer += bufsize;
2719 return pStubMsg->MemorySize;
2722 /***********************************************************************
2723 * NdrUserMarshalFree [RPCRT4.@]
2725 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
2726 unsigned char *pMemory,
2727 PFORMAT_STRING pFormat)
2729 /* unsigned flags = pFormat[1]; */
2730 unsigned index = *(const WORD*)&pFormat[2];
2731 unsigned long uflag = UserMarshalFlags(pStubMsg);
2732 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2733 TRACE("index=%d\n", index);
2735 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
2736 &uflag, pMemory);
2739 /***********************************************************************
2740 * NdrClearOutParameters [RPCRT4.@]
2742 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
2743 PFORMAT_STRING pFormat,
2744 void *ArgAddr)
2746 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
2749 /***********************************************************************
2750 * NdrConvert [RPCRT4.@]
2752 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
2754 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
2755 /* FIXME: since this stub doesn't do any converting, the proper behavior
2756 is to raise an exception */
2759 /***********************************************************************
2760 * NdrConvert2 [RPCRT4.@]
2762 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, long NumberParams )
2764 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %ld): stub.\n",
2765 pStubMsg, pFormat, NumberParams);
2766 /* FIXME: since this stub doesn't do any converting, the proper behavior
2767 is to raise an exception */
2770 typedef struct _NDR_CSTRUCT_FORMAT
2772 unsigned char type;
2773 unsigned char alignment;
2774 unsigned short memory_size;
2775 short offset_to_array_description;
2776 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
2778 /***********************************************************************
2779 * NdrConformantStructMarshall [RPCRT4.@]
2781 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2782 unsigned char *pMemory,
2783 PFORMAT_STRING pFormat)
2785 const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
2786 PFORMAT_STRING pCArrayFormat;
2787 ULONG esize;
2789 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2791 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2792 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2794 ERR("invalid format type %x\n", pCStructFormat->type);
2795 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2796 return NULL;
2799 pCArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
2800 pCStructFormat->offset_to_array_description;
2801 if (*pCArrayFormat != RPC_FC_CARRAY)
2803 ERR("invalid array format type %x\n", pCStructFormat->type);
2804 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2805 return NULL;
2807 esize = *(const WORD*)(pCArrayFormat+2);
2809 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
2810 pCArrayFormat + 4, 0);
2812 WriteConformance(pStubMsg);
2814 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
2816 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2818 /* copy constant sized part of struct */
2819 pStubMsg->BufferMark = pStubMsg->Buffer;
2820 memcpy(pStubMsg->Buffer, pMemory, pCStructFormat->memory_size + pStubMsg->MaxCount * esize);
2821 pStubMsg->Buffer += pCStructFormat->memory_size + pStubMsg->MaxCount * esize;
2823 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2824 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2826 STD_OVERFLOW_CHECK(pStubMsg);
2828 return NULL;
2831 /***********************************************************************
2832 * NdrConformantStructUnmarshall [RPCRT4.@]
2834 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2835 unsigned char **ppMemory,
2836 PFORMAT_STRING pFormat,
2837 unsigned char fMustAlloc)
2839 const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
2840 PFORMAT_STRING pCArrayFormat;
2841 ULONG esize;
2843 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2845 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2846 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2848 ERR("invalid format type %x\n", pCStructFormat->type);
2849 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2850 return NULL;
2852 pCArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
2853 pCStructFormat->offset_to_array_description;
2854 if (*pCArrayFormat != RPC_FC_CARRAY)
2856 ERR("invalid array format type %x\n", pCStructFormat->type);
2857 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2858 return NULL;
2860 esize = *(const WORD*)(pCArrayFormat+2);
2862 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
2864 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
2866 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2868 /* work out how much memory to allocate if we need to do so */
2869 if (!*ppMemory || fMustAlloc)
2871 SIZE_T size = pCStructFormat->memory_size + pStubMsg->MaxCount * esize;
2872 *ppMemory = NdrAllocate(pStubMsg, size);
2875 /* now copy the data */
2876 pStubMsg->BufferMark = pStubMsg->Buffer;
2877 memcpy(*ppMemory, pStubMsg->Buffer, pCStructFormat->memory_size + pStubMsg->MaxCount * esize);
2878 pStubMsg->Buffer += pCStructFormat->memory_size + pStubMsg->MaxCount * esize;
2880 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2881 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2883 return NULL;
2886 /***********************************************************************
2887 * NdrConformantStructBufferSize [RPCRT4.@]
2889 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2890 unsigned char *pMemory,
2891 PFORMAT_STRING pFormat)
2893 const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
2894 PFORMAT_STRING pCArrayFormat;
2895 ULONG esize;
2897 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2899 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2900 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2902 ERR("invalid format type %x\n", pCStructFormat->type);
2903 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2904 return;
2906 pCArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
2907 pCStructFormat->offset_to_array_description;
2908 if (*pCArrayFormat != RPC_FC_CARRAY)
2910 ERR("invalid array format type %x\n", pCStructFormat->type);
2911 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2912 return;
2914 esize = *(const WORD*)(pCArrayFormat+2);
2916 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
2917 SizeConformance(pStubMsg);
2919 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
2921 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2923 pStubMsg->BufferLength += pCStructFormat->memory_size + esize * pStubMsg->MaxCount;
2925 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2926 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2929 /***********************************************************************
2930 * NdrConformantStructMemorySize [RPCRT4.@]
2932 unsigned long WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2933 PFORMAT_STRING pFormat)
2935 FIXME("stub\n");
2936 return 0;
2939 /***********************************************************************
2940 * NdrConformantStructFree [RPCRT4.@]
2942 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2943 unsigned char *pMemory,
2944 PFORMAT_STRING pFormat)
2946 FIXME("stub\n");
2949 /***********************************************************************
2950 * NdrConformantVaryingStructMarshall [RPCRT4.@]
2952 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2953 unsigned char *pMemory,
2954 PFORMAT_STRING pFormat)
2956 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
2957 PFORMAT_STRING pCVArrayFormat;
2958 ULONG esize;
2960 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2962 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
2963 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
2965 ERR("invalid format type %x\n", pCVStructFormat->type);
2966 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2967 return NULL;
2970 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
2971 pCVStructFormat->offset_to_array_description;
2972 switch (*pCVArrayFormat)
2974 case RPC_FC_CVARRAY:
2975 esize = *(const WORD*)(pCVArrayFormat+2);
2977 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
2978 pCVArrayFormat + 4, 0);
2979 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
2980 pCVArrayFormat, 0);
2981 break;
2982 case RPC_FC_C_CSTRING:
2983 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
2984 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
2985 esize = sizeof(char);
2986 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
2987 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
2988 pCVArrayFormat + 2, 0);
2989 else
2990 pStubMsg->MaxCount = pStubMsg->ActualCount;
2991 break;
2992 case RPC_FC_C_WSTRING:
2993 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
2994 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
2995 esize = sizeof(WCHAR);
2996 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
2997 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
2998 pCVArrayFormat + 2, 0);
2999 else
3000 pStubMsg->MaxCount = pStubMsg->ActualCount;
3001 break;
3002 default:
3003 ERR("invalid array format type %x\n", *pCVArrayFormat);
3004 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3005 return NULL;
3008 WriteConformance(pStubMsg);
3010 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3012 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3014 /* write constant sized part */
3015 pStubMsg->BufferMark = pStubMsg->Buffer;
3016 memcpy(pStubMsg->Buffer, pMemory, pCVStructFormat->memory_size);
3017 pStubMsg->Buffer += pCVStructFormat->memory_size;
3019 WriteVariance(pStubMsg);
3021 /* write array part */
3022 memcpy(pStubMsg->Buffer, pMemory + pCVStructFormat->memory_size, pStubMsg->ActualCount * esize);
3023 pStubMsg->Buffer += pStubMsg->ActualCount * esize;
3025 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3027 STD_OVERFLOW_CHECK(pStubMsg);
3029 return NULL;
3032 /***********************************************************************
3033 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3035 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3036 unsigned char **ppMemory,
3037 PFORMAT_STRING pFormat,
3038 unsigned char fMustAlloc)
3040 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3041 PFORMAT_STRING pCVArrayFormat;
3042 ULONG esize;
3043 unsigned char cvarray_type;
3045 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3047 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3048 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3050 ERR("invalid format type %x\n", pCVStructFormat->type);
3051 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3052 return NULL;
3055 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3056 pCVStructFormat->offset_to_array_description;
3057 cvarray_type = *pCVArrayFormat;
3058 switch (cvarray_type)
3060 case RPC_FC_CVARRAY:
3061 esize = *(const WORD*)(pCVArrayFormat+2);
3062 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3063 break;
3064 case RPC_FC_C_CSTRING:
3065 esize = sizeof(char);
3066 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3067 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3068 else
3069 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3070 break;
3071 case RPC_FC_C_WSTRING:
3072 esize = sizeof(WCHAR);
3073 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3074 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3075 else
3076 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3077 break;
3078 default:
3079 ERR("invalid array format type %x\n", *pCVArrayFormat);
3080 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3081 return NULL;
3084 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3086 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3088 /* work out how much memory to allocate if we need to do so */
3089 if (!*ppMemory || fMustAlloc)
3091 SIZE_T size = pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3092 *ppMemory = NdrAllocate(pStubMsg, size);
3095 /* copy the constant data */
3096 pStubMsg->BufferMark = pStubMsg->Buffer;
3097 memcpy(*ppMemory, pStubMsg->Buffer, pCVStructFormat->memory_size);
3098 pStubMsg->Buffer += pCVStructFormat->memory_size;
3100 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat);
3102 /* copy the array data */
3103 memcpy(*ppMemory + pCVStructFormat->memory_size, pStubMsg->Buffer,
3104 pStubMsg->ActualCount * esize);
3105 pStubMsg->Buffer += pStubMsg->ActualCount * esize;
3107 if (cvarray_type == RPC_FC_C_CSTRING)
3108 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3109 else if (cvarray_type == RPC_FC_C_WSTRING)
3110 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3112 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3114 return NULL;
3117 /***********************************************************************
3118 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3120 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3121 unsigned char *pMemory,
3122 PFORMAT_STRING pFormat)
3124 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3125 PFORMAT_STRING pCVArrayFormat;
3126 ULONG esize;
3128 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3130 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3131 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3133 ERR("invalid format type %x\n", pCVStructFormat->type);
3134 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3135 return;
3138 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3139 pCVStructFormat->offset_to_array_description;
3140 switch (*pCVArrayFormat)
3142 case RPC_FC_CVARRAY:
3143 esize = *(const WORD*)(pCVArrayFormat+2);
3145 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3146 pCVArrayFormat + 4, 0);
3147 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3148 pCVArrayFormat + 4, 0);
3149 break;
3150 case RPC_FC_C_CSTRING:
3151 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3152 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3153 esize = sizeof(char);
3154 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3155 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3156 pCVArrayFormat + 2, 0);
3157 else
3158 pStubMsg->MaxCount = pStubMsg->ActualCount;
3159 break;
3160 case RPC_FC_C_WSTRING:
3161 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3162 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3163 esize = sizeof(WCHAR);
3164 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3165 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3166 pCVArrayFormat + 2, 0);
3167 else
3168 pStubMsg->MaxCount = pStubMsg->ActualCount;
3169 break;
3170 default:
3171 ERR("invalid array format type %x\n", *pCVArrayFormat);
3172 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3173 return;
3176 SizeConformance(pStubMsg);
3178 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
3180 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3182 pStubMsg->BufferLength += pCVStructFormat->memory_size;
3183 SizeVariance(pStubMsg);
3184 pStubMsg->BufferLength += esize * pStubMsg->MaxCount;
3186 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3189 /***********************************************************************
3190 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3192 unsigned long WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3193 PFORMAT_STRING pFormat)
3195 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3196 PFORMAT_STRING pCVArrayFormat;
3197 ULONG esize;
3198 unsigned char cvarray_type;
3200 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3202 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3203 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3205 ERR("invalid format type %x\n", pCVStructFormat->type);
3206 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3207 return 0;
3210 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3211 pCVStructFormat->offset_to_array_description;
3212 cvarray_type = *pCVArrayFormat;
3213 switch (cvarray_type)
3215 case RPC_FC_CVARRAY:
3216 esize = *(const WORD*)(pCVArrayFormat+2);
3217 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3218 break;
3219 case RPC_FC_C_CSTRING:
3220 esize = sizeof(char);
3221 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3222 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3223 else
3224 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3225 break;
3226 case RPC_FC_C_WSTRING:
3227 esize = sizeof(WCHAR);
3228 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3229 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3230 else
3231 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3232 break;
3233 default:
3234 ERR("invalid array format type %x\n", *pCVArrayFormat);
3235 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3236 return 0;
3239 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3241 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3243 pStubMsg->Buffer += pCVStructFormat->memory_size;
3244 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat);
3245 pStubMsg->Buffer += pCVStructFormat->memory_size + pStubMsg->ActualCount * esize;
3247 pStubMsg->MemorySize += pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3249 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3251 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3254 /***********************************************************************
3255 * NdrConformantVaryingStructFree [RPCRT4.@]
3257 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3258 unsigned char *pMemory,
3259 PFORMAT_STRING pFormat)
3261 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3262 PFORMAT_STRING pCVArrayFormat;
3263 ULONG esize;
3265 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3267 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3268 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3270 ERR("invalid format type %x\n", pCVStructFormat->type);
3271 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3272 return;
3275 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3276 pCVStructFormat->offset_to_array_description;
3277 switch (*pCVArrayFormat)
3279 case RPC_FC_CVARRAY:
3280 esize = *(const WORD*)(pCVArrayFormat+2);
3282 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3283 pCVArrayFormat + 4, 0);
3284 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3285 pCVArrayFormat, 0);
3286 break;
3287 case RPC_FC_C_CSTRING:
3288 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3289 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3290 esize = sizeof(char);
3291 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3292 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3293 pCVArrayFormat + 2, 0);
3294 else
3295 pStubMsg->MaxCount = pStubMsg->ActualCount;
3296 break;
3297 case RPC_FC_C_WSTRING:
3298 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3299 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3300 esize = sizeof(WCHAR);
3301 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3302 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3303 pCVArrayFormat + 2, 0);
3304 else
3305 pStubMsg->MaxCount = pStubMsg->ActualCount;
3306 break;
3307 default:
3308 ERR("invalid array format type %x\n", *pCVArrayFormat);
3309 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3310 return;
3313 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3315 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3318 typedef struct
3320 unsigned char type;
3321 unsigned char alignment;
3322 unsigned short total_size;
3323 } NDR_SMFARRAY_FORMAT;
3325 typedef struct
3327 unsigned char type;
3328 unsigned char alignment;
3329 unsigned long total_size;
3330 } NDR_LGFARRAY_FORMAT;
3332 /***********************************************************************
3333 * NdrFixedArrayMarshall [RPCRT4.@]
3335 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3336 unsigned char *pMemory,
3337 PFORMAT_STRING pFormat)
3339 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3340 unsigned long total_size;
3342 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3344 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3345 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3347 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3348 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3349 return NULL;
3352 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3354 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3356 total_size = pSmFArrayFormat->total_size;
3357 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3359 else
3361 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3362 total_size = pLgFArrayFormat->total_size;
3363 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3365 memcpy(pStubMsg->Buffer, pMemory, total_size);
3366 pStubMsg->Buffer += total_size;
3368 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3370 return NULL;
3373 /***********************************************************************
3374 * NdrFixedArrayUnmarshall [RPCRT4.@]
3376 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3377 unsigned char **ppMemory,
3378 PFORMAT_STRING pFormat,
3379 unsigned char fMustAlloc)
3381 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3382 unsigned long total_size;
3384 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3386 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3387 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3389 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3390 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3391 return NULL;
3394 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3396 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3398 total_size = pSmFArrayFormat->total_size;
3399 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3401 else
3403 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3404 total_size = pLgFArrayFormat->total_size;
3405 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3408 if (fMustAlloc || !*ppMemory)
3409 *ppMemory = NdrAllocate(pStubMsg, total_size);
3410 memcpy(*ppMemory, pStubMsg->Buffer, total_size);
3411 pStubMsg->Buffer += total_size;
3413 pFormat = EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3415 return NULL;
3418 /***********************************************************************
3419 * NdrFixedArrayBufferSize [RPCRT4.@]
3421 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3422 unsigned char *pMemory,
3423 PFORMAT_STRING pFormat)
3425 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3426 unsigned long total_size;
3428 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3430 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3431 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3433 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3434 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3435 return;
3438 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
3440 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3442 total_size = pSmFArrayFormat->total_size;
3443 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3445 else
3447 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3448 total_size = pLgFArrayFormat->total_size;
3449 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3451 pStubMsg->BufferLength += total_size;
3453 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3456 /***********************************************************************
3457 * NdrFixedArrayMemorySize [RPCRT4.@]
3459 unsigned long WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3460 PFORMAT_STRING pFormat)
3462 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3463 unsigned long total_size;
3465 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3467 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3468 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3470 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3471 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3472 return 0;
3475 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3477 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3479 total_size = pSmFArrayFormat->total_size;
3480 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3482 else
3484 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3485 total_size = pLgFArrayFormat->total_size;
3486 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3488 pStubMsg->Buffer += total_size;
3489 pStubMsg->MemorySize += total_size;
3491 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3493 return total_size;
3496 /***********************************************************************
3497 * NdrFixedArrayFree [RPCRT4.@]
3499 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3500 unsigned char *pMemory,
3501 PFORMAT_STRING pFormat)
3503 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3505 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3507 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3508 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3510 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3511 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3512 return;
3515 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3516 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3517 else
3519 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3520 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3523 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3526 /***********************************************************************
3527 * NdrVaryingArrayMarshall [RPCRT4.@]
3529 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3530 unsigned char *pMemory,
3531 PFORMAT_STRING pFormat)
3533 FIXME("stub\n");
3534 return NULL;
3537 /***********************************************************************
3538 * NdrVaryingArrayUnmarshall [RPCRT4.@]
3540 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3541 unsigned char **ppMemory,
3542 PFORMAT_STRING pFormat,
3543 unsigned char fMustAlloc)
3545 FIXME("stub\n");
3546 return NULL;
3549 /***********************************************************************
3550 * NdrVaryingArrayBufferSize [RPCRT4.@]
3552 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3553 unsigned char *pMemory,
3554 PFORMAT_STRING pFormat)
3556 FIXME("stub\n");
3559 /***********************************************************************
3560 * NdrVaryingArrayMemorySize [RPCRT4.@]
3562 unsigned long WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3563 PFORMAT_STRING pFormat)
3565 FIXME("stub\n");
3566 return 0;
3569 /***********************************************************************
3570 * NdrVaryingArrayFree [RPCRT4.@]
3572 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3573 unsigned char *pMemory,
3574 PFORMAT_STRING pFormat)
3576 FIXME("stub\n");
3579 /***********************************************************************
3580 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
3582 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3583 unsigned char *pMemory,
3584 PFORMAT_STRING pFormat)
3586 FIXME("stub\n");
3587 return NULL;
3590 /***********************************************************************
3591 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
3593 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3594 unsigned char **ppMemory,
3595 PFORMAT_STRING pFormat,
3596 unsigned char fMustAlloc)
3598 FIXME("stub\n");
3599 return NULL;
3602 /***********************************************************************
3603 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
3605 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3606 unsigned char *pMemory,
3607 PFORMAT_STRING pFormat)
3609 FIXME("stub\n");
3612 /***********************************************************************
3613 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
3615 unsigned long WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3616 PFORMAT_STRING pFormat)
3618 FIXME("stub\n");
3619 return 0;
3622 /***********************************************************************
3623 * NdrEncapsulatedUnionFree [RPCRT4.@]
3625 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
3626 unsigned char *pMemory,
3627 PFORMAT_STRING pFormat)
3629 FIXME("stub\n");
3632 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
3633 unsigned long discriminant,
3634 PFORMAT_STRING pFormat)
3636 unsigned short num_arms, arm, type;
3638 num_arms = *(const SHORT*)pFormat & 0x0fff;
3639 pFormat += 2;
3640 for(arm = 0; arm < num_arms; arm++)
3642 if(discriminant == *(const ULONG*)pFormat)
3644 pFormat += 4;
3645 break;
3647 pFormat += 6;
3650 type = *(const unsigned short*)pFormat;
3651 TRACE("type %04x\n", type);
3652 if(arm == num_arms) /* default arm extras */
3654 if(type == 0xffff)
3656 ERR("no arm for 0x%lx and no default case\n", discriminant);
3657 RpcRaiseException(RPC_S_INVALID_TAG);
3658 return NULL;
3660 if(type == 0)
3662 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
3663 return NULL;
3666 return pFormat;
3669 static PFORMAT_STRING get_non_encapsulated_union_arm(PMIDL_STUB_MESSAGE pStubMsg,
3670 ULONG value,
3671 PFORMAT_STRING pFormat)
3673 pFormat += *(const SHORT*)pFormat;
3674 pFormat += 2;
3676 return get_arm_offset_from_union_arm_selector(pStubMsg, value, pFormat);
3679 /***********************************************************************
3680 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
3682 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3683 unsigned char *pMemory,
3684 PFORMAT_STRING pFormat)
3686 unsigned short type;
3687 unsigned char switch_type;
3689 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3690 pFormat++;
3692 switch_type = *pFormat;
3693 pFormat++;
3695 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
3696 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
3697 /* Marshall discriminant */
3698 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
3700 pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
3701 if(!pFormat)
3702 return NULL;
3704 type = *(const unsigned short*)pFormat;
3705 if((type & 0xff00) == 0x8000)
3707 unsigned char basetype = LOBYTE(type);
3708 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
3710 else
3712 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
3713 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
3714 if (m)
3716 unsigned char *saved_buffer = NULL;
3717 switch(*desc)
3719 case RPC_FC_RP:
3720 case RPC_FC_UP:
3721 case RPC_FC_OP:
3722 case RPC_FC_FP:
3723 saved_buffer = pStubMsg->Buffer;
3724 pStubMsg->Buffer += 4; /* for pointer ID */
3725 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
3726 break;
3727 default:
3728 m(pStubMsg, pMemory, desc);
3731 else FIXME("no marshaller for embedded type %02x\n", *desc);
3733 return NULL;
3736 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
3737 PFORMAT_STRING *ppFormat)
3739 long discriminant = 0;
3741 switch(**ppFormat)
3743 case RPC_FC_BYTE:
3744 case RPC_FC_CHAR:
3745 case RPC_FC_SMALL:
3746 case RPC_FC_USMALL:
3747 discriminant = *(UCHAR *)pStubMsg->Buffer;
3748 pStubMsg->Buffer += sizeof(UCHAR);
3749 break;
3750 case RPC_FC_WCHAR:
3751 case RPC_FC_SHORT:
3752 case RPC_FC_USHORT:
3753 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
3754 discriminant = *(USHORT *)pStubMsg->Buffer;
3755 pStubMsg->Buffer += sizeof(USHORT);
3756 break;
3757 case RPC_FC_LONG:
3758 case RPC_FC_ULONG:
3759 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
3760 discriminant = *(ULONG *)pStubMsg->Buffer;
3761 pStubMsg->Buffer += sizeof(ULONG);
3762 break;
3763 default:
3764 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
3766 (*ppFormat)++;
3768 if (pStubMsg->fHasNewCorrDesc)
3769 *ppFormat += 6;
3770 else
3771 *ppFormat += 4;
3772 return discriminant;
3775 /**********************************************************************
3776 * NdrNonEncapsulatedUnionUnmarshall[RPCRT4.@]
3778 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3779 unsigned char **ppMemory,
3780 PFORMAT_STRING pFormat,
3781 unsigned char fMustAlloc)
3783 long discriminant;
3784 unsigned short type, size;
3786 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3787 pFormat++;
3789 /* Unmarshall discriminant */
3790 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
3791 TRACE("unmarshalled discriminant %lx\n", discriminant);
3793 pFormat += *(const SHORT*)pFormat;
3795 size = *(const unsigned short*)pFormat;
3796 pFormat += 2;
3798 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
3799 if(!pFormat)
3800 return NULL;
3802 if(!*ppMemory || fMustAlloc)
3803 *ppMemory = NdrAllocate(pStubMsg, size);
3805 type = *(const unsigned short*)pFormat;
3806 if((type & 0xff00) == 0x8000)
3808 unsigned char basetype = LOBYTE(type);
3809 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, fMustAlloc);
3811 else
3813 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
3814 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
3815 if (m)
3817 unsigned char *saved_buffer = NULL;
3818 switch(*desc)
3820 case RPC_FC_RP:
3821 case RPC_FC_UP:
3822 case RPC_FC_OP:
3823 case RPC_FC_FP:
3824 ALIGN_POINTER(pStubMsg->Buffer, 4);
3825 saved_buffer = pStubMsg->Buffer;
3826 pStubMsg->Buffer += 4; /* for pointer ID */
3827 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, desc, TRUE);
3828 break;
3829 default:
3830 m(pStubMsg, ppMemory, desc, fMustAlloc);
3833 else FIXME("no marshaller for embedded type %02x\n", *desc);
3835 return NULL;
3838 /***********************************************************************
3839 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
3841 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3842 unsigned char *pMemory,
3843 PFORMAT_STRING pFormat)
3845 unsigned short type;
3846 unsigned char switch_type;
3848 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3849 pFormat++;
3851 switch_type = *pFormat;
3852 pFormat++;
3854 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
3855 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
3856 /* Add discriminant size */
3857 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
3859 pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
3860 if(!pFormat)
3861 return;
3863 type = *(const unsigned short*)pFormat;
3864 if((type & 0xff00) == 0x8000)
3866 unsigned char basetype = LOBYTE(type);
3867 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
3869 else
3871 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
3872 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
3873 if (m)
3875 switch(*desc)
3877 case RPC_FC_RP:
3878 case RPC_FC_UP:
3879 case RPC_FC_OP:
3880 case RPC_FC_FP:
3881 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3882 pStubMsg->BufferLength += 4; /* for pointer ID */
3883 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
3884 break;
3885 default:
3886 m(pStubMsg, pMemory, desc);
3889 else FIXME("no buffersizer for embedded type %02x\n", *desc);
3891 return;
3894 /***********************************************************************
3895 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
3897 unsigned long WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3898 PFORMAT_STRING pFormat)
3900 unsigned long discriminant;
3901 unsigned short type, size;
3903 pFormat++;
3904 /* Unmarshall discriminant */
3905 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
3906 TRACE("unmarshalled discriminant 0x%lx\n", discriminant);
3908 pFormat += *(const SHORT*)pFormat;
3910 size = *(const unsigned short*)pFormat;
3911 pFormat += 2;
3913 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
3914 if(!pFormat)
3915 return 0;
3917 pStubMsg->Memory += size;
3919 type = *(const unsigned short*)pFormat;
3920 if((type & 0xff00) == 0x8000)
3922 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
3924 else
3926 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
3927 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
3928 unsigned char *saved_buffer;
3929 if (m)
3931 switch(*desc)
3933 case RPC_FC_RP:
3934 case RPC_FC_UP:
3935 case RPC_FC_OP:
3936 case RPC_FC_FP:
3937 ALIGN_POINTER(pStubMsg->Buffer, 4);
3938 saved_buffer = pStubMsg->Buffer;
3939 pStubMsg->Buffer += 4;
3940 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
3941 pStubMsg->MemorySize += 4;
3942 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
3943 break;
3944 default:
3945 return m(pStubMsg, desc);
3948 else FIXME("no marshaller for embedded type %02x\n", *desc);
3951 TRACE("size %d\n", size);
3952 return size;
3955 /***********************************************************************
3956 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
3958 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
3959 unsigned char *pMemory,
3960 PFORMAT_STRING pFormat)
3962 FIXME("stub\n");
3965 /***********************************************************************
3966 * NdrByteCountPointerMarshall [RPCRT4.@]
3968 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3969 unsigned char *pMemory,
3970 PFORMAT_STRING pFormat)
3972 FIXME("stub\n");
3973 return NULL;
3976 /***********************************************************************
3977 * NdrByteCountPointerUnmarshall [RPCRT4.@]
3979 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3980 unsigned char **ppMemory,
3981 PFORMAT_STRING pFormat,
3982 unsigned char fMustAlloc)
3984 FIXME("stub\n");
3985 return NULL;
3988 /***********************************************************************
3989 * NdrByteCountPointerBufferSize [RPCRT4.@]
3991 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3992 unsigned char *pMemory,
3993 PFORMAT_STRING pFormat)
3995 FIXME("stub\n");
3998 /***********************************************************************
3999 * NdrByteCountPointerMemorySize [RPCRT4.@]
4001 unsigned long WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4002 PFORMAT_STRING pFormat)
4004 FIXME("stub\n");
4005 return 0;
4008 /***********************************************************************
4009 * NdrByteCountPointerFree [RPCRT4.@]
4011 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
4012 unsigned char *pMemory,
4013 PFORMAT_STRING pFormat)
4015 FIXME("stub\n");
4018 /***********************************************************************
4019 * NdrXmitOrRepAsMarshall [RPCRT4.@]
4021 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4022 unsigned char *pMemory,
4023 PFORMAT_STRING pFormat)
4025 FIXME("stub\n");
4026 return NULL;
4029 /***********************************************************************
4030 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
4032 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4033 unsigned char **ppMemory,
4034 PFORMAT_STRING pFormat,
4035 unsigned char fMustAlloc)
4037 FIXME("stub\n");
4038 return NULL;
4041 /***********************************************************************
4042 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
4044 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4045 unsigned char *pMemory,
4046 PFORMAT_STRING pFormat)
4048 FIXME("stub\n");
4051 /***********************************************************************
4052 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
4054 unsigned long WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4055 PFORMAT_STRING pFormat)
4057 FIXME("stub\n");
4058 return 0;
4061 /***********************************************************************
4062 * NdrXmitOrRepAsFree [RPCRT4.@]
4064 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
4065 unsigned char *pMemory,
4066 PFORMAT_STRING pFormat)
4068 FIXME("stub\n");
4071 /***********************************************************************
4072 * NdrBaseTypeMarshall [internal]
4074 static unsigned char *WINAPI NdrBaseTypeMarshall(
4075 PMIDL_STUB_MESSAGE pStubMsg,
4076 unsigned char *pMemory,
4077 PFORMAT_STRING pFormat)
4079 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4081 switch(*pFormat)
4083 case RPC_FC_BYTE:
4084 case RPC_FC_CHAR:
4085 case RPC_FC_SMALL:
4086 case RPC_FC_USMALL:
4087 *(UCHAR *)pStubMsg->Buffer = *(UCHAR *)pMemory;
4088 pStubMsg->Buffer += sizeof(UCHAR);
4089 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
4090 break;
4091 case RPC_FC_WCHAR:
4092 case RPC_FC_SHORT:
4093 case RPC_FC_USHORT:
4094 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4095 *(USHORT *)pStubMsg->Buffer = *(USHORT *)pMemory;
4096 pStubMsg->Buffer += sizeof(USHORT);
4097 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
4098 break;
4099 case RPC_FC_LONG:
4100 case RPC_FC_ULONG:
4101 case RPC_FC_ERROR_STATUS_T:
4102 case RPC_FC_ENUM32:
4103 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4104 *(ULONG *)pStubMsg->Buffer = *(ULONG *)pMemory;
4105 pStubMsg->Buffer += sizeof(ULONG);
4106 TRACE("value: 0x%08lx\n", *(ULONG *)pMemory);
4107 break;
4108 case RPC_FC_FLOAT:
4109 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
4110 *(float *)pStubMsg->Buffer = *(float *)pMemory;
4111 pStubMsg->Buffer += sizeof(float);
4112 break;
4113 case RPC_FC_DOUBLE:
4114 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
4115 *(double *)pStubMsg->Buffer = *(double *)pMemory;
4116 pStubMsg->Buffer += sizeof(double);
4117 break;
4118 case RPC_FC_HYPER:
4119 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
4120 *(ULONGLONG *)pStubMsg->Buffer = *(ULONGLONG *)pMemory;
4121 pStubMsg->Buffer += sizeof(ULONGLONG);
4122 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
4123 break;
4124 case RPC_FC_ENUM16:
4125 /* only 16-bits on the wire, so do a sanity check */
4126 if (*(UINT *)pMemory > USHRT_MAX)
4127 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
4128 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4129 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
4130 pStubMsg->Buffer += sizeof(USHORT);
4131 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
4132 break;
4133 default:
4134 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4137 STD_OVERFLOW_CHECK(pStubMsg);
4139 /* FIXME: what is the correct return value? */
4140 return NULL;
4143 /***********************************************************************
4144 * NdrBaseTypeUnmarshall [internal]
4146 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
4147 PMIDL_STUB_MESSAGE pStubMsg,
4148 unsigned char **ppMemory,
4149 PFORMAT_STRING pFormat,
4150 unsigned char fMustAlloc)
4152 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
4154 if (fMustAlloc || !*ppMemory)
4156 unsigned char *Buffer = pStubMsg->Buffer;
4157 unsigned long MemorySize = pStubMsg->MemorySize;
4158 *ppMemory = NdrAllocate(pStubMsg, NdrBaseTypeMemorySize(pStubMsg, pFormat));
4159 pStubMsg->MemorySize = MemorySize;
4160 pStubMsg->Buffer = Buffer;
4163 TRACE("*ppMemory: %p\n", *ppMemory);
4165 #define BASE_TYPE_UNMARSHALL(type) \
4166 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
4167 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
4168 pStubMsg->Buffer += sizeof(type);
4170 switch(*pFormat)
4172 case RPC_FC_BYTE:
4173 case RPC_FC_CHAR:
4174 case RPC_FC_SMALL:
4175 case RPC_FC_USMALL:
4176 BASE_TYPE_UNMARSHALL(UCHAR);
4177 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
4178 break;
4179 case RPC_FC_WCHAR:
4180 case RPC_FC_SHORT:
4181 case RPC_FC_USHORT:
4182 BASE_TYPE_UNMARSHALL(USHORT);
4183 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
4184 break;
4185 case RPC_FC_LONG:
4186 case RPC_FC_ULONG:
4187 case RPC_FC_ERROR_STATUS_T:
4188 case RPC_FC_ENUM32:
4189 BASE_TYPE_UNMARSHALL(ULONG);
4190 TRACE("value: 0x%08lx\n", **(ULONG **)ppMemory);
4191 break;
4192 case RPC_FC_FLOAT:
4193 BASE_TYPE_UNMARSHALL(float);
4194 TRACE("value: %f\n", **(float **)ppMemory);
4195 break;
4196 case RPC_FC_DOUBLE:
4197 BASE_TYPE_UNMARSHALL(double);
4198 TRACE("value: %f\n", **(double **)ppMemory);
4199 break;
4200 case RPC_FC_HYPER:
4201 BASE_TYPE_UNMARSHALL(ULONGLONG);
4202 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
4203 break;
4204 case RPC_FC_ENUM16:
4205 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4206 /* 16-bits on the wire, but int in memory */
4207 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
4208 pStubMsg->Buffer += sizeof(USHORT);
4209 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
4210 break;
4211 default:
4212 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4214 #undef BASE_TYPE_UNMARSHALL
4216 /* FIXME: what is the correct return value? */
4218 return NULL;
4221 /***********************************************************************
4222 * NdrBaseTypeBufferSize [internal]
4224 static void WINAPI NdrBaseTypeBufferSize(
4225 PMIDL_STUB_MESSAGE pStubMsg,
4226 unsigned char *pMemory,
4227 PFORMAT_STRING pFormat)
4229 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4231 switch(*pFormat)
4233 case RPC_FC_BYTE:
4234 case RPC_FC_CHAR:
4235 case RPC_FC_SMALL:
4236 case RPC_FC_USMALL:
4237 pStubMsg->BufferLength += sizeof(UCHAR);
4238 break;
4239 case RPC_FC_WCHAR:
4240 case RPC_FC_SHORT:
4241 case RPC_FC_USHORT:
4242 case RPC_FC_ENUM16:
4243 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
4244 pStubMsg->BufferLength += sizeof(USHORT);
4245 break;
4246 case RPC_FC_LONG:
4247 case RPC_FC_ULONG:
4248 case RPC_FC_ENUM32:
4249 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
4250 pStubMsg->BufferLength += sizeof(ULONG);
4251 break;
4252 case RPC_FC_FLOAT:
4253 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
4254 pStubMsg->BufferLength += sizeof(float);
4255 break;
4256 case RPC_FC_DOUBLE:
4257 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
4258 pStubMsg->BufferLength += sizeof(double);
4259 break;
4260 case RPC_FC_HYPER:
4261 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
4262 pStubMsg->BufferLength += sizeof(ULONGLONG);
4263 break;
4264 case RPC_FC_ERROR_STATUS_T:
4265 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
4266 pStubMsg->BufferLength += sizeof(error_status_t);
4267 break;
4268 default:
4269 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4273 /***********************************************************************
4274 * NdrBaseTypeMemorySize [internal]
4276 static unsigned long WINAPI NdrBaseTypeMemorySize(
4277 PMIDL_STUB_MESSAGE pStubMsg,
4278 PFORMAT_STRING pFormat)
4280 switch(*pFormat)
4282 case RPC_FC_BYTE:
4283 case RPC_FC_CHAR:
4284 case RPC_FC_SMALL:
4285 case RPC_FC_USMALL:
4286 pStubMsg->Buffer += sizeof(UCHAR);
4287 pStubMsg->MemorySize += sizeof(UCHAR);
4288 return sizeof(UCHAR);
4289 case RPC_FC_WCHAR:
4290 case RPC_FC_SHORT:
4291 case RPC_FC_USHORT:
4292 pStubMsg->Buffer += sizeof(USHORT);
4293 pStubMsg->MemorySize += sizeof(USHORT);
4294 return sizeof(USHORT);
4295 case RPC_FC_LONG:
4296 case RPC_FC_ULONG:
4297 pStubMsg->Buffer += sizeof(ULONG);
4298 pStubMsg->MemorySize += sizeof(ULONG);
4299 return sizeof(ULONG);
4300 case RPC_FC_FLOAT:
4301 pStubMsg->Buffer += sizeof(float);
4302 pStubMsg->MemorySize += sizeof(float);
4303 return sizeof(float);
4304 case RPC_FC_DOUBLE:
4305 pStubMsg->Buffer += sizeof(double);
4306 pStubMsg->MemorySize += sizeof(double);
4307 return sizeof(double);
4308 case RPC_FC_HYPER:
4309 pStubMsg->Buffer += sizeof(ULONGLONG);
4310 pStubMsg->MemorySize += sizeof(ULONGLONG);
4311 return sizeof(ULONGLONG);
4312 case RPC_FC_ERROR_STATUS_T:
4313 pStubMsg->Buffer += sizeof(error_status_t);
4314 pStubMsg->MemorySize += sizeof(error_status_t);
4315 return sizeof(error_status_t);
4316 case RPC_FC_ENUM16:
4317 case RPC_FC_ENUM32:
4318 pStubMsg->Buffer += sizeof(INT);
4319 pStubMsg->MemorySize += sizeof(INT);
4320 return sizeof(INT);
4321 default:
4322 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4323 return 0;
4327 /***********************************************************************
4328 * NdrBaseTypeFree [internal]
4330 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
4331 unsigned char *pMemory,
4332 PFORMAT_STRING pFormat)
4334 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4336 /* nothing to do */
4339 /***********************************************************************
4340 * NdrClientContextMarshall
4342 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4343 NDR_CCONTEXT ContextHandle,
4344 int fCheck)
4346 TRACE("(%p, %p, %d): stub\n", pStubMsg, ContextHandle, fCheck);
4347 /* FIXME: what does fCheck do? */
4348 return NDRCContextMarshall(ContextHandle,
4349 pStubMsg->Buffer);
4352 /***********************************************************************
4353 * NdrClientContextUnmarshall
4355 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4356 NDR_CCONTEXT * pContextHandle,
4357 RPC_BINDING_HANDLE BindHandle)
4359 TRACE("(%p, %p, %p): stub\n", pStubMsg, pContextHandle, BindHandle);
4360 return NDRCContextUnmarshall(pContextHandle,
4361 BindHandle,
4362 pStubMsg->Buffer,
4363 pStubMsg->RpcMsg->DataRepresentation);
4366 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4367 NDR_SCONTEXT ContextHandle,
4368 NDR_RUNDOWN RundownRoutine )
4370 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
4373 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
4375 FIXME("(%p): stub\n", pStubMsg);
4376 return NULL;
4379 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
4380 unsigned char* pMemory,
4381 PFORMAT_STRING pFormat)
4383 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
4386 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
4387 PFORMAT_STRING pFormat)
4389 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
4390 return NULL;
4393 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4394 NDR_SCONTEXT ContextHandle,
4395 NDR_RUNDOWN RundownRoutine,
4396 PFORMAT_STRING pFormat)
4398 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
4401 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4402 PFORMAT_STRING pFormat)
4404 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
4405 return NULL;
4408 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
4410 FIXME("(%p): stub\n", CContext);
4411 return NULL;
4414 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
4416 FIXME("(%p %p): stub\n", CContext, pBuff);
4419 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
4420 RPC_BINDING_HANDLE hBinding,
4421 void *pBuff,
4422 unsigned long DataRepresentation)
4424 FIXME("(%p %p %p %08lx): stub\n", CContext, hBinding, pBuff, DataRepresentation);
4427 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
4428 void *pBuff,
4429 NDR_RUNDOWN userRunDownIn)
4431 FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn);
4434 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
4435 NDR_SCONTEXT CContext,
4436 void *pBuff,
4437 NDR_RUNDOWN userRunDownIn)
4439 FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn);
4442 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
4443 NDR_SCONTEXT CContext,
4444 void *pBuff,
4445 NDR_RUNDOWN userRunDownIn,
4446 void *CtxGuard,
4447 unsigned long Flags)
4449 FIXME("(%p %p %p %p %p %lu): stub\n",
4450 hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags);
4453 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
4454 unsigned long DataRepresentation)
4456 FIXME("(%p %08lx): stub\n", pBuff, DataRepresentation);
4457 return NULL;
4460 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
4461 void *pBuff,
4462 unsigned long DataRepresentation)
4464 FIXME("(%p %p %08lx): stub\n", hBinding, pBuff, DataRepresentation);
4465 return NULL;
4468 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
4469 void *pBuff,
4470 unsigned long DataRepresentation,
4471 void *CtxGuard,
4472 unsigned long Flags)
4474 FIXME("(%p %p %08lx %p %lu): stub\n",
4475 hBinding, pBuff, DataRepresentation, CtxGuard, Flags);
4476 return NULL;