push 0f15bbd80d260bbd8adf052e820484a405c49375
[wine/hacks.git] / dlls / rpcrt4 / ndr_marshall.c
blob8300b640e11e6796ed195169cc0c0d96f8659ade
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 pSrcPointer = NULL;
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("pSrcPointer = %p\n", pSrcPointer);
1024 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. As there is no space used in the buffer for pointers when using
1034 * reference pointers we must allocate memory in this case */
1035 if (type == RPC_FC_RP || attr & RPC_FC_P_DEREF) {
1036 fMustAlloc = TRUE;
1037 base_ptr_val = NULL;
1038 } else {
1039 base_ptr_val = NULL;
1040 *current_ptr = NULL;
1044 if (attr & RPC_FC_P_DEREF) {
1045 if (fMustAlloc) {
1046 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
1047 current_ptr = (unsigned char **)base_ptr_val;
1048 } else
1049 current_ptr = *(unsigned char***)current_ptr;
1050 TRACE("deref => %p\n", current_ptr);
1051 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
1053 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1054 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
1055 else FIXME("no unmarshaller for data type=%02x\n", *desc);
1057 if (type == RPC_FC_FP)
1058 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
1059 base_ptr_val);
1061 /* this must be done after the call to the unmarshaller, since when we are
1062 * unmarshalling reference pointers on the server side *pPointer will be
1063 * pointing to valid data */
1064 if (base_ptr_val && (!fMustAlloc || attr & RPC_FC_P_DEREF))
1065 *pPointer = base_ptr_val;
1068 TRACE("pointer=%p\n", *pPointer);
1071 /***********************************************************************
1072 * PointerBufferSize [internal]
1074 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1075 unsigned char *Pointer,
1076 PFORMAT_STRING pFormat)
1078 unsigned type = pFormat[0], attr = pFormat[1];
1079 PFORMAT_STRING desc;
1080 NDR_BUFFERSIZE m;
1081 int pointer_needs_sizing;
1082 ULONG pointer_id;
1084 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1085 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1086 pFormat += 2;
1087 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1088 else desc = pFormat + *(const SHORT*)pFormat;
1090 switch (type) {
1091 case RPC_FC_RP: /* ref pointer (always non-null) */
1092 if (!Pointer)
1094 ERR("NULL ref pointer is not allowed\n");
1095 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1097 break;
1098 case RPC_FC_OP:
1099 case RPC_FC_UP:
1100 /* NULL pointer has no further representation */
1101 if (!Pointer)
1102 return;
1103 break;
1104 case RPC_FC_FP:
1105 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1106 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1107 if (!pointer_needs_sizing)
1108 return;
1109 break;
1110 default:
1111 FIXME("unhandled ptr type=%02x\n", type);
1112 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1113 return;
1116 if (attr & RPC_FC_P_DEREF) {
1117 Pointer = *(unsigned char**)Pointer;
1118 TRACE("deref => %p\n", Pointer);
1121 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1122 if (m) m(pStubMsg, Pointer, desc);
1123 else FIXME("no buffersizer for data type=%02x\n", *desc);
1126 /***********************************************************************
1127 * PointerMemorySize [internal]
1129 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1130 unsigned char *Buffer,
1131 PFORMAT_STRING pFormat)
1133 unsigned type = pFormat[0], attr = pFormat[1];
1134 PFORMAT_STRING desc;
1135 NDR_MEMORYSIZE m;
1137 FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat);
1138 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1139 pFormat += 2;
1140 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1141 else desc = pFormat + *(const SHORT*)pFormat;
1143 switch (type) {
1144 case RPC_FC_RP: /* ref pointer (always non-null) */
1145 break;
1146 default:
1147 FIXME("unhandled ptr type=%02x\n", type);
1148 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1151 if (attr & RPC_FC_P_DEREF) {
1152 TRACE("deref\n");
1155 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1156 if (m) m(pStubMsg, desc);
1157 else FIXME("no memorysizer for data type=%02x\n", *desc);
1159 return 0;
1162 /***********************************************************************
1163 * PointerFree [internal]
1165 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1166 unsigned char *Pointer,
1167 PFORMAT_STRING pFormat)
1169 unsigned type = pFormat[0], attr = pFormat[1];
1170 PFORMAT_STRING desc;
1171 NDR_FREE m;
1173 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1174 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1175 if (attr & RPC_FC_P_DONTFREE) return;
1176 pFormat += 2;
1177 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1178 else desc = pFormat + *(const SHORT*)pFormat;
1180 if (!Pointer) return;
1182 if (type == RPC_FC_FP) {
1183 int pointer_needs_freeing = NdrFullPointerFree(
1184 pStubMsg->FullPtrXlatTables, Pointer);
1185 if (!pointer_needs_freeing)
1186 return;
1189 if (attr & RPC_FC_P_DEREF) {
1190 Pointer = *(unsigned char**)Pointer;
1191 TRACE("deref => %p\n", Pointer);
1194 m = NdrFreer[*desc & NDR_TABLE_MASK];
1195 if (m) m(pStubMsg, Pointer, desc);
1197 /* hmm... is this sensible?
1198 * perhaps we should check if the memory comes from NdrAllocate,
1199 * and deallocate only if so - checking if the pointer is between
1200 * BufferStart and BufferEnd is probably no good since the buffer
1201 * may be reallocated when the server wants to marshal the reply */
1202 switch (*desc) {
1203 case RPC_FC_BOGUS_STRUCT:
1204 case RPC_FC_BOGUS_ARRAY:
1205 case RPC_FC_USER_MARSHAL:
1206 case RPC_FC_CARRAY:
1207 case RPC_FC_CVARRAY:
1208 break;
1209 default:
1210 FIXME("unhandled data type=%02x\n", *desc);
1211 break;
1212 case RPC_FC_C_CSTRING:
1213 case RPC_FC_C_WSTRING:
1214 if (pStubMsg->ReuseBuffer) goto notfree;
1215 break;
1216 case RPC_FC_IP:
1217 goto notfree;
1220 if (attr & RPC_FC_P_ONSTACK) {
1221 TRACE("not freeing stack ptr %p\n", Pointer);
1222 return;
1224 TRACE("freeing %p\n", Pointer);
1225 NdrFree(pStubMsg, Pointer);
1226 return;
1227 notfree:
1228 TRACE("not freeing %p\n", Pointer);
1231 /***********************************************************************
1232 * EmbeddedPointerMarshall
1234 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1235 unsigned char *pMemory,
1236 PFORMAT_STRING pFormat)
1238 unsigned char *Mark = pStubMsg->BufferMark;
1239 unsigned rep, count, stride;
1240 unsigned i;
1241 unsigned char *saved_buffer = NULL;
1243 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1245 if (*pFormat != RPC_FC_PP) return NULL;
1246 pFormat += 2;
1248 if (pStubMsg->PointerBufferMark)
1250 saved_buffer = pStubMsg->Buffer;
1251 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1252 pStubMsg->PointerBufferMark = NULL;
1255 while (pFormat[0] != RPC_FC_END) {
1256 switch (pFormat[0]) {
1257 default:
1258 FIXME("unknown repeat type %d\n", pFormat[0]);
1259 case RPC_FC_NO_REPEAT:
1260 rep = 1;
1261 stride = 0;
1262 count = 1;
1263 pFormat += 2;
1264 break;
1265 case RPC_FC_FIXED_REPEAT:
1266 rep = *(const WORD*)&pFormat[2];
1267 stride = *(const WORD*)&pFormat[4];
1268 count = *(const WORD*)&pFormat[8];
1269 pFormat += 10;
1270 break;
1271 case RPC_FC_VARIABLE_REPEAT:
1272 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1273 stride = *(const WORD*)&pFormat[2];
1274 count = *(const WORD*)&pFormat[6];
1275 pFormat += 8;
1276 break;
1278 for (i = 0; i < rep; i++) {
1279 PFORMAT_STRING info = pFormat;
1280 unsigned char *membase = pMemory + (i * stride);
1281 unsigned char *bufbase = Mark + (i * stride);
1282 unsigned u;
1284 for (u=0; u<count; u++,info+=8) {
1285 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1286 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1287 unsigned char *saved_memory = pStubMsg->Memory;
1289 pStubMsg->Memory = pMemory;
1290 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1291 pStubMsg->Memory = saved_memory;
1294 pFormat += 8 * count;
1297 if (saved_buffer)
1299 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1300 pStubMsg->Buffer = saved_buffer;
1303 STD_OVERFLOW_CHECK(pStubMsg);
1305 return NULL;
1308 /***********************************************************************
1309 * EmbeddedPointerUnmarshall
1311 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1312 unsigned char *pDstMemoryPtrs,
1313 unsigned char *pSrcMemoryPtrs,
1314 PFORMAT_STRING pFormat,
1315 unsigned char fMustAlloc)
1317 unsigned char *Mark = pStubMsg->BufferMark;
1318 unsigned rep, count, stride;
1319 unsigned i;
1320 unsigned char *saved_buffer = NULL;
1322 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstMemoryPtrs, pSrcMemoryPtrs, pFormat, fMustAlloc);
1324 if (*pFormat != RPC_FC_PP) return NULL;
1325 pFormat += 2;
1327 if (pStubMsg->PointerBufferMark)
1329 saved_buffer = pStubMsg->Buffer;
1330 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1331 pStubMsg->PointerBufferMark = NULL;
1334 while (pFormat[0] != RPC_FC_END) {
1335 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1336 switch (pFormat[0]) {
1337 default:
1338 FIXME("unknown repeat type %d\n", pFormat[0]);
1339 case RPC_FC_NO_REPEAT:
1340 rep = 1;
1341 stride = 0;
1342 count = 1;
1343 pFormat += 2;
1344 break;
1345 case RPC_FC_FIXED_REPEAT:
1346 rep = *(const WORD*)&pFormat[2];
1347 stride = *(const WORD*)&pFormat[4];
1348 count = *(const WORD*)&pFormat[8];
1349 pFormat += 10;
1350 break;
1351 case RPC_FC_VARIABLE_REPEAT:
1352 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1353 stride = *(const WORD*)&pFormat[2];
1354 count = *(const WORD*)&pFormat[6];
1355 pFormat += 8;
1356 break;
1358 for (i = 0; i < rep; i++) {
1359 PFORMAT_STRING info = pFormat;
1360 unsigned char *memdstbase = pDstMemoryPtrs + (i * stride);
1361 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1362 unsigned char *bufbase = Mark + (i * stride);
1363 unsigned u;
1365 for (u=0; u<count; u++,info+=8) {
1366 unsigned char **memdstptr = (unsigned char **)(memdstbase + *(const SHORT*)&info[0]);
1367 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1368 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1369 PointerUnmarshall(pStubMsg, bufptr, memdstptr, *memsrcptr, info+4, fMustAlloc);
1372 pFormat += 8 * count;
1375 if (saved_buffer)
1377 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1378 pStubMsg->Buffer = saved_buffer;
1381 return NULL;
1384 /***********************************************************************
1385 * EmbeddedPointerBufferSize
1387 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1388 unsigned char *pMemory,
1389 PFORMAT_STRING pFormat)
1391 unsigned rep, count, stride;
1392 unsigned i;
1393 ULONG saved_buffer_length = 0;
1395 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1397 if (pStubMsg->IgnoreEmbeddedPointers) return;
1399 if (*pFormat != RPC_FC_PP) return;
1400 pFormat += 2;
1402 if (pStubMsg->PointerLength)
1404 saved_buffer_length = pStubMsg->BufferLength;
1405 pStubMsg->BufferLength = pStubMsg->PointerLength;
1406 pStubMsg->PointerLength = 0;
1409 while (pFormat[0] != RPC_FC_END) {
1410 switch (pFormat[0]) {
1411 default:
1412 FIXME("unknown repeat type %d\n", pFormat[0]);
1413 case RPC_FC_NO_REPEAT:
1414 rep = 1;
1415 stride = 0;
1416 count = 1;
1417 pFormat += 2;
1418 break;
1419 case RPC_FC_FIXED_REPEAT:
1420 rep = *(const WORD*)&pFormat[2];
1421 stride = *(const WORD*)&pFormat[4];
1422 count = *(const WORD*)&pFormat[8];
1423 pFormat += 10;
1424 break;
1425 case RPC_FC_VARIABLE_REPEAT:
1426 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1427 stride = *(const WORD*)&pFormat[2];
1428 count = *(const WORD*)&pFormat[6];
1429 pFormat += 8;
1430 break;
1432 for (i = 0; i < rep; i++) {
1433 PFORMAT_STRING info = pFormat;
1434 unsigned char *membase = pMemory + (i * stride);
1435 unsigned u;
1437 for (u=0; u<count; u++,info+=8) {
1438 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1439 unsigned char *saved_memory = pStubMsg->Memory;
1441 pStubMsg->Memory = pMemory;
1442 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1443 pStubMsg->Memory = saved_memory;
1446 pFormat += 8 * count;
1449 if (saved_buffer_length)
1451 pStubMsg->PointerLength = pStubMsg->BufferLength;
1452 pStubMsg->BufferLength = saved_buffer_length;
1456 /***********************************************************************
1457 * EmbeddedPointerMemorySize [internal]
1459 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1460 PFORMAT_STRING pFormat)
1462 unsigned char *Mark = pStubMsg->BufferMark;
1463 unsigned rep, count, stride;
1464 unsigned i;
1466 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1468 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1470 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1472 if (*pFormat != RPC_FC_PP) return 0;
1473 pFormat += 2;
1475 while (pFormat[0] != RPC_FC_END) {
1476 switch (pFormat[0]) {
1477 default:
1478 FIXME("unknown repeat type %d\n", pFormat[0]);
1479 case RPC_FC_NO_REPEAT:
1480 rep = 1;
1481 stride = 0;
1482 count = 1;
1483 pFormat += 2;
1484 break;
1485 case RPC_FC_FIXED_REPEAT:
1486 rep = *(const WORD*)&pFormat[2];
1487 stride = *(const WORD*)&pFormat[4];
1488 count = *(const WORD*)&pFormat[8];
1489 pFormat += 10;
1490 break;
1491 case RPC_FC_VARIABLE_REPEAT:
1492 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1493 stride = *(const WORD*)&pFormat[2];
1494 count = *(const WORD*)&pFormat[6];
1495 pFormat += 8;
1496 break;
1498 for (i = 0; i < rep; i++) {
1499 PFORMAT_STRING info = pFormat;
1500 unsigned char *bufbase = Mark + (i * stride);
1501 unsigned u;
1502 for (u=0; u<count; u++,info+=8) {
1503 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1504 PointerMemorySize(pStubMsg, bufptr, info+4);
1507 pFormat += 8 * count;
1510 return 0;
1513 /***********************************************************************
1514 * EmbeddedPointerFree [internal]
1516 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1517 unsigned char *pMemory,
1518 PFORMAT_STRING pFormat)
1520 unsigned rep, count, stride;
1521 unsigned i;
1523 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1524 if (*pFormat != RPC_FC_PP) return;
1525 pFormat += 2;
1527 while (pFormat[0] != RPC_FC_END) {
1528 switch (pFormat[0]) {
1529 default:
1530 FIXME("unknown repeat type %d\n", pFormat[0]);
1531 case RPC_FC_NO_REPEAT:
1532 rep = 1;
1533 stride = 0;
1534 count = 1;
1535 pFormat += 2;
1536 break;
1537 case RPC_FC_FIXED_REPEAT:
1538 rep = *(const WORD*)&pFormat[2];
1539 stride = *(const WORD*)&pFormat[4];
1540 count = *(const WORD*)&pFormat[8];
1541 pFormat += 10;
1542 break;
1543 case RPC_FC_VARIABLE_REPEAT:
1544 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1545 stride = *(const WORD*)&pFormat[2];
1546 count = *(const WORD*)&pFormat[6];
1547 pFormat += 8;
1548 break;
1550 for (i = 0; i < rep; i++) {
1551 PFORMAT_STRING info = pFormat;
1552 unsigned char *membase = pMemory + (i * stride);
1553 unsigned u;
1555 for (u=0; u<count; u++,info+=8) {
1556 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1557 unsigned char *saved_memory = pStubMsg->Memory;
1559 pStubMsg->Memory = pMemory;
1560 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1561 pStubMsg->Memory = saved_memory;
1564 pFormat += 8 * count;
1568 /***********************************************************************
1569 * NdrPointerMarshall [RPCRT4.@]
1571 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1572 unsigned char *pMemory,
1573 PFORMAT_STRING pFormat)
1575 unsigned char *Buffer;
1577 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1579 /* incremement the buffer here instead of in PointerMarshall,
1580 * as that is used by embedded pointers which already handle the incrementing
1581 * the buffer, and shouldn't write any additional pointer data to the wire */
1582 if (*pFormat != RPC_FC_RP)
1584 ALIGN_POINTER(pStubMsg->Buffer, 4);
1585 Buffer = pStubMsg->Buffer;
1586 safe_buffer_increment(pStubMsg, 4);
1588 else
1589 Buffer = pStubMsg->Buffer;
1591 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1593 return NULL;
1596 /***********************************************************************
1597 * NdrPointerUnmarshall [RPCRT4.@]
1599 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1600 unsigned char **ppMemory,
1601 PFORMAT_STRING pFormat,
1602 unsigned char fMustAlloc)
1604 unsigned char *Buffer;
1606 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1608 /* incremement the buffer here instead of in PointerUnmarshall,
1609 * as that is used by embedded pointers which already handle the incrementing
1610 * the buffer, and shouldn't read any additional pointer data from the
1611 * buffer */
1612 if (*pFormat != RPC_FC_RP)
1614 ALIGN_POINTER(pStubMsg->Buffer, 4);
1615 Buffer = pStubMsg->Buffer;
1616 safe_buffer_increment(pStubMsg, 4);
1618 else
1619 Buffer = pStubMsg->Buffer;
1621 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1623 return NULL;
1626 /***********************************************************************
1627 * NdrPointerBufferSize [RPCRT4.@]
1629 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1630 unsigned char *pMemory,
1631 PFORMAT_STRING pFormat)
1633 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1635 /* incremement the buffer length here instead of in PointerBufferSize,
1636 * as that is used by embedded pointers which already handle the buffer
1637 * length, and shouldn't write anything more to the wire */
1638 if (*pFormat != RPC_FC_RP)
1640 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1641 safe_buffer_length_increment(pStubMsg, 4);
1644 PointerBufferSize(pStubMsg, pMemory, pFormat);
1647 /***********************************************************************
1648 * NdrPointerMemorySize [RPCRT4.@]
1650 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1651 PFORMAT_STRING pFormat)
1653 /* unsigned size = *(LPWORD)(pFormat+2); */
1654 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1655 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1656 return 0;
1659 /***********************************************************************
1660 * NdrPointerFree [RPCRT4.@]
1662 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1663 unsigned char *pMemory,
1664 PFORMAT_STRING pFormat)
1666 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1667 PointerFree(pStubMsg, pMemory, pFormat);
1670 /***********************************************************************
1671 * NdrSimpleTypeMarshall [RPCRT4.@]
1673 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1674 unsigned char FormatChar )
1676 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1679 /***********************************************************************
1680 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1682 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1683 unsigned char FormatChar )
1685 NdrBaseTypeUnmarshall(pStubMsg, &pMemory, &FormatChar, 0);
1688 /***********************************************************************
1689 * NdrSimpleStructMarshall [RPCRT4.@]
1691 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1692 unsigned char *pMemory,
1693 PFORMAT_STRING pFormat)
1695 unsigned size = *(const WORD*)(pFormat+2);
1696 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1698 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1700 pStubMsg->BufferMark = pStubMsg->Buffer;
1701 safe_copy_to_buffer(pStubMsg, pMemory, size);
1703 if (pFormat[0] != RPC_FC_STRUCT)
1704 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1706 return NULL;
1709 /***********************************************************************
1710 * NdrSimpleStructUnmarshall [RPCRT4.@]
1712 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1713 unsigned char **ppMemory,
1714 PFORMAT_STRING pFormat,
1715 unsigned char fMustAlloc)
1717 unsigned size = *(const WORD*)(pFormat+2);
1718 unsigned char *saved_buffer;
1719 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1721 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1723 if (fMustAlloc)
1724 *ppMemory = NdrAllocate(pStubMsg, size);
1725 else
1727 if (!pStubMsg->IsClient && !*ppMemory)
1728 /* for servers, we just point straight into the RPC buffer */
1729 *ppMemory = pStubMsg->Buffer;
1732 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1733 safe_buffer_increment(pStubMsg, size);
1734 if (pFormat[0] == RPC_FC_PSTRUCT)
1735 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1737 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1738 if (*ppMemory != saved_buffer)
1739 memcpy(*ppMemory, saved_buffer, size);
1741 return NULL;
1744 /***********************************************************************
1745 * NdrSimpleStructBufferSize [RPCRT4.@]
1747 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1748 unsigned char *pMemory,
1749 PFORMAT_STRING pFormat)
1751 unsigned size = *(const WORD*)(pFormat+2);
1752 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1754 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1756 safe_buffer_length_increment(pStubMsg, size);
1757 if (pFormat[0] != RPC_FC_STRUCT)
1758 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1761 /***********************************************************************
1762 * NdrSimpleStructMemorySize [RPCRT4.@]
1764 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1765 PFORMAT_STRING pFormat)
1767 unsigned short size = *(const WORD *)(pFormat+2);
1769 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1771 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1772 pStubMsg->MemorySize += size;
1773 safe_buffer_increment(pStubMsg, size);
1775 if (pFormat[0] != RPC_FC_STRUCT)
1776 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1777 return size;
1780 /***********************************************************************
1781 * NdrSimpleStructFree [RPCRT4.@]
1783 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1784 unsigned char *pMemory,
1785 PFORMAT_STRING pFormat)
1787 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1788 if (pFormat[0] != RPC_FC_STRUCT)
1789 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1793 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE *pStubMsg,
1794 PFORMAT_STRING pFormat)
1796 switch (*pFormat) {
1797 case RPC_FC_STRUCT:
1798 case RPC_FC_PSTRUCT:
1799 case RPC_FC_CSTRUCT:
1800 case RPC_FC_BOGUS_STRUCT:
1801 case RPC_FC_SMFARRAY:
1802 case RPC_FC_SMVARRAY:
1803 return *(const WORD*)&pFormat[2];
1804 case RPC_FC_USER_MARSHAL:
1805 return *(const WORD*)&pFormat[4];
1806 case RPC_FC_NON_ENCAPSULATED_UNION:
1807 pFormat += 2;
1808 if (pStubMsg->fHasNewCorrDesc)
1809 pFormat += 6;
1810 else
1811 pFormat += 4;
1813 pFormat += *(const SHORT*)pFormat;
1814 return *(const SHORT*)pFormat;
1815 case RPC_FC_IP:
1816 return sizeof(void *);
1817 default:
1818 FIXME("unhandled embedded type %02x\n", *pFormat);
1820 return 0;
1824 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1825 PFORMAT_STRING pFormat)
1827 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1829 if (!m)
1831 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1832 return 0;
1835 return m(pStubMsg, pFormat);
1839 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1840 unsigned char *pMemory,
1841 PFORMAT_STRING pFormat,
1842 PFORMAT_STRING pPointer)
1844 PFORMAT_STRING desc;
1845 NDR_MARSHALL m;
1846 unsigned long size;
1848 while (*pFormat != RPC_FC_END) {
1849 switch (*pFormat) {
1850 case RPC_FC_BYTE:
1851 case RPC_FC_CHAR:
1852 case RPC_FC_SMALL:
1853 case RPC_FC_USMALL:
1854 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
1855 safe_copy_to_buffer(pStubMsg, pMemory, 1);
1856 pMemory += 1;
1857 break;
1858 case RPC_FC_WCHAR:
1859 case RPC_FC_SHORT:
1860 case RPC_FC_USHORT:
1861 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1862 safe_copy_to_buffer(pStubMsg, pMemory, 2);
1863 pMemory += 2;
1864 break;
1865 case RPC_FC_LONG:
1866 case RPC_FC_ULONG:
1867 case RPC_FC_ENUM32:
1868 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
1869 safe_copy_to_buffer(pStubMsg, pMemory, 4);
1870 pMemory += 4;
1871 break;
1872 case RPC_FC_HYPER:
1873 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1874 safe_copy_to_buffer(pStubMsg, pMemory, 8);
1875 pMemory += 8;
1876 break;
1877 case RPC_FC_POINTER:
1879 unsigned char *saved_buffer;
1880 int pointer_buffer_mark_set = 0;
1881 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1882 saved_buffer = pStubMsg->Buffer;
1883 if (pStubMsg->PointerBufferMark)
1885 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1886 pStubMsg->PointerBufferMark = NULL;
1887 pointer_buffer_mark_set = 1;
1889 else
1890 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
1891 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
1892 if (pointer_buffer_mark_set)
1894 STD_OVERFLOW_CHECK(pStubMsg);
1895 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1896 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
1898 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
1899 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
1900 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1902 pStubMsg->Buffer = saved_buffer + 4;
1904 pPointer += 4;
1905 pMemory += 4;
1906 break;
1908 case RPC_FC_ALIGNM4:
1909 ALIGN_POINTER(pMemory, 4);
1910 break;
1911 case RPC_FC_ALIGNM8:
1912 ALIGN_POINTER(pMemory, 8);
1913 break;
1914 case RPC_FC_STRUCTPAD1:
1915 case RPC_FC_STRUCTPAD2:
1916 case RPC_FC_STRUCTPAD3:
1917 case RPC_FC_STRUCTPAD4:
1918 case RPC_FC_STRUCTPAD5:
1919 case RPC_FC_STRUCTPAD6:
1920 case RPC_FC_STRUCTPAD7:
1921 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1922 break;
1923 case RPC_FC_EMBEDDED_COMPLEX:
1924 pMemory += pFormat[1];
1925 pFormat += 2;
1926 desc = pFormat + *(const SHORT*)pFormat;
1927 size = EmbeddedComplexSize(pStubMsg, desc);
1928 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1929 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1930 if (m)
1932 /* for some reason interface pointers aren't generated as
1933 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
1934 * they still need the derefencing treatment that pointers are
1935 * given */
1936 if (*desc == RPC_FC_IP)
1937 m(pStubMsg, *(unsigned char **)pMemory, desc);
1938 else
1939 m(pStubMsg, pMemory, desc);
1941 else FIXME("no marshaller for embedded type %02x\n", *desc);
1942 pMemory += size;
1943 pFormat += 2;
1944 continue;
1945 case RPC_FC_PAD:
1946 break;
1947 default:
1948 FIXME("unhandled format 0x%02x\n", *pFormat);
1950 pFormat++;
1953 return pMemory;
1956 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1957 unsigned char *pMemory,
1958 PFORMAT_STRING pFormat,
1959 PFORMAT_STRING pPointer)
1961 PFORMAT_STRING desc;
1962 NDR_UNMARSHALL m;
1963 unsigned long size;
1965 while (*pFormat != RPC_FC_END) {
1966 switch (*pFormat) {
1967 case RPC_FC_BYTE:
1968 case RPC_FC_CHAR:
1969 case RPC_FC_SMALL:
1970 case RPC_FC_USMALL:
1971 safe_copy_from_buffer(pStubMsg, pMemory, 1);
1972 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
1973 pMemory += 1;
1974 break;
1975 case RPC_FC_WCHAR:
1976 case RPC_FC_SHORT:
1977 case RPC_FC_USHORT:
1978 safe_copy_from_buffer(pStubMsg, pMemory, 2);
1979 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1980 pMemory += 2;
1981 break;
1982 case RPC_FC_LONG:
1983 case RPC_FC_ULONG:
1984 case RPC_FC_ENUM32:
1985 safe_copy_from_buffer(pStubMsg, pMemory, 4);
1986 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
1987 pMemory += 4;
1988 break;
1989 case RPC_FC_HYPER:
1990 safe_copy_from_buffer(pStubMsg, pMemory, 8);
1991 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1992 pMemory += 8;
1993 break;
1994 case RPC_FC_POINTER:
1996 unsigned char *saved_buffer;
1997 int pointer_buffer_mark_set = 0;
1998 TRACE("pointer => %p\n", pMemory);
1999 ALIGN_POINTER(pStubMsg->Buffer, 4);
2000 saved_buffer = pStubMsg->Buffer;
2001 if (pStubMsg->PointerBufferMark)
2003 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2004 pStubMsg->PointerBufferMark = NULL;
2005 pointer_buffer_mark_set = 1;
2007 else
2008 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2010 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, TRUE);
2011 if (pointer_buffer_mark_set)
2013 STD_OVERFLOW_CHECK(pStubMsg);
2014 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2015 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2017 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2018 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2019 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2021 pStubMsg->Buffer = saved_buffer + 4;
2023 pPointer += 4;
2024 pMemory += 4;
2025 break;
2027 case RPC_FC_ALIGNM4:
2028 ALIGN_POINTER(pMemory, 4);
2029 break;
2030 case RPC_FC_ALIGNM8:
2031 ALIGN_POINTER(pMemory, 8);
2032 break;
2033 case RPC_FC_STRUCTPAD1:
2034 case RPC_FC_STRUCTPAD2:
2035 case RPC_FC_STRUCTPAD3:
2036 case RPC_FC_STRUCTPAD4:
2037 case RPC_FC_STRUCTPAD5:
2038 case RPC_FC_STRUCTPAD6:
2039 case RPC_FC_STRUCTPAD7:
2040 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2041 break;
2042 case RPC_FC_EMBEDDED_COMPLEX:
2043 pMemory += pFormat[1];
2044 pFormat += 2;
2045 desc = pFormat + *(const SHORT*)pFormat;
2046 size = EmbeddedComplexSize(pStubMsg, desc);
2047 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2048 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2049 memset(pMemory, 0, size); /* just in case */
2050 if (m)
2052 /* for some reason interface pointers aren't generated as
2053 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2054 * they still need the derefencing treatment that pointers are
2055 * given */
2056 if (*desc == RPC_FC_IP)
2057 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2058 else
2059 m(pStubMsg, &pMemory, desc, FALSE);
2061 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2062 pMemory += size;
2063 pFormat += 2;
2064 continue;
2065 case RPC_FC_PAD:
2066 break;
2067 default:
2068 FIXME("unhandled format %d\n", *pFormat);
2070 pFormat++;
2073 return pMemory;
2076 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2077 unsigned char *pMemory,
2078 PFORMAT_STRING pFormat,
2079 PFORMAT_STRING pPointer)
2081 PFORMAT_STRING desc;
2082 NDR_BUFFERSIZE m;
2083 unsigned long size;
2085 while (*pFormat != RPC_FC_END) {
2086 switch (*pFormat) {
2087 case RPC_FC_BYTE:
2088 case RPC_FC_CHAR:
2089 case RPC_FC_SMALL:
2090 case RPC_FC_USMALL:
2091 safe_buffer_length_increment(pStubMsg, 1);
2092 pMemory += 1;
2093 break;
2094 case RPC_FC_WCHAR:
2095 case RPC_FC_SHORT:
2096 case RPC_FC_USHORT:
2097 safe_buffer_length_increment(pStubMsg, 2);
2098 pMemory += 2;
2099 break;
2100 case RPC_FC_LONG:
2101 case RPC_FC_ULONG:
2102 case RPC_FC_ENUM32:
2103 safe_buffer_length_increment(pStubMsg, 4);
2104 pMemory += 4;
2105 break;
2106 case RPC_FC_HYPER:
2107 safe_buffer_length_increment(pStubMsg, 8);
2108 pMemory += 8;
2109 break;
2110 case RPC_FC_POINTER:
2111 if (!pStubMsg->IgnoreEmbeddedPointers)
2113 int saved_buffer_length = pStubMsg->BufferLength;
2114 pStubMsg->BufferLength = pStubMsg->PointerLength;
2115 pStubMsg->PointerLength = 0;
2116 if(!pStubMsg->BufferLength)
2117 ERR("BufferLength == 0??\n");
2118 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2119 pStubMsg->PointerLength = pStubMsg->BufferLength;
2120 pStubMsg->BufferLength = saved_buffer_length;
2122 safe_buffer_length_increment(pStubMsg, 4);
2123 pPointer += 4;
2124 pMemory += 4;
2125 break;
2126 case RPC_FC_ALIGNM4:
2127 ALIGN_POINTER(pMemory, 4);
2128 break;
2129 case RPC_FC_ALIGNM8:
2130 ALIGN_POINTER(pMemory, 8);
2131 break;
2132 case RPC_FC_STRUCTPAD1:
2133 case RPC_FC_STRUCTPAD2:
2134 case RPC_FC_STRUCTPAD3:
2135 case RPC_FC_STRUCTPAD4:
2136 case RPC_FC_STRUCTPAD5:
2137 case RPC_FC_STRUCTPAD6:
2138 case RPC_FC_STRUCTPAD7:
2139 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2140 break;
2141 case RPC_FC_EMBEDDED_COMPLEX:
2142 pMemory += pFormat[1];
2143 pFormat += 2;
2144 desc = pFormat + *(const SHORT*)pFormat;
2145 size = EmbeddedComplexSize(pStubMsg, desc);
2146 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2147 if (m)
2149 /* for some reason interface pointers aren't generated as
2150 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2151 * they still need the derefencing treatment that pointers are
2152 * given */
2153 if (*desc == RPC_FC_IP)
2154 m(pStubMsg, *(unsigned char **)pMemory, desc);
2155 else
2156 m(pStubMsg, pMemory, desc);
2158 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2159 pMemory += size;
2160 pFormat += 2;
2161 continue;
2162 case RPC_FC_PAD:
2163 break;
2164 default:
2165 FIXME("unhandled format 0x%02x\n", *pFormat);
2167 pFormat++;
2170 return pMemory;
2173 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2174 unsigned char *pMemory,
2175 PFORMAT_STRING pFormat,
2176 PFORMAT_STRING pPointer)
2178 PFORMAT_STRING desc;
2179 NDR_FREE m;
2180 unsigned long size;
2182 while (*pFormat != RPC_FC_END) {
2183 switch (*pFormat) {
2184 case RPC_FC_BYTE:
2185 case RPC_FC_CHAR:
2186 case RPC_FC_SMALL:
2187 case RPC_FC_USMALL:
2188 pMemory += 1;
2189 break;
2190 case RPC_FC_WCHAR:
2191 case RPC_FC_SHORT:
2192 case RPC_FC_USHORT:
2193 pMemory += 2;
2194 break;
2195 case RPC_FC_LONG:
2196 case RPC_FC_ULONG:
2197 case RPC_FC_ENUM32:
2198 pMemory += 4;
2199 break;
2200 case RPC_FC_HYPER:
2201 pMemory += 8;
2202 break;
2203 case RPC_FC_POINTER:
2204 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
2205 pPointer += 4;
2206 pMemory += 4;
2207 break;
2208 case RPC_FC_ALIGNM4:
2209 ALIGN_POINTER(pMemory, 4);
2210 break;
2211 case RPC_FC_ALIGNM8:
2212 ALIGN_POINTER(pMemory, 8);
2213 break;
2214 case RPC_FC_STRUCTPAD1:
2215 case RPC_FC_STRUCTPAD2:
2216 case RPC_FC_STRUCTPAD3:
2217 case RPC_FC_STRUCTPAD4:
2218 case RPC_FC_STRUCTPAD5:
2219 case RPC_FC_STRUCTPAD6:
2220 case RPC_FC_STRUCTPAD7:
2221 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2222 break;
2223 case RPC_FC_EMBEDDED_COMPLEX:
2224 pMemory += pFormat[1];
2225 pFormat += 2;
2226 desc = pFormat + *(const SHORT*)pFormat;
2227 size = EmbeddedComplexSize(pStubMsg, desc);
2228 m = NdrFreer[*desc & NDR_TABLE_MASK];
2229 if (m)
2231 /* for some reason interface pointers aren't generated as
2232 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2233 * they still need the derefencing treatment that pointers are
2234 * given */
2235 if (*desc == RPC_FC_IP)
2236 m(pStubMsg, *(unsigned char **)pMemory, desc);
2237 else
2238 m(pStubMsg, pMemory, desc);
2240 else FIXME("no freer for embedded type %02x\n", *desc);
2241 pMemory += size;
2242 pFormat += 2;
2243 continue;
2244 case RPC_FC_PAD:
2245 break;
2246 default:
2247 FIXME("unhandled format 0x%02x\n", *pFormat);
2249 pFormat++;
2252 return pMemory;
2255 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2256 PFORMAT_STRING pFormat)
2258 PFORMAT_STRING desc;
2259 unsigned long size = 0;
2261 while (*pFormat != RPC_FC_END) {
2262 switch (*pFormat) {
2263 case RPC_FC_BYTE:
2264 case RPC_FC_CHAR:
2265 case RPC_FC_SMALL:
2266 case RPC_FC_USMALL:
2267 size += 1;
2268 safe_buffer_increment(pStubMsg, 1);
2269 break;
2270 case RPC_FC_WCHAR:
2271 case RPC_FC_SHORT:
2272 case RPC_FC_USHORT:
2273 size += 2;
2274 safe_buffer_increment(pStubMsg, 2);
2275 break;
2276 case RPC_FC_LONG:
2277 case RPC_FC_ULONG:
2278 case RPC_FC_ENUM32:
2279 size += 4;
2280 safe_buffer_increment(pStubMsg, 4);
2281 break;
2282 case RPC_FC_HYPER:
2283 size += 8;
2284 safe_buffer_increment(pStubMsg, 8);
2285 break;
2286 case RPC_FC_POINTER:
2287 size += 4;
2288 safe_buffer_increment(pStubMsg, 4);
2289 if (!pStubMsg->IgnoreEmbeddedPointers)
2290 FIXME("embedded pointers\n");
2291 break;
2292 case RPC_FC_ALIGNM4:
2293 ALIGN_LENGTH(size, 4);
2294 ALIGN_POINTER(pStubMsg->Buffer, 4);
2295 break;
2296 case RPC_FC_ALIGNM8:
2297 ALIGN_LENGTH(size, 8);
2298 ALIGN_POINTER(pStubMsg->Buffer, 8);
2299 break;
2300 case RPC_FC_STRUCTPAD1:
2301 case RPC_FC_STRUCTPAD2:
2302 case RPC_FC_STRUCTPAD3:
2303 case RPC_FC_STRUCTPAD4:
2304 case RPC_FC_STRUCTPAD5:
2305 case RPC_FC_STRUCTPAD6:
2306 case RPC_FC_STRUCTPAD7:
2307 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2308 break;
2309 case RPC_FC_EMBEDDED_COMPLEX:
2310 size += pFormat[1];
2311 pFormat += 2;
2312 desc = pFormat + *(const SHORT*)pFormat;
2313 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2314 pFormat += 2;
2315 continue;
2316 case RPC_FC_PAD:
2317 break;
2318 default:
2319 FIXME("unhandled format 0x%02x\n", *pFormat);
2321 pFormat++;
2324 return size;
2327 /***********************************************************************
2328 * NdrComplexStructMarshall [RPCRT4.@]
2330 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2331 unsigned char *pMemory,
2332 PFORMAT_STRING pFormat)
2334 PFORMAT_STRING conf_array = NULL;
2335 PFORMAT_STRING pointer_desc = NULL;
2336 unsigned char *OldMemory = pStubMsg->Memory;
2337 int pointer_buffer_mark_set = 0;
2339 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2341 if (!pStubMsg->PointerBufferMark)
2343 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2344 /* save buffer length */
2345 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2347 /* get the buffer pointer after complex array data, but before
2348 * pointer data */
2349 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2350 pStubMsg->IgnoreEmbeddedPointers = 1;
2351 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2352 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2354 /* save it for use by embedded pointer code later */
2355 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2356 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
2357 pointer_buffer_mark_set = 1;
2359 /* restore the original buffer length */
2360 pStubMsg->BufferLength = saved_buffer_length;
2363 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2365 pFormat += 4;
2366 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2367 pFormat += 2;
2368 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2369 pFormat += 2;
2371 pStubMsg->Memory = pMemory;
2373 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2375 if (conf_array)
2376 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2378 pStubMsg->Memory = OldMemory;
2380 if (pointer_buffer_mark_set)
2382 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2383 pStubMsg->PointerBufferMark = NULL;
2386 STD_OVERFLOW_CHECK(pStubMsg);
2388 return NULL;
2391 /***********************************************************************
2392 * NdrComplexStructUnmarshall [RPCRT4.@]
2394 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2395 unsigned char **ppMemory,
2396 PFORMAT_STRING pFormat,
2397 unsigned char fMustAlloc)
2399 unsigned size = *(const WORD*)(pFormat+2);
2400 PFORMAT_STRING conf_array = NULL;
2401 PFORMAT_STRING pointer_desc = NULL;
2402 unsigned char *pMemory;
2403 int pointer_buffer_mark_set = 0;
2405 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2407 if (!pStubMsg->PointerBufferMark)
2409 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2410 /* save buffer pointer */
2411 unsigned char *saved_buffer = pStubMsg->Buffer;
2413 /* get the buffer pointer after complex array data, but before
2414 * pointer data */
2415 pStubMsg->IgnoreEmbeddedPointers = 1;
2416 NdrComplexStructMemorySize(pStubMsg, pFormat);
2417 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2419 /* save it for use by embedded pointer code later */
2420 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2421 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
2422 pointer_buffer_mark_set = 1;
2424 /* restore the original buffer */
2425 pStubMsg->Buffer = saved_buffer;
2428 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2430 if (fMustAlloc || !*ppMemory)
2432 *ppMemory = NdrAllocate(pStubMsg, size);
2433 memset(*ppMemory, 0, size);
2436 pFormat += 4;
2437 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2438 pFormat += 2;
2439 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2440 pFormat += 2;
2442 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2444 if (conf_array)
2445 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2447 if (pointer_buffer_mark_set)
2449 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2450 pStubMsg->PointerBufferMark = NULL;
2453 return NULL;
2456 /***********************************************************************
2457 * NdrComplexStructBufferSize [RPCRT4.@]
2459 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2460 unsigned char *pMemory,
2461 PFORMAT_STRING pFormat)
2463 PFORMAT_STRING conf_array = NULL;
2464 PFORMAT_STRING pointer_desc = NULL;
2465 unsigned char *OldMemory = pStubMsg->Memory;
2466 int pointer_length_set = 0;
2468 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2470 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2472 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2474 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2475 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2477 /* get the buffer length after complex struct data, but before
2478 * pointer data */
2479 pStubMsg->IgnoreEmbeddedPointers = 1;
2480 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2481 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2483 /* save it for use by embedded pointer code later */
2484 pStubMsg->PointerLength = pStubMsg->BufferLength;
2485 pointer_length_set = 1;
2486 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
2488 /* restore the original buffer length */
2489 pStubMsg->BufferLength = saved_buffer_length;
2492 pFormat += 4;
2493 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2494 pFormat += 2;
2495 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2496 pFormat += 2;
2498 pStubMsg->Memory = pMemory;
2500 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2502 if (conf_array)
2503 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2505 pStubMsg->Memory = OldMemory;
2507 if(pointer_length_set)
2509 pStubMsg->BufferLength = pStubMsg->PointerLength;
2510 pStubMsg->PointerLength = 0;
2515 /***********************************************************************
2516 * NdrComplexStructMemorySize [RPCRT4.@]
2518 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2519 PFORMAT_STRING pFormat)
2521 unsigned size = *(const WORD*)(pFormat+2);
2522 PFORMAT_STRING conf_array = NULL;
2523 PFORMAT_STRING pointer_desc = NULL;
2525 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2527 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2529 pFormat += 4;
2530 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2531 pFormat += 2;
2532 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2533 pFormat += 2;
2535 ComplexStructMemorySize(pStubMsg, pFormat);
2537 if (conf_array)
2538 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2540 return size;
2543 /***********************************************************************
2544 * NdrComplexStructFree [RPCRT4.@]
2546 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2547 unsigned char *pMemory,
2548 PFORMAT_STRING pFormat)
2550 PFORMAT_STRING conf_array = NULL;
2551 PFORMAT_STRING pointer_desc = NULL;
2552 unsigned char *OldMemory = pStubMsg->Memory;
2554 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2556 pFormat += 4;
2557 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2558 pFormat += 2;
2559 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2560 pFormat += 2;
2562 pStubMsg->Memory = pMemory;
2564 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2566 if (conf_array)
2567 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2569 pStubMsg->Memory = OldMemory;
2572 /***********************************************************************
2573 * NdrConformantArrayMarshall [RPCRT4.@]
2575 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2576 unsigned char *pMemory,
2577 PFORMAT_STRING pFormat)
2579 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2580 unsigned char alignment = pFormat[1] + 1;
2582 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2583 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2585 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2587 WriteConformance(pStubMsg);
2589 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2591 size = safe_multiply(esize, pStubMsg->MaxCount);
2592 pStubMsg->BufferMark = pStubMsg->Buffer;
2593 safe_copy_to_buffer(pStubMsg, pMemory, size);
2595 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2597 return NULL;
2600 /***********************************************************************
2601 * NdrConformantArrayUnmarshall [RPCRT4.@]
2603 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2604 unsigned char **ppMemory,
2605 PFORMAT_STRING pFormat,
2606 unsigned char fMustAlloc)
2608 DWORD size, esize = *(const WORD*)(pFormat+2);
2609 unsigned char alignment = pFormat[1] + 1;
2611 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2612 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2614 pFormat = ReadConformance(pStubMsg, pFormat+4);
2616 size = safe_multiply(esize, pStubMsg->MaxCount);
2618 if (fMustAlloc || !*ppMemory)
2619 *ppMemory = NdrAllocate(pStubMsg, size);
2621 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2623 pStubMsg->BufferMark = pStubMsg->Buffer;
2624 safe_copy_from_buffer(pStubMsg, *ppMemory, size);
2626 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
2628 return NULL;
2631 /***********************************************************************
2632 * NdrConformantArrayBufferSize [RPCRT4.@]
2634 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2635 unsigned char *pMemory,
2636 PFORMAT_STRING pFormat)
2638 DWORD size, esize = *(const WORD*)(pFormat+2);
2639 unsigned char alignment = pFormat[1] + 1;
2641 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2642 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2644 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2646 SizeConformance(pStubMsg);
2648 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2650 size = safe_multiply(esize, pStubMsg->MaxCount);
2651 /* conformance value plus array */
2652 safe_buffer_length_increment(pStubMsg, size);
2654 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2657 /***********************************************************************
2658 * NdrConformantArrayMemorySize [RPCRT4.@]
2660 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2661 PFORMAT_STRING pFormat)
2663 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2664 unsigned char alignment = pFormat[1] + 1;
2666 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2667 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2669 pFormat = ReadConformance(pStubMsg, pFormat+4);
2670 size = safe_multiply(esize, pStubMsg->MaxCount);
2671 pStubMsg->MemorySize += size;
2673 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2674 pStubMsg->BufferMark = pStubMsg->Buffer;
2675 safe_buffer_increment(pStubMsg, size);
2677 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2679 return pStubMsg->MemorySize;
2682 /***********************************************************************
2683 * NdrConformantArrayFree [RPCRT4.@]
2685 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2686 unsigned char *pMemory,
2687 PFORMAT_STRING pFormat)
2689 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2690 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2692 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2694 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2698 /***********************************************************************
2699 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2701 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2702 unsigned char* pMemory,
2703 PFORMAT_STRING pFormat )
2705 ULONG bufsize;
2706 unsigned char alignment = pFormat[1] + 1;
2707 DWORD esize = *(const WORD*)(pFormat+2);
2709 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2711 if (pFormat[0] != RPC_FC_CVARRAY)
2713 ERR("invalid format type %x\n", pFormat[0]);
2714 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2715 return NULL;
2718 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2719 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2721 WriteConformance(pStubMsg);
2722 WriteVariance(pStubMsg);
2724 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2726 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2728 pStubMsg->BufferMark = pStubMsg->Buffer;
2729 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
2731 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2733 return NULL;
2737 /***********************************************************************
2738 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2740 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2741 unsigned char** ppMemory,
2742 PFORMAT_STRING pFormat,
2743 unsigned char fMustAlloc )
2745 ULONG bufsize, memsize;
2746 unsigned char alignment = pFormat[1] + 1;
2747 DWORD esize = *(const WORD*)(pFormat+2);
2749 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2751 if (pFormat[0] != RPC_FC_CVARRAY)
2753 ERR("invalid format type %x\n", pFormat[0]);
2754 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2755 return NULL;
2758 pFormat = ReadConformance(pStubMsg, pFormat+4);
2759 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2761 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2763 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2764 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2766 if (!*ppMemory || fMustAlloc)
2767 *ppMemory = NdrAllocate(pStubMsg, memsize);
2768 safe_copy_from_buffer(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize);
2770 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
2772 return NULL;
2776 /***********************************************************************
2777 * NdrConformantVaryingArrayFree [RPCRT4.@]
2779 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2780 unsigned char* pMemory,
2781 PFORMAT_STRING pFormat )
2783 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2785 if (pFormat[0] != RPC_FC_CVARRAY)
2787 ERR("invalid format type %x\n", pFormat[0]);
2788 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2789 return;
2792 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2793 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2795 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2799 /***********************************************************************
2800 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2802 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2803 unsigned char* pMemory, PFORMAT_STRING pFormat )
2805 unsigned char alignment = pFormat[1] + 1;
2806 DWORD esize = *(const WORD*)(pFormat+2);
2808 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2810 if (pFormat[0] != RPC_FC_CVARRAY)
2812 ERR("invalid format type %x\n", pFormat[0]);
2813 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2814 return;
2817 /* compute size */
2818 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2819 /* compute length */
2820 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2822 SizeConformance(pStubMsg);
2823 SizeVariance(pStubMsg);
2825 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2827 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2829 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2833 /***********************************************************************
2834 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2836 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2837 PFORMAT_STRING pFormat )
2839 FIXME( "stub\n" );
2840 return 0;
2844 /***********************************************************************
2845 * NdrComplexArrayMarshall [RPCRT4.@]
2847 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2848 unsigned char *pMemory,
2849 PFORMAT_STRING pFormat)
2851 ULONG i, count, def;
2852 BOOL variance_present;
2853 unsigned char alignment;
2854 int pointer_buffer_mark_set = 0;
2856 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2858 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2860 ERR("invalid format type %x\n", pFormat[0]);
2861 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2862 return NULL;
2865 alignment = pFormat[1] + 1;
2867 if (!pStubMsg->PointerBufferMark)
2869 /* save buffer fields that may be changed by buffer sizer functions
2870 * and that may be needed later on */
2871 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2872 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2873 unsigned long saved_max_count = pStubMsg->MaxCount;
2874 unsigned long saved_offset = pStubMsg->Offset;
2875 unsigned long saved_actual_count = pStubMsg->ActualCount;
2877 /* get the buffer pointer after complex array data, but before
2878 * pointer data */
2879 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2880 pStubMsg->IgnoreEmbeddedPointers = 1;
2881 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
2882 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2884 /* save it for use by embedded pointer code later */
2885 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2886 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
2887 pointer_buffer_mark_set = 1;
2889 /* restore fields */
2890 pStubMsg->ActualCount = saved_actual_count;
2891 pStubMsg->Offset = saved_offset;
2892 pStubMsg->MaxCount = saved_max_count;
2893 pStubMsg->BufferLength = saved_buffer_length;
2896 def = *(const WORD*)&pFormat[2];
2897 pFormat += 4;
2899 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2900 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2902 variance_present = IsConformanceOrVariancePresent(pFormat);
2903 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2904 TRACE("variance = %d\n", pStubMsg->ActualCount);
2906 WriteConformance(pStubMsg);
2907 if (variance_present)
2908 WriteVariance(pStubMsg);
2910 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2912 count = pStubMsg->ActualCount;
2913 for (i = 0; i < count; i++)
2914 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2916 STD_OVERFLOW_CHECK(pStubMsg);
2918 if (pointer_buffer_mark_set)
2920 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2921 pStubMsg->PointerBufferMark = NULL;
2924 return NULL;
2927 /***********************************************************************
2928 * NdrComplexArrayUnmarshall [RPCRT4.@]
2930 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2931 unsigned char **ppMemory,
2932 PFORMAT_STRING pFormat,
2933 unsigned char fMustAlloc)
2935 ULONG i, count, size;
2936 unsigned char alignment;
2937 unsigned char *pMemory;
2938 unsigned char *saved_buffer;
2939 int pointer_buffer_mark_set = 0;
2940 int saved_ignore_embedded;
2942 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2944 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2946 ERR("invalid format type %x\n", pFormat[0]);
2947 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2948 return NULL;
2951 alignment = pFormat[1] + 1;
2953 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2954 /* save buffer pointer */
2955 saved_buffer = pStubMsg->Buffer;
2956 /* get the buffer pointer after complex array data, but before
2957 * pointer data */
2958 pStubMsg->IgnoreEmbeddedPointers = 1;
2959 pStubMsg->MemorySize = 0;
2960 NdrComplexArrayMemorySize(pStubMsg, pFormat);
2961 size = pStubMsg->MemorySize;
2962 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2964 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
2965 if (!pStubMsg->PointerBufferMark)
2967 /* save it for use by embedded pointer code later */
2968 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2969 pointer_buffer_mark_set = 1;
2971 /* restore the original buffer */
2972 pStubMsg->Buffer = saved_buffer;
2974 pFormat += 4;
2976 pFormat = ReadConformance(pStubMsg, pFormat);
2977 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2979 if (fMustAlloc || !*ppMemory)
2981 *ppMemory = NdrAllocate(pStubMsg, size);
2982 memset(*ppMemory, 0, size);
2985 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2987 pMemory = *ppMemory;
2988 count = pStubMsg->ActualCount;
2989 for (i = 0; i < count; i++)
2990 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
2992 if (pointer_buffer_mark_set)
2994 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2995 pStubMsg->PointerBufferMark = NULL;
2998 return NULL;
3001 /***********************************************************************
3002 * NdrComplexArrayBufferSize [RPCRT4.@]
3004 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3005 unsigned char *pMemory,
3006 PFORMAT_STRING pFormat)
3008 ULONG i, count, def;
3009 unsigned char alignment;
3010 BOOL variance_present;
3011 int pointer_length_set = 0;
3013 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3015 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3017 ERR("invalid format type %x\n", pFormat[0]);
3018 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3019 return;
3022 alignment = pFormat[1] + 1;
3024 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3026 /* save buffer fields that may be changed by buffer sizer functions
3027 * and that may be needed later on */
3028 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3029 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3030 unsigned long saved_max_count = pStubMsg->MaxCount;
3031 unsigned long saved_offset = pStubMsg->Offset;
3032 unsigned long saved_actual_count = pStubMsg->ActualCount;
3034 /* get the buffer pointer after complex array data, but before
3035 * pointer data */
3036 pStubMsg->IgnoreEmbeddedPointers = 1;
3037 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3038 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3040 /* save it for use by embedded pointer code later */
3041 pStubMsg->PointerLength = pStubMsg->BufferLength;
3042 pointer_length_set = 1;
3044 /* restore fields */
3045 pStubMsg->ActualCount = saved_actual_count;
3046 pStubMsg->Offset = saved_offset;
3047 pStubMsg->MaxCount = saved_max_count;
3048 pStubMsg->BufferLength = saved_buffer_length;
3050 def = *(const WORD*)&pFormat[2];
3051 pFormat += 4;
3053 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3054 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3055 SizeConformance(pStubMsg);
3057 variance_present = IsConformanceOrVariancePresent(pFormat);
3058 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3059 TRACE("variance = %d\n", pStubMsg->ActualCount);
3061 if (variance_present)
3062 SizeVariance(pStubMsg);
3064 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3066 count = pStubMsg->ActualCount;
3067 for (i = 0; i < count; i++)
3068 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
3070 if(pointer_length_set)
3072 pStubMsg->BufferLength = pStubMsg->PointerLength;
3073 pStubMsg->PointerLength = 0;
3077 /***********************************************************************
3078 * NdrComplexArrayMemorySize [RPCRT4.@]
3080 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3081 PFORMAT_STRING pFormat)
3083 ULONG i, count, esize, SavedMemorySize, MemorySize;
3084 unsigned char alignment;
3085 unsigned char *Buffer;
3087 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3089 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3091 ERR("invalid format type %x\n", pFormat[0]);
3092 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3093 return 0;
3096 alignment = pFormat[1] + 1;
3098 pFormat += 4;
3100 pFormat = ReadConformance(pStubMsg, pFormat);
3101 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3103 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3105 SavedMemorySize = pStubMsg->MemorySize;
3107 Buffer = pStubMsg->Buffer;
3108 pStubMsg->MemorySize = 0;
3109 esize = ComplexStructMemorySize(pStubMsg, pFormat);
3110 pStubMsg->Buffer = Buffer;
3112 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
3114 count = pStubMsg->ActualCount;
3115 for (i = 0; i < count; i++)
3116 ComplexStructMemorySize(pStubMsg, pFormat);
3118 pStubMsg->MemorySize = SavedMemorySize;
3120 pStubMsg->MemorySize += MemorySize;
3121 return MemorySize;
3124 /***********************************************************************
3125 * NdrComplexArrayFree [RPCRT4.@]
3127 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3128 unsigned char *pMemory,
3129 PFORMAT_STRING pFormat)
3131 ULONG i, count, def;
3133 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3135 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3137 ERR("invalid format type %x\n", pFormat[0]);
3138 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3139 return;
3142 def = *(const WORD*)&pFormat[2];
3143 pFormat += 4;
3145 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3146 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3148 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3149 TRACE("variance = %d\n", pStubMsg->ActualCount);
3151 count = pStubMsg->ActualCount;
3152 for (i = 0; i < count; i++)
3153 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
3156 static ULONG UserMarshalFlags(const MIDL_STUB_MESSAGE *pStubMsg)
3158 return MAKELONG(pStubMsg->dwDestContext,
3159 pStubMsg->RpcMsg->DataRepresentation);
3162 #define USER_MARSHAL_PTR_PREFIX \
3163 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3164 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3166 /***********************************************************************
3167 * NdrUserMarshalMarshall [RPCRT4.@]
3169 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3170 unsigned char *pMemory,
3171 PFORMAT_STRING pFormat)
3173 unsigned flags = pFormat[1];
3174 unsigned index = *(const WORD*)&pFormat[2];
3175 unsigned char *saved_buffer = NULL;
3176 ULONG uflag = UserMarshalFlags(pStubMsg);
3177 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3178 TRACE("index=%d\n", index);
3180 if (flags & USER_MARSHAL_POINTER)
3182 ALIGN_POINTER(pStubMsg->Buffer, 4);
3183 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
3184 pStubMsg->Buffer += 4;
3185 if (pStubMsg->PointerBufferMark)
3187 saved_buffer = pStubMsg->Buffer;
3188 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3189 pStubMsg->PointerBufferMark = NULL;
3191 ALIGN_POINTER(pStubMsg->Buffer, 8);
3193 else
3194 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3196 pStubMsg->Buffer =
3197 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
3198 &uflag, pStubMsg->Buffer, pMemory);
3200 if (saved_buffer)
3202 STD_OVERFLOW_CHECK(pStubMsg);
3203 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3204 pStubMsg->Buffer = saved_buffer;
3207 STD_OVERFLOW_CHECK(pStubMsg);
3209 return NULL;
3212 /***********************************************************************
3213 * NdrUserMarshalUnmarshall [RPCRT4.@]
3215 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3216 unsigned char **ppMemory,
3217 PFORMAT_STRING pFormat,
3218 unsigned char fMustAlloc)
3220 unsigned flags = pFormat[1];
3221 unsigned index = *(const WORD*)&pFormat[2];
3222 DWORD memsize = *(const WORD*)&pFormat[4];
3223 unsigned char *saved_buffer = NULL;
3224 ULONG uflag = UserMarshalFlags(pStubMsg);
3225 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3226 TRACE("index=%d\n", index);
3228 if (flags & USER_MARSHAL_POINTER)
3230 ALIGN_POINTER(pStubMsg->Buffer, 4);
3231 /* skip pointer prefix */
3232 pStubMsg->Buffer += 4;
3233 if (pStubMsg->PointerBufferMark)
3235 saved_buffer = pStubMsg->Buffer;
3236 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3237 pStubMsg->PointerBufferMark = NULL;
3239 ALIGN_POINTER(pStubMsg->Buffer, 8);
3241 else
3242 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3244 if (fMustAlloc || !*ppMemory)
3245 *ppMemory = NdrAllocate(pStubMsg, memsize);
3247 pStubMsg->Buffer =
3248 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
3249 &uflag, pStubMsg->Buffer, *ppMemory);
3251 if (saved_buffer)
3253 STD_OVERFLOW_CHECK(pStubMsg);
3254 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3255 pStubMsg->Buffer = saved_buffer;
3258 return NULL;
3261 /***********************************************************************
3262 * NdrUserMarshalBufferSize [RPCRT4.@]
3264 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3265 unsigned char *pMemory,
3266 PFORMAT_STRING pFormat)
3268 unsigned flags = pFormat[1];
3269 unsigned index = *(const WORD*)&pFormat[2];
3270 DWORD bufsize = *(const WORD*)&pFormat[6];
3271 ULONG uflag = UserMarshalFlags(pStubMsg);
3272 unsigned long saved_buffer_length = 0;
3273 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3274 TRACE("index=%d\n", index);
3276 if (flags & USER_MARSHAL_POINTER)
3278 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3279 /* skip pointer prefix */
3280 safe_buffer_length_increment(pStubMsg, 4);
3281 if (pStubMsg->IgnoreEmbeddedPointers)
3282 return;
3283 if (pStubMsg->PointerLength)
3285 saved_buffer_length = pStubMsg->BufferLength;
3286 pStubMsg->BufferLength = pStubMsg->PointerLength;
3287 pStubMsg->PointerLength = 0;
3289 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
3291 else
3292 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
3294 if (bufsize) {
3295 TRACE("size=%d\n", bufsize);
3296 safe_buffer_length_increment(pStubMsg, bufsize);
3298 else
3299 pStubMsg->BufferLength =
3300 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
3301 &uflag, pStubMsg->BufferLength, pMemory);
3303 if (saved_buffer_length)
3305 pStubMsg->PointerLength = pStubMsg->BufferLength;
3306 pStubMsg->BufferLength = saved_buffer_length;
3311 /***********************************************************************
3312 * NdrUserMarshalMemorySize [RPCRT4.@]
3314 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3315 PFORMAT_STRING pFormat)
3317 unsigned flags = pFormat[1];
3318 unsigned index = *(const WORD*)&pFormat[2];
3319 DWORD memsize = *(const WORD*)&pFormat[4];
3320 DWORD bufsize = *(const WORD*)&pFormat[6];
3322 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3323 TRACE("index=%d\n", index);
3325 pStubMsg->MemorySize += memsize;
3327 if (flags & USER_MARSHAL_POINTER)
3329 ALIGN_POINTER(pStubMsg->Buffer, 4);
3330 /* skip pointer prefix */
3331 pStubMsg->Buffer += 4;
3332 if (pStubMsg->IgnoreEmbeddedPointers)
3333 return pStubMsg->MemorySize;
3334 ALIGN_POINTER(pStubMsg->Buffer, 8);
3336 else
3337 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3339 if (!bufsize)
3340 FIXME("not implemented for varying buffer size\n");
3342 pStubMsg->Buffer += bufsize;
3344 return pStubMsg->MemorySize;
3347 /***********************************************************************
3348 * NdrUserMarshalFree [RPCRT4.@]
3350 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
3351 unsigned char *pMemory,
3352 PFORMAT_STRING pFormat)
3354 /* unsigned flags = pFormat[1]; */
3355 unsigned index = *(const WORD*)&pFormat[2];
3356 ULONG uflag = UserMarshalFlags(pStubMsg);
3357 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3358 TRACE("index=%d\n", index);
3360 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
3361 &uflag, pMemory);
3364 /***********************************************************************
3365 * NdrClearOutParameters [RPCRT4.@]
3367 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
3368 PFORMAT_STRING pFormat,
3369 void *ArgAddr)
3371 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
3374 /***********************************************************************
3375 * NdrConvert [RPCRT4.@]
3377 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
3379 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
3380 /* FIXME: since this stub doesn't do any converting, the proper behavior
3381 is to raise an exception */
3384 /***********************************************************************
3385 * NdrConvert2 [RPCRT4.@]
3387 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
3389 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3390 pStubMsg, pFormat, NumberParams);
3391 /* FIXME: since this stub doesn't do any converting, the proper behavior
3392 is to raise an exception */
3395 #include "pshpack1.h"
3396 typedef struct _NDR_CSTRUCT_FORMAT
3398 unsigned char type;
3399 unsigned char alignment;
3400 unsigned short memory_size;
3401 short offset_to_array_description;
3402 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
3403 #include "poppack.h"
3405 /***********************************************************************
3406 * NdrConformantStructMarshall [RPCRT4.@]
3408 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3409 unsigned char *pMemory,
3410 PFORMAT_STRING pFormat)
3412 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3413 PFORMAT_STRING pCArrayFormat;
3414 ULONG esize, bufsize;
3416 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3418 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3419 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3421 ERR("invalid format type %x\n", pCStructFormat->type);
3422 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3423 return NULL;
3426 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3427 pCStructFormat->offset_to_array_description;
3428 if (*pCArrayFormat != RPC_FC_CARRAY)
3430 ERR("invalid array format type %x\n", pCStructFormat->type);
3431 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3432 return NULL;
3434 esize = *(const WORD*)(pCArrayFormat+2);
3436 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3437 pCArrayFormat + 4, 0);
3439 WriteConformance(pStubMsg);
3441 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3443 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3445 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3446 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3448 ERR("integer overflow of memory_size %u with bufsize %u\n",
3449 pCStructFormat->memory_size, bufsize);
3450 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3452 /* copy constant sized part of struct */
3453 pStubMsg->BufferMark = pStubMsg->Buffer;
3454 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
3456 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3457 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3459 return NULL;
3462 /***********************************************************************
3463 * NdrConformantStructUnmarshall [RPCRT4.@]
3465 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3466 unsigned char **ppMemory,
3467 PFORMAT_STRING pFormat,
3468 unsigned char fMustAlloc)
3470 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3471 PFORMAT_STRING pCArrayFormat;
3472 ULONG esize, bufsize;
3474 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3476 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3477 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3479 ERR("invalid format type %x\n", pCStructFormat->type);
3480 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3481 return NULL;
3483 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3484 pCStructFormat->offset_to_array_description;
3485 if (*pCArrayFormat != RPC_FC_CARRAY)
3487 ERR("invalid array format type %x\n", pCStructFormat->type);
3488 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3489 return NULL;
3491 esize = *(const WORD*)(pCArrayFormat+2);
3493 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3495 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3497 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3499 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3500 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3502 ERR("integer overflow of memory_size %u with bufsize %u\n",
3503 pCStructFormat->memory_size, bufsize);
3504 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3506 /* work out how much memory to allocate if we need to do so */
3507 if (!*ppMemory || fMustAlloc)
3509 SIZE_T size = pCStructFormat->memory_size + bufsize;
3510 *ppMemory = NdrAllocate(pStubMsg, size);
3513 /* now copy the data */
3514 pStubMsg->BufferMark = pStubMsg->Buffer;
3515 safe_copy_from_buffer(pStubMsg, *ppMemory, pCStructFormat->memory_size + bufsize);
3517 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3518 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
3520 return NULL;
3523 /***********************************************************************
3524 * NdrConformantStructBufferSize [RPCRT4.@]
3526 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3527 unsigned char *pMemory,
3528 PFORMAT_STRING pFormat)
3530 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3531 PFORMAT_STRING pCArrayFormat;
3532 ULONG esize;
3534 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3536 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3537 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3539 ERR("invalid format type %x\n", pCStructFormat->type);
3540 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3541 return;
3543 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3544 pCStructFormat->offset_to_array_description;
3545 if (*pCArrayFormat != RPC_FC_CARRAY)
3547 ERR("invalid array format type %x\n", pCStructFormat->type);
3548 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3549 return;
3551 esize = *(const WORD*)(pCArrayFormat+2);
3553 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
3554 SizeConformance(pStubMsg);
3556 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
3558 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3560 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
3561 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
3563 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3564 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3567 /***********************************************************************
3568 * NdrConformantStructMemorySize [RPCRT4.@]
3570 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3571 PFORMAT_STRING pFormat)
3573 FIXME("stub\n");
3574 return 0;
3577 /***********************************************************************
3578 * NdrConformantStructFree [RPCRT4.@]
3580 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3581 unsigned char *pMemory,
3582 PFORMAT_STRING pFormat)
3584 FIXME("stub\n");
3587 /***********************************************************************
3588 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3590 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3591 unsigned char *pMemory,
3592 PFORMAT_STRING pFormat)
3594 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3595 PFORMAT_STRING pCVArrayFormat;
3596 ULONG esize, bufsize;
3598 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3600 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3601 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3603 ERR("invalid format type %x\n", pCVStructFormat->type);
3604 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3605 return NULL;
3608 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3609 pCVStructFormat->offset_to_array_description;
3610 switch (*pCVArrayFormat)
3612 case RPC_FC_CVARRAY:
3613 esize = *(const WORD*)(pCVArrayFormat+2);
3615 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3616 pCVArrayFormat + 4, 0);
3617 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3618 pCVArrayFormat, 0);
3619 break;
3620 case RPC_FC_C_CSTRING:
3621 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3622 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3623 esize = sizeof(char);
3624 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3625 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3626 pCVArrayFormat + 2, 0);
3627 else
3628 pStubMsg->MaxCount = pStubMsg->ActualCount;
3629 break;
3630 case RPC_FC_C_WSTRING:
3631 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3632 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3633 esize = sizeof(WCHAR);
3634 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3635 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3636 pCVArrayFormat + 2, 0);
3637 else
3638 pStubMsg->MaxCount = pStubMsg->ActualCount;
3639 break;
3640 default:
3641 ERR("invalid array format type %x\n", *pCVArrayFormat);
3642 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3643 return NULL;
3646 WriteConformance(pStubMsg);
3648 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3650 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3652 /* write constant sized part */
3653 pStubMsg->BufferMark = pStubMsg->Buffer;
3654 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
3656 WriteVariance(pStubMsg);
3658 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3660 /* write array part */
3661 safe_copy_to_buffer(pStubMsg, pMemory + pCVStructFormat->memory_size, bufsize);
3663 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3665 return NULL;
3668 /***********************************************************************
3669 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3671 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3672 unsigned char **ppMemory,
3673 PFORMAT_STRING pFormat,
3674 unsigned char fMustAlloc)
3676 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3677 PFORMAT_STRING pCVArrayFormat;
3678 ULONG esize, bufsize;
3679 unsigned char cvarray_type;
3681 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3683 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3684 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3686 ERR("invalid format type %x\n", pCVStructFormat->type);
3687 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3688 return NULL;
3691 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3692 pCVStructFormat->offset_to_array_description;
3693 cvarray_type = *pCVArrayFormat;
3694 switch (cvarray_type)
3696 case RPC_FC_CVARRAY:
3697 esize = *(const WORD*)(pCVArrayFormat+2);
3698 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3699 break;
3700 case RPC_FC_C_CSTRING:
3701 esize = sizeof(char);
3702 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3703 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3704 else
3705 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3706 break;
3707 case RPC_FC_C_WSTRING:
3708 esize = sizeof(WCHAR);
3709 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3710 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3711 else
3712 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3713 break;
3714 default:
3715 ERR("invalid array format type %x\n", *pCVArrayFormat);
3716 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3717 return NULL;
3720 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3722 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3724 /* work out how much memory to allocate if we need to do so */
3725 if (!*ppMemory || fMustAlloc)
3727 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3728 *ppMemory = NdrAllocate(pStubMsg, size);
3731 /* copy the constant data */
3732 pStubMsg->BufferMark = pStubMsg->Buffer;
3733 safe_copy_from_buffer(pStubMsg, *ppMemory, pCVStructFormat->memory_size);
3735 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3737 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3739 if ((cvarray_type == RPC_FC_C_CSTRING) ||
3740 (cvarray_type == RPC_FC_C_WSTRING))
3742 ULONG i;
3743 /* strings must always have null terminating bytes */
3744 if (bufsize < esize)
3746 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
3747 RpcRaiseException(RPC_S_INVALID_BOUND);
3748 return NULL;
3750 for (i = bufsize - esize; i < bufsize; i++)
3751 if (pStubMsg->Buffer[i] != 0)
3753 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3754 i, pStubMsg->Buffer[i]);
3755 RpcRaiseException(RPC_S_INVALID_BOUND);
3756 return NULL;
3760 /* copy the array data */
3761 safe_copy_from_buffer(pStubMsg, *ppMemory + pCVStructFormat->memory_size, bufsize);
3763 if (cvarray_type == RPC_FC_C_CSTRING)
3764 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3765 else if (cvarray_type == RPC_FC_C_WSTRING)
3766 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3768 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
3770 return NULL;
3773 /***********************************************************************
3774 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3776 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3777 unsigned char *pMemory,
3778 PFORMAT_STRING pFormat)
3780 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3781 PFORMAT_STRING pCVArrayFormat;
3782 ULONG esize;
3784 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3786 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3787 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3789 ERR("invalid format type %x\n", pCVStructFormat->type);
3790 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3791 return;
3794 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3795 pCVStructFormat->offset_to_array_description;
3796 switch (*pCVArrayFormat)
3798 case RPC_FC_CVARRAY:
3799 esize = *(const WORD*)(pCVArrayFormat+2);
3801 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3802 pCVArrayFormat + 4, 0);
3803 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3804 pCVArrayFormat, 0);
3805 break;
3806 case RPC_FC_C_CSTRING:
3807 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3808 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3809 esize = sizeof(char);
3810 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3811 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3812 pCVArrayFormat + 2, 0);
3813 else
3814 pStubMsg->MaxCount = pStubMsg->ActualCount;
3815 break;
3816 case RPC_FC_C_WSTRING:
3817 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3818 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3819 esize = sizeof(WCHAR);
3820 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3821 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3822 pCVArrayFormat + 2, 0);
3823 else
3824 pStubMsg->MaxCount = pStubMsg->ActualCount;
3825 break;
3826 default:
3827 ERR("invalid array format type %x\n", *pCVArrayFormat);
3828 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3829 return;
3832 SizeConformance(pStubMsg);
3834 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
3836 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3838 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
3839 SizeVariance(pStubMsg);
3840 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
3842 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3845 /***********************************************************************
3846 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3848 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3849 PFORMAT_STRING pFormat)
3851 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3852 PFORMAT_STRING pCVArrayFormat;
3853 ULONG esize;
3854 unsigned char cvarray_type;
3856 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3858 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3859 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3861 ERR("invalid format type %x\n", pCVStructFormat->type);
3862 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3863 return 0;
3866 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3867 pCVStructFormat->offset_to_array_description;
3868 cvarray_type = *pCVArrayFormat;
3869 switch (cvarray_type)
3871 case RPC_FC_CVARRAY:
3872 esize = *(const WORD*)(pCVArrayFormat+2);
3873 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3874 break;
3875 case RPC_FC_C_CSTRING:
3876 esize = sizeof(char);
3877 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3878 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3879 else
3880 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3881 break;
3882 case RPC_FC_C_WSTRING:
3883 esize = sizeof(WCHAR);
3884 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3885 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3886 else
3887 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3888 break;
3889 default:
3890 ERR("invalid array format type %x\n", *pCVArrayFormat);
3891 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3892 return 0;
3895 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3897 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3899 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
3900 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3901 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
3903 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3905 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3907 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3910 /***********************************************************************
3911 * NdrConformantVaryingStructFree [RPCRT4.@]
3913 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3914 unsigned char *pMemory,
3915 PFORMAT_STRING pFormat)
3917 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3918 PFORMAT_STRING pCVArrayFormat;
3919 ULONG esize;
3921 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3923 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3924 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3926 ERR("invalid format type %x\n", pCVStructFormat->type);
3927 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3928 return;
3931 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3932 pCVStructFormat->offset_to_array_description;
3933 switch (*pCVArrayFormat)
3935 case RPC_FC_CVARRAY:
3936 esize = *(const WORD*)(pCVArrayFormat+2);
3938 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3939 pCVArrayFormat + 4, 0);
3940 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3941 pCVArrayFormat, 0);
3942 break;
3943 case RPC_FC_C_CSTRING:
3944 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3945 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3946 esize = sizeof(char);
3947 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3948 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3949 pCVArrayFormat + 2, 0);
3950 else
3951 pStubMsg->MaxCount = pStubMsg->ActualCount;
3952 break;
3953 case RPC_FC_C_WSTRING:
3954 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3955 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3956 esize = sizeof(WCHAR);
3957 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3958 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3959 pCVArrayFormat + 2, 0);
3960 else
3961 pStubMsg->MaxCount = pStubMsg->ActualCount;
3962 break;
3963 default:
3964 ERR("invalid array format type %x\n", *pCVArrayFormat);
3965 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3966 return;
3969 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3971 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3974 #include "pshpack1.h"
3975 typedef struct
3977 unsigned char type;
3978 unsigned char alignment;
3979 unsigned short total_size;
3980 } NDR_SMFARRAY_FORMAT;
3982 typedef struct
3984 unsigned char type;
3985 unsigned char alignment;
3986 unsigned long total_size;
3987 } NDR_LGFARRAY_FORMAT;
3988 #include "poppack.h"
3990 /***********************************************************************
3991 * NdrFixedArrayMarshall [RPCRT4.@]
3993 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3994 unsigned char *pMemory,
3995 PFORMAT_STRING pFormat)
3997 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3998 unsigned long total_size;
4000 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4002 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4003 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4005 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4006 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4007 return NULL;
4010 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4012 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4014 total_size = pSmFArrayFormat->total_size;
4015 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4017 else
4019 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4020 total_size = pLgFArrayFormat->total_size;
4021 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4024 pStubMsg->BufferMark = pStubMsg->Buffer;
4025 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4027 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4029 return NULL;
4032 /***********************************************************************
4033 * NdrFixedArrayUnmarshall [RPCRT4.@]
4035 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4036 unsigned char **ppMemory,
4037 PFORMAT_STRING pFormat,
4038 unsigned char fMustAlloc)
4040 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4041 unsigned long total_size;
4043 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4045 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4046 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4048 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4049 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4050 return NULL;
4053 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4055 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4057 total_size = pSmFArrayFormat->total_size;
4058 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4060 else
4062 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4063 total_size = pLgFArrayFormat->total_size;
4064 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4067 if (fMustAlloc || !*ppMemory)
4068 *ppMemory = NdrAllocate(pStubMsg, total_size);
4069 pStubMsg->BufferMark = pStubMsg->Buffer;
4070 safe_copy_from_buffer(pStubMsg, *ppMemory, total_size);
4072 pFormat = EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
4074 return NULL;
4077 /***********************************************************************
4078 * NdrFixedArrayBufferSize [RPCRT4.@]
4080 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4081 unsigned char *pMemory,
4082 PFORMAT_STRING pFormat)
4084 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4085 unsigned long total_size;
4087 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4089 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4090 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4092 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4093 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4094 return;
4097 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4099 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4101 total_size = pSmFArrayFormat->total_size;
4102 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4104 else
4106 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4107 total_size = pLgFArrayFormat->total_size;
4108 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4110 safe_buffer_length_increment(pStubMsg, total_size);
4112 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4115 /***********************************************************************
4116 * NdrFixedArrayMemorySize [RPCRT4.@]
4118 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4119 PFORMAT_STRING pFormat)
4121 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4122 ULONG total_size;
4124 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4126 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4127 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4129 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4130 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4131 return 0;
4134 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4136 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4138 total_size = pSmFArrayFormat->total_size;
4139 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4141 else
4143 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4144 total_size = pLgFArrayFormat->total_size;
4145 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4147 pStubMsg->BufferMark = pStubMsg->Buffer;
4148 safe_buffer_increment(pStubMsg, total_size);
4149 pStubMsg->MemorySize += total_size;
4151 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4153 return total_size;
4156 /***********************************************************************
4157 * NdrFixedArrayFree [RPCRT4.@]
4159 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4160 unsigned char *pMemory,
4161 PFORMAT_STRING pFormat)
4163 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4165 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4167 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4168 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4170 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4171 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4172 return;
4175 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4176 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4177 else
4179 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4180 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4183 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4186 /***********************************************************************
4187 * NdrVaryingArrayMarshall [RPCRT4.@]
4189 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4190 unsigned char *pMemory,
4191 PFORMAT_STRING pFormat)
4193 unsigned char alignment;
4194 DWORD elements, esize;
4195 ULONG bufsize;
4197 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4199 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4200 (pFormat[0] != RPC_FC_LGVARRAY))
4202 ERR("invalid format type %x\n", pFormat[0]);
4203 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4204 return NULL;
4207 alignment = pFormat[1] + 1;
4209 if (pFormat[0] == RPC_FC_SMVARRAY)
4211 pFormat += 2;
4212 pFormat += sizeof(WORD);
4213 elements = *(const WORD*)pFormat;
4214 pFormat += sizeof(WORD);
4216 else
4218 pFormat += 2;
4219 pFormat += sizeof(DWORD);
4220 elements = *(const DWORD*)pFormat;
4221 pFormat += sizeof(DWORD);
4224 esize = *(const WORD*)pFormat;
4225 pFormat += sizeof(WORD);
4227 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4228 if ((pStubMsg->ActualCount > elements) ||
4229 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4231 RpcRaiseException(RPC_S_INVALID_BOUND);
4232 return NULL;
4235 WriteVariance(pStubMsg);
4237 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4239 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4240 pStubMsg->BufferMark = pStubMsg->Buffer;
4241 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
4243 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4245 return NULL;
4248 /***********************************************************************
4249 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4251 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4252 unsigned char **ppMemory,
4253 PFORMAT_STRING pFormat,
4254 unsigned char fMustAlloc)
4256 unsigned char alignment;
4257 DWORD size, elements, esize;
4258 ULONG bufsize;
4260 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4262 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4263 (pFormat[0] != RPC_FC_LGVARRAY))
4265 ERR("invalid format type %x\n", pFormat[0]);
4266 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4267 return NULL;
4270 alignment = pFormat[1] + 1;
4272 if (pFormat[0] == RPC_FC_SMVARRAY)
4274 pFormat += 2;
4275 size = *(const WORD*)pFormat;
4276 pFormat += sizeof(WORD);
4277 elements = *(const WORD*)pFormat;
4278 pFormat += sizeof(WORD);
4280 else
4282 pFormat += 2;
4283 size = *(const DWORD*)pFormat;
4284 pFormat += sizeof(DWORD);
4285 elements = *(const DWORD*)pFormat;
4286 pFormat += sizeof(DWORD);
4289 esize = *(const WORD*)pFormat;
4290 pFormat += sizeof(WORD);
4292 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4294 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4296 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4298 if (!*ppMemory || fMustAlloc)
4299 *ppMemory = NdrAllocate(pStubMsg, size);
4300 safe_copy_from_buffer(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize);
4302 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
4304 return NULL;
4307 /***********************************************************************
4308 * NdrVaryingArrayBufferSize [RPCRT4.@]
4310 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4311 unsigned char *pMemory,
4312 PFORMAT_STRING pFormat)
4314 unsigned char alignment;
4315 DWORD elements, esize;
4317 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4319 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4320 (pFormat[0] != RPC_FC_LGVARRAY))
4322 ERR("invalid format type %x\n", pFormat[0]);
4323 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4324 return;
4327 alignment = pFormat[1] + 1;
4329 if (pFormat[0] == RPC_FC_SMVARRAY)
4331 pFormat += 2;
4332 pFormat += sizeof(WORD);
4333 elements = *(const WORD*)pFormat;
4334 pFormat += sizeof(WORD);
4336 else
4338 pFormat += 2;
4339 pFormat += sizeof(DWORD);
4340 elements = *(const DWORD*)pFormat;
4341 pFormat += sizeof(DWORD);
4344 esize = *(const WORD*)pFormat;
4345 pFormat += sizeof(WORD);
4347 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4348 if ((pStubMsg->ActualCount > elements) ||
4349 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4351 RpcRaiseException(RPC_S_INVALID_BOUND);
4352 return;
4355 SizeVariance(pStubMsg);
4357 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4359 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4361 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4364 /***********************************************************************
4365 * NdrVaryingArrayMemorySize [RPCRT4.@]
4367 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4368 PFORMAT_STRING pFormat)
4370 unsigned char alignment;
4371 DWORD size, elements, esize;
4373 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4375 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4376 (pFormat[0] != RPC_FC_LGVARRAY))
4378 ERR("invalid format type %x\n", pFormat[0]);
4379 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4380 return 0;
4383 alignment = pFormat[1] + 1;
4385 if (pFormat[0] == RPC_FC_SMVARRAY)
4387 pFormat += 2;
4388 size = *(const WORD*)pFormat;
4389 pFormat += sizeof(WORD);
4390 elements = *(const WORD*)pFormat;
4391 pFormat += sizeof(WORD);
4393 else
4395 pFormat += 2;
4396 size = *(const DWORD*)pFormat;
4397 pFormat += sizeof(DWORD);
4398 elements = *(const DWORD*)pFormat;
4399 pFormat += sizeof(DWORD);
4402 esize = *(const WORD*)pFormat;
4403 pFormat += sizeof(WORD);
4405 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4407 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4409 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4410 pStubMsg->MemorySize += size;
4412 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4414 return pStubMsg->MemorySize;
4417 /***********************************************************************
4418 * NdrVaryingArrayFree [RPCRT4.@]
4420 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4421 unsigned char *pMemory,
4422 PFORMAT_STRING pFormat)
4424 unsigned char alignment;
4425 DWORD elements;
4427 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4429 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4430 (pFormat[0] != RPC_FC_LGVARRAY))
4432 ERR("invalid format type %x\n", pFormat[0]);
4433 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4434 return;
4437 alignment = pFormat[1] + 1;
4439 if (pFormat[0] == RPC_FC_SMVARRAY)
4441 pFormat += 2;
4442 pFormat += sizeof(WORD);
4443 elements = *(const WORD*)pFormat;
4444 pFormat += sizeof(WORD);
4446 else
4448 pFormat += 2;
4449 pFormat += sizeof(DWORD);
4450 elements = *(const DWORD*)pFormat;
4451 pFormat += sizeof(DWORD);
4454 pFormat += sizeof(WORD);
4456 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4457 if ((pStubMsg->ActualCount > elements) ||
4458 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4460 RpcRaiseException(RPC_S_INVALID_BOUND);
4461 return;
4464 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4467 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
4469 switch (fc)
4471 case RPC_FC_BYTE:
4472 case RPC_FC_CHAR:
4473 case RPC_FC_SMALL:
4474 case RPC_FC_USMALL:
4475 return *(const UCHAR *)pMemory;
4476 case RPC_FC_WCHAR:
4477 case RPC_FC_SHORT:
4478 case RPC_FC_USHORT:
4479 case RPC_FC_ENUM16:
4480 return *(const USHORT *)pMemory;
4481 case RPC_FC_LONG:
4482 case RPC_FC_ULONG:
4483 case RPC_FC_ENUM32:
4484 return *(const ULONG *)pMemory;
4485 default:
4486 FIXME("Unhandled base type: 0x%02x\n", fc);
4487 return 0;
4491 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4492 unsigned long discriminant,
4493 PFORMAT_STRING pFormat)
4495 unsigned short num_arms, arm, type;
4497 num_arms = *(const SHORT*)pFormat & 0x0fff;
4498 pFormat += 2;
4499 for(arm = 0; arm < num_arms; arm++)
4501 if(discriminant == *(const ULONG*)pFormat)
4503 pFormat += 4;
4504 break;
4506 pFormat += 6;
4509 type = *(const unsigned short*)pFormat;
4510 TRACE("type %04x\n", type);
4511 if(arm == num_arms) /* default arm extras */
4513 if(type == 0xffff)
4515 ERR("no arm for 0x%lx and no default case\n", discriminant);
4516 RpcRaiseException(RPC_S_INVALID_TAG);
4517 return NULL;
4519 if(type == 0)
4521 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
4522 return NULL;
4525 return pFormat;
4528 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
4530 unsigned short type;
4532 pFormat += 2;
4534 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4535 if(!pFormat)
4536 return NULL;
4538 type = *(const unsigned short*)pFormat;
4539 if((type & 0xff00) == 0x8000)
4541 unsigned char basetype = LOBYTE(type);
4542 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
4544 else
4546 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4547 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
4548 if (m)
4550 unsigned char *saved_buffer = NULL;
4551 int pointer_buffer_mark_set = 0;
4552 switch(*desc)
4554 case RPC_FC_RP:
4555 case RPC_FC_UP:
4556 case RPC_FC_OP:
4557 case RPC_FC_FP:
4558 ALIGN_POINTER(pStubMsg->Buffer, 4);
4559 saved_buffer = pStubMsg->Buffer;
4560 if (pStubMsg->PointerBufferMark)
4562 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4563 pStubMsg->PointerBufferMark = NULL;
4564 pointer_buffer_mark_set = 1;
4566 else
4567 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
4569 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
4570 if (pointer_buffer_mark_set)
4572 STD_OVERFLOW_CHECK(pStubMsg);
4573 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4574 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
4576 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4577 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
4578 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4580 pStubMsg->Buffer = saved_buffer + 4;
4582 break;
4583 default:
4584 m(pStubMsg, pMemory, desc);
4587 else FIXME("no marshaller for embedded type %02x\n", *desc);
4589 return NULL;
4592 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4593 unsigned char **ppMemory,
4594 ULONG discriminant,
4595 PFORMAT_STRING pFormat,
4596 unsigned char fMustAlloc)
4598 unsigned short type;
4600 pFormat += 2;
4602 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4603 if(!pFormat)
4604 return NULL;
4606 type = *(const unsigned short*)pFormat;
4607 if((type & 0xff00) == 0x8000)
4609 unsigned char basetype = LOBYTE(type);
4610 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
4612 else
4614 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4615 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
4616 if (m)
4618 unsigned char *saved_buffer = NULL;
4619 int pointer_buffer_mark_set = 0;
4620 switch(*desc)
4622 case RPC_FC_RP:
4623 case RPC_FC_UP:
4624 case RPC_FC_OP:
4625 case RPC_FC_FP:
4626 **(void***)ppMemory = NULL;
4627 ALIGN_POINTER(pStubMsg->Buffer, 4);
4628 saved_buffer = pStubMsg->Buffer;
4629 if (pStubMsg->PointerBufferMark)
4631 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4632 pStubMsg->PointerBufferMark = NULL;
4633 pointer_buffer_mark_set = 1;
4635 else
4636 pStubMsg->Buffer += 4; /* for pointer ID */
4638 if (saved_buffer + 4 > pStubMsg->BufferEnd)
4640 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4641 saved_buffer, pStubMsg->BufferEnd);
4642 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4645 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
4646 if (pointer_buffer_mark_set)
4648 STD_OVERFLOW_CHECK(pStubMsg);
4649 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4650 pStubMsg->Buffer = saved_buffer + 4;
4652 break;
4653 default:
4654 m(pStubMsg, ppMemory, desc, fMustAlloc);
4657 else FIXME("no marshaller for embedded type %02x\n", *desc);
4659 return NULL;
4662 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
4663 unsigned char *pMemory,
4664 ULONG discriminant,
4665 PFORMAT_STRING pFormat)
4667 unsigned short type;
4669 pFormat += 2;
4671 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4672 if(!pFormat)
4673 return;
4675 type = *(const unsigned short*)pFormat;
4676 if((type & 0xff00) == 0x8000)
4678 unsigned char basetype = LOBYTE(type);
4679 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
4681 else
4683 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4684 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
4685 if (m)
4687 switch(*desc)
4689 case RPC_FC_RP:
4690 case RPC_FC_UP:
4691 case RPC_FC_OP:
4692 case RPC_FC_FP:
4693 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4694 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
4695 if (!pStubMsg->IgnoreEmbeddedPointers)
4697 int saved_buffer_length = pStubMsg->BufferLength;
4698 pStubMsg->BufferLength = pStubMsg->PointerLength;
4699 pStubMsg->PointerLength = 0;
4700 if(!pStubMsg->BufferLength)
4701 ERR("BufferLength == 0??\n");
4702 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
4703 pStubMsg->PointerLength = pStubMsg->BufferLength;
4704 pStubMsg->BufferLength = saved_buffer_length;
4706 break;
4707 default:
4708 m(pStubMsg, pMemory, desc);
4711 else FIXME("no buffersizer for embedded type %02x\n", *desc);
4715 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
4716 ULONG discriminant,
4717 PFORMAT_STRING pFormat)
4719 unsigned short type, size;
4721 size = *(const unsigned short*)pFormat;
4722 pStubMsg->Memory += size;
4723 pFormat += 2;
4725 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4726 if(!pFormat)
4727 return 0;
4729 type = *(const unsigned short*)pFormat;
4730 if((type & 0xff00) == 0x8000)
4732 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
4734 else
4736 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4737 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
4738 unsigned char *saved_buffer;
4739 if (m)
4741 switch(*desc)
4743 case RPC_FC_RP:
4744 case RPC_FC_UP:
4745 case RPC_FC_OP:
4746 case RPC_FC_FP:
4747 ALIGN_POINTER(pStubMsg->Buffer, 4);
4748 saved_buffer = pStubMsg->Buffer;
4749 safe_buffer_increment(pStubMsg, 4);
4750 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
4751 pStubMsg->MemorySize += 4;
4752 if (!pStubMsg->IgnoreEmbeddedPointers)
4753 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
4754 break;
4755 default:
4756 return m(pStubMsg, desc);
4759 else FIXME("no marshaller for embedded type %02x\n", *desc);
4762 TRACE("size %d\n", size);
4763 return size;
4766 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
4767 unsigned char *pMemory,
4768 ULONG discriminant,
4769 PFORMAT_STRING pFormat)
4771 unsigned short type;
4773 pFormat += 2;
4775 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4776 if(!pFormat)
4777 return;
4779 type = *(const unsigned short*)pFormat;
4780 if((type & 0xff00) != 0x8000)
4782 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4783 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
4784 if (m)
4786 switch(*desc)
4788 case RPC_FC_RP:
4789 case RPC_FC_UP:
4790 case RPC_FC_OP:
4791 case RPC_FC_FP:
4792 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
4793 break;
4794 default:
4795 m(pStubMsg, pMemory, desc);
4798 else FIXME("no freer for embedded type %02x\n", *desc);
4802 /***********************************************************************
4803 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4805 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4806 unsigned char *pMemory,
4807 PFORMAT_STRING pFormat)
4809 unsigned char switch_type;
4810 unsigned char increment;
4811 ULONG switch_value;
4813 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4814 pFormat++;
4816 switch_type = *pFormat & 0xf;
4817 increment = (*pFormat & 0xf0) >> 4;
4818 pFormat++;
4820 ALIGN_POINTER(pStubMsg->Buffer, increment);
4822 switch_value = get_discriminant(switch_type, pMemory);
4823 TRACE("got switch value 0x%x\n", switch_value);
4825 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
4826 pMemory += increment;
4828 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
4831 /***********************************************************************
4832 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4834 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4835 unsigned char **ppMemory,
4836 PFORMAT_STRING pFormat,
4837 unsigned char fMustAlloc)
4839 unsigned char switch_type;
4840 unsigned char increment;
4841 ULONG switch_value;
4842 unsigned short size;
4843 unsigned char *pMemoryArm;
4845 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4846 pFormat++;
4848 switch_type = *pFormat & 0xf;
4849 increment = (*pFormat & 0xf0) >> 4;
4850 pFormat++;
4852 ALIGN_POINTER(pStubMsg->Buffer, increment);
4853 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
4854 TRACE("got switch value 0x%x\n", switch_value);
4856 size = *(const unsigned short*)pFormat + increment;
4857 if(!*ppMemory || fMustAlloc)
4858 *ppMemory = NdrAllocate(pStubMsg, size);
4860 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
4861 pMemoryArm = *ppMemory + increment;
4863 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
4866 /***********************************************************************
4867 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4869 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4870 unsigned char *pMemory,
4871 PFORMAT_STRING pFormat)
4873 unsigned char switch_type;
4874 unsigned char increment;
4875 ULONG switch_value;
4877 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4878 pFormat++;
4880 switch_type = *pFormat & 0xf;
4881 increment = (*pFormat & 0xf0) >> 4;
4882 pFormat++;
4884 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
4885 switch_value = get_discriminant(switch_type, pMemory);
4886 TRACE("got switch value 0x%x\n", switch_value);
4888 /* Add discriminant size */
4889 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
4890 pMemory += increment;
4892 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
4895 /***********************************************************************
4896 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4898 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4899 PFORMAT_STRING pFormat)
4901 unsigned char switch_type;
4902 unsigned char increment;
4903 ULONG switch_value;
4905 switch_type = *pFormat & 0xf;
4906 increment = (*pFormat & 0xf0) >> 4;
4907 pFormat++;
4909 ALIGN_POINTER(pStubMsg->Buffer, increment);
4910 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
4911 TRACE("got switch value 0x%x\n", switch_value);
4913 pStubMsg->Memory += increment;
4915 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
4918 /***********************************************************************
4919 * NdrEncapsulatedUnionFree [RPCRT4.@]
4921 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4922 unsigned char *pMemory,
4923 PFORMAT_STRING pFormat)
4925 unsigned char switch_type;
4926 unsigned char increment;
4927 ULONG switch_value;
4929 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4930 pFormat++;
4932 switch_type = *pFormat & 0xf;
4933 increment = (*pFormat & 0xf0) >> 4;
4934 pFormat++;
4936 switch_value = get_discriminant(switch_type, pMemory);
4937 TRACE("got switch value 0x%x\n", switch_value);
4939 pMemory += increment;
4941 return union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
4944 /***********************************************************************
4945 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
4947 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4948 unsigned char *pMemory,
4949 PFORMAT_STRING pFormat)
4951 unsigned char switch_type;
4953 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4954 pFormat++;
4956 switch_type = *pFormat;
4957 pFormat++;
4959 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4960 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4961 /* Marshall discriminant */
4962 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4964 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
4967 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
4968 PFORMAT_STRING *ppFormat)
4970 long discriminant = 0;
4972 switch(**ppFormat)
4974 case RPC_FC_BYTE:
4975 case RPC_FC_CHAR:
4976 case RPC_FC_SMALL:
4977 case RPC_FC_USMALL:
4979 UCHAR d;
4980 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
4981 discriminant = d;
4982 break;
4984 case RPC_FC_WCHAR:
4985 case RPC_FC_SHORT:
4986 case RPC_FC_USHORT:
4988 USHORT d;
4989 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4990 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
4991 discriminant = d;
4992 break;
4994 case RPC_FC_LONG:
4995 case RPC_FC_ULONG:
4997 ULONG d;
4998 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4999 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5000 discriminant = d;
5001 break;
5003 default:
5004 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5006 (*ppFormat)++;
5008 if (pStubMsg->fHasNewCorrDesc)
5009 *ppFormat += 6;
5010 else
5011 *ppFormat += 4;
5012 return discriminant;
5015 /**********************************************************************
5016 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5018 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5019 unsigned char **ppMemory,
5020 PFORMAT_STRING pFormat,
5021 unsigned char fMustAlloc)
5023 long discriminant;
5024 unsigned short size;
5026 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5027 pFormat++;
5029 /* Unmarshall discriminant */
5030 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5031 TRACE("unmarshalled discriminant %lx\n", discriminant);
5033 pFormat += *(const SHORT*)pFormat;
5035 size = *(const unsigned short*)pFormat;
5037 if(!*ppMemory || fMustAlloc)
5038 *ppMemory = NdrAllocate(pStubMsg, size);
5040 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5043 /***********************************************************************
5044 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5046 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5047 unsigned char *pMemory,
5048 PFORMAT_STRING pFormat)
5050 unsigned char switch_type;
5052 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5053 pFormat++;
5055 switch_type = *pFormat;
5056 pFormat++;
5058 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5059 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5060 /* Add discriminant size */
5061 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5063 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5066 /***********************************************************************
5067 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5069 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5070 PFORMAT_STRING pFormat)
5072 ULONG discriminant;
5074 pFormat++;
5075 /* Unmarshall discriminant */
5076 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5077 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
5079 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
5082 /***********************************************************************
5083 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5085 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5086 unsigned char *pMemory,
5087 PFORMAT_STRING pFormat)
5089 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5090 pFormat++;
5091 pFormat++;
5093 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5094 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5096 return union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5099 /***********************************************************************
5100 * NdrByteCountPointerMarshall [RPCRT4.@]
5102 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5103 unsigned char *pMemory,
5104 PFORMAT_STRING pFormat)
5106 FIXME("stub\n");
5107 return NULL;
5110 /***********************************************************************
5111 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5113 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5114 unsigned char **ppMemory,
5115 PFORMAT_STRING pFormat,
5116 unsigned char fMustAlloc)
5118 FIXME("stub\n");
5119 return NULL;
5122 /***********************************************************************
5123 * NdrByteCountPointerBufferSize [RPCRT4.@]
5125 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5126 unsigned char *pMemory,
5127 PFORMAT_STRING pFormat)
5129 FIXME("stub\n");
5132 /***********************************************************************
5133 * NdrByteCountPointerMemorySize [RPCRT4.@]
5135 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5136 PFORMAT_STRING pFormat)
5138 FIXME("stub\n");
5139 return 0;
5142 /***********************************************************************
5143 * NdrByteCountPointerFree [RPCRT4.@]
5145 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
5146 unsigned char *pMemory,
5147 PFORMAT_STRING pFormat)
5149 FIXME("stub\n");
5152 /***********************************************************************
5153 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5155 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5156 unsigned char *pMemory,
5157 PFORMAT_STRING pFormat)
5159 FIXME("stub\n");
5160 return NULL;
5163 /***********************************************************************
5164 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5166 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5167 unsigned char **ppMemory,
5168 PFORMAT_STRING pFormat,
5169 unsigned char fMustAlloc)
5171 FIXME("stub\n");
5172 return NULL;
5175 /***********************************************************************
5176 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5178 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5179 unsigned char *pMemory,
5180 PFORMAT_STRING pFormat)
5182 FIXME("stub\n");
5185 /***********************************************************************
5186 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5188 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5189 PFORMAT_STRING pFormat)
5191 FIXME("stub\n");
5192 return 0;
5195 /***********************************************************************
5196 * NdrXmitOrRepAsFree [RPCRT4.@]
5198 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
5199 unsigned char *pMemory,
5200 PFORMAT_STRING pFormat)
5202 FIXME("stub\n");
5205 #include "pshpack1.h"
5206 typedef struct
5208 unsigned char type;
5209 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
5210 ULONG low_value;
5211 ULONG high_value;
5212 } NDR_RANGE;
5213 #include "poppack.h"
5215 /***********************************************************************
5216 * NdrRangeMarshall [internal]
5218 unsigned char *WINAPI NdrRangeMarshall(
5219 PMIDL_STUB_MESSAGE pStubMsg,
5220 unsigned char *pMemory,
5221 PFORMAT_STRING pFormat)
5223 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5224 unsigned char base_type;
5226 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5228 if (pRange->type != RPC_FC_RANGE)
5230 ERR("invalid format type %x\n", pRange->type);
5231 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5232 return NULL;
5235 base_type = pRange->flags_type & 0xf;
5237 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
5240 /***********************************************************************
5241 * NdrRangeUnmarshall
5243 unsigned char *WINAPI NdrRangeUnmarshall(
5244 PMIDL_STUB_MESSAGE pStubMsg,
5245 unsigned char **ppMemory,
5246 PFORMAT_STRING pFormat,
5247 unsigned char fMustAlloc)
5249 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5250 unsigned char base_type;
5252 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5254 if (pRange->type != RPC_FC_RANGE)
5256 ERR("invalid format type %x\n", pRange->type);
5257 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5258 return NULL;
5260 base_type = pRange->flags_type & 0xf;
5262 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5263 base_type, pRange->low_value, pRange->high_value);
5265 #define RANGE_UNMARSHALL(type, format_spec) \
5266 do \
5268 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5269 if (fMustAlloc || !*ppMemory) \
5270 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5271 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5273 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5274 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5275 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5277 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5278 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5280 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5281 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5282 (type)pRange->high_value); \
5283 RpcRaiseException(RPC_S_INVALID_BOUND); \
5284 return NULL; \
5286 TRACE("*ppMemory: %p\n", *ppMemory); \
5287 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5288 pStubMsg->Buffer += sizeof(type); \
5289 } while (0)
5291 switch(base_type)
5293 case RPC_FC_CHAR:
5294 case RPC_FC_SMALL:
5295 RANGE_UNMARSHALL(UCHAR, "%d");
5296 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5297 break;
5298 case RPC_FC_BYTE:
5299 case RPC_FC_USMALL:
5300 RANGE_UNMARSHALL(CHAR, "%u");
5301 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5302 break;
5303 case RPC_FC_WCHAR: /* FIXME: valid? */
5304 case RPC_FC_USHORT:
5305 RANGE_UNMARSHALL(USHORT, "%u");
5306 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5307 break;
5308 case RPC_FC_SHORT:
5309 RANGE_UNMARSHALL(SHORT, "%d");
5310 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5311 break;
5312 case RPC_FC_LONG:
5313 RANGE_UNMARSHALL(LONG, "%d");
5314 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5315 break;
5316 case RPC_FC_ULONG:
5317 RANGE_UNMARSHALL(ULONG, "%u");
5318 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5319 break;
5320 case RPC_FC_ENUM16:
5321 case RPC_FC_ENUM32:
5322 FIXME("Unhandled enum type\n");
5323 break;
5324 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
5325 case RPC_FC_FLOAT:
5326 case RPC_FC_DOUBLE:
5327 case RPC_FC_HYPER:
5328 default:
5329 ERR("invalid range base type: 0x%02x\n", base_type);
5330 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5333 return NULL;
5336 /***********************************************************************
5337 * NdrRangeBufferSize [internal]
5339 void WINAPI NdrRangeBufferSize(
5340 PMIDL_STUB_MESSAGE pStubMsg,
5341 unsigned char *pMemory,
5342 PFORMAT_STRING pFormat)
5344 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5345 unsigned char base_type;
5347 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5349 if (pRange->type != RPC_FC_RANGE)
5351 ERR("invalid format type %x\n", pRange->type);
5352 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5354 base_type = pRange->flags_type & 0xf;
5356 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
5359 /***********************************************************************
5360 * NdrRangeMemorySize [internal]
5362 ULONG WINAPI NdrRangeMemorySize(
5363 PMIDL_STUB_MESSAGE pStubMsg,
5364 PFORMAT_STRING pFormat)
5366 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5367 unsigned char base_type;
5369 if (pRange->type != RPC_FC_RANGE)
5371 ERR("invalid format type %x\n", pRange->type);
5372 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5373 return 0;
5375 base_type = pRange->flags_type & 0xf;
5377 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
5380 /***********************************************************************
5381 * NdrRangeFree [internal]
5383 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
5384 unsigned char *pMemory,
5385 PFORMAT_STRING pFormat)
5387 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5389 /* nothing to do */
5392 /***********************************************************************
5393 * NdrBaseTypeMarshall [internal]
5395 static unsigned char *WINAPI NdrBaseTypeMarshall(
5396 PMIDL_STUB_MESSAGE pStubMsg,
5397 unsigned char *pMemory,
5398 PFORMAT_STRING pFormat)
5400 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5402 switch(*pFormat)
5404 case RPC_FC_BYTE:
5405 case RPC_FC_CHAR:
5406 case RPC_FC_SMALL:
5407 case RPC_FC_USMALL:
5408 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
5409 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
5410 break;
5411 case RPC_FC_WCHAR:
5412 case RPC_FC_SHORT:
5413 case RPC_FC_USHORT:
5414 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5415 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
5416 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
5417 break;
5418 case RPC_FC_LONG:
5419 case RPC_FC_ULONG:
5420 case RPC_FC_ERROR_STATUS_T:
5421 case RPC_FC_ENUM32:
5422 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5423 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
5424 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
5425 break;
5426 case RPC_FC_FLOAT:
5427 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
5428 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
5429 break;
5430 case RPC_FC_DOUBLE:
5431 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
5432 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
5433 break;
5434 case RPC_FC_HYPER:
5435 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
5436 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
5437 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
5438 break;
5439 case RPC_FC_ENUM16:
5440 /* only 16-bits on the wire, so do a sanity check */
5441 if (*(UINT *)pMemory > SHRT_MAX)
5442 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
5443 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5444 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5445 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5446 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
5447 pStubMsg->Buffer += sizeof(USHORT);
5448 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
5449 break;
5450 case RPC_FC_IGNORE:
5451 break;
5452 default:
5453 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5456 /* FIXME: what is the correct return value? */
5457 return NULL;
5460 /***********************************************************************
5461 * NdrBaseTypeUnmarshall [internal]
5463 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
5464 PMIDL_STUB_MESSAGE pStubMsg,
5465 unsigned char **ppMemory,
5466 PFORMAT_STRING pFormat,
5467 unsigned char fMustAlloc)
5469 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5471 #define BASE_TYPE_UNMARSHALL(type) \
5472 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5473 if (fMustAlloc || !*ppMemory) \
5474 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5475 TRACE("*ppMemory: %p\n", *ppMemory); \
5476 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5477 pStubMsg->Buffer += sizeof(type);
5479 switch(*pFormat)
5481 case RPC_FC_BYTE:
5482 case RPC_FC_CHAR:
5483 case RPC_FC_SMALL:
5484 case RPC_FC_USMALL:
5485 BASE_TYPE_UNMARSHALL(UCHAR);
5486 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5487 break;
5488 case RPC_FC_WCHAR:
5489 case RPC_FC_SHORT:
5490 case RPC_FC_USHORT:
5491 BASE_TYPE_UNMARSHALL(USHORT);
5492 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5493 break;
5494 case RPC_FC_LONG:
5495 case RPC_FC_ULONG:
5496 case RPC_FC_ERROR_STATUS_T:
5497 case RPC_FC_ENUM32:
5498 BASE_TYPE_UNMARSHALL(ULONG);
5499 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5500 break;
5501 case RPC_FC_FLOAT:
5502 BASE_TYPE_UNMARSHALL(float);
5503 TRACE("value: %f\n", **(float **)ppMemory);
5504 break;
5505 case RPC_FC_DOUBLE:
5506 BASE_TYPE_UNMARSHALL(double);
5507 TRACE("value: %f\n", **(double **)ppMemory);
5508 break;
5509 case RPC_FC_HYPER:
5510 BASE_TYPE_UNMARSHALL(ULONGLONG);
5511 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
5512 break;
5513 case RPC_FC_ENUM16:
5514 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5515 if (fMustAlloc || !*ppMemory)
5516 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
5517 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
5518 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5519 TRACE("*ppMemory: %p\n", *ppMemory);
5520 /* 16-bits on the wire, but int in memory */
5521 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
5522 pStubMsg->Buffer += sizeof(USHORT);
5523 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
5524 break;
5525 case RPC_FC_IGNORE:
5526 break;
5527 default:
5528 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5530 #undef BASE_TYPE_UNMARSHALL
5532 /* FIXME: what is the correct return value? */
5534 return NULL;
5537 /***********************************************************************
5538 * NdrBaseTypeBufferSize [internal]
5540 static void WINAPI NdrBaseTypeBufferSize(
5541 PMIDL_STUB_MESSAGE pStubMsg,
5542 unsigned char *pMemory,
5543 PFORMAT_STRING pFormat)
5545 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5547 switch(*pFormat)
5549 case RPC_FC_BYTE:
5550 case RPC_FC_CHAR:
5551 case RPC_FC_SMALL:
5552 case RPC_FC_USMALL:
5553 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
5554 break;
5555 case RPC_FC_WCHAR:
5556 case RPC_FC_SHORT:
5557 case RPC_FC_USHORT:
5558 case RPC_FC_ENUM16:
5559 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
5560 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
5561 break;
5562 case RPC_FC_LONG:
5563 case RPC_FC_ULONG:
5564 case RPC_FC_ENUM32:
5565 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
5566 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
5567 break;
5568 case RPC_FC_FLOAT:
5569 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
5570 safe_buffer_length_increment(pStubMsg, sizeof(float));
5571 break;
5572 case RPC_FC_DOUBLE:
5573 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
5574 safe_buffer_length_increment(pStubMsg, sizeof(double));
5575 break;
5576 case RPC_FC_HYPER:
5577 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
5578 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
5579 break;
5580 case RPC_FC_ERROR_STATUS_T:
5581 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
5582 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
5583 break;
5584 case RPC_FC_IGNORE:
5585 break;
5586 default:
5587 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5591 /***********************************************************************
5592 * NdrBaseTypeMemorySize [internal]
5594 static ULONG WINAPI NdrBaseTypeMemorySize(
5595 PMIDL_STUB_MESSAGE pStubMsg,
5596 PFORMAT_STRING pFormat)
5598 switch(*pFormat)
5600 case RPC_FC_BYTE:
5601 case RPC_FC_CHAR:
5602 case RPC_FC_SMALL:
5603 case RPC_FC_USMALL:
5604 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
5605 pStubMsg->MemorySize += sizeof(UCHAR);
5606 return sizeof(UCHAR);
5607 case RPC_FC_WCHAR:
5608 case RPC_FC_SHORT:
5609 case RPC_FC_USHORT:
5610 safe_buffer_increment(pStubMsg, sizeof(USHORT));
5611 pStubMsg->MemorySize += sizeof(USHORT);
5612 return sizeof(USHORT);
5613 case RPC_FC_LONG:
5614 case RPC_FC_ULONG:
5615 case RPC_FC_ENUM32:
5616 safe_buffer_increment(pStubMsg, sizeof(ULONG));
5617 pStubMsg->MemorySize += sizeof(ULONG);
5618 return sizeof(ULONG);
5619 case RPC_FC_FLOAT:
5620 safe_buffer_increment(pStubMsg, sizeof(float));
5621 pStubMsg->MemorySize += sizeof(float);
5622 return sizeof(float);
5623 case RPC_FC_DOUBLE:
5624 safe_buffer_increment(pStubMsg, sizeof(double));
5625 pStubMsg->MemorySize += sizeof(double);
5626 return sizeof(double);
5627 case RPC_FC_HYPER:
5628 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
5629 pStubMsg->MemorySize += sizeof(ULONGLONG);
5630 return sizeof(ULONGLONG);
5631 case RPC_FC_ERROR_STATUS_T:
5632 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
5633 pStubMsg->MemorySize += sizeof(error_status_t);
5634 return sizeof(error_status_t);
5635 case RPC_FC_ENUM16:
5636 safe_buffer_increment(pStubMsg, sizeof(USHORT));
5637 pStubMsg->MemorySize += sizeof(UINT);
5638 return sizeof(UINT);
5639 case RPC_FC_IGNORE:
5640 pStubMsg->MemorySize += sizeof(void *);
5641 return sizeof(void *);
5642 default:
5643 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5644 return 0;
5648 /***********************************************************************
5649 * NdrBaseTypeFree [internal]
5651 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
5652 unsigned char *pMemory,
5653 PFORMAT_STRING pFormat)
5655 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5657 /* nothing to do */
5660 /***********************************************************************
5661 * NdrContextHandleBufferSize [internal]
5663 static void WINAPI NdrContextHandleBufferSize(
5664 PMIDL_STUB_MESSAGE pStubMsg,
5665 unsigned char *pMemory,
5666 PFORMAT_STRING pFormat)
5668 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5670 if (*pFormat != RPC_FC_BIND_CONTEXT)
5672 ERR("invalid format type %x\n", *pFormat);
5673 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5675 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5676 safe_buffer_length_increment(pStubMsg, cbNDRContext);
5679 /***********************************************************************
5680 * NdrContextHandleMarshall [internal]
5682 static unsigned char *WINAPI NdrContextHandleMarshall(
5683 PMIDL_STUB_MESSAGE pStubMsg,
5684 unsigned char *pMemory,
5685 PFORMAT_STRING pFormat)
5687 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5689 if (*pFormat != RPC_FC_BIND_CONTEXT)
5691 ERR("invalid format type %x\n", *pFormat);
5692 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5695 if (pFormat[1] & 0x80)
5696 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
5697 else
5698 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
5700 return NULL;
5703 /***********************************************************************
5704 * NdrContextHandleUnmarshall [internal]
5706 static unsigned char *WINAPI NdrContextHandleUnmarshall(
5707 PMIDL_STUB_MESSAGE pStubMsg,
5708 unsigned char **ppMemory,
5709 PFORMAT_STRING pFormat,
5710 unsigned char fMustAlloc)
5712 if (*pFormat != RPC_FC_BIND_CONTEXT)
5714 ERR("invalid format type %x\n", *pFormat);
5715 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5718 **(NDR_CCONTEXT **)ppMemory = NULL;
5719 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
5721 return NULL;
5724 /***********************************************************************
5725 * NdrClientContextMarshall [RPCRT4.@]
5727 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5728 NDR_CCONTEXT ContextHandle,
5729 int fCheck)
5731 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
5733 ALIGN_POINTER(pStubMsg->Buffer, 4);
5735 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5737 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
5738 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5739 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5742 /* FIXME: what does fCheck do? */
5743 NDRCContextMarshall(ContextHandle,
5744 pStubMsg->Buffer);
5746 pStubMsg->Buffer += cbNDRContext;
5749 /***********************************************************************
5750 * NdrClientContextUnmarshall [RPCRT4.@]
5752 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5753 NDR_CCONTEXT * pContextHandle,
5754 RPC_BINDING_HANDLE BindHandle)
5756 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
5758 ALIGN_POINTER(pStubMsg->Buffer, 4);
5760 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
5761 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5763 NDRCContextUnmarshall(pContextHandle,
5764 BindHandle,
5765 pStubMsg->Buffer,
5766 pStubMsg->RpcMsg->DataRepresentation);
5768 pStubMsg->Buffer += cbNDRContext;
5771 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5772 NDR_SCONTEXT ContextHandle,
5773 NDR_RUNDOWN RundownRoutine )
5775 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
5778 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
5780 FIXME("(%p): stub\n", pStubMsg);
5781 return NULL;
5784 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
5785 unsigned char* pMemory,
5786 PFORMAT_STRING pFormat)
5788 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
5791 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
5792 PFORMAT_STRING pFormat)
5794 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
5795 return NULL;
5798 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5799 NDR_SCONTEXT ContextHandle,
5800 NDR_RUNDOWN RundownRoutine,
5801 PFORMAT_STRING pFormat)
5803 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
5806 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5807 PFORMAT_STRING pFormat)
5809 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
5810 return NULL;
5813 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
5815 typedef struct ndr_context_handle
5817 DWORD attributes;
5818 GUID uuid;
5819 } ndr_context_handle;
5821 struct context_handle_entry
5823 struct list entry;
5824 DWORD magic;
5825 RPC_BINDING_HANDLE handle;
5826 ndr_context_handle wire_data;
5829 static struct list context_handle_list = LIST_INIT(context_handle_list);
5831 static CRITICAL_SECTION ndr_context_cs;
5832 static CRITICAL_SECTION_DEBUG ndr_context_debug =
5834 0, 0, &ndr_context_cs,
5835 { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
5836 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
5838 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
5840 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
5842 struct context_handle_entry *che = (struct context_handle_entry*) CContext;
5844 if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
5845 return NULL;
5846 return che;
5849 static struct context_handle_entry *context_entry_from_guid(LPCGUID uuid)
5851 struct context_handle_entry *che;
5852 LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
5853 if (IsEqualGUID(&che->wire_data.uuid, uuid))
5854 return che;
5855 return NULL;
5858 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
5860 struct context_handle_entry *che;
5861 RPC_BINDING_HANDLE handle = NULL;
5863 TRACE("%p\n", CContext);
5865 EnterCriticalSection(&ndr_context_cs);
5866 che = get_context_entry(CContext);
5867 if (che)
5868 handle = che->handle;
5869 LeaveCriticalSection(&ndr_context_cs);
5871 if (!handle)
5872 RpcRaiseException(ERROR_INVALID_HANDLE);
5873 return handle;
5876 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
5878 struct context_handle_entry *che;
5880 TRACE("%p %p\n", CContext, pBuff);
5882 if (CContext)
5884 EnterCriticalSection(&ndr_context_cs);
5885 che = get_context_entry(CContext);
5886 memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
5887 LeaveCriticalSection(&ndr_context_cs);
5889 else
5891 ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
5892 wire_data->attributes = 0;
5893 wire_data->uuid = GUID_NULL;
5897 /***********************************************************************
5898 * RpcSmDestroyClientContext [RPCRT4.@]
5900 RPC_STATUS WINAPI RpcSmDestroyClientContext(void **ContextHandle)
5902 RPC_STATUS status = RPC_X_SS_CONTEXT_MISMATCH;
5903 struct context_handle_entry *che = NULL;
5905 TRACE("(%p)\n", ContextHandle);
5907 EnterCriticalSection(&ndr_context_cs);
5908 che = get_context_entry(*ContextHandle);
5909 *ContextHandle = NULL;
5910 if (che)
5912 status = RPC_S_OK;
5913 list_remove(&che->entry);
5916 LeaveCriticalSection(&ndr_context_cs);
5918 if (che)
5920 RpcBindingFree(&che->handle);
5921 HeapFree(GetProcessHeap(), 0, che);
5924 return status;
5927 /***********************************************************************
5928 * RpcSsDestroyClientContext [RPCRT4.@]
5930 void WINAPI RpcSsDestroyClientContext(void **ContextHandle)
5932 RPC_STATUS status = RpcSmDestroyClientContext(ContextHandle);
5933 if (status != RPC_S_OK)
5934 RpcRaiseException(status);
5937 static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
5938 RPC_BINDING_HANDLE hBinding,
5939 const ndr_context_handle *chi)
5941 struct context_handle_entry *che = NULL;
5943 /* a null UUID means we should free the context handle */
5944 if (IsEqualGUID(&chi->uuid, &GUID_NULL))
5946 if (*CContext)
5948 che = get_context_entry(*CContext);
5949 if (!che)
5950 return ERROR_INVALID_HANDLE;
5951 list_remove(&che->entry);
5952 RpcBindingFree(&che->handle);
5953 HeapFree(GetProcessHeap(), 0, che);
5954 che = NULL;
5957 /* if there's no existing entry matching the GUID, allocate one */
5958 else if (!(che = context_entry_from_guid(&chi->uuid)))
5960 che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
5961 if (!che)
5962 return ERROR_NOT_ENOUGH_MEMORY;
5963 che->magic = NDR_CONTEXT_HANDLE_MAGIC;
5964 RpcBindingCopy(hBinding, &che->handle);
5965 list_add_tail(&context_handle_list, &che->entry);
5966 memcpy(&che->wire_data, chi, sizeof *chi);
5969 *CContext = che;
5971 return ERROR_SUCCESS;
5974 /***********************************************************************
5975 * NDRCContextUnmarshall [RPCRT4.@]
5977 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
5978 RPC_BINDING_HANDLE hBinding,
5979 void *pBuff, ULONG DataRepresentation)
5981 UINT r;
5983 TRACE("*%p=(%p) %p %p %08x\n",
5984 CContext, *CContext, hBinding, pBuff, DataRepresentation);
5986 EnterCriticalSection(&ndr_context_cs);
5987 r = ndr_update_context_handle(CContext, hBinding, pBuff);
5988 LeaveCriticalSection(&ndr_context_cs);
5989 if (r)
5990 RpcRaiseException(r);
5993 /***********************************************************************
5994 * NDRSContextMarshall [RPCRT4.@]
5996 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
5997 void *pBuff,
5998 NDR_RUNDOWN userRunDownIn)
6000 FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn);
6003 /***********************************************************************
6004 * NDRSContextMarshallEx [RPCRT4.@]
6006 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
6007 NDR_SCONTEXT CContext,
6008 void *pBuff,
6009 NDR_RUNDOWN userRunDownIn)
6011 FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn);
6014 /***********************************************************************
6015 * NDRSContextMarshall2 [RPCRT4.@]
6017 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
6018 NDR_SCONTEXT CContext,
6019 void *pBuff,
6020 NDR_RUNDOWN userRunDownIn,
6021 void *CtxGuard, ULONG Flags)
6023 FIXME("(%p %p %p %p %p %u): stub\n",
6024 hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags);
6027 /***********************************************************************
6028 * NDRSContextUnmarshall [RPCRT4.@]
6030 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
6031 ULONG DataRepresentation)
6033 FIXME("(%p %08x): stub\n", pBuff, DataRepresentation);
6034 return NULL;
6037 /***********************************************************************
6038 * NDRSContextUnmarshallEx [RPCRT4.@]
6040 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
6041 void *pBuff,
6042 ULONG DataRepresentation)
6044 FIXME("(%p %p %08x): stub\n", hBinding, pBuff, DataRepresentation);
6045 return NULL;
6048 /***********************************************************************
6049 * NDRSContextUnmarshall2 [RPCRT4.@]
6051 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
6052 void *pBuff,
6053 ULONG DataRepresentation,
6054 void *CtxGuard, ULONG Flags)
6056 FIXME("(%p %p %08x %p %u): stub\n",
6057 hBinding, pBuff, DataRepresentation, CtxGuard, Flags);
6058 return NULL;