rpcrt4: Use the offset to array data in embedded pointer format descriptions.
[wine/multimedia.git] / dlls / rpcrt4 / ndr_marshall.c
blobde6f5097cd24d171472bcd068a0788e02f973574
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 * - Encapsulated unions
25 * - Byte count pointers
26 * - transmit_as/represent as
27 * - Multi-dimensional arrays
28 * - Conversion functions (NdrConvert)
29 * - Checks for integer addition overflow
30 * - Checks for out-of-memory conditions
33 #include <stdarg.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <assert.h>
37 #include <limits.h>
39 #include "windef.h"
40 #include "winbase.h"
41 #include "winerror.h"
43 #include "ndr_misc.h"
44 #include "rpcndr.h"
46 #include "wine/unicode.h"
47 #include "wine/rpcfc.h"
49 #include "wine/debug.h"
50 #include "wine/list.h"
52 WINE_DEFAULT_DEBUG_CHANNEL(ole);
54 #if defined(__i386__)
55 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
56 (*((UINT32 *)(pchar)) = (uint32))
58 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
59 (*((UINT32 *)(pchar)))
60 #else
61 /* these would work for i386 too, but less efficient */
62 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
63 (*(pchar) = LOBYTE(LOWORD(uint32)), \
64 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
65 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
66 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
67 (uint32)) /* allow as r-value */
69 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
70 (MAKELONG( \
71 MAKEWORD(*(pchar), *((pchar)+1)), \
72 MAKEWORD(*((pchar)+2), *((pchar)+3))))
73 #endif
75 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
76 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
77 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
78 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
79 *(pchar) = HIBYTE(HIWORD(uint32)), \
80 (uint32)) /* allow as r-value */
82 #define BIG_ENDIAN_UINT32_READ(pchar) \
83 (MAKELONG( \
84 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
85 MAKEWORD(*((pchar)+1), *(pchar))))
87 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
88 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
89 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
90 # define NDR_LOCAL_UINT32_READ(pchar) \
91 BIG_ENDIAN_UINT32_READ(pchar)
92 #else
93 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
94 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
95 # define NDR_LOCAL_UINT32_READ(pchar) \
96 LITTLE_ENDIAN_UINT32_READ(pchar)
97 #endif
99 /* _Align must be the desired alignment,
100 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
101 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
102 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
103 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
104 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
106 #define STD_OVERFLOW_CHECK(_Msg) do { \
107 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
108 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
109 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
110 } while (0)
112 #define NDR_TABLE_SIZE 128
113 #define NDR_TABLE_MASK 127
115 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
116 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
117 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
118 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
119 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
121 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
123 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
124 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
125 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
126 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
127 /* 0x10 */
128 NdrBaseTypeMarshall,
129 /* 0x11 */
130 NdrPointerMarshall, NdrPointerMarshall,
131 NdrPointerMarshall, NdrPointerMarshall,
132 /* 0x15 */
133 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
134 NdrConformantStructMarshall, NdrConformantStructMarshall,
135 NdrConformantVaryingStructMarshall,
136 NdrComplexStructMarshall,
137 /* 0x1b */
138 NdrConformantArrayMarshall,
139 NdrConformantVaryingArrayMarshall,
140 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
141 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
142 NdrComplexArrayMarshall,
143 /* 0x22 */
144 NdrConformantStringMarshall, 0, 0,
145 NdrConformantStringMarshall,
146 NdrNonConformantStringMarshall, 0, 0, 0,
147 /* 0x2a */
148 NdrEncapsulatedUnionMarshall,
149 NdrNonEncapsulatedUnionMarshall,
150 NdrByteCountPointerMarshall,
151 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
152 /* 0x2f */
153 NdrInterfacePointerMarshall,
154 /* 0xb0 */
155 0, 0, 0, 0,
156 NdrUserMarshalMarshall
158 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
160 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
161 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
162 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
163 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
164 /* 0x10 */
165 NdrBaseTypeUnmarshall,
166 /* 0x11 */
167 NdrPointerUnmarshall, NdrPointerUnmarshall,
168 NdrPointerUnmarshall, NdrPointerUnmarshall,
169 /* 0x15 */
170 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
171 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
172 NdrConformantVaryingStructUnmarshall,
173 NdrComplexStructUnmarshall,
174 /* 0x1b */
175 NdrConformantArrayUnmarshall,
176 NdrConformantVaryingArrayUnmarshall,
177 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
178 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
179 NdrComplexArrayUnmarshall,
180 /* 0x22 */
181 NdrConformantStringUnmarshall, 0, 0,
182 NdrConformantStringUnmarshall,
183 NdrNonConformantStringUnmarshall, 0, 0, 0,
184 /* 0x2a */
185 NdrEncapsulatedUnionUnmarshall,
186 NdrNonEncapsulatedUnionUnmarshall,
187 NdrByteCountPointerUnmarshall,
188 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
189 /* 0x2f */
190 NdrInterfacePointerUnmarshall,
191 /* 0xb0 */
192 0, 0, 0, 0,
193 NdrUserMarshalUnmarshall
195 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
197 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
198 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
199 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
200 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
201 /* 0x10 */
202 NdrBaseTypeBufferSize,
203 /* 0x11 */
204 NdrPointerBufferSize, NdrPointerBufferSize,
205 NdrPointerBufferSize, NdrPointerBufferSize,
206 /* 0x15 */
207 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
208 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
209 NdrConformantVaryingStructBufferSize,
210 NdrComplexStructBufferSize,
211 /* 0x1b */
212 NdrConformantArrayBufferSize,
213 NdrConformantVaryingArrayBufferSize,
214 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
215 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
216 NdrComplexArrayBufferSize,
217 /* 0x22 */
218 NdrConformantStringBufferSize, 0, 0,
219 NdrConformantStringBufferSize,
220 NdrNonConformantStringBufferSize, 0, 0, 0,
221 /* 0x2a */
222 NdrEncapsulatedUnionBufferSize,
223 NdrNonEncapsulatedUnionBufferSize,
224 NdrByteCountPointerBufferSize,
225 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
226 /* 0x2f */
227 NdrInterfacePointerBufferSize,
228 /* 0xb0 */
229 0, 0, 0, 0,
230 NdrUserMarshalBufferSize
232 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
234 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
235 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
236 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
237 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
238 /* 0x10 */
239 NdrBaseTypeMemorySize,
240 /* 0x11 */
241 NdrPointerMemorySize, NdrPointerMemorySize,
242 NdrPointerMemorySize, NdrPointerMemorySize,
243 /* 0x15 */
244 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
245 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
246 NdrConformantVaryingStructMemorySize,
247 NdrComplexStructMemorySize,
248 /* 0x1b */
249 NdrConformantArrayMemorySize,
250 NdrConformantVaryingArrayMemorySize,
251 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
252 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
253 NdrComplexArrayMemorySize,
254 /* 0x22 */
255 NdrConformantStringMemorySize, 0, 0,
256 NdrConformantStringMemorySize,
257 NdrNonConformantStringMemorySize, 0, 0, 0,
258 /* 0x2a */
259 NdrEncapsulatedUnionMemorySize,
260 NdrNonEncapsulatedUnionMemorySize,
261 NdrByteCountPointerMemorySize,
262 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
263 /* 0x2f */
264 NdrInterfacePointerMemorySize,
265 /* 0xb0 */
266 0, 0, 0, 0,
267 NdrUserMarshalMemorySize
269 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
271 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
272 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
273 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
274 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
275 /* 0x10 */
276 NdrBaseTypeFree,
277 /* 0x11 */
278 NdrPointerFree, NdrPointerFree,
279 NdrPointerFree, NdrPointerFree,
280 /* 0x15 */
281 NdrSimpleStructFree, NdrSimpleStructFree,
282 NdrConformantStructFree, NdrConformantStructFree,
283 NdrConformantVaryingStructFree,
284 NdrComplexStructFree,
285 /* 0x1b */
286 NdrConformantArrayFree,
287 NdrConformantVaryingArrayFree,
288 NdrFixedArrayFree, NdrFixedArrayFree,
289 NdrVaryingArrayFree, NdrVaryingArrayFree,
290 NdrComplexArrayFree,
291 /* 0x22 */
292 0, 0, 0,
293 0, 0, 0, 0, 0,
294 /* 0x2a */
295 NdrEncapsulatedUnionFree,
296 NdrNonEncapsulatedUnionFree,
298 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
299 /* 0x2f */
300 NdrInterfacePointerFree,
301 /* 0xb0 */
302 0, 0, 0, 0,
303 NdrUserMarshalFree
306 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
308 /* hmm, this is probably supposed to do more? */
309 return pStubMsg->pfnAllocate(len);
312 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
314 pStubMsg->pfnFree(Pointer);
317 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
319 return (*(const ULONG *)pFormat != -1);
322 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
324 ALIGN_POINTER(pStubMsg->Buffer, 4);
325 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
326 pStubMsg->Buffer += 4;
327 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
328 if (pStubMsg->fHasNewCorrDesc)
329 return pFormat+6;
330 else
331 return pFormat+4;
334 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
336 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
338 pStubMsg->Offset = 0;
339 pStubMsg->ActualCount = pStubMsg->MaxCount;
340 goto done;
343 ALIGN_POINTER(pStubMsg->Buffer, 4);
344 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
345 pStubMsg->Buffer += 4;
346 TRACE("offset is %d\n", pStubMsg->Offset);
347 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
348 pStubMsg->Buffer += 4;
349 TRACE("variance is %d\n", pStubMsg->ActualCount);
351 if ((pStubMsg->ActualCount > MaxValue) ||
352 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
354 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
355 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
356 RpcRaiseException(RPC_S_INVALID_BOUND);
357 return NULL;
360 done:
361 if (pStubMsg->fHasNewCorrDesc)
362 return pFormat+6;
363 else
364 return pFormat+4;
367 /* writes the conformance value to the buffer */
368 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
370 ALIGN_POINTER(pStubMsg->Buffer, 4);
371 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
372 pStubMsg->Buffer += 4;
375 /* writes the variance values to the buffer */
376 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
378 ALIGN_POINTER(pStubMsg->Buffer, 4);
379 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
380 pStubMsg->Buffer += 4;
381 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
382 pStubMsg->Buffer += 4;
385 /* requests buffer space for the conformance value */
386 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
388 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
389 pStubMsg->BufferLength += 4;
392 /* requests buffer space for the variance values */
393 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
395 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
396 pStubMsg->BufferLength += 8;
399 PFORMAT_STRING ComputeConformanceOrVariance(
400 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
401 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
403 BYTE dtype = pFormat[0] & 0xf;
404 short ofs = *(const short *)&pFormat[2];
405 LPVOID ptr = NULL;
406 DWORD data = 0;
408 if (!IsConformanceOrVariancePresent(pFormat)) {
409 /* null descriptor */
410 *pCount = def;
411 goto finish_conf;
414 switch (pFormat[0] & 0xf0) {
415 case RPC_FC_NORMAL_CONFORMANCE:
416 TRACE("normal conformance, ofs=%d\n", ofs);
417 ptr = pMemory;
418 break;
419 case RPC_FC_POINTER_CONFORMANCE:
420 TRACE("pointer conformance, ofs=%d\n", ofs);
421 ptr = pStubMsg->Memory;
422 break;
423 case RPC_FC_TOP_LEVEL_CONFORMANCE:
424 TRACE("toplevel conformance, ofs=%d\n", ofs);
425 if (pStubMsg->StackTop) {
426 ptr = pStubMsg->StackTop;
428 else {
429 /* -Os mode, *pCount is already set */
430 goto finish_conf;
432 break;
433 case RPC_FC_CONSTANT_CONFORMANCE:
434 data = ofs | ((DWORD)pFormat[1] << 16);
435 TRACE("constant conformance, val=%d\n", data);
436 *pCount = data;
437 goto finish_conf;
438 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
439 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
440 if (pStubMsg->StackTop) {
441 ptr = pStubMsg->StackTop;
443 else {
444 /* ? */
445 goto done_conf_grab;
447 break;
448 default:
449 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
452 switch (pFormat[1]) {
453 case RPC_FC_DEREFERENCE:
454 ptr = *(LPVOID*)((char *)ptr + ofs);
455 break;
456 case RPC_FC_CALLBACK:
458 unsigned char *old_stack_top = pStubMsg->StackTop;
459 pStubMsg->StackTop = ptr;
461 /* ofs is index into StubDesc->apfnExprEval */
462 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
463 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
465 pStubMsg->StackTop = old_stack_top;
467 /* the callback function always stores the computed value in MaxCount */
468 *pCount = pStubMsg->MaxCount;
469 goto finish_conf;
471 default:
472 ptr = (char *)ptr + ofs;
473 break;
476 switch (dtype) {
477 case RPC_FC_LONG:
478 case RPC_FC_ULONG:
479 data = *(DWORD*)ptr;
480 break;
481 case RPC_FC_SHORT:
482 data = *(SHORT*)ptr;
483 break;
484 case RPC_FC_USHORT:
485 data = *(USHORT*)ptr;
486 break;
487 case RPC_FC_CHAR:
488 case RPC_FC_SMALL:
489 data = *(CHAR*)ptr;
490 break;
491 case RPC_FC_BYTE:
492 case RPC_FC_USMALL:
493 data = *(UCHAR*)ptr;
494 break;
495 default:
496 FIXME("unknown conformance data type %x\n", dtype);
497 goto done_conf_grab;
499 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
501 done_conf_grab:
502 switch (pFormat[1]) {
503 case RPC_FC_DEREFERENCE: /* already handled */
504 case 0: /* no op */
505 *pCount = data;
506 break;
507 case RPC_FC_ADD_1:
508 *pCount = data + 1;
509 break;
510 case RPC_FC_SUB_1:
511 *pCount = data - 1;
512 break;
513 case RPC_FC_MULT_2:
514 *pCount = data * 2;
515 break;
516 case RPC_FC_DIV_2:
517 *pCount = data / 2;
518 break;
519 default:
520 FIXME("unknown conformance op %d\n", pFormat[1]);
521 goto finish_conf;
524 finish_conf:
525 TRACE("resulting conformance is %ld\n", *pCount);
526 if (pStubMsg->fHasNewCorrDesc)
527 return pFormat+6;
528 else
529 return pFormat+4;
532 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
533 * the result overflows 32-bits */
534 static inline ULONG safe_multiply(ULONG a, ULONG b)
536 ULONGLONG ret = (ULONGLONG)a * b;
537 if (ret > 0xffffffff)
539 RpcRaiseException(RPC_S_INVALID_BOUND);
540 return 0;
542 return ret;
547 * NdrConformantString:
549 * What MS calls a ConformantString is, in DCE terminology,
550 * a Varying-Conformant String.
552 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
553 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
554 * into unmarshalled string)
555 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
556 * [
557 * data: CHARTYPE[maxlen]
558 * ]
559 * ], where CHARTYPE is the appropriate character type (specified externally)
563 /***********************************************************************
564 * NdrConformantStringMarshall [RPCRT4.@]
566 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
567 unsigned char *pszMessage, PFORMAT_STRING pFormat)
569 ULONG esize, size;
571 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
573 if (*pFormat == RPC_FC_C_CSTRING) {
574 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
575 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
576 esize = 1;
578 else if (*pFormat == RPC_FC_C_WSTRING) {
579 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
580 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
581 esize = 2;
583 else {
584 ERR("Unhandled string type: %#x\n", *pFormat);
585 /* FIXME: raise an exception. */
586 return NULL;
589 if (pFormat[1] == RPC_FC_STRING_SIZED)
590 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
591 else
592 pStubMsg->MaxCount = pStubMsg->ActualCount;
593 pStubMsg->Offset = 0;
594 WriteConformance(pStubMsg);
595 WriteVariance(pStubMsg);
597 size = safe_multiply(esize, pStubMsg->ActualCount);
598 memcpy(pStubMsg->Buffer, pszMessage, size); /* the string itself */
599 pStubMsg->Buffer += size;
601 STD_OVERFLOW_CHECK(pStubMsg);
603 /* success */
604 return NULL; /* is this always right? */
607 /***********************************************************************
608 * NdrConformantStringBufferSize [RPCRT4.@]
610 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
611 unsigned char* pMemory, PFORMAT_STRING pFormat)
613 ULONG esize;
615 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
617 SizeConformance(pStubMsg);
618 SizeVariance(pStubMsg);
620 if (*pFormat == RPC_FC_C_CSTRING) {
621 TRACE("string=%s\n", debugstr_a((char*)pMemory));
622 pStubMsg->ActualCount = strlen((char*)pMemory)+1;
623 esize = 1;
625 else if (*pFormat == RPC_FC_C_WSTRING) {
626 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
627 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;
628 esize = 2;
630 else {
631 ERR("Unhandled string type: %#x\n", *pFormat);
632 /* FIXME: raise an exception */
633 return;
636 if (pFormat[1] == RPC_FC_STRING_SIZED)
637 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
638 else
639 pStubMsg->MaxCount = pStubMsg->ActualCount;
641 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
644 /************************************************************************
645 * NdrConformantStringMemorySize [RPCRT4.@]
647 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
648 PFORMAT_STRING pFormat )
650 ULONG rslt = 0;
652 FIXME("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
654 assert(pStubMsg && pFormat);
656 if (*pFormat == RPC_FC_C_CSTRING) {
657 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
659 else if (*pFormat == RPC_FC_C_WSTRING) {
660 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
662 else {
663 ERR("Unhandled string type: %#x\n", *pFormat);
664 /* FIXME: raise an exception */
667 if (pFormat[1] != RPC_FC_PAD) {
668 FIXME("sized string format=%d\n", pFormat[1]);
671 TRACE(" --> %u\n", rslt);
672 return rslt;
675 /************************************************************************
676 * NdrConformantStringUnmarshall [RPCRT4.@]
678 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
679 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
681 ULONG bufsize, memsize, esize, i;
683 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
684 pStubMsg, *ppMemory, pFormat, fMustAlloc);
686 assert(pFormat && ppMemory && pStubMsg);
688 ReadConformance(pStubMsg, NULL);
689 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
691 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
692 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
693 else {
694 ERR("Unhandled string type: %#x\n", *pFormat);
695 /* FIXME: raise an exception */
696 esize = 0;
699 memsize = safe_multiply(esize, pStubMsg->MaxCount);
700 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
702 /* strings must always have null terminating bytes */
703 if (bufsize < esize)
705 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
706 RpcRaiseException(RPC_S_INVALID_BOUND);
707 return NULL;
709 for (i = bufsize - esize; i < bufsize; i++)
710 if (pStubMsg->Buffer[i] != 0)
712 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
713 i, pStubMsg->Buffer[i]);
714 RpcRaiseException(RPC_S_INVALID_BOUND);
715 return NULL;
718 if (fMustAlloc || !*ppMemory)
719 *ppMemory = NdrAllocate(pStubMsg, memsize);
721 memcpy(*ppMemory, pStubMsg->Buffer, bufsize);
723 pStubMsg->Buffer += bufsize;
725 if (*pFormat == RPC_FC_C_CSTRING) {
726 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
728 else if (*pFormat == RPC_FC_C_WSTRING) {
729 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
732 return NULL; /* FIXME: is this always right? */
735 /***********************************************************************
736 * NdrNonConformantStringMarshall [RPCRT4.@]
738 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
739 unsigned char *pMemory,
740 PFORMAT_STRING pFormat)
742 FIXME("stub\n");
743 return NULL;
746 /***********************************************************************
747 * NdrNonConformantStringUnmarshall [RPCRT4.@]
749 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
750 unsigned char **ppMemory,
751 PFORMAT_STRING pFormat,
752 unsigned char fMustAlloc)
754 FIXME("stub\n");
755 return NULL;
758 /***********************************************************************
759 * NdrNonConformantStringBufferSize [RPCRT4.@]
761 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
762 unsigned char *pMemory,
763 PFORMAT_STRING pFormat)
765 FIXME("stub\n");
768 /***********************************************************************
769 * NdrNonConformantStringMemorySize [RPCRT4.@]
771 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
772 PFORMAT_STRING pFormat)
774 FIXME("stub\n");
775 return 0;
778 static inline void dump_pointer_attr(unsigned char attr)
780 if (attr & RPC_FC_P_ALLOCALLNODES)
781 TRACE(" RPC_FC_P_ALLOCALLNODES");
782 if (attr & RPC_FC_P_DONTFREE)
783 TRACE(" RPC_FC_P_DONTFREE");
784 if (attr & RPC_FC_P_ONSTACK)
785 TRACE(" RPC_FC_P_ONSTACK");
786 if (attr & RPC_FC_P_SIMPLEPOINTER)
787 TRACE(" RPC_FC_P_SIMPLEPOINTER");
788 if (attr & RPC_FC_P_DEREF)
789 TRACE(" RPC_FC_P_DEREF");
790 TRACE("\n");
793 /***********************************************************************
794 * PointerMarshall [internal]
796 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
797 unsigned char *Buffer,
798 unsigned char *Pointer,
799 PFORMAT_STRING pFormat)
801 unsigned type = pFormat[0], attr = pFormat[1];
802 PFORMAT_STRING desc;
803 NDR_MARSHALL m;
804 ULONG pointer_id;
805 int pointer_needs_marshaling;
807 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
808 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
809 pFormat += 2;
810 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
811 else desc = pFormat + *(const SHORT*)pFormat;
813 switch (type) {
814 case RPC_FC_RP: /* ref pointer (always non-null) */
815 #if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
816 if (!Pointer)
817 RpcRaiseException(RPC_X_NULL_REF_POINTER);
818 #endif
819 pointer_needs_marshaling = 1;
820 break;
821 case RPC_FC_UP: /* unique pointer */
822 case RPC_FC_OP: /* object pointer - same as unique here */
823 if (Pointer)
824 pointer_needs_marshaling = 1;
825 else
826 pointer_needs_marshaling = 0;
827 pointer_id = (ULONG)Pointer;
828 TRACE("writing 0x%08x to buffer\n", pointer_id);
829 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
830 break;
831 case RPC_FC_FP:
832 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
833 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
834 TRACE("writing 0x%08x to buffer\n", pointer_id);
835 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
836 break;
837 default:
838 FIXME("unhandled ptr type=%02x\n", type);
839 RpcRaiseException(RPC_X_BAD_STUB_DATA);
840 return;
843 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
845 if (pointer_needs_marshaling) {
846 if (attr & RPC_FC_P_DEREF) {
847 Pointer = *(unsigned char**)Pointer;
848 TRACE("deref => %p\n", Pointer);
850 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
851 if (m) m(pStubMsg, Pointer, desc);
852 else FIXME("no marshaller for data type=%02x\n", *desc);
855 STD_OVERFLOW_CHECK(pStubMsg);
858 /***********************************************************************
859 * PointerUnmarshall [internal]
861 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
862 unsigned char *Buffer,
863 unsigned char **pPointer,
864 PFORMAT_STRING pFormat,
865 unsigned char fMustAlloc)
867 unsigned type = pFormat[0], attr = pFormat[1];
868 PFORMAT_STRING desc;
869 NDR_UNMARSHALL m;
870 DWORD pointer_id = 0;
871 int pointer_needs_unmarshaling;
873 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pFormat, fMustAlloc);
874 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
875 pFormat += 2;
876 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
877 else desc = pFormat + *(const SHORT*)pFormat;
879 switch (type) {
880 case RPC_FC_RP: /* ref pointer (always non-null) */
881 pointer_needs_unmarshaling = 1;
882 break;
883 case RPC_FC_UP: /* unique pointer */
884 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
885 TRACE("pointer_id is 0x%08x\n", pointer_id);
886 if (pointer_id)
887 pointer_needs_unmarshaling = 1;
888 else {
889 *pPointer = NULL;
890 pointer_needs_unmarshaling = 0;
892 break;
893 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
894 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
895 TRACE("pointer_id is 0x%08x\n", pointer_id);
896 if (!fMustAlloc && *pPointer)
898 FIXME("free object pointer %p\n", *pPointer);
899 *pPointer = NULL;
901 if (pointer_id)
902 pointer_needs_unmarshaling = 1;
903 else
904 pointer_needs_unmarshaling = 0;
905 break;
906 case RPC_FC_FP:
907 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
908 TRACE("pointer_id is 0x%08x\n", pointer_id);
909 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
910 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
911 break;
912 default:
913 FIXME("unhandled ptr type=%02x\n", type);
914 RpcRaiseException(RPC_X_BAD_STUB_DATA);
915 return;
918 if (pointer_needs_unmarshaling) {
919 if (attr & RPC_FC_P_DEREF) {
920 if (!*pPointer || fMustAlloc)
921 *pPointer = NdrAllocate(pStubMsg, sizeof(void *));
922 pPointer = *(unsigned char***)pPointer;
923 TRACE("deref => %p\n", pPointer);
925 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
926 if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
927 else FIXME("no unmarshaller for data type=%02x\n", *desc);
929 if (type == RPC_FC_FP)
930 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
931 *pPointer);
934 TRACE("pointer=%p\n", *pPointer);
937 /***********************************************************************
938 * PointerBufferSize [internal]
940 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
941 unsigned char *Pointer,
942 PFORMAT_STRING pFormat)
944 unsigned type = pFormat[0], attr = pFormat[1];
945 PFORMAT_STRING desc;
946 NDR_BUFFERSIZE m;
947 int pointer_needs_sizing;
948 ULONG pointer_id;
950 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
951 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
952 pFormat += 2;
953 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
954 else desc = pFormat + *(const SHORT*)pFormat;
956 switch (type) {
957 case RPC_FC_RP: /* ref pointer (always non-null) */
958 break;
959 case RPC_FC_OP:
960 case RPC_FC_UP:
961 /* NULL pointer has no further representation */
962 if (!Pointer)
963 return;
964 break;
965 case RPC_FC_FP:
966 pointer_needs_sizing = !NdrFullPointerQueryPointer(
967 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
968 if (!pointer_needs_sizing)
969 return;
970 break;
971 default:
972 FIXME("unhandled ptr type=%02x\n", type);
973 RpcRaiseException(RPC_X_BAD_STUB_DATA);
974 return;
977 if (attr & RPC_FC_P_DEREF) {
978 Pointer = *(unsigned char**)Pointer;
979 TRACE("deref => %p\n", Pointer);
982 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
983 if (m) m(pStubMsg, Pointer, desc);
984 else FIXME("no buffersizer for data type=%02x\n", *desc);
987 /***********************************************************************
988 * PointerMemorySize [internal]
990 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
991 unsigned char *Buffer,
992 PFORMAT_STRING pFormat)
994 unsigned type = pFormat[0], attr = pFormat[1];
995 PFORMAT_STRING desc;
996 NDR_MEMORYSIZE m;
998 FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat);
999 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1000 pFormat += 2;
1001 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1002 else desc = pFormat + *(const SHORT*)pFormat;
1004 switch (type) {
1005 case RPC_FC_RP: /* ref pointer (always non-null) */
1006 break;
1007 default:
1008 FIXME("unhandled ptr type=%02x\n", type);
1009 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1012 if (attr & RPC_FC_P_DEREF) {
1013 TRACE("deref\n");
1016 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1017 if (m) m(pStubMsg, desc);
1018 else FIXME("no memorysizer for data type=%02x\n", *desc);
1020 return 0;
1023 /***********************************************************************
1024 * PointerFree [internal]
1026 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1027 unsigned char *Pointer,
1028 PFORMAT_STRING pFormat)
1030 unsigned type = pFormat[0], attr = pFormat[1];
1031 PFORMAT_STRING desc;
1032 NDR_FREE m;
1034 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1035 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1036 if (attr & RPC_FC_P_DONTFREE) return;
1037 pFormat += 2;
1038 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1039 else desc = pFormat + *(const SHORT*)pFormat;
1041 if (!Pointer) return;
1043 if (type == RPC_FC_FP) {
1044 int pointer_needs_freeing = NdrFullPointerFree(
1045 pStubMsg->FullPtrXlatTables, Pointer);
1046 if (!pointer_needs_freeing)
1047 return;
1050 if (attr & RPC_FC_P_DEREF) {
1051 Pointer = *(unsigned char**)Pointer;
1052 TRACE("deref => %p\n", Pointer);
1055 m = NdrFreer[*desc & NDR_TABLE_MASK];
1056 if (m) m(pStubMsg, Pointer, desc);
1058 /* hmm... is this sensible?
1059 * perhaps we should check if the memory comes from NdrAllocate,
1060 * and deallocate only if so - checking if the pointer is between
1061 * BufferStart and BufferEnd is probably no good since the buffer
1062 * may be reallocated when the server wants to marshal the reply */
1063 switch (*desc) {
1064 case RPC_FC_BOGUS_STRUCT:
1065 case RPC_FC_BOGUS_ARRAY:
1066 case RPC_FC_USER_MARSHAL:
1067 case RPC_FC_CARRAY:
1068 case RPC_FC_CVARRAY:
1069 break;
1070 default:
1071 FIXME("unhandled data type=%02x\n", *desc);
1072 break;
1073 case RPC_FC_C_CSTRING:
1074 case RPC_FC_C_WSTRING:
1075 if (pStubMsg->ReuseBuffer) goto notfree;
1076 break;
1077 case RPC_FC_IP:
1078 goto notfree;
1081 if (attr & RPC_FC_P_ONSTACK) {
1082 TRACE("not freeing stack ptr %p\n", Pointer);
1083 return;
1085 TRACE("freeing %p\n", Pointer);
1086 NdrFree(pStubMsg, Pointer);
1087 return;
1088 notfree:
1089 TRACE("not freeing %p\n", Pointer);
1092 /***********************************************************************
1093 * EmbeddedPointerMarshall
1095 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1096 unsigned char *pMemory,
1097 PFORMAT_STRING pFormat)
1099 unsigned char *Mark = pStubMsg->BufferMark;
1100 unsigned long Offset = pStubMsg->Offset;
1101 unsigned ofs, rep, count, stride, xofs;
1102 unsigned i;
1104 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1106 if (*pFormat != RPC_FC_PP) return NULL;
1107 pFormat += 2;
1109 while (pFormat[0] != RPC_FC_END) {
1110 switch (pFormat[0]) {
1111 default:
1112 FIXME("unknown repeat type %d\n", pFormat[0]);
1113 case RPC_FC_NO_REPEAT:
1114 rep = 1;
1115 stride = 0;
1116 ofs = 0;
1117 count = 1;
1118 xofs = 0;
1119 pFormat += 2;
1120 break;
1121 case RPC_FC_FIXED_REPEAT:
1122 rep = *(const WORD*)&pFormat[2];
1123 stride = *(const WORD*)&pFormat[4];
1124 ofs = *(const WORD*)&pFormat[6];
1125 count = *(const WORD*)&pFormat[8];
1126 xofs = 0;
1127 pFormat += 10;
1128 break;
1129 case RPC_FC_VARIABLE_REPEAT:
1130 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1131 stride = *(const WORD*)&pFormat[2];
1132 ofs = *(const WORD*)&pFormat[4];
1133 count = *(const WORD*)&pFormat[6];
1134 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1135 pFormat += 8;
1136 break;
1138 for (i = 0; i < rep; i++) {
1139 PFORMAT_STRING info = pFormat;
1140 unsigned char *membase = pMemory + ofs + (i * stride);
1141 unsigned char *bufbase = Mark + ofs + (i * stride);
1142 unsigned u;
1144 for (u=0; u<count; u++,info+=8) {
1145 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1146 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1147 unsigned char *saved_memory = pStubMsg->Memory;
1149 pStubMsg->Memory = pMemory;
1150 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1151 pStubMsg->Memory = saved_memory;
1154 pFormat += 8 * count;
1157 STD_OVERFLOW_CHECK(pStubMsg);
1159 return NULL;
1162 /***********************************************************************
1163 * EmbeddedPointerUnmarshall
1165 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1166 unsigned char **ppMemory,
1167 PFORMAT_STRING pFormat,
1168 unsigned char fMustAlloc)
1170 unsigned char *Mark = pStubMsg->BufferMark;
1171 unsigned long Offset = pStubMsg->Offset;
1172 unsigned ofs, rep, count, stride, xofs;
1173 unsigned i;
1175 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1177 if (*pFormat != RPC_FC_PP) return NULL;
1178 pFormat += 2;
1180 while (pFormat[0] != RPC_FC_END) {
1181 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1182 switch (pFormat[0]) {
1183 default:
1184 FIXME("unknown repeat type %d\n", pFormat[0]);
1185 case RPC_FC_NO_REPEAT:
1186 rep = 1;
1187 stride = 0;
1188 ofs = 0;
1189 count = 1;
1190 xofs = 0;
1191 pFormat += 2;
1192 break;
1193 case RPC_FC_FIXED_REPEAT:
1194 rep = *(const WORD*)&pFormat[2];
1195 stride = *(const WORD*)&pFormat[4];
1196 ofs = *(const WORD*)&pFormat[6];
1197 count = *(const WORD*)&pFormat[8];
1198 xofs = 0;
1199 pFormat += 10;
1200 break;
1201 case RPC_FC_VARIABLE_REPEAT:
1202 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1203 stride = *(const WORD*)&pFormat[2];
1204 ofs = *(const WORD*)&pFormat[4];
1205 count = *(const WORD*)&pFormat[6];
1206 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1207 pFormat += 8;
1208 break;
1210 /* ofs doesn't seem to matter in this context */
1211 for (i = 0; i < rep; i++) {
1212 PFORMAT_STRING info = pFormat;
1213 unsigned char *membase = *ppMemory + ofs + (i * stride);
1214 unsigned char *bufbase = Mark + ofs + (i * stride);
1215 unsigned u;
1217 for (u=0; u<count; u++,info+=8) {
1218 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1219 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1220 PointerUnmarshall(pStubMsg, bufptr, (unsigned char**)memptr, info+4, TRUE);
1223 pFormat += 8 * count;
1226 return NULL;
1229 /***********************************************************************
1230 * EmbeddedPointerBufferSize
1232 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1233 unsigned char *pMemory,
1234 PFORMAT_STRING pFormat)
1236 unsigned long Offset = pStubMsg->Offset;
1237 unsigned ofs, rep, count, stride, xofs;
1238 unsigned i;
1240 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1242 if (pStubMsg->IgnoreEmbeddedPointers) return;
1244 if (*pFormat != RPC_FC_PP) return;
1245 pFormat += 2;
1247 while (pFormat[0] != RPC_FC_END) {
1248 switch (pFormat[0]) {
1249 default:
1250 FIXME("unknown repeat type %d\n", pFormat[0]);
1251 case RPC_FC_NO_REPEAT:
1252 rep = 1;
1253 stride = 0;
1254 ofs = 0;
1255 count = 1;
1256 xofs = 0;
1257 pFormat += 2;
1258 break;
1259 case RPC_FC_FIXED_REPEAT:
1260 rep = *(const WORD*)&pFormat[2];
1261 stride = *(const WORD*)&pFormat[4];
1262 ofs = *(const WORD*)&pFormat[6];
1263 count = *(const WORD*)&pFormat[8];
1264 xofs = 0;
1265 pFormat += 10;
1266 break;
1267 case RPC_FC_VARIABLE_REPEAT:
1268 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1269 stride = *(const WORD*)&pFormat[2];
1270 ofs = *(const WORD*)&pFormat[4];
1271 count = *(const WORD*)&pFormat[6];
1272 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1273 pFormat += 8;
1274 break;
1276 for (i = 0; i < rep; i++) {
1277 PFORMAT_STRING info = pFormat;
1278 unsigned char *membase = pMemory + ofs + (i * stride);
1279 unsigned u;
1281 for (u=0; u<count; u++,info+=8) {
1282 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1283 unsigned char *saved_memory = pStubMsg->Memory;
1285 pStubMsg->Memory = pMemory;
1286 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1287 pStubMsg->Memory = saved_memory;
1290 pFormat += 8 * count;
1294 /***********************************************************************
1295 * EmbeddedPointerMemorySize [internal]
1297 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1298 PFORMAT_STRING pFormat)
1300 unsigned long Offset = pStubMsg->Offset;
1301 unsigned char *Mark = pStubMsg->BufferMark;
1302 unsigned ofs, rep, count, stride, xofs;
1303 unsigned i;
1305 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1307 if (*pFormat != RPC_FC_PP) return 0;
1308 pFormat += 2;
1310 while (pFormat[0] != RPC_FC_END) {
1311 switch (pFormat[0]) {
1312 default:
1313 FIXME("unknown repeat type %d\n", pFormat[0]);
1314 case RPC_FC_NO_REPEAT:
1315 rep = 1;
1316 stride = 0;
1317 ofs = 0;
1318 count = 1;
1319 xofs = 0;
1320 pFormat += 2;
1321 break;
1322 case RPC_FC_FIXED_REPEAT:
1323 rep = *(const WORD*)&pFormat[2];
1324 stride = *(const WORD*)&pFormat[4];
1325 ofs = *(const WORD*)&pFormat[6];
1326 count = *(const WORD*)&pFormat[8];
1327 xofs = 0;
1328 pFormat += 10;
1329 break;
1330 case RPC_FC_VARIABLE_REPEAT:
1331 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1332 stride = *(const WORD*)&pFormat[2];
1333 ofs = *(const WORD*)&pFormat[4];
1334 count = *(const WORD*)&pFormat[6];
1335 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1336 pFormat += 8;
1337 break;
1339 /* ofs doesn't seem to matter in this context */
1340 for (i = 0; i < rep; i++) {
1341 PFORMAT_STRING info = pFormat;
1342 unsigned char *bufbase = Mark + ofs + (i * stride);
1343 unsigned u;
1344 for (u=0; u<count; u++,info+=8) {
1345 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1346 PointerMemorySize(pStubMsg, bufptr, info+4);
1349 pFormat += 8 * count;
1352 return 0;
1355 /***********************************************************************
1356 * EmbeddedPointerFree [internal]
1358 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1359 unsigned char *pMemory,
1360 PFORMAT_STRING pFormat)
1362 unsigned long Offset = pStubMsg->Offset;
1363 unsigned ofs, rep, count, stride, xofs;
1364 unsigned i;
1366 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1367 if (*pFormat != RPC_FC_PP) return;
1368 pFormat += 2;
1370 while (pFormat[0] != RPC_FC_END) {
1371 switch (pFormat[0]) {
1372 default:
1373 FIXME("unknown repeat type %d\n", pFormat[0]);
1374 case RPC_FC_NO_REPEAT:
1375 rep = 1;
1376 stride = 0;
1377 ofs = 0;
1378 count = 1;
1379 xofs = 0;
1380 pFormat += 2;
1381 break;
1382 case RPC_FC_FIXED_REPEAT:
1383 rep = *(const WORD*)&pFormat[2];
1384 stride = *(const WORD*)&pFormat[4];
1385 ofs = *(const WORD*)&pFormat[6];
1386 count = *(const WORD*)&pFormat[8];
1387 xofs = 0;
1388 pFormat += 10;
1389 break;
1390 case RPC_FC_VARIABLE_REPEAT:
1391 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1392 stride = *(const WORD*)&pFormat[2];
1393 ofs = *(const WORD*)&pFormat[4];
1394 count = *(const WORD*)&pFormat[6];
1395 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1396 pFormat += 8;
1397 break;
1399 for (i = 0; i < rep; i++) {
1400 PFORMAT_STRING info = pFormat;
1401 unsigned char *membase = pMemory + (i * stride);
1402 unsigned u;
1404 for (u=0; u<count; u++,info+=8) {
1405 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1406 unsigned char *saved_memory = pStubMsg->Memory;
1408 pStubMsg->Memory = pMemory;
1409 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1410 pStubMsg->Memory = saved_memory;
1413 pFormat += 8 * count;
1417 /***********************************************************************
1418 * NdrPointerMarshall [RPCRT4.@]
1420 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1421 unsigned char *pMemory,
1422 PFORMAT_STRING pFormat)
1424 unsigned char *Buffer;
1426 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1428 /* incremement the buffer here instead of in PointerMarshall,
1429 * as that is used by embedded pointers which already handle the incrementing
1430 * the buffer, and shouldn't write any additional pointer data to the wire */
1431 if (*pFormat != RPC_FC_RP)
1433 ALIGN_POINTER(pStubMsg->Buffer, 4);
1434 Buffer = pStubMsg->Buffer;
1435 pStubMsg->Buffer += 4;
1437 else
1438 Buffer = pStubMsg->Buffer;
1440 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1442 STD_OVERFLOW_CHECK(pStubMsg);
1444 return NULL;
1447 /***********************************************************************
1448 * NdrPointerUnmarshall [RPCRT4.@]
1450 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1451 unsigned char **ppMemory,
1452 PFORMAT_STRING pFormat,
1453 unsigned char fMustAlloc)
1455 unsigned char *Buffer;
1457 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1459 /* incremement the buffer here instead of in PointerUnmarshall,
1460 * as that is used by embedded pointers which already handle the incrementing
1461 * the buffer, and shouldn't read any additional pointer data from the
1462 * buffer */
1463 if (*pFormat != RPC_FC_RP)
1465 ALIGN_POINTER(pStubMsg->Buffer, 4);
1466 Buffer = pStubMsg->Buffer;
1467 pStubMsg->Buffer += 4;
1469 else
1470 Buffer = pStubMsg->Buffer;
1472 PointerUnmarshall(pStubMsg, Buffer, ppMemory, pFormat, fMustAlloc);
1474 return NULL;
1477 /***********************************************************************
1478 * NdrPointerBufferSize [RPCRT4.@]
1480 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1481 unsigned char *pMemory,
1482 PFORMAT_STRING pFormat)
1484 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1486 /* incremement the buffer length here instead of in PointerBufferSize,
1487 * as that is used by embedded pointers which already handle the buffer
1488 * length, and shouldn't write anything more to the wire */
1489 if (*pFormat != RPC_FC_RP)
1491 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1492 pStubMsg->BufferLength += 4;
1495 PointerBufferSize(pStubMsg, pMemory, pFormat);
1498 /***********************************************************************
1499 * NdrPointerMemorySize [RPCRT4.@]
1501 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1502 PFORMAT_STRING pFormat)
1504 /* unsigned size = *(LPWORD)(pFormat+2); */
1505 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1506 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1507 return 0;
1510 /***********************************************************************
1511 * NdrPointerFree [RPCRT4.@]
1513 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1514 unsigned char *pMemory,
1515 PFORMAT_STRING pFormat)
1517 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1518 PointerFree(pStubMsg, pMemory, pFormat);
1521 /***********************************************************************
1522 * NdrSimpleTypeMarshall [RPCRT4.@]
1524 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1525 unsigned char FormatChar )
1527 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1530 /***********************************************************************
1531 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1533 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1534 unsigned char FormatChar )
1536 NdrBaseTypeUnmarshall(pStubMsg, &pMemory, &FormatChar, 0);
1539 /***********************************************************************
1540 * NdrSimpleStructMarshall [RPCRT4.@]
1542 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1543 unsigned char *pMemory,
1544 PFORMAT_STRING pFormat)
1546 unsigned size = *(const WORD*)(pFormat+2);
1547 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1549 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1551 memcpy(pStubMsg->Buffer, pMemory, size);
1552 pStubMsg->BufferMark = pStubMsg->Buffer;
1553 pStubMsg->Buffer += size;
1555 if (pFormat[0] != RPC_FC_STRUCT)
1556 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1558 STD_OVERFLOW_CHECK(pStubMsg);
1560 return NULL;
1563 /***********************************************************************
1564 * NdrSimpleStructUnmarshall [RPCRT4.@]
1566 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1567 unsigned char **ppMemory,
1568 PFORMAT_STRING pFormat,
1569 unsigned char fMustAlloc)
1571 unsigned size = *(const WORD*)(pFormat+2);
1572 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1574 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1576 if (fMustAlloc) {
1577 *ppMemory = NdrAllocate(pStubMsg, size);
1578 memcpy(*ppMemory, pStubMsg->Buffer, size);
1579 } else {
1580 if (!pStubMsg->IsClient && !*ppMemory)
1581 /* for servers, we just point straight into the RPC buffer */
1582 *ppMemory = pStubMsg->Buffer;
1583 else
1584 /* for clients, memory should be provided by caller */
1585 memcpy(*ppMemory, pStubMsg->Buffer, size);
1588 pStubMsg->BufferMark = pStubMsg->Buffer;
1589 pStubMsg->Buffer += size;
1591 if (pFormat[0] != RPC_FC_STRUCT)
1592 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat+4, fMustAlloc);
1594 return NULL;
1597 /***********************************************************************
1598 * NdrSimpleStructBufferSize [RPCRT4.@]
1600 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1601 unsigned char *pMemory,
1602 PFORMAT_STRING pFormat)
1604 unsigned size = *(const WORD*)(pFormat+2);
1605 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1607 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1609 pStubMsg->BufferLength += size;
1610 if (pFormat[0] != RPC_FC_STRUCT)
1611 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1614 /***********************************************************************
1615 * NdrSimpleStructMemorySize [RPCRT4.@]
1617 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1618 PFORMAT_STRING pFormat)
1620 unsigned short size = *(const WORD *)(pFormat+2);
1622 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1624 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1625 pStubMsg->MemorySize += size;
1626 pStubMsg->Buffer += size;
1628 if (pFormat[0] != RPC_FC_STRUCT)
1629 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1630 return size;
1633 /***********************************************************************
1634 * NdrSimpleStructFree [RPCRT4.@]
1636 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1637 unsigned char *pMemory,
1638 PFORMAT_STRING pFormat)
1640 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1641 if (pFormat[0] != RPC_FC_STRUCT)
1642 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1646 static unsigned long EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg,
1647 PFORMAT_STRING pFormat)
1649 switch (*pFormat) {
1650 case RPC_FC_STRUCT:
1651 case RPC_FC_PSTRUCT:
1652 case RPC_FC_CSTRUCT:
1653 case RPC_FC_BOGUS_STRUCT:
1654 case RPC_FC_SMFARRAY:
1655 case RPC_FC_SMVARRAY:
1656 return *(const WORD*)&pFormat[2];
1657 case RPC_FC_USER_MARSHAL:
1658 return *(const WORD*)&pFormat[4];
1659 case RPC_FC_NON_ENCAPSULATED_UNION:
1660 pFormat += 2;
1661 if (pStubMsg->fHasNewCorrDesc)
1662 pFormat += 6;
1663 else
1664 pFormat += 4;
1666 pFormat += *(const SHORT*)pFormat;
1667 return *(const SHORT*)pFormat;
1668 case RPC_FC_IP:
1669 return sizeof(void *);
1670 default:
1671 FIXME("unhandled embedded type %02x\n", *pFormat);
1673 return 0;
1677 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1678 PFORMAT_STRING pFormat)
1680 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1682 if (!m)
1684 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1685 return 0;
1688 return m(pStubMsg, pFormat);
1692 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1693 unsigned char *pMemory,
1694 PFORMAT_STRING pFormat,
1695 PFORMAT_STRING pPointer)
1697 PFORMAT_STRING desc;
1698 NDR_MARSHALL m;
1699 unsigned long size;
1701 while (*pFormat != RPC_FC_END) {
1702 switch (*pFormat) {
1703 case RPC_FC_BYTE:
1704 case RPC_FC_CHAR:
1705 case RPC_FC_SMALL:
1706 case RPC_FC_USMALL:
1707 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
1708 memcpy(pStubMsg->Buffer, pMemory, 1);
1709 pStubMsg->Buffer += 1;
1710 pMemory += 1;
1711 break;
1712 case RPC_FC_WCHAR:
1713 case RPC_FC_SHORT:
1714 case RPC_FC_USHORT:
1715 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1716 memcpy(pStubMsg->Buffer, pMemory, 2);
1717 pStubMsg->Buffer += 2;
1718 pMemory += 2;
1719 break;
1720 case RPC_FC_LONG:
1721 case RPC_FC_ULONG:
1722 case RPC_FC_ENUM32:
1723 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
1724 memcpy(pStubMsg->Buffer, pMemory, 4);
1725 pStubMsg->Buffer += 4;
1726 pMemory += 4;
1727 break;
1728 case RPC_FC_HYPER:
1729 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1730 memcpy(pStubMsg->Buffer, pMemory, 8);
1731 pStubMsg->Buffer += 8;
1732 pMemory += 8;
1733 break;
1734 case RPC_FC_POINTER:
1735 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1736 NdrPointerMarshall(pStubMsg, *(unsigned char**)pMemory, pPointer);
1737 pPointer += 4;
1738 pMemory += 4;
1739 break;
1740 case RPC_FC_ALIGNM4:
1741 ALIGN_POINTER(pMemory, 4);
1742 break;
1743 case RPC_FC_ALIGNM8:
1744 ALIGN_POINTER(pMemory, 8);
1745 break;
1746 case RPC_FC_STRUCTPAD1:
1747 case RPC_FC_STRUCTPAD2:
1748 case RPC_FC_STRUCTPAD3:
1749 case RPC_FC_STRUCTPAD4:
1750 case RPC_FC_STRUCTPAD5:
1751 case RPC_FC_STRUCTPAD6:
1752 case RPC_FC_STRUCTPAD7:
1753 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1754 break;
1755 case RPC_FC_EMBEDDED_COMPLEX:
1756 pMemory += pFormat[1];
1757 pFormat += 2;
1758 desc = pFormat + *(const SHORT*)pFormat;
1759 size = EmbeddedComplexSize(pStubMsg, desc);
1760 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1761 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1762 if (m) m(pStubMsg, pMemory, desc);
1763 else FIXME("no marshaller for embedded type %02x\n", *desc);
1764 pMemory += size;
1765 pFormat += 2;
1766 continue;
1767 case RPC_FC_PAD:
1768 break;
1769 default:
1770 FIXME("unhandled format 0x%02x\n", *pFormat);
1772 pFormat++;
1775 return pMemory;
1778 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1779 unsigned char *pMemory,
1780 PFORMAT_STRING pFormat,
1781 PFORMAT_STRING pPointer)
1783 PFORMAT_STRING desc;
1784 NDR_UNMARSHALL m;
1785 unsigned long size;
1787 while (*pFormat != RPC_FC_END) {
1788 switch (*pFormat) {
1789 case RPC_FC_BYTE:
1790 case RPC_FC_CHAR:
1791 case RPC_FC_SMALL:
1792 case RPC_FC_USMALL:
1793 memcpy(pMemory, pStubMsg->Buffer, 1);
1794 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
1795 pStubMsg->Buffer += 1;
1796 pMemory += 1;
1797 break;
1798 case RPC_FC_WCHAR:
1799 case RPC_FC_SHORT:
1800 case RPC_FC_USHORT:
1801 memcpy(pMemory, pStubMsg->Buffer, 2);
1802 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1803 pStubMsg->Buffer += 2;
1804 pMemory += 2;
1805 break;
1806 case RPC_FC_LONG:
1807 case RPC_FC_ULONG:
1808 case RPC_FC_ENUM32:
1809 memcpy(pMemory, pStubMsg->Buffer, 4);
1810 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
1811 pStubMsg->Buffer += 4;
1812 pMemory += 4;
1813 break;
1814 case RPC_FC_HYPER:
1815 memcpy(pMemory, pStubMsg->Buffer, 8);
1816 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1817 pStubMsg->Buffer += 8;
1818 pMemory += 8;
1819 break;
1820 case RPC_FC_POINTER:
1821 TRACE("pointer => %p\n", pMemory);
1822 NdrPointerUnmarshall(pStubMsg, (unsigned char**)pMemory, pPointer, TRUE);
1823 pPointer += 4;
1824 pMemory += 4;
1825 break;
1826 case RPC_FC_ALIGNM4:
1827 ALIGN_POINTER(pMemory, 4);
1828 break;
1829 case RPC_FC_ALIGNM8:
1830 ALIGN_POINTER(pMemory, 8);
1831 break;
1832 case RPC_FC_STRUCTPAD1:
1833 case RPC_FC_STRUCTPAD2:
1834 case RPC_FC_STRUCTPAD3:
1835 case RPC_FC_STRUCTPAD4:
1836 case RPC_FC_STRUCTPAD5:
1837 case RPC_FC_STRUCTPAD6:
1838 case RPC_FC_STRUCTPAD7:
1839 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1840 break;
1841 case RPC_FC_EMBEDDED_COMPLEX:
1842 pMemory += pFormat[1];
1843 pFormat += 2;
1844 desc = pFormat + *(const SHORT*)pFormat;
1845 size = EmbeddedComplexSize(pStubMsg, desc);
1846 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
1847 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1848 memset(pMemory, 0, size); /* just in case */
1849 if (m) m(pStubMsg, &pMemory, desc, FALSE);
1850 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
1851 pMemory += size;
1852 pFormat += 2;
1853 continue;
1854 case RPC_FC_PAD:
1855 break;
1856 default:
1857 FIXME("unhandled format %d\n", *pFormat);
1859 pFormat++;
1862 return pMemory;
1865 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1866 unsigned char *pMemory,
1867 PFORMAT_STRING pFormat,
1868 PFORMAT_STRING pPointer)
1870 PFORMAT_STRING desc;
1871 NDR_BUFFERSIZE m;
1872 unsigned long size;
1874 while (*pFormat != RPC_FC_END) {
1875 switch (*pFormat) {
1876 case RPC_FC_BYTE:
1877 case RPC_FC_CHAR:
1878 case RPC_FC_SMALL:
1879 case RPC_FC_USMALL:
1880 pStubMsg->BufferLength += 1;
1881 pMemory += 1;
1882 break;
1883 case RPC_FC_WCHAR:
1884 case RPC_FC_SHORT:
1885 case RPC_FC_USHORT:
1886 pStubMsg->BufferLength += 2;
1887 pMemory += 2;
1888 break;
1889 case RPC_FC_LONG:
1890 case RPC_FC_ULONG:
1891 case RPC_FC_ENUM32:
1892 pStubMsg->BufferLength += 4;
1893 pMemory += 4;
1894 break;
1895 case RPC_FC_HYPER:
1896 pStubMsg->BufferLength += 8;
1897 pMemory += 8;
1898 break;
1899 case RPC_FC_POINTER:
1900 NdrPointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
1901 pPointer += 4;
1902 pMemory += 4;
1903 break;
1904 case RPC_FC_ALIGNM4:
1905 ALIGN_POINTER(pMemory, 4);
1906 break;
1907 case RPC_FC_ALIGNM8:
1908 ALIGN_POINTER(pMemory, 8);
1909 break;
1910 case RPC_FC_STRUCTPAD1:
1911 case RPC_FC_STRUCTPAD2:
1912 case RPC_FC_STRUCTPAD3:
1913 case RPC_FC_STRUCTPAD4:
1914 case RPC_FC_STRUCTPAD5:
1915 case RPC_FC_STRUCTPAD6:
1916 case RPC_FC_STRUCTPAD7:
1917 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1918 break;
1919 case RPC_FC_EMBEDDED_COMPLEX:
1920 pMemory += pFormat[1];
1921 pFormat += 2;
1922 desc = pFormat + *(const SHORT*)pFormat;
1923 size = EmbeddedComplexSize(pStubMsg, desc);
1924 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1925 if (m) m(pStubMsg, pMemory, desc);
1926 else FIXME("no buffersizer for embedded type %02x\n", *desc);
1927 pMemory += size;
1928 pFormat += 2;
1929 continue;
1930 case RPC_FC_PAD:
1931 break;
1932 default:
1933 FIXME("unhandled format 0x%02x\n", *pFormat);
1935 pFormat++;
1938 return pMemory;
1941 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
1942 unsigned char *pMemory,
1943 PFORMAT_STRING pFormat,
1944 PFORMAT_STRING pPointer)
1946 PFORMAT_STRING desc;
1947 NDR_FREE m;
1948 unsigned long size;
1950 while (*pFormat != RPC_FC_END) {
1951 switch (*pFormat) {
1952 case RPC_FC_BYTE:
1953 case RPC_FC_CHAR:
1954 case RPC_FC_SMALL:
1955 case RPC_FC_USMALL:
1956 pMemory += 1;
1957 break;
1958 case RPC_FC_WCHAR:
1959 case RPC_FC_SHORT:
1960 case RPC_FC_USHORT:
1961 pMemory += 2;
1962 break;
1963 case RPC_FC_LONG:
1964 case RPC_FC_ULONG:
1965 case RPC_FC_ENUM32:
1966 pMemory += 4;
1967 break;
1968 case RPC_FC_HYPER:
1969 pMemory += 8;
1970 break;
1971 case RPC_FC_POINTER:
1972 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
1973 pPointer += 4;
1974 pMemory += 4;
1975 break;
1976 case RPC_FC_ALIGNM4:
1977 ALIGN_POINTER(pMemory, 4);
1978 break;
1979 case RPC_FC_ALIGNM8:
1980 ALIGN_POINTER(pMemory, 8);
1981 break;
1982 case RPC_FC_STRUCTPAD1:
1983 case RPC_FC_STRUCTPAD2:
1984 case RPC_FC_STRUCTPAD3:
1985 case RPC_FC_STRUCTPAD4:
1986 case RPC_FC_STRUCTPAD5:
1987 case RPC_FC_STRUCTPAD6:
1988 case RPC_FC_STRUCTPAD7:
1989 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1990 break;
1991 case RPC_FC_EMBEDDED_COMPLEX:
1992 pMemory += pFormat[1];
1993 pFormat += 2;
1994 desc = pFormat + *(const SHORT*)pFormat;
1995 size = EmbeddedComplexSize(pStubMsg, desc);
1996 m = NdrFreer[*desc & NDR_TABLE_MASK];
1997 if (m) m(pStubMsg, pMemory, desc);
1998 else FIXME("no freer for embedded type %02x\n", *desc);
1999 pMemory += size;
2000 pFormat += 2;
2001 continue;
2002 case RPC_FC_PAD:
2003 break;
2004 default:
2005 FIXME("unhandled format 0x%02x\n", *pFormat);
2007 pFormat++;
2010 return pMemory;
2013 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2014 PFORMAT_STRING pFormat)
2016 PFORMAT_STRING desc;
2017 unsigned long size = 0;
2019 while (*pFormat != RPC_FC_END) {
2020 switch (*pFormat) {
2021 case RPC_FC_BYTE:
2022 case RPC_FC_CHAR:
2023 case RPC_FC_SMALL:
2024 case RPC_FC_USMALL:
2025 size += 1;
2026 pStubMsg->Buffer += 1;
2027 break;
2028 case RPC_FC_WCHAR:
2029 case RPC_FC_SHORT:
2030 case RPC_FC_USHORT:
2031 size += 2;
2032 pStubMsg->Buffer += 2;
2033 break;
2034 case RPC_FC_LONG:
2035 case RPC_FC_ULONG:
2036 case RPC_FC_ENUM32:
2037 size += 4;
2038 pStubMsg->Buffer += 4;
2039 break;
2040 case RPC_FC_HYPER:
2041 size += 8;
2042 pStubMsg->Buffer += 8;
2043 break;
2044 case RPC_FC_POINTER:
2045 size += 4;
2046 pStubMsg->Buffer += 4;
2047 break;
2048 case RPC_FC_ALIGNM4:
2049 ALIGN_LENGTH(size, 4);
2050 ALIGN_POINTER(pStubMsg->Buffer, 4);
2051 break;
2052 case RPC_FC_ALIGNM8:
2053 ALIGN_LENGTH(size, 8);
2054 ALIGN_POINTER(pStubMsg->Buffer, 8);
2055 break;
2056 case RPC_FC_STRUCTPAD1:
2057 case RPC_FC_STRUCTPAD2:
2058 case RPC_FC_STRUCTPAD3:
2059 case RPC_FC_STRUCTPAD4:
2060 case RPC_FC_STRUCTPAD5:
2061 case RPC_FC_STRUCTPAD6:
2062 case RPC_FC_STRUCTPAD7:
2063 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2064 break;
2065 case RPC_FC_EMBEDDED_COMPLEX:
2066 size += pFormat[1];
2067 pFormat += 2;
2068 desc = pFormat + *(const SHORT*)pFormat;
2069 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2070 pFormat += 2;
2071 continue;
2072 case RPC_FC_PAD:
2073 break;
2074 default:
2075 FIXME("unhandled format 0x%02x\n", *pFormat);
2077 pFormat++;
2080 return size;
2083 /***********************************************************************
2084 * NdrComplexStructMarshall [RPCRT4.@]
2086 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2087 unsigned char *pMemory,
2088 PFORMAT_STRING pFormat)
2090 PFORMAT_STRING conf_array = NULL;
2091 PFORMAT_STRING pointer_desc = NULL;
2092 unsigned char *OldMemory = pStubMsg->Memory;
2094 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2096 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2098 pFormat += 4;
2099 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2100 pFormat += 2;
2101 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2102 pFormat += 2;
2104 pStubMsg->Memory = pMemory;
2106 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2108 if (conf_array)
2109 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2111 pStubMsg->Memory = OldMemory;
2113 STD_OVERFLOW_CHECK(pStubMsg);
2115 return NULL;
2118 /***********************************************************************
2119 * NdrComplexStructUnmarshall [RPCRT4.@]
2121 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2122 unsigned char **ppMemory,
2123 PFORMAT_STRING pFormat,
2124 unsigned char fMustAlloc)
2126 unsigned size = *(const WORD*)(pFormat+2);
2127 PFORMAT_STRING conf_array = NULL;
2128 PFORMAT_STRING pointer_desc = NULL;
2129 unsigned char *pMemory;
2131 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2133 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2135 if (fMustAlloc || !*ppMemory)
2137 *ppMemory = NdrAllocate(pStubMsg, size);
2138 memset(*ppMemory, 0, size);
2141 pFormat += 4;
2142 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2143 pFormat += 2;
2144 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2145 pFormat += 2;
2147 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2149 if (conf_array)
2150 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2152 return NULL;
2155 /***********************************************************************
2156 * NdrComplexStructBufferSize [RPCRT4.@]
2158 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2159 unsigned char *pMemory,
2160 PFORMAT_STRING pFormat)
2162 PFORMAT_STRING conf_array = NULL;
2163 PFORMAT_STRING pointer_desc = NULL;
2164 unsigned char *OldMemory = pStubMsg->Memory;
2166 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2168 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2170 pFormat += 4;
2171 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2172 pFormat += 2;
2173 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2174 pFormat += 2;
2176 pStubMsg->Memory = pMemory;
2178 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2180 if (conf_array)
2181 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2183 pStubMsg->Memory = OldMemory;
2186 /***********************************************************************
2187 * NdrComplexStructMemorySize [RPCRT4.@]
2189 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2190 PFORMAT_STRING pFormat)
2192 unsigned size = *(const WORD*)(pFormat+2);
2193 PFORMAT_STRING conf_array = NULL;
2194 PFORMAT_STRING pointer_desc = NULL;
2196 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2198 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2200 pFormat += 4;
2201 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2202 pFormat += 2;
2203 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2204 pFormat += 2;
2206 ComplexStructMemorySize(pStubMsg, pFormat);
2208 if (conf_array)
2209 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2211 return size;
2214 /***********************************************************************
2215 * NdrComplexStructFree [RPCRT4.@]
2217 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2218 unsigned char *pMemory,
2219 PFORMAT_STRING pFormat)
2221 PFORMAT_STRING conf_array = NULL;
2222 PFORMAT_STRING pointer_desc = NULL;
2223 unsigned char *OldMemory = pStubMsg->Memory;
2225 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2227 pFormat += 4;
2228 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2229 pFormat += 2;
2230 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2231 pFormat += 2;
2233 pStubMsg->Memory = pMemory;
2235 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2237 if (conf_array)
2238 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2240 pStubMsg->Memory = OldMemory;
2243 /***********************************************************************
2244 * NdrConformantArrayMarshall [RPCRT4.@]
2246 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2247 unsigned char *pMemory,
2248 PFORMAT_STRING pFormat)
2250 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2251 unsigned char alignment = pFormat[1] + 1;
2253 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2254 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2256 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2258 WriteConformance(pStubMsg);
2260 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2262 size = safe_multiply(esize, pStubMsg->MaxCount);
2263 memcpy(pStubMsg->Buffer, pMemory, size);
2264 pStubMsg->BufferMark = pStubMsg->Buffer;
2265 pStubMsg->Buffer += size;
2267 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2269 STD_OVERFLOW_CHECK(pStubMsg);
2271 return NULL;
2274 /***********************************************************************
2275 * NdrConformantArrayUnmarshall [RPCRT4.@]
2277 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2278 unsigned char **ppMemory,
2279 PFORMAT_STRING pFormat,
2280 unsigned char fMustAlloc)
2282 DWORD size, esize = *(const WORD*)(pFormat+2);
2283 unsigned char alignment = pFormat[1] + 1;
2285 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2286 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2288 pFormat = ReadConformance(pStubMsg, pFormat+4);
2290 size = safe_multiply(esize, pStubMsg->MaxCount);
2292 if (fMustAlloc || !*ppMemory)
2293 *ppMemory = NdrAllocate(pStubMsg, size);
2295 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2297 memcpy(*ppMemory, pStubMsg->Buffer, size);
2299 pStubMsg->BufferMark = pStubMsg->Buffer;
2300 pStubMsg->Buffer += size;
2302 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2304 return NULL;
2307 /***********************************************************************
2308 * NdrConformantArrayBufferSize [RPCRT4.@]
2310 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2311 unsigned char *pMemory,
2312 PFORMAT_STRING pFormat)
2314 DWORD size, esize = *(const WORD*)(pFormat+2);
2315 unsigned char alignment = pFormat[1] + 1;
2317 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2318 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2320 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2322 SizeConformance(pStubMsg);
2324 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2326 size = safe_multiply(esize, pStubMsg->MaxCount);
2327 /* conformance value plus array */
2328 pStubMsg->BufferLength += size;
2330 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2333 /***********************************************************************
2334 * NdrConformantArrayMemorySize [RPCRT4.@]
2336 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2337 PFORMAT_STRING pFormat)
2339 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2340 unsigned char alignment = pFormat[1] + 1;
2342 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2343 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2345 pFormat = ReadConformance(pStubMsg, pFormat+4);
2346 size = safe_multiply(esize, pStubMsg->MaxCount);
2347 pStubMsg->MemorySize += size;
2349 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2350 pStubMsg->BufferMark = pStubMsg->Buffer;
2351 pStubMsg->Buffer += size;
2353 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2355 return pStubMsg->MemorySize;
2358 /***********************************************************************
2359 * NdrConformantArrayFree [RPCRT4.@]
2361 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2362 unsigned char *pMemory,
2363 PFORMAT_STRING pFormat)
2365 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2366 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2368 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2370 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2374 /***********************************************************************
2375 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2377 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2378 unsigned char* pMemory,
2379 PFORMAT_STRING pFormat )
2381 ULONG bufsize;
2382 unsigned char alignment = pFormat[1] + 1;
2383 DWORD esize = *(const WORD*)(pFormat+2);
2385 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2387 if (pFormat[0] != RPC_FC_CVARRAY)
2389 ERR("invalid format type %x\n", pFormat[0]);
2390 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2391 return NULL;
2394 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2395 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2397 WriteConformance(pStubMsg);
2398 WriteVariance(pStubMsg);
2400 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2402 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2404 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
2405 pStubMsg->BufferMark = pStubMsg->Buffer;
2406 pStubMsg->Buffer += bufsize;
2408 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2410 STD_OVERFLOW_CHECK(pStubMsg);
2412 return NULL;
2416 /***********************************************************************
2417 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2419 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2420 unsigned char** ppMemory,
2421 PFORMAT_STRING pFormat,
2422 unsigned char fMustAlloc )
2424 ULONG bufsize, memsize;
2425 unsigned char alignment = pFormat[1] + 1;
2426 DWORD esize = *(const WORD*)(pFormat+2);
2428 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2430 if (pFormat[0] != RPC_FC_CVARRAY)
2432 ERR("invalid format type %x\n", pFormat[0]);
2433 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2434 return NULL;
2437 pFormat = ReadConformance(pStubMsg, pFormat+4);
2438 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2440 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2442 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2443 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2445 if (!*ppMemory || fMustAlloc)
2446 *ppMemory = NdrAllocate(pStubMsg, memsize);
2447 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
2448 pStubMsg->Buffer += bufsize;
2450 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2452 return NULL;
2456 /***********************************************************************
2457 * NdrConformantVaryingArrayFree [RPCRT4.@]
2459 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2460 unsigned char* pMemory,
2461 PFORMAT_STRING pFormat )
2463 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2465 if (pFormat[0] != RPC_FC_CVARRAY)
2467 ERR("invalid format type %x\n", pFormat[0]);
2468 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2469 return;
2472 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2473 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2475 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2479 /***********************************************************************
2480 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2482 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2483 unsigned char* pMemory, PFORMAT_STRING pFormat )
2485 unsigned char alignment = pFormat[1] + 1;
2486 DWORD esize = *(const WORD*)(pFormat+2);
2488 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2490 if (pFormat[0] != RPC_FC_CVARRAY)
2492 ERR("invalid format type %x\n", pFormat[0]);
2493 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2494 return;
2497 /* compute size */
2498 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2499 /* compute length */
2500 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2502 SizeConformance(pStubMsg);
2503 SizeVariance(pStubMsg);
2505 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2507 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
2509 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2513 /***********************************************************************
2514 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2516 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2517 PFORMAT_STRING pFormat )
2519 FIXME( "stub\n" );
2520 return 0;
2524 /***********************************************************************
2525 * NdrComplexArrayMarshall [RPCRT4.@]
2527 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2528 unsigned char *pMemory,
2529 PFORMAT_STRING pFormat)
2531 ULONG i, count, def;
2532 BOOL variance_present;
2533 unsigned char alignment;
2535 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2537 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2539 ERR("invalid format type %x\n", pFormat[0]);
2540 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2541 return NULL;
2544 alignment = pFormat[1] + 1;
2546 def = *(const WORD*)&pFormat[2];
2547 pFormat += 4;
2549 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2550 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2552 variance_present = IsConformanceOrVariancePresent(pFormat);
2553 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2554 TRACE("variance = %d\n", pStubMsg->ActualCount);
2556 WriteConformance(pStubMsg);
2557 if (variance_present)
2558 WriteVariance(pStubMsg);
2560 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2562 count = pStubMsg->ActualCount;
2563 for (i = 0; i < count; i++)
2564 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2566 STD_OVERFLOW_CHECK(pStubMsg);
2568 return NULL;
2571 /***********************************************************************
2572 * NdrComplexArrayUnmarshall [RPCRT4.@]
2574 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2575 unsigned char **ppMemory,
2576 PFORMAT_STRING pFormat,
2577 unsigned char fMustAlloc)
2579 ULONG i, count, esize, memsize;
2580 unsigned char alignment;
2581 unsigned char *pMemory;
2582 unsigned char *Buffer;
2584 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2586 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2588 ERR("invalid format type %x\n", pFormat[0]);
2589 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2590 return NULL;
2593 alignment = pFormat[1] + 1;
2595 pFormat += 4;
2597 pFormat = ReadConformance(pStubMsg, pFormat);
2598 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2600 Buffer = pStubMsg->Buffer;
2601 pStubMsg->MemorySize = 0;
2602 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2603 pStubMsg->Buffer = Buffer;
2605 /* do multiply here instead of inside if block to verify MaxCount */
2606 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2607 if (fMustAlloc || !*ppMemory)
2609 *ppMemory = NdrAllocate(pStubMsg, memsize);
2610 memset(*ppMemory, 0, memsize);
2613 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2615 pMemory = *ppMemory;
2616 count = pStubMsg->ActualCount;
2617 for (i = 0; i < count; i++)
2618 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
2620 return NULL;
2623 /***********************************************************************
2624 * NdrComplexArrayBufferSize [RPCRT4.@]
2626 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2627 unsigned char *pMemory,
2628 PFORMAT_STRING pFormat)
2630 ULONG i, count, def;
2631 unsigned char alignment;
2632 BOOL variance_present;
2634 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2636 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2638 ERR("invalid format type %x\n", pFormat[0]);
2639 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2640 return;
2643 alignment = pFormat[1] + 1;
2645 def = *(const WORD*)&pFormat[2];
2646 pFormat += 4;
2648 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2649 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2650 SizeConformance(pStubMsg);
2652 variance_present = IsConformanceOrVariancePresent(pFormat);
2653 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2654 TRACE("variance = %d\n", pStubMsg->ActualCount);
2656 if (variance_present)
2657 SizeVariance(pStubMsg);
2659 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2661 count = pStubMsg->ActualCount;
2662 for (i = 0; i < count; i++)
2663 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
2666 /***********************************************************************
2667 * NdrComplexArrayMemorySize [RPCRT4.@]
2669 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2670 PFORMAT_STRING pFormat)
2672 ULONG i, count, esize, SavedMemorySize, MemorySize;
2673 unsigned char alignment;
2674 unsigned char *Buffer;
2676 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2678 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2680 ERR("invalid format type %x\n", pFormat[0]);
2681 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2682 return 0;
2685 alignment = pFormat[1] + 1;
2687 pFormat += 4;
2689 pFormat = ReadConformance(pStubMsg, pFormat);
2690 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2692 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2694 SavedMemorySize = pStubMsg->MemorySize;
2696 Buffer = pStubMsg->Buffer;
2697 pStubMsg->MemorySize = 0;
2698 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2699 pStubMsg->Buffer = Buffer;
2701 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
2703 count = pStubMsg->ActualCount;
2704 for (i = 0; i < count; i++)
2705 ComplexStructMemorySize(pStubMsg, pFormat);
2707 pStubMsg->MemorySize = SavedMemorySize;
2709 pStubMsg->MemorySize += MemorySize;
2710 return MemorySize;
2713 /***********************************************************************
2714 * NdrComplexArrayFree [RPCRT4.@]
2716 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2717 unsigned char *pMemory,
2718 PFORMAT_STRING pFormat)
2720 ULONG i, count, def;
2722 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2724 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2726 ERR("invalid format type %x\n", pFormat[0]);
2727 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2728 return;
2731 def = *(const WORD*)&pFormat[2];
2732 pFormat += 4;
2734 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2735 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2737 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2738 TRACE("variance = %d\n", pStubMsg->ActualCount);
2740 count = pStubMsg->ActualCount;
2741 for (i = 0; i < count; i++)
2742 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2745 static ULONG UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
2747 return MAKELONG(pStubMsg->dwDestContext,
2748 pStubMsg->RpcMsg->DataRepresentation);
2751 #define USER_MARSHAL_PTR_PREFIX \
2752 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
2753 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
2755 /***********************************************************************
2756 * NdrUserMarshalMarshall [RPCRT4.@]
2758 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2759 unsigned char *pMemory,
2760 PFORMAT_STRING pFormat)
2762 unsigned flags = pFormat[1];
2763 unsigned index = *(const WORD*)&pFormat[2];
2764 ULONG uflag = UserMarshalFlags(pStubMsg);
2765 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2766 TRACE("index=%d\n", index);
2768 if (flags & USER_MARSHAL_POINTER)
2770 ALIGN_POINTER(pStubMsg->Buffer, 4);
2771 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
2772 pStubMsg->Buffer += 4;
2773 ALIGN_POINTER(pStubMsg->Buffer, 8);
2775 else
2776 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2778 pStubMsg->Buffer =
2779 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
2780 &uflag, pStubMsg->Buffer, pMemory);
2782 STD_OVERFLOW_CHECK(pStubMsg);
2784 return NULL;
2787 /***********************************************************************
2788 * NdrUserMarshalUnmarshall [RPCRT4.@]
2790 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2791 unsigned char **ppMemory,
2792 PFORMAT_STRING pFormat,
2793 unsigned char fMustAlloc)
2795 unsigned flags = pFormat[1];
2796 unsigned index = *(const WORD*)&pFormat[2];
2797 DWORD memsize = *(const WORD*)&pFormat[4];
2798 ULONG uflag = UserMarshalFlags(pStubMsg);
2799 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2800 TRACE("index=%d\n", index);
2802 if (flags & USER_MARSHAL_POINTER)
2804 ALIGN_POINTER(pStubMsg->Buffer, 4);
2805 /* skip pointer prefix */
2806 pStubMsg->Buffer += 4;
2807 ALIGN_POINTER(pStubMsg->Buffer, 8);
2809 else
2810 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2812 if (fMustAlloc || !*ppMemory)
2813 *ppMemory = NdrAllocate(pStubMsg, memsize);
2815 pStubMsg->Buffer =
2816 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
2817 &uflag, pStubMsg->Buffer, *ppMemory);
2819 return NULL;
2822 /***********************************************************************
2823 * NdrUserMarshalBufferSize [RPCRT4.@]
2825 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2826 unsigned char *pMemory,
2827 PFORMAT_STRING pFormat)
2829 unsigned flags = pFormat[1];
2830 unsigned index = *(const WORD*)&pFormat[2];
2831 DWORD bufsize = *(const WORD*)&pFormat[6];
2832 ULONG uflag = UserMarshalFlags(pStubMsg);
2833 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2834 TRACE("index=%d\n", index);
2836 if (flags & USER_MARSHAL_POINTER)
2838 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2839 /* skip pointer prefix */
2840 pStubMsg->BufferLength += 4;
2841 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
2843 else
2844 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
2846 if (bufsize) {
2847 TRACE("size=%d\n", bufsize);
2848 pStubMsg->BufferLength += bufsize;
2849 return;
2852 pStubMsg->BufferLength =
2853 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
2854 &uflag, pStubMsg->BufferLength, pMemory);
2857 /***********************************************************************
2858 * NdrUserMarshalMemorySize [RPCRT4.@]
2860 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2861 PFORMAT_STRING pFormat)
2863 unsigned flags = pFormat[1];
2864 unsigned index = *(const WORD*)&pFormat[2];
2865 DWORD memsize = *(const WORD*)&pFormat[4];
2866 DWORD bufsize = *(const WORD*)&pFormat[6];
2868 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2869 TRACE("index=%d\n", index);
2871 pStubMsg->MemorySize += memsize;
2873 if (flags & USER_MARSHAL_POINTER)
2875 ALIGN_POINTER(pStubMsg->Buffer, 4);
2876 /* skip pointer prefix */
2877 pStubMsg->Buffer += 4;
2878 ALIGN_POINTER(pStubMsg->Buffer, 8);
2880 else
2881 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2883 pStubMsg->Buffer += bufsize;
2885 return pStubMsg->MemorySize;
2888 /***********************************************************************
2889 * NdrUserMarshalFree [RPCRT4.@]
2891 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
2892 unsigned char *pMemory,
2893 PFORMAT_STRING pFormat)
2895 /* unsigned flags = pFormat[1]; */
2896 unsigned index = *(const WORD*)&pFormat[2];
2897 ULONG uflag = UserMarshalFlags(pStubMsg);
2898 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2899 TRACE("index=%d\n", index);
2901 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
2902 &uflag, pMemory);
2905 /***********************************************************************
2906 * NdrClearOutParameters [RPCRT4.@]
2908 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
2909 PFORMAT_STRING pFormat,
2910 void *ArgAddr)
2912 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
2915 /***********************************************************************
2916 * NdrConvert [RPCRT4.@]
2918 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
2920 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
2921 /* FIXME: since this stub doesn't do any converting, the proper behavior
2922 is to raise an exception */
2925 /***********************************************************************
2926 * NdrConvert2 [RPCRT4.@]
2928 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
2930 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
2931 pStubMsg, pFormat, NumberParams);
2932 /* FIXME: since this stub doesn't do any converting, the proper behavior
2933 is to raise an exception */
2936 #include "pshpack1.h"
2937 typedef struct _NDR_CSTRUCT_FORMAT
2939 unsigned char type;
2940 unsigned char alignment;
2941 unsigned short memory_size;
2942 short offset_to_array_description;
2943 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
2944 #include "poppack.h"
2946 /***********************************************************************
2947 * NdrConformantStructMarshall [RPCRT4.@]
2949 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2950 unsigned char *pMemory,
2951 PFORMAT_STRING pFormat)
2953 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
2954 PFORMAT_STRING pCArrayFormat;
2955 ULONG esize, bufsize;
2957 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2959 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2960 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2962 ERR("invalid format type %x\n", pCStructFormat->type);
2963 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2964 return NULL;
2967 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
2968 pCStructFormat->offset_to_array_description;
2969 if (*pCArrayFormat != RPC_FC_CARRAY)
2971 ERR("invalid array format type %x\n", pCStructFormat->type);
2972 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2973 return NULL;
2975 esize = *(const WORD*)(pCArrayFormat+2);
2977 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
2978 pCArrayFormat + 4, 0);
2980 WriteConformance(pStubMsg);
2982 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
2984 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2986 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
2987 /* copy constant sized part of struct */
2988 pStubMsg->BufferMark = pStubMsg->Buffer;
2989 memcpy(pStubMsg->Buffer, pMemory, pCStructFormat->memory_size + bufsize);
2990 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
2992 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2993 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2995 STD_OVERFLOW_CHECK(pStubMsg);
2997 return NULL;
3000 /***********************************************************************
3001 * NdrConformantStructUnmarshall [RPCRT4.@]
3003 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3004 unsigned char **ppMemory,
3005 PFORMAT_STRING pFormat,
3006 unsigned char fMustAlloc)
3008 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3009 PFORMAT_STRING pCArrayFormat;
3010 ULONG esize, bufsize;
3012 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3014 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3015 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3017 ERR("invalid format type %x\n", pCStructFormat->type);
3018 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3019 return NULL;
3021 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3022 pCStructFormat->offset_to_array_description;
3023 if (*pCArrayFormat != RPC_FC_CARRAY)
3025 ERR("invalid array format type %x\n", pCStructFormat->type);
3026 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3027 return NULL;
3029 esize = *(const WORD*)(pCArrayFormat+2);
3031 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3033 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3035 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3037 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3038 /* work out how much memory to allocate if we need to do so */
3039 if (!*ppMemory || fMustAlloc)
3041 SIZE_T size = pCStructFormat->memory_size + bufsize;
3042 *ppMemory = NdrAllocate(pStubMsg, size);
3045 /* now copy the data */
3046 pStubMsg->BufferMark = pStubMsg->Buffer;
3047 memcpy(*ppMemory, pStubMsg->Buffer, pCStructFormat->memory_size + bufsize);
3048 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
3050 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3051 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3053 return NULL;
3056 /***********************************************************************
3057 * NdrConformantStructBufferSize [RPCRT4.@]
3059 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3060 unsigned char *pMemory,
3061 PFORMAT_STRING pFormat)
3063 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3064 PFORMAT_STRING pCArrayFormat;
3065 ULONG esize;
3067 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3069 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3070 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3072 ERR("invalid format type %x\n", pCStructFormat->type);
3073 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3074 return;
3076 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3077 pCStructFormat->offset_to_array_description;
3078 if (*pCArrayFormat != RPC_FC_CARRAY)
3080 ERR("invalid array format type %x\n", pCStructFormat->type);
3081 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3082 return;
3084 esize = *(const WORD*)(pCArrayFormat+2);
3086 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
3087 SizeConformance(pStubMsg);
3089 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
3091 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3093 pStubMsg->BufferLength += pCStructFormat->memory_size +
3094 safe_multiply(pStubMsg->MaxCount, esize);
3096 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3097 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3100 /***********************************************************************
3101 * NdrConformantStructMemorySize [RPCRT4.@]
3103 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3104 PFORMAT_STRING pFormat)
3106 FIXME("stub\n");
3107 return 0;
3110 /***********************************************************************
3111 * NdrConformantStructFree [RPCRT4.@]
3113 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3114 unsigned char *pMemory,
3115 PFORMAT_STRING pFormat)
3117 FIXME("stub\n");
3120 /***********************************************************************
3121 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3123 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3124 unsigned char *pMemory,
3125 PFORMAT_STRING pFormat)
3127 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3128 PFORMAT_STRING pCVArrayFormat;
3129 ULONG esize, bufsize;
3131 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3133 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3134 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3136 ERR("invalid format type %x\n", pCVStructFormat->type);
3137 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3138 return NULL;
3141 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3142 pCVStructFormat->offset_to_array_description;
3143 switch (*pCVArrayFormat)
3145 case RPC_FC_CVARRAY:
3146 esize = *(const WORD*)(pCVArrayFormat+2);
3148 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3149 pCVArrayFormat + 4, 0);
3150 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3151 pCVArrayFormat, 0);
3152 break;
3153 case RPC_FC_C_CSTRING:
3154 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3155 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3156 esize = sizeof(char);
3157 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3158 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3159 pCVArrayFormat + 2, 0);
3160 else
3161 pStubMsg->MaxCount = pStubMsg->ActualCount;
3162 break;
3163 case RPC_FC_C_WSTRING:
3164 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3165 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3166 esize = sizeof(WCHAR);
3167 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3168 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3169 pCVArrayFormat + 2, 0);
3170 else
3171 pStubMsg->MaxCount = pStubMsg->ActualCount;
3172 break;
3173 default:
3174 ERR("invalid array format type %x\n", *pCVArrayFormat);
3175 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3176 return NULL;
3179 WriteConformance(pStubMsg);
3181 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3183 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3185 /* write constant sized part */
3186 pStubMsg->BufferMark = pStubMsg->Buffer;
3187 memcpy(pStubMsg->Buffer, pMemory, pCVStructFormat->memory_size);
3188 pStubMsg->Buffer += pCVStructFormat->memory_size;
3190 WriteVariance(pStubMsg);
3192 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3194 /* write array part */
3195 memcpy(pStubMsg->Buffer, pMemory + pCVStructFormat->memory_size, bufsize);
3196 pStubMsg->Buffer += bufsize;
3198 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3200 STD_OVERFLOW_CHECK(pStubMsg);
3202 return NULL;
3205 /***********************************************************************
3206 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3208 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3209 unsigned char **ppMemory,
3210 PFORMAT_STRING pFormat,
3211 unsigned char fMustAlloc)
3213 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3214 PFORMAT_STRING pCVArrayFormat;
3215 ULONG esize, bufsize;
3216 unsigned char cvarray_type;
3218 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3220 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3221 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3223 ERR("invalid format type %x\n", pCVStructFormat->type);
3224 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3225 return NULL;
3228 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3229 pCVStructFormat->offset_to_array_description;
3230 cvarray_type = *pCVArrayFormat;
3231 switch (cvarray_type)
3233 case RPC_FC_CVARRAY:
3234 esize = *(const WORD*)(pCVArrayFormat+2);
3235 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3236 break;
3237 case RPC_FC_C_CSTRING:
3238 esize = sizeof(char);
3239 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3240 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3241 else
3242 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3243 break;
3244 case RPC_FC_C_WSTRING:
3245 esize = sizeof(WCHAR);
3246 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3247 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3248 else
3249 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3250 break;
3251 default:
3252 ERR("invalid array format type %x\n", *pCVArrayFormat);
3253 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3254 return NULL;
3257 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3259 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3261 /* work out how much memory to allocate if we need to do so */
3262 if (!*ppMemory || fMustAlloc)
3264 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3265 *ppMemory = NdrAllocate(pStubMsg, size);
3268 /* copy the constant data */
3269 pStubMsg->BufferMark = pStubMsg->Buffer;
3270 memcpy(*ppMemory, pStubMsg->Buffer, pCVStructFormat->memory_size);
3271 pStubMsg->Buffer += pCVStructFormat->memory_size;
3273 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3275 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3277 if ((cvarray_type == RPC_FC_C_CSTRING) ||
3278 (cvarray_type == RPC_FC_C_WSTRING))
3280 ULONG i;
3281 /* strings must always have null terminating bytes */
3282 if (bufsize < esize)
3284 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
3285 RpcRaiseException(RPC_S_INVALID_BOUND);
3286 return NULL;
3288 for (i = bufsize - esize; i < bufsize; i++)
3289 if (pStubMsg->Buffer[i] != 0)
3291 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3292 i, pStubMsg->Buffer[i]);
3293 RpcRaiseException(RPC_S_INVALID_BOUND);
3294 return NULL;
3298 /* copy the array data */
3299 memcpy(*ppMemory + pCVStructFormat->memory_size, pStubMsg->Buffer,
3300 bufsize);
3301 pStubMsg->Buffer += bufsize;
3303 if (cvarray_type == RPC_FC_C_CSTRING)
3304 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3305 else if (cvarray_type == RPC_FC_C_WSTRING)
3306 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3308 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3310 return NULL;
3313 /***********************************************************************
3314 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3316 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3317 unsigned char *pMemory,
3318 PFORMAT_STRING pFormat)
3320 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3321 PFORMAT_STRING pCVArrayFormat;
3322 ULONG esize;
3324 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3326 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3327 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3329 ERR("invalid format type %x\n", pCVStructFormat->type);
3330 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3331 return;
3334 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3335 pCVStructFormat->offset_to_array_description;
3336 switch (*pCVArrayFormat)
3338 case RPC_FC_CVARRAY:
3339 esize = *(const WORD*)(pCVArrayFormat+2);
3341 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3342 pCVArrayFormat + 4, 0);
3343 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3344 pCVArrayFormat, 0);
3345 break;
3346 case RPC_FC_C_CSTRING:
3347 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3348 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3349 esize = sizeof(char);
3350 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3351 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3352 pCVArrayFormat + 2, 0);
3353 else
3354 pStubMsg->MaxCount = pStubMsg->ActualCount;
3355 break;
3356 case RPC_FC_C_WSTRING:
3357 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3358 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3359 esize = sizeof(WCHAR);
3360 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3361 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3362 pCVArrayFormat + 2, 0);
3363 else
3364 pStubMsg->MaxCount = pStubMsg->ActualCount;
3365 break;
3366 default:
3367 ERR("invalid array format type %x\n", *pCVArrayFormat);
3368 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3369 return;
3372 SizeConformance(pStubMsg);
3374 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
3376 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3378 pStubMsg->BufferLength += pCVStructFormat->memory_size;
3379 SizeVariance(pStubMsg);
3380 pStubMsg->BufferLength += safe_multiply(pStubMsg->MaxCount, esize);
3382 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3385 /***********************************************************************
3386 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3388 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3389 PFORMAT_STRING pFormat)
3391 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3392 PFORMAT_STRING pCVArrayFormat;
3393 ULONG esize;
3394 unsigned char cvarray_type;
3396 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3398 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3399 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3401 ERR("invalid format type %x\n", pCVStructFormat->type);
3402 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3403 return 0;
3406 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3407 pCVStructFormat->offset_to_array_description;
3408 cvarray_type = *pCVArrayFormat;
3409 switch (cvarray_type)
3411 case RPC_FC_CVARRAY:
3412 esize = *(const WORD*)(pCVArrayFormat+2);
3413 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3414 break;
3415 case RPC_FC_C_CSTRING:
3416 esize = sizeof(char);
3417 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3418 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3419 else
3420 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3421 break;
3422 case RPC_FC_C_WSTRING:
3423 esize = sizeof(WCHAR);
3424 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3425 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3426 else
3427 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3428 break;
3429 default:
3430 ERR("invalid array format type %x\n", *pCVArrayFormat);
3431 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3432 return 0;
3435 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3437 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3439 pStubMsg->Buffer += pCVStructFormat->memory_size;
3440 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3441 pStubMsg->Buffer += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->ActualCount);
3443 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3445 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3447 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3450 /***********************************************************************
3451 * NdrConformantVaryingStructFree [RPCRT4.@]
3453 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3454 unsigned char *pMemory,
3455 PFORMAT_STRING pFormat)
3457 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3458 PFORMAT_STRING pCVArrayFormat;
3459 ULONG esize;
3461 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3463 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3464 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3466 ERR("invalid format type %x\n", pCVStructFormat->type);
3467 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3468 return;
3471 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3472 pCVStructFormat->offset_to_array_description;
3473 switch (*pCVArrayFormat)
3475 case RPC_FC_CVARRAY:
3476 esize = *(const WORD*)(pCVArrayFormat+2);
3478 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3479 pCVArrayFormat + 4, 0);
3480 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3481 pCVArrayFormat, 0);
3482 break;
3483 case RPC_FC_C_CSTRING:
3484 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3485 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3486 esize = sizeof(char);
3487 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3488 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3489 pCVArrayFormat + 2, 0);
3490 else
3491 pStubMsg->MaxCount = pStubMsg->ActualCount;
3492 break;
3493 case RPC_FC_C_WSTRING:
3494 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3495 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3496 esize = sizeof(WCHAR);
3497 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3498 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3499 pCVArrayFormat + 2, 0);
3500 else
3501 pStubMsg->MaxCount = pStubMsg->ActualCount;
3502 break;
3503 default:
3504 ERR("invalid array format type %x\n", *pCVArrayFormat);
3505 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3506 return;
3509 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3511 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3514 #include "pshpack1.h"
3515 typedef struct
3517 unsigned char type;
3518 unsigned char alignment;
3519 unsigned short total_size;
3520 } NDR_SMFARRAY_FORMAT;
3522 typedef struct
3524 unsigned char type;
3525 unsigned char alignment;
3526 unsigned long total_size;
3527 } NDR_LGFARRAY_FORMAT;
3528 #include "poppack.h"
3530 /***********************************************************************
3531 * NdrFixedArrayMarshall [RPCRT4.@]
3533 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3534 unsigned char *pMemory,
3535 PFORMAT_STRING pFormat)
3537 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3538 unsigned long total_size;
3540 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3542 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3543 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3545 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3546 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3547 return NULL;
3550 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3552 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3554 total_size = pSmFArrayFormat->total_size;
3555 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3557 else
3559 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3560 total_size = pLgFArrayFormat->total_size;
3561 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3564 memcpy(pStubMsg->Buffer, pMemory, total_size);
3565 pStubMsg->BufferMark = pStubMsg->Buffer;
3566 pStubMsg->Buffer += total_size;
3568 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3570 return NULL;
3573 /***********************************************************************
3574 * NdrFixedArrayUnmarshall [RPCRT4.@]
3576 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3577 unsigned char **ppMemory,
3578 PFORMAT_STRING pFormat,
3579 unsigned char fMustAlloc)
3581 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3582 unsigned long total_size;
3584 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3586 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3587 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3589 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3590 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3591 return NULL;
3594 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3596 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3598 total_size = pSmFArrayFormat->total_size;
3599 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3601 else
3603 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3604 total_size = pLgFArrayFormat->total_size;
3605 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3608 if (fMustAlloc || !*ppMemory)
3609 *ppMemory = NdrAllocate(pStubMsg, total_size);
3610 memcpy(*ppMemory, pStubMsg->Buffer, total_size);
3611 pStubMsg->BufferMark = pStubMsg->Buffer;
3612 pStubMsg->Buffer += total_size;
3614 pFormat = EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3616 return NULL;
3619 /***********************************************************************
3620 * NdrFixedArrayBufferSize [RPCRT4.@]
3622 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3623 unsigned char *pMemory,
3624 PFORMAT_STRING pFormat)
3626 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3627 unsigned long total_size;
3629 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3631 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3632 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3634 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3635 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3636 return;
3639 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
3641 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3643 total_size = pSmFArrayFormat->total_size;
3644 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3646 else
3648 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3649 total_size = pLgFArrayFormat->total_size;
3650 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3652 pStubMsg->BufferLength += total_size;
3654 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3657 /***********************************************************************
3658 * NdrFixedArrayMemorySize [RPCRT4.@]
3660 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3661 PFORMAT_STRING pFormat)
3663 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3664 ULONG total_size;
3666 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3668 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3669 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3671 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3672 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3673 return 0;
3676 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3678 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3680 total_size = pSmFArrayFormat->total_size;
3681 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3683 else
3685 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3686 total_size = pLgFArrayFormat->total_size;
3687 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3689 pStubMsg->BufferMark = pStubMsg->Buffer;
3690 pStubMsg->Buffer += total_size;
3691 pStubMsg->MemorySize += total_size;
3693 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3695 return total_size;
3698 /***********************************************************************
3699 * NdrFixedArrayFree [RPCRT4.@]
3701 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3702 unsigned char *pMemory,
3703 PFORMAT_STRING pFormat)
3705 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3707 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3709 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3710 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3712 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3713 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3714 return;
3717 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3718 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3719 else
3721 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3722 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3725 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3728 /***********************************************************************
3729 * NdrVaryingArrayMarshall [RPCRT4.@]
3731 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3732 unsigned char *pMemory,
3733 PFORMAT_STRING pFormat)
3735 unsigned char alignment;
3736 DWORD elements, esize;
3737 ULONG bufsize;
3739 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3741 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3742 (pFormat[0] != RPC_FC_LGVARRAY))
3744 ERR("invalid format type %x\n", pFormat[0]);
3745 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3746 return NULL;
3749 alignment = pFormat[1] + 1;
3751 if (pFormat[0] == RPC_FC_SMVARRAY)
3753 pFormat += 2;
3754 pFormat += sizeof(WORD);
3755 elements = *(const WORD*)pFormat;
3756 pFormat += sizeof(WORD);
3758 else
3760 pFormat += 2;
3761 pFormat += sizeof(DWORD);
3762 elements = *(const DWORD*)pFormat;
3763 pFormat += sizeof(DWORD);
3766 esize = *(const WORD*)pFormat;
3767 pFormat += sizeof(WORD);
3769 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3770 if ((pStubMsg->ActualCount > elements) ||
3771 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3773 RpcRaiseException(RPC_S_INVALID_BOUND);
3774 return NULL;
3777 WriteVariance(pStubMsg);
3779 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3781 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3782 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
3783 pStubMsg->BufferMark = pStubMsg->Buffer;
3784 pStubMsg->Buffer += bufsize;
3786 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3788 STD_OVERFLOW_CHECK(pStubMsg);
3790 return NULL;
3793 /***********************************************************************
3794 * NdrVaryingArrayUnmarshall [RPCRT4.@]
3796 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3797 unsigned char **ppMemory,
3798 PFORMAT_STRING pFormat,
3799 unsigned char fMustAlloc)
3801 unsigned char alignment;
3802 DWORD size, elements, esize;
3803 ULONG bufsize;
3805 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3807 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3808 (pFormat[0] != RPC_FC_LGVARRAY))
3810 ERR("invalid format type %x\n", pFormat[0]);
3811 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3812 return NULL;
3815 alignment = pFormat[1] + 1;
3817 if (pFormat[0] == RPC_FC_SMVARRAY)
3819 pFormat += 2;
3820 size = *(const WORD*)pFormat;
3821 pFormat += sizeof(WORD);
3822 elements = *(const WORD*)pFormat;
3823 pFormat += sizeof(WORD);
3825 else
3827 pFormat += 2;
3828 size = *(const DWORD*)pFormat;
3829 pFormat += sizeof(DWORD);
3830 elements = *(const DWORD*)pFormat;
3831 pFormat += sizeof(DWORD);
3834 esize = *(const WORD*)pFormat;
3835 pFormat += sizeof(WORD);
3837 pFormat = ReadVariance(pStubMsg, pFormat, elements);
3839 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3841 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3843 if (!*ppMemory || fMustAlloc)
3844 *ppMemory = NdrAllocate(pStubMsg, size);
3845 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
3846 pStubMsg->Buffer += bufsize;
3848 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3850 return NULL;
3853 /***********************************************************************
3854 * NdrVaryingArrayBufferSize [RPCRT4.@]
3856 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3857 unsigned char *pMemory,
3858 PFORMAT_STRING pFormat)
3860 unsigned char alignment;
3861 DWORD elements, esize;
3863 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3865 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3866 (pFormat[0] != RPC_FC_LGVARRAY))
3868 ERR("invalid format type %x\n", pFormat[0]);
3869 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3870 return;
3873 alignment = pFormat[1] + 1;
3875 if (pFormat[0] == RPC_FC_SMVARRAY)
3877 pFormat += 2;
3878 pFormat += sizeof(WORD);
3879 elements = *(const WORD*)pFormat;
3880 pFormat += sizeof(WORD);
3882 else
3884 pFormat += 2;
3885 pFormat += sizeof(DWORD);
3886 elements = *(const DWORD*)pFormat;
3887 pFormat += sizeof(DWORD);
3890 esize = *(const WORD*)pFormat;
3891 pFormat += sizeof(WORD);
3893 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3894 if ((pStubMsg->ActualCount > elements) ||
3895 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3897 RpcRaiseException(RPC_S_INVALID_BOUND);
3898 return;
3901 SizeVariance(pStubMsg);
3903 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3905 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
3907 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3910 /***********************************************************************
3911 * NdrVaryingArrayMemorySize [RPCRT4.@]
3913 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3914 PFORMAT_STRING pFormat)
3916 unsigned char alignment;
3917 DWORD size, elements, esize;
3919 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3921 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3922 (pFormat[0] != RPC_FC_LGVARRAY))
3924 ERR("invalid format type %x\n", pFormat[0]);
3925 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3926 return 0;
3929 alignment = pFormat[1] + 1;
3931 if (pFormat[0] == RPC_FC_SMVARRAY)
3933 pFormat += 2;
3934 size = *(const WORD*)pFormat;
3935 pFormat += sizeof(WORD);
3936 elements = *(const WORD*)pFormat;
3937 pFormat += sizeof(WORD);
3939 else
3941 pFormat += 2;
3942 size = *(const DWORD*)pFormat;
3943 pFormat += sizeof(DWORD);
3944 elements = *(const DWORD*)pFormat;
3945 pFormat += sizeof(DWORD);
3948 esize = *(const WORD*)pFormat;
3949 pFormat += sizeof(WORD);
3951 pFormat = ReadVariance(pStubMsg, pFormat, elements);
3953 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3955 pStubMsg->Buffer += safe_multiply(esize, pStubMsg->ActualCount);
3956 pStubMsg->MemorySize += size;
3958 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3960 return pStubMsg->MemorySize;
3963 /***********************************************************************
3964 * NdrVaryingArrayFree [RPCRT4.@]
3966 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3967 unsigned char *pMemory,
3968 PFORMAT_STRING pFormat)
3970 unsigned char alignment;
3971 DWORD elements;
3973 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3975 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3976 (pFormat[0] != RPC_FC_LGVARRAY))
3978 ERR("invalid format type %x\n", pFormat[0]);
3979 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3980 return;
3983 alignment = pFormat[1] + 1;
3985 if (pFormat[0] == RPC_FC_SMVARRAY)
3987 pFormat += 2;
3988 pFormat += sizeof(WORD);
3989 elements = *(const WORD*)pFormat;
3990 pFormat += sizeof(WORD);
3992 else
3994 pFormat += 2;
3995 pFormat += sizeof(DWORD);
3996 elements = *(const DWORD*)pFormat;
3997 pFormat += sizeof(DWORD);
4000 pFormat += sizeof(WORD);
4002 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4003 if ((pStubMsg->ActualCount > elements) ||
4004 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4006 RpcRaiseException(RPC_S_INVALID_BOUND);
4007 return;
4010 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4013 static ULONG get_discriminant(unsigned char fc, unsigned char *pMemory)
4015 switch (fc)
4017 case RPC_FC_BYTE:
4018 case RPC_FC_CHAR:
4019 case RPC_FC_SMALL:
4020 case RPC_FC_USMALL:
4021 return *(UCHAR *)pMemory;
4022 case RPC_FC_WCHAR:
4023 case RPC_FC_SHORT:
4024 case RPC_FC_USHORT:
4025 return *(USHORT *)pMemory;
4026 case RPC_FC_LONG:
4027 case RPC_FC_ULONG:
4028 return *(ULONG *)pMemory;
4029 default:
4030 FIXME("Unhandled base type: 0x%02x\n", fc);
4031 return 0;
4035 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4036 unsigned long discriminant,
4037 PFORMAT_STRING pFormat)
4039 unsigned short num_arms, arm, type;
4041 num_arms = *(const SHORT*)pFormat & 0x0fff;
4042 pFormat += 2;
4043 for(arm = 0; arm < num_arms; arm++)
4045 if(discriminant == *(const ULONG*)pFormat)
4047 pFormat += 4;
4048 break;
4050 pFormat += 6;
4053 type = *(const unsigned short*)pFormat;
4054 TRACE("type %04x\n", type);
4055 if(arm == num_arms) /* default arm extras */
4057 if(type == 0xffff)
4059 ERR("no arm for 0x%lx and no default case\n", discriminant);
4060 RpcRaiseException(RPC_S_INVALID_TAG);
4061 return NULL;
4063 if(type == 0)
4065 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
4066 return NULL;
4069 return pFormat;
4072 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
4074 unsigned short type;
4076 pFormat += 2;
4078 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4079 if(!pFormat)
4080 return NULL;
4082 type = *(const unsigned short*)pFormat;
4083 if((type & 0xff00) == 0x8000)
4085 unsigned char basetype = LOBYTE(type);
4086 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
4088 else
4090 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4091 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
4092 if (m)
4094 unsigned char *saved_buffer = NULL;
4095 switch(*desc)
4097 case RPC_FC_RP:
4098 case RPC_FC_UP:
4099 case RPC_FC_OP:
4100 case RPC_FC_FP:
4101 saved_buffer = pStubMsg->Buffer;
4102 pStubMsg->Buffer += 4; /* for pointer ID */
4103 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
4104 break;
4105 default:
4106 m(pStubMsg, pMemory, desc);
4109 else FIXME("no marshaller for embedded type %02x\n", *desc);
4111 return NULL;
4114 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4115 unsigned char **ppMemory,
4116 ULONG discriminant,
4117 PFORMAT_STRING pFormat,
4118 unsigned char fMustAlloc)
4120 unsigned short type;
4122 pFormat += 2;
4124 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4125 if(!pFormat)
4126 return NULL;
4128 type = *(const unsigned short*)pFormat;
4129 if((type & 0xff00) == 0x8000)
4131 unsigned char basetype = LOBYTE(type);
4132 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, fMustAlloc);
4134 else
4136 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4137 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
4138 if (m)
4140 unsigned char *saved_buffer = NULL;
4141 switch(*desc)
4143 case RPC_FC_RP:
4144 case RPC_FC_UP:
4145 case RPC_FC_OP:
4146 case RPC_FC_FP:
4147 ALIGN_POINTER(pStubMsg->Buffer, 4);
4148 saved_buffer = pStubMsg->Buffer;
4149 pStubMsg->Buffer += 4; /* for pointer ID */
4150 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, desc, TRUE);
4151 break;
4152 default:
4153 m(pStubMsg, ppMemory, desc, fMustAlloc);
4156 else FIXME("no marshaller for embedded type %02x\n", *desc);
4158 return NULL;
4161 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
4162 unsigned char *pMemory,
4163 ULONG discriminant,
4164 PFORMAT_STRING pFormat)
4166 unsigned short type;
4168 pFormat += 2;
4170 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4171 if(!pFormat)
4172 return;
4174 type = *(const unsigned short*)pFormat;
4175 if((type & 0xff00) == 0x8000)
4177 unsigned char basetype = LOBYTE(type);
4178 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
4180 else
4182 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4183 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
4184 if (m)
4186 switch(*desc)
4188 case RPC_FC_RP:
4189 case RPC_FC_UP:
4190 case RPC_FC_OP:
4191 case RPC_FC_FP:
4192 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4193 pStubMsg->BufferLength += 4; /* for pointer ID */
4194 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
4195 break;
4196 default:
4197 m(pStubMsg, pMemory, desc);
4200 else FIXME("no buffersizer for embedded type %02x\n", *desc);
4204 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
4205 ULONG discriminant,
4206 PFORMAT_STRING pFormat)
4208 unsigned short type, size;
4210 size = *(const unsigned short*)pFormat;
4211 pStubMsg->Memory += size;
4212 pFormat += 2;
4214 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4215 if(!pFormat)
4216 return 0;
4218 type = *(const unsigned short*)pFormat;
4219 if((type & 0xff00) == 0x8000)
4221 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
4223 else
4225 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4226 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
4227 unsigned char *saved_buffer;
4228 if (m)
4230 switch(*desc)
4232 case RPC_FC_RP:
4233 case RPC_FC_UP:
4234 case RPC_FC_OP:
4235 case RPC_FC_FP:
4236 ALIGN_POINTER(pStubMsg->Buffer, 4);
4237 saved_buffer = pStubMsg->Buffer;
4238 pStubMsg->Buffer += 4;
4239 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
4240 pStubMsg->MemorySize += 4;
4241 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
4242 break;
4243 default:
4244 return m(pStubMsg, desc);
4247 else FIXME("no marshaller for embedded type %02x\n", *desc);
4250 TRACE("size %d\n", size);
4251 return size;
4254 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
4255 unsigned char *pMemory,
4256 ULONG discriminant,
4257 PFORMAT_STRING pFormat)
4259 unsigned short type;
4261 pFormat += 2;
4263 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4264 if(!pFormat)
4265 return;
4267 type = *(const unsigned short*)pFormat;
4268 if((type & 0xff00) != 0x8000)
4270 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4271 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
4272 if (m)
4274 switch(*desc)
4276 case RPC_FC_RP:
4277 case RPC_FC_UP:
4278 case RPC_FC_OP:
4279 case RPC_FC_FP:
4280 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
4281 break;
4282 default:
4283 m(pStubMsg, pMemory, desc);
4286 else FIXME("no freer for embedded type %02x\n", *desc);
4290 /***********************************************************************
4291 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4293 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4294 unsigned char *pMemory,
4295 PFORMAT_STRING pFormat)
4297 unsigned char switch_type;
4298 unsigned char increment;
4299 ULONG switch_value;
4301 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4302 pFormat++;
4304 switch_type = *pFormat & 0xf;
4305 increment = (*pFormat & 0xf0) >> 4;
4306 pFormat++;
4308 ALIGN_POINTER(pStubMsg->Buffer, increment);
4310 switch_value = get_discriminant(switch_type, pMemory);
4311 TRACE("got switch value 0x%x\n", switch_value);
4313 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
4314 pMemory += increment;
4316 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
4319 /***********************************************************************
4320 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4322 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4323 unsigned char **ppMemory,
4324 PFORMAT_STRING pFormat,
4325 unsigned char fMustAlloc)
4327 unsigned char switch_type;
4328 unsigned char increment;
4329 ULONG switch_value;
4330 unsigned short size;
4331 unsigned char *pMemoryArm;
4333 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4334 pFormat++;
4336 switch_type = *pFormat & 0xf;
4337 increment = (*pFormat & 0xf0) >> 4;
4338 pFormat++;
4340 ALIGN_POINTER(pStubMsg->Buffer, increment);
4341 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
4342 TRACE("got switch value 0x%x\n", switch_value);
4344 size = *(const unsigned short*)pFormat + increment;
4345 if(!*ppMemory || fMustAlloc)
4346 *ppMemory = NdrAllocate(pStubMsg, size);
4348 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
4349 pMemoryArm = *ppMemory + increment;
4351 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
4354 /***********************************************************************
4355 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4357 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4358 unsigned char *pMemory,
4359 PFORMAT_STRING pFormat)
4361 unsigned char switch_type;
4362 unsigned char increment;
4363 ULONG switch_value;
4365 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4366 pFormat++;
4368 switch_type = *pFormat & 0xf;
4369 increment = (*pFormat & 0xf0) >> 4;
4370 pFormat++;
4372 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
4373 switch_value = get_discriminant(switch_type, pMemory);
4374 TRACE("got switch value 0x%x\n", switch_value);
4376 /* Add discriminant size */
4377 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
4378 pMemory += increment;
4380 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
4383 /***********************************************************************
4384 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4386 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4387 PFORMAT_STRING pFormat)
4389 unsigned char switch_type;
4390 unsigned char increment;
4391 ULONG switch_value;
4393 switch_type = *pFormat & 0xf;
4394 increment = (*pFormat & 0xf0) >> 4;
4395 pFormat++;
4397 ALIGN_POINTER(pStubMsg->Buffer, increment);
4398 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
4399 TRACE("got switch value 0x%x\n", switch_value);
4401 pStubMsg->Memory += increment;
4403 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
4406 /***********************************************************************
4407 * NdrEncapsulatedUnionFree [RPCRT4.@]
4409 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4410 unsigned char *pMemory,
4411 PFORMAT_STRING pFormat)
4413 unsigned char switch_type;
4414 unsigned char increment;
4415 ULONG switch_value;
4417 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4418 pFormat++;
4420 switch_type = *pFormat & 0xf;
4421 increment = (*pFormat & 0xf0) >> 4;
4422 pFormat++;
4424 switch_value = get_discriminant(switch_type, pMemory);
4425 TRACE("got switch value 0x%x\n", switch_value);
4427 pMemory += increment;
4429 return union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
4432 /***********************************************************************
4433 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
4435 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4436 unsigned char *pMemory,
4437 PFORMAT_STRING pFormat)
4439 unsigned char switch_type;
4441 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4442 pFormat++;
4444 switch_type = *pFormat;
4445 pFormat++;
4447 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4448 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4449 /* Marshall discriminant */
4450 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4452 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
4455 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
4456 PFORMAT_STRING *ppFormat)
4458 long discriminant = 0;
4460 switch(**ppFormat)
4462 case RPC_FC_BYTE:
4463 case RPC_FC_CHAR:
4464 case RPC_FC_SMALL:
4465 case RPC_FC_USMALL:
4466 discriminant = *(UCHAR *)pStubMsg->Buffer;
4467 pStubMsg->Buffer += sizeof(UCHAR);
4468 break;
4469 case RPC_FC_WCHAR:
4470 case RPC_FC_SHORT:
4471 case RPC_FC_USHORT:
4472 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4473 discriminant = *(USHORT *)pStubMsg->Buffer;
4474 pStubMsg->Buffer += sizeof(USHORT);
4475 break;
4476 case RPC_FC_LONG:
4477 case RPC_FC_ULONG:
4478 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4479 discriminant = *(ULONG *)pStubMsg->Buffer;
4480 pStubMsg->Buffer += sizeof(ULONG);
4481 break;
4482 default:
4483 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
4485 (*ppFormat)++;
4487 if (pStubMsg->fHasNewCorrDesc)
4488 *ppFormat += 6;
4489 else
4490 *ppFormat += 4;
4491 return discriminant;
4494 /**********************************************************************
4495 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
4497 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4498 unsigned char **ppMemory,
4499 PFORMAT_STRING pFormat,
4500 unsigned char fMustAlloc)
4502 long discriminant;
4503 unsigned short size;
4505 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4506 pFormat++;
4508 /* Unmarshall discriminant */
4509 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4510 TRACE("unmarshalled discriminant %lx\n", discriminant);
4512 pFormat += *(const SHORT*)pFormat;
4514 size = *(const unsigned short*)pFormat;
4516 if(!*ppMemory || fMustAlloc)
4517 *ppMemory = NdrAllocate(pStubMsg, size);
4519 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
4522 /***********************************************************************
4523 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
4525 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4526 unsigned char *pMemory,
4527 PFORMAT_STRING pFormat)
4529 unsigned char switch_type;
4531 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4532 pFormat++;
4534 switch_type = *pFormat;
4535 pFormat++;
4537 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4538 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4539 /* Add discriminant size */
4540 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4542 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
4545 /***********************************************************************
4546 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
4548 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4549 PFORMAT_STRING pFormat)
4551 ULONG discriminant;
4553 pFormat++;
4554 /* Unmarshall discriminant */
4555 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4556 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
4558 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
4561 /***********************************************************************
4562 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
4564 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4565 unsigned char *pMemory,
4566 PFORMAT_STRING pFormat)
4568 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4569 pFormat++;
4570 pFormat++;
4572 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4573 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4575 return union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
4578 /***********************************************************************
4579 * NdrByteCountPointerMarshall [RPCRT4.@]
4581 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4582 unsigned char *pMemory,
4583 PFORMAT_STRING pFormat)
4585 FIXME("stub\n");
4586 return NULL;
4589 /***********************************************************************
4590 * NdrByteCountPointerUnmarshall [RPCRT4.@]
4592 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4593 unsigned char **ppMemory,
4594 PFORMAT_STRING pFormat,
4595 unsigned char fMustAlloc)
4597 FIXME("stub\n");
4598 return NULL;
4601 /***********************************************************************
4602 * NdrByteCountPointerBufferSize [RPCRT4.@]
4604 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4605 unsigned char *pMemory,
4606 PFORMAT_STRING pFormat)
4608 FIXME("stub\n");
4611 /***********************************************************************
4612 * NdrByteCountPointerMemorySize [RPCRT4.@]
4614 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4615 PFORMAT_STRING pFormat)
4617 FIXME("stub\n");
4618 return 0;
4621 /***********************************************************************
4622 * NdrByteCountPointerFree [RPCRT4.@]
4624 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
4625 unsigned char *pMemory,
4626 PFORMAT_STRING pFormat)
4628 FIXME("stub\n");
4631 /***********************************************************************
4632 * NdrXmitOrRepAsMarshall [RPCRT4.@]
4634 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4635 unsigned char *pMemory,
4636 PFORMAT_STRING pFormat)
4638 FIXME("stub\n");
4639 return NULL;
4642 /***********************************************************************
4643 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
4645 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4646 unsigned char **ppMemory,
4647 PFORMAT_STRING pFormat,
4648 unsigned char fMustAlloc)
4650 FIXME("stub\n");
4651 return NULL;
4654 /***********************************************************************
4655 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
4657 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4658 unsigned char *pMemory,
4659 PFORMAT_STRING pFormat)
4661 FIXME("stub\n");
4664 /***********************************************************************
4665 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
4667 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4668 PFORMAT_STRING pFormat)
4670 FIXME("stub\n");
4671 return 0;
4674 /***********************************************************************
4675 * NdrXmitOrRepAsFree [RPCRT4.@]
4677 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
4678 unsigned char *pMemory,
4679 PFORMAT_STRING pFormat)
4681 FIXME("stub\n");
4684 /***********************************************************************
4685 * NdrBaseTypeMarshall [internal]
4687 static unsigned char *WINAPI NdrBaseTypeMarshall(
4688 PMIDL_STUB_MESSAGE pStubMsg,
4689 unsigned char *pMemory,
4690 PFORMAT_STRING pFormat)
4692 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4694 switch(*pFormat)
4696 case RPC_FC_BYTE:
4697 case RPC_FC_CHAR:
4698 case RPC_FC_SMALL:
4699 case RPC_FC_USMALL:
4700 *(UCHAR *)pStubMsg->Buffer = *(UCHAR *)pMemory;
4701 pStubMsg->Buffer += sizeof(UCHAR);
4702 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
4703 break;
4704 case RPC_FC_WCHAR:
4705 case RPC_FC_SHORT:
4706 case RPC_FC_USHORT:
4707 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4708 *(USHORT *)pStubMsg->Buffer = *(USHORT *)pMemory;
4709 pStubMsg->Buffer += sizeof(USHORT);
4710 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
4711 break;
4712 case RPC_FC_LONG:
4713 case RPC_FC_ULONG:
4714 case RPC_FC_ERROR_STATUS_T:
4715 case RPC_FC_ENUM32:
4716 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4717 *(ULONG *)pStubMsg->Buffer = *(ULONG *)pMemory;
4718 pStubMsg->Buffer += sizeof(ULONG);
4719 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
4720 break;
4721 case RPC_FC_FLOAT:
4722 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
4723 *(float *)pStubMsg->Buffer = *(float *)pMemory;
4724 pStubMsg->Buffer += sizeof(float);
4725 break;
4726 case RPC_FC_DOUBLE:
4727 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
4728 *(double *)pStubMsg->Buffer = *(double *)pMemory;
4729 pStubMsg->Buffer += sizeof(double);
4730 break;
4731 case RPC_FC_HYPER:
4732 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
4733 *(ULONGLONG *)pStubMsg->Buffer = *(ULONGLONG *)pMemory;
4734 pStubMsg->Buffer += sizeof(ULONGLONG);
4735 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
4736 break;
4737 case RPC_FC_ENUM16:
4738 /* only 16-bits on the wire, so do a sanity check */
4739 if (*(UINT *)pMemory > USHRT_MAX)
4740 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
4741 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4742 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
4743 pStubMsg->Buffer += sizeof(USHORT);
4744 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
4745 break;
4746 default:
4747 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4750 STD_OVERFLOW_CHECK(pStubMsg);
4752 /* FIXME: what is the correct return value? */
4753 return NULL;
4756 /***********************************************************************
4757 * NdrBaseTypeUnmarshall [internal]
4759 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
4760 PMIDL_STUB_MESSAGE pStubMsg,
4761 unsigned char **ppMemory,
4762 PFORMAT_STRING pFormat,
4763 unsigned char fMustAlloc)
4765 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
4767 #define BASE_TYPE_UNMARSHALL(type) \
4768 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
4769 if (fMustAlloc || !*ppMemory) \
4770 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
4771 TRACE("*ppMemory: %p\n", *ppMemory); \
4772 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
4773 pStubMsg->Buffer += sizeof(type);
4775 switch(*pFormat)
4777 case RPC_FC_BYTE:
4778 case RPC_FC_CHAR:
4779 case RPC_FC_SMALL:
4780 case RPC_FC_USMALL:
4781 BASE_TYPE_UNMARSHALL(UCHAR);
4782 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
4783 break;
4784 case RPC_FC_WCHAR:
4785 case RPC_FC_SHORT:
4786 case RPC_FC_USHORT:
4787 BASE_TYPE_UNMARSHALL(USHORT);
4788 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
4789 break;
4790 case RPC_FC_LONG:
4791 case RPC_FC_ULONG:
4792 case RPC_FC_ERROR_STATUS_T:
4793 case RPC_FC_ENUM32:
4794 BASE_TYPE_UNMARSHALL(ULONG);
4795 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
4796 break;
4797 case RPC_FC_FLOAT:
4798 BASE_TYPE_UNMARSHALL(float);
4799 TRACE("value: %f\n", **(float **)ppMemory);
4800 break;
4801 case RPC_FC_DOUBLE:
4802 BASE_TYPE_UNMARSHALL(double);
4803 TRACE("value: %f\n", **(double **)ppMemory);
4804 break;
4805 case RPC_FC_HYPER:
4806 BASE_TYPE_UNMARSHALL(ULONGLONG);
4807 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
4808 break;
4809 case RPC_FC_ENUM16:
4810 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4811 if (fMustAlloc || !*ppMemory)
4812 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
4813 TRACE("*ppMemory: %p\n", *ppMemory);
4814 /* 16-bits on the wire, but int in memory */
4815 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
4816 pStubMsg->Buffer += sizeof(USHORT);
4817 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
4818 break;
4819 default:
4820 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4822 #undef BASE_TYPE_UNMARSHALL
4824 /* FIXME: what is the correct return value? */
4826 return NULL;
4829 /***********************************************************************
4830 * NdrBaseTypeBufferSize [internal]
4832 static void WINAPI NdrBaseTypeBufferSize(
4833 PMIDL_STUB_MESSAGE pStubMsg,
4834 unsigned char *pMemory,
4835 PFORMAT_STRING pFormat)
4837 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4839 switch(*pFormat)
4841 case RPC_FC_BYTE:
4842 case RPC_FC_CHAR:
4843 case RPC_FC_SMALL:
4844 case RPC_FC_USMALL:
4845 pStubMsg->BufferLength += sizeof(UCHAR);
4846 break;
4847 case RPC_FC_WCHAR:
4848 case RPC_FC_SHORT:
4849 case RPC_FC_USHORT:
4850 case RPC_FC_ENUM16:
4851 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
4852 pStubMsg->BufferLength += sizeof(USHORT);
4853 break;
4854 case RPC_FC_LONG:
4855 case RPC_FC_ULONG:
4856 case RPC_FC_ENUM32:
4857 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
4858 pStubMsg->BufferLength += sizeof(ULONG);
4859 break;
4860 case RPC_FC_FLOAT:
4861 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
4862 pStubMsg->BufferLength += sizeof(float);
4863 break;
4864 case RPC_FC_DOUBLE:
4865 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
4866 pStubMsg->BufferLength += sizeof(double);
4867 break;
4868 case RPC_FC_HYPER:
4869 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
4870 pStubMsg->BufferLength += sizeof(ULONGLONG);
4871 break;
4872 case RPC_FC_ERROR_STATUS_T:
4873 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
4874 pStubMsg->BufferLength += sizeof(error_status_t);
4875 break;
4876 default:
4877 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4881 /***********************************************************************
4882 * NdrBaseTypeMemorySize [internal]
4884 static ULONG WINAPI NdrBaseTypeMemorySize(
4885 PMIDL_STUB_MESSAGE pStubMsg,
4886 PFORMAT_STRING pFormat)
4888 switch(*pFormat)
4890 case RPC_FC_BYTE:
4891 case RPC_FC_CHAR:
4892 case RPC_FC_SMALL:
4893 case RPC_FC_USMALL:
4894 pStubMsg->Buffer += sizeof(UCHAR);
4895 pStubMsg->MemorySize += sizeof(UCHAR);
4896 return sizeof(UCHAR);
4897 case RPC_FC_WCHAR:
4898 case RPC_FC_SHORT:
4899 case RPC_FC_USHORT:
4900 pStubMsg->Buffer += sizeof(USHORT);
4901 pStubMsg->MemorySize += sizeof(USHORT);
4902 return sizeof(USHORT);
4903 case RPC_FC_LONG:
4904 case RPC_FC_ULONG:
4905 pStubMsg->Buffer += sizeof(ULONG);
4906 pStubMsg->MemorySize += sizeof(ULONG);
4907 return sizeof(ULONG);
4908 case RPC_FC_FLOAT:
4909 pStubMsg->Buffer += sizeof(float);
4910 pStubMsg->MemorySize += sizeof(float);
4911 return sizeof(float);
4912 case RPC_FC_DOUBLE:
4913 pStubMsg->Buffer += sizeof(double);
4914 pStubMsg->MemorySize += sizeof(double);
4915 return sizeof(double);
4916 case RPC_FC_HYPER:
4917 pStubMsg->Buffer += sizeof(ULONGLONG);
4918 pStubMsg->MemorySize += sizeof(ULONGLONG);
4919 return sizeof(ULONGLONG);
4920 case RPC_FC_ERROR_STATUS_T:
4921 pStubMsg->Buffer += sizeof(error_status_t);
4922 pStubMsg->MemorySize += sizeof(error_status_t);
4923 return sizeof(error_status_t);
4924 case RPC_FC_ENUM16:
4925 case RPC_FC_ENUM32:
4926 pStubMsg->Buffer += sizeof(INT);
4927 pStubMsg->MemorySize += sizeof(INT);
4928 return sizeof(INT);
4929 default:
4930 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4931 return 0;
4935 /***********************************************************************
4936 * NdrBaseTypeFree [internal]
4938 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
4939 unsigned char *pMemory,
4940 PFORMAT_STRING pFormat)
4942 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4944 /* nothing to do */
4947 /***********************************************************************
4948 * NdrClientContextMarshall [RPCRT4.@]
4950 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4951 NDR_CCONTEXT ContextHandle,
4952 int fCheck)
4954 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
4956 ALIGN_POINTER(pStubMsg->Buffer, 4);
4958 /* FIXME: what does fCheck do? */
4959 NDRCContextMarshall(ContextHandle,
4960 pStubMsg->Buffer);
4962 pStubMsg->Buffer += cbNDRContext;
4965 /***********************************************************************
4966 * NdrClientContextUnmarshall [RPCRT4.@]
4968 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4969 NDR_CCONTEXT * pContextHandle,
4970 RPC_BINDING_HANDLE BindHandle)
4972 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
4974 ALIGN_POINTER(pStubMsg->Buffer, 4);
4976 NDRCContextUnmarshall(pContextHandle,
4977 BindHandle,
4978 pStubMsg->Buffer,
4979 pStubMsg->RpcMsg->DataRepresentation);
4981 pStubMsg->Buffer += cbNDRContext;
4984 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4985 NDR_SCONTEXT ContextHandle,
4986 NDR_RUNDOWN RundownRoutine )
4988 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
4991 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
4993 FIXME("(%p): stub\n", pStubMsg);
4994 return NULL;
4997 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
4998 unsigned char* pMemory,
4999 PFORMAT_STRING pFormat)
5001 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
5004 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
5005 PFORMAT_STRING pFormat)
5007 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
5008 return NULL;
5011 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5012 NDR_SCONTEXT ContextHandle,
5013 NDR_RUNDOWN RundownRoutine,
5014 PFORMAT_STRING pFormat)
5016 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
5019 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5020 PFORMAT_STRING pFormat)
5022 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
5023 return NULL;
5026 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
5028 typedef struct ndr_context_handle
5030 DWORD attributes;
5031 GUID uuid;
5032 } ndr_context_handle;
5034 struct context_handle_entry
5036 struct list entry;
5037 DWORD magic;
5038 RPC_BINDING_HANDLE handle;
5039 ndr_context_handle wire_data;
5042 static struct list context_handle_list = LIST_INIT(context_handle_list);
5044 static CRITICAL_SECTION ndr_context_cs;
5045 static CRITICAL_SECTION_DEBUG ndr_context_debug =
5047 0, 0, &ndr_context_cs,
5048 { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
5049 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
5051 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
5053 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
5055 struct context_handle_entry *che = (struct context_handle_entry*) CContext;
5057 if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
5058 return NULL;
5059 return che;
5062 static struct context_handle_entry *context_entry_from_guid(LPGUID uuid)
5064 struct context_handle_entry *che;
5065 LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
5066 if (IsEqualGUID(&che->wire_data.uuid, uuid))
5067 return che;
5068 return NULL;
5071 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
5073 struct context_handle_entry *che;
5074 RPC_BINDING_HANDLE handle = NULL;
5076 TRACE("%p\n", CContext);
5078 EnterCriticalSection(&ndr_context_cs);
5079 che = get_context_entry(CContext);
5080 if (che)
5081 handle = che->handle;
5082 LeaveCriticalSection(&ndr_context_cs);
5084 if (!handle)
5085 RpcRaiseException(ERROR_INVALID_HANDLE);
5086 return handle;
5089 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
5091 struct context_handle_entry *che;
5093 TRACE("%p %p\n", CContext, pBuff);
5095 if (CContext)
5097 EnterCriticalSection(&ndr_context_cs);
5098 che = get_context_entry(CContext);
5099 memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
5100 LeaveCriticalSection(&ndr_context_cs);
5102 else
5104 ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
5105 wire_data->attributes = 0;
5106 wire_data->uuid = GUID_NULL;
5110 static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
5111 RPC_BINDING_HANDLE hBinding,
5112 ndr_context_handle *chi)
5114 struct context_handle_entry *che = NULL;
5116 /* a null UUID means we should free the context handle */
5117 if (IsEqualGUID(&chi->uuid, &GUID_NULL))
5119 if (*CContext)
5121 che = get_context_entry(*CContext);
5122 if (!che)
5123 return ERROR_INVALID_HANDLE;
5124 list_remove(&che->entry);
5125 RpcBindingFree(&che->handle);
5126 HeapFree(GetProcessHeap(), 0, che);
5127 che = NULL;
5130 /* if there's no existing entry matching the GUID, allocate one */
5131 else if (!(che = context_entry_from_guid(&chi->uuid)))
5133 che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
5134 if (!che)
5135 return ERROR_NOT_ENOUGH_MEMORY;
5136 che->magic = NDR_CONTEXT_HANDLE_MAGIC;
5137 RpcBindingCopy(hBinding, &che->handle);
5138 list_add_tail(&context_handle_list, &che->entry);
5139 memcpy(&che->wire_data, chi, sizeof *chi);
5142 *CContext = che;
5144 return ERROR_SUCCESS;
5147 /***********************************************************************
5148 * NDRCContextUnmarshall [RPCRT4.@]
5150 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
5151 RPC_BINDING_HANDLE hBinding,
5152 void *pBuff, ULONG DataRepresentation)
5154 UINT r;
5156 TRACE("*%p=(%p) %p %p %08x\n",
5157 CContext, *CContext, hBinding, pBuff, DataRepresentation);
5159 EnterCriticalSection(&ndr_context_cs);
5160 r = ndr_update_context_handle(CContext, hBinding, pBuff);
5161 LeaveCriticalSection(&ndr_context_cs);
5162 if (r)
5163 RpcRaiseException(r);
5166 /***********************************************************************
5167 * NDRSContextMarshall [RPCRT4.@]
5169 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
5170 void *pBuff,
5171 NDR_RUNDOWN userRunDownIn)
5173 FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn);
5176 /***********************************************************************
5177 * NDRSContextMarshallEx [RPCRT4.@]
5179 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
5180 NDR_SCONTEXT CContext,
5181 void *pBuff,
5182 NDR_RUNDOWN userRunDownIn)
5184 FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn);
5187 /***********************************************************************
5188 * NDRSContextMarshall2 [RPCRT4.@]
5190 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
5191 NDR_SCONTEXT CContext,
5192 void *pBuff,
5193 NDR_RUNDOWN userRunDownIn,
5194 void *CtxGuard, ULONG Flags)
5196 FIXME("(%p %p %p %p %p %u): stub\n",
5197 hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags);
5200 /***********************************************************************
5201 * NDRSContextUnmarshall [RPCRT4.@]
5203 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
5204 ULONG DataRepresentation)
5206 FIXME("(%p %08x): stub\n", pBuff, DataRepresentation);
5207 return NULL;
5210 /***********************************************************************
5211 * NDRSContextUnmarshallEx [RPCRT4.@]
5213 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
5214 void *pBuff,
5215 ULONG DataRepresentation)
5217 FIXME("(%p %p %08x): stub\n", hBinding, pBuff, DataRepresentation);
5218 return NULL;
5221 /***********************************************************************
5222 * NDRSContextUnmarshall2 [RPCRT4.@]
5224 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
5225 void *pBuff,
5226 ULONG DataRepresentation,
5227 void *CtxGuard, ULONG Flags)
5229 FIXME("(%p %p %08x %p %u): stub\n",
5230 hBinding, pBuff, DataRepresentation, CtxGuard, Flags);
5231 return NULL;