rpcrt4: Fix NdrFixedArrayUnmarshall to use buffer memory if applicable and to reuse...
[wine.git] / dlls / rpcrt4 / ndr_marshall.c
blob0a5bd9c07972b72c9919f79ca32b7914d3cdbd2b
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 * - Byte count pointers
25 * - transmit_as/represent as
26 * - Multi-dimensional arrays
27 * - Conversion functions (NdrConvert)
28 * - Checks for integer addition overflow
29 * - Checks for out-of-memory conditions
32 #include <stdarg.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <assert.h>
36 #include <limits.h>
38 #include "windef.h"
39 #include "winbase.h"
40 #include "winerror.h"
42 #include "ndr_misc.h"
43 #include "rpcndr.h"
45 #include "wine/unicode.h"
46 #include "wine/rpcfc.h"
48 #include "wine/debug.h"
49 #include "wine/list.h"
51 WINE_DEFAULT_DEBUG_CHANNEL(ole);
53 #if defined(__i386__)
54 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
55 (*((UINT32 *)(pchar)) = (uint32))
57 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
58 (*((UINT32 *)(pchar)))
59 #else
60 /* these would work for i386 too, but less efficient */
61 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
62 (*(pchar) = LOBYTE(LOWORD(uint32)), \
63 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
64 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
65 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
66 (uint32)) /* allow as r-value */
68 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
69 (MAKELONG( \
70 MAKEWORD(*(pchar), *((pchar)+1)), \
71 MAKEWORD(*((pchar)+2), *((pchar)+3))))
72 #endif
74 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
75 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
76 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
77 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
78 *(pchar) = HIBYTE(HIWORD(uint32)), \
79 (uint32)) /* allow as r-value */
81 #define BIG_ENDIAN_UINT32_READ(pchar) \
82 (MAKELONG( \
83 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
84 MAKEWORD(*((pchar)+1), *(pchar))))
86 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
87 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
88 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
89 # define NDR_LOCAL_UINT32_READ(pchar) \
90 BIG_ENDIAN_UINT32_READ(pchar)
91 #else
92 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
93 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
94 # define NDR_LOCAL_UINT32_READ(pchar) \
95 LITTLE_ENDIAN_UINT32_READ(pchar)
96 #endif
98 /* _Align must be the desired alignment,
99 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
100 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
101 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
102 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
103 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
105 #define STD_OVERFLOW_CHECK(_Msg) do { \
106 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
107 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
108 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
109 } while (0)
111 #define NDR_TABLE_SIZE 128
112 #define NDR_TABLE_MASK 127
114 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
115 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
116 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
117 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
118 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
120 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
121 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
122 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
124 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
126 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
127 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
128 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
129 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
130 /* 0x10 */
131 NdrBaseTypeMarshall,
132 /* 0x11 */
133 NdrPointerMarshall, NdrPointerMarshall,
134 NdrPointerMarshall, NdrPointerMarshall,
135 /* 0x15 */
136 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
137 NdrConformantStructMarshall, NdrConformantStructMarshall,
138 NdrConformantVaryingStructMarshall,
139 NdrComplexStructMarshall,
140 /* 0x1b */
141 NdrConformantArrayMarshall,
142 NdrConformantVaryingArrayMarshall,
143 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
144 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
145 NdrComplexArrayMarshall,
146 /* 0x22 */
147 NdrConformantStringMarshall, 0, 0,
148 NdrConformantStringMarshall,
149 NdrNonConformantStringMarshall, 0, 0, 0,
150 /* 0x2a */
151 NdrEncapsulatedUnionMarshall,
152 NdrNonEncapsulatedUnionMarshall,
153 NdrByteCountPointerMarshall,
154 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
155 /* 0x2f */
156 NdrInterfacePointerMarshall,
157 /* 0x30 */
158 NdrContextHandleMarshall,
159 /* 0xb1 */
160 0, 0, 0,
161 NdrUserMarshalMarshall,
162 0, 0,
163 /* 0xb7 */
164 NdrRangeMarshall
166 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
168 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
169 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
170 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
171 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
172 /* 0x10 */
173 NdrBaseTypeUnmarshall,
174 /* 0x11 */
175 NdrPointerUnmarshall, NdrPointerUnmarshall,
176 NdrPointerUnmarshall, NdrPointerUnmarshall,
177 /* 0x15 */
178 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
179 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
180 NdrConformantVaryingStructUnmarshall,
181 NdrComplexStructUnmarshall,
182 /* 0x1b */
183 NdrConformantArrayUnmarshall,
184 NdrConformantVaryingArrayUnmarshall,
185 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
186 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
187 NdrComplexArrayUnmarshall,
188 /* 0x22 */
189 NdrConformantStringUnmarshall, 0, 0,
190 NdrConformantStringUnmarshall,
191 NdrNonConformantStringUnmarshall, 0, 0, 0,
192 /* 0x2a */
193 NdrEncapsulatedUnionUnmarshall,
194 NdrNonEncapsulatedUnionUnmarshall,
195 NdrByteCountPointerUnmarshall,
196 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
197 /* 0x2f */
198 NdrInterfacePointerUnmarshall,
199 /* 0x30 */
200 NdrContextHandleUnmarshall,
201 /* 0xb1 */
202 0, 0, 0,
203 NdrUserMarshalUnmarshall,
204 0, 0,
205 /* 0xb7 */
206 NdrRangeUnmarshall
208 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
210 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
211 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
212 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
213 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
214 /* 0x10 */
215 NdrBaseTypeBufferSize,
216 /* 0x11 */
217 NdrPointerBufferSize, NdrPointerBufferSize,
218 NdrPointerBufferSize, NdrPointerBufferSize,
219 /* 0x15 */
220 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
221 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
222 NdrConformantVaryingStructBufferSize,
223 NdrComplexStructBufferSize,
224 /* 0x1b */
225 NdrConformantArrayBufferSize,
226 NdrConformantVaryingArrayBufferSize,
227 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
228 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
229 NdrComplexArrayBufferSize,
230 /* 0x22 */
231 NdrConformantStringBufferSize, 0, 0,
232 NdrConformantStringBufferSize,
233 NdrNonConformantStringBufferSize, 0, 0, 0,
234 /* 0x2a */
235 NdrEncapsulatedUnionBufferSize,
236 NdrNonEncapsulatedUnionBufferSize,
237 NdrByteCountPointerBufferSize,
238 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
239 /* 0x2f */
240 NdrInterfacePointerBufferSize,
241 /* 0x30 */
242 NdrContextHandleBufferSize,
243 /* 0xb1 */
244 0, 0, 0,
245 NdrUserMarshalBufferSize,
246 0, 0,
247 /* 0xb7 */
248 NdrRangeBufferSize
250 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
252 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
253 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
254 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
255 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
256 /* 0x10 */
257 NdrBaseTypeMemorySize,
258 /* 0x11 */
259 NdrPointerMemorySize, NdrPointerMemorySize,
260 NdrPointerMemorySize, NdrPointerMemorySize,
261 /* 0x15 */
262 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
263 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
264 NdrConformantVaryingStructMemorySize,
265 NdrComplexStructMemorySize,
266 /* 0x1b */
267 NdrConformantArrayMemorySize,
268 NdrConformantVaryingArrayMemorySize,
269 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
270 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
271 NdrComplexArrayMemorySize,
272 /* 0x22 */
273 NdrConformantStringMemorySize, 0, 0,
274 NdrConformantStringMemorySize,
275 NdrNonConformantStringMemorySize, 0, 0, 0,
276 /* 0x2a */
277 NdrEncapsulatedUnionMemorySize,
278 NdrNonEncapsulatedUnionMemorySize,
279 NdrByteCountPointerMemorySize,
280 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
281 /* 0x2f */
282 NdrInterfacePointerMemorySize,
283 /* 0x30 */
285 /* 0xb1 */
286 0, 0, 0,
287 NdrUserMarshalMemorySize,
288 0, 0,
289 /* 0xb7 */
290 NdrRangeMemorySize
292 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
294 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
295 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
296 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
297 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
298 /* 0x10 */
299 NdrBaseTypeFree,
300 /* 0x11 */
301 NdrPointerFree, NdrPointerFree,
302 NdrPointerFree, NdrPointerFree,
303 /* 0x15 */
304 NdrSimpleStructFree, NdrSimpleStructFree,
305 NdrConformantStructFree, NdrConformantStructFree,
306 NdrConformantVaryingStructFree,
307 NdrComplexStructFree,
308 /* 0x1b */
309 NdrConformantArrayFree,
310 NdrConformantVaryingArrayFree,
311 NdrFixedArrayFree, NdrFixedArrayFree,
312 NdrVaryingArrayFree, NdrVaryingArrayFree,
313 NdrComplexArrayFree,
314 /* 0x22 */
315 0, 0, 0,
316 0, 0, 0, 0, 0,
317 /* 0x2a */
318 NdrEncapsulatedUnionFree,
319 NdrNonEncapsulatedUnionFree,
321 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
322 /* 0x2f */
323 NdrInterfacePointerFree,
324 /* 0x30 */
326 /* 0xb1 */
327 0, 0, 0,
328 NdrUserMarshalFree,
329 0, 0,
330 /* 0xb7 */
331 NdrRangeFree
334 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
336 /* hmm, this is probably supposed to do more? */
337 return pStubMsg->pfnAllocate(len);
340 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
342 pStubMsg->pfnFree(Pointer);
345 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
347 return (*(const ULONG *)pFormat != -1);
350 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
352 ALIGN_POINTER(pStubMsg->Buffer, 4);
353 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
354 RpcRaiseException(RPC_X_BAD_STUB_DATA);
355 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
356 pStubMsg->Buffer += 4;
357 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
358 if (pStubMsg->fHasNewCorrDesc)
359 return pFormat+6;
360 else
361 return pFormat+4;
364 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
366 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
368 pStubMsg->Offset = 0;
369 pStubMsg->ActualCount = pStubMsg->MaxCount;
370 goto done;
373 ALIGN_POINTER(pStubMsg->Buffer, 4);
374 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
375 RpcRaiseException(RPC_X_BAD_STUB_DATA);
376 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
377 pStubMsg->Buffer += 4;
378 TRACE("offset is %d\n", pStubMsg->Offset);
379 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
380 pStubMsg->Buffer += 4;
381 TRACE("variance is %d\n", pStubMsg->ActualCount);
383 if ((pStubMsg->ActualCount > MaxValue) ||
384 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
386 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
387 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
388 RpcRaiseException(RPC_S_INVALID_BOUND);
389 return NULL;
392 done:
393 if (pStubMsg->fHasNewCorrDesc)
394 return pFormat+6;
395 else
396 return pFormat+4;
399 /* writes the conformance value to the buffer */
400 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
402 ALIGN_POINTER(pStubMsg->Buffer, 4);
403 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
404 RpcRaiseException(RPC_X_BAD_STUB_DATA);
405 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
406 pStubMsg->Buffer += 4;
409 /* writes the variance values to the buffer */
410 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
412 ALIGN_POINTER(pStubMsg->Buffer, 4);
413 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
414 RpcRaiseException(RPC_X_BAD_STUB_DATA);
415 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
416 pStubMsg->Buffer += 4;
417 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
418 pStubMsg->Buffer += 4;
421 /* requests buffer space for the conformance value */
422 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
424 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
425 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
426 RpcRaiseException(RPC_X_BAD_STUB_DATA);
427 pStubMsg->BufferLength += 4;
430 /* requests buffer space for the variance values */
431 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
433 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
434 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
435 RpcRaiseException(RPC_X_BAD_STUB_DATA);
436 pStubMsg->BufferLength += 8;
439 PFORMAT_STRING ComputeConformanceOrVariance(
440 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
441 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
443 BYTE dtype = pFormat[0] & 0xf;
444 short ofs = *(const short *)&pFormat[2];
445 LPVOID ptr = NULL;
446 DWORD data = 0;
448 if (!IsConformanceOrVariancePresent(pFormat)) {
449 /* null descriptor */
450 *pCount = def;
451 goto finish_conf;
454 switch (pFormat[0] & 0xf0) {
455 case RPC_FC_NORMAL_CONFORMANCE:
456 TRACE("normal conformance, ofs=%d\n", ofs);
457 ptr = pMemory;
458 break;
459 case RPC_FC_POINTER_CONFORMANCE:
460 TRACE("pointer conformance, ofs=%d\n", ofs);
461 ptr = pStubMsg->Memory;
462 break;
463 case RPC_FC_TOP_LEVEL_CONFORMANCE:
464 TRACE("toplevel conformance, ofs=%d\n", ofs);
465 if (pStubMsg->StackTop) {
466 ptr = pStubMsg->StackTop;
468 else {
469 /* -Os mode, *pCount is already set */
470 goto finish_conf;
472 break;
473 case RPC_FC_CONSTANT_CONFORMANCE:
474 data = ofs | ((DWORD)pFormat[1] << 16);
475 TRACE("constant conformance, val=%d\n", data);
476 *pCount = data;
477 goto finish_conf;
478 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
479 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
480 if (pStubMsg->StackTop) {
481 ptr = pStubMsg->StackTop;
483 else {
484 /* ? */
485 goto done_conf_grab;
487 break;
488 default:
489 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
492 switch (pFormat[1]) {
493 case RPC_FC_DEREFERENCE:
494 ptr = *(LPVOID*)((char *)ptr + ofs);
495 break;
496 case RPC_FC_CALLBACK:
498 unsigned char *old_stack_top = pStubMsg->StackTop;
499 pStubMsg->StackTop = ptr;
501 /* ofs is index into StubDesc->apfnExprEval */
502 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
503 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
505 pStubMsg->StackTop = old_stack_top;
507 /* the callback function always stores the computed value in MaxCount */
508 *pCount = pStubMsg->MaxCount;
509 goto finish_conf;
511 default:
512 ptr = (char *)ptr + ofs;
513 break;
516 switch (dtype) {
517 case RPC_FC_LONG:
518 case RPC_FC_ULONG:
519 data = *(DWORD*)ptr;
520 break;
521 case RPC_FC_SHORT:
522 data = *(SHORT*)ptr;
523 break;
524 case RPC_FC_USHORT:
525 data = *(USHORT*)ptr;
526 break;
527 case RPC_FC_CHAR:
528 case RPC_FC_SMALL:
529 data = *(CHAR*)ptr;
530 break;
531 case RPC_FC_BYTE:
532 case RPC_FC_USMALL:
533 data = *(UCHAR*)ptr;
534 break;
535 default:
536 FIXME("unknown conformance data type %x\n", dtype);
537 goto done_conf_grab;
539 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
541 done_conf_grab:
542 switch (pFormat[1]) {
543 case RPC_FC_DEREFERENCE: /* already handled */
544 case 0: /* no op */
545 *pCount = data;
546 break;
547 case RPC_FC_ADD_1:
548 *pCount = data + 1;
549 break;
550 case RPC_FC_SUB_1:
551 *pCount = data - 1;
552 break;
553 case RPC_FC_MULT_2:
554 *pCount = data * 2;
555 break;
556 case RPC_FC_DIV_2:
557 *pCount = data / 2;
558 break;
559 default:
560 FIXME("unknown conformance op %d\n", pFormat[1]);
561 goto finish_conf;
564 finish_conf:
565 TRACE("resulting conformance is %ld\n", *pCount);
566 if (pStubMsg->fHasNewCorrDesc)
567 return pFormat+6;
568 else
569 return pFormat+4;
572 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
573 * the result overflows 32-bits */
574 static inline ULONG safe_multiply(ULONG a, ULONG b)
576 ULONGLONG ret = (ULONGLONG)a * b;
577 if (ret > 0xffffffff)
579 RpcRaiseException(RPC_S_INVALID_BOUND);
580 return 0;
582 return ret;
585 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
587 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
588 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
589 RpcRaiseException(RPC_X_BAD_STUB_DATA);
590 pStubMsg->Buffer += size;
593 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
595 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
597 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
598 pStubMsg->BufferLength, size);
599 RpcRaiseException(RPC_X_BAD_STUB_DATA);
601 pStubMsg->BufferLength += size;
604 /* copies data from the buffer, checking that there is enough data in the buffer
605 * to do so */
606 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
608 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
609 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
610 RpcRaiseException(RPC_X_BAD_STUB_DATA);
611 memcpy(p, pStubMsg->Buffer, size);
612 pStubMsg->Buffer += size;
615 /* copies data to the buffer, checking that there is enough space to do so */
616 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
618 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
619 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
621 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
622 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
623 size);
624 RpcRaiseException(RPC_X_BAD_STUB_DATA);
626 memcpy(pStubMsg->Buffer, p, size);
627 pStubMsg->Buffer += size;
631 * NdrConformantString:
633 * What MS calls a ConformantString is, in DCE terminology,
634 * a Varying-Conformant String.
636 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
637 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
638 * into unmarshalled string)
639 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
640 * [
641 * data: CHARTYPE[maxlen]
642 * ]
643 * ], where CHARTYPE is the appropriate character type (specified externally)
647 /***********************************************************************
648 * NdrConformantStringMarshall [RPCRT4.@]
650 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
651 unsigned char *pszMessage, PFORMAT_STRING pFormat)
653 ULONG esize, size;
655 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
657 if (*pFormat == RPC_FC_C_CSTRING) {
658 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
659 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
660 esize = 1;
662 else if (*pFormat == RPC_FC_C_WSTRING) {
663 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
664 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
665 esize = 2;
667 else {
668 ERR("Unhandled string type: %#x\n", *pFormat);
669 /* FIXME: raise an exception. */
670 return NULL;
673 if (pFormat[1] == RPC_FC_STRING_SIZED)
674 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
675 else
676 pStubMsg->MaxCount = pStubMsg->ActualCount;
677 pStubMsg->Offset = 0;
678 WriteConformance(pStubMsg);
679 WriteVariance(pStubMsg);
681 size = safe_multiply(esize, pStubMsg->ActualCount);
682 safe_copy_to_buffer(pStubMsg, pszMessage, size); /* the string itself */
684 /* success */
685 return NULL; /* is this always right? */
688 /***********************************************************************
689 * NdrConformantStringBufferSize [RPCRT4.@]
691 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
692 unsigned char* pMemory, PFORMAT_STRING pFormat)
694 ULONG esize;
696 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
698 SizeConformance(pStubMsg);
699 SizeVariance(pStubMsg);
701 if (*pFormat == RPC_FC_C_CSTRING) {
702 TRACE("string=%s\n", debugstr_a((char*)pMemory));
703 pStubMsg->ActualCount = strlen((char*)pMemory)+1;
704 esize = 1;
706 else if (*pFormat == RPC_FC_C_WSTRING) {
707 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
708 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;
709 esize = 2;
711 else {
712 ERR("Unhandled string type: %#x\n", *pFormat);
713 /* FIXME: raise an exception */
714 return;
717 if (pFormat[1] == RPC_FC_STRING_SIZED)
718 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
719 else
720 pStubMsg->MaxCount = pStubMsg->ActualCount;
722 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
725 /************************************************************************
726 * NdrConformantStringMemorySize [RPCRT4.@]
728 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
729 PFORMAT_STRING pFormat )
731 ULONG rslt = 0;
733 FIXME("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
735 assert(pStubMsg && pFormat);
737 if (*pFormat == RPC_FC_C_CSTRING) {
738 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
740 else if (*pFormat == RPC_FC_C_WSTRING) {
741 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
743 else {
744 ERR("Unhandled string type: %#x\n", *pFormat);
745 /* FIXME: raise an exception */
748 if (pFormat[1] != RPC_FC_PAD) {
749 FIXME("sized string format=%d\n", pFormat[1]);
752 TRACE(" --> %u\n", rslt);
753 return rslt;
756 /************************************************************************
757 * NdrConformantStringUnmarshall [RPCRT4.@]
759 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
760 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
762 ULONG bufsize, memsize, esize, i;
764 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
765 pStubMsg, *ppMemory, pFormat, fMustAlloc);
767 assert(pFormat && ppMemory && pStubMsg);
769 ReadConformance(pStubMsg, NULL);
770 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
772 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
773 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
774 else {
775 ERR("Unhandled string type: %#x\n", *pFormat);
776 /* FIXME: raise an exception */
777 esize = 0;
780 memsize = safe_multiply(esize, pStubMsg->MaxCount);
781 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
783 /* strings must always have null terminating bytes */
784 if (bufsize < esize)
786 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
787 RpcRaiseException(RPC_S_INVALID_BOUND);
788 return NULL;
791 /* verify the buffer is safe to access */
792 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
793 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
795 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
796 pStubMsg->BufferEnd, pStubMsg->Buffer);
797 RpcRaiseException(RPC_X_BAD_STUB_DATA);
798 return NULL;
801 for (i = bufsize - esize; i < bufsize; i++)
802 if (pStubMsg->Buffer[i] != 0)
804 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
805 i, pStubMsg->Buffer[i]);
806 RpcRaiseException(RPC_S_INVALID_BOUND);
807 return NULL;
810 if (fMustAlloc || !*ppMemory)
811 *ppMemory = NdrAllocate(pStubMsg, memsize);
813 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
815 if (*pFormat == RPC_FC_C_CSTRING) {
816 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
818 else if (*pFormat == RPC_FC_C_WSTRING) {
819 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
822 return NULL; /* FIXME: is this always right? */
825 /***********************************************************************
826 * NdrNonConformantStringMarshall [RPCRT4.@]
828 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
829 unsigned char *pMemory,
830 PFORMAT_STRING pFormat)
832 FIXME("stub\n");
833 return NULL;
836 /***********************************************************************
837 * NdrNonConformantStringUnmarshall [RPCRT4.@]
839 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
840 unsigned char **ppMemory,
841 PFORMAT_STRING pFormat,
842 unsigned char fMustAlloc)
844 FIXME("stub\n");
845 return NULL;
848 /***********************************************************************
849 * NdrNonConformantStringBufferSize [RPCRT4.@]
851 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
852 unsigned char *pMemory,
853 PFORMAT_STRING pFormat)
855 FIXME("stub\n");
858 /***********************************************************************
859 * NdrNonConformantStringMemorySize [RPCRT4.@]
861 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
862 PFORMAT_STRING pFormat)
864 FIXME("stub\n");
865 return 0;
868 static inline void dump_pointer_attr(unsigned char attr)
870 if (attr & RPC_FC_P_ALLOCALLNODES)
871 TRACE(" RPC_FC_P_ALLOCALLNODES");
872 if (attr & RPC_FC_P_DONTFREE)
873 TRACE(" RPC_FC_P_DONTFREE");
874 if (attr & RPC_FC_P_ONSTACK)
875 TRACE(" RPC_FC_P_ONSTACK");
876 if (attr & RPC_FC_P_SIMPLEPOINTER)
877 TRACE(" RPC_FC_P_SIMPLEPOINTER");
878 if (attr & RPC_FC_P_DEREF)
879 TRACE(" RPC_FC_P_DEREF");
880 TRACE("\n");
883 /***********************************************************************
884 * PointerMarshall [internal]
886 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
887 unsigned char *Buffer,
888 unsigned char *Pointer,
889 PFORMAT_STRING pFormat)
891 unsigned type = pFormat[0], attr = pFormat[1];
892 PFORMAT_STRING desc;
893 NDR_MARSHALL m;
894 ULONG pointer_id;
895 int pointer_needs_marshaling;
897 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
898 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
899 pFormat += 2;
900 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
901 else desc = pFormat + *(const SHORT*)pFormat;
903 switch (type) {
904 case RPC_FC_RP: /* ref pointer (always non-null) */
905 if (!Pointer)
907 ERR("NULL ref pointer is not allowed\n");
908 RpcRaiseException(RPC_X_NULL_REF_POINTER);
910 pointer_needs_marshaling = 1;
911 break;
912 case RPC_FC_UP: /* unique pointer */
913 case RPC_FC_OP: /* object pointer - same as unique here */
914 if (Pointer)
915 pointer_needs_marshaling = 1;
916 else
917 pointer_needs_marshaling = 0;
918 pointer_id = (ULONG)Pointer;
919 TRACE("writing 0x%08x to buffer\n", pointer_id);
920 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
921 break;
922 case RPC_FC_FP:
923 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
924 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
925 TRACE("writing 0x%08x to buffer\n", pointer_id);
926 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
927 break;
928 default:
929 FIXME("unhandled ptr type=%02x\n", type);
930 RpcRaiseException(RPC_X_BAD_STUB_DATA);
931 return;
934 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
936 if (pointer_needs_marshaling) {
937 if (attr & RPC_FC_P_DEREF) {
938 Pointer = *(unsigned char**)Pointer;
939 TRACE("deref => %p\n", Pointer);
941 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
942 if (m) m(pStubMsg, Pointer, desc);
943 else FIXME("no marshaller for data type=%02x\n", *desc);
946 STD_OVERFLOW_CHECK(pStubMsg);
949 /***********************************************************************
950 * PointerUnmarshall [internal]
952 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
953 unsigned char *Buffer,
954 unsigned char **pPointer,
955 unsigned char *pSrcPointer,
956 PFORMAT_STRING pFormat,
957 unsigned char fMustAlloc)
959 unsigned type = pFormat[0], attr = pFormat[1];
960 PFORMAT_STRING desc;
961 NDR_UNMARSHALL m;
962 DWORD pointer_id = 0;
963 int pointer_needs_unmarshaling;
965 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
966 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
967 pFormat += 2;
968 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
969 else desc = pFormat + *(const SHORT*)pFormat;
971 switch (type) {
972 case RPC_FC_RP: /* ref pointer (always non-null) */
973 pointer_needs_unmarshaling = 1;
974 break;
975 case RPC_FC_UP: /* unique pointer */
976 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
977 TRACE("pointer_id is 0x%08x\n", pointer_id);
978 if (pointer_id)
979 pointer_needs_unmarshaling = 1;
980 else {
981 *pPointer = NULL;
982 pointer_needs_unmarshaling = 0;
984 break;
985 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
986 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
987 TRACE("pointer_id is 0x%08x\n", pointer_id);
988 if (!fMustAlloc && pSrcPointer)
990 FIXME("free object pointer %p\n", pSrcPointer);
991 fMustAlloc = TRUE;
993 if (pointer_id)
994 pointer_needs_unmarshaling = 1;
995 else
996 pointer_needs_unmarshaling = 0;
997 break;
998 case RPC_FC_FP:
999 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1000 TRACE("pointer_id is 0x%08x\n", pointer_id);
1001 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
1002 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
1003 break;
1004 default:
1005 FIXME("unhandled ptr type=%02x\n", type);
1006 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1007 return;
1010 if (pointer_needs_unmarshaling) {
1011 unsigned char *base_ptr_val = *pPointer;
1012 unsigned char **current_ptr = pPointer;
1013 if (pStubMsg->IsClient) {
1014 TRACE("client\n");
1015 /* if we aren't forcing allocation of memory then try to use the existing
1016 * (source) pointer to unmarshall the data into so that [in,out]
1017 * parameters behave correctly. it doesn't matter if the parameter is
1018 * [out] only since in that case the pointer will be NULL. we force
1019 * allocation when the source pointer is NULL here instead of in the type
1020 * unmarshalling routine for the benefit of the deref code below */
1021 if (!fMustAlloc) {
1022 if (pSrcPointer) {
1023 TRACE("setting *pPointer to %p\n", pSrcPointer);
1024 *pPointer = base_ptr_val = pSrcPointer;
1025 } else
1026 fMustAlloc = TRUE;
1028 } else {
1029 TRACE("server\n");
1030 /* the memory in a stub is never initialised, so we have to work out here
1031 * whether we have to initialise it so we can use the optimisation of
1032 * setting the pointer to the buffer, if possible, or set fMustAlloc to
1033 * TRUE. */
1034 if (attr & RPC_FC_P_DEREF) {
1035 fMustAlloc = TRUE;
1036 } else {
1037 base_ptr_val = NULL;
1038 *current_ptr = NULL;
1042 if (attr & RPC_FC_P_DEREF) {
1043 if (fMustAlloc) {
1044 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
1045 *pPointer = base_ptr_val;
1046 current_ptr = (unsigned char **)base_ptr_val;
1047 } else
1048 current_ptr = *(unsigned char***)current_ptr;
1049 TRACE("deref => %p\n", current_ptr);
1050 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
1052 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1053 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
1054 else FIXME("no unmarshaller for data type=%02x\n", *desc);
1056 if (type == RPC_FC_FP)
1057 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
1058 base_ptr_val);
1061 TRACE("pointer=%p\n", *pPointer);
1064 /***********************************************************************
1065 * PointerBufferSize [internal]
1067 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1068 unsigned char *Pointer,
1069 PFORMAT_STRING pFormat)
1071 unsigned type = pFormat[0], attr = pFormat[1];
1072 PFORMAT_STRING desc;
1073 NDR_BUFFERSIZE m;
1074 int pointer_needs_sizing;
1075 ULONG pointer_id;
1077 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1078 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1079 pFormat += 2;
1080 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1081 else desc = pFormat + *(const SHORT*)pFormat;
1083 switch (type) {
1084 case RPC_FC_RP: /* ref pointer (always non-null) */
1085 if (!Pointer)
1087 ERR("NULL ref pointer is not allowed\n");
1088 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1090 break;
1091 case RPC_FC_OP:
1092 case RPC_FC_UP:
1093 /* NULL pointer has no further representation */
1094 if (!Pointer)
1095 return;
1096 break;
1097 case RPC_FC_FP:
1098 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1099 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1100 if (!pointer_needs_sizing)
1101 return;
1102 break;
1103 default:
1104 FIXME("unhandled ptr type=%02x\n", type);
1105 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1106 return;
1109 if (attr & RPC_FC_P_DEREF) {
1110 Pointer = *(unsigned char**)Pointer;
1111 TRACE("deref => %p\n", Pointer);
1114 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1115 if (m) m(pStubMsg, Pointer, desc);
1116 else FIXME("no buffersizer for data type=%02x\n", *desc);
1119 /***********************************************************************
1120 * PointerMemorySize [internal]
1122 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1123 unsigned char *Buffer,
1124 PFORMAT_STRING pFormat)
1126 unsigned type = pFormat[0], attr = pFormat[1];
1127 PFORMAT_STRING desc;
1128 NDR_MEMORYSIZE m;
1130 FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat);
1131 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1132 pFormat += 2;
1133 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1134 else desc = pFormat + *(const SHORT*)pFormat;
1136 switch (type) {
1137 case RPC_FC_RP: /* ref pointer (always non-null) */
1138 break;
1139 default:
1140 FIXME("unhandled ptr type=%02x\n", type);
1141 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1144 if (attr & RPC_FC_P_DEREF) {
1145 TRACE("deref\n");
1148 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1149 if (m) m(pStubMsg, desc);
1150 else FIXME("no memorysizer for data type=%02x\n", *desc);
1152 return 0;
1155 /***********************************************************************
1156 * PointerFree [internal]
1158 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1159 unsigned char *Pointer,
1160 PFORMAT_STRING pFormat)
1162 unsigned type = pFormat[0], attr = pFormat[1];
1163 PFORMAT_STRING desc;
1164 NDR_FREE m;
1166 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1167 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1168 if (attr & RPC_FC_P_DONTFREE) return;
1169 pFormat += 2;
1170 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1171 else desc = pFormat + *(const SHORT*)pFormat;
1173 if (!Pointer) return;
1175 if (type == RPC_FC_FP) {
1176 int pointer_needs_freeing = NdrFullPointerFree(
1177 pStubMsg->FullPtrXlatTables, Pointer);
1178 if (!pointer_needs_freeing)
1179 return;
1182 if (attr & RPC_FC_P_DEREF) {
1183 Pointer = *(unsigned char**)Pointer;
1184 TRACE("deref => %p\n", Pointer);
1187 m = NdrFreer[*desc & NDR_TABLE_MASK];
1188 if (m) m(pStubMsg, Pointer, desc);
1190 /* we should check if the memory comes from NdrAllocate,
1191 * and deallocate only if so - checking if the pointer is between
1192 * BufferStart and BufferEnd will not always work since the buffer
1193 * may be reallocated when the server wants to marshal the reply */
1194 if (Pointer >= (unsigned char *)pStubMsg->RpcMsg->Buffer ||
1195 Pointer <= (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
1196 goto notfree;
1198 if (attr & RPC_FC_P_ONSTACK) {
1199 TRACE("not freeing stack ptr %p\n", Pointer);
1200 return;
1202 TRACE("freeing %p\n", Pointer);
1203 NdrFree(pStubMsg, Pointer);
1204 return;
1205 notfree:
1206 TRACE("not freeing %p\n", Pointer);
1209 /***********************************************************************
1210 * EmbeddedPointerMarshall
1212 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1213 unsigned char *pMemory,
1214 PFORMAT_STRING pFormat)
1216 unsigned char *Mark = pStubMsg->BufferMark;
1217 unsigned rep, count, stride;
1218 unsigned i;
1219 unsigned char *saved_buffer = NULL;
1221 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1223 if (*pFormat != RPC_FC_PP) return NULL;
1224 pFormat += 2;
1226 if (pStubMsg->PointerBufferMark)
1228 saved_buffer = pStubMsg->Buffer;
1229 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1230 pStubMsg->PointerBufferMark = NULL;
1233 while (pFormat[0] != RPC_FC_END) {
1234 switch (pFormat[0]) {
1235 default:
1236 FIXME("unknown repeat type %d\n", pFormat[0]);
1237 case RPC_FC_NO_REPEAT:
1238 rep = 1;
1239 stride = 0;
1240 count = 1;
1241 pFormat += 2;
1242 break;
1243 case RPC_FC_FIXED_REPEAT:
1244 rep = *(const WORD*)&pFormat[2];
1245 stride = *(const WORD*)&pFormat[4];
1246 count = *(const WORD*)&pFormat[8];
1247 pFormat += 10;
1248 break;
1249 case RPC_FC_VARIABLE_REPEAT:
1250 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1251 stride = *(const WORD*)&pFormat[2];
1252 count = *(const WORD*)&pFormat[6];
1253 pFormat += 8;
1254 break;
1256 for (i = 0; i < rep; i++) {
1257 PFORMAT_STRING info = pFormat;
1258 unsigned char *membase = pMemory + (i * stride);
1259 unsigned char *bufbase = Mark + (i * stride);
1260 unsigned u;
1262 for (u=0; u<count; u++,info+=8) {
1263 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1264 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1265 unsigned char *saved_memory = pStubMsg->Memory;
1267 pStubMsg->Memory = pMemory;
1268 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1269 pStubMsg->Memory = saved_memory;
1272 pFormat += 8 * count;
1275 if (saved_buffer)
1277 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1278 pStubMsg->Buffer = saved_buffer;
1281 STD_OVERFLOW_CHECK(pStubMsg);
1283 return NULL;
1286 /***********************************************************************
1287 * EmbeddedPointerUnmarshall
1289 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1290 unsigned char *pDstMemoryPtrs,
1291 unsigned char *pSrcMemoryPtrs,
1292 PFORMAT_STRING pFormat,
1293 unsigned char fMustAlloc)
1295 unsigned char *Mark = pStubMsg->BufferMark;
1296 unsigned rep, count, stride;
1297 unsigned i;
1298 unsigned char *saved_buffer = NULL;
1300 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstMemoryPtrs, pSrcMemoryPtrs, pFormat, fMustAlloc);
1302 if (*pFormat != RPC_FC_PP) return NULL;
1303 pFormat += 2;
1305 if (pStubMsg->PointerBufferMark)
1307 saved_buffer = pStubMsg->Buffer;
1308 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1309 pStubMsg->PointerBufferMark = NULL;
1312 while (pFormat[0] != RPC_FC_END) {
1313 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1314 switch (pFormat[0]) {
1315 default:
1316 FIXME("unknown repeat type %d\n", pFormat[0]);
1317 case RPC_FC_NO_REPEAT:
1318 rep = 1;
1319 stride = 0;
1320 count = 1;
1321 pFormat += 2;
1322 break;
1323 case RPC_FC_FIXED_REPEAT:
1324 rep = *(const WORD*)&pFormat[2];
1325 stride = *(const WORD*)&pFormat[4];
1326 count = *(const WORD*)&pFormat[8];
1327 pFormat += 10;
1328 break;
1329 case RPC_FC_VARIABLE_REPEAT:
1330 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1331 stride = *(const WORD*)&pFormat[2];
1332 count = *(const WORD*)&pFormat[6];
1333 pFormat += 8;
1334 break;
1336 for (i = 0; i < rep; i++) {
1337 PFORMAT_STRING info = pFormat;
1338 unsigned char *memdstbase = pDstMemoryPtrs + (i * stride);
1339 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1340 unsigned char *bufbase = Mark + (i * stride);
1341 unsigned u;
1343 for (u=0; u<count; u++,info+=8) {
1344 unsigned char **memdstptr = (unsigned char **)(memdstbase + *(const SHORT*)&info[0]);
1345 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1346 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1347 PointerUnmarshall(pStubMsg, bufptr, memdstptr, *memsrcptr, info+4, fMustAlloc);
1350 pFormat += 8 * count;
1353 if (saved_buffer)
1355 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1356 pStubMsg->Buffer = saved_buffer;
1359 return NULL;
1362 /***********************************************************************
1363 * EmbeddedPointerBufferSize
1365 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1366 unsigned char *pMemory,
1367 PFORMAT_STRING pFormat)
1369 unsigned rep, count, stride;
1370 unsigned i;
1371 ULONG saved_buffer_length = 0;
1373 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1375 if (pStubMsg->IgnoreEmbeddedPointers) return;
1377 if (*pFormat != RPC_FC_PP) return;
1378 pFormat += 2;
1380 if (pStubMsg->PointerLength)
1382 saved_buffer_length = pStubMsg->BufferLength;
1383 pStubMsg->BufferLength = pStubMsg->PointerLength;
1384 pStubMsg->PointerLength = 0;
1387 while (pFormat[0] != RPC_FC_END) {
1388 switch (pFormat[0]) {
1389 default:
1390 FIXME("unknown repeat type %d\n", pFormat[0]);
1391 case RPC_FC_NO_REPEAT:
1392 rep = 1;
1393 stride = 0;
1394 count = 1;
1395 pFormat += 2;
1396 break;
1397 case RPC_FC_FIXED_REPEAT:
1398 rep = *(const WORD*)&pFormat[2];
1399 stride = *(const WORD*)&pFormat[4];
1400 count = *(const WORD*)&pFormat[8];
1401 pFormat += 10;
1402 break;
1403 case RPC_FC_VARIABLE_REPEAT:
1404 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1405 stride = *(const WORD*)&pFormat[2];
1406 count = *(const WORD*)&pFormat[6];
1407 pFormat += 8;
1408 break;
1410 for (i = 0; i < rep; i++) {
1411 PFORMAT_STRING info = pFormat;
1412 unsigned char *membase = pMemory + (i * stride);
1413 unsigned u;
1415 for (u=0; u<count; u++,info+=8) {
1416 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1417 unsigned char *saved_memory = pStubMsg->Memory;
1419 pStubMsg->Memory = pMemory;
1420 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1421 pStubMsg->Memory = saved_memory;
1424 pFormat += 8 * count;
1427 if (saved_buffer_length)
1429 pStubMsg->PointerLength = pStubMsg->BufferLength;
1430 pStubMsg->BufferLength = saved_buffer_length;
1434 /***********************************************************************
1435 * EmbeddedPointerMemorySize [internal]
1437 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1438 PFORMAT_STRING pFormat)
1440 unsigned char *Mark = pStubMsg->BufferMark;
1441 unsigned rep, count, stride;
1442 unsigned i;
1444 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1446 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1448 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1450 if (*pFormat != RPC_FC_PP) return 0;
1451 pFormat += 2;
1453 while (pFormat[0] != RPC_FC_END) {
1454 switch (pFormat[0]) {
1455 default:
1456 FIXME("unknown repeat type %d\n", pFormat[0]);
1457 case RPC_FC_NO_REPEAT:
1458 rep = 1;
1459 stride = 0;
1460 count = 1;
1461 pFormat += 2;
1462 break;
1463 case RPC_FC_FIXED_REPEAT:
1464 rep = *(const WORD*)&pFormat[2];
1465 stride = *(const WORD*)&pFormat[4];
1466 count = *(const WORD*)&pFormat[8];
1467 pFormat += 10;
1468 break;
1469 case RPC_FC_VARIABLE_REPEAT:
1470 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1471 stride = *(const WORD*)&pFormat[2];
1472 count = *(const WORD*)&pFormat[6];
1473 pFormat += 8;
1474 break;
1476 for (i = 0; i < rep; i++) {
1477 PFORMAT_STRING info = pFormat;
1478 unsigned char *bufbase = Mark + (i * stride);
1479 unsigned u;
1480 for (u=0; u<count; u++,info+=8) {
1481 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1482 PointerMemorySize(pStubMsg, bufptr, info+4);
1485 pFormat += 8 * count;
1488 return 0;
1491 /***********************************************************************
1492 * EmbeddedPointerFree [internal]
1494 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1495 unsigned char *pMemory,
1496 PFORMAT_STRING pFormat)
1498 unsigned rep, count, stride;
1499 unsigned i;
1501 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1502 if (*pFormat != RPC_FC_PP) return;
1503 pFormat += 2;
1505 while (pFormat[0] != RPC_FC_END) {
1506 switch (pFormat[0]) {
1507 default:
1508 FIXME("unknown repeat type %d\n", pFormat[0]);
1509 case RPC_FC_NO_REPEAT:
1510 rep = 1;
1511 stride = 0;
1512 count = 1;
1513 pFormat += 2;
1514 break;
1515 case RPC_FC_FIXED_REPEAT:
1516 rep = *(const WORD*)&pFormat[2];
1517 stride = *(const WORD*)&pFormat[4];
1518 count = *(const WORD*)&pFormat[8];
1519 pFormat += 10;
1520 break;
1521 case RPC_FC_VARIABLE_REPEAT:
1522 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1523 stride = *(const WORD*)&pFormat[2];
1524 count = *(const WORD*)&pFormat[6];
1525 pFormat += 8;
1526 break;
1528 for (i = 0; i < rep; i++) {
1529 PFORMAT_STRING info = pFormat;
1530 unsigned char *membase = pMemory + (i * stride);
1531 unsigned u;
1533 for (u=0; u<count; u++,info+=8) {
1534 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1535 unsigned char *saved_memory = pStubMsg->Memory;
1537 pStubMsg->Memory = pMemory;
1538 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1539 pStubMsg->Memory = saved_memory;
1542 pFormat += 8 * count;
1546 /***********************************************************************
1547 * NdrPointerMarshall [RPCRT4.@]
1549 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1550 unsigned char *pMemory,
1551 PFORMAT_STRING pFormat)
1553 unsigned char *Buffer;
1555 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1557 /* incremement the buffer here instead of in PointerMarshall,
1558 * as that is used by embedded pointers which already handle the incrementing
1559 * the buffer, and shouldn't write any additional pointer data to the wire */
1560 if (*pFormat != RPC_FC_RP)
1562 ALIGN_POINTER(pStubMsg->Buffer, 4);
1563 Buffer = pStubMsg->Buffer;
1564 safe_buffer_increment(pStubMsg, 4);
1566 else
1567 Buffer = pStubMsg->Buffer;
1569 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1571 return NULL;
1574 /***********************************************************************
1575 * NdrPointerUnmarshall [RPCRT4.@]
1577 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1578 unsigned char **ppMemory,
1579 PFORMAT_STRING pFormat,
1580 unsigned char fMustAlloc)
1582 unsigned char *Buffer;
1584 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1586 /* incremement the buffer here instead of in PointerUnmarshall,
1587 * as that is used by embedded pointers which already handle the incrementing
1588 * the buffer, and shouldn't read any additional pointer data from the
1589 * buffer */
1590 if (*pFormat != RPC_FC_RP)
1592 ALIGN_POINTER(pStubMsg->Buffer, 4);
1593 Buffer = pStubMsg->Buffer;
1594 safe_buffer_increment(pStubMsg, 4);
1596 else
1597 Buffer = pStubMsg->Buffer;
1599 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1601 return NULL;
1604 /***********************************************************************
1605 * NdrPointerBufferSize [RPCRT4.@]
1607 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1608 unsigned char *pMemory,
1609 PFORMAT_STRING pFormat)
1611 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1613 /* incremement the buffer length here instead of in PointerBufferSize,
1614 * as that is used by embedded pointers which already handle the buffer
1615 * length, and shouldn't write anything more to the wire */
1616 if (*pFormat != RPC_FC_RP)
1618 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1619 safe_buffer_length_increment(pStubMsg, 4);
1622 PointerBufferSize(pStubMsg, pMemory, pFormat);
1625 /***********************************************************************
1626 * NdrPointerMemorySize [RPCRT4.@]
1628 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1629 PFORMAT_STRING pFormat)
1631 /* unsigned size = *(LPWORD)(pFormat+2); */
1632 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1633 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1634 return 0;
1637 /***********************************************************************
1638 * NdrPointerFree [RPCRT4.@]
1640 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1641 unsigned char *pMemory,
1642 PFORMAT_STRING pFormat)
1644 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1645 PointerFree(pStubMsg, pMemory, pFormat);
1648 /***********************************************************************
1649 * NdrSimpleTypeMarshall [RPCRT4.@]
1651 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1652 unsigned char FormatChar )
1654 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1657 /***********************************************************************
1658 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1660 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1661 unsigned char FormatChar )
1663 NdrBaseTypeUnmarshall(pStubMsg, &pMemory, &FormatChar, 0);
1666 /***********************************************************************
1667 * NdrSimpleStructMarshall [RPCRT4.@]
1669 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1670 unsigned char *pMemory,
1671 PFORMAT_STRING pFormat)
1673 unsigned size = *(const WORD*)(pFormat+2);
1674 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1676 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1678 pStubMsg->BufferMark = pStubMsg->Buffer;
1679 safe_copy_to_buffer(pStubMsg, pMemory, size);
1681 if (pFormat[0] != RPC_FC_STRUCT)
1682 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1684 return NULL;
1687 /***********************************************************************
1688 * NdrSimpleStructUnmarshall [RPCRT4.@]
1690 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1691 unsigned char **ppMemory,
1692 PFORMAT_STRING pFormat,
1693 unsigned char fMustAlloc)
1695 unsigned size = *(const WORD*)(pFormat+2);
1696 unsigned char *saved_buffer;
1697 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1699 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1701 if (fMustAlloc)
1702 *ppMemory = NdrAllocate(pStubMsg, size);
1703 else
1705 if (!pStubMsg->IsClient && !*ppMemory)
1706 /* for servers, we just point straight into the RPC buffer */
1707 *ppMemory = pStubMsg->Buffer;
1710 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1711 safe_buffer_increment(pStubMsg, size);
1712 if (pFormat[0] == RPC_FC_PSTRUCT)
1713 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1715 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1716 if (*ppMemory != saved_buffer)
1717 memcpy(*ppMemory, saved_buffer, size);
1719 return NULL;
1722 /***********************************************************************
1723 * NdrSimpleStructBufferSize [RPCRT4.@]
1725 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1726 unsigned char *pMemory,
1727 PFORMAT_STRING pFormat)
1729 unsigned size = *(const WORD*)(pFormat+2);
1730 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1732 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1734 safe_buffer_length_increment(pStubMsg, size);
1735 if (pFormat[0] != RPC_FC_STRUCT)
1736 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1739 /***********************************************************************
1740 * NdrSimpleStructMemorySize [RPCRT4.@]
1742 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1743 PFORMAT_STRING pFormat)
1745 unsigned short size = *(const WORD *)(pFormat+2);
1747 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1749 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1750 pStubMsg->MemorySize += size;
1751 safe_buffer_increment(pStubMsg, size);
1753 if (pFormat[0] != RPC_FC_STRUCT)
1754 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1755 return size;
1758 /***********************************************************************
1759 * NdrSimpleStructFree [RPCRT4.@]
1761 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1762 unsigned char *pMemory,
1763 PFORMAT_STRING pFormat)
1765 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1766 if (pFormat[0] != RPC_FC_STRUCT)
1767 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1771 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE *pStubMsg,
1772 PFORMAT_STRING pFormat)
1774 switch (*pFormat) {
1775 case RPC_FC_STRUCT:
1776 case RPC_FC_PSTRUCT:
1777 case RPC_FC_CSTRUCT:
1778 case RPC_FC_BOGUS_STRUCT:
1779 case RPC_FC_SMFARRAY:
1780 case RPC_FC_SMVARRAY:
1781 return *(const WORD*)&pFormat[2];
1782 case RPC_FC_USER_MARSHAL:
1783 return *(const WORD*)&pFormat[4];
1784 case RPC_FC_NON_ENCAPSULATED_UNION:
1785 pFormat += 2;
1786 if (pStubMsg->fHasNewCorrDesc)
1787 pFormat += 6;
1788 else
1789 pFormat += 4;
1791 pFormat += *(const SHORT*)pFormat;
1792 return *(const SHORT*)pFormat;
1793 case RPC_FC_IP:
1794 return sizeof(void *);
1795 default:
1796 FIXME("unhandled embedded type %02x\n", *pFormat);
1798 return 0;
1802 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1803 PFORMAT_STRING pFormat)
1805 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1807 if (!m)
1809 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1810 return 0;
1813 return m(pStubMsg, pFormat);
1817 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1818 unsigned char *pMemory,
1819 PFORMAT_STRING pFormat,
1820 PFORMAT_STRING pPointer)
1822 PFORMAT_STRING desc;
1823 NDR_MARSHALL m;
1824 unsigned long size;
1826 while (*pFormat != RPC_FC_END) {
1827 switch (*pFormat) {
1828 case RPC_FC_BYTE:
1829 case RPC_FC_CHAR:
1830 case RPC_FC_SMALL:
1831 case RPC_FC_USMALL:
1832 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
1833 safe_copy_to_buffer(pStubMsg, pMemory, 1);
1834 pMemory += 1;
1835 break;
1836 case RPC_FC_WCHAR:
1837 case RPC_FC_SHORT:
1838 case RPC_FC_USHORT:
1839 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1840 safe_copy_to_buffer(pStubMsg, pMemory, 2);
1841 pMemory += 2;
1842 break;
1843 case RPC_FC_LONG:
1844 case RPC_FC_ULONG:
1845 case RPC_FC_ENUM32:
1846 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
1847 safe_copy_to_buffer(pStubMsg, pMemory, 4);
1848 pMemory += 4;
1849 break;
1850 case RPC_FC_HYPER:
1851 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1852 safe_copy_to_buffer(pStubMsg, pMemory, 8);
1853 pMemory += 8;
1854 break;
1855 case RPC_FC_POINTER:
1857 unsigned char *saved_buffer;
1858 int pointer_buffer_mark_set = 0;
1859 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1860 saved_buffer = pStubMsg->Buffer;
1861 if (pStubMsg->PointerBufferMark)
1863 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1864 pStubMsg->PointerBufferMark = NULL;
1865 pointer_buffer_mark_set = 1;
1867 else
1868 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
1869 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
1870 if (pointer_buffer_mark_set)
1872 STD_OVERFLOW_CHECK(pStubMsg);
1873 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1874 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
1876 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
1877 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
1878 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1880 pStubMsg->Buffer = saved_buffer + 4;
1882 pPointer += 4;
1883 pMemory += 4;
1884 break;
1886 case RPC_FC_ALIGNM4:
1887 ALIGN_POINTER(pMemory, 4);
1888 break;
1889 case RPC_FC_ALIGNM8:
1890 ALIGN_POINTER(pMemory, 8);
1891 break;
1892 case RPC_FC_STRUCTPAD1:
1893 case RPC_FC_STRUCTPAD2:
1894 case RPC_FC_STRUCTPAD3:
1895 case RPC_FC_STRUCTPAD4:
1896 case RPC_FC_STRUCTPAD5:
1897 case RPC_FC_STRUCTPAD6:
1898 case RPC_FC_STRUCTPAD7:
1899 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1900 break;
1901 case RPC_FC_EMBEDDED_COMPLEX:
1902 pMemory += pFormat[1];
1903 pFormat += 2;
1904 desc = pFormat + *(const SHORT*)pFormat;
1905 size = EmbeddedComplexSize(pStubMsg, desc);
1906 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1907 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1908 if (m)
1910 /* for some reason interface pointers aren't generated as
1911 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
1912 * they still need the derefencing treatment that pointers are
1913 * given */
1914 if (*desc == RPC_FC_IP)
1915 m(pStubMsg, *(unsigned char **)pMemory, desc);
1916 else
1917 m(pStubMsg, pMemory, desc);
1919 else FIXME("no marshaller for embedded type %02x\n", *desc);
1920 pMemory += size;
1921 pFormat += 2;
1922 continue;
1923 case RPC_FC_PAD:
1924 break;
1925 default:
1926 FIXME("unhandled format 0x%02x\n", *pFormat);
1928 pFormat++;
1931 return pMemory;
1934 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1935 unsigned char *pMemory,
1936 PFORMAT_STRING pFormat,
1937 PFORMAT_STRING pPointer)
1939 PFORMAT_STRING desc;
1940 NDR_UNMARSHALL m;
1941 unsigned long size;
1943 while (*pFormat != RPC_FC_END) {
1944 switch (*pFormat) {
1945 case RPC_FC_BYTE:
1946 case RPC_FC_CHAR:
1947 case RPC_FC_SMALL:
1948 case RPC_FC_USMALL:
1949 safe_copy_from_buffer(pStubMsg, pMemory, 1);
1950 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
1951 pMemory += 1;
1952 break;
1953 case RPC_FC_WCHAR:
1954 case RPC_FC_SHORT:
1955 case RPC_FC_USHORT:
1956 safe_copy_from_buffer(pStubMsg, pMemory, 2);
1957 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1958 pMemory += 2;
1959 break;
1960 case RPC_FC_LONG:
1961 case RPC_FC_ULONG:
1962 case RPC_FC_ENUM32:
1963 safe_copy_from_buffer(pStubMsg, pMemory, 4);
1964 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
1965 pMemory += 4;
1966 break;
1967 case RPC_FC_HYPER:
1968 safe_copy_from_buffer(pStubMsg, pMemory, 8);
1969 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1970 pMemory += 8;
1971 break;
1972 case RPC_FC_POINTER:
1974 unsigned char *saved_buffer;
1975 int pointer_buffer_mark_set = 0;
1976 TRACE("pointer => %p\n", pMemory);
1977 ALIGN_POINTER(pStubMsg->Buffer, 4);
1978 saved_buffer = pStubMsg->Buffer;
1979 if (pStubMsg->PointerBufferMark)
1981 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1982 pStubMsg->PointerBufferMark = NULL;
1983 pointer_buffer_mark_set = 1;
1985 else
1986 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
1988 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, TRUE);
1989 if (pointer_buffer_mark_set)
1991 STD_OVERFLOW_CHECK(pStubMsg);
1992 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1993 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
1995 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
1996 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
1997 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1999 pStubMsg->Buffer = saved_buffer + 4;
2001 pPointer += 4;
2002 pMemory += 4;
2003 break;
2005 case RPC_FC_ALIGNM4:
2006 ALIGN_POINTER(pMemory, 4);
2007 break;
2008 case RPC_FC_ALIGNM8:
2009 ALIGN_POINTER(pMemory, 8);
2010 break;
2011 case RPC_FC_STRUCTPAD1:
2012 case RPC_FC_STRUCTPAD2:
2013 case RPC_FC_STRUCTPAD3:
2014 case RPC_FC_STRUCTPAD4:
2015 case RPC_FC_STRUCTPAD5:
2016 case RPC_FC_STRUCTPAD6:
2017 case RPC_FC_STRUCTPAD7:
2018 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2019 break;
2020 case RPC_FC_EMBEDDED_COMPLEX:
2021 pMemory += pFormat[1];
2022 pFormat += 2;
2023 desc = pFormat + *(const SHORT*)pFormat;
2024 size = EmbeddedComplexSize(pStubMsg, desc);
2025 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2026 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2027 memset(pMemory, 0, size); /* just in case */
2028 if (m)
2030 /* for some reason interface pointers aren't generated as
2031 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2032 * they still need the derefencing treatment that pointers are
2033 * given */
2034 if (*desc == RPC_FC_IP)
2035 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2036 else
2037 m(pStubMsg, &pMemory, desc, FALSE);
2039 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2040 pMemory += size;
2041 pFormat += 2;
2042 continue;
2043 case RPC_FC_PAD:
2044 break;
2045 default:
2046 FIXME("unhandled format %d\n", *pFormat);
2048 pFormat++;
2051 return pMemory;
2054 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2055 unsigned char *pMemory,
2056 PFORMAT_STRING pFormat,
2057 PFORMAT_STRING pPointer)
2059 PFORMAT_STRING desc;
2060 NDR_BUFFERSIZE m;
2061 unsigned long size;
2063 while (*pFormat != RPC_FC_END) {
2064 switch (*pFormat) {
2065 case RPC_FC_BYTE:
2066 case RPC_FC_CHAR:
2067 case RPC_FC_SMALL:
2068 case RPC_FC_USMALL:
2069 safe_buffer_length_increment(pStubMsg, 1);
2070 pMemory += 1;
2071 break;
2072 case RPC_FC_WCHAR:
2073 case RPC_FC_SHORT:
2074 case RPC_FC_USHORT:
2075 safe_buffer_length_increment(pStubMsg, 2);
2076 pMemory += 2;
2077 break;
2078 case RPC_FC_LONG:
2079 case RPC_FC_ULONG:
2080 case RPC_FC_ENUM32:
2081 safe_buffer_length_increment(pStubMsg, 4);
2082 pMemory += 4;
2083 break;
2084 case RPC_FC_HYPER:
2085 safe_buffer_length_increment(pStubMsg, 8);
2086 pMemory += 8;
2087 break;
2088 case RPC_FC_POINTER:
2089 if (!pStubMsg->IgnoreEmbeddedPointers)
2091 int saved_buffer_length = pStubMsg->BufferLength;
2092 pStubMsg->BufferLength = pStubMsg->PointerLength;
2093 pStubMsg->PointerLength = 0;
2094 if(!pStubMsg->BufferLength)
2095 ERR("BufferLength == 0??\n");
2096 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2097 pStubMsg->PointerLength = pStubMsg->BufferLength;
2098 pStubMsg->BufferLength = saved_buffer_length;
2100 safe_buffer_length_increment(pStubMsg, 4);
2101 pPointer += 4;
2102 pMemory += 4;
2103 break;
2104 case RPC_FC_ALIGNM4:
2105 ALIGN_POINTER(pMemory, 4);
2106 break;
2107 case RPC_FC_ALIGNM8:
2108 ALIGN_POINTER(pMemory, 8);
2109 break;
2110 case RPC_FC_STRUCTPAD1:
2111 case RPC_FC_STRUCTPAD2:
2112 case RPC_FC_STRUCTPAD3:
2113 case RPC_FC_STRUCTPAD4:
2114 case RPC_FC_STRUCTPAD5:
2115 case RPC_FC_STRUCTPAD6:
2116 case RPC_FC_STRUCTPAD7:
2117 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2118 break;
2119 case RPC_FC_EMBEDDED_COMPLEX:
2120 pMemory += pFormat[1];
2121 pFormat += 2;
2122 desc = pFormat + *(const SHORT*)pFormat;
2123 size = EmbeddedComplexSize(pStubMsg, desc);
2124 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2125 if (m)
2127 /* for some reason interface pointers aren't generated as
2128 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2129 * they still need the derefencing treatment that pointers are
2130 * given */
2131 if (*desc == RPC_FC_IP)
2132 m(pStubMsg, *(unsigned char **)pMemory, desc);
2133 else
2134 m(pStubMsg, pMemory, desc);
2136 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2137 pMemory += size;
2138 pFormat += 2;
2139 continue;
2140 case RPC_FC_PAD:
2141 break;
2142 default:
2143 FIXME("unhandled format 0x%02x\n", *pFormat);
2145 pFormat++;
2148 return pMemory;
2151 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2152 unsigned char *pMemory,
2153 PFORMAT_STRING pFormat,
2154 PFORMAT_STRING pPointer)
2156 PFORMAT_STRING desc;
2157 NDR_FREE m;
2158 unsigned long size;
2160 while (*pFormat != RPC_FC_END) {
2161 switch (*pFormat) {
2162 case RPC_FC_BYTE:
2163 case RPC_FC_CHAR:
2164 case RPC_FC_SMALL:
2165 case RPC_FC_USMALL:
2166 pMemory += 1;
2167 break;
2168 case RPC_FC_WCHAR:
2169 case RPC_FC_SHORT:
2170 case RPC_FC_USHORT:
2171 pMemory += 2;
2172 break;
2173 case RPC_FC_LONG:
2174 case RPC_FC_ULONG:
2175 case RPC_FC_ENUM32:
2176 pMemory += 4;
2177 break;
2178 case RPC_FC_HYPER:
2179 pMemory += 8;
2180 break;
2181 case RPC_FC_POINTER:
2182 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
2183 pPointer += 4;
2184 pMemory += 4;
2185 break;
2186 case RPC_FC_ALIGNM4:
2187 ALIGN_POINTER(pMemory, 4);
2188 break;
2189 case RPC_FC_ALIGNM8:
2190 ALIGN_POINTER(pMemory, 8);
2191 break;
2192 case RPC_FC_STRUCTPAD1:
2193 case RPC_FC_STRUCTPAD2:
2194 case RPC_FC_STRUCTPAD3:
2195 case RPC_FC_STRUCTPAD4:
2196 case RPC_FC_STRUCTPAD5:
2197 case RPC_FC_STRUCTPAD6:
2198 case RPC_FC_STRUCTPAD7:
2199 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2200 break;
2201 case RPC_FC_EMBEDDED_COMPLEX:
2202 pMemory += pFormat[1];
2203 pFormat += 2;
2204 desc = pFormat + *(const SHORT*)pFormat;
2205 size = EmbeddedComplexSize(pStubMsg, desc);
2206 m = NdrFreer[*desc & NDR_TABLE_MASK];
2207 if (m)
2209 /* for some reason interface pointers aren't generated as
2210 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2211 * they still need the derefencing treatment that pointers are
2212 * given */
2213 if (*desc == RPC_FC_IP)
2214 m(pStubMsg, *(unsigned char **)pMemory, desc);
2215 else
2216 m(pStubMsg, pMemory, desc);
2218 else FIXME("no freer for embedded type %02x\n", *desc);
2219 pMemory += size;
2220 pFormat += 2;
2221 continue;
2222 case RPC_FC_PAD:
2223 break;
2224 default:
2225 FIXME("unhandled format 0x%02x\n", *pFormat);
2227 pFormat++;
2230 return pMemory;
2233 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2234 PFORMAT_STRING pFormat)
2236 PFORMAT_STRING desc;
2237 unsigned long size = 0;
2239 while (*pFormat != RPC_FC_END) {
2240 switch (*pFormat) {
2241 case RPC_FC_BYTE:
2242 case RPC_FC_CHAR:
2243 case RPC_FC_SMALL:
2244 case RPC_FC_USMALL:
2245 size += 1;
2246 safe_buffer_increment(pStubMsg, 1);
2247 break;
2248 case RPC_FC_WCHAR:
2249 case RPC_FC_SHORT:
2250 case RPC_FC_USHORT:
2251 size += 2;
2252 safe_buffer_increment(pStubMsg, 2);
2253 break;
2254 case RPC_FC_LONG:
2255 case RPC_FC_ULONG:
2256 case RPC_FC_ENUM32:
2257 size += 4;
2258 safe_buffer_increment(pStubMsg, 4);
2259 break;
2260 case RPC_FC_HYPER:
2261 size += 8;
2262 safe_buffer_increment(pStubMsg, 8);
2263 break;
2264 case RPC_FC_POINTER:
2265 size += 4;
2266 safe_buffer_increment(pStubMsg, 4);
2267 if (!pStubMsg->IgnoreEmbeddedPointers)
2268 FIXME("embedded pointers\n");
2269 break;
2270 case RPC_FC_ALIGNM4:
2271 ALIGN_LENGTH(size, 4);
2272 ALIGN_POINTER(pStubMsg->Buffer, 4);
2273 break;
2274 case RPC_FC_ALIGNM8:
2275 ALIGN_LENGTH(size, 8);
2276 ALIGN_POINTER(pStubMsg->Buffer, 8);
2277 break;
2278 case RPC_FC_STRUCTPAD1:
2279 case RPC_FC_STRUCTPAD2:
2280 case RPC_FC_STRUCTPAD3:
2281 case RPC_FC_STRUCTPAD4:
2282 case RPC_FC_STRUCTPAD5:
2283 case RPC_FC_STRUCTPAD6:
2284 case RPC_FC_STRUCTPAD7:
2285 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2286 break;
2287 case RPC_FC_EMBEDDED_COMPLEX:
2288 size += pFormat[1];
2289 pFormat += 2;
2290 desc = pFormat + *(const SHORT*)pFormat;
2291 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2292 pFormat += 2;
2293 continue;
2294 case RPC_FC_PAD:
2295 break;
2296 default:
2297 FIXME("unhandled format 0x%02x\n", *pFormat);
2299 pFormat++;
2302 return size;
2305 /***********************************************************************
2306 * NdrComplexStructMarshall [RPCRT4.@]
2308 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2309 unsigned char *pMemory,
2310 PFORMAT_STRING pFormat)
2312 PFORMAT_STRING conf_array = NULL;
2313 PFORMAT_STRING pointer_desc = NULL;
2314 unsigned char *OldMemory = pStubMsg->Memory;
2315 int pointer_buffer_mark_set = 0;
2317 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2319 if (!pStubMsg->PointerBufferMark)
2321 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2322 /* save buffer length */
2323 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2325 /* get the buffer pointer after complex array data, but before
2326 * pointer data */
2327 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2328 pStubMsg->IgnoreEmbeddedPointers = 1;
2329 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2330 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2332 /* save it for use by embedded pointer code later */
2333 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2334 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
2335 pointer_buffer_mark_set = 1;
2337 /* restore the original buffer length */
2338 pStubMsg->BufferLength = saved_buffer_length;
2341 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2343 pFormat += 4;
2344 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2345 pFormat += 2;
2346 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2347 pFormat += 2;
2349 pStubMsg->Memory = pMemory;
2351 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2353 if (conf_array)
2354 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2356 pStubMsg->Memory = OldMemory;
2358 if (pointer_buffer_mark_set)
2360 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2361 pStubMsg->PointerBufferMark = NULL;
2364 STD_OVERFLOW_CHECK(pStubMsg);
2366 return NULL;
2369 /***********************************************************************
2370 * NdrComplexStructUnmarshall [RPCRT4.@]
2372 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2373 unsigned char **ppMemory,
2374 PFORMAT_STRING pFormat,
2375 unsigned char fMustAlloc)
2377 unsigned size = *(const WORD*)(pFormat+2);
2378 PFORMAT_STRING conf_array = NULL;
2379 PFORMAT_STRING pointer_desc = NULL;
2380 unsigned char *pMemory;
2381 int pointer_buffer_mark_set = 0;
2383 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2385 if (!pStubMsg->PointerBufferMark)
2387 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2388 /* save buffer pointer */
2389 unsigned char *saved_buffer = pStubMsg->Buffer;
2391 /* get the buffer pointer after complex array data, but before
2392 * pointer data */
2393 pStubMsg->IgnoreEmbeddedPointers = 1;
2394 NdrComplexStructMemorySize(pStubMsg, pFormat);
2395 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2397 /* save it for use by embedded pointer code later */
2398 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2399 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
2400 pointer_buffer_mark_set = 1;
2402 /* restore the original buffer */
2403 pStubMsg->Buffer = saved_buffer;
2406 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2408 if (fMustAlloc || !*ppMemory)
2410 *ppMemory = NdrAllocate(pStubMsg, size);
2411 memset(*ppMemory, 0, size);
2414 pFormat += 4;
2415 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2416 pFormat += 2;
2417 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2418 pFormat += 2;
2420 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2422 if (conf_array)
2423 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2425 if (pointer_buffer_mark_set)
2427 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2428 pStubMsg->PointerBufferMark = NULL;
2431 return NULL;
2434 /***********************************************************************
2435 * NdrComplexStructBufferSize [RPCRT4.@]
2437 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2438 unsigned char *pMemory,
2439 PFORMAT_STRING pFormat)
2441 PFORMAT_STRING conf_array = NULL;
2442 PFORMAT_STRING pointer_desc = NULL;
2443 unsigned char *OldMemory = pStubMsg->Memory;
2444 int pointer_length_set = 0;
2446 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2448 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2450 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2452 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2453 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2455 /* get the buffer length after complex struct data, but before
2456 * pointer data */
2457 pStubMsg->IgnoreEmbeddedPointers = 1;
2458 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2459 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2461 /* save it for use by embedded pointer code later */
2462 pStubMsg->PointerLength = pStubMsg->BufferLength;
2463 pointer_length_set = 1;
2464 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
2466 /* restore the original buffer length */
2467 pStubMsg->BufferLength = saved_buffer_length;
2470 pFormat += 4;
2471 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2472 pFormat += 2;
2473 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2474 pFormat += 2;
2476 pStubMsg->Memory = pMemory;
2478 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2480 if (conf_array)
2481 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2483 pStubMsg->Memory = OldMemory;
2485 if(pointer_length_set)
2487 pStubMsg->BufferLength = pStubMsg->PointerLength;
2488 pStubMsg->PointerLength = 0;
2493 /***********************************************************************
2494 * NdrComplexStructMemorySize [RPCRT4.@]
2496 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2497 PFORMAT_STRING pFormat)
2499 unsigned size = *(const WORD*)(pFormat+2);
2500 PFORMAT_STRING conf_array = NULL;
2501 PFORMAT_STRING pointer_desc = NULL;
2503 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2505 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2507 pFormat += 4;
2508 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2509 pFormat += 2;
2510 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2511 pFormat += 2;
2513 ComplexStructMemorySize(pStubMsg, pFormat);
2515 if (conf_array)
2516 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2518 return size;
2521 /***********************************************************************
2522 * NdrComplexStructFree [RPCRT4.@]
2524 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2525 unsigned char *pMemory,
2526 PFORMAT_STRING pFormat)
2528 PFORMAT_STRING conf_array = NULL;
2529 PFORMAT_STRING pointer_desc = NULL;
2530 unsigned char *OldMemory = pStubMsg->Memory;
2532 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2534 pFormat += 4;
2535 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2536 pFormat += 2;
2537 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2538 pFormat += 2;
2540 pStubMsg->Memory = pMemory;
2542 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2544 if (conf_array)
2545 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2547 pStubMsg->Memory = OldMemory;
2550 /***********************************************************************
2551 * NdrConformantArrayMarshall [RPCRT4.@]
2553 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2554 unsigned char *pMemory,
2555 PFORMAT_STRING pFormat)
2557 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2558 unsigned char alignment = pFormat[1] + 1;
2560 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2561 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2563 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2565 WriteConformance(pStubMsg);
2567 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2569 size = safe_multiply(esize, pStubMsg->MaxCount);
2570 pStubMsg->BufferMark = pStubMsg->Buffer;
2571 safe_copy_to_buffer(pStubMsg, pMemory, size);
2573 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2575 return NULL;
2578 /***********************************************************************
2579 * NdrConformantArrayUnmarshall [RPCRT4.@]
2581 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2582 unsigned char **ppMemory,
2583 PFORMAT_STRING pFormat,
2584 unsigned char fMustAlloc)
2586 DWORD size, esize = *(const WORD*)(pFormat+2);
2587 unsigned char alignment = pFormat[1] + 1;
2588 unsigned char *saved_buffer;
2590 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2591 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2593 pFormat = ReadConformance(pStubMsg, pFormat+4);
2595 size = safe_multiply(esize, pStubMsg->MaxCount);
2596 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2598 if (fMustAlloc)
2599 *ppMemory = NdrAllocate(pStubMsg, size);
2600 else
2602 if (!pStubMsg->IsClient && !*ppMemory)
2603 /* for servers, we just point straight into the RPC buffer */
2604 *ppMemory = pStubMsg->Buffer;
2607 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
2608 safe_buffer_increment(pStubMsg, size);
2609 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2611 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2612 if (*ppMemory != saved_buffer)
2613 memcpy(*ppMemory, saved_buffer, size);
2615 return NULL;
2618 /***********************************************************************
2619 * NdrConformantArrayBufferSize [RPCRT4.@]
2621 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2622 unsigned char *pMemory,
2623 PFORMAT_STRING pFormat)
2625 DWORD size, esize = *(const WORD*)(pFormat+2);
2626 unsigned char alignment = pFormat[1] + 1;
2628 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2629 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2631 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2633 SizeConformance(pStubMsg);
2635 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2637 size = safe_multiply(esize, pStubMsg->MaxCount);
2638 /* conformance value plus array */
2639 safe_buffer_length_increment(pStubMsg, size);
2641 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2644 /***********************************************************************
2645 * NdrConformantArrayMemorySize [RPCRT4.@]
2647 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2648 PFORMAT_STRING pFormat)
2650 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2651 unsigned char alignment = pFormat[1] + 1;
2653 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2654 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2656 pFormat = ReadConformance(pStubMsg, pFormat+4);
2657 size = safe_multiply(esize, pStubMsg->MaxCount);
2658 pStubMsg->MemorySize += size;
2660 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2661 pStubMsg->BufferMark = pStubMsg->Buffer;
2662 safe_buffer_increment(pStubMsg, size);
2664 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2666 return pStubMsg->MemorySize;
2669 /***********************************************************************
2670 * NdrConformantArrayFree [RPCRT4.@]
2672 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2673 unsigned char *pMemory,
2674 PFORMAT_STRING pFormat)
2676 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2677 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2679 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2681 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2685 /***********************************************************************
2686 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2688 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2689 unsigned char* pMemory,
2690 PFORMAT_STRING pFormat )
2692 ULONG bufsize;
2693 unsigned char alignment = pFormat[1] + 1;
2694 DWORD esize = *(const WORD*)(pFormat+2);
2696 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2698 if (pFormat[0] != RPC_FC_CVARRAY)
2700 ERR("invalid format type %x\n", pFormat[0]);
2701 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2702 return NULL;
2705 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2706 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2708 WriteConformance(pStubMsg);
2709 WriteVariance(pStubMsg);
2711 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2713 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2715 pStubMsg->BufferMark = pStubMsg->Buffer;
2716 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
2718 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2720 return NULL;
2724 /***********************************************************************
2725 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2727 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2728 unsigned char** ppMemory,
2729 PFORMAT_STRING pFormat,
2730 unsigned char fMustAlloc )
2732 ULONG bufsize, memsize;
2733 unsigned char alignment = pFormat[1] + 1;
2734 DWORD esize = *(const WORD*)(pFormat+2);
2736 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2738 if (pFormat[0] != RPC_FC_CVARRAY)
2740 ERR("invalid format type %x\n", pFormat[0]);
2741 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2742 return NULL;
2745 pFormat = ReadConformance(pStubMsg, pFormat+4);
2746 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2748 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2750 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2751 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2753 if (!*ppMemory || fMustAlloc)
2754 *ppMemory = NdrAllocate(pStubMsg, memsize);
2755 safe_copy_from_buffer(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize);
2757 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
2759 return NULL;
2763 /***********************************************************************
2764 * NdrConformantVaryingArrayFree [RPCRT4.@]
2766 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2767 unsigned char* pMemory,
2768 PFORMAT_STRING pFormat )
2770 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2772 if (pFormat[0] != RPC_FC_CVARRAY)
2774 ERR("invalid format type %x\n", pFormat[0]);
2775 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2776 return;
2779 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2780 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2782 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2786 /***********************************************************************
2787 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2789 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2790 unsigned char* pMemory, PFORMAT_STRING pFormat )
2792 unsigned char alignment = pFormat[1] + 1;
2793 DWORD esize = *(const WORD*)(pFormat+2);
2795 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2797 if (pFormat[0] != RPC_FC_CVARRAY)
2799 ERR("invalid format type %x\n", pFormat[0]);
2800 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2801 return;
2804 /* compute size */
2805 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2806 /* compute length */
2807 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2809 SizeConformance(pStubMsg);
2810 SizeVariance(pStubMsg);
2812 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2814 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2816 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2820 /***********************************************************************
2821 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2823 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2824 PFORMAT_STRING pFormat )
2826 FIXME( "stub\n" );
2827 return 0;
2831 /***********************************************************************
2832 * NdrComplexArrayMarshall [RPCRT4.@]
2834 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2835 unsigned char *pMemory,
2836 PFORMAT_STRING pFormat)
2838 ULONG i, count, def;
2839 BOOL variance_present;
2840 unsigned char alignment;
2841 int pointer_buffer_mark_set = 0;
2843 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2845 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2847 ERR("invalid format type %x\n", pFormat[0]);
2848 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2849 return NULL;
2852 alignment = pFormat[1] + 1;
2854 if (!pStubMsg->PointerBufferMark)
2856 /* save buffer fields that may be changed by buffer sizer functions
2857 * and that may be needed later on */
2858 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2859 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2860 unsigned long saved_max_count = pStubMsg->MaxCount;
2861 unsigned long saved_offset = pStubMsg->Offset;
2862 unsigned long saved_actual_count = pStubMsg->ActualCount;
2864 /* get the buffer pointer after complex array data, but before
2865 * pointer data */
2866 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2867 pStubMsg->IgnoreEmbeddedPointers = 1;
2868 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
2869 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2871 /* save it for use by embedded pointer code later */
2872 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2873 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
2874 pointer_buffer_mark_set = 1;
2876 /* restore fields */
2877 pStubMsg->ActualCount = saved_actual_count;
2878 pStubMsg->Offset = saved_offset;
2879 pStubMsg->MaxCount = saved_max_count;
2880 pStubMsg->BufferLength = saved_buffer_length;
2883 def = *(const WORD*)&pFormat[2];
2884 pFormat += 4;
2886 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2887 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2889 variance_present = IsConformanceOrVariancePresent(pFormat);
2890 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2891 TRACE("variance = %d\n", pStubMsg->ActualCount);
2893 WriteConformance(pStubMsg);
2894 if (variance_present)
2895 WriteVariance(pStubMsg);
2897 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2899 count = pStubMsg->ActualCount;
2900 for (i = 0; i < count; i++)
2901 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2903 STD_OVERFLOW_CHECK(pStubMsg);
2905 if (pointer_buffer_mark_set)
2907 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2908 pStubMsg->PointerBufferMark = NULL;
2911 return NULL;
2914 /***********************************************************************
2915 * NdrComplexArrayUnmarshall [RPCRT4.@]
2917 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2918 unsigned char **ppMemory,
2919 PFORMAT_STRING pFormat,
2920 unsigned char fMustAlloc)
2922 ULONG i, count, size;
2923 unsigned char alignment;
2924 unsigned char *pMemory;
2925 unsigned char *saved_buffer;
2926 int pointer_buffer_mark_set = 0;
2927 int saved_ignore_embedded;
2929 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2931 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2933 ERR("invalid format type %x\n", pFormat[0]);
2934 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2935 return NULL;
2938 alignment = pFormat[1] + 1;
2940 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2941 /* save buffer pointer */
2942 saved_buffer = pStubMsg->Buffer;
2943 /* get the buffer pointer after complex array data, but before
2944 * pointer data */
2945 pStubMsg->IgnoreEmbeddedPointers = 1;
2946 pStubMsg->MemorySize = 0;
2947 NdrComplexArrayMemorySize(pStubMsg, pFormat);
2948 size = pStubMsg->MemorySize;
2949 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2951 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
2952 if (!pStubMsg->PointerBufferMark)
2954 /* save it for use by embedded pointer code later */
2955 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2956 pointer_buffer_mark_set = 1;
2958 /* restore the original buffer */
2959 pStubMsg->Buffer = saved_buffer;
2961 pFormat += 4;
2963 pFormat = ReadConformance(pStubMsg, pFormat);
2964 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2966 if (fMustAlloc || !*ppMemory)
2968 *ppMemory = NdrAllocate(pStubMsg, size);
2969 memset(*ppMemory, 0, size);
2972 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2974 pMemory = *ppMemory;
2975 count = pStubMsg->ActualCount;
2976 for (i = 0; i < count; i++)
2977 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
2979 if (pointer_buffer_mark_set)
2981 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2982 pStubMsg->PointerBufferMark = NULL;
2985 return NULL;
2988 /***********************************************************************
2989 * NdrComplexArrayBufferSize [RPCRT4.@]
2991 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2992 unsigned char *pMemory,
2993 PFORMAT_STRING pFormat)
2995 ULONG i, count, def;
2996 unsigned char alignment;
2997 BOOL variance_present;
2998 int pointer_length_set = 0;
3000 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3002 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3004 ERR("invalid format type %x\n", pFormat[0]);
3005 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3006 return;
3009 alignment = pFormat[1] + 1;
3011 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3013 /* save buffer fields that may be changed by buffer sizer functions
3014 * and that may be needed later on */
3015 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3016 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3017 unsigned long saved_max_count = pStubMsg->MaxCount;
3018 unsigned long saved_offset = pStubMsg->Offset;
3019 unsigned long saved_actual_count = pStubMsg->ActualCount;
3021 /* get the buffer pointer after complex array data, but before
3022 * pointer data */
3023 pStubMsg->IgnoreEmbeddedPointers = 1;
3024 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3025 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3027 /* save it for use by embedded pointer code later */
3028 pStubMsg->PointerLength = pStubMsg->BufferLength;
3029 pointer_length_set = 1;
3031 /* restore fields */
3032 pStubMsg->ActualCount = saved_actual_count;
3033 pStubMsg->Offset = saved_offset;
3034 pStubMsg->MaxCount = saved_max_count;
3035 pStubMsg->BufferLength = saved_buffer_length;
3037 def = *(const WORD*)&pFormat[2];
3038 pFormat += 4;
3040 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3041 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3042 SizeConformance(pStubMsg);
3044 variance_present = IsConformanceOrVariancePresent(pFormat);
3045 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3046 TRACE("variance = %d\n", pStubMsg->ActualCount);
3048 if (variance_present)
3049 SizeVariance(pStubMsg);
3051 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3053 count = pStubMsg->ActualCount;
3054 for (i = 0; i < count; i++)
3055 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
3057 if(pointer_length_set)
3059 pStubMsg->BufferLength = pStubMsg->PointerLength;
3060 pStubMsg->PointerLength = 0;
3064 /***********************************************************************
3065 * NdrComplexArrayMemorySize [RPCRT4.@]
3067 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3068 PFORMAT_STRING pFormat)
3070 ULONG i, count, esize, SavedMemorySize, MemorySize;
3071 unsigned char alignment;
3072 unsigned char *Buffer;
3074 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3076 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3078 ERR("invalid format type %x\n", pFormat[0]);
3079 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3080 return 0;
3083 alignment = pFormat[1] + 1;
3085 pFormat += 4;
3087 pFormat = ReadConformance(pStubMsg, pFormat);
3088 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3090 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3092 SavedMemorySize = pStubMsg->MemorySize;
3094 Buffer = pStubMsg->Buffer;
3095 pStubMsg->MemorySize = 0;
3096 esize = ComplexStructMemorySize(pStubMsg, pFormat);
3097 pStubMsg->Buffer = Buffer;
3099 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
3101 count = pStubMsg->ActualCount;
3102 for (i = 0; i < count; i++)
3103 ComplexStructMemorySize(pStubMsg, pFormat);
3105 pStubMsg->MemorySize = SavedMemorySize;
3107 pStubMsg->MemorySize += MemorySize;
3108 return MemorySize;
3111 /***********************************************************************
3112 * NdrComplexArrayFree [RPCRT4.@]
3114 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3115 unsigned char *pMemory,
3116 PFORMAT_STRING pFormat)
3118 ULONG i, count, def;
3120 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3122 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3124 ERR("invalid format type %x\n", pFormat[0]);
3125 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3126 return;
3129 def = *(const WORD*)&pFormat[2];
3130 pFormat += 4;
3132 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3133 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3135 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3136 TRACE("variance = %d\n", pStubMsg->ActualCount);
3138 count = pStubMsg->ActualCount;
3139 for (i = 0; i < count; i++)
3140 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
3143 static ULONG UserMarshalFlags(const MIDL_STUB_MESSAGE *pStubMsg)
3145 return MAKELONG(pStubMsg->dwDestContext,
3146 pStubMsg->RpcMsg->DataRepresentation);
3149 #define USER_MARSHAL_PTR_PREFIX \
3150 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3151 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3153 /***********************************************************************
3154 * NdrUserMarshalMarshall [RPCRT4.@]
3156 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3157 unsigned char *pMemory,
3158 PFORMAT_STRING pFormat)
3160 unsigned flags = pFormat[1];
3161 unsigned index = *(const WORD*)&pFormat[2];
3162 unsigned char *saved_buffer = NULL;
3163 ULONG uflag = UserMarshalFlags(pStubMsg);
3164 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3165 TRACE("index=%d\n", index);
3167 if (flags & USER_MARSHAL_POINTER)
3169 ALIGN_POINTER(pStubMsg->Buffer, 4);
3170 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
3171 pStubMsg->Buffer += 4;
3172 if (pStubMsg->PointerBufferMark)
3174 saved_buffer = pStubMsg->Buffer;
3175 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3176 pStubMsg->PointerBufferMark = NULL;
3178 ALIGN_POINTER(pStubMsg->Buffer, 8);
3180 else
3181 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3183 pStubMsg->Buffer =
3184 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
3185 &uflag, pStubMsg->Buffer, pMemory);
3187 if (saved_buffer)
3189 STD_OVERFLOW_CHECK(pStubMsg);
3190 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3191 pStubMsg->Buffer = saved_buffer;
3194 STD_OVERFLOW_CHECK(pStubMsg);
3196 return NULL;
3199 /***********************************************************************
3200 * NdrUserMarshalUnmarshall [RPCRT4.@]
3202 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3203 unsigned char **ppMemory,
3204 PFORMAT_STRING pFormat,
3205 unsigned char fMustAlloc)
3207 unsigned flags = pFormat[1];
3208 unsigned index = *(const WORD*)&pFormat[2];
3209 DWORD memsize = *(const WORD*)&pFormat[4];
3210 unsigned char *saved_buffer = NULL;
3211 ULONG uflag = UserMarshalFlags(pStubMsg);
3212 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3213 TRACE("index=%d\n", index);
3215 if (flags & USER_MARSHAL_POINTER)
3217 ALIGN_POINTER(pStubMsg->Buffer, 4);
3218 /* skip pointer prefix */
3219 pStubMsg->Buffer += 4;
3220 if (pStubMsg->PointerBufferMark)
3222 saved_buffer = pStubMsg->Buffer;
3223 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3224 pStubMsg->PointerBufferMark = NULL;
3226 ALIGN_POINTER(pStubMsg->Buffer, 8);
3228 else
3229 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3231 if (fMustAlloc || !*ppMemory)
3232 *ppMemory = NdrAllocate(pStubMsg, memsize);
3234 pStubMsg->Buffer =
3235 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
3236 &uflag, pStubMsg->Buffer, *ppMemory);
3238 if (saved_buffer)
3240 STD_OVERFLOW_CHECK(pStubMsg);
3241 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3242 pStubMsg->Buffer = saved_buffer;
3245 return NULL;
3248 /***********************************************************************
3249 * NdrUserMarshalBufferSize [RPCRT4.@]
3251 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3252 unsigned char *pMemory,
3253 PFORMAT_STRING pFormat)
3255 unsigned flags = pFormat[1];
3256 unsigned index = *(const WORD*)&pFormat[2];
3257 DWORD bufsize = *(const WORD*)&pFormat[6];
3258 ULONG uflag = UserMarshalFlags(pStubMsg);
3259 unsigned long saved_buffer_length = 0;
3260 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3261 TRACE("index=%d\n", index);
3263 if (flags & USER_MARSHAL_POINTER)
3265 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3266 /* skip pointer prefix */
3267 safe_buffer_length_increment(pStubMsg, 4);
3268 if (pStubMsg->IgnoreEmbeddedPointers)
3269 return;
3270 if (pStubMsg->PointerLength)
3272 saved_buffer_length = pStubMsg->BufferLength;
3273 pStubMsg->BufferLength = pStubMsg->PointerLength;
3274 pStubMsg->PointerLength = 0;
3276 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
3278 else
3279 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
3281 if (bufsize) {
3282 TRACE("size=%d\n", bufsize);
3283 safe_buffer_length_increment(pStubMsg, bufsize);
3285 else
3286 pStubMsg->BufferLength =
3287 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
3288 &uflag, pStubMsg->BufferLength, pMemory);
3290 if (saved_buffer_length)
3292 pStubMsg->PointerLength = pStubMsg->BufferLength;
3293 pStubMsg->BufferLength = saved_buffer_length;
3298 /***********************************************************************
3299 * NdrUserMarshalMemorySize [RPCRT4.@]
3301 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3302 PFORMAT_STRING pFormat)
3304 unsigned flags = pFormat[1];
3305 unsigned index = *(const WORD*)&pFormat[2];
3306 DWORD memsize = *(const WORD*)&pFormat[4];
3307 DWORD bufsize = *(const WORD*)&pFormat[6];
3309 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3310 TRACE("index=%d\n", index);
3312 pStubMsg->MemorySize += memsize;
3314 if (flags & USER_MARSHAL_POINTER)
3316 ALIGN_POINTER(pStubMsg->Buffer, 4);
3317 /* skip pointer prefix */
3318 pStubMsg->Buffer += 4;
3319 if (pStubMsg->IgnoreEmbeddedPointers)
3320 return pStubMsg->MemorySize;
3321 ALIGN_POINTER(pStubMsg->Buffer, 8);
3323 else
3324 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3326 if (!bufsize)
3327 FIXME("not implemented for varying buffer size\n");
3329 pStubMsg->Buffer += bufsize;
3331 return pStubMsg->MemorySize;
3334 /***********************************************************************
3335 * NdrUserMarshalFree [RPCRT4.@]
3337 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
3338 unsigned char *pMemory,
3339 PFORMAT_STRING pFormat)
3341 /* unsigned flags = pFormat[1]; */
3342 unsigned index = *(const WORD*)&pFormat[2];
3343 ULONG uflag = UserMarshalFlags(pStubMsg);
3344 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3345 TRACE("index=%d\n", index);
3347 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
3348 &uflag, pMemory);
3351 /***********************************************************************
3352 * NdrClearOutParameters [RPCRT4.@]
3354 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
3355 PFORMAT_STRING pFormat,
3356 void *ArgAddr)
3358 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
3361 /***********************************************************************
3362 * NdrConvert [RPCRT4.@]
3364 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
3366 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
3367 /* FIXME: since this stub doesn't do any converting, the proper behavior
3368 is to raise an exception */
3371 /***********************************************************************
3372 * NdrConvert2 [RPCRT4.@]
3374 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
3376 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3377 pStubMsg, pFormat, NumberParams);
3378 /* FIXME: since this stub doesn't do any converting, the proper behavior
3379 is to raise an exception */
3382 #include "pshpack1.h"
3383 typedef struct _NDR_CSTRUCT_FORMAT
3385 unsigned char type;
3386 unsigned char alignment;
3387 unsigned short memory_size;
3388 short offset_to_array_description;
3389 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
3390 #include "poppack.h"
3392 /***********************************************************************
3393 * NdrConformantStructMarshall [RPCRT4.@]
3395 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3396 unsigned char *pMemory,
3397 PFORMAT_STRING pFormat)
3399 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3400 PFORMAT_STRING pCArrayFormat;
3401 ULONG esize, bufsize;
3403 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3405 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3406 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3408 ERR("invalid format type %x\n", pCStructFormat->type);
3409 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3410 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 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3424 pCArrayFormat + 4, 0);
3426 WriteConformance(pStubMsg);
3428 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3430 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3432 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3433 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3435 ERR("integer overflow of memory_size %u with bufsize %u\n",
3436 pCStructFormat->memory_size, bufsize);
3437 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3439 /* copy constant sized part of struct */
3440 pStubMsg->BufferMark = pStubMsg->Buffer;
3441 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
3443 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3444 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3446 return NULL;
3449 /***********************************************************************
3450 * NdrConformantStructUnmarshall [RPCRT4.@]
3452 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3453 unsigned char **ppMemory,
3454 PFORMAT_STRING pFormat,
3455 unsigned char fMustAlloc)
3457 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3458 PFORMAT_STRING pCArrayFormat;
3459 ULONG esize, bufsize;
3461 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3463 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3464 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3466 ERR("invalid format type %x\n", pCStructFormat->type);
3467 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3468 return NULL;
3470 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3471 pCStructFormat->offset_to_array_description;
3472 if (*pCArrayFormat != RPC_FC_CARRAY)
3474 ERR("invalid array format type %x\n", pCStructFormat->type);
3475 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3476 return NULL;
3478 esize = *(const WORD*)(pCArrayFormat+2);
3480 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3482 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3484 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3486 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3487 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3489 ERR("integer overflow of memory_size %u with bufsize %u\n",
3490 pCStructFormat->memory_size, bufsize);
3491 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3493 /* work out how much memory to allocate if we need to do so */
3494 if (!*ppMemory || fMustAlloc)
3496 SIZE_T size = pCStructFormat->memory_size + bufsize;
3497 *ppMemory = NdrAllocate(pStubMsg, size);
3500 /* now copy the data */
3501 pStubMsg->BufferMark = pStubMsg->Buffer;
3502 safe_copy_from_buffer(pStubMsg, *ppMemory, pCStructFormat->memory_size + bufsize);
3504 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3505 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
3507 return NULL;
3510 /***********************************************************************
3511 * NdrConformantStructBufferSize [RPCRT4.@]
3513 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3514 unsigned char *pMemory,
3515 PFORMAT_STRING pFormat)
3517 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3518 PFORMAT_STRING pCArrayFormat;
3519 ULONG esize;
3521 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3523 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3524 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3526 ERR("invalid format type %x\n", pCStructFormat->type);
3527 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3528 return;
3530 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3531 pCStructFormat->offset_to_array_description;
3532 if (*pCArrayFormat != RPC_FC_CARRAY)
3534 ERR("invalid array format type %x\n", pCStructFormat->type);
3535 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3536 return;
3538 esize = *(const WORD*)(pCArrayFormat+2);
3540 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
3541 SizeConformance(pStubMsg);
3543 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
3545 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3547 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
3548 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
3550 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3551 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3554 /***********************************************************************
3555 * NdrConformantStructMemorySize [RPCRT4.@]
3557 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3558 PFORMAT_STRING pFormat)
3560 FIXME("stub\n");
3561 return 0;
3564 /***********************************************************************
3565 * NdrConformantStructFree [RPCRT4.@]
3567 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3568 unsigned char *pMemory,
3569 PFORMAT_STRING pFormat)
3571 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3572 PFORMAT_STRING pCArrayFormat;
3573 ULONG esize;
3575 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3577 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3578 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3580 ERR("invalid format type %x\n", pCStructFormat->type);
3581 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3582 return;
3585 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3586 pCStructFormat->offset_to_array_description;
3587 if (*pCArrayFormat != RPC_FC_CARRAY)
3589 ERR("invalid array format type %x\n", pCStructFormat->type);
3590 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3591 return;
3593 esize = *(const WORD*)(pCArrayFormat+2);
3595 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3596 pCArrayFormat + 4, 0);
3598 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3600 /* copy constant sized part of struct */
3601 pStubMsg->BufferMark = pStubMsg->Buffer;
3603 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3604 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3607 /***********************************************************************
3608 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3610 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3611 unsigned char *pMemory,
3612 PFORMAT_STRING pFormat)
3614 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3615 PFORMAT_STRING pCVArrayFormat;
3616 ULONG esize, bufsize;
3618 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3620 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3621 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3623 ERR("invalid format type %x\n", pCVStructFormat->type);
3624 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3625 return NULL;
3628 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3629 pCVStructFormat->offset_to_array_description;
3630 switch (*pCVArrayFormat)
3632 case RPC_FC_CVARRAY:
3633 esize = *(const WORD*)(pCVArrayFormat+2);
3635 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3636 pCVArrayFormat + 4, 0);
3637 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3638 pCVArrayFormat, 0);
3639 break;
3640 case RPC_FC_C_CSTRING:
3641 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3642 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3643 esize = sizeof(char);
3644 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3645 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3646 pCVArrayFormat + 2, 0);
3647 else
3648 pStubMsg->MaxCount = pStubMsg->ActualCount;
3649 break;
3650 case RPC_FC_C_WSTRING:
3651 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3652 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3653 esize = sizeof(WCHAR);
3654 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3655 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3656 pCVArrayFormat + 2, 0);
3657 else
3658 pStubMsg->MaxCount = pStubMsg->ActualCount;
3659 break;
3660 default:
3661 ERR("invalid array format type %x\n", *pCVArrayFormat);
3662 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3663 return NULL;
3666 WriteConformance(pStubMsg);
3668 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3670 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3672 /* write constant sized part */
3673 pStubMsg->BufferMark = pStubMsg->Buffer;
3674 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
3676 WriteVariance(pStubMsg);
3678 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3680 /* write array part */
3681 safe_copy_to_buffer(pStubMsg, pMemory + pCVStructFormat->memory_size, bufsize);
3683 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3685 return NULL;
3688 /***********************************************************************
3689 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3691 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3692 unsigned char **ppMemory,
3693 PFORMAT_STRING pFormat,
3694 unsigned char fMustAlloc)
3696 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3697 PFORMAT_STRING pCVArrayFormat;
3698 ULONG esize, bufsize;
3699 unsigned char cvarray_type;
3701 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3703 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3704 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3706 ERR("invalid format type %x\n", pCVStructFormat->type);
3707 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3708 return NULL;
3711 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3712 pCVStructFormat->offset_to_array_description;
3713 cvarray_type = *pCVArrayFormat;
3714 switch (cvarray_type)
3716 case RPC_FC_CVARRAY:
3717 esize = *(const WORD*)(pCVArrayFormat+2);
3718 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3719 break;
3720 case RPC_FC_C_CSTRING:
3721 esize = sizeof(char);
3722 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3723 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3724 else
3725 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3726 break;
3727 case RPC_FC_C_WSTRING:
3728 esize = sizeof(WCHAR);
3729 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3730 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3731 else
3732 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3733 break;
3734 default:
3735 ERR("invalid array format type %x\n", *pCVArrayFormat);
3736 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3737 return NULL;
3740 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3742 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3744 /* work out how much memory to allocate if we need to do so */
3745 if (!*ppMemory || fMustAlloc)
3747 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3748 *ppMemory = NdrAllocate(pStubMsg, size);
3751 /* copy the constant data */
3752 pStubMsg->BufferMark = pStubMsg->Buffer;
3753 safe_copy_from_buffer(pStubMsg, *ppMemory, pCVStructFormat->memory_size);
3755 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3757 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3759 if ((cvarray_type == RPC_FC_C_CSTRING) ||
3760 (cvarray_type == RPC_FC_C_WSTRING))
3762 ULONG i;
3763 /* strings must always have null terminating bytes */
3764 if (bufsize < esize)
3766 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
3767 RpcRaiseException(RPC_S_INVALID_BOUND);
3768 return NULL;
3770 for (i = bufsize - esize; i < bufsize; i++)
3771 if (pStubMsg->Buffer[i] != 0)
3773 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3774 i, pStubMsg->Buffer[i]);
3775 RpcRaiseException(RPC_S_INVALID_BOUND);
3776 return NULL;
3780 /* copy the array data */
3781 safe_copy_from_buffer(pStubMsg, *ppMemory + pCVStructFormat->memory_size, bufsize);
3783 if (cvarray_type == RPC_FC_C_CSTRING)
3784 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3785 else if (cvarray_type == RPC_FC_C_WSTRING)
3786 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3788 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
3790 return NULL;
3793 /***********************************************************************
3794 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3796 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3797 unsigned char *pMemory,
3798 PFORMAT_STRING pFormat)
3800 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3801 PFORMAT_STRING pCVArrayFormat;
3802 ULONG esize;
3804 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3806 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3807 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3809 ERR("invalid format type %x\n", pCVStructFormat->type);
3810 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3811 return;
3814 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3815 pCVStructFormat->offset_to_array_description;
3816 switch (*pCVArrayFormat)
3818 case RPC_FC_CVARRAY:
3819 esize = *(const WORD*)(pCVArrayFormat+2);
3821 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3822 pCVArrayFormat + 4, 0);
3823 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3824 pCVArrayFormat, 0);
3825 break;
3826 case RPC_FC_C_CSTRING:
3827 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3828 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3829 esize = sizeof(char);
3830 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3831 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3832 pCVArrayFormat + 2, 0);
3833 else
3834 pStubMsg->MaxCount = pStubMsg->ActualCount;
3835 break;
3836 case RPC_FC_C_WSTRING:
3837 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3838 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3839 esize = sizeof(WCHAR);
3840 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3841 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3842 pCVArrayFormat + 2, 0);
3843 else
3844 pStubMsg->MaxCount = pStubMsg->ActualCount;
3845 break;
3846 default:
3847 ERR("invalid array format type %x\n", *pCVArrayFormat);
3848 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3849 return;
3852 SizeConformance(pStubMsg);
3854 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
3856 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3858 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
3859 SizeVariance(pStubMsg);
3860 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
3862 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3865 /***********************************************************************
3866 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3868 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3869 PFORMAT_STRING pFormat)
3871 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3872 PFORMAT_STRING pCVArrayFormat;
3873 ULONG esize;
3874 unsigned char cvarray_type;
3876 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3878 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3879 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3881 ERR("invalid format type %x\n", pCVStructFormat->type);
3882 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3883 return 0;
3886 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3887 pCVStructFormat->offset_to_array_description;
3888 cvarray_type = *pCVArrayFormat;
3889 switch (cvarray_type)
3891 case RPC_FC_CVARRAY:
3892 esize = *(const WORD*)(pCVArrayFormat+2);
3893 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3894 break;
3895 case RPC_FC_C_CSTRING:
3896 esize = sizeof(char);
3897 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3898 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3899 else
3900 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3901 break;
3902 case RPC_FC_C_WSTRING:
3903 esize = sizeof(WCHAR);
3904 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3905 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3906 else
3907 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3908 break;
3909 default:
3910 ERR("invalid array format type %x\n", *pCVArrayFormat);
3911 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3912 return 0;
3915 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3917 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3919 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
3920 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3921 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
3923 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3925 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3927 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3930 /***********************************************************************
3931 * NdrConformantVaryingStructFree [RPCRT4.@]
3933 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3934 unsigned char *pMemory,
3935 PFORMAT_STRING pFormat)
3937 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3938 PFORMAT_STRING pCVArrayFormat;
3939 ULONG esize;
3941 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3943 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3944 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3946 ERR("invalid format type %x\n", pCVStructFormat->type);
3947 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3948 return;
3951 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3952 pCVStructFormat->offset_to_array_description;
3953 switch (*pCVArrayFormat)
3955 case RPC_FC_CVARRAY:
3956 esize = *(const WORD*)(pCVArrayFormat+2);
3958 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3959 pCVArrayFormat + 4, 0);
3960 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3961 pCVArrayFormat, 0);
3962 break;
3963 case RPC_FC_C_CSTRING:
3964 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3965 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3966 esize = sizeof(char);
3967 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3968 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3969 pCVArrayFormat + 2, 0);
3970 else
3971 pStubMsg->MaxCount = pStubMsg->ActualCount;
3972 break;
3973 case RPC_FC_C_WSTRING:
3974 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3975 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3976 esize = sizeof(WCHAR);
3977 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3978 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3979 pCVArrayFormat + 2, 0);
3980 else
3981 pStubMsg->MaxCount = pStubMsg->ActualCount;
3982 break;
3983 default:
3984 ERR("invalid array format type %x\n", *pCVArrayFormat);
3985 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3986 return;
3989 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3991 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3994 #include "pshpack1.h"
3995 typedef struct
3997 unsigned char type;
3998 unsigned char alignment;
3999 unsigned short total_size;
4000 } NDR_SMFARRAY_FORMAT;
4002 typedef struct
4004 unsigned char type;
4005 unsigned char alignment;
4006 unsigned long total_size;
4007 } NDR_LGFARRAY_FORMAT;
4008 #include "poppack.h"
4010 /***********************************************************************
4011 * NdrFixedArrayMarshall [RPCRT4.@]
4013 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4014 unsigned char *pMemory,
4015 PFORMAT_STRING pFormat)
4017 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4018 unsigned long total_size;
4020 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4022 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4023 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4025 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4026 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4027 return NULL;
4030 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4032 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4034 total_size = pSmFArrayFormat->total_size;
4035 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4037 else
4039 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4040 total_size = pLgFArrayFormat->total_size;
4041 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4044 pStubMsg->BufferMark = pStubMsg->Buffer;
4045 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4047 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4049 return NULL;
4052 /***********************************************************************
4053 * NdrFixedArrayUnmarshall [RPCRT4.@]
4055 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4056 unsigned char **ppMemory,
4057 PFORMAT_STRING pFormat,
4058 unsigned char fMustAlloc)
4060 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4061 unsigned long total_size;
4062 unsigned char *saved_buffer;
4064 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4066 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4067 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4069 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4070 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4071 return NULL;
4074 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4076 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4078 total_size = pSmFArrayFormat->total_size;
4079 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4081 else
4083 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4084 total_size = pLgFArrayFormat->total_size;
4085 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4088 if (fMustAlloc)
4089 *ppMemory = NdrAllocate(pStubMsg, total_size);
4090 else
4092 if (!pStubMsg->IsClient && !*ppMemory)
4093 /* for servers, we just point straight into the RPC buffer */
4094 *ppMemory = pStubMsg->Buffer;
4097 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4098 safe_buffer_increment(pStubMsg, total_size);
4099 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4101 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4102 if (*ppMemory != saved_buffer)
4103 memcpy(*ppMemory, saved_buffer, total_size);
4105 return NULL;
4108 /***********************************************************************
4109 * NdrFixedArrayBufferSize [RPCRT4.@]
4111 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4112 unsigned char *pMemory,
4113 PFORMAT_STRING pFormat)
4115 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4116 unsigned long total_size;
4118 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4120 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4121 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4123 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4124 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4125 return;
4128 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4130 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4132 total_size = pSmFArrayFormat->total_size;
4133 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4135 else
4137 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4138 total_size = pLgFArrayFormat->total_size;
4139 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4141 safe_buffer_length_increment(pStubMsg, total_size);
4143 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4146 /***********************************************************************
4147 * NdrFixedArrayMemorySize [RPCRT4.@]
4149 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4150 PFORMAT_STRING pFormat)
4152 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4153 ULONG total_size;
4155 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4157 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4158 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4160 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4161 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4162 return 0;
4165 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4167 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4169 total_size = pSmFArrayFormat->total_size;
4170 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4172 else
4174 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4175 total_size = pLgFArrayFormat->total_size;
4176 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4178 pStubMsg->BufferMark = pStubMsg->Buffer;
4179 safe_buffer_increment(pStubMsg, total_size);
4180 pStubMsg->MemorySize += total_size;
4182 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4184 return total_size;
4187 /***********************************************************************
4188 * NdrFixedArrayFree [RPCRT4.@]
4190 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4191 unsigned char *pMemory,
4192 PFORMAT_STRING pFormat)
4194 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4196 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4198 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4199 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4201 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4202 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4203 return;
4206 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4207 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4208 else
4210 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4211 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4214 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4217 /***********************************************************************
4218 * NdrVaryingArrayMarshall [RPCRT4.@]
4220 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4221 unsigned char *pMemory,
4222 PFORMAT_STRING pFormat)
4224 unsigned char alignment;
4225 DWORD elements, esize;
4226 ULONG bufsize;
4228 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4230 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4231 (pFormat[0] != RPC_FC_LGVARRAY))
4233 ERR("invalid format type %x\n", pFormat[0]);
4234 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4235 return NULL;
4238 alignment = pFormat[1] + 1;
4240 if (pFormat[0] == RPC_FC_SMVARRAY)
4242 pFormat += 2;
4243 pFormat += sizeof(WORD);
4244 elements = *(const WORD*)pFormat;
4245 pFormat += sizeof(WORD);
4247 else
4249 pFormat += 2;
4250 pFormat += sizeof(DWORD);
4251 elements = *(const DWORD*)pFormat;
4252 pFormat += sizeof(DWORD);
4255 esize = *(const WORD*)pFormat;
4256 pFormat += sizeof(WORD);
4258 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4259 if ((pStubMsg->ActualCount > elements) ||
4260 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4262 RpcRaiseException(RPC_S_INVALID_BOUND);
4263 return NULL;
4266 WriteVariance(pStubMsg);
4268 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4270 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4271 pStubMsg->BufferMark = pStubMsg->Buffer;
4272 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
4274 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4276 return NULL;
4279 /***********************************************************************
4280 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4282 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4283 unsigned char **ppMemory,
4284 PFORMAT_STRING pFormat,
4285 unsigned char fMustAlloc)
4287 unsigned char alignment;
4288 DWORD size, elements, esize;
4289 ULONG bufsize;
4291 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4293 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4294 (pFormat[0] != RPC_FC_LGVARRAY))
4296 ERR("invalid format type %x\n", pFormat[0]);
4297 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4298 return NULL;
4301 alignment = pFormat[1] + 1;
4303 if (pFormat[0] == RPC_FC_SMVARRAY)
4305 pFormat += 2;
4306 size = *(const WORD*)pFormat;
4307 pFormat += sizeof(WORD);
4308 elements = *(const WORD*)pFormat;
4309 pFormat += sizeof(WORD);
4311 else
4313 pFormat += 2;
4314 size = *(const DWORD*)pFormat;
4315 pFormat += sizeof(DWORD);
4316 elements = *(const DWORD*)pFormat;
4317 pFormat += sizeof(DWORD);
4320 esize = *(const WORD*)pFormat;
4321 pFormat += sizeof(WORD);
4323 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4325 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4327 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4329 if (!*ppMemory || fMustAlloc)
4330 *ppMemory = NdrAllocate(pStubMsg, size);
4331 safe_copy_from_buffer(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize);
4333 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
4335 return NULL;
4338 /***********************************************************************
4339 * NdrVaryingArrayBufferSize [RPCRT4.@]
4341 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4342 unsigned char *pMemory,
4343 PFORMAT_STRING pFormat)
4345 unsigned char alignment;
4346 DWORD elements, esize;
4348 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4350 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4351 (pFormat[0] != RPC_FC_LGVARRAY))
4353 ERR("invalid format type %x\n", pFormat[0]);
4354 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4355 return;
4358 alignment = pFormat[1] + 1;
4360 if (pFormat[0] == RPC_FC_SMVARRAY)
4362 pFormat += 2;
4363 pFormat += sizeof(WORD);
4364 elements = *(const WORD*)pFormat;
4365 pFormat += sizeof(WORD);
4367 else
4369 pFormat += 2;
4370 pFormat += sizeof(DWORD);
4371 elements = *(const DWORD*)pFormat;
4372 pFormat += sizeof(DWORD);
4375 esize = *(const WORD*)pFormat;
4376 pFormat += sizeof(WORD);
4378 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4379 if ((pStubMsg->ActualCount > elements) ||
4380 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4382 RpcRaiseException(RPC_S_INVALID_BOUND);
4383 return;
4386 SizeVariance(pStubMsg);
4388 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4390 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4392 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4395 /***********************************************************************
4396 * NdrVaryingArrayMemorySize [RPCRT4.@]
4398 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4399 PFORMAT_STRING pFormat)
4401 unsigned char alignment;
4402 DWORD size, elements, esize;
4404 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4406 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4407 (pFormat[0] != RPC_FC_LGVARRAY))
4409 ERR("invalid format type %x\n", pFormat[0]);
4410 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4411 return 0;
4414 alignment = pFormat[1] + 1;
4416 if (pFormat[0] == RPC_FC_SMVARRAY)
4418 pFormat += 2;
4419 size = *(const WORD*)pFormat;
4420 pFormat += sizeof(WORD);
4421 elements = *(const WORD*)pFormat;
4422 pFormat += sizeof(WORD);
4424 else
4426 pFormat += 2;
4427 size = *(const DWORD*)pFormat;
4428 pFormat += sizeof(DWORD);
4429 elements = *(const DWORD*)pFormat;
4430 pFormat += sizeof(DWORD);
4433 esize = *(const WORD*)pFormat;
4434 pFormat += sizeof(WORD);
4436 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4438 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4440 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4441 pStubMsg->MemorySize += size;
4443 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4445 return pStubMsg->MemorySize;
4448 /***********************************************************************
4449 * NdrVaryingArrayFree [RPCRT4.@]
4451 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4452 unsigned char *pMemory,
4453 PFORMAT_STRING pFormat)
4455 unsigned char alignment;
4456 DWORD elements;
4458 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4460 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4461 (pFormat[0] != RPC_FC_LGVARRAY))
4463 ERR("invalid format type %x\n", pFormat[0]);
4464 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4465 return;
4468 alignment = pFormat[1] + 1;
4470 if (pFormat[0] == RPC_FC_SMVARRAY)
4472 pFormat += 2;
4473 pFormat += sizeof(WORD);
4474 elements = *(const WORD*)pFormat;
4475 pFormat += sizeof(WORD);
4477 else
4479 pFormat += 2;
4480 pFormat += sizeof(DWORD);
4481 elements = *(const DWORD*)pFormat;
4482 pFormat += sizeof(DWORD);
4485 pFormat += sizeof(WORD);
4487 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4488 if ((pStubMsg->ActualCount > elements) ||
4489 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4491 RpcRaiseException(RPC_S_INVALID_BOUND);
4492 return;
4495 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4498 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
4500 switch (fc)
4502 case RPC_FC_BYTE:
4503 case RPC_FC_CHAR:
4504 case RPC_FC_SMALL:
4505 case RPC_FC_USMALL:
4506 return *(const UCHAR *)pMemory;
4507 case RPC_FC_WCHAR:
4508 case RPC_FC_SHORT:
4509 case RPC_FC_USHORT:
4510 case RPC_FC_ENUM16:
4511 return *(const USHORT *)pMemory;
4512 case RPC_FC_LONG:
4513 case RPC_FC_ULONG:
4514 case RPC_FC_ENUM32:
4515 return *(const ULONG *)pMemory;
4516 default:
4517 FIXME("Unhandled base type: 0x%02x\n", fc);
4518 return 0;
4522 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4523 unsigned long discriminant,
4524 PFORMAT_STRING pFormat)
4526 unsigned short num_arms, arm, type;
4528 num_arms = *(const SHORT*)pFormat & 0x0fff;
4529 pFormat += 2;
4530 for(arm = 0; arm < num_arms; arm++)
4532 if(discriminant == *(const ULONG*)pFormat)
4534 pFormat += 4;
4535 break;
4537 pFormat += 6;
4540 type = *(const unsigned short*)pFormat;
4541 TRACE("type %04x\n", type);
4542 if(arm == num_arms) /* default arm extras */
4544 if(type == 0xffff)
4546 ERR("no arm for 0x%lx and no default case\n", discriminant);
4547 RpcRaiseException(RPC_S_INVALID_TAG);
4548 return NULL;
4550 if(type == 0)
4552 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
4553 return NULL;
4556 return pFormat;
4559 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
4561 unsigned short type;
4563 pFormat += 2;
4565 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4566 if(!pFormat)
4567 return NULL;
4569 type = *(const unsigned short*)pFormat;
4570 if((type & 0xff00) == 0x8000)
4572 unsigned char basetype = LOBYTE(type);
4573 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
4575 else
4577 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4578 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
4579 if (m)
4581 unsigned char *saved_buffer = NULL;
4582 int pointer_buffer_mark_set = 0;
4583 switch(*desc)
4585 case RPC_FC_RP:
4586 case RPC_FC_UP:
4587 case RPC_FC_OP:
4588 case RPC_FC_FP:
4589 ALIGN_POINTER(pStubMsg->Buffer, 4);
4590 saved_buffer = pStubMsg->Buffer;
4591 if (pStubMsg->PointerBufferMark)
4593 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4594 pStubMsg->PointerBufferMark = NULL;
4595 pointer_buffer_mark_set = 1;
4597 else
4598 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
4600 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
4601 if (pointer_buffer_mark_set)
4603 STD_OVERFLOW_CHECK(pStubMsg);
4604 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4605 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
4607 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4608 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
4609 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4611 pStubMsg->Buffer = saved_buffer + 4;
4613 break;
4614 default:
4615 m(pStubMsg, pMemory, desc);
4618 else FIXME("no marshaller for embedded type %02x\n", *desc);
4620 return NULL;
4623 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4624 unsigned char **ppMemory,
4625 ULONG discriminant,
4626 PFORMAT_STRING pFormat,
4627 unsigned char fMustAlloc)
4629 unsigned short type;
4631 pFormat += 2;
4633 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4634 if(!pFormat)
4635 return NULL;
4637 type = *(const unsigned short*)pFormat;
4638 if((type & 0xff00) == 0x8000)
4640 unsigned char basetype = LOBYTE(type);
4641 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
4643 else
4645 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4646 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
4647 if (m)
4649 unsigned char *saved_buffer = NULL;
4650 int pointer_buffer_mark_set = 0;
4651 switch(*desc)
4653 case RPC_FC_RP:
4654 case RPC_FC_UP:
4655 case RPC_FC_OP:
4656 case RPC_FC_FP:
4657 **(void***)ppMemory = NULL;
4658 ALIGN_POINTER(pStubMsg->Buffer, 4);
4659 saved_buffer = pStubMsg->Buffer;
4660 if (pStubMsg->PointerBufferMark)
4662 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4663 pStubMsg->PointerBufferMark = NULL;
4664 pointer_buffer_mark_set = 1;
4666 else
4667 pStubMsg->Buffer += 4; /* for pointer ID */
4669 if (saved_buffer + 4 > pStubMsg->BufferEnd)
4671 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4672 saved_buffer, pStubMsg->BufferEnd);
4673 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4676 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
4677 if (pointer_buffer_mark_set)
4679 STD_OVERFLOW_CHECK(pStubMsg);
4680 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4681 pStubMsg->Buffer = saved_buffer + 4;
4683 break;
4684 default:
4685 m(pStubMsg, ppMemory, desc, fMustAlloc);
4688 else FIXME("no marshaller for embedded type %02x\n", *desc);
4690 return NULL;
4693 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
4694 unsigned char *pMemory,
4695 ULONG discriminant,
4696 PFORMAT_STRING pFormat)
4698 unsigned short type;
4700 pFormat += 2;
4702 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4703 if(!pFormat)
4704 return;
4706 type = *(const unsigned short*)pFormat;
4707 if((type & 0xff00) == 0x8000)
4709 unsigned char basetype = LOBYTE(type);
4710 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
4712 else
4714 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4715 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
4716 if (m)
4718 switch(*desc)
4720 case RPC_FC_RP:
4721 case RPC_FC_UP:
4722 case RPC_FC_OP:
4723 case RPC_FC_FP:
4724 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4725 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
4726 if (!pStubMsg->IgnoreEmbeddedPointers)
4728 int saved_buffer_length = pStubMsg->BufferLength;
4729 pStubMsg->BufferLength = pStubMsg->PointerLength;
4730 pStubMsg->PointerLength = 0;
4731 if(!pStubMsg->BufferLength)
4732 ERR("BufferLength == 0??\n");
4733 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
4734 pStubMsg->PointerLength = pStubMsg->BufferLength;
4735 pStubMsg->BufferLength = saved_buffer_length;
4737 break;
4738 default:
4739 m(pStubMsg, pMemory, desc);
4742 else FIXME("no buffersizer for embedded type %02x\n", *desc);
4746 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
4747 ULONG discriminant,
4748 PFORMAT_STRING pFormat)
4750 unsigned short type, size;
4752 size = *(const unsigned short*)pFormat;
4753 pStubMsg->Memory += size;
4754 pFormat += 2;
4756 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4757 if(!pFormat)
4758 return 0;
4760 type = *(const unsigned short*)pFormat;
4761 if((type & 0xff00) == 0x8000)
4763 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
4765 else
4767 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4768 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
4769 unsigned char *saved_buffer;
4770 if (m)
4772 switch(*desc)
4774 case RPC_FC_RP:
4775 case RPC_FC_UP:
4776 case RPC_FC_OP:
4777 case RPC_FC_FP:
4778 ALIGN_POINTER(pStubMsg->Buffer, 4);
4779 saved_buffer = pStubMsg->Buffer;
4780 safe_buffer_increment(pStubMsg, 4);
4781 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
4782 pStubMsg->MemorySize += 4;
4783 if (!pStubMsg->IgnoreEmbeddedPointers)
4784 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
4785 break;
4786 default:
4787 return m(pStubMsg, desc);
4790 else FIXME("no marshaller for embedded type %02x\n", *desc);
4793 TRACE("size %d\n", size);
4794 return size;
4797 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
4798 unsigned char *pMemory,
4799 ULONG discriminant,
4800 PFORMAT_STRING pFormat)
4802 unsigned short type;
4804 pFormat += 2;
4806 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4807 if(!pFormat)
4808 return;
4810 type = *(const unsigned short*)pFormat;
4811 if((type & 0xff00) != 0x8000)
4813 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4814 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
4815 if (m)
4817 switch(*desc)
4819 case RPC_FC_RP:
4820 case RPC_FC_UP:
4821 case RPC_FC_OP:
4822 case RPC_FC_FP:
4823 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
4824 break;
4825 default:
4826 m(pStubMsg, pMemory, desc);
4829 else FIXME("no freer for embedded type %02x\n", *desc);
4833 /***********************************************************************
4834 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4836 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4837 unsigned char *pMemory,
4838 PFORMAT_STRING pFormat)
4840 unsigned char switch_type;
4841 unsigned char increment;
4842 ULONG switch_value;
4844 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4845 pFormat++;
4847 switch_type = *pFormat & 0xf;
4848 increment = (*pFormat & 0xf0) >> 4;
4849 pFormat++;
4851 ALIGN_POINTER(pStubMsg->Buffer, increment);
4853 switch_value = get_discriminant(switch_type, pMemory);
4854 TRACE("got switch value 0x%x\n", switch_value);
4856 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
4857 pMemory += increment;
4859 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
4862 /***********************************************************************
4863 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4865 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4866 unsigned char **ppMemory,
4867 PFORMAT_STRING pFormat,
4868 unsigned char fMustAlloc)
4870 unsigned char switch_type;
4871 unsigned char increment;
4872 ULONG switch_value;
4873 unsigned short size;
4874 unsigned char *pMemoryArm;
4876 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4877 pFormat++;
4879 switch_type = *pFormat & 0xf;
4880 increment = (*pFormat & 0xf0) >> 4;
4881 pFormat++;
4883 ALIGN_POINTER(pStubMsg->Buffer, increment);
4884 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
4885 TRACE("got switch value 0x%x\n", switch_value);
4887 size = *(const unsigned short*)pFormat + increment;
4888 if(!*ppMemory || fMustAlloc)
4889 *ppMemory = NdrAllocate(pStubMsg, size);
4891 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
4892 pMemoryArm = *ppMemory + increment;
4894 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
4897 /***********************************************************************
4898 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4900 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4901 unsigned char *pMemory,
4902 PFORMAT_STRING pFormat)
4904 unsigned char switch_type;
4905 unsigned char increment;
4906 ULONG switch_value;
4908 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4909 pFormat++;
4911 switch_type = *pFormat & 0xf;
4912 increment = (*pFormat & 0xf0) >> 4;
4913 pFormat++;
4915 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
4916 switch_value = get_discriminant(switch_type, pMemory);
4917 TRACE("got switch value 0x%x\n", switch_value);
4919 /* Add discriminant size */
4920 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
4921 pMemory += increment;
4923 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
4926 /***********************************************************************
4927 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4929 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4930 PFORMAT_STRING pFormat)
4932 unsigned char switch_type;
4933 unsigned char increment;
4934 ULONG switch_value;
4936 switch_type = *pFormat & 0xf;
4937 increment = (*pFormat & 0xf0) >> 4;
4938 pFormat++;
4940 ALIGN_POINTER(pStubMsg->Buffer, increment);
4941 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
4942 TRACE("got switch value 0x%x\n", switch_value);
4944 pStubMsg->Memory += increment;
4946 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
4949 /***********************************************************************
4950 * NdrEncapsulatedUnionFree [RPCRT4.@]
4952 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4953 unsigned char *pMemory,
4954 PFORMAT_STRING pFormat)
4956 unsigned char switch_type;
4957 unsigned char increment;
4958 ULONG switch_value;
4960 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4961 pFormat++;
4963 switch_type = *pFormat & 0xf;
4964 increment = (*pFormat & 0xf0) >> 4;
4965 pFormat++;
4967 switch_value = get_discriminant(switch_type, pMemory);
4968 TRACE("got switch value 0x%x\n", switch_value);
4970 pMemory += increment;
4972 return union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
4975 /***********************************************************************
4976 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
4978 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4979 unsigned char *pMemory,
4980 PFORMAT_STRING pFormat)
4982 unsigned char switch_type;
4984 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4985 pFormat++;
4987 switch_type = *pFormat;
4988 pFormat++;
4990 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4991 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4992 /* Marshall discriminant */
4993 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4995 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
4998 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
4999 PFORMAT_STRING *ppFormat)
5001 long discriminant = 0;
5003 switch(**ppFormat)
5005 case RPC_FC_BYTE:
5006 case RPC_FC_CHAR:
5007 case RPC_FC_SMALL:
5008 case RPC_FC_USMALL:
5010 UCHAR d;
5011 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5012 discriminant = d;
5013 break;
5015 case RPC_FC_WCHAR:
5016 case RPC_FC_SHORT:
5017 case RPC_FC_USHORT:
5019 USHORT d;
5020 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5021 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5022 discriminant = d;
5023 break;
5025 case RPC_FC_LONG:
5026 case RPC_FC_ULONG:
5028 ULONG d;
5029 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5030 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5031 discriminant = d;
5032 break;
5034 default:
5035 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5037 (*ppFormat)++;
5039 if (pStubMsg->fHasNewCorrDesc)
5040 *ppFormat += 6;
5041 else
5042 *ppFormat += 4;
5043 return discriminant;
5046 /**********************************************************************
5047 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5049 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5050 unsigned char **ppMemory,
5051 PFORMAT_STRING pFormat,
5052 unsigned char fMustAlloc)
5054 long discriminant;
5055 unsigned short size;
5057 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5058 pFormat++;
5060 /* Unmarshall discriminant */
5061 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5062 TRACE("unmarshalled discriminant %lx\n", discriminant);
5064 pFormat += *(const SHORT*)pFormat;
5066 size = *(const unsigned short*)pFormat;
5068 if(!*ppMemory || fMustAlloc)
5069 *ppMemory = NdrAllocate(pStubMsg, size);
5071 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5074 /***********************************************************************
5075 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5077 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5078 unsigned char *pMemory,
5079 PFORMAT_STRING pFormat)
5081 unsigned char switch_type;
5083 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5084 pFormat++;
5086 switch_type = *pFormat;
5087 pFormat++;
5089 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5090 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5091 /* Add discriminant size */
5092 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5094 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5097 /***********************************************************************
5098 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5100 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5101 PFORMAT_STRING pFormat)
5103 ULONG discriminant;
5105 pFormat++;
5106 /* Unmarshall discriminant */
5107 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5108 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
5110 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
5113 /***********************************************************************
5114 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5116 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5117 unsigned char *pMemory,
5118 PFORMAT_STRING pFormat)
5120 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5121 pFormat++;
5122 pFormat++;
5124 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5125 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5127 return union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5130 /***********************************************************************
5131 * NdrByteCountPointerMarshall [RPCRT4.@]
5133 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5134 unsigned char *pMemory,
5135 PFORMAT_STRING pFormat)
5137 FIXME("stub\n");
5138 return NULL;
5141 /***********************************************************************
5142 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5144 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5145 unsigned char **ppMemory,
5146 PFORMAT_STRING pFormat,
5147 unsigned char fMustAlloc)
5149 FIXME("stub\n");
5150 return NULL;
5153 /***********************************************************************
5154 * NdrByteCountPointerBufferSize [RPCRT4.@]
5156 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5157 unsigned char *pMemory,
5158 PFORMAT_STRING pFormat)
5160 FIXME("stub\n");
5163 /***********************************************************************
5164 * NdrByteCountPointerMemorySize [RPCRT4.@]
5166 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5167 PFORMAT_STRING pFormat)
5169 FIXME("stub\n");
5170 return 0;
5173 /***********************************************************************
5174 * NdrByteCountPointerFree [RPCRT4.@]
5176 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
5177 unsigned char *pMemory,
5178 PFORMAT_STRING pFormat)
5180 FIXME("stub\n");
5183 /***********************************************************************
5184 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5186 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5187 unsigned char *pMemory,
5188 PFORMAT_STRING pFormat)
5190 FIXME("stub\n");
5191 return NULL;
5194 /***********************************************************************
5195 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5197 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5198 unsigned char **ppMemory,
5199 PFORMAT_STRING pFormat,
5200 unsigned char fMustAlloc)
5202 FIXME("stub\n");
5203 return NULL;
5206 /***********************************************************************
5207 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5209 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5210 unsigned char *pMemory,
5211 PFORMAT_STRING pFormat)
5213 FIXME("stub\n");
5216 /***********************************************************************
5217 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5219 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5220 PFORMAT_STRING pFormat)
5222 FIXME("stub\n");
5223 return 0;
5226 /***********************************************************************
5227 * NdrXmitOrRepAsFree [RPCRT4.@]
5229 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
5230 unsigned char *pMemory,
5231 PFORMAT_STRING pFormat)
5233 FIXME("stub\n");
5236 #include "pshpack1.h"
5237 typedef struct
5239 unsigned char type;
5240 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
5241 ULONG low_value;
5242 ULONG high_value;
5243 } NDR_RANGE;
5244 #include "poppack.h"
5246 /***********************************************************************
5247 * NdrRangeMarshall [internal]
5249 unsigned char *WINAPI NdrRangeMarshall(
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);
5263 return NULL;
5266 base_type = pRange->flags_type & 0xf;
5268 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
5271 /***********************************************************************
5272 * NdrRangeUnmarshall
5274 unsigned char *WINAPI NdrRangeUnmarshall(
5275 PMIDL_STUB_MESSAGE pStubMsg,
5276 unsigned char **ppMemory,
5277 PFORMAT_STRING pFormat,
5278 unsigned char fMustAlloc)
5280 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5281 unsigned char base_type;
5283 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5285 if (pRange->type != RPC_FC_RANGE)
5287 ERR("invalid format type %x\n", pRange->type);
5288 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5289 return NULL;
5291 base_type = pRange->flags_type & 0xf;
5293 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5294 base_type, pRange->low_value, pRange->high_value);
5296 #define RANGE_UNMARSHALL(type, format_spec) \
5297 do \
5299 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5300 if (fMustAlloc || !*ppMemory) \
5301 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5302 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5304 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5305 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5306 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5308 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5309 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5311 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5312 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5313 (type)pRange->high_value); \
5314 RpcRaiseException(RPC_S_INVALID_BOUND); \
5315 return NULL; \
5317 TRACE("*ppMemory: %p\n", *ppMemory); \
5318 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5319 pStubMsg->Buffer += sizeof(type); \
5320 } while (0)
5322 switch(base_type)
5324 case RPC_FC_CHAR:
5325 case RPC_FC_SMALL:
5326 RANGE_UNMARSHALL(UCHAR, "%d");
5327 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5328 break;
5329 case RPC_FC_BYTE:
5330 case RPC_FC_USMALL:
5331 RANGE_UNMARSHALL(CHAR, "%u");
5332 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5333 break;
5334 case RPC_FC_WCHAR: /* FIXME: valid? */
5335 case RPC_FC_USHORT:
5336 RANGE_UNMARSHALL(USHORT, "%u");
5337 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5338 break;
5339 case RPC_FC_SHORT:
5340 RANGE_UNMARSHALL(SHORT, "%d");
5341 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5342 break;
5343 case RPC_FC_LONG:
5344 RANGE_UNMARSHALL(LONG, "%d");
5345 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5346 break;
5347 case RPC_FC_ULONG:
5348 RANGE_UNMARSHALL(ULONG, "%u");
5349 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5350 break;
5351 case RPC_FC_ENUM16:
5352 case RPC_FC_ENUM32:
5353 FIXME("Unhandled enum type\n");
5354 break;
5355 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
5356 case RPC_FC_FLOAT:
5357 case RPC_FC_DOUBLE:
5358 case RPC_FC_HYPER:
5359 default:
5360 ERR("invalid range base type: 0x%02x\n", base_type);
5361 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5364 return NULL;
5367 /***********************************************************************
5368 * NdrRangeBufferSize [internal]
5370 void WINAPI NdrRangeBufferSize(
5371 PMIDL_STUB_MESSAGE pStubMsg,
5372 unsigned char *pMemory,
5373 PFORMAT_STRING pFormat)
5375 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5376 unsigned char base_type;
5378 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5380 if (pRange->type != RPC_FC_RANGE)
5382 ERR("invalid format type %x\n", pRange->type);
5383 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5385 base_type = pRange->flags_type & 0xf;
5387 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
5390 /***********************************************************************
5391 * NdrRangeMemorySize [internal]
5393 ULONG WINAPI NdrRangeMemorySize(
5394 PMIDL_STUB_MESSAGE pStubMsg,
5395 PFORMAT_STRING pFormat)
5397 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5398 unsigned char base_type;
5400 if (pRange->type != RPC_FC_RANGE)
5402 ERR("invalid format type %x\n", pRange->type);
5403 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5404 return 0;
5406 base_type = pRange->flags_type & 0xf;
5408 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
5411 /***********************************************************************
5412 * NdrRangeFree [internal]
5414 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
5415 unsigned char *pMemory,
5416 PFORMAT_STRING pFormat)
5418 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5420 /* nothing to do */
5423 /***********************************************************************
5424 * NdrBaseTypeMarshall [internal]
5426 static unsigned char *WINAPI NdrBaseTypeMarshall(
5427 PMIDL_STUB_MESSAGE pStubMsg,
5428 unsigned char *pMemory,
5429 PFORMAT_STRING pFormat)
5431 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5433 switch(*pFormat)
5435 case RPC_FC_BYTE:
5436 case RPC_FC_CHAR:
5437 case RPC_FC_SMALL:
5438 case RPC_FC_USMALL:
5439 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
5440 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
5441 break;
5442 case RPC_FC_WCHAR:
5443 case RPC_FC_SHORT:
5444 case RPC_FC_USHORT:
5445 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5446 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
5447 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
5448 break;
5449 case RPC_FC_LONG:
5450 case RPC_FC_ULONG:
5451 case RPC_FC_ERROR_STATUS_T:
5452 case RPC_FC_ENUM32:
5453 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5454 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
5455 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
5456 break;
5457 case RPC_FC_FLOAT:
5458 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
5459 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
5460 break;
5461 case RPC_FC_DOUBLE:
5462 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
5463 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
5464 break;
5465 case RPC_FC_HYPER:
5466 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
5467 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
5468 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
5469 break;
5470 case RPC_FC_ENUM16:
5471 /* only 16-bits on the wire, so do a sanity check */
5472 if (*(UINT *)pMemory > SHRT_MAX)
5473 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
5474 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5475 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5476 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5477 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
5478 pStubMsg->Buffer += sizeof(USHORT);
5479 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
5480 break;
5481 case RPC_FC_IGNORE:
5482 break;
5483 default:
5484 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5487 /* FIXME: what is the correct return value? */
5488 return NULL;
5491 /***********************************************************************
5492 * NdrBaseTypeUnmarshall [internal]
5494 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
5495 PMIDL_STUB_MESSAGE pStubMsg,
5496 unsigned char **ppMemory,
5497 PFORMAT_STRING pFormat,
5498 unsigned char fMustAlloc)
5500 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5502 #define BASE_TYPE_UNMARSHALL(type) \
5503 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5504 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
5506 *ppMemory = pStubMsg->Buffer; \
5507 TRACE("*ppMemory: %p\n", *ppMemory); \
5509 else \
5511 if (fMustAlloc) \
5512 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5513 TRACE("*ppMemory: %p\n", *ppMemory); \
5514 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5516 pStubMsg->Buffer += sizeof(type);
5518 switch(*pFormat)
5520 case RPC_FC_BYTE:
5521 case RPC_FC_CHAR:
5522 case RPC_FC_SMALL:
5523 case RPC_FC_USMALL:
5524 BASE_TYPE_UNMARSHALL(UCHAR);
5525 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5526 break;
5527 case RPC_FC_WCHAR:
5528 case RPC_FC_SHORT:
5529 case RPC_FC_USHORT:
5530 BASE_TYPE_UNMARSHALL(USHORT);
5531 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5532 break;
5533 case RPC_FC_LONG:
5534 case RPC_FC_ULONG:
5535 case RPC_FC_ERROR_STATUS_T:
5536 case RPC_FC_ENUM32:
5537 BASE_TYPE_UNMARSHALL(ULONG);
5538 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5539 break;
5540 case RPC_FC_FLOAT:
5541 BASE_TYPE_UNMARSHALL(float);
5542 TRACE("value: %f\n", **(float **)ppMemory);
5543 break;
5544 case RPC_FC_DOUBLE:
5545 BASE_TYPE_UNMARSHALL(double);
5546 TRACE("value: %f\n", **(double **)ppMemory);
5547 break;
5548 case RPC_FC_HYPER:
5549 BASE_TYPE_UNMARSHALL(ULONGLONG);
5550 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
5551 break;
5552 case RPC_FC_ENUM16:
5553 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5554 if (fMustAlloc || !*ppMemory)
5555 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
5556 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
5557 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5558 TRACE("*ppMemory: %p\n", *ppMemory);
5559 /* 16-bits on the wire, but int in memory */
5560 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
5561 pStubMsg->Buffer += sizeof(USHORT);
5562 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
5563 break;
5564 case RPC_FC_IGNORE:
5565 break;
5566 default:
5567 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5569 #undef BASE_TYPE_UNMARSHALL
5571 /* FIXME: what is the correct return value? */
5573 return NULL;
5576 /***********************************************************************
5577 * NdrBaseTypeBufferSize [internal]
5579 static void WINAPI NdrBaseTypeBufferSize(
5580 PMIDL_STUB_MESSAGE pStubMsg,
5581 unsigned char *pMemory,
5582 PFORMAT_STRING pFormat)
5584 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5586 switch(*pFormat)
5588 case RPC_FC_BYTE:
5589 case RPC_FC_CHAR:
5590 case RPC_FC_SMALL:
5591 case RPC_FC_USMALL:
5592 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
5593 break;
5594 case RPC_FC_WCHAR:
5595 case RPC_FC_SHORT:
5596 case RPC_FC_USHORT:
5597 case RPC_FC_ENUM16:
5598 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
5599 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
5600 break;
5601 case RPC_FC_LONG:
5602 case RPC_FC_ULONG:
5603 case RPC_FC_ENUM32:
5604 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
5605 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
5606 break;
5607 case RPC_FC_FLOAT:
5608 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
5609 safe_buffer_length_increment(pStubMsg, sizeof(float));
5610 break;
5611 case RPC_FC_DOUBLE:
5612 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
5613 safe_buffer_length_increment(pStubMsg, sizeof(double));
5614 break;
5615 case RPC_FC_HYPER:
5616 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
5617 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
5618 break;
5619 case RPC_FC_ERROR_STATUS_T:
5620 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
5621 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
5622 break;
5623 case RPC_FC_IGNORE:
5624 break;
5625 default:
5626 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5630 /***********************************************************************
5631 * NdrBaseTypeMemorySize [internal]
5633 static ULONG WINAPI NdrBaseTypeMemorySize(
5634 PMIDL_STUB_MESSAGE pStubMsg,
5635 PFORMAT_STRING pFormat)
5637 switch(*pFormat)
5639 case RPC_FC_BYTE:
5640 case RPC_FC_CHAR:
5641 case RPC_FC_SMALL:
5642 case RPC_FC_USMALL:
5643 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
5644 pStubMsg->MemorySize += sizeof(UCHAR);
5645 return sizeof(UCHAR);
5646 case RPC_FC_WCHAR:
5647 case RPC_FC_SHORT:
5648 case RPC_FC_USHORT:
5649 safe_buffer_increment(pStubMsg, sizeof(USHORT));
5650 pStubMsg->MemorySize += sizeof(USHORT);
5651 return sizeof(USHORT);
5652 case RPC_FC_LONG:
5653 case RPC_FC_ULONG:
5654 case RPC_FC_ENUM32:
5655 safe_buffer_increment(pStubMsg, sizeof(ULONG));
5656 pStubMsg->MemorySize += sizeof(ULONG);
5657 return sizeof(ULONG);
5658 case RPC_FC_FLOAT:
5659 safe_buffer_increment(pStubMsg, sizeof(float));
5660 pStubMsg->MemorySize += sizeof(float);
5661 return sizeof(float);
5662 case RPC_FC_DOUBLE:
5663 safe_buffer_increment(pStubMsg, sizeof(double));
5664 pStubMsg->MemorySize += sizeof(double);
5665 return sizeof(double);
5666 case RPC_FC_HYPER:
5667 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
5668 pStubMsg->MemorySize += sizeof(ULONGLONG);
5669 return sizeof(ULONGLONG);
5670 case RPC_FC_ERROR_STATUS_T:
5671 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
5672 pStubMsg->MemorySize += sizeof(error_status_t);
5673 return sizeof(error_status_t);
5674 case RPC_FC_ENUM16:
5675 safe_buffer_increment(pStubMsg, sizeof(USHORT));
5676 pStubMsg->MemorySize += sizeof(UINT);
5677 return sizeof(UINT);
5678 case RPC_FC_IGNORE:
5679 pStubMsg->MemorySize += sizeof(void *);
5680 return sizeof(void *);
5681 default:
5682 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5683 return 0;
5687 /***********************************************************************
5688 * NdrBaseTypeFree [internal]
5690 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
5691 unsigned char *pMemory,
5692 PFORMAT_STRING pFormat)
5694 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5696 /* nothing to do */
5699 /***********************************************************************
5700 * NdrContextHandleBufferSize [internal]
5702 static void WINAPI NdrContextHandleBufferSize(
5703 PMIDL_STUB_MESSAGE pStubMsg,
5704 unsigned char *pMemory,
5705 PFORMAT_STRING pFormat)
5707 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5709 if (*pFormat != RPC_FC_BIND_CONTEXT)
5711 ERR("invalid format type %x\n", *pFormat);
5712 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5714 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5715 safe_buffer_length_increment(pStubMsg, cbNDRContext);
5718 /***********************************************************************
5719 * NdrContextHandleMarshall [internal]
5721 static unsigned char *WINAPI NdrContextHandleMarshall(
5722 PMIDL_STUB_MESSAGE pStubMsg,
5723 unsigned char *pMemory,
5724 PFORMAT_STRING pFormat)
5726 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5728 if (*pFormat != RPC_FC_BIND_CONTEXT)
5730 ERR("invalid format type %x\n", *pFormat);
5731 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5734 if (pFormat[1] & 0x80)
5735 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
5736 else
5737 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
5739 return NULL;
5742 /***********************************************************************
5743 * NdrContextHandleUnmarshall [internal]
5745 static unsigned char *WINAPI NdrContextHandleUnmarshall(
5746 PMIDL_STUB_MESSAGE pStubMsg,
5747 unsigned char **ppMemory,
5748 PFORMAT_STRING pFormat,
5749 unsigned char fMustAlloc)
5751 if (*pFormat != RPC_FC_BIND_CONTEXT)
5753 ERR("invalid format type %x\n", *pFormat);
5754 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5757 **(NDR_CCONTEXT **)ppMemory = NULL;
5758 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
5760 return NULL;
5763 /***********************************************************************
5764 * NdrClientContextMarshall [RPCRT4.@]
5766 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5767 NDR_CCONTEXT ContextHandle,
5768 int fCheck)
5770 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
5772 ALIGN_POINTER(pStubMsg->Buffer, 4);
5774 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5776 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
5777 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5778 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5781 /* FIXME: what does fCheck do? */
5782 NDRCContextMarshall(ContextHandle,
5783 pStubMsg->Buffer);
5785 pStubMsg->Buffer += cbNDRContext;
5788 /***********************************************************************
5789 * NdrClientContextUnmarshall [RPCRT4.@]
5791 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5792 NDR_CCONTEXT * pContextHandle,
5793 RPC_BINDING_HANDLE BindHandle)
5795 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
5797 ALIGN_POINTER(pStubMsg->Buffer, 4);
5799 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
5800 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5802 NDRCContextUnmarshall(pContextHandle,
5803 BindHandle,
5804 pStubMsg->Buffer,
5805 pStubMsg->RpcMsg->DataRepresentation);
5807 pStubMsg->Buffer += cbNDRContext;
5810 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5811 NDR_SCONTEXT ContextHandle,
5812 NDR_RUNDOWN RundownRoutine )
5814 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
5817 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
5819 FIXME("(%p): stub\n", pStubMsg);
5820 return NULL;
5823 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
5824 unsigned char* pMemory,
5825 PFORMAT_STRING pFormat)
5827 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
5830 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
5831 PFORMAT_STRING pFormat)
5833 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
5834 return NULL;
5837 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5838 NDR_SCONTEXT ContextHandle,
5839 NDR_RUNDOWN RundownRoutine,
5840 PFORMAT_STRING pFormat)
5842 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
5845 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5846 PFORMAT_STRING pFormat)
5848 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
5849 return NULL;
5852 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
5854 typedef struct ndr_context_handle
5856 DWORD attributes;
5857 GUID uuid;
5858 } ndr_context_handle;
5860 struct context_handle_entry
5862 struct list entry;
5863 DWORD magic;
5864 RPC_BINDING_HANDLE handle;
5865 ndr_context_handle wire_data;
5868 static struct list context_handle_list = LIST_INIT(context_handle_list);
5870 static CRITICAL_SECTION ndr_context_cs;
5871 static CRITICAL_SECTION_DEBUG ndr_context_debug =
5873 0, 0, &ndr_context_cs,
5874 { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
5875 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
5877 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
5879 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
5881 struct context_handle_entry *che = (struct context_handle_entry*) CContext;
5883 if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
5884 return NULL;
5885 return che;
5888 static struct context_handle_entry *context_entry_from_guid(LPCGUID uuid)
5890 struct context_handle_entry *che;
5891 LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
5892 if (IsEqualGUID(&che->wire_data.uuid, uuid))
5893 return che;
5894 return NULL;
5897 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
5899 struct context_handle_entry *che;
5900 RPC_BINDING_HANDLE handle = NULL;
5902 TRACE("%p\n", CContext);
5904 EnterCriticalSection(&ndr_context_cs);
5905 che = get_context_entry(CContext);
5906 if (che)
5907 handle = che->handle;
5908 LeaveCriticalSection(&ndr_context_cs);
5910 if (!handle)
5911 RpcRaiseException(ERROR_INVALID_HANDLE);
5912 return handle;
5915 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
5917 struct context_handle_entry *che;
5919 TRACE("%p %p\n", CContext, pBuff);
5921 if (CContext)
5923 EnterCriticalSection(&ndr_context_cs);
5924 che = get_context_entry(CContext);
5925 memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
5926 LeaveCriticalSection(&ndr_context_cs);
5928 else
5930 ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
5931 wire_data->attributes = 0;
5932 wire_data->uuid = GUID_NULL;
5936 /***********************************************************************
5937 * RpcSmDestroyClientContext [RPCRT4.@]
5939 RPC_STATUS WINAPI RpcSmDestroyClientContext(void **ContextHandle)
5941 RPC_STATUS status = RPC_X_SS_CONTEXT_MISMATCH;
5942 struct context_handle_entry *che = NULL;
5944 TRACE("(%p)\n", ContextHandle);
5946 EnterCriticalSection(&ndr_context_cs);
5947 che = get_context_entry(*ContextHandle);
5948 *ContextHandle = NULL;
5949 if (che)
5951 status = RPC_S_OK;
5952 list_remove(&che->entry);
5955 LeaveCriticalSection(&ndr_context_cs);
5957 if (che)
5959 RpcBindingFree(&che->handle);
5960 HeapFree(GetProcessHeap(), 0, che);
5963 return status;
5966 /***********************************************************************
5967 * RpcSsDestroyClientContext [RPCRT4.@]
5969 void WINAPI RpcSsDestroyClientContext(void **ContextHandle)
5971 RPC_STATUS status = RpcSmDestroyClientContext(ContextHandle);
5972 if (status != RPC_S_OK)
5973 RpcRaiseException(status);
5976 static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
5977 RPC_BINDING_HANDLE hBinding,
5978 const ndr_context_handle *chi)
5980 struct context_handle_entry *che = NULL;
5982 /* a null UUID means we should free the context handle */
5983 if (IsEqualGUID(&chi->uuid, &GUID_NULL))
5985 if (*CContext)
5987 che = get_context_entry(*CContext);
5988 if (!che)
5989 return ERROR_INVALID_HANDLE;
5990 list_remove(&che->entry);
5991 RpcBindingFree(&che->handle);
5992 HeapFree(GetProcessHeap(), 0, che);
5993 che = NULL;
5996 /* if there's no existing entry matching the GUID, allocate one */
5997 else if (!(che = context_entry_from_guid(&chi->uuid)))
5999 che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
6000 if (!che)
6001 return ERROR_NOT_ENOUGH_MEMORY;
6002 che->magic = NDR_CONTEXT_HANDLE_MAGIC;
6003 RpcBindingCopy(hBinding, &che->handle);
6004 list_add_tail(&context_handle_list, &che->entry);
6005 memcpy(&che->wire_data, chi, sizeof *chi);
6008 *CContext = che;
6010 return ERROR_SUCCESS;
6013 /***********************************************************************
6014 * NDRCContextUnmarshall [RPCRT4.@]
6016 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
6017 RPC_BINDING_HANDLE hBinding,
6018 void *pBuff, ULONG DataRepresentation)
6020 UINT r;
6022 TRACE("*%p=(%p) %p %p %08x\n",
6023 CContext, *CContext, hBinding, pBuff, DataRepresentation);
6025 EnterCriticalSection(&ndr_context_cs);
6026 r = ndr_update_context_handle(CContext, hBinding, pBuff);
6027 LeaveCriticalSection(&ndr_context_cs);
6028 if (r)
6029 RpcRaiseException(r);
6032 /***********************************************************************
6033 * NDRSContextMarshall [RPCRT4.@]
6035 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
6036 void *pBuff,
6037 NDR_RUNDOWN userRunDownIn)
6039 FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn);
6042 /***********************************************************************
6043 * NDRSContextMarshallEx [RPCRT4.@]
6045 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
6046 NDR_SCONTEXT CContext,
6047 void *pBuff,
6048 NDR_RUNDOWN userRunDownIn)
6050 FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn);
6053 /***********************************************************************
6054 * NDRSContextMarshall2 [RPCRT4.@]
6056 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
6057 NDR_SCONTEXT CContext,
6058 void *pBuff,
6059 NDR_RUNDOWN userRunDownIn,
6060 void *CtxGuard, ULONG Flags)
6062 FIXME("(%p %p %p %p %p %u): stub\n",
6063 hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags);
6066 /***********************************************************************
6067 * NDRSContextUnmarshall [RPCRT4.@]
6069 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
6070 ULONG DataRepresentation)
6072 FIXME("(%p %08x): stub\n", pBuff, DataRepresentation);
6073 return NULL;
6076 /***********************************************************************
6077 * NDRSContextUnmarshallEx [RPCRT4.@]
6079 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
6080 void *pBuff,
6081 ULONG DataRepresentation)
6083 FIXME("(%p %p %08x): stub\n", hBinding, pBuff, DataRepresentation);
6084 return NULL;
6087 /***********************************************************************
6088 * NDRSContextUnmarshall2 [RPCRT4.@]
6090 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
6091 void *pBuff,
6092 ULONG DataRepresentation,
6093 void *CtxGuard, ULONG Flags)
6095 FIXME("(%p %p %08x %p %u): stub\n",
6096 hBinding, pBuff, DataRepresentation, CtxGuard, Flags);
6097 return NULL;