push aea352fc3df615e3f4b48daf6f897ea93ad1fffd
[wine/hacks.git] / dlls / rpcrt4 / ndr_marshall.c
blobd8395b80d44ee3d63da6d7e608d7a01616169106
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 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
122 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
123 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
125 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
127 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
128 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
129 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
130 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
131 /* 0x10 */
132 NdrBaseTypeMarshall,
133 /* 0x11 */
134 NdrPointerMarshall, NdrPointerMarshall,
135 NdrPointerMarshall, NdrPointerMarshall,
136 /* 0x15 */
137 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
138 NdrConformantStructMarshall, NdrConformantStructMarshall,
139 NdrConformantVaryingStructMarshall,
140 NdrComplexStructMarshall,
141 /* 0x1b */
142 NdrConformantArrayMarshall,
143 NdrConformantVaryingArrayMarshall,
144 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
145 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
146 NdrComplexArrayMarshall,
147 /* 0x22 */
148 NdrConformantStringMarshall, 0, 0,
149 NdrConformantStringMarshall,
150 NdrNonConformantStringMarshall, 0, 0, 0,
151 /* 0x2a */
152 NdrEncapsulatedUnionMarshall,
153 NdrNonEncapsulatedUnionMarshall,
154 NdrByteCountPointerMarshall,
155 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
156 /* 0x2f */
157 NdrInterfacePointerMarshall,
158 /* 0x30 */
159 NdrContextHandleMarshall,
160 /* 0xb1 */
161 0, 0, 0,
162 NdrUserMarshalMarshall,
163 0, 0,
164 /* 0xb7 */
165 NdrRangeMarshall
167 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
169 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
170 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
171 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
172 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
173 /* 0x10 */
174 NdrBaseTypeUnmarshall,
175 /* 0x11 */
176 NdrPointerUnmarshall, NdrPointerUnmarshall,
177 NdrPointerUnmarshall, NdrPointerUnmarshall,
178 /* 0x15 */
179 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
180 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
181 NdrConformantVaryingStructUnmarshall,
182 NdrComplexStructUnmarshall,
183 /* 0x1b */
184 NdrConformantArrayUnmarshall,
185 NdrConformantVaryingArrayUnmarshall,
186 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
187 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
188 NdrComplexArrayUnmarshall,
189 /* 0x22 */
190 NdrConformantStringUnmarshall, 0, 0,
191 NdrConformantStringUnmarshall,
192 NdrNonConformantStringUnmarshall, 0, 0, 0,
193 /* 0x2a */
194 NdrEncapsulatedUnionUnmarshall,
195 NdrNonEncapsulatedUnionUnmarshall,
196 NdrByteCountPointerUnmarshall,
197 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
198 /* 0x2f */
199 NdrInterfacePointerUnmarshall,
200 /* 0x30 */
201 NdrContextHandleUnmarshall,
202 /* 0xb1 */
203 0, 0, 0,
204 NdrUserMarshalUnmarshall,
205 0, 0,
206 /* 0xb7 */
207 NdrRangeUnmarshall
209 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
211 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
212 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
213 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
214 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
215 /* 0x10 */
216 NdrBaseTypeBufferSize,
217 /* 0x11 */
218 NdrPointerBufferSize, NdrPointerBufferSize,
219 NdrPointerBufferSize, NdrPointerBufferSize,
220 /* 0x15 */
221 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
222 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
223 NdrConformantVaryingStructBufferSize,
224 NdrComplexStructBufferSize,
225 /* 0x1b */
226 NdrConformantArrayBufferSize,
227 NdrConformantVaryingArrayBufferSize,
228 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
229 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
230 NdrComplexArrayBufferSize,
231 /* 0x22 */
232 NdrConformantStringBufferSize, 0, 0,
233 NdrConformantStringBufferSize,
234 NdrNonConformantStringBufferSize, 0, 0, 0,
235 /* 0x2a */
236 NdrEncapsulatedUnionBufferSize,
237 NdrNonEncapsulatedUnionBufferSize,
238 NdrByteCountPointerBufferSize,
239 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
240 /* 0x2f */
241 NdrInterfacePointerBufferSize,
242 /* 0x30 */
243 NdrContextHandleBufferSize,
244 /* 0xb1 */
245 0, 0, 0,
246 NdrUserMarshalBufferSize,
247 0, 0,
248 /* 0xb7 */
249 NdrRangeBufferSize
251 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
253 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
254 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
255 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
256 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
257 /* 0x10 */
258 NdrBaseTypeMemorySize,
259 /* 0x11 */
260 NdrPointerMemorySize, NdrPointerMemorySize,
261 NdrPointerMemorySize, NdrPointerMemorySize,
262 /* 0x15 */
263 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
264 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
265 NdrConformantVaryingStructMemorySize,
266 NdrComplexStructMemorySize,
267 /* 0x1b */
268 NdrConformantArrayMemorySize,
269 NdrConformantVaryingArrayMemorySize,
270 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
271 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
272 NdrComplexArrayMemorySize,
273 /* 0x22 */
274 NdrConformantStringMemorySize, 0, 0,
275 NdrConformantStringMemorySize,
276 NdrNonConformantStringMemorySize, 0, 0, 0,
277 /* 0x2a */
278 NdrEncapsulatedUnionMemorySize,
279 NdrNonEncapsulatedUnionMemorySize,
280 NdrByteCountPointerMemorySize,
281 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
282 /* 0x2f */
283 NdrInterfacePointerMemorySize,
284 /* 0x30 */
286 /* 0xb1 */
287 0, 0, 0,
288 NdrUserMarshalMemorySize,
289 0, 0,
290 /* 0xb7 */
291 NdrRangeMemorySize
293 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
295 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
296 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
297 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
298 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
299 /* 0x10 */
300 NdrBaseTypeFree,
301 /* 0x11 */
302 NdrPointerFree, NdrPointerFree,
303 NdrPointerFree, NdrPointerFree,
304 /* 0x15 */
305 NdrSimpleStructFree, NdrSimpleStructFree,
306 NdrConformantStructFree, NdrConformantStructFree,
307 NdrConformantVaryingStructFree,
308 NdrComplexStructFree,
309 /* 0x1b */
310 NdrConformantArrayFree,
311 NdrConformantVaryingArrayFree,
312 NdrFixedArrayFree, NdrFixedArrayFree,
313 NdrVaryingArrayFree, NdrVaryingArrayFree,
314 NdrComplexArrayFree,
315 /* 0x22 */
316 0, 0, 0,
317 0, 0, 0, 0, 0,
318 /* 0x2a */
319 NdrEncapsulatedUnionFree,
320 NdrNonEncapsulatedUnionFree,
322 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
323 /* 0x2f */
324 NdrInterfacePointerFree,
325 /* 0x30 */
327 /* 0xb1 */
328 0, 0, 0,
329 NdrUserMarshalFree,
330 0, 0,
331 /* 0xb7 */
332 NdrRangeFree
335 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
337 /* hmm, this is probably supposed to do more? */
338 return pStubMsg->pfnAllocate(len);
341 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
343 pStubMsg->pfnFree(Pointer);
346 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
348 return (*(const ULONG *)pFormat != -1);
351 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
353 ALIGN_POINTER(pStubMsg->Buffer, 4);
354 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
355 pStubMsg->Buffer += 4;
356 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
357 if (pStubMsg->fHasNewCorrDesc)
358 return pFormat+6;
359 else
360 return pFormat+4;
363 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
365 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
367 pStubMsg->Offset = 0;
368 pStubMsg->ActualCount = pStubMsg->MaxCount;
369 goto done;
372 ALIGN_POINTER(pStubMsg->Buffer, 4);
373 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
374 pStubMsg->Buffer += 4;
375 TRACE("offset is %d\n", pStubMsg->Offset);
376 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
377 pStubMsg->Buffer += 4;
378 TRACE("variance is %d\n", pStubMsg->ActualCount);
380 if ((pStubMsg->ActualCount > MaxValue) ||
381 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
383 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
384 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
385 RpcRaiseException(RPC_S_INVALID_BOUND);
386 return NULL;
389 done:
390 if (pStubMsg->fHasNewCorrDesc)
391 return pFormat+6;
392 else
393 return pFormat+4;
396 /* writes the conformance value to the buffer */
397 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
399 ALIGN_POINTER(pStubMsg->Buffer, 4);
400 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
401 pStubMsg->Buffer += 4;
404 /* writes the variance values to the buffer */
405 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
407 ALIGN_POINTER(pStubMsg->Buffer, 4);
408 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
409 pStubMsg->Buffer += 4;
410 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
411 pStubMsg->Buffer += 4;
414 /* requests buffer space for the conformance value */
415 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
417 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
418 pStubMsg->BufferLength += 4;
421 /* requests buffer space for the variance values */
422 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
424 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
425 pStubMsg->BufferLength += 8;
428 PFORMAT_STRING ComputeConformanceOrVariance(
429 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
430 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
432 BYTE dtype = pFormat[0] & 0xf;
433 short ofs = *(const short *)&pFormat[2];
434 LPVOID ptr = NULL;
435 DWORD data = 0;
437 if (!IsConformanceOrVariancePresent(pFormat)) {
438 /* null descriptor */
439 *pCount = def;
440 goto finish_conf;
443 switch (pFormat[0] & 0xf0) {
444 case RPC_FC_NORMAL_CONFORMANCE:
445 TRACE("normal conformance, ofs=%d\n", ofs);
446 ptr = pMemory;
447 break;
448 case RPC_FC_POINTER_CONFORMANCE:
449 TRACE("pointer conformance, ofs=%d\n", ofs);
450 ptr = pStubMsg->Memory;
451 break;
452 case RPC_FC_TOP_LEVEL_CONFORMANCE:
453 TRACE("toplevel conformance, ofs=%d\n", ofs);
454 if (pStubMsg->StackTop) {
455 ptr = pStubMsg->StackTop;
457 else {
458 /* -Os mode, *pCount is already set */
459 goto finish_conf;
461 break;
462 case RPC_FC_CONSTANT_CONFORMANCE:
463 data = ofs | ((DWORD)pFormat[1] << 16);
464 TRACE("constant conformance, val=%d\n", data);
465 *pCount = data;
466 goto finish_conf;
467 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
468 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
469 if (pStubMsg->StackTop) {
470 ptr = pStubMsg->StackTop;
472 else {
473 /* ? */
474 goto done_conf_grab;
476 break;
477 default:
478 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
481 switch (pFormat[1]) {
482 case RPC_FC_DEREFERENCE:
483 ptr = *(LPVOID*)((char *)ptr + ofs);
484 break;
485 case RPC_FC_CALLBACK:
487 unsigned char *old_stack_top = pStubMsg->StackTop;
488 pStubMsg->StackTop = ptr;
490 /* ofs is index into StubDesc->apfnExprEval */
491 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
492 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
494 pStubMsg->StackTop = old_stack_top;
496 /* the callback function always stores the computed value in MaxCount */
497 *pCount = pStubMsg->MaxCount;
498 goto finish_conf;
500 default:
501 ptr = (char *)ptr + ofs;
502 break;
505 switch (dtype) {
506 case RPC_FC_LONG:
507 case RPC_FC_ULONG:
508 data = *(DWORD*)ptr;
509 break;
510 case RPC_FC_SHORT:
511 data = *(SHORT*)ptr;
512 break;
513 case RPC_FC_USHORT:
514 data = *(USHORT*)ptr;
515 break;
516 case RPC_FC_CHAR:
517 case RPC_FC_SMALL:
518 data = *(CHAR*)ptr;
519 break;
520 case RPC_FC_BYTE:
521 case RPC_FC_USMALL:
522 data = *(UCHAR*)ptr;
523 break;
524 default:
525 FIXME("unknown conformance data type %x\n", dtype);
526 goto done_conf_grab;
528 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
530 done_conf_grab:
531 switch (pFormat[1]) {
532 case RPC_FC_DEREFERENCE: /* already handled */
533 case 0: /* no op */
534 *pCount = data;
535 break;
536 case RPC_FC_ADD_1:
537 *pCount = data + 1;
538 break;
539 case RPC_FC_SUB_1:
540 *pCount = data - 1;
541 break;
542 case RPC_FC_MULT_2:
543 *pCount = data * 2;
544 break;
545 case RPC_FC_DIV_2:
546 *pCount = data / 2;
547 break;
548 default:
549 FIXME("unknown conformance op %d\n", pFormat[1]);
550 goto finish_conf;
553 finish_conf:
554 TRACE("resulting conformance is %ld\n", *pCount);
555 if (pStubMsg->fHasNewCorrDesc)
556 return pFormat+6;
557 else
558 return pFormat+4;
561 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
562 * the result overflows 32-bits */
563 static inline ULONG safe_multiply(ULONG a, ULONG b)
565 ULONGLONG ret = (ULONGLONG)a * b;
566 if (ret > 0xffffffff)
568 RpcRaiseException(RPC_S_INVALID_BOUND);
569 return 0;
571 return ret;
576 * NdrConformantString:
578 * What MS calls a ConformantString is, in DCE terminology,
579 * a Varying-Conformant String.
581 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
582 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
583 * into unmarshalled string)
584 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
585 * [
586 * data: CHARTYPE[maxlen]
587 * ]
588 * ], where CHARTYPE is the appropriate character type (specified externally)
592 /***********************************************************************
593 * NdrConformantStringMarshall [RPCRT4.@]
595 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
596 unsigned char *pszMessage, PFORMAT_STRING pFormat)
598 ULONG esize, size;
600 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
602 if (*pFormat == RPC_FC_C_CSTRING) {
603 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
604 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
605 esize = 1;
607 else if (*pFormat == RPC_FC_C_WSTRING) {
608 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
609 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
610 esize = 2;
612 else {
613 ERR("Unhandled string type: %#x\n", *pFormat);
614 /* FIXME: raise an exception. */
615 return NULL;
618 if (pFormat[1] == RPC_FC_STRING_SIZED)
619 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
620 else
621 pStubMsg->MaxCount = pStubMsg->ActualCount;
622 pStubMsg->Offset = 0;
623 WriteConformance(pStubMsg);
624 WriteVariance(pStubMsg);
626 size = safe_multiply(esize, pStubMsg->ActualCount);
627 memcpy(pStubMsg->Buffer, pszMessage, size); /* the string itself */
628 pStubMsg->Buffer += size;
630 STD_OVERFLOW_CHECK(pStubMsg);
632 /* success */
633 return NULL; /* is this always right? */
636 /***********************************************************************
637 * NdrConformantStringBufferSize [RPCRT4.@]
639 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
640 unsigned char* pMemory, PFORMAT_STRING pFormat)
642 ULONG esize;
644 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
646 SizeConformance(pStubMsg);
647 SizeVariance(pStubMsg);
649 if (*pFormat == RPC_FC_C_CSTRING) {
650 TRACE("string=%s\n", debugstr_a((char*)pMemory));
651 pStubMsg->ActualCount = strlen((char*)pMemory)+1;
652 esize = 1;
654 else if (*pFormat == RPC_FC_C_WSTRING) {
655 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
656 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;
657 esize = 2;
659 else {
660 ERR("Unhandled string type: %#x\n", *pFormat);
661 /* FIXME: raise an exception */
662 return;
665 if (pFormat[1] == RPC_FC_STRING_SIZED)
666 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
667 else
668 pStubMsg->MaxCount = pStubMsg->ActualCount;
670 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
673 /************************************************************************
674 * NdrConformantStringMemorySize [RPCRT4.@]
676 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
677 PFORMAT_STRING pFormat )
679 ULONG rslt = 0;
681 FIXME("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
683 assert(pStubMsg && pFormat);
685 if (*pFormat == RPC_FC_C_CSTRING) {
686 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
688 else if (*pFormat == RPC_FC_C_WSTRING) {
689 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
691 else {
692 ERR("Unhandled string type: %#x\n", *pFormat);
693 /* FIXME: raise an exception */
696 if (pFormat[1] != RPC_FC_PAD) {
697 FIXME("sized string format=%d\n", pFormat[1]);
700 TRACE(" --> %u\n", rslt);
701 return rslt;
704 /************************************************************************
705 * NdrConformantStringUnmarshall [RPCRT4.@]
707 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
708 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
710 ULONG bufsize, memsize, esize, i;
712 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
713 pStubMsg, *ppMemory, pFormat, fMustAlloc);
715 assert(pFormat && ppMemory && pStubMsg);
717 ReadConformance(pStubMsg, NULL);
718 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
720 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
721 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
722 else {
723 ERR("Unhandled string type: %#x\n", *pFormat);
724 /* FIXME: raise an exception */
725 esize = 0;
728 memsize = safe_multiply(esize, pStubMsg->MaxCount);
729 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
731 /* strings must always have null terminating bytes */
732 if (bufsize < esize)
734 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
735 RpcRaiseException(RPC_S_INVALID_BOUND);
736 return NULL;
738 for (i = bufsize - esize; i < bufsize; i++)
739 if (pStubMsg->Buffer[i] != 0)
741 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
742 i, pStubMsg->Buffer[i]);
743 RpcRaiseException(RPC_S_INVALID_BOUND);
744 return NULL;
747 if (fMustAlloc || !*ppMemory)
748 *ppMemory = NdrAllocate(pStubMsg, memsize);
750 memcpy(*ppMemory, pStubMsg->Buffer, bufsize);
752 pStubMsg->Buffer += bufsize;
754 if (*pFormat == RPC_FC_C_CSTRING) {
755 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
757 else if (*pFormat == RPC_FC_C_WSTRING) {
758 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
761 return NULL; /* FIXME: is this always right? */
764 /***********************************************************************
765 * NdrNonConformantStringMarshall [RPCRT4.@]
767 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
768 unsigned char *pMemory,
769 PFORMAT_STRING pFormat)
771 FIXME("stub\n");
772 return NULL;
775 /***********************************************************************
776 * NdrNonConformantStringUnmarshall [RPCRT4.@]
778 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
779 unsigned char **ppMemory,
780 PFORMAT_STRING pFormat,
781 unsigned char fMustAlloc)
783 FIXME("stub\n");
784 return NULL;
787 /***********************************************************************
788 * NdrNonConformantStringBufferSize [RPCRT4.@]
790 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
791 unsigned char *pMemory,
792 PFORMAT_STRING pFormat)
794 FIXME("stub\n");
797 /***********************************************************************
798 * NdrNonConformantStringMemorySize [RPCRT4.@]
800 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
801 PFORMAT_STRING pFormat)
803 FIXME("stub\n");
804 return 0;
807 static inline void dump_pointer_attr(unsigned char attr)
809 if (attr & RPC_FC_P_ALLOCALLNODES)
810 TRACE(" RPC_FC_P_ALLOCALLNODES");
811 if (attr & RPC_FC_P_DONTFREE)
812 TRACE(" RPC_FC_P_DONTFREE");
813 if (attr & RPC_FC_P_ONSTACK)
814 TRACE(" RPC_FC_P_ONSTACK");
815 if (attr & RPC_FC_P_SIMPLEPOINTER)
816 TRACE(" RPC_FC_P_SIMPLEPOINTER");
817 if (attr & RPC_FC_P_DEREF)
818 TRACE(" RPC_FC_P_DEREF");
819 TRACE("\n");
822 /***********************************************************************
823 * PointerMarshall [internal]
825 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
826 unsigned char *Buffer,
827 unsigned char *Pointer,
828 PFORMAT_STRING pFormat)
830 unsigned type = pFormat[0], attr = pFormat[1];
831 PFORMAT_STRING desc;
832 NDR_MARSHALL m;
833 ULONG pointer_id;
834 int pointer_needs_marshaling;
836 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
837 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
838 pFormat += 2;
839 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
840 else desc = pFormat + *(const SHORT*)pFormat;
842 switch (type) {
843 case RPC_FC_RP: /* ref pointer (always non-null) */
844 #if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
845 if (!Pointer)
846 RpcRaiseException(RPC_X_NULL_REF_POINTER);
847 #endif
848 pointer_needs_marshaling = 1;
849 break;
850 case RPC_FC_UP: /* unique pointer */
851 case RPC_FC_OP: /* object pointer - same as unique here */
852 if (Pointer)
853 pointer_needs_marshaling = 1;
854 else
855 pointer_needs_marshaling = 0;
856 pointer_id = (ULONG)Pointer;
857 TRACE("writing 0x%08x to buffer\n", pointer_id);
858 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
859 break;
860 case RPC_FC_FP:
861 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
862 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
863 TRACE("writing 0x%08x to buffer\n", pointer_id);
864 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
865 break;
866 default:
867 FIXME("unhandled ptr type=%02x\n", type);
868 RpcRaiseException(RPC_X_BAD_STUB_DATA);
869 return;
872 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
874 if (pointer_needs_marshaling) {
875 if (attr & RPC_FC_P_DEREF) {
876 Pointer = *(unsigned char**)Pointer;
877 TRACE("deref => %p\n", Pointer);
879 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
880 if (m) m(pStubMsg, Pointer, desc);
881 else FIXME("no marshaller for data type=%02x\n", *desc);
884 STD_OVERFLOW_CHECK(pStubMsg);
887 /***********************************************************************
888 * PointerUnmarshall [internal]
890 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
891 unsigned char *Buffer,
892 unsigned char **pPointer,
893 PFORMAT_STRING pFormat,
894 unsigned char fMustAlloc)
896 unsigned type = pFormat[0], attr = pFormat[1];
897 PFORMAT_STRING desc;
898 NDR_UNMARSHALL m;
899 DWORD pointer_id = 0;
900 int pointer_needs_unmarshaling;
902 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pFormat, fMustAlloc);
903 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
904 pFormat += 2;
905 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
906 else desc = pFormat + *(const SHORT*)pFormat;
908 switch (type) {
909 case RPC_FC_RP: /* ref pointer (always non-null) */
910 pointer_needs_unmarshaling = 1;
911 break;
912 case RPC_FC_UP: /* unique pointer */
913 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
914 TRACE("pointer_id is 0x%08x\n", pointer_id);
915 if (pointer_id)
916 pointer_needs_unmarshaling = 1;
917 else {
918 *pPointer = NULL;
919 pointer_needs_unmarshaling = 0;
921 break;
922 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
923 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
924 TRACE("pointer_id is 0x%08x\n", pointer_id);
925 if (!fMustAlloc && *pPointer)
927 FIXME("free object pointer %p\n", *pPointer);
928 *pPointer = NULL;
930 if (pointer_id)
931 pointer_needs_unmarshaling = 1;
932 else
933 pointer_needs_unmarshaling = 0;
934 break;
935 case RPC_FC_FP:
936 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
937 TRACE("pointer_id is 0x%08x\n", pointer_id);
938 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
939 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
940 break;
941 default:
942 FIXME("unhandled ptr type=%02x\n", type);
943 RpcRaiseException(RPC_X_BAD_STUB_DATA);
944 return;
947 if (pointer_needs_unmarshaling) {
948 if (attr & RPC_FC_P_DEREF) {
949 if (!*pPointer || fMustAlloc)
950 *pPointer = NdrAllocate(pStubMsg, sizeof(void *));
951 pPointer = *(unsigned char***)pPointer;
952 TRACE("deref => %p\n", pPointer);
954 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
955 if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
956 else FIXME("no unmarshaller for data type=%02x\n", *desc);
958 if (type == RPC_FC_FP)
959 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
960 *pPointer);
963 TRACE("pointer=%p\n", *pPointer);
966 /***********************************************************************
967 * PointerBufferSize [internal]
969 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
970 unsigned char *Pointer,
971 PFORMAT_STRING pFormat)
973 unsigned type = pFormat[0], attr = pFormat[1];
974 PFORMAT_STRING desc;
975 NDR_BUFFERSIZE m;
976 int pointer_needs_sizing;
977 ULONG pointer_id;
979 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
980 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
981 pFormat += 2;
982 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
983 else desc = pFormat + *(const SHORT*)pFormat;
985 switch (type) {
986 case RPC_FC_RP: /* ref pointer (always non-null) */
987 break;
988 case RPC_FC_OP:
989 case RPC_FC_UP:
990 /* NULL pointer has no further representation */
991 if (!Pointer)
992 return;
993 break;
994 case RPC_FC_FP:
995 pointer_needs_sizing = !NdrFullPointerQueryPointer(
996 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
997 if (!pointer_needs_sizing)
998 return;
999 break;
1000 default:
1001 FIXME("unhandled ptr type=%02x\n", type);
1002 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1003 return;
1006 if (attr & RPC_FC_P_DEREF) {
1007 Pointer = *(unsigned char**)Pointer;
1008 TRACE("deref => %p\n", Pointer);
1011 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1012 if (m) m(pStubMsg, Pointer, desc);
1013 else FIXME("no buffersizer for data type=%02x\n", *desc);
1016 /***********************************************************************
1017 * PointerMemorySize [internal]
1019 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1020 unsigned char *Buffer,
1021 PFORMAT_STRING pFormat)
1023 unsigned type = pFormat[0], attr = pFormat[1];
1024 PFORMAT_STRING desc;
1025 NDR_MEMORYSIZE m;
1027 FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat);
1028 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1029 pFormat += 2;
1030 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1031 else desc = pFormat + *(const SHORT*)pFormat;
1033 switch (type) {
1034 case RPC_FC_RP: /* ref pointer (always non-null) */
1035 break;
1036 default:
1037 FIXME("unhandled ptr type=%02x\n", type);
1038 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1041 if (attr & RPC_FC_P_DEREF) {
1042 TRACE("deref\n");
1045 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1046 if (m) m(pStubMsg, desc);
1047 else FIXME("no memorysizer for data type=%02x\n", *desc);
1049 return 0;
1052 /***********************************************************************
1053 * PointerFree [internal]
1055 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1056 unsigned char *Pointer,
1057 PFORMAT_STRING pFormat)
1059 unsigned type = pFormat[0], attr = pFormat[1];
1060 PFORMAT_STRING desc;
1061 NDR_FREE m;
1063 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1064 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1065 if (attr & RPC_FC_P_DONTFREE) return;
1066 pFormat += 2;
1067 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1068 else desc = pFormat + *(const SHORT*)pFormat;
1070 if (!Pointer) return;
1072 if (type == RPC_FC_FP) {
1073 int pointer_needs_freeing = NdrFullPointerFree(
1074 pStubMsg->FullPtrXlatTables, Pointer);
1075 if (!pointer_needs_freeing)
1076 return;
1079 if (attr & RPC_FC_P_DEREF) {
1080 Pointer = *(unsigned char**)Pointer;
1081 TRACE("deref => %p\n", Pointer);
1084 m = NdrFreer[*desc & NDR_TABLE_MASK];
1085 if (m) m(pStubMsg, Pointer, desc);
1087 /* hmm... is this sensible?
1088 * perhaps we should check if the memory comes from NdrAllocate,
1089 * and deallocate only if so - checking if the pointer is between
1090 * BufferStart and BufferEnd is probably no good since the buffer
1091 * may be reallocated when the server wants to marshal the reply */
1092 switch (*desc) {
1093 case RPC_FC_BOGUS_STRUCT:
1094 case RPC_FC_BOGUS_ARRAY:
1095 case RPC_FC_USER_MARSHAL:
1096 case RPC_FC_CARRAY:
1097 case RPC_FC_CVARRAY:
1098 break;
1099 default:
1100 FIXME("unhandled data type=%02x\n", *desc);
1101 break;
1102 case RPC_FC_C_CSTRING:
1103 case RPC_FC_C_WSTRING:
1104 if (pStubMsg->ReuseBuffer) goto notfree;
1105 break;
1106 case RPC_FC_IP:
1107 goto notfree;
1110 if (attr & RPC_FC_P_ONSTACK) {
1111 TRACE("not freeing stack ptr %p\n", Pointer);
1112 return;
1114 TRACE("freeing %p\n", Pointer);
1115 NdrFree(pStubMsg, Pointer);
1116 return;
1117 notfree:
1118 TRACE("not freeing %p\n", Pointer);
1121 /***********************************************************************
1122 * EmbeddedPointerMarshall
1124 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1125 unsigned char *pMemory,
1126 PFORMAT_STRING pFormat)
1128 unsigned char *Mark = pStubMsg->BufferMark;
1129 unsigned long Offset = pStubMsg->Offset;
1130 unsigned ofs, rep, count, stride, xofs;
1131 unsigned i;
1132 unsigned char *saved_buffer = NULL;
1134 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1136 if (*pFormat != RPC_FC_PP) return NULL;
1137 pFormat += 2;
1139 if (pStubMsg->PointerBufferMark)
1141 saved_buffer = pStubMsg->Buffer;
1142 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1143 pStubMsg->PointerBufferMark = NULL;
1146 while (pFormat[0] != RPC_FC_END) {
1147 switch (pFormat[0]) {
1148 default:
1149 FIXME("unknown repeat type %d\n", pFormat[0]);
1150 case RPC_FC_NO_REPEAT:
1151 rep = 1;
1152 stride = 0;
1153 ofs = 0;
1154 count = 1;
1155 xofs = 0;
1156 pFormat += 2;
1157 break;
1158 case RPC_FC_FIXED_REPEAT:
1159 rep = *(const WORD*)&pFormat[2];
1160 stride = *(const WORD*)&pFormat[4];
1161 ofs = *(const WORD*)&pFormat[6];
1162 count = *(const WORD*)&pFormat[8];
1163 xofs = 0;
1164 pFormat += 10;
1165 break;
1166 case RPC_FC_VARIABLE_REPEAT:
1167 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1168 stride = *(const WORD*)&pFormat[2];
1169 ofs = *(const WORD*)&pFormat[4];
1170 count = *(const WORD*)&pFormat[6];
1171 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1172 pFormat += 8;
1173 break;
1175 for (i = 0; i < rep; i++) {
1176 PFORMAT_STRING info = pFormat;
1177 unsigned char *membase = pMemory + ofs + (i * stride);
1178 unsigned char *bufbase = Mark + ofs + (i * stride);
1179 unsigned u;
1181 for (u=0; u<count; u++,info+=8) {
1182 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1183 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1184 unsigned char *saved_memory = pStubMsg->Memory;
1186 pStubMsg->Memory = pMemory;
1187 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1188 pStubMsg->Memory = saved_memory;
1191 pFormat += 8 * count;
1194 if (saved_buffer)
1196 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1197 pStubMsg->Buffer = saved_buffer;
1200 STD_OVERFLOW_CHECK(pStubMsg);
1202 return NULL;
1205 /***********************************************************************
1206 * EmbeddedPointerUnmarshall
1208 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1209 unsigned char **ppMemory,
1210 PFORMAT_STRING pFormat,
1211 unsigned char fMustAlloc)
1213 unsigned char *Mark = pStubMsg->BufferMark;
1214 unsigned long Offset = pStubMsg->Offset;
1215 unsigned ofs, rep, count, stride, xofs;
1216 unsigned i;
1217 unsigned char *saved_buffer = NULL;
1219 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1221 if (*pFormat != RPC_FC_PP) return NULL;
1222 pFormat += 2;
1224 if (pStubMsg->PointerBufferMark)
1226 saved_buffer = pStubMsg->Buffer;
1227 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1228 pStubMsg->PointerBufferMark = NULL;
1231 while (pFormat[0] != RPC_FC_END) {
1232 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1233 switch (pFormat[0]) {
1234 default:
1235 FIXME("unknown repeat type %d\n", pFormat[0]);
1236 case RPC_FC_NO_REPEAT:
1237 rep = 1;
1238 stride = 0;
1239 ofs = 0;
1240 count = 1;
1241 xofs = 0;
1242 pFormat += 2;
1243 break;
1244 case RPC_FC_FIXED_REPEAT:
1245 rep = *(const WORD*)&pFormat[2];
1246 stride = *(const WORD*)&pFormat[4];
1247 ofs = *(const WORD*)&pFormat[6];
1248 count = *(const WORD*)&pFormat[8];
1249 xofs = 0;
1250 pFormat += 10;
1251 break;
1252 case RPC_FC_VARIABLE_REPEAT:
1253 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1254 stride = *(const WORD*)&pFormat[2];
1255 ofs = *(const WORD*)&pFormat[4];
1256 count = *(const WORD*)&pFormat[6];
1257 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1258 pFormat += 8;
1259 break;
1261 /* ofs doesn't seem to matter in this context */
1262 for (i = 0; i < rep; i++) {
1263 PFORMAT_STRING info = pFormat;
1264 unsigned char *membase = *ppMemory + ofs + (i * stride);
1265 unsigned char *bufbase = Mark + ofs + (i * stride);
1266 unsigned u;
1268 for (u=0; u<count; u++,info+=8) {
1269 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1270 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1271 PointerUnmarshall(pStubMsg, bufptr, (unsigned char**)memptr, info+4, TRUE);
1274 pFormat += 8 * count;
1277 if (saved_buffer)
1279 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1280 pStubMsg->Buffer = saved_buffer;
1283 return NULL;
1286 /***********************************************************************
1287 * EmbeddedPointerBufferSize
1289 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1290 unsigned char *pMemory,
1291 PFORMAT_STRING pFormat)
1293 unsigned long Offset = pStubMsg->Offset;
1294 unsigned ofs, rep, count, stride, xofs;
1295 unsigned i;
1296 ULONG saved_buffer_length = 0;
1298 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1300 if (pStubMsg->IgnoreEmbeddedPointers) return;
1302 if (*pFormat != RPC_FC_PP) return;
1303 pFormat += 2;
1305 if (pStubMsg->PointerLength)
1307 saved_buffer_length = pStubMsg->BufferLength;
1308 pStubMsg->BufferLength = pStubMsg->PointerLength;
1309 pStubMsg->PointerLength = 0;
1312 while (pFormat[0] != RPC_FC_END) {
1313 switch (pFormat[0]) {
1314 default:
1315 FIXME("unknown repeat type %d\n", pFormat[0]);
1316 case RPC_FC_NO_REPEAT:
1317 rep = 1;
1318 stride = 0;
1319 ofs = 0;
1320 count = 1;
1321 xofs = 0;
1322 pFormat += 2;
1323 break;
1324 case RPC_FC_FIXED_REPEAT:
1325 rep = *(const WORD*)&pFormat[2];
1326 stride = *(const WORD*)&pFormat[4];
1327 ofs = *(const WORD*)&pFormat[6];
1328 count = *(const WORD*)&pFormat[8];
1329 xofs = 0;
1330 pFormat += 10;
1331 break;
1332 case RPC_FC_VARIABLE_REPEAT:
1333 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1334 stride = *(const WORD*)&pFormat[2];
1335 ofs = *(const WORD*)&pFormat[4];
1336 count = *(const WORD*)&pFormat[6];
1337 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1338 pFormat += 8;
1339 break;
1341 for (i = 0; i < rep; i++) {
1342 PFORMAT_STRING info = pFormat;
1343 unsigned char *membase = pMemory + ofs + (i * stride);
1344 unsigned u;
1346 for (u=0; u<count; u++,info+=8) {
1347 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1348 unsigned char *saved_memory = pStubMsg->Memory;
1350 pStubMsg->Memory = pMemory;
1351 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1352 pStubMsg->Memory = saved_memory;
1355 pFormat += 8 * count;
1358 if (saved_buffer_length)
1360 pStubMsg->PointerLength = pStubMsg->BufferLength;
1361 pStubMsg->BufferLength = saved_buffer_length;
1365 /***********************************************************************
1366 * EmbeddedPointerMemorySize [internal]
1368 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1369 PFORMAT_STRING pFormat)
1371 unsigned long Offset = pStubMsg->Offset;
1372 unsigned char *Mark = pStubMsg->BufferMark;
1373 unsigned ofs, rep, count, stride, xofs;
1374 unsigned i;
1376 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1378 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1380 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1382 if (*pFormat != RPC_FC_PP) return 0;
1383 pFormat += 2;
1385 while (pFormat[0] != RPC_FC_END) {
1386 switch (pFormat[0]) {
1387 default:
1388 FIXME("unknown repeat type %d\n", pFormat[0]);
1389 case RPC_FC_NO_REPEAT:
1390 rep = 1;
1391 stride = 0;
1392 ofs = 0;
1393 count = 1;
1394 xofs = 0;
1395 pFormat += 2;
1396 break;
1397 case RPC_FC_FIXED_REPEAT:
1398 rep = *(const WORD*)&pFormat[2];
1399 stride = *(const WORD*)&pFormat[4];
1400 ofs = *(const WORD*)&pFormat[6];
1401 count = *(const WORD*)&pFormat[8];
1402 xofs = 0;
1403 pFormat += 10;
1404 break;
1405 case RPC_FC_VARIABLE_REPEAT:
1406 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1407 stride = *(const WORD*)&pFormat[2];
1408 ofs = *(const WORD*)&pFormat[4];
1409 count = *(const WORD*)&pFormat[6];
1410 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1411 pFormat += 8;
1412 break;
1414 /* ofs doesn't seem to matter in this context */
1415 for (i = 0; i < rep; i++) {
1416 PFORMAT_STRING info = pFormat;
1417 unsigned char *bufbase = Mark + ofs + (i * stride);
1418 unsigned u;
1419 for (u=0; u<count; u++,info+=8) {
1420 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1421 PointerMemorySize(pStubMsg, bufptr, info+4);
1424 pFormat += 8 * count;
1427 return 0;
1430 /***********************************************************************
1431 * EmbeddedPointerFree [internal]
1433 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1434 unsigned char *pMemory,
1435 PFORMAT_STRING pFormat)
1437 unsigned long Offset = pStubMsg->Offset;
1438 unsigned ofs, rep, count, stride, xofs;
1439 unsigned i;
1441 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1442 if (*pFormat != RPC_FC_PP) return;
1443 pFormat += 2;
1445 while (pFormat[0] != RPC_FC_END) {
1446 switch (pFormat[0]) {
1447 default:
1448 FIXME("unknown repeat type %d\n", pFormat[0]);
1449 case RPC_FC_NO_REPEAT:
1450 rep = 1;
1451 stride = 0;
1452 ofs = 0;
1453 count = 1;
1454 xofs = 0;
1455 pFormat += 2;
1456 break;
1457 case RPC_FC_FIXED_REPEAT:
1458 rep = *(const WORD*)&pFormat[2];
1459 stride = *(const WORD*)&pFormat[4];
1460 ofs = *(const WORD*)&pFormat[6];
1461 count = *(const WORD*)&pFormat[8];
1462 xofs = 0;
1463 pFormat += 10;
1464 break;
1465 case RPC_FC_VARIABLE_REPEAT:
1466 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1467 stride = *(const WORD*)&pFormat[2];
1468 ofs = *(const WORD*)&pFormat[4];
1469 count = *(const WORD*)&pFormat[6];
1470 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1471 pFormat += 8;
1472 break;
1474 for (i = 0; i < rep; i++) {
1475 PFORMAT_STRING info = pFormat;
1476 unsigned char *membase = pMemory + (i * stride);
1477 unsigned u;
1479 for (u=0; u<count; u++,info+=8) {
1480 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1481 unsigned char *saved_memory = pStubMsg->Memory;
1483 pStubMsg->Memory = pMemory;
1484 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1485 pStubMsg->Memory = saved_memory;
1488 pFormat += 8 * count;
1492 /***********************************************************************
1493 * NdrPointerMarshall [RPCRT4.@]
1495 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1496 unsigned char *pMemory,
1497 PFORMAT_STRING pFormat)
1499 unsigned char *Buffer;
1501 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1503 /* incremement the buffer here instead of in PointerMarshall,
1504 * as that is used by embedded pointers which already handle the incrementing
1505 * the buffer, and shouldn't write any additional pointer data to the wire */
1506 if (*pFormat != RPC_FC_RP)
1508 ALIGN_POINTER(pStubMsg->Buffer, 4);
1509 Buffer = pStubMsg->Buffer;
1510 pStubMsg->Buffer += 4;
1512 else
1513 Buffer = pStubMsg->Buffer;
1515 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1517 STD_OVERFLOW_CHECK(pStubMsg);
1519 return NULL;
1522 /***********************************************************************
1523 * NdrPointerUnmarshall [RPCRT4.@]
1525 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1526 unsigned char **ppMemory,
1527 PFORMAT_STRING pFormat,
1528 unsigned char fMustAlloc)
1530 unsigned char *Buffer;
1532 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1534 /* incremement the buffer here instead of in PointerUnmarshall,
1535 * as that is used by embedded pointers which already handle the incrementing
1536 * the buffer, and shouldn't read any additional pointer data from the
1537 * buffer */
1538 if (*pFormat != RPC_FC_RP)
1540 ALIGN_POINTER(pStubMsg->Buffer, 4);
1541 Buffer = pStubMsg->Buffer;
1542 pStubMsg->Buffer += 4;
1544 else
1545 Buffer = pStubMsg->Buffer;
1547 PointerUnmarshall(pStubMsg, Buffer, ppMemory, pFormat, fMustAlloc);
1549 return NULL;
1552 /***********************************************************************
1553 * NdrPointerBufferSize [RPCRT4.@]
1555 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1556 unsigned char *pMemory,
1557 PFORMAT_STRING pFormat)
1559 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1561 /* incremement the buffer length here instead of in PointerBufferSize,
1562 * as that is used by embedded pointers which already handle the buffer
1563 * length, and shouldn't write anything more to the wire */
1564 if (*pFormat != RPC_FC_RP)
1566 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1567 pStubMsg->BufferLength += 4;
1570 PointerBufferSize(pStubMsg, pMemory, pFormat);
1573 /***********************************************************************
1574 * NdrPointerMemorySize [RPCRT4.@]
1576 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1577 PFORMAT_STRING pFormat)
1579 /* unsigned size = *(LPWORD)(pFormat+2); */
1580 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1581 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1582 return 0;
1585 /***********************************************************************
1586 * NdrPointerFree [RPCRT4.@]
1588 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1589 unsigned char *pMemory,
1590 PFORMAT_STRING pFormat)
1592 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1593 PointerFree(pStubMsg, pMemory, pFormat);
1596 /***********************************************************************
1597 * NdrSimpleTypeMarshall [RPCRT4.@]
1599 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1600 unsigned char FormatChar )
1602 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1605 /***********************************************************************
1606 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1608 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1609 unsigned char FormatChar )
1611 NdrBaseTypeUnmarshall(pStubMsg, &pMemory, &FormatChar, 0);
1614 /***********************************************************************
1615 * NdrSimpleStructMarshall [RPCRT4.@]
1617 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1618 unsigned char *pMemory,
1619 PFORMAT_STRING pFormat)
1621 unsigned size = *(const WORD*)(pFormat+2);
1622 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1624 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1626 memcpy(pStubMsg->Buffer, pMemory, size);
1627 pStubMsg->BufferMark = pStubMsg->Buffer;
1628 pStubMsg->Buffer += size;
1630 if (pFormat[0] != RPC_FC_STRUCT)
1631 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1633 STD_OVERFLOW_CHECK(pStubMsg);
1635 return NULL;
1638 /***********************************************************************
1639 * NdrSimpleStructUnmarshall [RPCRT4.@]
1641 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1642 unsigned char **ppMemory,
1643 PFORMAT_STRING pFormat,
1644 unsigned char fMustAlloc)
1646 unsigned size = *(const WORD*)(pFormat+2);
1647 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1649 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1651 if (fMustAlloc) {
1652 *ppMemory = NdrAllocate(pStubMsg, size);
1653 memcpy(*ppMemory, pStubMsg->Buffer, size);
1654 } else {
1655 if (!pStubMsg->IsClient && !*ppMemory)
1656 /* for servers, we just point straight into the RPC buffer */
1657 *ppMemory = pStubMsg->Buffer;
1658 else
1659 /* for clients, memory should be provided by caller */
1660 memcpy(*ppMemory, pStubMsg->Buffer, size);
1663 pStubMsg->BufferMark = pStubMsg->Buffer;
1664 pStubMsg->Buffer += size;
1666 if (pFormat[0] != RPC_FC_STRUCT)
1667 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat+4, fMustAlloc);
1669 return NULL;
1672 /***********************************************************************
1673 * NdrSimpleStructBufferSize [RPCRT4.@]
1675 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1676 unsigned char *pMemory,
1677 PFORMAT_STRING pFormat)
1679 unsigned size = *(const WORD*)(pFormat+2);
1680 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1682 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1684 pStubMsg->BufferLength += size;
1685 if (pFormat[0] != RPC_FC_STRUCT)
1686 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1689 /***********************************************************************
1690 * NdrSimpleStructMemorySize [RPCRT4.@]
1692 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1693 PFORMAT_STRING pFormat)
1695 unsigned short size = *(const WORD *)(pFormat+2);
1697 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1699 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1700 pStubMsg->MemorySize += size;
1701 pStubMsg->Buffer += size;
1703 if (pFormat[0] != RPC_FC_STRUCT)
1704 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1705 return size;
1708 /***********************************************************************
1709 * NdrSimpleStructFree [RPCRT4.@]
1711 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1712 unsigned char *pMemory,
1713 PFORMAT_STRING pFormat)
1715 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1716 if (pFormat[0] != RPC_FC_STRUCT)
1717 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1721 static unsigned long EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg,
1722 PFORMAT_STRING pFormat)
1724 switch (*pFormat) {
1725 case RPC_FC_STRUCT:
1726 case RPC_FC_PSTRUCT:
1727 case RPC_FC_CSTRUCT:
1728 case RPC_FC_BOGUS_STRUCT:
1729 case RPC_FC_SMFARRAY:
1730 case RPC_FC_SMVARRAY:
1731 return *(const WORD*)&pFormat[2];
1732 case RPC_FC_USER_MARSHAL:
1733 return *(const WORD*)&pFormat[4];
1734 case RPC_FC_NON_ENCAPSULATED_UNION:
1735 pFormat += 2;
1736 if (pStubMsg->fHasNewCorrDesc)
1737 pFormat += 6;
1738 else
1739 pFormat += 4;
1741 pFormat += *(const SHORT*)pFormat;
1742 return *(const SHORT*)pFormat;
1743 case RPC_FC_IP:
1744 return sizeof(void *);
1745 default:
1746 FIXME("unhandled embedded type %02x\n", *pFormat);
1748 return 0;
1752 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1753 PFORMAT_STRING pFormat)
1755 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1757 if (!m)
1759 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1760 return 0;
1763 return m(pStubMsg, pFormat);
1767 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1768 unsigned char *pMemory,
1769 PFORMAT_STRING pFormat,
1770 PFORMAT_STRING pPointer)
1772 PFORMAT_STRING desc;
1773 NDR_MARSHALL m;
1774 unsigned long size;
1776 while (*pFormat != RPC_FC_END) {
1777 switch (*pFormat) {
1778 case RPC_FC_BYTE:
1779 case RPC_FC_CHAR:
1780 case RPC_FC_SMALL:
1781 case RPC_FC_USMALL:
1782 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
1783 memcpy(pStubMsg->Buffer, pMemory, 1);
1784 pStubMsg->Buffer += 1;
1785 pMemory += 1;
1786 break;
1787 case RPC_FC_WCHAR:
1788 case RPC_FC_SHORT:
1789 case RPC_FC_USHORT:
1790 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1791 memcpy(pStubMsg->Buffer, pMemory, 2);
1792 pStubMsg->Buffer += 2;
1793 pMemory += 2;
1794 break;
1795 case RPC_FC_LONG:
1796 case RPC_FC_ULONG:
1797 case RPC_FC_ENUM32:
1798 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
1799 memcpy(pStubMsg->Buffer, pMemory, 4);
1800 pStubMsg->Buffer += 4;
1801 pMemory += 4;
1802 break;
1803 case RPC_FC_HYPER:
1804 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1805 memcpy(pStubMsg->Buffer, pMemory, 8);
1806 pStubMsg->Buffer += 8;
1807 pMemory += 8;
1808 break;
1809 case RPC_FC_POINTER:
1811 unsigned char *saved_buffer;
1812 int pointer_buffer_mark_set = 0;
1813 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1814 saved_buffer = pStubMsg->Buffer;
1815 if (pStubMsg->PointerBufferMark)
1817 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1818 pStubMsg->PointerBufferMark = NULL;
1819 pointer_buffer_mark_set = 1;
1821 else
1822 pStubMsg->Buffer += 4; /* for pointer ID */
1823 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
1824 if (pointer_buffer_mark_set)
1826 STD_OVERFLOW_CHECK(pStubMsg);
1827 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1828 pStubMsg->Buffer = saved_buffer + 4;
1830 pPointer += 4;
1831 pMemory += 4;
1832 break;
1834 case RPC_FC_ALIGNM4:
1835 ALIGN_POINTER(pMemory, 4);
1836 break;
1837 case RPC_FC_ALIGNM8:
1838 ALIGN_POINTER(pMemory, 8);
1839 break;
1840 case RPC_FC_STRUCTPAD1:
1841 case RPC_FC_STRUCTPAD2:
1842 case RPC_FC_STRUCTPAD3:
1843 case RPC_FC_STRUCTPAD4:
1844 case RPC_FC_STRUCTPAD5:
1845 case RPC_FC_STRUCTPAD6:
1846 case RPC_FC_STRUCTPAD7:
1847 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1848 break;
1849 case RPC_FC_EMBEDDED_COMPLEX:
1850 pMemory += pFormat[1];
1851 pFormat += 2;
1852 desc = pFormat + *(const SHORT*)pFormat;
1853 size = EmbeddedComplexSize(pStubMsg, desc);
1854 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1855 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1856 if (m)
1858 /* for some reason interface pointers aren't generated as
1859 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
1860 * they still need the derefencing treatment that pointers are
1861 * given */
1862 if (*desc == RPC_FC_IP)
1863 m(pStubMsg, *(unsigned char **)pMemory, desc);
1864 else
1865 m(pStubMsg, pMemory, desc);
1867 else FIXME("no marshaller for embedded type %02x\n", *desc);
1868 pMemory += size;
1869 pFormat += 2;
1870 continue;
1871 case RPC_FC_PAD:
1872 break;
1873 default:
1874 FIXME("unhandled format 0x%02x\n", *pFormat);
1876 pFormat++;
1879 return pMemory;
1882 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1883 unsigned char *pMemory,
1884 PFORMAT_STRING pFormat,
1885 PFORMAT_STRING pPointer)
1887 PFORMAT_STRING desc;
1888 NDR_UNMARSHALL m;
1889 unsigned long size;
1891 while (*pFormat != RPC_FC_END) {
1892 switch (*pFormat) {
1893 case RPC_FC_BYTE:
1894 case RPC_FC_CHAR:
1895 case RPC_FC_SMALL:
1896 case RPC_FC_USMALL:
1897 memcpy(pMemory, pStubMsg->Buffer, 1);
1898 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
1899 pStubMsg->Buffer += 1;
1900 pMemory += 1;
1901 break;
1902 case RPC_FC_WCHAR:
1903 case RPC_FC_SHORT:
1904 case RPC_FC_USHORT:
1905 memcpy(pMemory, pStubMsg->Buffer, 2);
1906 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1907 pStubMsg->Buffer += 2;
1908 pMemory += 2;
1909 break;
1910 case RPC_FC_LONG:
1911 case RPC_FC_ULONG:
1912 case RPC_FC_ENUM32:
1913 memcpy(pMemory, pStubMsg->Buffer, 4);
1914 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
1915 pStubMsg->Buffer += 4;
1916 pMemory += 4;
1917 break;
1918 case RPC_FC_HYPER:
1919 memcpy(pMemory, pStubMsg->Buffer, 8);
1920 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1921 pStubMsg->Buffer += 8;
1922 pMemory += 8;
1923 break;
1924 case RPC_FC_POINTER:
1926 unsigned char *saved_buffer;
1927 int pointer_buffer_mark_set = 0;
1928 TRACE("pointer => %p\n", pMemory);
1929 ALIGN_POINTER(pStubMsg->Buffer, 4);
1930 saved_buffer = pStubMsg->Buffer;
1931 if (pStubMsg->PointerBufferMark)
1933 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1934 pStubMsg->PointerBufferMark = NULL;
1935 pointer_buffer_mark_set = 1;
1937 else
1938 pStubMsg->Buffer += 4; /* for pointer ID */
1940 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, pPointer, TRUE);
1941 if (pointer_buffer_mark_set)
1943 STD_OVERFLOW_CHECK(pStubMsg);
1944 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1945 pStubMsg->Buffer = saved_buffer + 4;
1947 pPointer += 4;
1948 pMemory += 4;
1949 break;
1951 case RPC_FC_ALIGNM4:
1952 ALIGN_POINTER(pMemory, 4);
1953 break;
1954 case RPC_FC_ALIGNM8:
1955 ALIGN_POINTER(pMemory, 8);
1956 break;
1957 case RPC_FC_STRUCTPAD1:
1958 case RPC_FC_STRUCTPAD2:
1959 case RPC_FC_STRUCTPAD3:
1960 case RPC_FC_STRUCTPAD4:
1961 case RPC_FC_STRUCTPAD5:
1962 case RPC_FC_STRUCTPAD6:
1963 case RPC_FC_STRUCTPAD7:
1964 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1965 break;
1966 case RPC_FC_EMBEDDED_COMPLEX:
1967 pMemory += pFormat[1];
1968 pFormat += 2;
1969 desc = pFormat + *(const SHORT*)pFormat;
1970 size = EmbeddedComplexSize(pStubMsg, desc);
1971 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
1972 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1973 memset(pMemory, 0, size); /* just in case */
1974 if (m)
1976 /* for some reason interface pointers aren't generated as
1977 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
1978 * they still need the derefencing treatment that pointers are
1979 * given */
1980 if (*desc == RPC_FC_IP)
1981 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
1982 else
1983 m(pStubMsg, &pMemory, desc, FALSE);
1985 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
1986 pMemory += size;
1987 pFormat += 2;
1988 continue;
1989 case RPC_FC_PAD:
1990 break;
1991 default:
1992 FIXME("unhandled format %d\n", *pFormat);
1994 pFormat++;
1997 return pMemory;
2000 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2001 unsigned char *pMemory,
2002 PFORMAT_STRING pFormat,
2003 PFORMAT_STRING pPointer)
2005 PFORMAT_STRING desc;
2006 NDR_BUFFERSIZE m;
2007 unsigned long size;
2009 while (*pFormat != RPC_FC_END) {
2010 switch (*pFormat) {
2011 case RPC_FC_BYTE:
2012 case RPC_FC_CHAR:
2013 case RPC_FC_SMALL:
2014 case RPC_FC_USMALL:
2015 pStubMsg->BufferLength += 1;
2016 pMemory += 1;
2017 break;
2018 case RPC_FC_WCHAR:
2019 case RPC_FC_SHORT:
2020 case RPC_FC_USHORT:
2021 pStubMsg->BufferLength += 2;
2022 pMemory += 2;
2023 break;
2024 case RPC_FC_LONG:
2025 case RPC_FC_ULONG:
2026 case RPC_FC_ENUM32:
2027 pStubMsg->BufferLength += 4;
2028 pMemory += 4;
2029 break;
2030 case RPC_FC_HYPER:
2031 pStubMsg->BufferLength += 8;
2032 pMemory += 8;
2033 break;
2034 case RPC_FC_POINTER:
2035 if (!pStubMsg->IgnoreEmbeddedPointers)
2037 int saved_buffer_length = pStubMsg->BufferLength;
2038 pStubMsg->BufferLength = pStubMsg->PointerLength;
2039 pStubMsg->PointerLength = 0;
2040 if(!pStubMsg->BufferLength)
2041 ERR("BufferLength == 0??\n");
2042 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2043 pStubMsg->PointerLength = pStubMsg->BufferLength;
2044 pStubMsg->BufferLength = saved_buffer_length;
2046 pStubMsg->BufferLength += 4;
2047 pPointer += 4;
2048 pMemory += 4;
2049 break;
2050 case RPC_FC_ALIGNM4:
2051 ALIGN_POINTER(pMemory, 4);
2052 break;
2053 case RPC_FC_ALIGNM8:
2054 ALIGN_POINTER(pMemory, 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 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2064 break;
2065 case RPC_FC_EMBEDDED_COMPLEX:
2066 pMemory += pFormat[1];
2067 pFormat += 2;
2068 desc = pFormat + *(const SHORT*)pFormat;
2069 size = EmbeddedComplexSize(pStubMsg, desc);
2070 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2071 if (m)
2073 /* for some reason interface pointers aren't generated as
2074 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2075 * they still need the derefencing treatment that pointers are
2076 * given */
2077 if (*desc == RPC_FC_IP)
2078 m(pStubMsg, *(unsigned char **)pMemory, desc);
2079 else
2080 m(pStubMsg, pMemory, desc);
2082 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2083 pMemory += size;
2084 pFormat += 2;
2085 continue;
2086 case RPC_FC_PAD:
2087 break;
2088 default:
2089 FIXME("unhandled format 0x%02x\n", *pFormat);
2091 pFormat++;
2094 return pMemory;
2097 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2098 unsigned char *pMemory,
2099 PFORMAT_STRING pFormat,
2100 PFORMAT_STRING pPointer)
2102 PFORMAT_STRING desc;
2103 NDR_FREE m;
2104 unsigned long size;
2106 while (*pFormat != RPC_FC_END) {
2107 switch (*pFormat) {
2108 case RPC_FC_BYTE:
2109 case RPC_FC_CHAR:
2110 case RPC_FC_SMALL:
2111 case RPC_FC_USMALL:
2112 pMemory += 1;
2113 break;
2114 case RPC_FC_WCHAR:
2115 case RPC_FC_SHORT:
2116 case RPC_FC_USHORT:
2117 pMemory += 2;
2118 break;
2119 case RPC_FC_LONG:
2120 case RPC_FC_ULONG:
2121 case RPC_FC_ENUM32:
2122 pMemory += 4;
2123 break;
2124 case RPC_FC_HYPER:
2125 pMemory += 8;
2126 break;
2127 case RPC_FC_POINTER:
2128 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
2129 pPointer += 4;
2130 pMemory += 4;
2131 break;
2132 case RPC_FC_ALIGNM4:
2133 ALIGN_POINTER(pMemory, 4);
2134 break;
2135 case RPC_FC_ALIGNM8:
2136 ALIGN_POINTER(pMemory, 8);
2137 break;
2138 case RPC_FC_STRUCTPAD1:
2139 case RPC_FC_STRUCTPAD2:
2140 case RPC_FC_STRUCTPAD3:
2141 case RPC_FC_STRUCTPAD4:
2142 case RPC_FC_STRUCTPAD5:
2143 case RPC_FC_STRUCTPAD6:
2144 case RPC_FC_STRUCTPAD7:
2145 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2146 break;
2147 case RPC_FC_EMBEDDED_COMPLEX:
2148 pMemory += pFormat[1];
2149 pFormat += 2;
2150 desc = pFormat + *(const SHORT*)pFormat;
2151 size = EmbeddedComplexSize(pStubMsg, desc);
2152 m = NdrFreer[*desc & NDR_TABLE_MASK];
2153 if (m)
2155 /* for some reason interface pointers aren't generated as
2156 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2157 * they still need the derefencing treatment that pointers are
2158 * given */
2159 if (*desc == RPC_FC_IP)
2160 m(pStubMsg, *(unsigned char **)pMemory, desc);
2161 else
2162 m(pStubMsg, pMemory, desc);
2164 else FIXME("no freer for embedded type %02x\n", *desc);
2165 pMemory += size;
2166 pFormat += 2;
2167 continue;
2168 case RPC_FC_PAD:
2169 break;
2170 default:
2171 FIXME("unhandled format 0x%02x\n", *pFormat);
2173 pFormat++;
2176 return pMemory;
2179 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2180 PFORMAT_STRING pFormat)
2182 PFORMAT_STRING desc;
2183 unsigned long size = 0;
2185 while (*pFormat != RPC_FC_END) {
2186 switch (*pFormat) {
2187 case RPC_FC_BYTE:
2188 case RPC_FC_CHAR:
2189 case RPC_FC_SMALL:
2190 case RPC_FC_USMALL:
2191 size += 1;
2192 pStubMsg->Buffer += 1;
2193 break;
2194 case RPC_FC_WCHAR:
2195 case RPC_FC_SHORT:
2196 case RPC_FC_USHORT:
2197 size += 2;
2198 pStubMsg->Buffer += 2;
2199 break;
2200 case RPC_FC_LONG:
2201 case RPC_FC_ULONG:
2202 case RPC_FC_ENUM32:
2203 size += 4;
2204 pStubMsg->Buffer += 4;
2205 break;
2206 case RPC_FC_HYPER:
2207 size += 8;
2208 pStubMsg->Buffer += 8;
2209 break;
2210 case RPC_FC_POINTER:
2211 size += 4;
2212 pStubMsg->Buffer += 4;
2213 if (!pStubMsg->IgnoreEmbeddedPointers)
2214 FIXME("embedded pointers\n");
2215 break;
2216 case RPC_FC_ALIGNM4:
2217 ALIGN_LENGTH(size, 4);
2218 ALIGN_POINTER(pStubMsg->Buffer, 4);
2219 break;
2220 case RPC_FC_ALIGNM8:
2221 ALIGN_LENGTH(size, 8);
2222 ALIGN_POINTER(pStubMsg->Buffer, 8);
2223 break;
2224 case RPC_FC_STRUCTPAD1:
2225 case RPC_FC_STRUCTPAD2:
2226 case RPC_FC_STRUCTPAD3:
2227 case RPC_FC_STRUCTPAD4:
2228 case RPC_FC_STRUCTPAD5:
2229 case RPC_FC_STRUCTPAD6:
2230 case RPC_FC_STRUCTPAD7:
2231 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2232 break;
2233 case RPC_FC_EMBEDDED_COMPLEX:
2234 size += pFormat[1];
2235 pFormat += 2;
2236 desc = pFormat + *(const SHORT*)pFormat;
2237 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2238 pFormat += 2;
2239 continue;
2240 case RPC_FC_PAD:
2241 break;
2242 default:
2243 FIXME("unhandled format 0x%02x\n", *pFormat);
2245 pFormat++;
2248 return size;
2251 /***********************************************************************
2252 * NdrComplexStructMarshall [RPCRT4.@]
2254 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2255 unsigned char *pMemory,
2256 PFORMAT_STRING pFormat)
2258 PFORMAT_STRING conf_array = NULL;
2259 PFORMAT_STRING pointer_desc = NULL;
2260 unsigned char *OldMemory = pStubMsg->Memory;
2261 int pointer_buffer_mark_set = 0;
2263 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2265 if (!pStubMsg->PointerBufferMark)
2267 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2268 /* save buffer length */
2269 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2271 /* get the buffer pointer after complex array data, but before
2272 * pointer data */
2273 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2274 pStubMsg->IgnoreEmbeddedPointers = 1;
2275 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2276 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2278 /* save it for use by embedded pointer code later */
2279 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2280 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
2281 pointer_buffer_mark_set = 1;
2283 /* restore the original buffer length */
2284 pStubMsg->BufferLength = saved_buffer_length;
2287 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2289 pFormat += 4;
2290 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2291 pFormat += 2;
2292 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2293 pFormat += 2;
2295 pStubMsg->Memory = pMemory;
2297 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2299 if (conf_array)
2300 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2302 pStubMsg->Memory = OldMemory;
2304 if (pointer_buffer_mark_set)
2306 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2307 pStubMsg->PointerBufferMark = NULL;
2310 STD_OVERFLOW_CHECK(pStubMsg);
2312 return NULL;
2315 /***********************************************************************
2316 * NdrComplexStructUnmarshall [RPCRT4.@]
2318 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2319 unsigned char **ppMemory,
2320 PFORMAT_STRING pFormat,
2321 unsigned char fMustAlloc)
2323 unsigned size = *(const WORD*)(pFormat+2);
2324 PFORMAT_STRING conf_array = NULL;
2325 PFORMAT_STRING pointer_desc = NULL;
2326 unsigned char *pMemory;
2327 int pointer_buffer_mark_set = 0;
2329 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2331 if (!pStubMsg->PointerBufferMark)
2333 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2334 /* save buffer pointer */
2335 unsigned char *saved_buffer = pStubMsg->Buffer;
2337 /* get the buffer pointer after complex array data, but before
2338 * pointer data */
2339 pStubMsg->IgnoreEmbeddedPointers = 1;
2340 NdrComplexStructMemorySize(pStubMsg, pFormat);
2341 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2343 /* save it for use by embedded pointer code later */
2344 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2345 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
2346 pointer_buffer_mark_set = 1;
2348 /* restore the original buffer */
2349 pStubMsg->Buffer = saved_buffer;
2352 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2354 if (fMustAlloc || !*ppMemory)
2356 *ppMemory = NdrAllocate(pStubMsg, size);
2357 memset(*ppMemory, 0, size);
2360 pFormat += 4;
2361 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2362 pFormat += 2;
2363 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2364 pFormat += 2;
2366 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2368 if (conf_array)
2369 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2371 if (pointer_buffer_mark_set)
2373 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2374 pStubMsg->PointerBufferMark = NULL;
2377 return NULL;
2380 /***********************************************************************
2381 * NdrComplexStructBufferSize [RPCRT4.@]
2383 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2384 unsigned char *pMemory,
2385 PFORMAT_STRING pFormat)
2387 PFORMAT_STRING conf_array = NULL;
2388 PFORMAT_STRING pointer_desc = NULL;
2389 unsigned char *OldMemory = pStubMsg->Memory;
2390 int pointer_length_set = 0;
2392 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2394 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2396 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2398 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2399 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2401 /* get the buffer length after complex struct data, but before
2402 * pointer data */
2403 pStubMsg->IgnoreEmbeddedPointers = 1;
2404 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2405 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2407 /* save it for use by embedded pointer code later */
2408 pStubMsg->PointerLength = pStubMsg->BufferLength;
2409 pointer_length_set = 1;
2410 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
2412 /* restore the original buffer length */
2413 pStubMsg->BufferLength = saved_buffer_length;
2416 pFormat += 4;
2417 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2418 pFormat += 2;
2419 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2420 pFormat += 2;
2422 pStubMsg->Memory = pMemory;
2424 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2426 if (conf_array)
2427 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2429 pStubMsg->Memory = OldMemory;
2431 if(pointer_length_set)
2433 pStubMsg->BufferLength = pStubMsg->PointerLength;
2434 pStubMsg->PointerLength = 0;
2439 /***********************************************************************
2440 * NdrComplexStructMemorySize [RPCRT4.@]
2442 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2443 PFORMAT_STRING pFormat)
2445 unsigned size = *(const WORD*)(pFormat+2);
2446 PFORMAT_STRING conf_array = NULL;
2447 PFORMAT_STRING pointer_desc = NULL;
2449 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2451 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2453 pFormat += 4;
2454 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2455 pFormat += 2;
2456 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2457 pFormat += 2;
2459 ComplexStructMemorySize(pStubMsg, pFormat);
2461 if (conf_array)
2462 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2464 return size;
2467 /***********************************************************************
2468 * NdrComplexStructFree [RPCRT4.@]
2470 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2471 unsigned char *pMemory,
2472 PFORMAT_STRING pFormat)
2474 PFORMAT_STRING conf_array = NULL;
2475 PFORMAT_STRING pointer_desc = NULL;
2476 unsigned char *OldMemory = pStubMsg->Memory;
2478 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2480 pFormat += 4;
2481 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2482 pFormat += 2;
2483 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2484 pFormat += 2;
2486 pStubMsg->Memory = pMemory;
2488 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2490 if (conf_array)
2491 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2493 pStubMsg->Memory = OldMemory;
2496 /***********************************************************************
2497 * NdrConformantArrayMarshall [RPCRT4.@]
2499 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2500 unsigned char *pMemory,
2501 PFORMAT_STRING pFormat)
2503 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2504 unsigned char alignment = pFormat[1] + 1;
2506 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2507 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2509 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2511 WriteConformance(pStubMsg);
2513 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2515 size = safe_multiply(esize, pStubMsg->MaxCount);
2516 memcpy(pStubMsg->Buffer, pMemory, size);
2517 pStubMsg->BufferMark = pStubMsg->Buffer;
2518 pStubMsg->Buffer += size;
2520 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2522 STD_OVERFLOW_CHECK(pStubMsg);
2524 return NULL;
2527 /***********************************************************************
2528 * NdrConformantArrayUnmarshall [RPCRT4.@]
2530 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2531 unsigned char **ppMemory,
2532 PFORMAT_STRING pFormat,
2533 unsigned char fMustAlloc)
2535 DWORD size, esize = *(const WORD*)(pFormat+2);
2536 unsigned char alignment = pFormat[1] + 1;
2538 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2539 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2541 pFormat = ReadConformance(pStubMsg, pFormat+4);
2543 size = safe_multiply(esize, pStubMsg->MaxCount);
2545 if (fMustAlloc || !*ppMemory)
2546 *ppMemory = NdrAllocate(pStubMsg, size);
2548 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2550 memcpy(*ppMemory, pStubMsg->Buffer, size);
2552 pStubMsg->BufferMark = pStubMsg->Buffer;
2553 pStubMsg->Buffer += size;
2555 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2557 return NULL;
2560 /***********************************************************************
2561 * NdrConformantArrayBufferSize [RPCRT4.@]
2563 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2564 unsigned char *pMemory,
2565 PFORMAT_STRING pFormat)
2567 DWORD size, esize = *(const WORD*)(pFormat+2);
2568 unsigned char alignment = pFormat[1] + 1;
2570 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2571 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2573 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2575 SizeConformance(pStubMsg);
2577 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2579 size = safe_multiply(esize, pStubMsg->MaxCount);
2580 /* conformance value plus array */
2581 pStubMsg->BufferLength += size;
2583 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2586 /***********************************************************************
2587 * NdrConformantArrayMemorySize [RPCRT4.@]
2589 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2590 PFORMAT_STRING pFormat)
2592 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2593 unsigned char alignment = pFormat[1] + 1;
2595 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2596 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2598 pFormat = ReadConformance(pStubMsg, pFormat+4);
2599 size = safe_multiply(esize, pStubMsg->MaxCount);
2600 pStubMsg->MemorySize += size;
2602 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2603 pStubMsg->BufferMark = pStubMsg->Buffer;
2604 pStubMsg->Buffer += size;
2606 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2608 return pStubMsg->MemorySize;
2611 /***********************************************************************
2612 * NdrConformantArrayFree [RPCRT4.@]
2614 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2615 unsigned char *pMemory,
2616 PFORMAT_STRING pFormat)
2618 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2619 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2621 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2623 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2627 /***********************************************************************
2628 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2630 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2631 unsigned char* pMemory,
2632 PFORMAT_STRING pFormat )
2634 ULONG bufsize;
2635 unsigned char alignment = pFormat[1] + 1;
2636 DWORD esize = *(const WORD*)(pFormat+2);
2638 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2640 if (pFormat[0] != RPC_FC_CVARRAY)
2642 ERR("invalid format type %x\n", pFormat[0]);
2643 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2644 return NULL;
2647 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2648 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2650 WriteConformance(pStubMsg);
2651 WriteVariance(pStubMsg);
2653 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2655 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2657 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
2658 pStubMsg->BufferMark = pStubMsg->Buffer;
2659 pStubMsg->Buffer += bufsize;
2661 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2663 STD_OVERFLOW_CHECK(pStubMsg);
2665 return NULL;
2669 /***********************************************************************
2670 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2672 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2673 unsigned char** ppMemory,
2674 PFORMAT_STRING pFormat,
2675 unsigned char fMustAlloc )
2677 ULONG bufsize, memsize;
2678 unsigned char alignment = pFormat[1] + 1;
2679 DWORD esize = *(const WORD*)(pFormat+2);
2681 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2683 if (pFormat[0] != RPC_FC_CVARRAY)
2685 ERR("invalid format type %x\n", pFormat[0]);
2686 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2687 return NULL;
2690 pFormat = ReadConformance(pStubMsg, pFormat+4);
2691 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2693 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2695 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2696 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2698 if (!*ppMemory || fMustAlloc)
2699 *ppMemory = NdrAllocate(pStubMsg, memsize);
2700 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
2701 pStubMsg->Buffer += bufsize;
2703 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2705 return NULL;
2709 /***********************************************************************
2710 * NdrConformantVaryingArrayFree [RPCRT4.@]
2712 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2713 unsigned char* pMemory,
2714 PFORMAT_STRING pFormat )
2716 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2718 if (pFormat[0] != RPC_FC_CVARRAY)
2720 ERR("invalid format type %x\n", pFormat[0]);
2721 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2722 return;
2725 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2726 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2728 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2732 /***********************************************************************
2733 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2735 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2736 unsigned char* pMemory, PFORMAT_STRING pFormat )
2738 unsigned char alignment = pFormat[1] + 1;
2739 DWORD esize = *(const WORD*)(pFormat+2);
2741 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2743 if (pFormat[0] != RPC_FC_CVARRAY)
2745 ERR("invalid format type %x\n", pFormat[0]);
2746 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2747 return;
2750 /* compute size */
2751 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2752 /* compute length */
2753 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2755 SizeConformance(pStubMsg);
2756 SizeVariance(pStubMsg);
2758 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2760 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
2762 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2766 /***********************************************************************
2767 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2769 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2770 PFORMAT_STRING pFormat )
2772 FIXME( "stub\n" );
2773 return 0;
2777 /***********************************************************************
2778 * NdrComplexArrayMarshall [RPCRT4.@]
2780 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2781 unsigned char *pMemory,
2782 PFORMAT_STRING pFormat)
2784 ULONG i, count, def;
2785 BOOL variance_present;
2786 unsigned char alignment;
2787 int pointer_buffer_mark_set = 0;
2789 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2791 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2793 ERR("invalid format type %x\n", pFormat[0]);
2794 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2795 return NULL;
2798 alignment = pFormat[1] + 1;
2800 if (!pStubMsg->PointerBufferMark)
2802 /* save buffer fields that may be changed by buffer sizer functions
2803 * and that may be needed later on */
2804 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2805 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2806 unsigned long saved_max_count = pStubMsg->MaxCount;
2807 unsigned long saved_offset = pStubMsg->Offset;
2808 unsigned long saved_actual_count = pStubMsg->ActualCount;
2810 /* get the buffer pointer after complex array data, but before
2811 * pointer data */
2812 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2813 pStubMsg->IgnoreEmbeddedPointers = 1;
2814 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
2815 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2817 /* save it for use by embedded pointer code later */
2818 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2819 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
2820 pointer_buffer_mark_set = 1;
2822 /* restore fields */
2823 pStubMsg->ActualCount = saved_actual_count;
2824 pStubMsg->Offset = saved_offset;
2825 pStubMsg->MaxCount = saved_max_count;
2826 pStubMsg->BufferLength = saved_buffer_length;
2829 def = *(const WORD*)&pFormat[2];
2830 pFormat += 4;
2832 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2833 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2835 variance_present = IsConformanceOrVariancePresent(pFormat);
2836 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2837 TRACE("variance = %d\n", pStubMsg->ActualCount);
2839 WriteConformance(pStubMsg);
2840 if (variance_present)
2841 WriteVariance(pStubMsg);
2843 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2845 count = pStubMsg->ActualCount;
2846 for (i = 0; i < count; i++)
2847 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2849 STD_OVERFLOW_CHECK(pStubMsg);
2851 if (pointer_buffer_mark_set)
2853 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2854 pStubMsg->PointerBufferMark = NULL;
2857 return NULL;
2860 /***********************************************************************
2861 * NdrComplexArrayUnmarshall [RPCRT4.@]
2863 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2864 unsigned char **ppMemory,
2865 PFORMAT_STRING pFormat,
2866 unsigned char fMustAlloc)
2868 ULONG i, count, size;
2869 unsigned char alignment;
2870 unsigned char *pMemory;
2871 unsigned char *saved_buffer;
2872 int pointer_buffer_mark_set = 0;
2873 int saved_ignore_embedded;
2875 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2877 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2879 ERR("invalid format type %x\n", pFormat[0]);
2880 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2881 return NULL;
2884 alignment = pFormat[1] + 1;
2886 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2887 /* save buffer pointer */
2888 saved_buffer = pStubMsg->Buffer;
2889 /* get the buffer pointer after complex array data, but before
2890 * pointer data */
2891 pStubMsg->IgnoreEmbeddedPointers = 1;
2892 pStubMsg->MemorySize = 0;
2893 NdrComplexArrayMemorySize(pStubMsg, pFormat);
2894 size = pStubMsg->MemorySize;
2895 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2897 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
2898 if (!pStubMsg->PointerBufferMark)
2900 /* save it for use by embedded pointer code later */
2901 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2902 pointer_buffer_mark_set = 1;
2904 /* restore the original buffer */
2905 pStubMsg->Buffer = saved_buffer;
2907 pFormat += 4;
2909 pFormat = ReadConformance(pStubMsg, pFormat);
2910 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2912 if (fMustAlloc || !*ppMemory)
2914 *ppMemory = NdrAllocate(pStubMsg, size);
2915 memset(*ppMemory, 0, size);
2918 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2920 pMemory = *ppMemory;
2921 count = pStubMsg->ActualCount;
2922 for (i = 0; i < count; i++)
2923 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
2925 if (pointer_buffer_mark_set)
2927 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2928 pStubMsg->PointerBufferMark = NULL;
2931 return NULL;
2934 /***********************************************************************
2935 * NdrComplexArrayBufferSize [RPCRT4.@]
2937 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2938 unsigned char *pMemory,
2939 PFORMAT_STRING pFormat)
2941 ULONG i, count, def;
2942 unsigned char alignment;
2943 BOOL variance_present;
2944 int pointer_length_set = 0;
2946 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2948 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2950 ERR("invalid format type %x\n", pFormat[0]);
2951 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2952 return;
2955 alignment = pFormat[1] + 1;
2957 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2959 /* save buffer fields that may be changed by buffer sizer functions
2960 * and that may be needed later on */
2961 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2962 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2963 unsigned long saved_max_count = pStubMsg->MaxCount;
2964 unsigned long saved_offset = pStubMsg->Offset;
2965 unsigned long saved_actual_count = pStubMsg->ActualCount;
2967 /* get the buffer pointer after complex array data, but before
2968 * pointer data */
2969 pStubMsg->IgnoreEmbeddedPointers = 1;
2970 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
2971 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2973 /* save it for use by embedded pointer code later */
2974 pStubMsg->PointerLength = pStubMsg->BufferLength;
2975 pointer_length_set = 1;
2977 /* restore fields */
2978 pStubMsg->ActualCount = saved_actual_count;
2979 pStubMsg->Offset = saved_offset;
2980 pStubMsg->MaxCount = saved_max_count;
2981 pStubMsg->BufferLength = saved_buffer_length;
2983 def = *(const WORD*)&pFormat[2];
2984 pFormat += 4;
2986 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2987 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2988 SizeConformance(pStubMsg);
2990 variance_present = IsConformanceOrVariancePresent(pFormat);
2991 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2992 TRACE("variance = %d\n", pStubMsg->ActualCount);
2994 if (variance_present)
2995 SizeVariance(pStubMsg);
2997 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2999 count = pStubMsg->ActualCount;
3000 for (i = 0; i < count; i++)
3001 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
3003 if(pointer_length_set)
3005 pStubMsg->BufferLength = pStubMsg->PointerLength;
3006 pStubMsg->PointerLength = 0;
3010 /***********************************************************************
3011 * NdrComplexArrayMemorySize [RPCRT4.@]
3013 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3014 PFORMAT_STRING pFormat)
3016 ULONG i, count, esize, SavedMemorySize, MemorySize;
3017 unsigned char alignment;
3018 unsigned char *Buffer;
3020 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3022 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3024 ERR("invalid format type %x\n", pFormat[0]);
3025 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3026 return 0;
3029 alignment = pFormat[1] + 1;
3031 pFormat += 4;
3033 pFormat = ReadConformance(pStubMsg, pFormat);
3034 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3036 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3038 SavedMemorySize = pStubMsg->MemorySize;
3040 Buffer = pStubMsg->Buffer;
3041 pStubMsg->MemorySize = 0;
3042 esize = ComplexStructMemorySize(pStubMsg, pFormat);
3043 pStubMsg->Buffer = Buffer;
3045 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
3047 count = pStubMsg->ActualCount;
3048 for (i = 0; i < count; i++)
3049 ComplexStructMemorySize(pStubMsg, pFormat);
3051 pStubMsg->MemorySize = SavedMemorySize;
3053 pStubMsg->MemorySize += MemorySize;
3054 return MemorySize;
3057 /***********************************************************************
3058 * NdrComplexArrayFree [RPCRT4.@]
3060 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3061 unsigned char *pMemory,
3062 PFORMAT_STRING pFormat)
3064 ULONG i, count, def;
3066 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3068 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3070 ERR("invalid format type %x\n", pFormat[0]);
3071 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3072 return;
3075 def = *(const WORD*)&pFormat[2];
3076 pFormat += 4;
3078 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3079 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3081 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3082 TRACE("variance = %d\n", pStubMsg->ActualCount);
3084 count = pStubMsg->ActualCount;
3085 for (i = 0; i < count; i++)
3086 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
3089 static ULONG UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
3091 return MAKELONG(pStubMsg->dwDestContext,
3092 pStubMsg->RpcMsg->DataRepresentation);
3095 #define USER_MARSHAL_PTR_PREFIX \
3096 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3097 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3099 /***********************************************************************
3100 * NdrUserMarshalMarshall [RPCRT4.@]
3102 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3103 unsigned char *pMemory,
3104 PFORMAT_STRING pFormat)
3106 unsigned flags = pFormat[1];
3107 unsigned index = *(const WORD*)&pFormat[2];
3108 unsigned char *saved_buffer = NULL;
3109 ULONG uflag = UserMarshalFlags(pStubMsg);
3110 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3111 TRACE("index=%d\n", index);
3113 if (flags & USER_MARSHAL_POINTER)
3115 ALIGN_POINTER(pStubMsg->Buffer, 4);
3116 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
3117 pStubMsg->Buffer += 4;
3118 if (pStubMsg->PointerBufferMark)
3120 saved_buffer = pStubMsg->Buffer;
3121 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3122 pStubMsg->PointerBufferMark = NULL;
3124 ALIGN_POINTER(pStubMsg->Buffer, 8);
3126 else
3127 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3129 pStubMsg->Buffer =
3130 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
3131 &uflag, pStubMsg->Buffer, pMemory);
3133 if (saved_buffer)
3135 STD_OVERFLOW_CHECK(pStubMsg);
3136 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3137 pStubMsg->Buffer = saved_buffer;
3140 STD_OVERFLOW_CHECK(pStubMsg);
3142 return NULL;
3145 /***********************************************************************
3146 * NdrUserMarshalUnmarshall [RPCRT4.@]
3148 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3149 unsigned char **ppMemory,
3150 PFORMAT_STRING pFormat,
3151 unsigned char fMustAlloc)
3153 unsigned flags = pFormat[1];
3154 unsigned index = *(const WORD*)&pFormat[2];
3155 DWORD memsize = *(const WORD*)&pFormat[4];
3156 unsigned char *saved_buffer = NULL;
3157 ULONG uflag = UserMarshalFlags(pStubMsg);
3158 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3159 TRACE("index=%d\n", index);
3161 if (flags & USER_MARSHAL_POINTER)
3163 ALIGN_POINTER(pStubMsg->Buffer, 4);
3164 /* skip pointer prefix */
3165 pStubMsg->Buffer += 4;
3166 if (pStubMsg->PointerBufferMark)
3168 saved_buffer = pStubMsg->Buffer;
3169 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3170 pStubMsg->PointerBufferMark = NULL;
3172 ALIGN_POINTER(pStubMsg->Buffer, 8);
3174 else
3175 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3177 if (fMustAlloc || !*ppMemory)
3178 *ppMemory = NdrAllocate(pStubMsg, memsize);
3180 pStubMsg->Buffer =
3181 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
3182 &uflag, pStubMsg->Buffer, *ppMemory);
3184 if (saved_buffer)
3186 STD_OVERFLOW_CHECK(pStubMsg);
3187 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3188 pStubMsg->Buffer = saved_buffer;
3191 return NULL;
3194 /***********************************************************************
3195 * NdrUserMarshalBufferSize [RPCRT4.@]
3197 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3198 unsigned char *pMemory,
3199 PFORMAT_STRING pFormat)
3201 unsigned flags = pFormat[1];
3202 unsigned index = *(const WORD*)&pFormat[2];
3203 DWORD bufsize = *(const WORD*)&pFormat[6];
3204 ULONG uflag = UserMarshalFlags(pStubMsg);
3205 unsigned long saved_buffer_length = 0;
3206 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3207 TRACE("index=%d\n", index);
3209 if (flags & USER_MARSHAL_POINTER)
3211 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3212 /* skip pointer prefix */
3213 pStubMsg->BufferLength += 4;
3214 if (pStubMsg->IgnoreEmbeddedPointers)
3215 return;
3216 if (pStubMsg->PointerLength)
3218 saved_buffer_length = pStubMsg->BufferLength;
3219 pStubMsg->BufferLength = pStubMsg->PointerLength;
3220 pStubMsg->PointerLength = 0;
3222 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
3224 else
3225 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
3227 if (bufsize) {
3228 TRACE("size=%d\n", bufsize);
3229 pStubMsg->BufferLength += bufsize;
3231 else
3232 pStubMsg->BufferLength =
3233 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
3234 &uflag, pStubMsg->BufferLength, pMemory);
3236 if (saved_buffer_length)
3238 pStubMsg->PointerLength = pStubMsg->BufferLength;
3239 pStubMsg->BufferLength = saved_buffer_length;
3244 /***********************************************************************
3245 * NdrUserMarshalMemorySize [RPCRT4.@]
3247 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3248 PFORMAT_STRING pFormat)
3250 unsigned flags = pFormat[1];
3251 unsigned index = *(const WORD*)&pFormat[2];
3252 DWORD memsize = *(const WORD*)&pFormat[4];
3253 DWORD bufsize = *(const WORD*)&pFormat[6];
3255 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3256 TRACE("index=%d\n", index);
3258 pStubMsg->MemorySize += memsize;
3260 if (flags & USER_MARSHAL_POINTER)
3262 ALIGN_POINTER(pStubMsg->Buffer, 4);
3263 /* skip pointer prefix */
3264 pStubMsg->Buffer += 4;
3265 if (pStubMsg->IgnoreEmbeddedPointers)
3266 return pStubMsg->MemorySize;
3267 ALIGN_POINTER(pStubMsg->Buffer, 8);
3269 else
3270 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3272 if (!bufsize)
3273 FIXME("not implemented for varying buffer size\n");
3275 pStubMsg->Buffer += bufsize;
3277 return pStubMsg->MemorySize;
3280 /***********************************************************************
3281 * NdrUserMarshalFree [RPCRT4.@]
3283 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
3284 unsigned char *pMemory,
3285 PFORMAT_STRING pFormat)
3287 /* unsigned flags = pFormat[1]; */
3288 unsigned index = *(const WORD*)&pFormat[2];
3289 ULONG uflag = UserMarshalFlags(pStubMsg);
3290 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3291 TRACE("index=%d\n", index);
3293 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
3294 &uflag, pMemory);
3297 /***********************************************************************
3298 * NdrClearOutParameters [RPCRT4.@]
3300 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
3301 PFORMAT_STRING pFormat,
3302 void *ArgAddr)
3304 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
3307 /***********************************************************************
3308 * NdrConvert [RPCRT4.@]
3310 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
3312 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
3313 /* FIXME: since this stub doesn't do any converting, the proper behavior
3314 is to raise an exception */
3317 /***********************************************************************
3318 * NdrConvert2 [RPCRT4.@]
3320 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
3322 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3323 pStubMsg, pFormat, NumberParams);
3324 /* FIXME: since this stub doesn't do any converting, the proper behavior
3325 is to raise an exception */
3328 #include "pshpack1.h"
3329 typedef struct _NDR_CSTRUCT_FORMAT
3331 unsigned char type;
3332 unsigned char alignment;
3333 unsigned short memory_size;
3334 short offset_to_array_description;
3335 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
3336 #include "poppack.h"
3338 /***********************************************************************
3339 * NdrConformantStructMarshall [RPCRT4.@]
3341 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3342 unsigned char *pMemory,
3343 PFORMAT_STRING pFormat)
3345 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3346 PFORMAT_STRING pCArrayFormat;
3347 ULONG esize, bufsize;
3349 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3351 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3352 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3354 ERR("invalid format type %x\n", pCStructFormat->type);
3355 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3356 return NULL;
3359 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3360 pCStructFormat->offset_to_array_description;
3361 if (*pCArrayFormat != RPC_FC_CARRAY)
3363 ERR("invalid array format type %x\n", pCStructFormat->type);
3364 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3365 return NULL;
3367 esize = *(const WORD*)(pCArrayFormat+2);
3369 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3370 pCArrayFormat + 4, 0);
3372 WriteConformance(pStubMsg);
3374 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3376 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3378 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3379 /* copy constant sized part of struct */
3380 pStubMsg->BufferMark = pStubMsg->Buffer;
3381 memcpy(pStubMsg->Buffer, pMemory, pCStructFormat->memory_size + bufsize);
3382 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
3384 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3385 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3387 STD_OVERFLOW_CHECK(pStubMsg);
3389 return NULL;
3392 /***********************************************************************
3393 * NdrConformantStructUnmarshall [RPCRT4.@]
3395 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3396 unsigned char **ppMemory,
3397 PFORMAT_STRING pFormat,
3398 unsigned char fMustAlloc)
3400 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3401 PFORMAT_STRING pCArrayFormat;
3402 ULONG esize, bufsize;
3404 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3406 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3407 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3409 ERR("invalid format type %x\n", pCStructFormat->type);
3410 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3411 return NULL;
3413 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3414 pCStructFormat->offset_to_array_description;
3415 if (*pCArrayFormat != RPC_FC_CARRAY)
3417 ERR("invalid array format type %x\n", pCStructFormat->type);
3418 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3419 return NULL;
3421 esize = *(const WORD*)(pCArrayFormat+2);
3423 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3425 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3427 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3429 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3430 /* work out how much memory to allocate if we need to do so */
3431 if (!*ppMemory || fMustAlloc)
3433 SIZE_T size = pCStructFormat->memory_size + bufsize;
3434 *ppMemory = NdrAllocate(pStubMsg, size);
3437 /* now copy the data */
3438 pStubMsg->BufferMark = pStubMsg->Buffer;
3439 memcpy(*ppMemory, pStubMsg->Buffer, pCStructFormat->memory_size + bufsize);
3440 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
3442 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3443 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3445 return NULL;
3448 /***********************************************************************
3449 * NdrConformantStructBufferSize [RPCRT4.@]
3451 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3452 unsigned char *pMemory,
3453 PFORMAT_STRING pFormat)
3455 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3456 PFORMAT_STRING pCArrayFormat;
3457 ULONG esize;
3459 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3461 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3462 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3464 ERR("invalid format type %x\n", pCStructFormat->type);
3465 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3466 return;
3468 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3469 pCStructFormat->offset_to_array_description;
3470 if (*pCArrayFormat != RPC_FC_CARRAY)
3472 ERR("invalid array format type %x\n", pCStructFormat->type);
3473 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3474 return;
3476 esize = *(const WORD*)(pCArrayFormat+2);
3478 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
3479 SizeConformance(pStubMsg);
3481 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
3483 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3485 pStubMsg->BufferLength += pCStructFormat->memory_size +
3486 safe_multiply(pStubMsg->MaxCount, esize);
3488 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3489 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3492 /***********************************************************************
3493 * NdrConformantStructMemorySize [RPCRT4.@]
3495 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3496 PFORMAT_STRING pFormat)
3498 FIXME("stub\n");
3499 return 0;
3502 /***********************************************************************
3503 * NdrConformantStructFree [RPCRT4.@]
3505 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3506 unsigned char *pMemory,
3507 PFORMAT_STRING pFormat)
3509 FIXME("stub\n");
3512 /***********************************************************************
3513 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3515 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3516 unsigned char *pMemory,
3517 PFORMAT_STRING pFormat)
3519 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3520 PFORMAT_STRING pCVArrayFormat;
3521 ULONG esize, bufsize;
3523 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3525 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3526 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3528 ERR("invalid format type %x\n", pCVStructFormat->type);
3529 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3530 return NULL;
3533 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3534 pCVStructFormat->offset_to_array_description;
3535 switch (*pCVArrayFormat)
3537 case RPC_FC_CVARRAY:
3538 esize = *(const WORD*)(pCVArrayFormat+2);
3540 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3541 pCVArrayFormat + 4, 0);
3542 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3543 pCVArrayFormat, 0);
3544 break;
3545 case RPC_FC_C_CSTRING:
3546 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3547 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3548 esize = sizeof(char);
3549 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3550 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3551 pCVArrayFormat + 2, 0);
3552 else
3553 pStubMsg->MaxCount = pStubMsg->ActualCount;
3554 break;
3555 case RPC_FC_C_WSTRING:
3556 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3557 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3558 esize = sizeof(WCHAR);
3559 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3560 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3561 pCVArrayFormat + 2, 0);
3562 else
3563 pStubMsg->MaxCount = pStubMsg->ActualCount;
3564 break;
3565 default:
3566 ERR("invalid array format type %x\n", *pCVArrayFormat);
3567 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3568 return NULL;
3571 WriteConformance(pStubMsg);
3573 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3575 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3577 /* write constant sized part */
3578 pStubMsg->BufferMark = pStubMsg->Buffer;
3579 memcpy(pStubMsg->Buffer, pMemory, pCVStructFormat->memory_size);
3580 pStubMsg->Buffer += pCVStructFormat->memory_size;
3582 WriteVariance(pStubMsg);
3584 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3586 /* write array part */
3587 memcpy(pStubMsg->Buffer, pMemory + pCVStructFormat->memory_size, bufsize);
3588 pStubMsg->Buffer += bufsize;
3590 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3592 STD_OVERFLOW_CHECK(pStubMsg);
3594 return NULL;
3597 /***********************************************************************
3598 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3600 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3601 unsigned char **ppMemory,
3602 PFORMAT_STRING pFormat,
3603 unsigned char fMustAlloc)
3605 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3606 PFORMAT_STRING pCVArrayFormat;
3607 ULONG esize, bufsize;
3608 unsigned char cvarray_type;
3610 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3612 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3613 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3615 ERR("invalid format type %x\n", pCVStructFormat->type);
3616 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3617 return NULL;
3620 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3621 pCVStructFormat->offset_to_array_description;
3622 cvarray_type = *pCVArrayFormat;
3623 switch (cvarray_type)
3625 case RPC_FC_CVARRAY:
3626 esize = *(const WORD*)(pCVArrayFormat+2);
3627 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3628 break;
3629 case RPC_FC_C_CSTRING:
3630 esize = sizeof(char);
3631 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3632 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3633 else
3634 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3635 break;
3636 case RPC_FC_C_WSTRING:
3637 esize = sizeof(WCHAR);
3638 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3639 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3640 else
3641 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3642 break;
3643 default:
3644 ERR("invalid array format type %x\n", *pCVArrayFormat);
3645 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3646 return NULL;
3649 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3651 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3653 /* work out how much memory to allocate if we need to do so */
3654 if (!*ppMemory || fMustAlloc)
3656 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3657 *ppMemory = NdrAllocate(pStubMsg, size);
3660 /* copy the constant data */
3661 pStubMsg->BufferMark = pStubMsg->Buffer;
3662 memcpy(*ppMemory, pStubMsg->Buffer, pCVStructFormat->memory_size);
3663 pStubMsg->Buffer += pCVStructFormat->memory_size;
3665 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3667 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3669 if ((cvarray_type == RPC_FC_C_CSTRING) ||
3670 (cvarray_type == RPC_FC_C_WSTRING))
3672 ULONG i;
3673 /* strings must always have null terminating bytes */
3674 if (bufsize < esize)
3676 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
3677 RpcRaiseException(RPC_S_INVALID_BOUND);
3678 return NULL;
3680 for (i = bufsize - esize; i < bufsize; i++)
3681 if (pStubMsg->Buffer[i] != 0)
3683 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3684 i, pStubMsg->Buffer[i]);
3685 RpcRaiseException(RPC_S_INVALID_BOUND);
3686 return NULL;
3690 /* copy the array data */
3691 memcpy(*ppMemory + pCVStructFormat->memory_size, pStubMsg->Buffer,
3692 bufsize);
3693 pStubMsg->Buffer += bufsize;
3695 if (cvarray_type == RPC_FC_C_CSTRING)
3696 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3697 else if (cvarray_type == RPC_FC_C_WSTRING)
3698 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3700 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3702 return NULL;
3705 /***********************************************************************
3706 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3708 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3709 unsigned char *pMemory,
3710 PFORMAT_STRING pFormat)
3712 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3713 PFORMAT_STRING pCVArrayFormat;
3714 ULONG esize;
3716 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3718 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3719 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3721 ERR("invalid format type %x\n", pCVStructFormat->type);
3722 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3723 return;
3726 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3727 pCVStructFormat->offset_to_array_description;
3728 switch (*pCVArrayFormat)
3730 case RPC_FC_CVARRAY:
3731 esize = *(const WORD*)(pCVArrayFormat+2);
3733 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3734 pCVArrayFormat + 4, 0);
3735 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3736 pCVArrayFormat, 0);
3737 break;
3738 case RPC_FC_C_CSTRING:
3739 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3740 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3741 esize = sizeof(char);
3742 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3743 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3744 pCVArrayFormat + 2, 0);
3745 else
3746 pStubMsg->MaxCount = pStubMsg->ActualCount;
3747 break;
3748 case RPC_FC_C_WSTRING:
3749 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3750 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3751 esize = sizeof(WCHAR);
3752 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3753 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3754 pCVArrayFormat + 2, 0);
3755 else
3756 pStubMsg->MaxCount = pStubMsg->ActualCount;
3757 break;
3758 default:
3759 ERR("invalid array format type %x\n", *pCVArrayFormat);
3760 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3761 return;
3764 SizeConformance(pStubMsg);
3766 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
3768 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3770 pStubMsg->BufferLength += pCVStructFormat->memory_size;
3771 SizeVariance(pStubMsg);
3772 pStubMsg->BufferLength += safe_multiply(pStubMsg->MaxCount, esize);
3774 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3777 /***********************************************************************
3778 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3780 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3781 PFORMAT_STRING pFormat)
3783 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3784 PFORMAT_STRING pCVArrayFormat;
3785 ULONG esize;
3786 unsigned char cvarray_type;
3788 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3790 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3791 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3793 ERR("invalid format type %x\n", pCVStructFormat->type);
3794 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3795 return 0;
3798 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3799 pCVStructFormat->offset_to_array_description;
3800 cvarray_type = *pCVArrayFormat;
3801 switch (cvarray_type)
3803 case RPC_FC_CVARRAY:
3804 esize = *(const WORD*)(pCVArrayFormat+2);
3805 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3806 break;
3807 case RPC_FC_C_CSTRING:
3808 esize = sizeof(char);
3809 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3810 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3811 else
3812 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3813 break;
3814 case RPC_FC_C_WSTRING:
3815 esize = sizeof(WCHAR);
3816 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3817 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3818 else
3819 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3820 break;
3821 default:
3822 ERR("invalid array format type %x\n", *pCVArrayFormat);
3823 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3824 return 0;
3827 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3829 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3831 pStubMsg->Buffer += pCVStructFormat->memory_size;
3832 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3833 pStubMsg->Buffer += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->ActualCount);
3835 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3837 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3839 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3842 /***********************************************************************
3843 * NdrConformantVaryingStructFree [RPCRT4.@]
3845 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3846 unsigned char *pMemory,
3847 PFORMAT_STRING pFormat)
3849 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3850 PFORMAT_STRING pCVArrayFormat;
3851 ULONG esize;
3853 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3855 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3856 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3858 ERR("invalid format type %x\n", pCVStructFormat->type);
3859 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3860 return;
3863 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3864 pCVStructFormat->offset_to_array_description;
3865 switch (*pCVArrayFormat)
3867 case RPC_FC_CVARRAY:
3868 esize = *(const WORD*)(pCVArrayFormat+2);
3870 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3871 pCVArrayFormat + 4, 0);
3872 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3873 pCVArrayFormat, 0);
3874 break;
3875 case RPC_FC_C_CSTRING:
3876 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3877 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3878 esize = sizeof(char);
3879 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3880 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3881 pCVArrayFormat + 2, 0);
3882 else
3883 pStubMsg->MaxCount = pStubMsg->ActualCount;
3884 break;
3885 case RPC_FC_C_WSTRING:
3886 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3887 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3888 esize = sizeof(WCHAR);
3889 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3890 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3891 pCVArrayFormat + 2, 0);
3892 else
3893 pStubMsg->MaxCount = pStubMsg->ActualCount;
3894 break;
3895 default:
3896 ERR("invalid array format type %x\n", *pCVArrayFormat);
3897 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3898 return;
3901 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3903 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3906 #include "pshpack1.h"
3907 typedef struct
3909 unsigned char type;
3910 unsigned char alignment;
3911 unsigned short total_size;
3912 } NDR_SMFARRAY_FORMAT;
3914 typedef struct
3916 unsigned char type;
3917 unsigned char alignment;
3918 unsigned long total_size;
3919 } NDR_LGFARRAY_FORMAT;
3920 #include "poppack.h"
3922 /***********************************************************************
3923 * NdrFixedArrayMarshall [RPCRT4.@]
3925 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3926 unsigned char *pMemory,
3927 PFORMAT_STRING pFormat)
3929 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3930 unsigned long total_size;
3932 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3934 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3935 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3937 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3938 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3939 return NULL;
3942 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3944 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3946 total_size = pSmFArrayFormat->total_size;
3947 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3949 else
3951 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3952 total_size = pLgFArrayFormat->total_size;
3953 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3956 memcpy(pStubMsg->Buffer, pMemory, total_size);
3957 pStubMsg->BufferMark = pStubMsg->Buffer;
3958 pStubMsg->Buffer += total_size;
3960 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3962 return NULL;
3965 /***********************************************************************
3966 * NdrFixedArrayUnmarshall [RPCRT4.@]
3968 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3969 unsigned char **ppMemory,
3970 PFORMAT_STRING pFormat,
3971 unsigned char fMustAlloc)
3973 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3974 unsigned long total_size;
3976 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3978 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3979 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3981 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3982 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3983 return NULL;
3986 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3988 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3990 total_size = pSmFArrayFormat->total_size;
3991 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3993 else
3995 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3996 total_size = pLgFArrayFormat->total_size;
3997 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4000 if (fMustAlloc || !*ppMemory)
4001 *ppMemory = NdrAllocate(pStubMsg, total_size);
4002 memcpy(*ppMemory, pStubMsg->Buffer, total_size);
4003 pStubMsg->BufferMark = pStubMsg->Buffer;
4004 pStubMsg->Buffer += total_size;
4006 pFormat = EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
4008 return NULL;
4011 /***********************************************************************
4012 * NdrFixedArrayBufferSize [RPCRT4.@]
4014 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4015 unsigned char *pMemory,
4016 PFORMAT_STRING pFormat)
4018 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4019 unsigned long total_size;
4021 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4023 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4024 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4026 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4027 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4028 return;
4031 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4033 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4035 total_size = pSmFArrayFormat->total_size;
4036 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4038 else
4040 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4041 total_size = pLgFArrayFormat->total_size;
4042 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4044 pStubMsg->BufferLength += total_size;
4046 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4049 /***********************************************************************
4050 * NdrFixedArrayMemorySize [RPCRT4.@]
4052 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4053 PFORMAT_STRING pFormat)
4055 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4056 ULONG total_size;
4058 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4060 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4061 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4063 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4064 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4065 return 0;
4068 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4070 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4072 total_size = pSmFArrayFormat->total_size;
4073 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4075 else
4077 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4078 total_size = pLgFArrayFormat->total_size;
4079 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4081 pStubMsg->BufferMark = pStubMsg->Buffer;
4082 pStubMsg->Buffer += total_size;
4083 pStubMsg->MemorySize += total_size;
4085 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4087 return total_size;
4090 /***********************************************************************
4091 * NdrFixedArrayFree [RPCRT4.@]
4093 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4094 unsigned char *pMemory,
4095 PFORMAT_STRING pFormat)
4097 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4099 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4101 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4102 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4104 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4105 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4106 return;
4109 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4110 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4111 else
4113 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4114 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4117 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4120 /***********************************************************************
4121 * NdrVaryingArrayMarshall [RPCRT4.@]
4123 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4124 unsigned char *pMemory,
4125 PFORMAT_STRING pFormat)
4127 unsigned char alignment;
4128 DWORD elements, esize;
4129 ULONG bufsize;
4131 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4133 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4134 (pFormat[0] != RPC_FC_LGVARRAY))
4136 ERR("invalid format type %x\n", pFormat[0]);
4137 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4138 return NULL;
4141 alignment = pFormat[1] + 1;
4143 if (pFormat[0] == RPC_FC_SMVARRAY)
4145 pFormat += 2;
4146 pFormat += sizeof(WORD);
4147 elements = *(const WORD*)pFormat;
4148 pFormat += sizeof(WORD);
4150 else
4152 pFormat += 2;
4153 pFormat += sizeof(DWORD);
4154 elements = *(const DWORD*)pFormat;
4155 pFormat += sizeof(DWORD);
4158 esize = *(const WORD*)pFormat;
4159 pFormat += sizeof(WORD);
4161 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4162 if ((pStubMsg->ActualCount > elements) ||
4163 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4165 RpcRaiseException(RPC_S_INVALID_BOUND);
4166 return NULL;
4169 WriteVariance(pStubMsg);
4171 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4173 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4174 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
4175 pStubMsg->BufferMark = pStubMsg->Buffer;
4176 pStubMsg->Buffer += bufsize;
4178 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4180 STD_OVERFLOW_CHECK(pStubMsg);
4182 return NULL;
4185 /***********************************************************************
4186 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4188 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4189 unsigned char **ppMemory,
4190 PFORMAT_STRING pFormat,
4191 unsigned char fMustAlloc)
4193 unsigned char alignment;
4194 DWORD size, elements, esize;
4195 ULONG bufsize;
4197 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4199 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4200 (pFormat[0] != RPC_FC_LGVARRAY))
4202 ERR("invalid format type %x\n", pFormat[0]);
4203 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4204 return NULL;
4207 alignment = pFormat[1] + 1;
4209 if (pFormat[0] == RPC_FC_SMVARRAY)
4211 pFormat += 2;
4212 size = *(const WORD*)pFormat;
4213 pFormat += sizeof(WORD);
4214 elements = *(const WORD*)pFormat;
4215 pFormat += sizeof(WORD);
4217 else
4219 pFormat += 2;
4220 size = *(const DWORD*)pFormat;
4221 pFormat += sizeof(DWORD);
4222 elements = *(const DWORD*)pFormat;
4223 pFormat += sizeof(DWORD);
4226 esize = *(const WORD*)pFormat;
4227 pFormat += sizeof(WORD);
4229 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4231 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4233 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4235 if (!*ppMemory || fMustAlloc)
4236 *ppMemory = NdrAllocate(pStubMsg, size);
4237 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
4238 pStubMsg->Buffer += bufsize;
4240 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
4242 return NULL;
4245 /***********************************************************************
4246 * NdrVaryingArrayBufferSize [RPCRT4.@]
4248 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4249 unsigned char *pMemory,
4250 PFORMAT_STRING pFormat)
4252 unsigned char alignment;
4253 DWORD elements, esize;
4255 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4257 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4258 (pFormat[0] != RPC_FC_LGVARRAY))
4260 ERR("invalid format type %x\n", pFormat[0]);
4261 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4262 return;
4265 alignment = pFormat[1] + 1;
4267 if (pFormat[0] == RPC_FC_SMVARRAY)
4269 pFormat += 2;
4270 pFormat += sizeof(WORD);
4271 elements = *(const WORD*)pFormat;
4272 pFormat += sizeof(WORD);
4274 else
4276 pFormat += 2;
4277 pFormat += sizeof(DWORD);
4278 elements = *(const DWORD*)pFormat;
4279 pFormat += sizeof(DWORD);
4282 esize = *(const WORD*)pFormat;
4283 pFormat += sizeof(WORD);
4285 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4286 if ((pStubMsg->ActualCount > elements) ||
4287 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4289 RpcRaiseException(RPC_S_INVALID_BOUND);
4290 return;
4293 SizeVariance(pStubMsg);
4295 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4297 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
4299 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4302 /***********************************************************************
4303 * NdrVaryingArrayMemorySize [RPCRT4.@]
4305 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4306 PFORMAT_STRING pFormat)
4308 unsigned char alignment;
4309 DWORD size, elements, esize;
4311 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4313 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4314 (pFormat[0] != RPC_FC_LGVARRAY))
4316 ERR("invalid format type %x\n", pFormat[0]);
4317 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4318 return 0;
4321 alignment = pFormat[1] + 1;
4323 if (pFormat[0] == RPC_FC_SMVARRAY)
4325 pFormat += 2;
4326 size = *(const WORD*)pFormat;
4327 pFormat += sizeof(WORD);
4328 elements = *(const WORD*)pFormat;
4329 pFormat += sizeof(WORD);
4331 else
4333 pFormat += 2;
4334 size = *(const DWORD*)pFormat;
4335 pFormat += sizeof(DWORD);
4336 elements = *(const DWORD*)pFormat;
4337 pFormat += sizeof(DWORD);
4340 esize = *(const WORD*)pFormat;
4341 pFormat += sizeof(WORD);
4343 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4345 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4347 pStubMsg->Buffer += safe_multiply(esize, pStubMsg->ActualCount);
4348 pStubMsg->MemorySize += size;
4350 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4352 return pStubMsg->MemorySize;
4355 /***********************************************************************
4356 * NdrVaryingArrayFree [RPCRT4.@]
4358 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4359 unsigned char *pMemory,
4360 PFORMAT_STRING pFormat)
4362 unsigned char alignment;
4363 DWORD elements;
4365 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4367 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4368 (pFormat[0] != RPC_FC_LGVARRAY))
4370 ERR("invalid format type %x\n", pFormat[0]);
4371 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4372 return;
4375 alignment = pFormat[1] + 1;
4377 if (pFormat[0] == RPC_FC_SMVARRAY)
4379 pFormat += 2;
4380 pFormat += sizeof(WORD);
4381 elements = *(const WORD*)pFormat;
4382 pFormat += sizeof(WORD);
4384 else
4386 pFormat += 2;
4387 pFormat += sizeof(DWORD);
4388 elements = *(const DWORD*)pFormat;
4389 pFormat += sizeof(DWORD);
4392 pFormat += sizeof(WORD);
4394 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4395 if ((pStubMsg->ActualCount > elements) ||
4396 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4398 RpcRaiseException(RPC_S_INVALID_BOUND);
4399 return;
4402 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4405 static ULONG get_discriminant(unsigned char fc, unsigned char *pMemory)
4407 switch (fc)
4409 case RPC_FC_BYTE:
4410 case RPC_FC_CHAR:
4411 case RPC_FC_SMALL:
4412 case RPC_FC_USMALL:
4413 return *(UCHAR *)pMemory;
4414 case RPC_FC_WCHAR:
4415 case RPC_FC_SHORT:
4416 case RPC_FC_USHORT:
4417 case RPC_FC_ENUM16:
4418 return *(USHORT *)pMemory;
4419 case RPC_FC_LONG:
4420 case RPC_FC_ULONG:
4421 case RPC_FC_ENUM32:
4422 return *(ULONG *)pMemory;
4423 default:
4424 FIXME("Unhandled base type: 0x%02x\n", fc);
4425 return 0;
4429 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4430 unsigned long discriminant,
4431 PFORMAT_STRING pFormat)
4433 unsigned short num_arms, arm, type;
4435 num_arms = *(const SHORT*)pFormat & 0x0fff;
4436 pFormat += 2;
4437 for(arm = 0; arm < num_arms; arm++)
4439 if(discriminant == *(const ULONG*)pFormat)
4441 pFormat += 4;
4442 break;
4444 pFormat += 6;
4447 type = *(const unsigned short*)pFormat;
4448 TRACE("type %04x\n", type);
4449 if(arm == num_arms) /* default arm extras */
4451 if(type == 0xffff)
4453 ERR("no arm for 0x%lx and no default case\n", discriminant);
4454 RpcRaiseException(RPC_S_INVALID_TAG);
4455 return NULL;
4457 if(type == 0)
4459 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
4460 return NULL;
4463 return pFormat;
4466 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
4468 unsigned short type;
4470 pFormat += 2;
4472 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4473 if(!pFormat)
4474 return NULL;
4476 type = *(const unsigned short*)pFormat;
4477 if((type & 0xff00) == 0x8000)
4479 unsigned char basetype = LOBYTE(type);
4480 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
4482 else
4484 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4485 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
4486 if (m)
4488 unsigned char *saved_buffer = NULL;
4489 int pointer_buffer_mark_set = 0;
4490 switch(*desc)
4492 case RPC_FC_RP:
4493 case RPC_FC_UP:
4494 case RPC_FC_OP:
4495 case RPC_FC_FP:
4496 ALIGN_POINTER(pStubMsg->Buffer, 4);
4497 saved_buffer = pStubMsg->Buffer;
4498 if (pStubMsg->PointerBufferMark)
4500 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4501 pStubMsg->PointerBufferMark = NULL;
4502 pointer_buffer_mark_set = 1;
4504 else
4505 pStubMsg->Buffer += 4; /* for pointer ID */
4507 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
4508 if (pointer_buffer_mark_set)
4510 STD_OVERFLOW_CHECK(pStubMsg);
4511 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4512 pStubMsg->Buffer = saved_buffer + 4;
4514 break;
4515 default:
4516 m(pStubMsg, pMemory, desc);
4519 else FIXME("no marshaller for embedded type %02x\n", *desc);
4521 return NULL;
4524 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4525 unsigned char **ppMemory,
4526 ULONG discriminant,
4527 PFORMAT_STRING pFormat,
4528 unsigned char fMustAlloc)
4530 unsigned short type;
4532 pFormat += 2;
4534 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4535 if(!pFormat)
4536 return NULL;
4538 type = *(const unsigned short*)pFormat;
4539 if((type & 0xff00) == 0x8000)
4541 unsigned char basetype = LOBYTE(type);
4542 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, fMustAlloc);
4544 else
4546 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4547 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
4548 if (m)
4550 unsigned char *saved_buffer = NULL;
4551 int pointer_buffer_mark_set = 0;
4552 switch(*desc)
4554 case RPC_FC_RP:
4555 case RPC_FC_UP:
4556 case RPC_FC_OP:
4557 case RPC_FC_FP:
4558 **(void***)ppMemory = NULL;
4559 ALIGN_POINTER(pStubMsg->Buffer, 4);
4560 saved_buffer = pStubMsg->Buffer;
4561 if (pStubMsg->PointerBufferMark)
4563 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4564 pStubMsg->PointerBufferMark = NULL;
4565 pointer_buffer_mark_set = 1;
4567 else
4568 pStubMsg->Buffer += 4; /* for pointer ID */
4570 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, desc, fMustAlloc);
4571 if (pointer_buffer_mark_set)
4573 STD_OVERFLOW_CHECK(pStubMsg);
4574 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4575 pStubMsg->Buffer = saved_buffer + 4;
4577 break;
4578 default:
4579 m(pStubMsg, ppMemory, desc, fMustAlloc);
4582 else FIXME("no marshaller for embedded type %02x\n", *desc);
4584 return NULL;
4587 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
4588 unsigned char *pMemory,
4589 ULONG discriminant,
4590 PFORMAT_STRING pFormat)
4592 unsigned short type;
4594 pFormat += 2;
4596 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4597 if(!pFormat)
4598 return;
4600 type = *(const unsigned short*)pFormat;
4601 if((type & 0xff00) == 0x8000)
4603 unsigned char basetype = LOBYTE(type);
4604 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
4606 else
4608 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4609 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
4610 if (m)
4612 switch(*desc)
4614 case RPC_FC_RP:
4615 case RPC_FC_UP:
4616 case RPC_FC_OP:
4617 case RPC_FC_FP:
4618 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4619 pStubMsg->BufferLength += 4; /* for pointer ID */
4620 if (!pStubMsg->IgnoreEmbeddedPointers)
4622 int saved_buffer_length = pStubMsg->BufferLength;
4623 pStubMsg->BufferLength = pStubMsg->PointerLength;
4624 pStubMsg->PointerLength = 0;
4625 if(!pStubMsg->BufferLength)
4626 ERR("BufferLength == 0??\n");
4627 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
4628 pStubMsg->PointerLength = pStubMsg->BufferLength;
4629 pStubMsg->BufferLength = saved_buffer_length;
4631 break;
4632 default:
4633 m(pStubMsg, pMemory, desc);
4636 else FIXME("no buffersizer for embedded type %02x\n", *desc);
4640 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
4641 ULONG discriminant,
4642 PFORMAT_STRING pFormat)
4644 unsigned short type, size;
4646 size = *(const unsigned short*)pFormat;
4647 pStubMsg->Memory += size;
4648 pFormat += 2;
4650 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4651 if(!pFormat)
4652 return 0;
4654 type = *(const unsigned short*)pFormat;
4655 if((type & 0xff00) == 0x8000)
4657 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
4659 else
4661 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4662 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
4663 unsigned char *saved_buffer;
4664 if (m)
4666 switch(*desc)
4668 case RPC_FC_RP:
4669 case RPC_FC_UP:
4670 case RPC_FC_OP:
4671 case RPC_FC_FP:
4672 ALIGN_POINTER(pStubMsg->Buffer, 4);
4673 saved_buffer = pStubMsg->Buffer;
4674 pStubMsg->Buffer += 4;
4675 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
4676 pStubMsg->MemorySize += 4;
4677 if (!pStubMsg->IgnoreEmbeddedPointers)
4678 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
4679 break;
4680 default:
4681 return m(pStubMsg, desc);
4684 else FIXME("no marshaller for embedded type %02x\n", *desc);
4687 TRACE("size %d\n", size);
4688 return size;
4691 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
4692 unsigned char *pMemory,
4693 ULONG discriminant,
4694 PFORMAT_STRING pFormat)
4696 unsigned short type;
4698 pFormat += 2;
4700 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4701 if(!pFormat)
4702 return;
4704 type = *(const unsigned short*)pFormat;
4705 if((type & 0xff00) != 0x8000)
4707 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4708 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
4709 if (m)
4711 switch(*desc)
4713 case RPC_FC_RP:
4714 case RPC_FC_UP:
4715 case RPC_FC_OP:
4716 case RPC_FC_FP:
4717 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
4718 break;
4719 default:
4720 m(pStubMsg, pMemory, desc);
4723 else FIXME("no freer for embedded type %02x\n", *desc);
4727 /***********************************************************************
4728 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4730 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4731 unsigned char *pMemory,
4732 PFORMAT_STRING pFormat)
4734 unsigned char switch_type;
4735 unsigned char increment;
4736 ULONG switch_value;
4738 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4739 pFormat++;
4741 switch_type = *pFormat & 0xf;
4742 increment = (*pFormat & 0xf0) >> 4;
4743 pFormat++;
4745 ALIGN_POINTER(pStubMsg->Buffer, increment);
4747 switch_value = get_discriminant(switch_type, pMemory);
4748 TRACE("got switch value 0x%x\n", switch_value);
4750 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
4751 pMemory += increment;
4753 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
4756 /***********************************************************************
4757 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4759 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4760 unsigned char **ppMemory,
4761 PFORMAT_STRING pFormat,
4762 unsigned char fMustAlloc)
4764 unsigned char switch_type;
4765 unsigned char increment;
4766 ULONG switch_value;
4767 unsigned short size;
4768 unsigned char *pMemoryArm;
4770 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4771 pFormat++;
4773 switch_type = *pFormat & 0xf;
4774 increment = (*pFormat & 0xf0) >> 4;
4775 pFormat++;
4777 ALIGN_POINTER(pStubMsg->Buffer, increment);
4778 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
4779 TRACE("got switch value 0x%x\n", switch_value);
4781 size = *(const unsigned short*)pFormat + increment;
4782 if(!*ppMemory || fMustAlloc)
4783 *ppMemory = NdrAllocate(pStubMsg, size);
4785 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
4786 pMemoryArm = *ppMemory + increment;
4788 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
4791 /***********************************************************************
4792 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4794 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4795 unsigned char *pMemory,
4796 PFORMAT_STRING pFormat)
4798 unsigned char switch_type;
4799 unsigned char increment;
4800 ULONG switch_value;
4802 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4803 pFormat++;
4805 switch_type = *pFormat & 0xf;
4806 increment = (*pFormat & 0xf0) >> 4;
4807 pFormat++;
4809 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
4810 switch_value = get_discriminant(switch_type, pMemory);
4811 TRACE("got switch value 0x%x\n", switch_value);
4813 /* Add discriminant size */
4814 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
4815 pMemory += increment;
4817 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
4820 /***********************************************************************
4821 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4823 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4824 PFORMAT_STRING pFormat)
4826 unsigned char switch_type;
4827 unsigned char increment;
4828 ULONG switch_value;
4830 switch_type = *pFormat & 0xf;
4831 increment = (*pFormat & 0xf0) >> 4;
4832 pFormat++;
4834 ALIGN_POINTER(pStubMsg->Buffer, increment);
4835 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
4836 TRACE("got switch value 0x%x\n", switch_value);
4838 pStubMsg->Memory += increment;
4840 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
4843 /***********************************************************************
4844 * NdrEncapsulatedUnionFree [RPCRT4.@]
4846 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4847 unsigned char *pMemory,
4848 PFORMAT_STRING pFormat)
4850 unsigned char switch_type;
4851 unsigned char increment;
4852 ULONG switch_value;
4854 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4855 pFormat++;
4857 switch_type = *pFormat & 0xf;
4858 increment = (*pFormat & 0xf0) >> 4;
4859 pFormat++;
4861 switch_value = get_discriminant(switch_type, pMemory);
4862 TRACE("got switch value 0x%x\n", switch_value);
4864 pMemory += increment;
4866 return union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
4869 /***********************************************************************
4870 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
4872 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4873 unsigned char *pMemory,
4874 PFORMAT_STRING pFormat)
4876 unsigned char switch_type;
4878 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4879 pFormat++;
4881 switch_type = *pFormat;
4882 pFormat++;
4884 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4885 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4886 /* Marshall discriminant */
4887 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4889 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
4892 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
4893 PFORMAT_STRING *ppFormat)
4895 long discriminant = 0;
4897 switch(**ppFormat)
4899 case RPC_FC_BYTE:
4900 case RPC_FC_CHAR:
4901 case RPC_FC_SMALL:
4902 case RPC_FC_USMALL:
4903 discriminant = *(UCHAR *)pStubMsg->Buffer;
4904 pStubMsg->Buffer += sizeof(UCHAR);
4905 break;
4906 case RPC_FC_WCHAR:
4907 case RPC_FC_SHORT:
4908 case RPC_FC_USHORT:
4909 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4910 discriminant = *(USHORT *)pStubMsg->Buffer;
4911 pStubMsg->Buffer += sizeof(USHORT);
4912 break;
4913 case RPC_FC_LONG:
4914 case RPC_FC_ULONG:
4915 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4916 discriminant = *(ULONG *)pStubMsg->Buffer;
4917 pStubMsg->Buffer += sizeof(ULONG);
4918 break;
4919 default:
4920 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
4922 (*ppFormat)++;
4924 if (pStubMsg->fHasNewCorrDesc)
4925 *ppFormat += 6;
4926 else
4927 *ppFormat += 4;
4928 return discriminant;
4931 /**********************************************************************
4932 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
4934 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4935 unsigned char **ppMemory,
4936 PFORMAT_STRING pFormat,
4937 unsigned char fMustAlloc)
4939 long discriminant;
4940 unsigned short size;
4942 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4943 pFormat++;
4945 /* Unmarshall discriminant */
4946 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4947 TRACE("unmarshalled discriminant %lx\n", discriminant);
4949 pFormat += *(const SHORT*)pFormat;
4951 size = *(const unsigned short*)pFormat;
4953 if(!*ppMemory || fMustAlloc)
4954 *ppMemory = NdrAllocate(pStubMsg, size);
4956 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
4959 /***********************************************************************
4960 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
4962 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4963 unsigned char *pMemory,
4964 PFORMAT_STRING pFormat)
4966 unsigned char switch_type;
4968 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4969 pFormat++;
4971 switch_type = *pFormat;
4972 pFormat++;
4974 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4975 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4976 /* Add discriminant size */
4977 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4979 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
4982 /***********************************************************************
4983 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
4985 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4986 PFORMAT_STRING pFormat)
4988 ULONG discriminant;
4990 pFormat++;
4991 /* Unmarshall discriminant */
4992 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4993 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
4995 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
4998 /***********************************************************************
4999 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5001 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5002 unsigned char *pMemory,
5003 PFORMAT_STRING pFormat)
5005 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5006 pFormat++;
5007 pFormat++;
5009 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5010 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5012 return union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5015 /***********************************************************************
5016 * NdrByteCountPointerMarshall [RPCRT4.@]
5018 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5019 unsigned char *pMemory,
5020 PFORMAT_STRING pFormat)
5022 FIXME("stub\n");
5023 return NULL;
5026 /***********************************************************************
5027 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5029 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5030 unsigned char **ppMemory,
5031 PFORMAT_STRING pFormat,
5032 unsigned char fMustAlloc)
5034 FIXME("stub\n");
5035 return NULL;
5038 /***********************************************************************
5039 * NdrByteCountPointerBufferSize [RPCRT4.@]
5041 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5042 unsigned char *pMemory,
5043 PFORMAT_STRING pFormat)
5045 FIXME("stub\n");
5048 /***********************************************************************
5049 * NdrByteCountPointerMemorySize [RPCRT4.@]
5051 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5052 PFORMAT_STRING pFormat)
5054 FIXME("stub\n");
5055 return 0;
5058 /***********************************************************************
5059 * NdrByteCountPointerFree [RPCRT4.@]
5061 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
5062 unsigned char *pMemory,
5063 PFORMAT_STRING pFormat)
5065 FIXME("stub\n");
5068 /***********************************************************************
5069 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5071 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5072 unsigned char *pMemory,
5073 PFORMAT_STRING pFormat)
5075 FIXME("stub\n");
5076 return NULL;
5079 /***********************************************************************
5080 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5082 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5083 unsigned char **ppMemory,
5084 PFORMAT_STRING pFormat,
5085 unsigned char fMustAlloc)
5087 FIXME("stub\n");
5088 return NULL;
5091 /***********************************************************************
5092 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5094 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5095 unsigned char *pMemory,
5096 PFORMAT_STRING pFormat)
5098 FIXME("stub\n");
5101 /***********************************************************************
5102 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5104 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5105 PFORMAT_STRING pFormat)
5107 FIXME("stub\n");
5108 return 0;
5111 /***********************************************************************
5112 * NdrXmitOrRepAsFree [RPCRT4.@]
5114 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
5115 unsigned char *pMemory,
5116 PFORMAT_STRING pFormat)
5118 FIXME("stub\n");
5121 #include "pshpack1.h"
5122 typedef struct
5124 unsigned char type;
5125 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
5126 ULONG low_value;
5127 ULONG high_value;
5128 } NDR_RANGE;
5129 #include "poppack.h"
5131 /***********************************************************************
5132 * NdrRangeMarshall [internal]
5134 unsigned char *WINAPI NdrRangeMarshall(
5135 PMIDL_STUB_MESSAGE pStubMsg,
5136 unsigned char *pMemory,
5137 PFORMAT_STRING pFormat)
5139 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5140 unsigned char base_type;
5142 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5144 if (pRange->type != RPC_FC_RANGE)
5146 ERR("invalid format type %x\n", pRange->type);
5147 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5148 return NULL;
5151 base_type = pRange->flags_type & 0xf;
5153 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
5156 /***********************************************************************
5157 * NdrRangeUnmarshall
5159 unsigned char *WINAPI NdrRangeUnmarshall(
5160 PMIDL_STUB_MESSAGE pStubMsg,
5161 unsigned char **ppMemory,
5162 PFORMAT_STRING pFormat,
5163 unsigned char fMustAlloc)
5165 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5166 unsigned char base_type;
5168 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5170 if (pRange->type != RPC_FC_RANGE)
5172 ERR("invalid format type %x\n", pRange->type);
5173 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5174 return NULL;
5176 base_type = pRange->flags_type & 0xf;
5178 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5179 base_type, pRange->low_value, pRange->high_value);
5181 #define RANGE_UNMARSHALL(type, format_spec) \
5182 do \
5184 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5185 if (fMustAlloc || !*ppMemory) \
5186 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5187 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5188 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5190 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5191 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5192 (type)pRange->high_value); \
5193 RpcRaiseException(RPC_S_INVALID_BOUND); \
5194 return NULL; \
5196 TRACE("*ppMemory: %p\n", *ppMemory); \
5197 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5198 pStubMsg->Buffer += sizeof(type); \
5199 } while (0)
5201 switch(base_type)
5203 case RPC_FC_CHAR:
5204 case RPC_FC_SMALL:
5205 RANGE_UNMARSHALL(UCHAR, "%d");
5206 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5207 break;
5208 case RPC_FC_BYTE:
5209 case RPC_FC_USMALL:
5210 RANGE_UNMARSHALL(CHAR, "%u");
5211 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5212 break;
5213 case RPC_FC_WCHAR: /* FIXME: valid? */
5214 case RPC_FC_USHORT:
5215 RANGE_UNMARSHALL(USHORT, "%u");
5216 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5217 break;
5218 case RPC_FC_SHORT:
5219 RANGE_UNMARSHALL(SHORT, "%d");
5220 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5221 break;
5222 case RPC_FC_LONG:
5223 RANGE_UNMARSHALL(LONG, "%d");
5224 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5225 break;
5226 case RPC_FC_ULONG:
5227 RANGE_UNMARSHALL(ULONG, "%u");
5228 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5229 break;
5230 case RPC_FC_ENUM16:
5231 case RPC_FC_ENUM32:
5232 FIXME("Unhandled enum type\n");
5233 break;
5234 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
5235 case RPC_FC_FLOAT:
5236 case RPC_FC_DOUBLE:
5237 case RPC_FC_HYPER:
5238 default:
5239 ERR("invalid range base type: 0x%02x\n", base_type);
5240 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5243 return NULL;
5246 /***********************************************************************
5247 * NdrRangeBufferSize [internal]
5249 void WINAPI NdrRangeBufferSize(
5250 PMIDL_STUB_MESSAGE pStubMsg,
5251 unsigned char *pMemory,
5252 PFORMAT_STRING pFormat)
5254 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5255 unsigned char base_type;
5257 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5259 if (pRange->type != RPC_FC_RANGE)
5261 ERR("invalid format type %x\n", pRange->type);
5262 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5264 base_type = pRange->flags_type & 0xf;
5266 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
5269 /***********************************************************************
5270 * NdrRangeMemorySize [internal]
5272 ULONG WINAPI NdrRangeMemorySize(
5273 PMIDL_STUB_MESSAGE pStubMsg,
5274 PFORMAT_STRING pFormat)
5276 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5277 unsigned char base_type;
5279 if (pRange->type != RPC_FC_RANGE)
5281 ERR("invalid format type %x\n", pRange->type);
5282 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5283 return 0;
5285 base_type = pRange->flags_type & 0xf;
5287 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
5290 /***********************************************************************
5291 * NdrRangeFree [internal]
5293 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
5294 unsigned char *pMemory,
5295 PFORMAT_STRING pFormat)
5297 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5299 /* nothing to do */
5302 /***********************************************************************
5303 * NdrBaseTypeMarshall [internal]
5305 static unsigned char *WINAPI NdrBaseTypeMarshall(
5306 PMIDL_STUB_MESSAGE pStubMsg,
5307 unsigned char *pMemory,
5308 PFORMAT_STRING pFormat)
5310 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5312 switch(*pFormat)
5314 case RPC_FC_BYTE:
5315 case RPC_FC_CHAR:
5316 case RPC_FC_SMALL:
5317 case RPC_FC_USMALL:
5318 *(UCHAR *)pStubMsg->Buffer = *(UCHAR *)pMemory;
5319 pStubMsg->Buffer += sizeof(UCHAR);
5320 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
5321 break;
5322 case RPC_FC_WCHAR:
5323 case RPC_FC_SHORT:
5324 case RPC_FC_USHORT:
5325 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5326 *(USHORT *)pStubMsg->Buffer = *(USHORT *)pMemory;
5327 pStubMsg->Buffer += sizeof(USHORT);
5328 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
5329 break;
5330 case RPC_FC_LONG:
5331 case RPC_FC_ULONG:
5332 case RPC_FC_ERROR_STATUS_T:
5333 case RPC_FC_ENUM32:
5334 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5335 *(ULONG *)pStubMsg->Buffer = *(ULONG *)pMemory;
5336 pStubMsg->Buffer += sizeof(ULONG);
5337 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
5338 break;
5339 case RPC_FC_FLOAT:
5340 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
5341 *(float *)pStubMsg->Buffer = *(float *)pMemory;
5342 pStubMsg->Buffer += sizeof(float);
5343 break;
5344 case RPC_FC_DOUBLE:
5345 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
5346 *(double *)pStubMsg->Buffer = *(double *)pMemory;
5347 pStubMsg->Buffer += sizeof(double);
5348 break;
5349 case RPC_FC_HYPER:
5350 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
5351 *(ULONGLONG *)pStubMsg->Buffer = *(ULONGLONG *)pMemory;
5352 pStubMsg->Buffer += sizeof(ULONGLONG);
5353 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
5354 break;
5355 case RPC_FC_ENUM16:
5356 /* only 16-bits on the wire, so do a sanity check */
5357 if (*(UINT *)pMemory > USHRT_MAX)
5358 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
5359 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5360 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
5361 pStubMsg->Buffer += sizeof(USHORT);
5362 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
5363 break;
5364 default:
5365 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5368 STD_OVERFLOW_CHECK(pStubMsg);
5370 /* FIXME: what is the correct return value? */
5371 return NULL;
5374 /***********************************************************************
5375 * NdrBaseTypeUnmarshall [internal]
5377 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
5378 PMIDL_STUB_MESSAGE pStubMsg,
5379 unsigned char **ppMemory,
5380 PFORMAT_STRING pFormat,
5381 unsigned char fMustAlloc)
5383 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5385 #define BASE_TYPE_UNMARSHALL(type) \
5386 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5387 if (fMustAlloc || !*ppMemory) \
5388 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5389 TRACE("*ppMemory: %p\n", *ppMemory); \
5390 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5391 pStubMsg->Buffer += sizeof(type);
5393 switch(*pFormat)
5395 case RPC_FC_BYTE:
5396 case RPC_FC_CHAR:
5397 case RPC_FC_SMALL:
5398 case RPC_FC_USMALL:
5399 BASE_TYPE_UNMARSHALL(UCHAR);
5400 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5401 break;
5402 case RPC_FC_WCHAR:
5403 case RPC_FC_SHORT:
5404 case RPC_FC_USHORT:
5405 BASE_TYPE_UNMARSHALL(USHORT);
5406 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5407 break;
5408 case RPC_FC_LONG:
5409 case RPC_FC_ULONG:
5410 case RPC_FC_ERROR_STATUS_T:
5411 case RPC_FC_ENUM32:
5412 BASE_TYPE_UNMARSHALL(ULONG);
5413 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5414 break;
5415 case RPC_FC_FLOAT:
5416 BASE_TYPE_UNMARSHALL(float);
5417 TRACE("value: %f\n", **(float **)ppMemory);
5418 break;
5419 case RPC_FC_DOUBLE:
5420 BASE_TYPE_UNMARSHALL(double);
5421 TRACE("value: %f\n", **(double **)ppMemory);
5422 break;
5423 case RPC_FC_HYPER:
5424 BASE_TYPE_UNMARSHALL(ULONGLONG);
5425 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
5426 break;
5427 case RPC_FC_ENUM16:
5428 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5429 if (fMustAlloc || !*ppMemory)
5430 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
5431 TRACE("*ppMemory: %p\n", *ppMemory);
5432 /* 16-bits on the wire, but int in memory */
5433 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
5434 pStubMsg->Buffer += sizeof(USHORT);
5435 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
5436 break;
5437 default:
5438 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5440 #undef BASE_TYPE_UNMARSHALL
5442 /* FIXME: what is the correct return value? */
5444 return NULL;
5447 /***********************************************************************
5448 * NdrBaseTypeBufferSize [internal]
5450 static void WINAPI NdrBaseTypeBufferSize(
5451 PMIDL_STUB_MESSAGE pStubMsg,
5452 unsigned char *pMemory,
5453 PFORMAT_STRING pFormat)
5455 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5457 switch(*pFormat)
5459 case RPC_FC_BYTE:
5460 case RPC_FC_CHAR:
5461 case RPC_FC_SMALL:
5462 case RPC_FC_USMALL:
5463 pStubMsg->BufferLength += sizeof(UCHAR);
5464 break;
5465 case RPC_FC_WCHAR:
5466 case RPC_FC_SHORT:
5467 case RPC_FC_USHORT:
5468 case RPC_FC_ENUM16:
5469 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
5470 pStubMsg->BufferLength += sizeof(USHORT);
5471 break;
5472 case RPC_FC_LONG:
5473 case RPC_FC_ULONG:
5474 case RPC_FC_ENUM32:
5475 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
5476 pStubMsg->BufferLength += sizeof(ULONG);
5477 break;
5478 case RPC_FC_FLOAT:
5479 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
5480 pStubMsg->BufferLength += sizeof(float);
5481 break;
5482 case RPC_FC_DOUBLE:
5483 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
5484 pStubMsg->BufferLength += sizeof(double);
5485 break;
5486 case RPC_FC_HYPER:
5487 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
5488 pStubMsg->BufferLength += sizeof(ULONGLONG);
5489 break;
5490 case RPC_FC_ERROR_STATUS_T:
5491 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
5492 pStubMsg->BufferLength += sizeof(error_status_t);
5493 break;
5494 default:
5495 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5499 /***********************************************************************
5500 * NdrBaseTypeMemorySize [internal]
5502 static ULONG WINAPI NdrBaseTypeMemorySize(
5503 PMIDL_STUB_MESSAGE pStubMsg,
5504 PFORMAT_STRING pFormat)
5506 switch(*pFormat)
5508 case RPC_FC_BYTE:
5509 case RPC_FC_CHAR:
5510 case RPC_FC_SMALL:
5511 case RPC_FC_USMALL:
5512 pStubMsg->Buffer += sizeof(UCHAR);
5513 pStubMsg->MemorySize += sizeof(UCHAR);
5514 return sizeof(UCHAR);
5515 case RPC_FC_WCHAR:
5516 case RPC_FC_SHORT:
5517 case RPC_FC_USHORT:
5518 pStubMsg->Buffer += sizeof(USHORT);
5519 pStubMsg->MemorySize += sizeof(USHORT);
5520 return sizeof(USHORT);
5521 case RPC_FC_LONG:
5522 case RPC_FC_ULONG:
5523 pStubMsg->Buffer += sizeof(ULONG);
5524 pStubMsg->MemorySize += sizeof(ULONG);
5525 return sizeof(ULONG);
5526 case RPC_FC_FLOAT:
5527 pStubMsg->Buffer += sizeof(float);
5528 pStubMsg->MemorySize += sizeof(float);
5529 return sizeof(float);
5530 case RPC_FC_DOUBLE:
5531 pStubMsg->Buffer += sizeof(double);
5532 pStubMsg->MemorySize += sizeof(double);
5533 return sizeof(double);
5534 case RPC_FC_HYPER:
5535 pStubMsg->Buffer += sizeof(ULONGLONG);
5536 pStubMsg->MemorySize += sizeof(ULONGLONG);
5537 return sizeof(ULONGLONG);
5538 case RPC_FC_ERROR_STATUS_T:
5539 pStubMsg->Buffer += sizeof(error_status_t);
5540 pStubMsg->MemorySize += sizeof(error_status_t);
5541 return sizeof(error_status_t);
5542 case RPC_FC_ENUM16:
5543 case RPC_FC_ENUM32:
5544 pStubMsg->Buffer += sizeof(INT);
5545 pStubMsg->MemorySize += sizeof(INT);
5546 return sizeof(INT);
5547 default:
5548 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5549 return 0;
5553 /***********************************************************************
5554 * NdrBaseTypeFree [internal]
5556 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
5557 unsigned char *pMemory,
5558 PFORMAT_STRING pFormat)
5560 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5562 /* nothing to do */
5565 /***********************************************************************
5566 * NdrContextHandleBufferSize [internal]
5568 static void WINAPI NdrContextHandleBufferSize(
5569 PMIDL_STUB_MESSAGE pStubMsg,
5570 unsigned char *pMemory,
5571 PFORMAT_STRING pFormat)
5573 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5575 if (*pFormat != RPC_FC_BIND_CONTEXT)
5577 ERR("invalid format type %x\n", *pFormat);
5578 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5580 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5581 pStubMsg->BufferLength += cbNDRContext;
5584 /***********************************************************************
5585 * NdrContextHandleMarshall [internal]
5587 static unsigned char *WINAPI NdrContextHandleMarshall(
5588 PMIDL_STUB_MESSAGE pStubMsg,
5589 unsigned char *pMemory,
5590 PFORMAT_STRING pFormat)
5592 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5594 if (*pFormat != RPC_FC_BIND_CONTEXT)
5596 ERR("invalid format type %x\n", *pFormat);
5597 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5600 if (pFormat[1] & 0x80)
5601 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
5602 else
5603 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
5605 return NULL;
5608 /***********************************************************************
5609 * NdrContextHandleUnmarshall [internal]
5611 static unsigned char *WINAPI NdrContextHandleUnmarshall(
5612 PMIDL_STUB_MESSAGE pStubMsg,
5613 unsigned char **ppMemory,
5614 PFORMAT_STRING pFormat,
5615 unsigned char fMustAlloc)
5617 if (*pFormat != RPC_FC_BIND_CONTEXT)
5619 ERR("invalid format type %x\n", *pFormat);
5620 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5623 **(NDR_CCONTEXT **)ppMemory = NULL;
5624 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
5626 return NULL;
5629 /***********************************************************************
5630 * NdrClientContextMarshall [RPCRT4.@]
5632 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5633 NDR_CCONTEXT ContextHandle,
5634 int fCheck)
5636 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
5638 ALIGN_POINTER(pStubMsg->Buffer, 4);
5640 /* FIXME: what does fCheck do? */
5641 NDRCContextMarshall(ContextHandle,
5642 pStubMsg->Buffer);
5644 pStubMsg->Buffer += cbNDRContext;
5647 /***********************************************************************
5648 * NdrClientContextUnmarshall [RPCRT4.@]
5650 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5651 NDR_CCONTEXT * pContextHandle,
5652 RPC_BINDING_HANDLE BindHandle)
5654 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
5656 ALIGN_POINTER(pStubMsg->Buffer, 4);
5658 NDRCContextUnmarshall(pContextHandle,
5659 BindHandle,
5660 pStubMsg->Buffer,
5661 pStubMsg->RpcMsg->DataRepresentation);
5663 pStubMsg->Buffer += cbNDRContext;
5666 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5667 NDR_SCONTEXT ContextHandle,
5668 NDR_RUNDOWN RundownRoutine )
5670 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
5673 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
5675 FIXME("(%p): stub\n", pStubMsg);
5676 return NULL;
5679 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
5680 unsigned char* pMemory,
5681 PFORMAT_STRING pFormat)
5683 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
5686 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
5687 PFORMAT_STRING pFormat)
5689 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
5690 return NULL;
5693 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5694 NDR_SCONTEXT ContextHandle,
5695 NDR_RUNDOWN RundownRoutine,
5696 PFORMAT_STRING pFormat)
5698 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
5701 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5702 PFORMAT_STRING pFormat)
5704 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
5705 return NULL;
5708 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
5710 typedef struct ndr_context_handle
5712 DWORD attributes;
5713 GUID uuid;
5714 } ndr_context_handle;
5716 struct context_handle_entry
5718 struct list entry;
5719 DWORD magic;
5720 RPC_BINDING_HANDLE handle;
5721 ndr_context_handle wire_data;
5724 static struct list context_handle_list = LIST_INIT(context_handle_list);
5726 static CRITICAL_SECTION ndr_context_cs;
5727 static CRITICAL_SECTION_DEBUG ndr_context_debug =
5729 0, 0, &ndr_context_cs,
5730 { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
5731 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
5733 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
5735 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
5737 struct context_handle_entry *che = (struct context_handle_entry*) CContext;
5739 if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
5740 return NULL;
5741 return che;
5744 static struct context_handle_entry *context_entry_from_guid(LPGUID uuid)
5746 struct context_handle_entry *che;
5747 LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
5748 if (IsEqualGUID(&che->wire_data.uuid, uuid))
5749 return che;
5750 return NULL;
5753 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
5755 struct context_handle_entry *che;
5756 RPC_BINDING_HANDLE handle = NULL;
5758 TRACE("%p\n", CContext);
5760 EnterCriticalSection(&ndr_context_cs);
5761 che = get_context_entry(CContext);
5762 if (che)
5763 handle = che->handle;
5764 LeaveCriticalSection(&ndr_context_cs);
5766 if (!handle)
5767 RpcRaiseException(ERROR_INVALID_HANDLE);
5768 return handle;
5771 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
5773 struct context_handle_entry *che;
5775 TRACE("%p %p\n", CContext, pBuff);
5777 if (CContext)
5779 EnterCriticalSection(&ndr_context_cs);
5780 che = get_context_entry(CContext);
5781 memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
5782 LeaveCriticalSection(&ndr_context_cs);
5784 else
5786 ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
5787 wire_data->attributes = 0;
5788 wire_data->uuid = GUID_NULL;
5792 static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
5793 RPC_BINDING_HANDLE hBinding,
5794 ndr_context_handle *chi)
5796 struct context_handle_entry *che = NULL;
5798 /* a null UUID means we should free the context handle */
5799 if (IsEqualGUID(&chi->uuid, &GUID_NULL))
5801 if (*CContext)
5803 che = get_context_entry(*CContext);
5804 if (!che)
5805 return ERROR_INVALID_HANDLE;
5806 list_remove(&che->entry);
5807 RpcBindingFree(&che->handle);
5808 HeapFree(GetProcessHeap(), 0, che);
5809 che = NULL;
5812 /* if there's no existing entry matching the GUID, allocate one */
5813 else if (!(che = context_entry_from_guid(&chi->uuid)))
5815 che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
5816 if (!che)
5817 return ERROR_NOT_ENOUGH_MEMORY;
5818 che->magic = NDR_CONTEXT_HANDLE_MAGIC;
5819 RpcBindingCopy(hBinding, &che->handle);
5820 list_add_tail(&context_handle_list, &che->entry);
5821 memcpy(&che->wire_data, chi, sizeof *chi);
5824 *CContext = che;
5826 return ERROR_SUCCESS;
5829 /***********************************************************************
5830 * NDRCContextUnmarshall [RPCRT4.@]
5832 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
5833 RPC_BINDING_HANDLE hBinding,
5834 void *pBuff, ULONG DataRepresentation)
5836 UINT r;
5838 TRACE("*%p=(%p) %p %p %08x\n",
5839 CContext, *CContext, hBinding, pBuff, DataRepresentation);
5841 EnterCriticalSection(&ndr_context_cs);
5842 r = ndr_update_context_handle(CContext, hBinding, pBuff);
5843 LeaveCriticalSection(&ndr_context_cs);
5844 if (r)
5845 RpcRaiseException(r);
5848 /***********************************************************************
5849 * NDRSContextMarshall [RPCRT4.@]
5851 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
5852 void *pBuff,
5853 NDR_RUNDOWN userRunDownIn)
5855 FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn);
5858 /***********************************************************************
5859 * NDRSContextMarshallEx [RPCRT4.@]
5861 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
5862 NDR_SCONTEXT CContext,
5863 void *pBuff,
5864 NDR_RUNDOWN userRunDownIn)
5866 FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn);
5869 /***********************************************************************
5870 * NDRSContextMarshall2 [RPCRT4.@]
5872 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
5873 NDR_SCONTEXT CContext,
5874 void *pBuff,
5875 NDR_RUNDOWN userRunDownIn,
5876 void *CtxGuard, ULONG Flags)
5878 FIXME("(%p %p %p %p %p %u): stub\n",
5879 hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags);
5882 /***********************************************************************
5883 * NDRSContextUnmarshall [RPCRT4.@]
5885 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
5886 ULONG DataRepresentation)
5888 FIXME("(%p %08x): stub\n", pBuff, DataRepresentation);
5889 return NULL;
5892 /***********************************************************************
5893 * NDRSContextUnmarshallEx [RPCRT4.@]
5895 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
5896 void *pBuff,
5897 ULONG DataRepresentation)
5899 FIXME("(%p %p %08x): stub\n", hBinding, pBuff, DataRepresentation);
5900 return NULL;
5903 /***********************************************************************
5904 * NDRSContextUnmarshall2 [RPCRT4.@]
5906 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
5907 void *pBuff,
5908 ULONG DataRepresentation,
5909 void *CtxGuard, ULONG Flags)
5911 FIXME("(%p %p %08x %p %u): stub\n",
5912 hBinding, pBuff, DataRepresentation, CtxGuard, Flags);
5913 return NULL;