rpcrt4: Add a trace to NdrBaseTypeMemorySize.
[wine.git] / dlls / rpcrt4 / ndr_marshall.c
blob17b84c4ca617eaab3d4ff8663907e06674be742a
1 /*
2 * NDR data marshalling
4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 * TODO:
22 * - Non-conformant strings
23 * - String structs
24 * - Byte count pointers
25 * - transmit_as/represent as
26 * - Multi-dimensional arrays
27 * - Conversion functions (NdrConvert)
28 * - Checks for integer addition overflow
29 * - Checks for out-of-memory conditions
32 #include <stdarg.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <assert.h>
36 #include <limits.h>
38 #include "windef.h"
39 #include "winbase.h"
40 #include "winerror.h"
42 #include "ndr_misc.h"
43 #include "rpcndr.h"
45 #include "wine/unicode.h"
46 #include "wine/rpcfc.h"
48 #include "wine/debug.h"
49 #include "wine/list.h"
51 WINE_DEFAULT_DEBUG_CHANNEL(ole);
53 #if defined(__i386__)
54 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
55 (*((UINT32 *)(pchar)) = (uint32))
57 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
58 (*((UINT32 *)(pchar)))
59 #else
60 /* these would work for i386 too, but less efficient */
61 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
62 (*(pchar) = LOBYTE(LOWORD(uint32)), \
63 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
64 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
65 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
66 (uint32)) /* allow as r-value */
68 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
69 (MAKELONG( \
70 MAKEWORD(*(pchar), *((pchar)+1)), \
71 MAKEWORD(*((pchar)+2), *((pchar)+3))))
72 #endif
74 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
75 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
76 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
77 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
78 *(pchar) = HIBYTE(HIWORD(uint32)), \
79 (uint32)) /* allow as r-value */
81 #define BIG_ENDIAN_UINT32_READ(pchar) \
82 (MAKELONG( \
83 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
84 MAKEWORD(*((pchar)+1), *(pchar))))
86 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
87 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
88 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
89 # define NDR_LOCAL_UINT32_READ(pchar) \
90 BIG_ENDIAN_UINT32_READ(pchar)
91 #else
92 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
93 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
94 # define NDR_LOCAL_UINT32_READ(pchar) \
95 LITTLE_ENDIAN_UINT32_READ(pchar)
96 #endif
98 /* _Align must be the desired alignment,
99 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
100 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
101 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
102 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
103 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
105 #define STD_OVERFLOW_CHECK(_Msg) do { \
106 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
107 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
108 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
109 } while (0)
111 #define NDR_TABLE_SIZE 128
112 #define NDR_TABLE_MASK 127
114 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
115 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
116 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
117 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
118 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
120 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
121 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
122 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
124 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
126 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
127 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
128 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
129 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
130 /* 0x10 */
131 NdrBaseTypeMarshall,
132 /* 0x11 */
133 NdrPointerMarshall, NdrPointerMarshall,
134 NdrPointerMarshall, NdrPointerMarshall,
135 /* 0x15 */
136 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
137 NdrConformantStructMarshall, NdrConformantStructMarshall,
138 NdrConformantVaryingStructMarshall,
139 NdrComplexStructMarshall,
140 /* 0x1b */
141 NdrConformantArrayMarshall,
142 NdrConformantVaryingArrayMarshall,
143 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
144 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
145 NdrComplexArrayMarshall,
146 /* 0x22 */
147 NdrConformantStringMarshall, 0, 0,
148 NdrConformantStringMarshall,
149 NdrNonConformantStringMarshall, 0, 0, 0,
150 /* 0x2a */
151 NdrEncapsulatedUnionMarshall,
152 NdrNonEncapsulatedUnionMarshall,
153 NdrByteCountPointerMarshall,
154 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
155 /* 0x2f */
156 NdrInterfacePointerMarshall,
157 /* 0x30 */
158 NdrContextHandleMarshall,
159 /* 0xb1 */
160 0, 0, 0,
161 NdrUserMarshalMarshall,
162 0, 0,
163 /* 0xb7 */
164 NdrRangeMarshall
166 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
168 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
169 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
170 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
171 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
172 /* 0x10 */
173 NdrBaseTypeUnmarshall,
174 /* 0x11 */
175 NdrPointerUnmarshall, NdrPointerUnmarshall,
176 NdrPointerUnmarshall, NdrPointerUnmarshall,
177 /* 0x15 */
178 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
179 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
180 NdrConformantVaryingStructUnmarshall,
181 NdrComplexStructUnmarshall,
182 /* 0x1b */
183 NdrConformantArrayUnmarshall,
184 NdrConformantVaryingArrayUnmarshall,
185 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
186 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
187 NdrComplexArrayUnmarshall,
188 /* 0x22 */
189 NdrConformantStringUnmarshall, 0, 0,
190 NdrConformantStringUnmarshall,
191 NdrNonConformantStringUnmarshall, 0, 0, 0,
192 /* 0x2a */
193 NdrEncapsulatedUnionUnmarshall,
194 NdrNonEncapsulatedUnionUnmarshall,
195 NdrByteCountPointerUnmarshall,
196 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
197 /* 0x2f */
198 NdrInterfacePointerUnmarshall,
199 /* 0x30 */
200 NdrContextHandleUnmarshall,
201 /* 0xb1 */
202 0, 0, 0,
203 NdrUserMarshalUnmarshall,
204 0, 0,
205 /* 0xb7 */
206 NdrRangeUnmarshall
208 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
210 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
211 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
212 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
213 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
214 /* 0x10 */
215 NdrBaseTypeBufferSize,
216 /* 0x11 */
217 NdrPointerBufferSize, NdrPointerBufferSize,
218 NdrPointerBufferSize, NdrPointerBufferSize,
219 /* 0x15 */
220 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
221 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
222 NdrConformantVaryingStructBufferSize,
223 NdrComplexStructBufferSize,
224 /* 0x1b */
225 NdrConformantArrayBufferSize,
226 NdrConformantVaryingArrayBufferSize,
227 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
228 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
229 NdrComplexArrayBufferSize,
230 /* 0x22 */
231 NdrConformantStringBufferSize, 0, 0,
232 NdrConformantStringBufferSize,
233 NdrNonConformantStringBufferSize, 0, 0, 0,
234 /* 0x2a */
235 NdrEncapsulatedUnionBufferSize,
236 NdrNonEncapsulatedUnionBufferSize,
237 NdrByteCountPointerBufferSize,
238 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
239 /* 0x2f */
240 NdrInterfacePointerBufferSize,
241 /* 0x30 */
242 NdrContextHandleBufferSize,
243 /* 0xb1 */
244 0, 0, 0,
245 NdrUserMarshalBufferSize,
246 0, 0,
247 /* 0xb7 */
248 NdrRangeBufferSize
250 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
252 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
253 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
254 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
255 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
256 /* 0x10 */
257 NdrBaseTypeMemorySize,
258 /* 0x11 */
259 NdrPointerMemorySize, NdrPointerMemorySize,
260 NdrPointerMemorySize, NdrPointerMemorySize,
261 /* 0x15 */
262 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
263 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
264 NdrConformantVaryingStructMemorySize,
265 NdrComplexStructMemorySize,
266 /* 0x1b */
267 NdrConformantArrayMemorySize,
268 NdrConformantVaryingArrayMemorySize,
269 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
270 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
271 NdrComplexArrayMemorySize,
272 /* 0x22 */
273 NdrConformantStringMemorySize, 0, 0,
274 NdrConformantStringMemorySize,
275 NdrNonConformantStringMemorySize, 0, 0, 0,
276 /* 0x2a */
277 NdrEncapsulatedUnionMemorySize,
278 NdrNonEncapsulatedUnionMemorySize,
279 NdrByteCountPointerMemorySize,
280 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
281 /* 0x2f */
282 NdrInterfacePointerMemorySize,
283 /* 0x30 */
285 /* 0xb1 */
286 0, 0, 0,
287 NdrUserMarshalMemorySize,
288 0, 0,
289 /* 0xb7 */
290 NdrRangeMemorySize
292 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
294 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
295 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
296 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
297 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
298 /* 0x10 */
299 NdrBaseTypeFree,
300 /* 0x11 */
301 NdrPointerFree, NdrPointerFree,
302 NdrPointerFree, NdrPointerFree,
303 /* 0x15 */
304 NdrSimpleStructFree, NdrSimpleStructFree,
305 NdrConformantStructFree, NdrConformantStructFree,
306 NdrConformantVaryingStructFree,
307 NdrComplexStructFree,
308 /* 0x1b */
309 NdrConformantArrayFree,
310 NdrConformantVaryingArrayFree,
311 NdrFixedArrayFree, NdrFixedArrayFree,
312 NdrVaryingArrayFree, NdrVaryingArrayFree,
313 NdrComplexArrayFree,
314 /* 0x22 */
315 0, 0, 0,
316 0, 0, 0, 0, 0,
317 /* 0x2a */
318 NdrEncapsulatedUnionFree,
319 NdrNonEncapsulatedUnionFree,
321 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
322 /* 0x2f */
323 NdrInterfacePointerFree,
324 /* 0x30 */
326 /* 0xb1 */
327 0, 0, 0,
328 NdrUserMarshalFree,
329 0, 0,
330 /* 0xb7 */
331 NdrRangeFree
334 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
336 /* hmm, this is probably supposed to do more? */
337 return pStubMsg->pfnAllocate(len);
340 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
342 pStubMsg->pfnFree(Pointer);
345 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
347 return (*(const ULONG *)pFormat != -1);
350 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
352 ALIGN_POINTER(pStubMsg->Buffer, 4);
353 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
354 RpcRaiseException(RPC_X_BAD_STUB_DATA);
355 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
356 pStubMsg->Buffer += 4;
357 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
358 if (pStubMsg->fHasNewCorrDesc)
359 return pFormat+6;
360 else
361 return pFormat+4;
364 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
366 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
368 pStubMsg->Offset = 0;
369 pStubMsg->ActualCount = pStubMsg->MaxCount;
370 goto done;
373 ALIGN_POINTER(pStubMsg->Buffer, 4);
374 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
375 RpcRaiseException(RPC_X_BAD_STUB_DATA);
376 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
377 pStubMsg->Buffer += 4;
378 TRACE("offset is %d\n", pStubMsg->Offset);
379 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
380 pStubMsg->Buffer += 4;
381 TRACE("variance is %d\n", pStubMsg->ActualCount);
383 if ((pStubMsg->ActualCount > MaxValue) ||
384 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
386 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
387 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
388 RpcRaiseException(RPC_S_INVALID_BOUND);
389 return NULL;
392 done:
393 if (pStubMsg->fHasNewCorrDesc)
394 return pFormat+6;
395 else
396 return pFormat+4;
399 /* writes the conformance value to the buffer */
400 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
402 ALIGN_POINTER(pStubMsg->Buffer, 4);
403 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
404 RpcRaiseException(RPC_X_BAD_STUB_DATA);
405 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
406 pStubMsg->Buffer += 4;
409 /* writes the variance values to the buffer */
410 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
412 ALIGN_POINTER(pStubMsg->Buffer, 4);
413 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
414 RpcRaiseException(RPC_X_BAD_STUB_DATA);
415 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
416 pStubMsg->Buffer += 4;
417 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
418 pStubMsg->Buffer += 4;
421 /* requests buffer space for the conformance value */
422 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
424 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
425 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
426 RpcRaiseException(RPC_X_BAD_STUB_DATA);
427 pStubMsg->BufferLength += 4;
430 /* requests buffer space for the variance values */
431 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
433 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
434 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
435 RpcRaiseException(RPC_X_BAD_STUB_DATA);
436 pStubMsg->BufferLength += 8;
439 PFORMAT_STRING ComputeConformanceOrVariance(
440 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
441 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
443 BYTE dtype = pFormat[0] & 0xf;
444 short ofs = *(const short *)&pFormat[2];
445 LPVOID ptr = NULL;
446 DWORD data = 0;
448 if (!IsConformanceOrVariancePresent(pFormat)) {
449 /* null descriptor */
450 *pCount = def;
451 goto finish_conf;
454 switch (pFormat[0] & 0xf0) {
455 case RPC_FC_NORMAL_CONFORMANCE:
456 TRACE("normal conformance, ofs=%d\n", ofs);
457 ptr = pMemory;
458 break;
459 case RPC_FC_POINTER_CONFORMANCE:
460 TRACE("pointer conformance, ofs=%d\n", ofs);
461 ptr = pStubMsg->Memory;
462 break;
463 case RPC_FC_TOP_LEVEL_CONFORMANCE:
464 TRACE("toplevel conformance, ofs=%d\n", ofs);
465 if (pStubMsg->StackTop) {
466 ptr = pStubMsg->StackTop;
468 else {
469 /* -Os mode, *pCount is already set */
470 goto finish_conf;
472 break;
473 case RPC_FC_CONSTANT_CONFORMANCE:
474 data = ofs | ((DWORD)pFormat[1] << 16);
475 TRACE("constant conformance, val=%d\n", data);
476 *pCount = data;
477 goto finish_conf;
478 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
479 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
480 if (pStubMsg->StackTop) {
481 ptr = pStubMsg->StackTop;
483 else {
484 /* ? */
485 goto done_conf_grab;
487 break;
488 default:
489 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
492 switch (pFormat[1]) {
493 case RPC_FC_DEREFERENCE:
494 ptr = *(LPVOID*)((char *)ptr + ofs);
495 break;
496 case RPC_FC_CALLBACK:
498 unsigned char *old_stack_top = pStubMsg->StackTop;
499 pStubMsg->StackTop = ptr;
501 /* ofs is index into StubDesc->apfnExprEval */
502 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
503 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
505 pStubMsg->StackTop = old_stack_top;
507 /* the callback function always stores the computed value in MaxCount */
508 *pCount = pStubMsg->MaxCount;
509 goto finish_conf;
511 default:
512 ptr = (char *)ptr + ofs;
513 break;
516 switch (dtype) {
517 case RPC_FC_LONG:
518 case RPC_FC_ULONG:
519 data = *(DWORD*)ptr;
520 break;
521 case RPC_FC_SHORT:
522 data = *(SHORT*)ptr;
523 break;
524 case RPC_FC_USHORT:
525 data = *(USHORT*)ptr;
526 break;
527 case RPC_FC_CHAR:
528 case RPC_FC_SMALL:
529 data = *(CHAR*)ptr;
530 break;
531 case RPC_FC_BYTE:
532 case RPC_FC_USMALL:
533 data = *(UCHAR*)ptr;
534 break;
535 default:
536 FIXME("unknown conformance data type %x\n", dtype);
537 goto done_conf_grab;
539 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
541 done_conf_grab:
542 switch (pFormat[1]) {
543 case RPC_FC_DEREFERENCE: /* already handled */
544 case 0: /* no op */
545 *pCount = data;
546 break;
547 case RPC_FC_ADD_1:
548 *pCount = data + 1;
549 break;
550 case RPC_FC_SUB_1:
551 *pCount = data - 1;
552 break;
553 case RPC_FC_MULT_2:
554 *pCount = data * 2;
555 break;
556 case RPC_FC_DIV_2:
557 *pCount = data / 2;
558 break;
559 default:
560 FIXME("unknown conformance op %d\n", pFormat[1]);
561 goto finish_conf;
564 finish_conf:
565 TRACE("resulting conformance is %ld\n", *pCount);
566 if (pStubMsg->fHasNewCorrDesc)
567 return pFormat+6;
568 else
569 return pFormat+4;
572 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
573 * the result overflows 32-bits */
574 static inline ULONG safe_multiply(ULONG a, ULONG b)
576 ULONGLONG ret = (ULONGLONG)a * b;
577 if (ret > 0xffffffff)
579 RpcRaiseException(RPC_S_INVALID_BOUND);
580 return 0;
582 return ret;
585 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
587 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
588 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
589 RpcRaiseException(RPC_X_BAD_STUB_DATA);
590 pStubMsg->Buffer += size;
593 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
595 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
597 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
598 pStubMsg->BufferLength, size);
599 RpcRaiseException(RPC_X_BAD_STUB_DATA);
601 pStubMsg->BufferLength += size;
604 /* copies data from the buffer, checking that there is enough data in the buffer
605 * to do so */
606 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
608 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
609 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
610 RpcRaiseException(RPC_X_BAD_STUB_DATA);
611 memcpy(p, pStubMsg->Buffer, size);
612 pStubMsg->Buffer += size;
615 /* copies data to the buffer, checking that there is enough space to do so */
616 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
618 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
619 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
621 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
622 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
623 size);
624 RpcRaiseException(RPC_X_BAD_STUB_DATA);
626 memcpy(pStubMsg->Buffer, p, size);
627 pStubMsg->Buffer += size;
631 * NdrConformantString:
633 * What MS calls a ConformantString is, in DCE terminology,
634 * a Varying-Conformant String.
636 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
637 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
638 * into unmarshalled string)
639 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
640 * [
641 * data: CHARTYPE[maxlen]
642 * ]
643 * ], where CHARTYPE is the appropriate character type (specified externally)
647 /***********************************************************************
648 * NdrConformantStringMarshall [RPCRT4.@]
650 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
651 unsigned char *pszMessage, PFORMAT_STRING pFormat)
653 ULONG esize, size;
655 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
657 if (*pFormat == RPC_FC_C_CSTRING) {
658 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
659 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
660 esize = 1;
662 else if (*pFormat == RPC_FC_C_WSTRING) {
663 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
664 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
665 esize = 2;
667 else {
668 ERR("Unhandled string type: %#x\n", *pFormat);
669 /* FIXME: raise an exception. */
670 return NULL;
673 if (pFormat[1] == RPC_FC_STRING_SIZED)
674 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
675 else
676 pStubMsg->MaxCount = pStubMsg->ActualCount;
677 pStubMsg->Offset = 0;
678 WriteConformance(pStubMsg);
679 WriteVariance(pStubMsg);
681 size = safe_multiply(esize, pStubMsg->ActualCount);
682 safe_copy_to_buffer(pStubMsg, pszMessage, size); /* the string itself */
684 /* success */
685 return NULL; /* is this always right? */
688 /***********************************************************************
689 * NdrConformantStringBufferSize [RPCRT4.@]
691 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
692 unsigned char* pMemory, PFORMAT_STRING pFormat)
694 ULONG esize;
696 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
698 SizeConformance(pStubMsg);
699 SizeVariance(pStubMsg);
701 if (*pFormat == RPC_FC_C_CSTRING) {
702 TRACE("string=%s\n", debugstr_a((char*)pMemory));
703 pStubMsg->ActualCount = strlen((char*)pMemory)+1;
704 esize = 1;
706 else if (*pFormat == RPC_FC_C_WSTRING) {
707 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
708 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;
709 esize = 2;
711 else {
712 ERR("Unhandled string type: %#x\n", *pFormat);
713 /* FIXME: raise an exception */
714 return;
717 if (pFormat[1] == RPC_FC_STRING_SIZED)
718 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
719 else
720 pStubMsg->MaxCount = pStubMsg->ActualCount;
722 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
725 /************************************************************************
726 * NdrConformantStringMemorySize [RPCRT4.@]
728 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
729 PFORMAT_STRING pFormat )
731 ULONG rslt = 0;
733 FIXME("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
735 assert(pStubMsg && pFormat);
737 if (*pFormat == RPC_FC_C_CSTRING) {
738 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
740 else if (*pFormat == RPC_FC_C_WSTRING) {
741 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
743 else {
744 ERR("Unhandled string type: %#x\n", *pFormat);
745 /* FIXME: raise an exception */
748 if (pFormat[1] != RPC_FC_PAD) {
749 FIXME("sized string format=%d\n", pFormat[1]);
752 TRACE(" --> %u\n", rslt);
753 return rslt;
756 /************************************************************************
757 * NdrConformantStringUnmarshall [RPCRT4.@]
759 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
760 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
762 ULONG bufsize, memsize, esize, i;
764 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
765 pStubMsg, *ppMemory, pFormat, fMustAlloc);
767 assert(pFormat && ppMemory && pStubMsg);
769 ReadConformance(pStubMsg, NULL);
770 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
772 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
773 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
774 else {
775 ERR("Unhandled string type: %#x\n", *pFormat);
776 /* FIXME: raise an exception */
777 esize = 0;
780 memsize = safe_multiply(esize, pStubMsg->MaxCount);
781 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
783 /* strings must always have null terminating bytes */
784 if (bufsize < esize)
786 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
787 RpcRaiseException(RPC_S_INVALID_BOUND);
788 return NULL;
791 /* verify the buffer is safe to access */
792 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
793 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
795 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
796 pStubMsg->BufferEnd, pStubMsg->Buffer);
797 RpcRaiseException(RPC_X_BAD_STUB_DATA);
798 return NULL;
801 for (i = bufsize - esize; i < bufsize; i++)
802 if (pStubMsg->Buffer[i] != 0)
804 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
805 i, pStubMsg->Buffer[i]);
806 RpcRaiseException(RPC_S_INVALID_BOUND);
807 return NULL;
810 if (fMustAlloc || !*ppMemory)
811 *ppMemory = NdrAllocate(pStubMsg, memsize);
813 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
815 if (*pFormat == RPC_FC_C_CSTRING) {
816 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
818 else if (*pFormat == RPC_FC_C_WSTRING) {
819 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
822 return NULL; /* FIXME: is this always right? */
825 /***********************************************************************
826 * NdrNonConformantStringMarshall [RPCRT4.@]
828 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
829 unsigned char *pMemory,
830 PFORMAT_STRING pFormat)
832 FIXME("stub\n");
833 return NULL;
836 /***********************************************************************
837 * NdrNonConformantStringUnmarshall [RPCRT4.@]
839 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
840 unsigned char **ppMemory,
841 PFORMAT_STRING pFormat,
842 unsigned char fMustAlloc)
844 FIXME("stub\n");
845 return NULL;
848 /***********************************************************************
849 * NdrNonConformantStringBufferSize [RPCRT4.@]
851 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
852 unsigned char *pMemory,
853 PFORMAT_STRING pFormat)
855 FIXME("stub\n");
858 /***********************************************************************
859 * NdrNonConformantStringMemorySize [RPCRT4.@]
861 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
862 PFORMAT_STRING pFormat)
864 FIXME("stub\n");
865 return 0;
868 static inline void dump_pointer_attr(unsigned char attr)
870 if (attr & RPC_FC_P_ALLOCALLNODES)
871 TRACE(" RPC_FC_P_ALLOCALLNODES");
872 if (attr & RPC_FC_P_DONTFREE)
873 TRACE(" RPC_FC_P_DONTFREE");
874 if (attr & RPC_FC_P_ONSTACK)
875 TRACE(" RPC_FC_P_ONSTACK");
876 if (attr & RPC_FC_P_SIMPLEPOINTER)
877 TRACE(" RPC_FC_P_SIMPLEPOINTER");
878 if (attr & RPC_FC_P_DEREF)
879 TRACE(" RPC_FC_P_DEREF");
880 TRACE("\n");
883 /***********************************************************************
884 * PointerMarshall [internal]
886 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
887 unsigned char *Buffer,
888 unsigned char *Pointer,
889 PFORMAT_STRING pFormat)
891 unsigned type = pFormat[0], attr = pFormat[1];
892 PFORMAT_STRING desc;
893 NDR_MARSHALL m;
894 ULONG pointer_id;
895 int pointer_needs_marshaling;
897 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
898 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
899 pFormat += 2;
900 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
901 else desc = pFormat + *(const SHORT*)pFormat;
903 switch (type) {
904 case RPC_FC_RP: /* ref pointer (always non-null) */
905 if (!Pointer)
907 ERR("NULL ref pointer is not allowed\n");
908 RpcRaiseException(RPC_X_NULL_REF_POINTER);
910 pointer_needs_marshaling = 1;
911 break;
912 case RPC_FC_UP: /* unique pointer */
913 case RPC_FC_OP: /* object pointer - same as unique here */
914 if (Pointer)
915 pointer_needs_marshaling = 1;
916 else
917 pointer_needs_marshaling = 0;
918 pointer_id = (ULONG)Pointer;
919 TRACE("writing 0x%08x to buffer\n", pointer_id);
920 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
921 break;
922 case RPC_FC_FP:
923 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
924 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
925 TRACE("writing 0x%08x to buffer\n", pointer_id);
926 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
927 break;
928 default:
929 FIXME("unhandled ptr type=%02x\n", type);
930 RpcRaiseException(RPC_X_BAD_STUB_DATA);
931 return;
934 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
936 if (pointer_needs_marshaling) {
937 if (attr & RPC_FC_P_DEREF) {
938 Pointer = *(unsigned char**)Pointer;
939 TRACE("deref => %p\n", Pointer);
941 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
942 if (m) m(pStubMsg, Pointer, desc);
943 else FIXME("no marshaller for data type=%02x\n", *desc);
946 STD_OVERFLOW_CHECK(pStubMsg);
949 /***********************************************************************
950 * PointerUnmarshall [internal]
952 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
953 unsigned char *Buffer,
954 unsigned char **pPointer,
955 unsigned char *pSrcPointer,
956 PFORMAT_STRING pFormat,
957 unsigned char fMustAlloc)
959 unsigned type = pFormat[0], attr = pFormat[1];
960 PFORMAT_STRING desc;
961 NDR_UNMARSHALL m;
962 DWORD pointer_id = 0;
963 int pointer_needs_unmarshaling;
965 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
966 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
967 pFormat += 2;
968 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
969 else desc = pFormat + *(const SHORT*)pFormat;
971 switch (type) {
972 case RPC_FC_RP: /* ref pointer (always non-null) */
973 pointer_needs_unmarshaling = 1;
974 break;
975 case RPC_FC_UP: /* unique pointer */
976 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
977 TRACE("pointer_id is 0x%08x\n", pointer_id);
978 if (pointer_id)
979 pointer_needs_unmarshaling = 1;
980 else {
981 *pPointer = NULL;
982 pointer_needs_unmarshaling = 0;
984 break;
985 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
986 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
987 TRACE("pointer_id is 0x%08x\n", pointer_id);
988 if (!fMustAlloc && pSrcPointer)
990 FIXME("free object pointer %p\n", pSrcPointer);
991 fMustAlloc = TRUE;
993 if (pointer_id)
994 pointer_needs_unmarshaling = 1;
995 else
996 pointer_needs_unmarshaling = 0;
997 break;
998 case RPC_FC_FP:
999 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1000 TRACE("pointer_id is 0x%08x\n", pointer_id);
1001 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
1002 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
1003 break;
1004 default:
1005 FIXME("unhandled ptr type=%02x\n", type);
1006 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1007 return;
1010 if (pointer_needs_unmarshaling) {
1011 unsigned char *base_ptr_val = *pPointer;
1012 unsigned char **current_ptr = pPointer;
1013 if (pStubMsg->IsClient) {
1014 TRACE("client\n");
1015 /* if we aren't forcing allocation of memory then try to use the existing
1016 * (source) pointer to unmarshall the data into so that [in,out]
1017 * parameters behave correctly. it doesn't matter if the parameter is
1018 * [out] only since in that case the pointer will be NULL. we force
1019 * allocation when the source pointer is NULL here instead of in the type
1020 * unmarshalling routine for the benefit of the deref code below */
1021 if (!fMustAlloc) {
1022 if (pSrcPointer) {
1023 TRACE("setting *pPointer to %p\n", pSrcPointer);
1024 *pPointer = base_ptr_val = pSrcPointer;
1025 } else
1026 fMustAlloc = TRUE;
1028 } else {
1029 TRACE("server\n");
1030 /* the memory in a stub is never initialised, so we have to work out here
1031 * whether we have to initialise it so we can use the optimisation of
1032 * setting the pointer to the buffer, if possible, or set fMustAlloc to
1033 * TRUE. */
1034 if (attr & RPC_FC_P_DEREF) {
1035 fMustAlloc = TRUE;
1036 } else {
1037 base_ptr_val = NULL;
1038 *current_ptr = NULL;
1042 if (attr & RPC_FC_P_DEREF) {
1043 if (fMustAlloc) {
1044 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
1045 *pPointer = base_ptr_val;
1046 current_ptr = (unsigned char **)base_ptr_val;
1047 } else
1048 current_ptr = *(unsigned char***)current_ptr;
1049 TRACE("deref => %p\n", current_ptr);
1050 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
1052 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1053 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
1054 else FIXME("no unmarshaller for data type=%02x\n", *desc);
1056 if (type == RPC_FC_FP)
1057 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
1058 base_ptr_val);
1061 TRACE("pointer=%p\n", *pPointer);
1064 /***********************************************************************
1065 * PointerBufferSize [internal]
1067 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1068 unsigned char *Pointer,
1069 PFORMAT_STRING pFormat)
1071 unsigned type = pFormat[0], attr = pFormat[1];
1072 PFORMAT_STRING desc;
1073 NDR_BUFFERSIZE m;
1074 int pointer_needs_sizing;
1075 ULONG pointer_id;
1077 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1078 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1079 pFormat += 2;
1080 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1081 else desc = pFormat + *(const SHORT*)pFormat;
1083 switch (type) {
1084 case RPC_FC_RP: /* ref pointer (always non-null) */
1085 if (!Pointer)
1087 ERR("NULL ref pointer is not allowed\n");
1088 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1090 break;
1091 case RPC_FC_OP:
1092 case RPC_FC_UP:
1093 /* NULL pointer has no further representation */
1094 if (!Pointer)
1095 return;
1096 break;
1097 case RPC_FC_FP:
1098 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1099 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1100 if (!pointer_needs_sizing)
1101 return;
1102 break;
1103 default:
1104 FIXME("unhandled ptr type=%02x\n", type);
1105 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1106 return;
1109 if (attr & RPC_FC_P_DEREF) {
1110 Pointer = *(unsigned char**)Pointer;
1111 TRACE("deref => %p\n", Pointer);
1114 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1115 if (m) m(pStubMsg, Pointer, desc);
1116 else FIXME("no buffersizer for data type=%02x\n", *desc);
1119 /***********************************************************************
1120 * PointerMemorySize [internal]
1122 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1123 unsigned char *Buffer,
1124 PFORMAT_STRING pFormat)
1126 unsigned type = pFormat[0], attr = pFormat[1];
1127 PFORMAT_STRING desc;
1128 NDR_MEMORYSIZE m;
1129 DWORD pointer_id = 0;
1130 int pointer_needs_sizing;
1132 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1133 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1134 pFormat += 2;
1135 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1136 else desc = pFormat + *(const SHORT*)pFormat;
1138 switch (type) {
1139 case RPC_FC_RP: /* ref pointer (always non-null) */
1140 pointer_needs_sizing = 1;
1141 break;
1142 case RPC_FC_UP: /* unique pointer */
1143 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1144 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1145 TRACE("pointer_id is 0x%08x\n", pointer_id);
1146 if (pointer_id)
1147 pointer_needs_sizing = 1;
1148 else
1149 pointer_needs_sizing = 0;
1150 break;
1151 case RPC_FC_FP:
1153 void *pointer;
1154 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1155 TRACE("pointer_id is 0x%08x\n", pointer_id);
1156 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1157 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1158 break;
1160 default:
1161 FIXME("unhandled ptr type=%02x\n", type);
1162 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1163 return 0;
1166 if (attr & RPC_FC_P_DEREF) {
1167 TRACE("deref\n");
1170 if (pointer_needs_sizing) {
1171 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1172 if (m) m(pStubMsg, desc);
1173 else FIXME("no memorysizer for data type=%02x\n", *desc);
1176 return pStubMsg->MemorySize;
1179 /***********************************************************************
1180 * PointerFree [internal]
1182 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1183 unsigned char *Pointer,
1184 PFORMAT_STRING pFormat)
1186 unsigned type = pFormat[0], attr = pFormat[1];
1187 PFORMAT_STRING desc;
1188 NDR_FREE m;
1190 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1191 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1192 if (attr & RPC_FC_P_DONTFREE) return;
1193 pFormat += 2;
1194 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1195 else desc = pFormat + *(const SHORT*)pFormat;
1197 if (!Pointer) return;
1199 if (type == RPC_FC_FP) {
1200 int pointer_needs_freeing = NdrFullPointerFree(
1201 pStubMsg->FullPtrXlatTables, Pointer);
1202 if (!pointer_needs_freeing)
1203 return;
1206 if (attr & RPC_FC_P_DEREF) {
1207 Pointer = *(unsigned char**)Pointer;
1208 TRACE("deref => %p\n", Pointer);
1211 m = NdrFreer[*desc & NDR_TABLE_MASK];
1212 if (m) m(pStubMsg, Pointer, desc);
1214 /* we should check if the memory comes from NdrAllocate,
1215 * and deallocate only if so - checking if the pointer is between
1216 * BufferStart and BufferEnd will not always work since the buffer
1217 * may be reallocated when the server wants to marshal the reply */
1218 if (Pointer >= (unsigned char *)pStubMsg->RpcMsg->Buffer ||
1219 Pointer <= (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
1220 goto notfree;
1222 if (attr & RPC_FC_P_ONSTACK) {
1223 TRACE("not freeing stack ptr %p\n", Pointer);
1224 return;
1226 TRACE("freeing %p\n", Pointer);
1227 NdrFree(pStubMsg, Pointer);
1228 return;
1229 notfree:
1230 TRACE("not freeing %p\n", Pointer);
1233 /***********************************************************************
1234 * EmbeddedPointerMarshall
1236 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1237 unsigned char *pMemory,
1238 PFORMAT_STRING pFormat)
1240 unsigned char *Mark = pStubMsg->BufferMark;
1241 unsigned rep, count, stride;
1242 unsigned i;
1243 unsigned char *saved_buffer = NULL;
1245 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1247 if (*pFormat != RPC_FC_PP) return NULL;
1248 pFormat += 2;
1250 if (pStubMsg->PointerBufferMark)
1252 saved_buffer = pStubMsg->Buffer;
1253 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1254 pStubMsg->PointerBufferMark = NULL;
1257 while (pFormat[0] != RPC_FC_END) {
1258 switch (pFormat[0]) {
1259 default:
1260 FIXME("unknown repeat type %d\n", pFormat[0]);
1261 case RPC_FC_NO_REPEAT:
1262 rep = 1;
1263 stride = 0;
1264 count = 1;
1265 pFormat += 2;
1266 break;
1267 case RPC_FC_FIXED_REPEAT:
1268 rep = *(const WORD*)&pFormat[2];
1269 stride = *(const WORD*)&pFormat[4];
1270 count = *(const WORD*)&pFormat[8];
1271 pFormat += 10;
1272 break;
1273 case RPC_FC_VARIABLE_REPEAT:
1274 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1275 stride = *(const WORD*)&pFormat[2];
1276 count = *(const WORD*)&pFormat[6];
1277 pFormat += 8;
1278 break;
1280 for (i = 0; i < rep; i++) {
1281 PFORMAT_STRING info = pFormat;
1282 unsigned char *membase = pMemory + (i * stride);
1283 unsigned char *bufbase = Mark + (i * stride);
1284 unsigned u;
1286 for (u=0; u<count; u++,info+=8) {
1287 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1288 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1289 unsigned char *saved_memory = pStubMsg->Memory;
1291 pStubMsg->Memory = pMemory;
1292 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1293 pStubMsg->Memory = saved_memory;
1296 pFormat += 8 * count;
1299 if (saved_buffer)
1301 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1302 pStubMsg->Buffer = saved_buffer;
1305 STD_OVERFLOW_CHECK(pStubMsg);
1307 return NULL;
1310 /***********************************************************************
1311 * EmbeddedPointerUnmarshall
1313 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1314 unsigned char *pDstMemoryPtrs,
1315 unsigned char *pSrcMemoryPtrs,
1316 PFORMAT_STRING pFormat,
1317 unsigned char fMustAlloc)
1319 unsigned char *Mark = pStubMsg->BufferMark;
1320 unsigned rep, count, stride;
1321 unsigned i;
1322 unsigned char *saved_buffer = NULL;
1324 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstMemoryPtrs, pSrcMemoryPtrs, pFormat, fMustAlloc);
1326 if (*pFormat != RPC_FC_PP) return NULL;
1327 pFormat += 2;
1329 if (pStubMsg->PointerBufferMark)
1331 saved_buffer = pStubMsg->Buffer;
1332 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1333 pStubMsg->PointerBufferMark = NULL;
1336 while (pFormat[0] != RPC_FC_END) {
1337 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1338 switch (pFormat[0]) {
1339 default:
1340 FIXME("unknown repeat type %d\n", pFormat[0]);
1341 case RPC_FC_NO_REPEAT:
1342 rep = 1;
1343 stride = 0;
1344 count = 1;
1345 pFormat += 2;
1346 break;
1347 case RPC_FC_FIXED_REPEAT:
1348 rep = *(const WORD*)&pFormat[2];
1349 stride = *(const WORD*)&pFormat[4];
1350 count = *(const WORD*)&pFormat[8];
1351 pFormat += 10;
1352 break;
1353 case RPC_FC_VARIABLE_REPEAT:
1354 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1355 stride = *(const WORD*)&pFormat[2];
1356 count = *(const WORD*)&pFormat[6];
1357 pFormat += 8;
1358 break;
1360 for (i = 0; i < rep; i++) {
1361 PFORMAT_STRING info = pFormat;
1362 unsigned char *memdstbase = pDstMemoryPtrs + (i * stride);
1363 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1364 unsigned char *bufbase = Mark + (i * stride);
1365 unsigned u;
1367 for (u=0; u<count; u++,info+=8) {
1368 unsigned char **memdstptr = (unsigned char **)(memdstbase + *(const SHORT*)&info[0]);
1369 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1370 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1371 PointerUnmarshall(pStubMsg, bufptr, memdstptr, *memsrcptr, info+4, fMustAlloc);
1374 pFormat += 8 * count;
1377 if (saved_buffer)
1379 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1380 pStubMsg->Buffer = saved_buffer;
1383 return NULL;
1386 /***********************************************************************
1387 * EmbeddedPointerBufferSize
1389 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1390 unsigned char *pMemory,
1391 PFORMAT_STRING pFormat)
1393 unsigned rep, count, stride;
1394 unsigned i;
1395 ULONG saved_buffer_length = 0;
1397 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1399 if (pStubMsg->IgnoreEmbeddedPointers) return;
1401 if (*pFormat != RPC_FC_PP) return;
1402 pFormat += 2;
1404 if (pStubMsg->PointerLength)
1406 saved_buffer_length = pStubMsg->BufferLength;
1407 pStubMsg->BufferLength = pStubMsg->PointerLength;
1408 pStubMsg->PointerLength = 0;
1411 while (pFormat[0] != RPC_FC_END) {
1412 switch (pFormat[0]) {
1413 default:
1414 FIXME("unknown repeat type %d\n", pFormat[0]);
1415 case RPC_FC_NO_REPEAT:
1416 rep = 1;
1417 stride = 0;
1418 count = 1;
1419 pFormat += 2;
1420 break;
1421 case RPC_FC_FIXED_REPEAT:
1422 rep = *(const WORD*)&pFormat[2];
1423 stride = *(const WORD*)&pFormat[4];
1424 count = *(const WORD*)&pFormat[8];
1425 pFormat += 10;
1426 break;
1427 case RPC_FC_VARIABLE_REPEAT:
1428 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1429 stride = *(const WORD*)&pFormat[2];
1430 count = *(const WORD*)&pFormat[6];
1431 pFormat += 8;
1432 break;
1434 for (i = 0; i < rep; i++) {
1435 PFORMAT_STRING info = pFormat;
1436 unsigned char *membase = pMemory + (i * stride);
1437 unsigned u;
1439 for (u=0; u<count; u++,info+=8) {
1440 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1441 unsigned char *saved_memory = pStubMsg->Memory;
1443 pStubMsg->Memory = pMemory;
1444 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1445 pStubMsg->Memory = saved_memory;
1448 pFormat += 8 * count;
1451 if (saved_buffer_length)
1453 pStubMsg->PointerLength = pStubMsg->BufferLength;
1454 pStubMsg->BufferLength = saved_buffer_length;
1458 /***********************************************************************
1459 * EmbeddedPointerMemorySize [internal]
1461 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1462 PFORMAT_STRING pFormat)
1464 unsigned char *Mark = pStubMsg->BufferMark;
1465 unsigned rep, count, stride;
1466 unsigned i;
1468 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1470 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1472 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1474 if (*pFormat != RPC_FC_PP) return 0;
1475 pFormat += 2;
1477 while (pFormat[0] != RPC_FC_END) {
1478 switch (pFormat[0]) {
1479 default:
1480 FIXME("unknown repeat type %d\n", pFormat[0]);
1481 case RPC_FC_NO_REPEAT:
1482 rep = 1;
1483 stride = 0;
1484 count = 1;
1485 pFormat += 2;
1486 break;
1487 case RPC_FC_FIXED_REPEAT:
1488 rep = *(const WORD*)&pFormat[2];
1489 stride = *(const WORD*)&pFormat[4];
1490 count = *(const WORD*)&pFormat[8];
1491 pFormat += 10;
1492 break;
1493 case RPC_FC_VARIABLE_REPEAT:
1494 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1495 stride = *(const WORD*)&pFormat[2];
1496 count = *(const WORD*)&pFormat[6];
1497 pFormat += 8;
1498 break;
1500 for (i = 0; i < rep; i++) {
1501 PFORMAT_STRING info = pFormat;
1502 unsigned char *bufbase = Mark + (i * stride);
1503 unsigned u;
1504 for (u=0; u<count; u++,info+=8) {
1505 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1506 PointerMemorySize(pStubMsg, bufptr, info+4);
1509 pFormat += 8 * count;
1512 return 0;
1515 /***********************************************************************
1516 * EmbeddedPointerFree [internal]
1518 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1519 unsigned char *pMemory,
1520 PFORMAT_STRING pFormat)
1522 unsigned rep, count, stride;
1523 unsigned i;
1525 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1526 if (*pFormat != RPC_FC_PP) return;
1527 pFormat += 2;
1529 while (pFormat[0] != RPC_FC_END) {
1530 switch (pFormat[0]) {
1531 default:
1532 FIXME("unknown repeat type %d\n", pFormat[0]);
1533 case RPC_FC_NO_REPEAT:
1534 rep = 1;
1535 stride = 0;
1536 count = 1;
1537 pFormat += 2;
1538 break;
1539 case RPC_FC_FIXED_REPEAT:
1540 rep = *(const WORD*)&pFormat[2];
1541 stride = *(const WORD*)&pFormat[4];
1542 count = *(const WORD*)&pFormat[8];
1543 pFormat += 10;
1544 break;
1545 case RPC_FC_VARIABLE_REPEAT:
1546 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1547 stride = *(const WORD*)&pFormat[2];
1548 count = *(const WORD*)&pFormat[6];
1549 pFormat += 8;
1550 break;
1552 for (i = 0; i < rep; i++) {
1553 PFORMAT_STRING info = pFormat;
1554 unsigned char *membase = pMemory + (i * stride);
1555 unsigned u;
1557 for (u=0; u<count; u++,info+=8) {
1558 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1559 unsigned char *saved_memory = pStubMsg->Memory;
1561 pStubMsg->Memory = pMemory;
1562 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1563 pStubMsg->Memory = saved_memory;
1566 pFormat += 8 * count;
1570 /***********************************************************************
1571 * NdrPointerMarshall [RPCRT4.@]
1573 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1574 unsigned char *pMemory,
1575 PFORMAT_STRING pFormat)
1577 unsigned char *Buffer;
1579 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1581 /* incremement the buffer here instead of in PointerMarshall,
1582 * as that is used by embedded pointers which already handle the incrementing
1583 * the buffer, and shouldn't write any additional pointer data to the wire */
1584 if (*pFormat != RPC_FC_RP)
1586 ALIGN_POINTER(pStubMsg->Buffer, 4);
1587 Buffer = pStubMsg->Buffer;
1588 safe_buffer_increment(pStubMsg, 4);
1590 else
1591 Buffer = pStubMsg->Buffer;
1593 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1595 return NULL;
1598 /***********************************************************************
1599 * NdrPointerUnmarshall [RPCRT4.@]
1601 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1602 unsigned char **ppMemory,
1603 PFORMAT_STRING pFormat,
1604 unsigned char fMustAlloc)
1606 unsigned char *Buffer;
1608 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1610 /* incremement the buffer here instead of in PointerUnmarshall,
1611 * as that is used by embedded pointers which already handle the incrementing
1612 * the buffer, and shouldn't read any additional pointer data from the
1613 * buffer */
1614 if (*pFormat != RPC_FC_RP)
1616 ALIGN_POINTER(pStubMsg->Buffer, 4);
1617 Buffer = pStubMsg->Buffer;
1618 safe_buffer_increment(pStubMsg, 4);
1620 else
1621 Buffer = pStubMsg->Buffer;
1623 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1625 return NULL;
1628 /***********************************************************************
1629 * NdrPointerBufferSize [RPCRT4.@]
1631 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1632 unsigned char *pMemory,
1633 PFORMAT_STRING pFormat)
1635 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1637 /* incremement the buffer length here instead of in PointerBufferSize,
1638 * as that is used by embedded pointers which already handle the buffer
1639 * length, and shouldn't write anything more to the wire */
1640 if (*pFormat != RPC_FC_RP)
1642 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1643 safe_buffer_length_increment(pStubMsg, 4);
1646 PointerBufferSize(pStubMsg, pMemory, pFormat);
1649 /***********************************************************************
1650 * NdrPointerMemorySize [RPCRT4.@]
1652 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1653 PFORMAT_STRING pFormat)
1655 /* unsigned size = *(LPWORD)(pFormat+2); */
1656 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1657 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1658 return 0;
1661 /***********************************************************************
1662 * NdrPointerFree [RPCRT4.@]
1664 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1665 unsigned char *pMemory,
1666 PFORMAT_STRING pFormat)
1668 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1669 PointerFree(pStubMsg, pMemory, pFormat);
1672 /***********************************************************************
1673 * NdrSimpleTypeMarshall [RPCRT4.@]
1675 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1676 unsigned char FormatChar )
1678 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1681 /***********************************************************************
1682 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1684 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1685 unsigned char FormatChar )
1687 NdrBaseTypeUnmarshall(pStubMsg, &pMemory, &FormatChar, 0);
1690 /***********************************************************************
1691 * NdrSimpleStructMarshall [RPCRT4.@]
1693 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1694 unsigned char *pMemory,
1695 PFORMAT_STRING pFormat)
1697 unsigned size = *(const WORD*)(pFormat+2);
1698 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1700 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1702 pStubMsg->BufferMark = pStubMsg->Buffer;
1703 safe_copy_to_buffer(pStubMsg, pMemory, size);
1705 if (pFormat[0] != RPC_FC_STRUCT)
1706 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1708 return NULL;
1711 /***********************************************************************
1712 * NdrSimpleStructUnmarshall [RPCRT4.@]
1714 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1715 unsigned char **ppMemory,
1716 PFORMAT_STRING pFormat,
1717 unsigned char fMustAlloc)
1719 unsigned size = *(const WORD*)(pFormat+2);
1720 unsigned char *saved_buffer;
1721 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1723 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1725 if (fMustAlloc)
1726 *ppMemory = NdrAllocate(pStubMsg, size);
1727 else
1729 if (!pStubMsg->IsClient && !*ppMemory)
1730 /* for servers, we just point straight into the RPC buffer */
1731 *ppMemory = pStubMsg->Buffer;
1734 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1735 safe_buffer_increment(pStubMsg, size);
1736 if (pFormat[0] == RPC_FC_PSTRUCT)
1737 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1739 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1740 if (*ppMemory != saved_buffer)
1741 memcpy(*ppMemory, saved_buffer, size);
1743 return NULL;
1746 /***********************************************************************
1747 * NdrSimpleStructBufferSize [RPCRT4.@]
1749 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1750 unsigned char *pMemory,
1751 PFORMAT_STRING pFormat)
1753 unsigned size = *(const WORD*)(pFormat+2);
1754 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1756 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1758 safe_buffer_length_increment(pStubMsg, size);
1759 if (pFormat[0] != RPC_FC_STRUCT)
1760 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1763 /***********************************************************************
1764 * NdrSimpleStructMemorySize [RPCRT4.@]
1766 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1767 PFORMAT_STRING pFormat)
1769 unsigned short size = *(const WORD *)(pFormat+2);
1771 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1773 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1774 pStubMsg->MemorySize += size;
1775 safe_buffer_increment(pStubMsg, size);
1777 if (pFormat[0] != RPC_FC_STRUCT)
1778 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1779 return size;
1782 /***********************************************************************
1783 * NdrSimpleStructFree [RPCRT4.@]
1785 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1786 unsigned char *pMemory,
1787 PFORMAT_STRING pFormat)
1789 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1790 if (pFormat[0] != RPC_FC_STRUCT)
1791 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1795 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE *pStubMsg,
1796 PFORMAT_STRING pFormat)
1798 switch (*pFormat) {
1799 case RPC_FC_STRUCT:
1800 case RPC_FC_PSTRUCT:
1801 case RPC_FC_CSTRUCT:
1802 case RPC_FC_BOGUS_STRUCT:
1803 case RPC_FC_SMFARRAY:
1804 case RPC_FC_SMVARRAY:
1805 return *(const WORD*)&pFormat[2];
1806 case RPC_FC_USER_MARSHAL:
1807 return *(const WORD*)&pFormat[4];
1808 case RPC_FC_NON_ENCAPSULATED_UNION:
1809 pFormat += 2;
1810 if (pStubMsg->fHasNewCorrDesc)
1811 pFormat += 6;
1812 else
1813 pFormat += 4;
1815 pFormat += *(const SHORT*)pFormat;
1816 return *(const SHORT*)pFormat;
1817 case RPC_FC_IP:
1818 return sizeof(void *);
1819 default:
1820 FIXME("unhandled embedded type %02x\n", *pFormat);
1822 return 0;
1826 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1827 PFORMAT_STRING pFormat)
1829 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1831 if (!m)
1833 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1834 return 0;
1837 return m(pStubMsg, pFormat);
1841 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1842 unsigned char *pMemory,
1843 PFORMAT_STRING pFormat,
1844 PFORMAT_STRING pPointer)
1846 PFORMAT_STRING desc;
1847 NDR_MARSHALL m;
1848 unsigned long size;
1850 while (*pFormat != RPC_FC_END) {
1851 switch (*pFormat) {
1852 case RPC_FC_BYTE:
1853 case RPC_FC_CHAR:
1854 case RPC_FC_SMALL:
1855 case RPC_FC_USMALL:
1856 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
1857 safe_copy_to_buffer(pStubMsg, pMemory, 1);
1858 pMemory += 1;
1859 break;
1860 case RPC_FC_WCHAR:
1861 case RPC_FC_SHORT:
1862 case RPC_FC_USHORT:
1863 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1864 safe_copy_to_buffer(pStubMsg, pMemory, 2);
1865 pMemory += 2;
1866 break;
1867 case RPC_FC_LONG:
1868 case RPC_FC_ULONG:
1869 case RPC_FC_ENUM32:
1870 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
1871 safe_copy_to_buffer(pStubMsg, pMemory, 4);
1872 pMemory += 4;
1873 break;
1874 case RPC_FC_HYPER:
1875 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1876 safe_copy_to_buffer(pStubMsg, pMemory, 8);
1877 pMemory += 8;
1878 break;
1879 case RPC_FC_POINTER:
1881 unsigned char *saved_buffer;
1882 int pointer_buffer_mark_set = 0;
1883 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1884 saved_buffer = pStubMsg->Buffer;
1885 if (pStubMsg->PointerBufferMark)
1887 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1888 pStubMsg->PointerBufferMark = NULL;
1889 pointer_buffer_mark_set = 1;
1891 else
1892 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
1893 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
1894 if (pointer_buffer_mark_set)
1896 STD_OVERFLOW_CHECK(pStubMsg);
1897 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1898 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
1900 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
1901 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
1902 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1904 pStubMsg->Buffer = saved_buffer + 4;
1906 pPointer += 4;
1907 pMemory += 4;
1908 break;
1910 case RPC_FC_ALIGNM4:
1911 ALIGN_POINTER(pMemory, 4);
1912 break;
1913 case RPC_FC_ALIGNM8:
1914 ALIGN_POINTER(pMemory, 8);
1915 break;
1916 case RPC_FC_STRUCTPAD1:
1917 case RPC_FC_STRUCTPAD2:
1918 case RPC_FC_STRUCTPAD3:
1919 case RPC_FC_STRUCTPAD4:
1920 case RPC_FC_STRUCTPAD5:
1921 case RPC_FC_STRUCTPAD6:
1922 case RPC_FC_STRUCTPAD7:
1923 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1924 break;
1925 case RPC_FC_EMBEDDED_COMPLEX:
1926 pMemory += pFormat[1];
1927 pFormat += 2;
1928 desc = pFormat + *(const SHORT*)pFormat;
1929 size = EmbeddedComplexSize(pStubMsg, desc);
1930 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1931 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1932 if (m)
1934 /* for some reason interface pointers aren't generated as
1935 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
1936 * they still need the derefencing treatment that pointers are
1937 * given */
1938 if (*desc == RPC_FC_IP)
1939 m(pStubMsg, *(unsigned char **)pMemory, desc);
1940 else
1941 m(pStubMsg, pMemory, desc);
1943 else FIXME("no marshaller for embedded type %02x\n", *desc);
1944 pMemory += size;
1945 pFormat += 2;
1946 continue;
1947 case RPC_FC_PAD:
1948 break;
1949 default:
1950 FIXME("unhandled format 0x%02x\n", *pFormat);
1952 pFormat++;
1955 return pMemory;
1958 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1959 unsigned char *pMemory,
1960 PFORMAT_STRING pFormat,
1961 PFORMAT_STRING pPointer)
1963 PFORMAT_STRING desc;
1964 NDR_UNMARSHALL m;
1965 unsigned long size;
1967 while (*pFormat != RPC_FC_END) {
1968 switch (*pFormat) {
1969 case RPC_FC_BYTE:
1970 case RPC_FC_CHAR:
1971 case RPC_FC_SMALL:
1972 case RPC_FC_USMALL:
1973 safe_copy_from_buffer(pStubMsg, pMemory, 1);
1974 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
1975 pMemory += 1;
1976 break;
1977 case RPC_FC_WCHAR:
1978 case RPC_FC_SHORT:
1979 case RPC_FC_USHORT:
1980 safe_copy_from_buffer(pStubMsg, pMemory, 2);
1981 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1982 pMemory += 2;
1983 break;
1984 case RPC_FC_LONG:
1985 case RPC_FC_ULONG:
1986 case RPC_FC_ENUM32:
1987 safe_copy_from_buffer(pStubMsg, pMemory, 4);
1988 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
1989 pMemory += 4;
1990 break;
1991 case RPC_FC_HYPER:
1992 safe_copy_from_buffer(pStubMsg, pMemory, 8);
1993 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1994 pMemory += 8;
1995 break;
1996 case RPC_FC_POINTER:
1998 unsigned char *saved_buffer;
1999 int pointer_buffer_mark_set = 0;
2000 TRACE("pointer => %p\n", pMemory);
2001 ALIGN_POINTER(pStubMsg->Buffer, 4);
2002 saved_buffer = pStubMsg->Buffer;
2003 if (pStubMsg->PointerBufferMark)
2005 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2006 pStubMsg->PointerBufferMark = NULL;
2007 pointer_buffer_mark_set = 1;
2009 else
2010 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2012 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, TRUE);
2013 if (pointer_buffer_mark_set)
2015 STD_OVERFLOW_CHECK(pStubMsg);
2016 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2017 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2019 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2020 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2021 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2023 pStubMsg->Buffer = saved_buffer + 4;
2025 pPointer += 4;
2026 pMemory += 4;
2027 break;
2029 case RPC_FC_ALIGNM4:
2030 ALIGN_POINTER(pMemory, 4);
2031 break;
2032 case RPC_FC_ALIGNM8:
2033 ALIGN_POINTER(pMemory, 8);
2034 break;
2035 case RPC_FC_STRUCTPAD1:
2036 case RPC_FC_STRUCTPAD2:
2037 case RPC_FC_STRUCTPAD3:
2038 case RPC_FC_STRUCTPAD4:
2039 case RPC_FC_STRUCTPAD5:
2040 case RPC_FC_STRUCTPAD6:
2041 case RPC_FC_STRUCTPAD7:
2042 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2043 break;
2044 case RPC_FC_EMBEDDED_COMPLEX:
2045 pMemory += pFormat[1];
2046 pFormat += 2;
2047 desc = pFormat + *(const SHORT*)pFormat;
2048 size = EmbeddedComplexSize(pStubMsg, desc);
2049 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2050 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2051 memset(pMemory, 0, size); /* just in case */
2052 if (m)
2054 /* for some reason interface pointers aren't generated as
2055 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2056 * they still need the derefencing treatment that pointers are
2057 * given */
2058 if (*desc == RPC_FC_IP)
2059 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2060 else
2061 m(pStubMsg, &pMemory, desc, FALSE);
2063 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2064 pMemory += size;
2065 pFormat += 2;
2066 continue;
2067 case RPC_FC_PAD:
2068 break;
2069 default:
2070 FIXME("unhandled format %d\n", *pFormat);
2072 pFormat++;
2075 return pMemory;
2078 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2079 unsigned char *pMemory,
2080 PFORMAT_STRING pFormat,
2081 PFORMAT_STRING pPointer)
2083 PFORMAT_STRING desc;
2084 NDR_BUFFERSIZE m;
2085 unsigned long size;
2087 while (*pFormat != RPC_FC_END) {
2088 switch (*pFormat) {
2089 case RPC_FC_BYTE:
2090 case RPC_FC_CHAR:
2091 case RPC_FC_SMALL:
2092 case RPC_FC_USMALL:
2093 safe_buffer_length_increment(pStubMsg, 1);
2094 pMemory += 1;
2095 break;
2096 case RPC_FC_WCHAR:
2097 case RPC_FC_SHORT:
2098 case RPC_FC_USHORT:
2099 safe_buffer_length_increment(pStubMsg, 2);
2100 pMemory += 2;
2101 break;
2102 case RPC_FC_LONG:
2103 case RPC_FC_ULONG:
2104 case RPC_FC_ENUM32:
2105 safe_buffer_length_increment(pStubMsg, 4);
2106 pMemory += 4;
2107 break;
2108 case RPC_FC_HYPER:
2109 safe_buffer_length_increment(pStubMsg, 8);
2110 pMemory += 8;
2111 break;
2112 case RPC_FC_POINTER:
2113 if (!pStubMsg->IgnoreEmbeddedPointers)
2115 int saved_buffer_length = pStubMsg->BufferLength;
2116 pStubMsg->BufferLength = pStubMsg->PointerLength;
2117 pStubMsg->PointerLength = 0;
2118 if(!pStubMsg->BufferLength)
2119 ERR("BufferLength == 0??\n");
2120 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2121 pStubMsg->PointerLength = pStubMsg->BufferLength;
2122 pStubMsg->BufferLength = saved_buffer_length;
2124 safe_buffer_length_increment(pStubMsg, 4);
2125 pPointer += 4;
2126 pMemory += 4;
2127 break;
2128 case RPC_FC_ALIGNM4:
2129 ALIGN_POINTER(pMemory, 4);
2130 break;
2131 case RPC_FC_ALIGNM8:
2132 ALIGN_POINTER(pMemory, 8);
2133 break;
2134 case RPC_FC_STRUCTPAD1:
2135 case RPC_FC_STRUCTPAD2:
2136 case RPC_FC_STRUCTPAD3:
2137 case RPC_FC_STRUCTPAD4:
2138 case RPC_FC_STRUCTPAD5:
2139 case RPC_FC_STRUCTPAD6:
2140 case RPC_FC_STRUCTPAD7:
2141 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2142 break;
2143 case RPC_FC_EMBEDDED_COMPLEX:
2144 pMemory += pFormat[1];
2145 pFormat += 2;
2146 desc = pFormat + *(const SHORT*)pFormat;
2147 size = EmbeddedComplexSize(pStubMsg, desc);
2148 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2149 if (m)
2151 /* for some reason interface pointers aren't generated as
2152 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2153 * they still need the derefencing treatment that pointers are
2154 * given */
2155 if (*desc == RPC_FC_IP)
2156 m(pStubMsg, *(unsigned char **)pMemory, desc);
2157 else
2158 m(pStubMsg, pMemory, desc);
2160 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2161 pMemory += size;
2162 pFormat += 2;
2163 continue;
2164 case RPC_FC_PAD:
2165 break;
2166 default:
2167 FIXME("unhandled format 0x%02x\n", *pFormat);
2169 pFormat++;
2172 return pMemory;
2175 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2176 unsigned char *pMemory,
2177 PFORMAT_STRING pFormat,
2178 PFORMAT_STRING pPointer)
2180 PFORMAT_STRING desc;
2181 NDR_FREE m;
2182 unsigned long size;
2184 while (*pFormat != RPC_FC_END) {
2185 switch (*pFormat) {
2186 case RPC_FC_BYTE:
2187 case RPC_FC_CHAR:
2188 case RPC_FC_SMALL:
2189 case RPC_FC_USMALL:
2190 pMemory += 1;
2191 break;
2192 case RPC_FC_WCHAR:
2193 case RPC_FC_SHORT:
2194 case RPC_FC_USHORT:
2195 pMemory += 2;
2196 break;
2197 case RPC_FC_LONG:
2198 case RPC_FC_ULONG:
2199 case RPC_FC_ENUM32:
2200 pMemory += 4;
2201 break;
2202 case RPC_FC_HYPER:
2203 pMemory += 8;
2204 break;
2205 case RPC_FC_POINTER:
2206 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
2207 pPointer += 4;
2208 pMemory += 4;
2209 break;
2210 case RPC_FC_ALIGNM4:
2211 ALIGN_POINTER(pMemory, 4);
2212 break;
2213 case RPC_FC_ALIGNM8:
2214 ALIGN_POINTER(pMemory, 8);
2215 break;
2216 case RPC_FC_STRUCTPAD1:
2217 case RPC_FC_STRUCTPAD2:
2218 case RPC_FC_STRUCTPAD3:
2219 case RPC_FC_STRUCTPAD4:
2220 case RPC_FC_STRUCTPAD5:
2221 case RPC_FC_STRUCTPAD6:
2222 case RPC_FC_STRUCTPAD7:
2223 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2224 break;
2225 case RPC_FC_EMBEDDED_COMPLEX:
2226 pMemory += pFormat[1];
2227 pFormat += 2;
2228 desc = pFormat + *(const SHORT*)pFormat;
2229 size = EmbeddedComplexSize(pStubMsg, desc);
2230 m = NdrFreer[*desc & NDR_TABLE_MASK];
2231 if (m)
2233 /* for some reason interface pointers aren't generated as
2234 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2235 * they still need the derefencing treatment that pointers are
2236 * given */
2237 if (*desc == RPC_FC_IP)
2238 m(pStubMsg, *(unsigned char **)pMemory, desc);
2239 else
2240 m(pStubMsg, pMemory, desc);
2242 else FIXME("no freer for embedded type %02x\n", *desc);
2243 pMemory += size;
2244 pFormat += 2;
2245 continue;
2246 case RPC_FC_PAD:
2247 break;
2248 default:
2249 FIXME("unhandled format 0x%02x\n", *pFormat);
2251 pFormat++;
2254 return pMemory;
2257 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2258 PFORMAT_STRING pFormat)
2260 PFORMAT_STRING desc;
2261 unsigned long size = 0;
2263 while (*pFormat != RPC_FC_END) {
2264 switch (*pFormat) {
2265 case RPC_FC_BYTE:
2266 case RPC_FC_CHAR:
2267 case RPC_FC_SMALL:
2268 case RPC_FC_USMALL:
2269 size += 1;
2270 safe_buffer_increment(pStubMsg, 1);
2271 break;
2272 case RPC_FC_WCHAR:
2273 case RPC_FC_SHORT:
2274 case RPC_FC_USHORT:
2275 size += 2;
2276 safe_buffer_increment(pStubMsg, 2);
2277 break;
2278 case RPC_FC_LONG:
2279 case RPC_FC_ULONG:
2280 case RPC_FC_ENUM32:
2281 size += 4;
2282 safe_buffer_increment(pStubMsg, 4);
2283 break;
2284 case RPC_FC_HYPER:
2285 size += 8;
2286 safe_buffer_increment(pStubMsg, 8);
2287 break;
2288 case RPC_FC_POINTER:
2289 size += 4;
2290 safe_buffer_increment(pStubMsg, 4);
2291 if (!pStubMsg->IgnoreEmbeddedPointers)
2292 FIXME("embedded pointers\n");
2293 break;
2294 case RPC_FC_ALIGNM4:
2295 ALIGN_LENGTH(size, 4);
2296 ALIGN_POINTER(pStubMsg->Buffer, 4);
2297 break;
2298 case RPC_FC_ALIGNM8:
2299 ALIGN_LENGTH(size, 8);
2300 ALIGN_POINTER(pStubMsg->Buffer, 8);
2301 break;
2302 case RPC_FC_STRUCTPAD1:
2303 case RPC_FC_STRUCTPAD2:
2304 case RPC_FC_STRUCTPAD3:
2305 case RPC_FC_STRUCTPAD4:
2306 case RPC_FC_STRUCTPAD5:
2307 case RPC_FC_STRUCTPAD6:
2308 case RPC_FC_STRUCTPAD7:
2309 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2310 break;
2311 case RPC_FC_EMBEDDED_COMPLEX:
2312 size += pFormat[1];
2313 pFormat += 2;
2314 desc = pFormat + *(const SHORT*)pFormat;
2315 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2316 pFormat += 2;
2317 continue;
2318 case RPC_FC_PAD:
2319 break;
2320 default:
2321 FIXME("unhandled format 0x%02x\n", *pFormat);
2323 pFormat++;
2326 return size;
2329 /***********************************************************************
2330 * NdrComplexStructMarshall [RPCRT4.@]
2332 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2333 unsigned char *pMemory,
2334 PFORMAT_STRING pFormat)
2336 PFORMAT_STRING conf_array = NULL;
2337 PFORMAT_STRING pointer_desc = NULL;
2338 unsigned char *OldMemory = pStubMsg->Memory;
2339 int pointer_buffer_mark_set = 0;
2341 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2343 if (!pStubMsg->PointerBufferMark)
2345 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2346 /* save buffer length */
2347 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2349 /* get the buffer pointer after complex array data, but before
2350 * pointer data */
2351 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2352 pStubMsg->IgnoreEmbeddedPointers = 1;
2353 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2354 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2356 /* save it for use by embedded pointer code later */
2357 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2358 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
2359 pointer_buffer_mark_set = 1;
2361 /* restore the original buffer length */
2362 pStubMsg->BufferLength = saved_buffer_length;
2365 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2367 pFormat += 4;
2368 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2369 pFormat += 2;
2370 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2371 pFormat += 2;
2373 pStubMsg->Memory = pMemory;
2375 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2377 if (conf_array)
2378 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2380 pStubMsg->Memory = OldMemory;
2382 if (pointer_buffer_mark_set)
2384 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2385 pStubMsg->PointerBufferMark = NULL;
2388 STD_OVERFLOW_CHECK(pStubMsg);
2390 return NULL;
2393 /***********************************************************************
2394 * NdrComplexStructUnmarshall [RPCRT4.@]
2396 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2397 unsigned char **ppMemory,
2398 PFORMAT_STRING pFormat,
2399 unsigned char fMustAlloc)
2401 unsigned size = *(const WORD*)(pFormat+2);
2402 PFORMAT_STRING conf_array = NULL;
2403 PFORMAT_STRING pointer_desc = NULL;
2404 unsigned char *pMemory;
2405 int pointer_buffer_mark_set = 0;
2407 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2409 if (!pStubMsg->PointerBufferMark)
2411 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2412 /* save buffer pointer */
2413 unsigned char *saved_buffer = pStubMsg->Buffer;
2415 /* get the buffer pointer after complex array data, but before
2416 * pointer data */
2417 pStubMsg->IgnoreEmbeddedPointers = 1;
2418 NdrComplexStructMemorySize(pStubMsg, pFormat);
2419 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2421 /* save it for use by embedded pointer code later */
2422 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2423 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
2424 pointer_buffer_mark_set = 1;
2426 /* restore the original buffer */
2427 pStubMsg->Buffer = saved_buffer;
2430 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2432 if (fMustAlloc || !*ppMemory)
2434 *ppMemory = NdrAllocate(pStubMsg, size);
2435 memset(*ppMemory, 0, size);
2438 pFormat += 4;
2439 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2440 pFormat += 2;
2441 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2442 pFormat += 2;
2444 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2446 if (conf_array)
2447 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2449 if (pointer_buffer_mark_set)
2451 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2452 pStubMsg->PointerBufferMark = NULL;
2455 return NULL;
2458 /***********************************************************************
2459 * NdrComplexStructBufferSize [RPCRT4.@]
2461 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2462 unsigned char *pMemory,
2463 PFORMAT_STRING pFormat)
2465 PFORMAT_STRING conf_array = NULL;
2466 PFORMAT_STRING pointer_desc = NULL;
2467 unsigned char *OldMemory = pStubMsg->Memory;
2468 int pointer_length_set = 0;
2470 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2472 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2474 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2476 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2477 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2479 /* get the buffer length after complex struct data, but before
2480 * pointer data */
2481 pStubMsg->IgnoreEmbeddedPointers = 1;
2482 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2483 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2485 /* save it for use by embedded pointer code later */
2486 pStubMsg->PointerLength = pStubMsg->BufferLength;
2487 pointer_length_set = 1;
2488 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
2490 /* restore the original buffer length */
2491 pStubMsg->BufferLength = saved_buffer_length;
2494 pFormat += 4;
2495 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2496 pFormat += 2;
2497 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2498 pFormat += 2;
2500 pStubMsg->Memory = pMemory;
2502 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2504 if (conf_array)
2505 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2507 pStubMsg->Memory = OldMemory;
2509 if(pointer_length_set)
2511 pStubMsg->BufferLength = pStubMsg->PointerLength;
2512 pStubMsg->PointerLength = 0;
2517 /***********************************************************************
2518 * NdrComplexStructMemorySize [RPCRT4.@]
2520 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2521 PFORMAT_STRING pFormat)
2523 unsigned size = *(const WORD*)(pFormat+2);
2524 PFORMAT_STRING conf_array = NULL;
2525 PFORMAT_STRING pointer_desc = NULL;
2527 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2529 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2531 pFormat += 4;
2532 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2533 pFormat += 2;
2534 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2535 pFormat += 2;
2537 ComplexStructMemorySize(pStubMsg, pFormat);
2539 if (conf_array)
2540 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2542 return size;
2545 /***********************************************************************
2546 * NdrComplexStructFree [RPCRT4.@]
2548 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2549 unsigned char *pMemory,
2550 PFORMAT_STRING pFormat)
2552 PFORMAT_STRING conf_array = NULL;
2553 PFORMAT_STRING pointer_desc = NULL;
2554 unsigned char *OldMemory = pStubMsg->Memory;
2556 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2558 pFormat += 4;
2559 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2560 pFormat += 2;
2561 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2562 pFormat += 2;
2564 pStubMsg->Memory = pMemory;
2566 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2568 if (conf_array)
2569 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2571 pStubMsg->Memory = OldMemory;
2574 /***********************************************************************
2575 * NdrConformantArrayMarshall [RPCRT4.@]
2577 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2578 unsigned char *pMemory,
2579 PFORMAT_STRING pFormat)
2581 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2582 unsigned char alignment = pFormat[1] + 1;
2584 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2585 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2587 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2589 WriteConformance(pStubMsg);
2591 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2593 size = safe_multiply(esize, pStubMsg->MaxCount);
2594 pStubMsg->BufferMark = pStubMsg->Buffer;
2595 safe_copy_to_buffer(pStubMsg, pMemory, size);
2597 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2599 return NULL;
2602 /***********************************************************************
2603 * NdrConformantArrayUnmarshall [RPCRT4.@]
2605 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2606 unsigned char **ppMemory,
2607 PFORMAT_STRING pFormat,
2608 unsigned char fMustAlloc)
2610 DWORD size, esize = *(const WORD*)(pFormat+2);
2611 unsigned char alignment = pFormat[1] + 1;
2612 unsigned char *saved_buffer;
2614 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2615 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2617 pFormat = ReadConformance(pStubMsg, pFormat+4);
2619 size = safe_multiply(esize, pStubMsg->MaxCount);
2620 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2622 if (fMustAlloc)
2623 *ppMemory = NdrAllocate(pStubMsg, size);
2624 else
2626 if (!pStubMsg->IsClient && !*ppMemory)
2627 /* for servers, we just point straight into the RPC buffer */
2628 *ppMemory = pStubMsg->Buffer;
2631 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
2632 safe_buffer_increment(pStubMsg, size);
2633 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2635 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2636 if (*ppMemory != saved_buffer)
2637 memcpy(*ppMemory, saved_buffer, size);
2639 return NULL;
2642 /***********************************************************************
2643 * NdrConformantArrayBufferSize [RPCRT4.@]
2645 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2646 unsigned char *pMemory,
2647 PFORMAT_STRING pFormat)
2649 DWORD size, esize = *(const WORD*)(pFormat+2);
2650 unsigned char alignment = pFormat[1] + 1;
2652 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2653 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2655 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2657 SizeConformance(pStubMsg);
2659 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2661 size = safe_multiply(esize, pStubMsg->MaxCount);
2662 /* conformance value plus array */
2663 safe_buffer_length_increment(pStubMsg, size);
2665 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2668 /***********************************************************************
2669 * NdrConformantArrayMemorySize [RPCRT4.@]
2671 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2672 PFORMAT_STRING pFormat)
2674 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2675 unsigned char alignment = pFormat[1] + 1;
2677 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2678 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2680 pFormat = ReadConformance(pStubMsg, pFormat+4);
2681 size = safe_multiply(esize, pStubMsg->MaxCount);
2682 pStubMsg->MemorySize += size;
2684 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2685 pStubMsg->BufferMark = pStubMsg->Buffer;
2686 safe_buffer_increment(pStubMsg, size);
2688 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2690 return pStubMsg->MemorySize;
2693 /***********************************************************************
2694 * NdrConformantArrayFree [RPCRT4.@]
2696 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2697 unsigned char *pMemory,
2698 PFORMAT_STRING pFormat)
2700 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2701 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2703 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2705 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2709 /***********************************************************************
2710 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2712 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2713 unsigned char* pMemory,
2714 PFORMAT_STRING pFormat )
2716 ULONG bufsize;
2717 unsigned char alignment = pFormat[1] + 1;
2718 DWORD esize = *(const WORD*)(pFormat+2);
2720 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2722 if (pFormat[0] != RPC_FC_CVARRAY)
2724 ERR("invalid format type %x\n", pFormat[0]);
2725 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2726 return NULL;
2729 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2730 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2732 WriteConformance(pStubMsg);
2733 WriteVariance(pStubMsg);
2735 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2737 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2739 pStubMsg->BufferMark = pStubMsg->Buffer;
2740 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
2742 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2744 return NULL;
2748 /***********************************************************************
2749 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2751 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2752 unsigned char** ppMemory,
2753 PFORMAT_STRING pFormat,
2754 unsigned char fMustAlloc )
2756 ULONG bufsize, memsize;
2757 unsigned char alignment = pFormat[1] + 1;
2758 DWORD esize = *(const WORD*)(pFormat+2);
2760 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2762 if (pFormat[0] != RPC_FC_CVARRAY)
2764 ERR("invalid format type %x\n", pFormat[0]);
2765 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2766 return NULL;
2769 pFormat = ReadConformance(pStubMsg, pFormat+4);
2770 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2772 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2774 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2775 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2777 if (!*ppMemory || fMustAlloc)
2778 *ppMemory = NdrAllocate(pStubMsg, memsize);
2779 safe_copy_from_buffer(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize);
2781 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
2783 return NULL;
2787 /***********************************************************************
2788 * NdrConformantVaryingArrayFree [RPCRT4.@]
2790 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2791 unsigned char* pMemory,
2792 PFORMAT_STRING pFormat )
2794 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2796 if (pFormat[0] != RPC_FC_CVARRAY)
2798 ERR("invalid format type %x\n", pFormat[0]);
2799 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2800 return;
2803 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2804 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2806 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2810 /***********************************************************************
2811 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2813 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2814 unsigned char* pMemory, PFORMAT_STRING pFormat )
2816 unsigned char alignment = pFormat[1] + 1;
2817 DWORD esize = *(const WORD*)(pFormat+2);
2819 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2821 if (pFormat[0] != RPC_FC_CVARRAY)
2823 ERR("invalid format type %x\n", pFormat[0]);
2824 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2825 return;
2828 /* compute size */
2829 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2830 /* compute length */
2831 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2833 SizeConformance(pStubMsg);
2834 SizeVariance(pStubMsg);
2836 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2838 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2840 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2844 /***********************************************************************
2845 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2847 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2848 PFORMAT_STRING pFormat )
2850 FIXME( "stub\n" );
2851 return 0;
2855 /***********************************************************************
2856 * NdrComplexArrayMarshall [RPCRT4.@]
2858 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2859 unsigned char *pMemory,
2860 PFORMAT_STRING pFormat)
2862 ULONG i, count, def;
2863 BOOL variance_present;
2864 unsigned char alignment;
2865 int pointer_buffer_mark_set = 0;
2867 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2869 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2871 ERR("invalid format type %x\n", pFormat[0]);
2872 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2873 return NULL;
2876 alignment = pFormat[1] + 1;
2878 if (!pStubMsg->PointerBufferMark)
2880 /* save buffer fields that may be changed by buffer sizer functions
2881 * and that may be needed later on */
2882 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2883 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2884 unsigned long saved_max_count = pStubMsg->MaxCount;
2885 unsigned long saved_offset = pStubMsg->Offset;
2886 unsigned long saved_actual_count = pStubMsg->ActualCount;
2888 /* get the buffer pointer after complex array data, but before
2889 * pointer data */
2890 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2891 pStubMsg->IgnoreEmbeddedPointers = 1;
2892 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
2893 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2895 /* save it for use by embedded pointer code later */
2896 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2897 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
2898 pointer_buffer_mark_set = 1;
2900 /* restore fields */
2901 pStubMsg->ActualCount = saved_actual_count;
2902 pStubMsg->Offset = saved_offset;
2903 pStubMsg->MaxCount = saved_max_count;
2904 pStubMsg->BufferLength = saved_buffer_length;
2907 def = *(const WORD*)&pFormat[2];
2908 pFormat += 4;
2910 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2911 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2913 variance_present = IsConformanceOrVariancePresent(pFormat);
2914 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2915 TRACE("variance = %d\n", pStubMsg->ActualCount);
2917 WriteConformance(pStubMsg);
2918 if (variance_present)
2919 WriteVariance(pStubMsg);
2921 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2923 count = pStubMsg->ActualCount;
2924 for (i = 0; i < count; i++)
2925 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2927 STD_OVERFLOW_CHECK(pStubMsg);
2929 if (pointer_buffer_mark_set)
2931 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2932 pStubMsg->PointerBufferMark = NULL;
2935 return NULL;
2938 /***********************************************************************
2939 * NdrComplexArrayUnmarshall [RPCRT4.@]
2941 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2942 unsigned char **ppMemory,
2943 PFORMAT_STRING pFormat,
2944 unsigned char fMustAlloc)
2946 ULONG i, count, size;
2947 unsigned char alignment;
2948 unsigned char *pMemory;
2949 unsigned char *saved_buffer;
2950 int pointer_buffer_mark_set = 0;
2951 int saved_ignore_embedded;
2953 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2955 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2957 ERR("invalid format type %x\n", pFormat[0]);
2958 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2959 return NULL;
2962 alignment = pFormat[1] + 1;
2964 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2965 /* save buffer pointer */
2966 saved_buffer = pStubMsg->Buffer;
2967 /* get the buffer pointer after complex array data, but before
2968 * pointer data */
2969 pStubMsg->IgnoreEmbeddedPointers = 1;
2970 pStubMsg->MemorySize = 0;
2971 NdrComplexArrayMemorySize(pStubMsg, pFormat);
2972 size = pStubMsg->MemorySize;
2973 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2975 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
2976 if (!pStubMsg->PointerBufferMark)
2978 /* save it for use by embedded pointer code later */
2979 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2980 pointer_buffer_mark_set = 1;
2982 /* restore the original buffer */
2983 pStubMsg->Buffer = saved_buffer;
2985 pFormat += 4;
2987 pFormat = ReadConformance(pStubMsg, pFormat);
2988 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2990 if (fMustAlloc || !*ppMemory)
2992 *ppMemory = NdrAllocate(pStubMsg, size);
2993 memset(*ppMemory, 0, size);
2996 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2998 pMemory = *ppMemory;
2999 count = pStubMsg->ActualCount;
3000 for (i = 0; i < count; i++)
3001 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
3003 if (pointer_buffer_mark_set)
3005 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3006 pStubMsg->PointerBufferMark = NULL;
3009 return NULL;
3012 /***********************************************************************
3013 * NdrComplexArrayBufferSize [RPCRT4.@]
3015 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3016 unsigned char *pMemory,
3017 PFORMAT_STRING pFormat)
3019 ULONG i, count, def;
3020 unsigned char alignment;
3021 BOOL variance_present;
3022 int pointer_length_set = 0;
3024 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3026 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3028 ERR("invalid format type %x\n", pFormat[0]);
3029 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3030 return;
3033 alignment = pFormat[1] + 1;
3035 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3037 /* save buffer fields that may be changed by buffer sizer functions
3038 * and that may be needed later on */
3039 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3040 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3041 unsigned long saved_max_count = pStubMsg->MaxCount;
3042 unsigned long saved_offset = pStubMsg->Offset;
3043 unsigned long saved_actual_count = pStubMsg->ActualCount;
3045 /* get the buffer pointer after complex array data, but before
3046 * pointer data */
3047 pStubMsg->IgnoreEmbeddedPointers = 1;
3048 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3049 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3051 /* save it for use by embedded pointer code later */
3052 pStubMsg->PointerLength = pStubMsg->BufferLength;
3053 pointer_length_set = 1;
3055 /* restore fields */
3056 pStubMsg->ActualCount = saved_actual_count;
3057 pStubMsg->Offset = saved_offset;
3058 pStubMsg->MaxCount = saved_max_count;
3059 pStubMsg->BufferLength = saved_buffer_length;
3061 def = *(const WORD*)&pFormat[2];
3062 pFormat += 4;
3064 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3065 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3066 SizeConformance(pStubMsg);
3068 variance_present = IsConformanceOrVariancePresent(pFormat);
3069 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3070 TRACE("variance = %d\n", pStubMsg->ActualCount);
3072 if (variance_present)
3073 SizeVariance(pStubMsg);
3075 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3077 count = pStubMsg->ActualCount;
3078 for (i = 0; i < count; i++)
3079 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
3081 if(pointer_length_set)
3083 pStubMsg->BufferLength = pStubMsg->PointerLength;
3084 pStubMsg->PointerLength = 0;
3088 /***********************************************************************
3089 * NdrComplexArrayMemorySize [RPCRT4.@]
3091 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3092 PFORMAT_STRING pFormat)
3094 ULONG i, count, esize, SavedMemorySize, MemorySize;
3095 unsigned char alignment;
3096 unsigned char *Buffer;
3098 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3100 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3102 ERR("invalid format type %x\n", pFormat[0]);
3103 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3104 return 0;
3107 alignment = pFormat[1] + 1;
3109 pFormat += 4;
3111 pFormat = ReadConformance(pStubMsg, pFormat);
3112 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3114 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3116 SavedMemorySize = pStubMsg->MemorySize;
3118 Buffer = pStubMsg->Buffer;
3119 pStubMsg->MemorySize = 0;
3120 esize = ComplexStructMemorySize(pStubMsg, pFormat);
3121 pStubMsg->Buffer = Buffer;
3123 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
3125 count = pStubMsg->ActualCount;
3126 for (i = 0; i < count; i++)
3127 ComplexStructMemorySize(pStubMsg, pFormat);
3129 pStubMsg->MemorySize = SavedMemorySize;
3131 pStubMsg->MemorySize += MemorySize;
3132 return MemorySize;
3135 /***********************************************************************
3136 * NdrComplexArrayFree [RPCRT4.@]
3138 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3139 unsigned char *pMemory,
3140 PFORMAT_STRING pFormat)
3142 ULONG i, count, def;
3144 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3146 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3148 ERR("invalid format type %x\n", pFormat[0]);
3149 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3150 return;
3153 def = *(const WORD*)&pFormat[2];
3154 pFormat += 4;
3156 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3157 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3159 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3160 TRACE("variance = %d\n", pStubMsg->ActualCount);
3162 count = pStubMsg->ActualCount;
3163 for (i = 0; i < count; i++)
3164 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
3167 static ULONG UserMarshalFlags(const MIDL_STUB_MESSAGE *pStubMsg)
3169 return MAKELONG(pStubMsg->dwDestContext,
3170 pStubMsg->RpcMsg->DataRepresentation);
3173 #define USER_MARSHAL_PTR_PREFIX \
3174 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3175 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3177 /***********************************************************************
3178 * NdrUserMarshalMarshall [RPCRT4.@]
3180 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3181 unsigned char *pMemory,
3182 PFORMAT_STRING pFormat)
3184 unsigned flags = pFormat[1];
3185 unsigned index = *(const WORD*)&pFormat[2];
3186 unsigned char *saved_buffer = NULL;
3187 ULONG uflag = UserMarshalFlags(pStubMsg);
3188 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3189 TRACE("index=%d\n", index);
3191 if (flags & USER_MARSHAL_POINTER)
3193 ALIGN_POINTER(pStubMsg->Buffer, 4);
3194 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
3195 pStubMsg->Buffer += 4;
3196 if (pStubMsg->PointerBufferMark)
3198 saved_buffer = pStubMsg->Buffer;
3199 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3200 pStubMsg->PointerBufferMark = NULL;
3202 ALIGN_POINTER(pStubMsg->Buffer, 8);
3204 else
3205 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3207 pStubMsg->Buffer =
3208 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
3209 &uflag, pStubMsg->Buffer, pMemory);
3211 if (saved_buffer)
3213 STD_OVERFLOW_CHECK(pStubMsg);
3214 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3215 pStubMsg->Buffer = saved_buffer;
3218 STD_OVERFLOW_CHECK(pStubMsg);
3220 return NULL;
3223 /***********************************************************************
3224 * NdrUserMarshalUnmarshall [RPCRT4.@]
3226 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3227 unsigned char **ppMemory,
3228 PFORMAT_STRING pFormat,
3229 unsigned char fMustAlloc)
3231 unsigned flags = pFormat[1];
3232 unsigned index = *(const WORD*)&pFormat[2];
3233 DWORD memsize = *(const WORD*)&pFormat[4];
3234 unsigned char *saved_buffer = NULL;
3235 ULONG uflag = UserMarshalFlags(pStubMsg);
3236 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3237 TRACE("index=%d\n", index);
3239 if (flags & USER_MARSHAL_POINTER)
3241 ALIGN_POINTER(pStubMsg->Buffer, 4);
3242 /* skip pointer prefix */
3243 pStubMsg->Buffer += 4;
3244 if (pStubMsg->PointerBufferMark)
3246 saved_buffer = pStubMsg->Buffer;
3247 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3248 pStubMsg->PointerBufferMark = NULL;
3250 ALIGN_POINTER(pStubMsg->Buffer, 8);
3252 else
3253 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3255 if (fMustAlloc || !*ppMemory)
3256 *ppMemory = NdrAllocate(pStubMsg, memsize);
3258 pStubMsg->Buffer =
3259 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
3260 &uflag, pStubMsg->Buffer, *ppMemory);
3262 if (saved_buffer)
3264 STD_OVERFLOW_CHECK(pStubMsg);
3265 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3266 pStubMsg->Buffer = saved_buffer;
3269 return NULL;
3272 /***********************************************************************
3273 * NdrUserMarshalBufferSize [RPCRT4.@]
3275 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3276 unsigned char *pMemory,
3277 PFORMAT_STRING pFormat)
3279 unsigned flags = pFormat[1];
3280 unsigned index = *(const WORD*)&pFormat[2];
3281 DWORD bufsize = *(const WORD*)&pFormat[6];
3282 ULONG uflag = UserMarshalFlags(pStubMsg);
3283 unsigned long saved_buffer_length = 0;
3284 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3285 TRACE("index=%d\n", index);
3287 if (flags & USER_MARSHAL_POINTER)
3289 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3290 /* skip pointer prefix */
3291 safe_buffer_length_increment(pStubMsg, 4);
3292 if (pStubMsg->IgnoreEmbeddedPointers)
3293 return;
3294 if (pStubMsg->PointerLength)
3296 saved_buffer_length = pStubMsg->BufferLength;
3297 pStubMsg->BufferLength = pStubMsg->PointerLength;
3298 pStubMsg->PointerLength = 0;
3300 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
3302 else
3303 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
3305 if (bufsize) {
3306 TRACE("size=%d\n", bufsize);
3307 safe_buffer_length_increment(pStubMsg, bufsize);
3309 else
3310 pStubMsg->BufferLength =
3311 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
3312 &uflag, pStubMsg->BufferLength, pMemory);
3314 if (saved_buffer_length)
3316 pStubMsg->PointerLength = pStubMsg->BufferLength;
3317 pStubMsg->BufferLength = saved_buffer_length;
3322 /***********************************************************************
3323 * NdrUserMarshalMemorySize [RPCRT4.@]
3325 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3326 PFORMAT_STRING pFormat)
3328 unsigned flags = pFormat[1];
3329 unsigned index = *(const WORD*)&pFormat[2];
3330 DWORD memsize = *(const WORD*)&pFormat[4];
3331 DWORD bufsize = *(const WORD*)&pFormat[6];
3333 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3334 TRACE("index=%d\n", index);
3336 pStubMsg->MemorySize += memsize;
3338 if (flags & USER_MARSHAL_POINTER)
3340 ALIGN_POINTER(pStubMsg->Buffer, 4);
3341 /* skip pointer prefix */
3342 pStubMsg->Buffer += 4;
3343 if (pStubMsg->IgnoreEmbeddedPointers)
3344 return pStubMsg->MemorySize;
3345 ALIGN_POINTER(pStubMsg->Buffer, 8);
3347 else
3348 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3350 if (!bufsize)
3351 FIXME("not implemented for varying buffer size\n");
3353 pStubMsg->Buffer += bufsize;
3355 return pStubMsg->MemorySize;
3358 /***********************************************************************
3359 * NdrUserMarshalFree [RPCRT4.@]
3361 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
3362 unsigned char *pMemory,
3363 PFORMAT_STRING pFormat)
3365 /* unsigned flags = pFormat[1]; */
3366 unsigned index = *(const WORD*)&pFormat[2];
3367 ULONG uflag = UserMarshalFlags(pStubMsg);
3368 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3369 TRACE("index=%d\n", index);
3371 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
3372 &uflag, pMemory);
3375 /***********************************************************************
3376 * NdrClearOutParameters [RPCRT4.@]
3378 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
3379 PFORMAT_STRING pFormat,
3380 void *ArgAddr)
3382 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
3385 /***********************************************************************
3386 * NdrConvert [RPCRT4.@]
3388 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
3390 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
3391 /* FIXME: since this stub doesn't do any converting, the proper behavior
3392 is to raise an exception */
3395 /***********************************************************************
3396 * NdrConvert2 [RPCRT4.@]
3398 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
3400 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3401 pStubMsg, pFormat, NumberParams);
3402 /* FIXME: since this stub doesn't do any converting, the proper behavior
3403 is to raise an exception */
3406 #include "pshpack1.h"
3407 typedef struct _NDR_CSTRUCT_FORMAT
3409 unsigned char type;
3410 unsigned char alignment;
3411 unsigned short memory_size;
3412 short offset_to_array_description;
3413 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
3414 #include "poppack.h"
3416 /***********************************************************************
3417 * NdrConformantStructMarshall [RPCRT4.@]
3419 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3420 unsigned char *pMemory,
3421 PFORMAT_STRING pFormat)
3423 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3424 PFORMAT_STRING pCArrayFormat;
3425 ULONG esize, bufsize;
3427 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3429 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3430 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3432 ERR("invalid format type %x\n", pCStructFormat->type);
3433 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3434 return NULL;
3437 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3438 pCStructFormat->offset_to_array_description;
3439 if (*pCArrayFormat != RPC_FC_CARRAY)
3441 ERR("invalid array format type %x\n", pCStructFormat->type);
3442 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3443 return NULL;
3445 esize = *(const WORD*)(pCArrayFormat+2);
3447 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3448 pCArrayFormat + 4, 0);
3450 WriteConformance(pStubMsg);
3452 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3454 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3456 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3457 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3459 ERR("integer overflow of memory_size %u with bufsize %u\n",
3460 pCStructFormat->memory_size, bufsize);
3461 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3463 /* copy constant sized part of struct */
3464 pStubMsg->BufferMark = pStubMsg->Buffer;
3465 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
3467 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3468 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3470 return NULL;
3473 /***********************************************************************
3474 * NdrConformantStructUnmarshall [RPCRT4.@]
3476 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3477 unsigned char **ppMemory,
3478 PFORMAT_STRING pFormat,
3479 unsigned char fMustAlloc)
3481 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3482 PFORMAT_STRING pCArrayFormat;
3483 ULONG esize, bufsize;
3484 unsigned char *saved_buffer;
3486 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3488 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3489 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3491 ERR("invalid format type %x\n", pCStructFormat->type);
3492 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3493 return NULL;
3495 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3496 pCStructFormat->offset_to_array_description;
3497 if (*pCArrayFormat != RPC_FC_CARRAY)
3499 ERR("invalid array format type %x\n", pCStructFormat->type);
3500 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3501 return NULL;
3503 esize = *(const WORD*)(pCArrayFormat+2);
3505 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3507 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3509 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3511 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3512 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3514 ERR("integer overflow of memory_size %u with bufsize %u\n",
3515 pCStructFormat->memory_size, bufsize);
3516 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3519 if (fMustAlloc)
3521 SIZE_T size = pCStructFormat->memory_size + bufsize;
3522 *ppMemory = NdrAllocate(pStubMsg, size);
3524 else
3526 if (!pStubMsg->IsClient && !*ppMemory)
3527 /* for servers, we just point straight into the RPC buffer */
3528 *ppMemory = pStubMsg->Buffer;
3531 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3532 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
3533 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3534 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3536 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
3537 if (*ppMemory != saved_buffer)
3538 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
3540 return NULL;
3543 /***********************************************************************
3544 * NdrConformantStructBufferSize [RPCRT4.@]
3546 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3547 unsigned char *pMemory,
3548 PFORMAT_STRING pFormat)
3550 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3551 PFORMAT_STRING pCArrayFormat;
3552 ULONG esize;
3554 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3556 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3557 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3559 ERR("invalid format type %x\n", pCStructFormat->type);
3560 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3561 return;
3563 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3564 pCStructFormat->offset_to_array_description;
3565 if (*pCArrayFormat != RPC_FC_CARRAY)
3567 ERR("invalid array format type %x\n", pCStructFormat->type);
3568 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3569 return;
3571 esize = *(const WORD*)(pCArrayFormat+2);
3573 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
3574 SizeConformance(pStubMsg);
3576 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
3578 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3580 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
3581 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
3583 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3584 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3587 /***********************************************************************
3588 * NdrConformantStructMemorySize [RPCRT4.@]
3590 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3591 PFORMAT_STRING pFormat)
3593 FIXME("stub\n");
3594 return 0;
3597 /***********************************************************************
3598 * NdrConformantStructFree [RPCRT4.@]
3600 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3601 unsigned char *pMemory,
3602 PFORMAT_STRING pFormat)
3604 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3605 PFORMAT_STRING pCArrayFormat;
3606 ULONG esize;
3608 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3610 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3611 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3613 ERR("invalid format type %x\n", pCStructFormat->type);
3614 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3615 return;
3618 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3619 pCStructFormat->offset_to_array_description;
3620 if (*pCArrayFormat != RPC_FC_CARRAY)
3622 ERR("invalid array format type %x\n", pCStructFormat->type);
3623 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3624 return;
3626 esize = *(const WORD*)(pCArrayFormat+2);
3628 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3629 pCArrayFormat + 4, 0);
3631 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3633 /* copy constant sized part of struct */
3634 pStubMsg->BufferMark = pStubMsg->Buffer;
3636 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3637 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3640 /***********************************************************************
3641 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3643 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3644 unsigned char *pMemory,
3645 PFORMAT_STRING pFormat)
3647 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3648 PFORMAT_STRING pCVArrayFormat;
3649 ULONG esize, bufsize;
3651 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3653 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3654 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3656 ERR("invalid format type %x\n", pCVStructFormat->type);
3657 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3658 return NULL;
3661 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3662 pCVStructFormat->offset_to_array_description;
3663 switch (*pCVArrayFormat)
3665 case RPC_FC_CVARRAY:
3666 esize = *(const WORD*)(pCVArrayFormat+2);
3668 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3669 pCVArrayFormat + 4, 0);
3670 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3671 pCVArrayFormat, 0);
3672 break;
3673 case RPC_FC_C_CSTRING:
3674 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3675 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3676 esize = sizeof(char);
3677 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3678 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3679 pCVArrayFormat + 2, 0);
3680 else
3681 pStubMsg->MaxCount = pStubMsg->ActualCount;
3682 break;
3683 case RPC_FC_C_WSTRING:
3684 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3685 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3686 esize = sizeof(WCHAR);
3687 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3688 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3689 pCVArrayFormat + 2, 0);
3690 else
3691 pStubMsg->MaxCount = pStubMsg->ActualCount;
3692 break;
3693 default:
3694 ERR("invalid array format type %x\n", *pCVArrayFormat);
3695 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3696 return NULL;
3699 WriteConformance(pStubMsg);
3701 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3703 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3705 /* write constant sized part */
3706 pStubMsg->BufferMark = pStubMsg->Buffer;
3707 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
3709 WriteVariance(pStubMsg);
3711 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3713 /* write array part */
3714 safe_copy_to_buffer(pStubMsg, pMemory + pCVStructFormat->memory_size, bufsize);
3716 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3718 return NULL;
3721 /***********************************************************************
3722 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3724 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3725 unsigned char **ppMemory,
3726 PFORMAT_STRING pFormat,
3727 unsigned char fMustAlloc)
3729 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3730 PFORMAT_STRING pCVArrayFormat;
3731 ULONG esize, bufsize;
3732 unsigned char cvarray_type;
3734 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3736 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3737 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3739 ERR("invalid format type %x\n", pCVStructFormat->type);
3740 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3741 return NULL;
3744 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3745 pCVStructFormat->offset_to_array_description;
3746 cvarray_type = *pCVArrayFormat;
3747 switch (cvarray_type)
3749 case RPC_FC_CVARRAY:
3750 esize = *(const WORD*)(pCVArrayFormat+2);
3751 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3752 break;
3753 case RPC_FC_C_CSTRING:
3754 esize = sizeof(char);
3755 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3756 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3757 else
3758 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3759 break;
3760 case RPC_FC_C_WSTRING:
3761 esize = sizeof(WCHAR);
3762 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3763 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3764 else
3765 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3766 break;
3767 default:
3768 ERR("invalid array format type %x\n", *pCVArrayFormat);
3769 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3770 return NULL;
3773 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3775 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3777 /* work out how much memory to allocate if we need to do so */
3778 if (!*ppMemory || fMustAlloc)
3780 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3781 *ppMemory = NdrAllocate(pStubMsg, size);
3784 /* copy the constant data */
3785 pStubMsg->BufferMark = pStubMsg->Buffer;
3786 safe_copy_from_buffer(pStubMsg, *ppMemory, pCVStructFormat->memory_size);
3788 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3790 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3792 if ((cvarray_type == RPC_FC_C_CSTRING) ||
3793 (cvarray_type == RPC_FC_C_WSTRING))
3795 ULONG i;
3796 /* strings must always have null terminating bytes */
3797 if (bufsize < esize)
3799 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
3800 RpcRaiseException(RPC_S_INVALID_BOUND);
3801 return NULL;
3803 for (i = bufsize - esize; i < bufsize; i++)
3804 if (pStubMsg->Buffer[i] != 0)
3806 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3807 i, pStubMsg->Buffer[i]);
3808 RpcRaiseException(RPC_S_INVALID_BOUND);
3809 return NULL;
3813 /* copy the array data */
3814 safe_copy_from_buffer(pStubMsg, *ppMemory + pCVStructFormat->memory_size, bufsize);
3816 if (cvarray_type == RPC_FC_C_CSTRING)
3817 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3818 else if (cvarray_type == RPC_FC_C_WSTRING)
3819 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3821 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
3823 return NULL;
3826 /***********************************************************************
3827 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3829 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3830 unsigned char *pMemory,
3831 PFORMAT_STRING pFormat)
3833 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3834 PFORMAT_STRING pCVArrayFormat;
3835 ULONG esize;
3837 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3839 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3840 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3842 ERR("invalid format type %x\n", pCVStructFormat->type);
3843 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3844 return;
3847 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3848 pCVStructFormat->offset_to_array_description;
3849 switch (*pCVArrayFormat)
3851 case RPC_FC_CVARRAY:
3852 esize = *(const WORD*)(pCVArrayFormat+2);
3854 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3855 pCVArrayFormat + 4, 0);
3856 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3857 pCVArrayFormat, 0);
3858 break;
3859 case RPC_FC_C_CSTRING:
3860 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3861 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3862 esize = sizeof(char);
3863 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3864 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3865 pCVArrayFormat + 2, 0);
3866 else
3867 pStubMsg->MaxCount = pStubMsg->ActualCount;
3868 break;
3869 case RPC_FC_C_WSTRING:
3870 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3871 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3872 esize = sizeof(WCHAR);
3873 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3874 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3875 pCVArrayFormat + 2, 0);
3876 else
3877 pStubMsg->MaxCount = pStubMsg->ActualCount;
3878 break;
3879 default:
3880 ERR("invalid array format type %x\n", *pCVArrayFormat);
3881 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3882 return;
3885 SizeConformance(pStubMsg);
3887 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
3889 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3891 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
3892 SizeVariance(pStubMsg);
3893 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
3895 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3898 /***********************************************************************
3899 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3901 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3902 PFORMAT_STRING pFormat)
3904 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3905 PFORMAT_STRING pCVArrayFormat;
3906 ULONG esize;
3907 unsigned char cvarray_type;
3909 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3911 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3912 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3914 ERR("invalid format type %x\n", pCVStructFormat->type);
3915 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3916 return 0;
3919 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3920 pCVStructFormat->offset_to_array_description;
3921 cvarray_type = *pCVArrayFormat;
3922 switch (cvarray_type)
3924 case RPC_FC_CVARRAY:
3925 esize = *(const WORD*)(pCVArrayFormat+2);
3926 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3927 break;
3928 case RPC_FC_C_CSTRING:
3929 esize = sizeof(char);
3930 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3931 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3932 else
3933 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3934 break;
3935 case RPC_FC_C_WSTRING:
3936 esize = sizeof(WCHAR);
3937 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3938 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3939 else
3940 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3941 break;
3942 default:
3943 ERR("invalid array format type %x\n", *pCVArrayFormat);
3944 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3945 return 0;
3948 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3950 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3952 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
3953 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3954 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
3956 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3958 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3960 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3963 /***********************************************************************
3964 * NdrConformantVaryingStructFree [RPCRT4.@]
3966 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3967 unsigned char *pMemory,
3968 PFORMAT_STRING pFormat)
3970 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3971 PFORMAT_STRING pCVArrayFormat;
3972 ULONG esize;
3974 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3976 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3977 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3979 ERR("invalid format type %x\n", pCVStructFormat->type);
3980 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3981 return;
3984 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3985 pCVStructFormat->offset_to_array_description;
3986 switch (*pCVArrayFormat)
3988 case RPC_FC_CVARRAY:
3989 esize = *(const WORD*)(pCVArrayFormat+2);
3991 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3992 pCVArrayFormat + 4, 0);
3993 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3994 pCVArrayFormat, 0);
3995 break;
3996 case RPC_FC_C_CSTRING:
3997 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3998 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3999 esize = sizeof(char);
4000 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4001 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4002 pCVArrayFormat + 2, 0);
4003 else
4004 pStubMsg->MaxCount = pStubMsg->ActualCount;
4005 break;
4006 case RPC_FC_C_WSTRING:
4007 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4008 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4009 esize = sizeof(WCHAR);
4010 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4011 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4012 pCVArrayFormat + 2, 0);
4013 else
4014 pStubMsg->MaxCount = pStubMsg->ActualCount;
4015 break;
4016 default:
4017 ERR("invalid array format type %x\n", *pCVArrayFormat);
4018 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4019 return;
4022 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4024 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4027 #include "pshpack1.h"
4028 typedef struct
4030 unsigned char type;
4031 unsigned char alignment;
4032 unsigned short total_size;
4033 } NDR_SMFARRAY_FORMAT;
4035 typedef struct
4037 unsigned char type;
4038 unsigned char alignment;
4039 unsigned long total_size;
4040 } NDR_LGFARRAY_FORMAT;
4041 #include "poppack.h"
4043 /***********************************************************************
4044 * NdrFixedArrayMarshall [RPCRT4.@]
4046 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4047 unsigned char *pMemory,
4048 PFORMAT_STRING pFormat)
4050 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4051 unsigned long total_size;
4053 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4055 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4056 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4058 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4059 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4060 return NULL;
4063 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4065 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4067 total_size = pSmFArrayFormat->total_size;
4068 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4070 else
4072 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4073 total_size = pLgFArrayFormat->total_size;
4074 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4077 pStubMsg->BufferMark = pStubMsg->Buffer;
4078 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4080 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4082 return NULL;
4085 /***********************************************************************
4086 * NdrFixedArrayUnmarshall [RPCRT4.@]
4088 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4089 unsigned char **ppMemory,
4090 PFORMAT_STRING pFormat,
4091 unsigned char fMustAlloc)
4093 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4094 unsigned long total_size;
4095 unsigned char *saved_buffer;
4097 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4099 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4100 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4102 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4103 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4104 return NULL;
4107 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4109 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4111 total_size = pSmFArrayFormat->total_size;
4112 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4114 else
4116 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4117 total_size = pLgFArrayFormat->total_size;
4118 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4121 if (fMustAlloc)
4122 *ppMemory = NdrAllocate(pStubMsg, total_size);
4123 else
4125 if (!pStubMsg->IsClient && !*ppMemory)
4126 /* for servers, we just point straight into the RPC buffer */
4127 *ppMemory = pStubMsg->Buffer;
4130 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4131 safe_buffer_increment(pStubMsg, total_size);
4132 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4134 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4135 if (*ppMemory != saved_buffer)
4136 memcpy(*ppMemory, saved_buffer, total_size);
4138 return NULL;
4141 /***********************************************************************
4142 * NdrFixedArrayBufferSize [RPCRT4.@]
4144 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4145 unsigned char *pMemory,
4146 PFORMAT_STRING pFormat)
4148 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4149 unsigned long total_size;
4151 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4153 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4154 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4156 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4157 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4158 return;
4161 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4163 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4165 total_size = pSmFArrayFormat->total_size;
4166 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4168 else
4170 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4171 total_size = pLgFArrayFormat->total_size;
4172 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4174 safe_buffer_length_increment(pStubMsg, total_size);
4176 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4179 /***********************************************************************
4180 * NdrFixedArrayMemorySize [RPCRT4.@]
4182 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4183 PFORMAT_STRING pFormat)
4185 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4186 ULONG total_size;
4188 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4190 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4191 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4193 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4194 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4195 return 0;
4198 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4200 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4202 total_size = pSmFArrayFormat->total_size;
4203 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4205 else
4207 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4208 total_size = pLgFArrayFormat->total_size;
4209 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4211 pStubMsg->BufferMark = pStubMsg->Buffer;
4212 safe_buffer_increment(pStubMsg, total_size);
4213 pStubMsg->MemorySize += total_size;
4215 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4217 return total_size;
4220 /***********************************************************************
4221 * NdrFixedArrayFree [RPCRT4.@]
4223 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4224 unsigned char *pMemory,
4225 PFORMAT_STRING pFormat)
4227 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4229 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4231 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4232 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4234 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4235 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4236 return;
4239 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4240 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4241 else
4243 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4244 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4247 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4250 /***********************************************************************
4251 * NdrVaryingArrayMarshall [RPCRT4.@]
4253 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4254 unsigned char *pMemory,
4255 PFORMAT_STRING pFormat)
4257 unsigned char alignment;
4258 DWORD elements, esize;
4259 ULONG bufsize;
4261 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4263 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4264 (pFormat[0] != RPC_FC_LGVARRAY))
4266 ERR("invalid format type %x\n", pFormat[0]);
4267 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4268 return NULL;
4271 alignment = pFormat[1] + 1;
4273 if (pFormat[0] == RPC_FC_SMVARRAY)
4275 pFormat += 2;
4276 pFormat += sizeof(WORD);
4277 elements = *(const WORD*)pFormat;
4278 pFormat += sizeof(WORD);
4280 else
4282 pFormat += 2;
4283 pFormat += sizeof(DWORD);
4284 elements = *(const DWORD*)pFormat;
4285 pFormat += sizeof(DWORD);
4288 esize = *(const WORD*)pFormat;
4289 pFormat += sizeof(WORD);
4291 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4292 if ((pStubMsg->ActualCount > elements) ||
4293 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4295 RpcRaiseException(RPC_S_INVALID_BOUND);
4296 return NULL;
4299 WriteVariance(pStubMsg);
4301 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4303 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4304 pStubMsg->BufferMark = pStubMsg->Buffer;
4305 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
4307 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4309 return NULL;
4312 /***********************************************************************
4313 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4315 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4316 unsigned char **ppMemory,
4317 PFORMAT_STRING pFormat,
4318 unsigned char fMustAlloc)
4320 unsigned char alignment;
4321 DWORD size, elements, esize;
4322 ULONG bufsize;
4324 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4326 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4327 (pFormat[0] != RPC_FC_LGVARRAY))
4329 ERR("invalid format type %x\n", pFormat[0]);
4330 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4331 return NULL;
4334 alignment = pFormat[1] + 1;
4336 if (pFormat[0] == RPC_FC_SMVARRAY)
4338 pFormat += 2;
4339 size = *(const WORD*)pFormat;
4340 pFormat += sizeof(WORD);
4341 elements = *(const WORD*)pFormat;
4342 pFormat += sizeof(WORD);
4344 else
4346 pFormat += 2;
4347 size = *(const DWORD*)pFormat;
4348 pFormat += sizeof(DWORD);
4349 elements = *(const DWORD*)pFormat;
4350 pFormat += sizeof(DWORD);
4353 esize = *(const WORD*)pFormat;
4354 pFormat += sizeof(WORD);
4356 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4358 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4360 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4362 if (!*ppMemory || fMustAlloc)
4363 *ppMemory = NdrAllocate(pStubMsg, size);
4364 safe_copy_from_buffer(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize);
4366 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
4368 return NULL;
4371 /***********************************************************************
4372 * NdrVaryingArrayBufferSize [RPCRT4.@]
4374 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4375 unsigned char *pMemory,
4376 PFORMAT_STRING pFormat)
4378 unsigned char alignment;
4379 DWORD elements, esize;
4381 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4383 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4384 (pFormat[0] != RPC_FC_LGVARRAY))
4386 ERR("invalid format type %x\n", pFormat[0]);
4387 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4388 return;
4391 alignment = pFormat[1] + 1;
4393 if (pFormat[0] == RPC_FC_SMVARRAY)
4395 pFormat += 2;
4396 pFormat += sizeof(WORD);
4397 elements = *(const WORD*)pFormat;
4398 pFormat += sizeof(WORD);
4400 else
4402 pFormat += 2;
4403 pFormat += sizeof(DWORD);
4404 elements = *(const DWORD*)pFormat;
4405 pFormat += sizeof(DWORD);
4408 esize = *(const WORD*)pFormat;
4409 pFormat += sizeof(WORD);
4411 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4412 if ((pStubMsg->ActualCount > elements) ||
4413 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4415 RpcRaiseException(RPC_S_INVALID_BOUND);
4416 return;
4419 SizeVariance(pStubMsg);
4421 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4423 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4425 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4428 /***********************************************************************
4429 * NdrVaryingArrayMemorySize [RPCRT4.@]
4431 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4432 PFORMAT_STRING pFormat)
4434 unsigned char alignment;
4435 DWORD size, elements, esize;
4437 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4439 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4440 (pFormat[0] != RPC_FC_LGVARRAY))
4442 ERR("invalid format type %x\n", pFormat[0]);
4443 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4444 return 0;
4447 alignment = pFormat[1] + 1;
4449 if (pFormat[0] == RPC_FC_SMVARRAY)
4451 pFormat += 2;
4452 size = *(const WORD*)pFormat;
4453 pFormat += sizeof(WORD);
4454 elements = *(const WORD*)pFormat;
4455 pFormat += sizeof(WORD);
4457 else
4459 pFormat += 2;
4460 size = *(const DWORD*)pFormat;
4461 pFormat += sizeof(DWORD);
4462 elements = *(const DWORD*)pFormat;
4463 pFormat += sizeof(DWORD);
4466 esize = *(const WORD*)pFormat;
4467 pFormat += sizeof(WORD);
4469 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4471 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4473 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4474 pStubMsg->MemorySize += size;
4476 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4478 return pStubMsg->MemorySize;
4481 /***********************************************************************
4482 * NdrVaryingArrayFree [RPCRT4.@]
4484 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4485 unsigned char *pMemory,
4486 PFORMAT_STRING pFormat)
4488 unsigned char alignment;
4489 DWORD elements;
4491 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4493 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4494 (pFormat[0] != RPC_FC_LGVARRAY))
4496 ERR("invalid format type %x\n", pFormat[0]);
4497 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4498 return;
4501 alignment = pFormat[1] + 1;
4503 if (pFormat[0] == RPC_FC_SMVARRAY)
4505 pFormat += 2;
4506 pFormat += sizeof(WORD);
4507 elements = *(const WORD*)pFormat;
4508 pFormat += sizeof(WORD);
4510 else
4512 pFormat += 2;
4513 pFormat += sizeof(DWORD);
4514 elements = *(const DWORD*)pFormat;
4515 pFormat += sizeof(DWORD);
4518 pFormat += sizeof(WORD);
4520 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4521 if ((pStubMsg->ActualCount > elements) ||
4522 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4524 RpcRaiseException(RPC_S_INVALID_BOUND);
4525 return;
4528 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4531 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
4533 switch (fc)
4535 case RPC_FC_BYTE:
4536 case RPC_FC_CHAR:
4537 case RPC_FC_SMALL:
4538 case RPC_FC_USMALL:
4539 return *(const UCHAR *)pMemory;
4540 case RPC_FC_WCHAR:
4541 case RPC_FC_SHORT:
4542 case RPC_FC_USHORT:
4543 case RPC_FC_ENUM16:
4544 return *(const USHORT *)pMemory;
4545 case RPC_FC_LONG:
4546 case RPC_FC_ULONG:
4547 case RPC_FC_ENUM32:
4548 return *(const ULONG *)pMemory;
4549 default:
4550 FIXME("Unhandled base type: 0x%02x\n", fc);
4551 return 0;
4555 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4556 unsigned long discriminant,
4557 PFORMAT_STRING pFormat)
4559 unsigned short num_arms, arm, type;
4561 num_arms = *(const SHORT*)pFormat & 0x0fff;
4562 pFormat += 2;
4563 for(arm = 0; arm < num_arms; arm++)
4565 if(discriminant == *(const ULONG*)pFormat)
4567 pFormat += 4;
4568 break;
4570 pFormat += 6;
4573 type = *(const unsigned short*)pFormat;
4574 TRACE("type %04x\n", type);
4575 if(arm == num_arms) /* default arm extras */
4577 if(type == 0xffff)
4579 ERR("no arm for 0x%lx and no default case\n", discriminant);
4580 RpcRaiseException(RPC_S_INVALID_TAG);
4581 return NULL;
4583 if(type == 0)
4585 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
4586 return NULL;
4589 return pFormat;
4592 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
4594 unsigned short type;
4596 pFormat += 2;
4598 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4599 if(!pFormat)
4600 return NULL;
4602 type = *(const unsigned short*)pFormat;
4603 if((type & 0xff00) == 0x8000)
4605 unsigned char basetype = LOBYTE(type);
4606 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
4608 else
4610 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4611 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
4612 if (m)
4614 unsigned char *saved_buffer = NULL;
4615 int pointer_buffer_mark_set = 0;
4616 switch(*desc)
4618 case RPC_FC_RP:
4619 case RPC_FC_UP:
4620 case RPC_FC_OP:
4621 case RPC_FC_FP:
4622 ALIGN_POINTER(pStubMsg->Buffer, 4);
4623 saved_buffer = pStubMsg->Buffer;
4624 if (pStubMsg->PointerBufferMark)
4626 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4627 pStubMsg->PointerBufferMark = NULL;
4628 pointer_buffer_mark_set = 1;
4630 else
4631 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
4633 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
4634 if (pointer_buffer_mark_set)
4636 STD_OVERFLOW_CHECK(pStubMsg);
4637 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4638 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
4640 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4641 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
4642 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4644 pStubMsg->Buffer = saved_buffer + 4;
4646 break;
4647 default:
4648 m(pStubMsg, pMemory, desc);
4651 else FIXME("no marshaller for embedded type %02x\n", *desc);
4653 return NULL;
4656 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4657 unsigned char **ppMemory,
4658 ULONG discriminant,
4659 PFORMAT_STRING pFormat,
4660 unsigned char fMustAlloc)
4662 unsigned short type;
4664 pFormat += 2;
4666 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4667 if(!pFormat)
4668 return NULL;
4670 type = *(const unsigned short*)pFormat;
4671 if((type & 0xff00) == 0x8000)
4673 unsigned char basetype = LOBYTE(type);
4674 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
4676 else
4678 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4679 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
4680 if (m)
4682 unsigned char *saved_buffer = NULL;
4683 int pointer_buffer_mark_set = 0;
4684 switch(*desc)
4686 case RPC_FC_RP:
4687 case RPC_FC_UP:
4688 case RPC_FC_OP:
4689 case RPC_FC_FP:
4690 **(void***)ppMemory = NULL;
4691 ALIGN_POINTER(pStubMsg->Buffer, 4);
4692 saved_buffer = pStubMsg->Buffer;
4693 if (pStubMsg->PointerBufferMark)
4695 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4696 pStubMsg->PointerBufferMark = NULL;
4697 pointer_buffer_mark_set = 1;
4699 else
4700 pStubMsg->Buffer += 4; /* for pointer ID */
4702 if (saved_buffer + 4 > pStubMsg->BufferEnd)
4704 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4705 saved_buffer, pStubMsg->BufferEnd);
4706 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4709 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
4710 if (pointer_buffer_mark_set)
4712 STD_OVERFLOW_CHECK(pStubMsg);
4713 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4714 pStubMsg->Buffer = saved_buffer + 4;
4716 break;
4717 default:
4718 m(pStubMsg, ppMemory, desc, fMustAlloc);
4721 else FIXME("no marshaller for embedded type %02x\n", *desc);
4723 return NULL;
4726 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
4727 unsigned char *pMemory,
4728 ULONG discriminant,
4729 PFORMAT_STRING pFormat)
4731 unsigned short type;
4733 pFormat += 2;
4735 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4736 if(!pFormat)
4737 return;
4739 type = *(const unsigned short*)pFormat;
4740 if((type & 0xff00) == 0x8000)
4742 unsigned char basetype = LOBYTE(type);
4743 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
4745 else
4747 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4748 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
4749 if (m)
4751 switch(*desc)
4753 case RPC_FC_RP:
4754 case RPC_FC_UP:
4755 case RPC_FC_OP:
4756 case RPC_FC_FP:
4757 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4758 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
4759 if (!pStubMsg->IgnoreEmbeddedPointers)
4761 int saved_buffer_length = pStubMsg->BufferLength;
4762 pStubMsg->BufferLength = pStubMsg->PointerLength;
4763 pStubMsg->PointerLength = 0;
4764 if(!pStubMsg->BufferLength)
4765 ERR("BufferLength == 0??\n");
4766 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
4767 pStubMsg->PointerLength = pStubMsg->BufferLength;
4768 pStubMsg->BufferLength = saved_buffer_length;
4770 break;
4771 default:
4772 m(pStubMsg, pMemory, desc);
4775 else FIXME("no buffersizer for embedded type %02x\n", *desc);
4779 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
4780 ULONG discriminant,
4781 PFORMAT_STRING pFormat)
4783 unsigned short type, size;
4785 size = *(const unsigned short*)pFormat;
4786 pStubMsg->Memory += size;
4787 pFormat += 2;
4789 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4790 if(!pFormat)
4791 return 0;
4793 type = *(const unsigned short*)pFormat;
4794 if((type & 0xff00) == 0x8000)
4796 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
4798 else
4800 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4801 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
4802 unsigned char *saved_buffer;
4803 if (m)
4805 switch(*desc)
4807 case RPC_FC_RP:
4808 case RPC_FC_UP:
4809 case RPC_FC_OP:
4810 case RPC_FC_FP:
4811 ALIGN_POINTER(pStubMsg->Buffer, 4);
4812 saved_buffer = pStubMsg->Buffer;
4813 safe_buffer_increment(pStubMsg, 4);
4814 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
4815 pStubMsg->MemorySize += 4;
4816 if (!pStubMsg->IgnoreEmbeddedPointers)
4817 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
4818 break;
4819 default:
4820 return m(pStubMsg, desc);
4823 else FIXME("no marshaller for embedded type %02x\n", *desc);
4826 TRACE("size %d\n", size);
4827 return size;
4830 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
4831 unsigned char *pMemory,
4832 ULONG discriminant,
4833 PFORMAT_STRING pFormat)
4835 unsigned short type;
4837 pFormat += 2;
4839 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4840 if(!pFormat)
4841 return;
4843 type = *(const unsigned short*)pFormat;
4844 if((type & 0xff00) != 0x8000)
4846 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4847 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
4848 if (m)
4850 switch(*desc)
4852 case RPC_FC_RP:
4853 case RPC_FC_UP:
4854 case RPC_FC_OP:
4855 case RPC_FC_FP:
4856 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
4857 break;
4858 default:
4859 m(pStubMsg, pMemory, desc);
4862 else FIXME("no freer for embedded type %02x\n", *desc);
4866 /***********************************************************************
4867 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4869 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(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_POINTER(pStubMsg->Buffer, increment);
4886 switch_value = get_discriminant(switch_type, pMemory);
4887 TRACE("got switch value 0x%x\n", switch_value);
4889 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
4890 pMemory += increment;
4892 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
4895 /***********************************************************************
4896 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4898 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4899 unsigned char **ppMemory,
4900 PFORMAT_STRING pFormat,
4901 unsigned char fMustAlloc)
4903 unsigned char switch_type;
4904 unsigned char increment;
4905 ULONG switch_value;
4906 unsigned short size;
4907 unsigned char *pMemoryArm;
4909 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4910 pFormat++;
4912 switch_type = *pFormat & 0xf;
4913 increment = (*pFormat & 0xf0) >> 4;
4914 pFormat++;
4916 ALIGN_POINTER(pStubMsg->Buffer, increment);
4917 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
4918 TRACE("got switch value 0x%x\n", switch_value);
4920 size = *(const unsigned short*)pFormat + increment;
4921 if(!*ppMemory || fMustAlloc)
4922 *ppMemory = NdrAllocate(pStubMsg, size);
4924 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
4925 pMemoryArm = *ppMemory + increment;
4927 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
4930 /***********************************************************************
4931 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4933 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4934 unsigned char *pMemory,
4935 PFORMAT_STRING pFormat)
4937 unsigned char switch_type;
4938 unsigned char increment;
4939 ULONG switch_value;
4941 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4942 pFormat++;
4944 switch_type = *pFormat & 0xf;
4945 increment = (*pFormat & 0xf0) >> 4;
4946 pFormat++;
4948 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
4949 switch_value = get_discriminant(switch_type, pMemory);
4950 TRACE("got switch value 0x%x\n", switch_value);
4952 /* Add discriminant size */
4953 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
4954 pMemory += increment;
4956 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
4959 /***********************************************************************
4960 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4962 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4963 PFORMAT_STRING pFormat)
4965 unsigned char switch_type;
4966 unsigned char increment;
4967 ULONG switch_value;
4969 switch_type = *pFormat & 0xf;
4970 increment = (*pFormat & 0xf0) >> 4;
4971 pFormat++;
4973 ALIGN_POINTER(pStubMsg->Buffer, increment);
4974 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
4975 TRACE("got switch value 0x%x\n", switch_value);
4977 pStubMsg->Memory += increment;
4979 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
4982 /***********************************************************************
4983 * NdrEncapsulatedUnionFree [RPCRT4.@]
4985 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4986 unsigned char *pMemory,
4987 PFORMAT_STRING pFormat)
4989 unsigned char switch_type;
4990 unsigned char increment;
4991 ULONG switch_value;
4993 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4994 pFormat++;
4996 switch_type = *pFormat & 0xf;
4997 increment = (*pFormat & 0xf0) >> 4;
4998 pFormat++;
5000 switch_value = get_discriminant(switch_type, pMemory);
5001 TRACE("got switch value 0x%x\n", switch_value);
5003 pMemory += increment;
5005 return union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5008 /***********************************************************************
5009 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5011 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5012 unsigned char *pMemory,
5013 PFORMAT_STRING pFormat)
5015 unsigned char switch_type;
5017 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5018 pFormat++;
5020 switch_type = *pFormat;
5021 pFormat++;
5023 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5024 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5025 /* Marshall discriminant */
5026 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5028 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5031 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5032 PFORMAT_STRING *ppFormat)
5034 long discriminant = 0;
5036 switch(**ppFormat)
5038 case RPC_FC_BYTE:
5039 case RPC_FC_CHAR:
5040 case RPC_FC_SMALL:
5041 case RPC_FC_USMALL:
5043 UCHAR d;
5044 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5045 discriminant = d;
5046 break;
5048 case RPC_FC_WCHAR:
5049 case RPC_FC_SHORT:
5050 case RPC_FC_USHORT:
5052 USHORT d;
5053 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5054 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5055 discriminant = d;
5056 break;
5058 case RPC_FC_LONG:
5059 case RPC_FC_ULONG:
5061 ULONG d;
5062 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5063 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5064 discriminant = d;
5065 break;
5067 default:
5068 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5070 (*ppFormat)++;
5072 if (pStubMsg->fHasNewCorrDesc)
5073 *ppFormat += 6;
5074 else
5075 *ppFormat += 4;
5076 return discriminant;
5079 /**********************************************************************
5080 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5082 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5083 unsigned char **ppMemory,
5084 PFORMAT_STRING pFormat,
5085 unsigned char fMustAlloc)
5087 long discriminant;
5088 unsigned short size;
5090 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5091 pFormat++;
5093 /* Unmarshall discriminant */
5094 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5095 TRACE("unmarshalled discriminant %lx\n", discriminant);
5097 pFormat += *(const SHORT*)pFormat;
5099 size = *(const unsigned short*)pFormat;
5101 if(!*ppMemory || fMustAlloc)
5102 *ppMemory = NdrAllocate(pStubMsg, size);
5104 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5107 /***********************************************************************
5108 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5110 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5111 unsigned char *pMemory,
5112 PFORMAT_STRING pFormat)
5114 unsigned char switch_type;
5116 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5117 pFormat++;
5119 switch_type = *pFormat;
5120 pFormat++;
5122 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5123 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5124 /* Add discriminant size */
5125 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5127 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5130 /***********************************************************************
5131 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5133 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5134 PFORMAT_STRING pFormat)
5136 ULONG discriminant;
5138 pFormat++;
5139 /* Unmarshall discriminant */
5140 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5141 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
5143 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
5146 /***********************************************************************
5147 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5149 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5150 unsigned char *pMemory,
5151 PFORMAT_STRING pFormat)
5153 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5154 pFormat++;
5155 pFormat++;
5157 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5158 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5160 return union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5163 /***********************************************************************
5164 * NdrByteCountPointerMarshall [RPCRT4.@]
5166 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5167 unsigned char *pMemory,
5168 PFORMAT_STRING pFormat)
5170 FIXME("stub\n");
5171 return NULL;
5174 /***********************************************************************
5175 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5177 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5178 unsigned char **ppMemory,
5179 PFORMAT_STRING pFormat,
5180 unsigned char fMustAlloc)
5182 FIXME("stub\n");
5183 return NULL;
5186 /***********************************************************************
5187 * NdrByteCountPointerBufferSize [RPCRT4.@]
5189 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5190 unsigned char *pMemory,
5191 PFORMAT_STRING pFormat)
5193 FIXME("stub\n");
5196 /***********************************************************************
5197 * NdrByteCountPointerMemorySize [RPCRT4.@]
5199 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5200 PFORMAT_STRING pFormat)
5202 FIXME("stub\n");
5203 return 0;
5206 /***********************************************************************
5207 * NdrByteCountPointerFree [RPCRT4.@]
5209 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
5210 unsigned char *pMemory,
5211 PFORMAT_STRING pFormat)
5213 FIXME("stub\n");
5216 /***********************************************************************
5217 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5219 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5220 unsigned char *pMemory,
5221 PFORMAT_STRING pFormat)
5223 FIXME("stub\n");
5224 return NULL;
5227 /***********************************************************************
5228 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5230 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5231 unsigned char **ppMemory,
5232 PFORMAT_STRING pFormat,
5233 unsigned char fMustAlloc)
5235 FIXME("stub\n");
5236 return NULL;
5239 /***********************************************************************
5240 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5242 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5243 unsigned char *pMemory,
5244 PFORMAT_STRING pFormat)
5246 FIXME("stub\n");
5249 /***********************************************************************
5250 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5252 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5253 PFORMAT_STRING pFormat)
5255 FIXME("stub\n");
5256 return 0;
5259 /***********************************************************************
5260 * NdrXmitOrRepAsFree [RPCRT4.@]
5262 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
5263 unsigned char *pMemory,
5264 PFORMAT_STRING pFormat)
5266 FIXME("stub\n");
5269 #include "pshpack1.h"
5270 typedef struct
5272 unsigned char type;
5273 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
5274 ULONG low_value;
5275 ULONG high_value;
5276 } NDR_RANGE;
5277 #include "poppack.h"
5279 /***********************************************************************
5280 * NdrRangeMarshall [internal]
5282 unsigned char *WINAPI NdrRangeMarshall(
5283 PMIDL_STUB_MESSAGE pStubMsg,
5284 unsigned char *pMemory,
5285 PFORMAT_STRING pFormat)
5287 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5288 unsigned char base_type;
5290 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5292 if (pRange->type != RPC_FC_RANGE)
5294 ERR("invalid format type %x\n", pRange->type);
5295 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5296 return NULL;
5299 base_type = pRange->flags_type & 0xf;
5301 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
5304 /***********************************************************************
5305 * NdrRangeUnmarshall
5307 unsigned char *WINAPI NdrRangeUnmarshall(
5308 PMIDL_STUB_MESSAGE pStubMsg,
5309 unsigned char **ppMemory,
5310 PFORMAT_STRING pFormat,
5311 unsigned char fMustAlloc)
5313 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5314 unsigned char base_type;
5316 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5318 if (pRange->type != RPC_FC_RANGE)
5320 ERR("invalid format type %x\n", pRange->type);
5321 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5322 return NULL;
5324 base_type = pRange->flags_type & 0xf;
5326 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5327 base_type, pRange->low_value, pRange->high_value);
5329 #define RANGE_UNMARSHALL(type, format_spec) \
5330 do \
5332 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5333 if (fMustAlloc || !*ppMemory) \
5334 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5335 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5337 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5338 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5339 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5341 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5342 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5344 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5345 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5346 (type)pRange->high_value); \
5347 RpcRaiseException(RPC_S_INVALID_BOUND); \
5348 return NULL; \
5350 TRACE("*ppMemory: %p\n", *ppMemory); \
5351 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5352 pStubMsg->Buffer += sizeof(type); \
5353 } while (0)
5355 switch(base_type)
5357 case RPC_FC_CHAR:
5358 case RPC_FC_SMALL:
5359 RANGE_UNMARSHALL(UCHAR, "%d");
5360 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5361 break;
5362 case RPC_FC_BYTE:
5363 case RPC_FC_USMALL:
5364 RANGE_UNMARSHALL(CHAR, "%u");
5365 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5366 break;
5367 case RPC_FC_WCHAR: /* FIXME: valid? */
5368 case RPC_FC_USHORT:
5369 RANGE_UNMARSHALL(USHORT, "%u");
5370 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5371 break;
5372 case RPC_FC_SHORT:
5373 RANGE_UNMARSHALL(SHORT, "%d");
5374 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5375 break;
5376 case RPC_FC_LONG:
5377 RANGE_UNMARSHALL(LONG, "%d");
5378 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5379 break;
5380 case RPC_FC_ULONG:
5381 RANGE_UNMARSHALL(ULONG, "%u");
5382 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5383 break;
5384 case RPC_FC_ENUM16:
5385 case RPC_FC_ENUM32:
5386 FIXME("Unhandled enum type\n");
5387 break;
5388 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
5389 case RPC_FC_FLOAT:
5390 case RPC_FC_DOUBLE:
5391 case RPC_FC_HYPER:
5392 default:
5393 ERR("invalid range base type: 0x%02x\n", base_type);
5394 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5397 return NULL;
5400 /***********************************************************************
5401 * NdrRangeBufferSize [internal]
5403 void WINAPI NdrRangeBufferSize(
5404 PMIDL_STUB_MESSAGE pStubMsg,
5405 unsigned char *pMemory,
5406 PFORMAT_STRING pFormat)
5408 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5409 unsigned char base_type;
5411 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5413 if (pRange->type != RPC_FC_RANGE)
5415 ERR("invalid format type %x\n", pRange->type);
5416 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5418 base_type = pRange->flags_type & 0xf;
5420 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
5423 /***********************************************************************
5424 * NdrRangeMemorySize [internal]
5426 ULONG WINAPI NdrRangeMemorySize(
5427 PMIDL_STUB_MESSAGE pStubMsg,
5428 PFORMAT_STRING pFormat)
5430 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5431 unsigned char base_type;
5433 if (pRange->type != RPC_FC_RANGE)
5435 ERR("invalid format type %x\n", pRange->type);
5436 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5437 return 0;
5439 base_type = pRange->flags_type & 0xf;
5441 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
5444 /***********************************************************************
5445 * NdrRangeFree [internal]
5447 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
5448 unsigned char *pMemory,
5449 PFORMAT_STRING pFormat)
5451 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5453 /* nothing to do */
5456 /***********************************************************************
5457 * NdrBaseTypeMarshall [internal]
5459 static unsigned char *WINAPI NdrBaseTypeMarshall(
5460 PMIDL_STUB_MESSAGE pStubMsg,
5461 unsigned char *pMemory,
5462 PFORMAT_STRING pFormat)
5464 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5466 switch(*pFormat)
5468 case RPC_FC_BYTE:
5469 case RPC_FC_CHAR:
5470 case RPC_FC_SMALL:
5471 case RPC_FC_USMALL:
5472 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
5473 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
5474 break;
5475 case RPC_FC_WCHAR:
5476 case RPC_FC_SHORT:
5477 case RPC_FC_USHORT:
5478 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5479 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
5480 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
5481 break;
5482 case RPC_FC_LONG:
5483 case RPC_FC_ULONG:
5484 case RPC_FC_ERROR_STATUS_T:
5485 case RPC_FC_ENUM32:
5486 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5487 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
5488 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
5489 break;
5490 case RPC_FC_FLOAT:
5491 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
5492 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
5493 break;
5494 case RPC_FC_DOUBLE:
5495 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
5496 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
5497 break;
5498 case RPC_FC_HYPER:
5499 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
5500 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
5501 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
5502 break;
5503 case RPC_FC_ENUM16:
5504 /* only 16-bits on the wire, so do a sanity check */
5505 if (*(UINT *)pMemory > SHRT_MAX)
5506 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
5507 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5508 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5509 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5510 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
5511 pStubMsg->Buffer += sizeof(USHORT);
5512 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
5513 break;
5514 case RPC_FC_IGNORE:
5515 break;
5516 default:
5517 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5520 /* FIXME: what is the correct return value? */
5521 return NULL;
5524 /***********************************************************************
5525 * NdrBaseTypeUnmarshall [internal]
5527 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
5528 PMIDL_STUB_MESSAGE pStubMsg,
5529 unsigned char **ppMemory,
5530 PFORMAT_STRING pFormat,
5531 unsigned char fMustAlloc)
5533 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5535 #define BASE_TYPE_UNMARSHALL(type) \
5536 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5537 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
5539 *ppMemory = pStubMsg->Buffer; \
5540 TRACE("*ppMemory: %p\n", *ppMemory); \
5542 else \
5544 if (fMustAlloc) \
5545 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5546 TRACE("*ppMemory: %p\n", *ppMemory); \
5547 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5549 pStubMsg->Buffer += sizeof(type);
5551 switch(*pFormat)
5553 case RPC_FC_BYTE:
5554 case RPC_FC_CHAR:
5555 case RPC_FC_SMALL:
5556 case RPC_FC_USMALL:
5557 BASE_TYPE_UNMARSHALL(UCHAR);
5558 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5559 break;
5560 case RPC_FC_WCHAR:
5561 case RPC_FC_SHORT:
5562 case RPC_FC_USHORT:
5563 BASE_TYPE_UNMARSHALL(USHORT);
5564 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5565 break;
5566 case RPC_FC_LONG:
5567 case RPC_FC_ULONG:
5568 case RPC_FC_ERROR_STATUS_T:
5569 case RPC_FC_ENUM32:
5570 BASE_TYPE_UNMARSHALL(ULONG);
5571 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5572 break;
5573 case RPC_FC_FLOAT:
5574 BASE_TYPE_UNMARSHALL(float);
5575 TRACE("value: %f\n", **(float **)ppMemory);
5576 break;
5577 case RPC_FC_DOUBLE:
5578 BASE_TYPE_UNMARSHALL(double);
5579 TRACE("value: %f\n", **(double **)ppMemory);
5580 break;
5581 case RPC_FC_HYPER:
5582 BASE_TYPE_UNMARSHALL(ULONGLONG);
5583 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
5584 break;
5585 case RPC_FC_ENUM16:
5586 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5587 if (fMustAlloc || !*ppMemory)
5588 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
5589 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
5590 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5591 TRACE("*ppMemory: %p\n", *ppMemory);
5592 /* 16-bits on the wire, but int in memory */
5593 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
5594 pStubMsg->Buffer += sizeof(USHORT);
5595 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
5596 break;
5597 case RPC_FC_IGNORE:
5598 break;
5599 default:
5600 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5602 #undef BASE_TYPE_UNMARSHALL
5604 /* FIXME: what is the correct return value? */
5606 return NULL;
5609 /***********************************************************************
5610 * NdrBaseTypeBufferSize [internal]
5612 static void WINAPI NdrBaseTypeBufferSize(
5613 PMIDL_STUB_MESSAGE pStubMsg,
5614 unsigned char *pMemory,
5615 PFORMAT_STRING pFormat)
5617 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5619 switch(*pFormat)
5621 case RPC_FC_BYTE:
5622 case RPC_FC_CHAR:
5623 case RPC_FC_SMALL:
5624 case RPC_FC_USMALL:
5625 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
5626 break;
5627 case RPC_FC_WCHAR:
5628 case RPC_FC_SHORT:
5629 case RPC_FC_USHORT:
5630 case RPC_FC_ENUM16:
5631 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
5632 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
5633 break;
5634 case RPC_FC_LONG:
5635 case RPC_FC_ULONG:
5636 case RPC_FC_ENUM32:
5637 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
5638 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
5639 break;
5640 case RPC_FC_FLOAT:
5641 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
5642 safe_buffer_length_increment(pStubMsg, sizeof(float));
5643 break;
5644 case RPC_FC_DOUBLE:
5645 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
5646 safe_buffer_length_increment(pStubMsg, sizeof(double));
5647 break;
5648 case RPC_FC_HYPER:
5649 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
5650 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
5651 break;
5652 case RPC_FC_ERROR_STATUS_T:
5653 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
5654 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
5655 break;
5656 case RPC_FC_IGNORE:
5657 break;
5658 default:
5659 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5663 /***********************************************************************
5664 * NdrBaseTypeMemorySize [internal]
5666 static ULONG WINAPI NdrBaseTypeMemorySize(
5667 PMIDL_STUB_MESSAGE pStubMsg,
5668 PFORMAT_STRING pFormat)
5670 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
5672 switch(*pFormat)
5674 case RPC_FC_BYTE:
5675 case RPC_FC_CHAR:
5676 case RPC_FC_SMALL:
5677 case RPC_FC_USMALL:
5678 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
5679 pStubMsg->MemorySize += sizeof(UCHAR);
5680 return sizeof(UCHAR);
5681 case RPC_FC_WCHAR:
5682 case RPC_FC_SHORT:
5683 case RPC_FC_USHORT:
5684 safe_buffer_increment(pStubMsg, sizeof(USHORT));
5685 pStubMsg->MemorySize += sizeof(USHORT);
5686 return sizeof(USHORT);
5687 case RPC_FC_LONG:
5688 case RPC_FC_ULONG:
5689 case RPC_FC_ENUM32:
5690 safe_buffer_increment(pStubMsg, sizeof(ULONG));
5691 pStubMsg->MemorySize += sizeof(ULONG);
5692 return sizeof(ULONG);
5693 case RPC_FC_FLOAT:
5694 safe_buffer_increment(pStubMsg, sizeof(float));
5695 pStubMsg->MemorySize += sizeof(float);
5696 return sizeof(float);
5697 case RPC_FC_DOUBLE:
5698 safe_buffer_increment(pStubMsg, sizeof(double));
5699 pStubMsg->MemorySize += sizeof(double);
5700 return sizeof(double);
5701 case RPC_FC_HYPER:
5702 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
5703 pStubMsg->MemorySize += sizeof(ULONGLONG);
5704 return sizeof(ULONGLONG);
5705 case RPC_FC_ERROR_STATUS_T:
5706 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
5707 pStubMsg->MemorySize += sizeof(error_status_t);
5708 return sizeof(error_status_t);
5709 case RPC_FC_ENUM16:
5710 safe_buffer_increment(pStubMsg, sizeof(USHORT));
5711 pStubMsg->MemorySize += sizeof(UINT);
5712 return sizeof(UINT);
5713 case RPC_FC_IGNORE:
5714 pStubMsg->MemorySize += sizeof(void *);
5715 return sizeof(void *);
5716 default:
5717 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5718 return 0;
5722 /***********************************************************************
5723 * NdrBaseTypeFree [internal]
5725 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
5726 unsigned char *pMemory,
5727 PFORMAT_STRING pFormat)
5729 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5731 /* nothing to do */
5734 /***********************************************************************
5735 * NdrContextHandleBufferSize [internal]
5737 static void WINAPI NdrContextHandleBufferSize(
5738 PMIDL_STUB_MESSAGE pStubMsg,
5739 unsigned char *pMemory,
5740 PFORMAT_STRING pFormat)
5742 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5744 if (*pFormat != RPC_FC_BIND_CONTEXT)
5746 ERR("invalid format type %x\n", *pFormat);
5747 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5749 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5750 safe_buffer_length_increment(pStubMsg, cbNDRContext);
5753 /***********************************************************************
5754 * NdrContextHandleMarshall [internal]
5756 static unsigned char *WINAPI NdrContextHandleMarshall(
5757 PMIDL_STUB_MESSAGE pStubMsg,
5758 unsigned char *pMemory,
5759 PFORMAT_STRING pFormat)
5761 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5763 if (*pFormat != RPC_FC_BIND_CONTEXT)
5765 ERR("invalid format type %x\n", *pFormat);
5766 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5769 if (pFormat[1] & 0x80)
5770 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
5771 else
5772 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
5774 return NULL;
5777 /***********************************************************************
5778 * NdrContextHandleUnmarshall [internal]
5780 static unsigned char *WINAPI NdrContextHandleUnmarshall(
5781 PMIDL_STUB_MESSAGE pStubMsg,
5782 unsigned char **ppMemory,
5783 PFORMAT_STRING pFormat,
5784 unsigned char fMustAlloc)
5786 if (*pFormat != RPC_FC_BIND_CONTEXT)
5788 ERR("invalid format type %x\n", *pFormat);
5789 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5792 **(NDR_CCONTEXT **)ppMemory = NULL;
5793 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
5795 return NULL;
5798 /***********************************************************************
5799 * NdrClientContextMarshall [RPCRT4.@]
5801 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5802 NDR_CCONTEXT ContextHandle,
5803 int fCheck)
5805 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
5807 ALIGN_POINTER(pStubMsg->Buffer, 4);
5809 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5811 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
5812 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5813 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5816 /* FIXME: what does fCheck do? */
5817 NDRCContextMarshall(ContextHandle,
5818 pStubMsg->Buffer);
5820 pStubMsg->Buffer += cbNDRContext;
5823 /***********************************************************************
5824 * NdrClientContextUnmarshall [RPCRT4.@]
5826 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5827 NDR_CCONTEXT * pContextHandle,
5828 RPC_BINDING_HANDLE BindHandle)
5830 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
5832 ALIGN_POINTER(pStubMsg->Buffer, 4);
5834 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
5835 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5837 NDRCContextUnmarshall(pContextHandle,
5838 BindHandle,
5839 pStubMsg->Buffer,
5840 pStubMsg->RpcMsg->DataRepresentation);
5842 pStubMsg->Buffer += cbNDRContext;
5845 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5846 NDR_SCONTEXT ContextHandle,
5847 NDR_RUNDOWN RundownRoutine )
5849 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
5852 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
5854 FIXME("(%p): stub\n", pStubMsg);
5855 return NULL;
5858 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
5859 unsigned char* pMemory,
5860 PFORMAT_STRING pFormat)
5862 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
5865 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
5866 PFORMAT_STRING pFormat)
5868 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
5869 return NULL;
5872 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5873 NDR_SCONTEXT ContextHandle,
5874 NDR_RUNDOWN RundownRoutine,
5875 PFORMAT_STRING pFormat)
5877 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
5880 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5881 PFORMAT_STRING pFormat)
5883 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
5884 return NULL;
5887 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
5889 typedef struct ndr_context_handle
5891 DWORD attributes;
5892 GUID uuid;
5893 } ndr_context_handle;
5895 struct context_handle_entry
5897 struct list entry;
5898 DWORD magic;
5899 RPC_BINDING_HANDLE handle;
5900 ndr_context_handle wire_data;
5903 static struct list context_handle_list = LIST_INIT(context_handle_list);
5905 static CRITICAL_SECTION ndr_context_cs;
5906 static CRITICAL_SECTION_DEBUG ndr_context_debug =
5908 0, 0, &ndr_context_cs,
5909 { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
5910 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
5912 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
5914 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
5916 struct context_handle_entry *che = (struct context_handle_entry*) CContext;
5918 if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
5919 return NULL;
5920 return che;
5923 static struct context_handle_entry *context_entry_from_guid(LPCGUID uuid)
5925 struct context_handle_entry *che;
5926 LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
5927 if (IsEqualGUID(&che->wire_data.uuid, uuid))
5928 return che;
5929 return NULL;
5932 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
5934 struct context_handle_entry *che;
5935 RPC_BINDING_HANDLE handle = NULL;
5937 TRACE("%p\n", CContext);
5939 EnterCriticalSection(&ndr_context_cs);
5940 che = get_context_entry(CContext);
5941 if (che)
5942 handle = che->handle;
5943 LeaveCriticalSection(&ndr_context_cs);
5945 if (!handle)
5946 RpcRaiseException(ERROR_INVALID_HANDLE);
5947 return handle;
5950 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
5952 struct context_handle_entry *che;
5954 TRACE("%p %p\n", CContext, pBuff);
5956 if (CContext)
5958 EnterCriticalSection(&ndr_context_cs);
5959 che = get_context_entry(CContext);
5960 memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
5961 LeaveCriticalSection(&ndr_context_cs);
5963 else
5965 ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
5966 wire_data->attributes = 0;
5967 wire_data->uuid = GUID_NULL;
5971 /***********************************************************************
5972 * RpcSmDestroyClientContext [RPCRT4.@]
5974 RPC_STATUS WINAPI RpcSmDestroyClientContext(void **ContextHandle)
5976 RPC_STATUS status = RPC_X_SS_CONTEXT_MISMATCH;
5977 struct context_handle_entry *che = NULL;
5979 TRACE("(%p)\n", ContextHandle);
5981 EnterCriticalSection(&ndr_context_cs);
5982 che = get_context_entry(*ContextHandle);
5983 *ContextHandle = NULL;
5984 if (che)
5986 status = RPC_S_OK;
5987 list_remove(&che->entry);
5990 LeaveCriticalSection(&ndr_context_cs);
5992 if (che)
5994 RpcBindingFree(&che->handle);
5995 HeapFree(GetProcessHeap(), 0, che);
5998 return status;
6001 /***********************************************************************
6002 * RpcSsDestroyClientContext [RPCRT4.@]
6004 void WINAPI RpcSsDestroyClientContext(void **ContextHandle)
6006 RPC_STATUS status = RpcSmDestroyClientContext(ContextHandle);
6007 if (status != RPC_S_OK)
6008 RpcRaiseException(status);
6011 static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
6012 RPC_BINDING_HANDLE hBinding,
6013 const ndr_context_handle *chi)
6015 struct context_handle_entry *che = NULL;
6017 /* a null UUID means we should free the context handle */
6018 if (IsEqualGUID(&chi->uuid, &GUID_NULL))
6020 if (*CContext)
6022 che = get_context_entry(*CContext);
6023 if (!che)
6024 return ERROR_INVALID_HANDLE;
6025 list_remove(&che->entry);
6026 RpcBindingFree(&che->handle);
6027 HeapFree(GetProcessHeap(), 0, che);
6028 che = NULL;
6031 /* if there's no existing entry matching the GUID, allocate one */
6032 else if (!(che = context_entry_from_guid(&chi->uuid)))
6034 che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
6035 if (!che)
6036 return ERROR_NOT_ENOUGH_MEMORY;
6037 che->magic = NDR_CONTEXT_HANDLE_MAGIC;
6038 RpcBindingCopy(hBinding, &che->handle);
6039 list_add_tail(&context_handle_list, &che->entry);
6040 memcpy(&che->wire_data, chi, sizeof *chi);
6043 *CContext = che;
6045 return ERROR_SUCCESS;
6048 /***********************************************************************
6049 * NDRCContextUnmarshall [RPCRT4.@]
6051 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
6052 RPC_BINDING_HANDLE hBinding,
6053 void *pBuff, ULONG DataRepresentation)
6055 UINT r;
6057 TRACE("*%p=(%p) %p %p %08x\n",
6058 CContext, *CContext, hBinding, pBuff, DataRepresentation);
6060 EnterCriticalSection(&ndr_context_cs);
6061 r = ndr_update_context_handle(CContext, hBinding, pBuff);
6062 LeaveCriticalSection(&ndr_context_cs);
6063 if (r)
6064 RpcRaiseException(r);
6067 /***********************************************************************
6068 * NDRSContextMarshall [RPCRT4.@]
6070 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
6071 void *pBuff,
6072 NDR_RUNDOWN userRunDownIn)
6074 FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn);
6077 /***********************************************************************
6078 * NDRSContextMarshallEx [RPCRT4.@]
6080 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
6081 NDR_SCONTEXT CContext,
6082 void *pBuff,
6083 NDR_RUNDOWN userRunDownIn)
6085 FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn);
6088 /***********************************************************************
6089 * NDRSContextMarshall2 [RPCRT4.@]
6091 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
6092 NDR_SCONTEXT CContext,
6093 void *pBuff,
6094 NDR_RUNDOWN userRunDownIn,
6095 void *CtxGuard, ULONG Flags)
6097 FIXME("(%p %p %p %p %p %u): stub\n",
6098 hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags);
6101 /***********************************************************************
6102 * NDRSContextUnmarshall [RPCRT4.@]
6104 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
6105 ULONG DataRepresentation)
6107 FIXME("(%p %08x): stub\n", pBuff, DataRepresentation);
6108 return NULL;
6111 /***********************************************************************
6112 * NDRSContextUnmarshallEx [RPCRT4.@]
6114 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
6115 void *pBuff,
6116 ULONG DataRepresentation)
6118 FIXME("(%p %p %08x): stub\n", hBinding, pBuff, DataRepresentation);
6119 return NULL;
6122 /***********************************************************************
6123 * NDRSContextUnmarshall2 [RPCRT4.@]
6125 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
6126 void *pBuff,
6127 ULONG DataRepresentation,
6128 void *CtxGuard, ULONG Flags)
6130 FIXME("(%p %p %08x %p %u): stub\n",
6131 hBinding, pBuff, DataRepresentation, CtxGuard, Flags);
6132 return NULL;