rpcrt4: Save the buffer in EmbeddedPointerMemorySize, like EmbeddedPointerUnmarshall...
[wine/winequartzdrv.git] / dlls / rpcrt4 / ndr_marshall.c
blob7578221b5a07ea6e7807323854ed2627db738cbd
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;
1467 unsigned char *saved_buffer = NULL;
1469 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1471 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1473 if (pStubMsg->PointerBufferMark)
1475 saved_buffer = pStubMsg->Buffer;
1476 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1477 pStubMsg->PointerBufferMark = NULL;
1480 if (*pFormat != RPC_FC_PP) return 0;
1481 pFormat += 2;
1483 while (pFormat[0] != RPC_FC_END) {
1484 switch (pFormat[0]) {
1485 default:
1486 FIXME("unknown repeat type %d\n", pFormat[0]);
1487 case RPC_FC_NO_REPEAT:
1488 rep = 1;
1489 stride = 0;
1490 count = 1;
1491 pFormat += 2;
1492 break;
1493 case RPC_FC_FIXED_REPEAT:
1494 rep = *(const WORD*)&pFormat[2];
1495 stride = *(const WORD*)&pFormat[4];
1496 count = *(const WORD*)&pFormat[8];
1497 pFormat += 10;
1498 break;
1499 case RPC_FC_VARIABLE_REPEAT:
1500 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1501 stride = *(const WORD*)&pFormat[2];
1502 count = *(const WORD*)&pFormat[6];
1503 pFormat += 8;
1504 break;
1506 for (i = 0; i < rep; i++) {
1507 PFORMAT_STRING info = pFormat;
1508 unsigned char *bufbase = Mark + (i * stride);
1509 unsigned u;
1510 for (u=0; u<count; u++,info+=8) {
1511 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1512 PointerMemorySize(pStubMsg, bufptr, info+4);
1515 pFormat += 8 * count;
1518 if (saved_buffer)
1520 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1521 pStubMsg->Buffer = saved_buffer;
1524 return 0;
1527 /***********************************************************************
1528 * EmbeddedPointerFree [internal]
1530 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1531 unsigned char *pMemory,
1532 PFORMAT_STRING pFormat)
1534 unsigned rep, count, stride;
1535 unsigned i;
1537 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1538 if (*pFormat != RPC_FC_PP) return;
1539 pFormat += 2;
1541 while (pFormat[0] != RPC_FC_END) {
1542 switch (pFormat[0]) {
1543 default:
1544 FIXME("unknown repeat type %d\n", pFormat[0]);
1545 case RPC_FC_NO_REPEAT:
1546 rep = 1;
1547 stride = 0;
1548 count = 1;
1549 pFormat += 2;
1550 break;
1551 case RPC_FC_FIXED_REPEAT:
1552 rep = *(const WORD*)&pFormat[2];
1553 stride = *(const WORD*)&pFormat[4];
1554 count = *(const WORD*)&pFormat[8];
1555 pFormat += 10;
1556 break;
1557 case RPC_FC_VARIABLE_REPEAT:
1558 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1559 stride = *(const WORD*)&pFormat[2];
1560 count = *(const WORD*)&pFormat[6];
1561 pFormat += 8;
1562 break;
1564 for (i = 0; i < rep; i++) {
1565 PFORMAT_STRING info = pFormat;
1566 unsigned char *membase = pMemory + (i * stride);
1567 unsigned u;
1569 for (u=0; u<count; u++,info+=8) {
1570 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1571 unsigned char *saved_memory = pStubMsg->Memory;
1573 pStubMsg->Memory = pMemory;
1574 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1575 pStubMsg->Memory = saved_memory;
1578 pFormat += 8 * count;
1582 /***********************************************************************
1583 * NdrPointerMarshall [RPCRT4.@]
1585 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1586 unsigned char *pMemory,
1587 PFORMAT_STRING pFormat)
1589 unsigned char *Buffer;
1591 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1593 /* incremement the buffer here instead of in PointerMarshall,
1594 * as that is used by embedded pointers which already handle the incrementing
1595 * the buffer, and shouldn't write any additional pointer data to the wire */
1596 if (*pFormat != RPC_FC_RP)
1598 ALIGN_POINTER(pStubMsg->Buffer, 4);
1599 Buffer = pStubMsg->Buffer;
1600 safe_buffer_increment(pStubMsg, 4);
1602 else
1603 Buffer = pStubMsg->Buffer;
1605 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1607 return NULL;
1610 /***********************************************************************
1611 * NdrPointerUnmarshall [RPCRT4.@]
1613 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1614 unsigned char **ppMemory,
1615 PFORMAT_STRING pFormat,
1616 unsigned char fMustAlloc)
1618 unsigned char *Buffer;
1620 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1622 /* incremement the buffer here instead of in PointerUnmarshall,
1623 * as that is used by embedded pointers which already handle the incrementing
1624 * the buffer, and shouldn't read any additional pointer data from the
1625 * buffer */
1626 if (*pFormat != RPC_FC_RP)
1628 ALIGN_POINTER(pStubMsg->Buffer, 4);
1629 Buffer = pStubMsg->Buffer;
1630 safe_buffer_increment(pStubMsg, 4);
1632 else
1633 Buffer = pStubMsg->Buffer;
1635 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1637 return NULL;
1640 /***********************************************************************
1641 * NdrPointerBufferSize [RPCRT4.@]
1643 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1644 unsigned char *pMemory,
1645 PFORMAT_STRING pFormat)
1647 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1649 /* incremement the buffer length here instead of in PointerBufferSize,
1650 * as that is used by embedded pointers which already handle the buffer
1651 * length, and shouldn't write anything more to the wire */
1652 if (*pFormat != RPC_FC_RP)
1654 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1655 safe_buffer_length_increment(pStubMsg, 4);
1658 PointerBufferSize(pStubMsg, pMemory, pFormat);
1661 /***********************************************************************
1662 * NdrPointerMemorySize [RPCRT4.@]
1664 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1665 PFORMAT_STRING pFormat)
1667 /* unsigned size = *(LPWORD)(pFormat+2); */
1668 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1669 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1670 return 0;
1673 /***********************************************************************
1674 * NdrPointerFree [RPCRT4.@]
1676 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1677 unsigned char *pMemory,
1678 PFORMAT_STRING pFormat)
1680 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1681 PointerFree(pStubMsg, pMemory, pFormat);
1684 /***********************************************************************
1685 * NdrSimpleTypeMarshall [RPCRT4.@]
1687 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1688 unsigned char FormatChar )
1690 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1693 /***********************************************************************
1694 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1696 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1697 unsigned char FormatChar )
1699 NdrBaseTypeUnmarshall(pStubMsg, &pMemory, &FormatChar, 0);
1702 /***********************************************************************
1703 * NdrSimpleStructMarshall [RPCRT4.@]
1705 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1706 unsigned char *pMemory,
1707 PFORMAT_STRING pFormat)
1709 unsigned size = *(const WORD*)(pFormat+2);
1710 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1712 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1714 pStubMsg->BufferMark = pStubMsg->Buffer;
1715 safe_copy_to_buffer(pStubMsg, pMemory, size);
1717 if (pFormat[0] != RPC_FC_STRUCT)
1718 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1720 return NULL;
1723 /***********************************************************************
1724 * NdrSimpleStructUnmarshall [RPCRT4.@]
1726 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1727 unsigned char **ppMemory,
1728 PFORMAT_STRING pFormat,
1729 unsigned char fMustAlloc)
1731 unsigned size = *(const WORD*)(pFormat+2);
1732 unsigned char *saved_buffer;
1733 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1735 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1737 if (fMustAlloc)
1738 *ppMemory = NdrAllocate(pStubMsg, size);
1739 else
1741 if (!pStubMsg->IsClient && !*ppMemory)
1742 /* for servers, we just point straight into the RPC buffer */
1743 *ppMemory = pStubMsg->Buffer;
1746 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1747 safe_buffer_increment(pStubMsg, size);
1748 if (pFormat[0] == RPC_FC_PSTRUCT)
1749 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1751 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1752 if (*ppMemory != saved_buffer)
1753 memcpy(*ppMemory, saved_buffer, size);
1755 return NULL;
1758 /***********************************************************************
1759 * NdrSimpleStructBufferSize [RPCRT4.@]
1761 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1762 unsigned char *pMemory,
1763 PFORMAT_STRING pFormat)
1765 unsigned size = *(const WORD*)(pFormat+2);
1766 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1768 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1770 safe_buffer_length_increment(pStubMsg, size);
1771 if (pFormat[0] != RPC_FC_STRUCT)
1772 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1775 /***********************************************************************
1776 * NdrSimpleStructMemorySize [RPCRT4.@]
1778 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1779 PFORMAT_STRING pFormat)
1781 unsigned short size = *(const WORD *)(pFormat+2);
1783 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1785 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1786 pStubMsg->MemorySize += size;
1787 safe_buffer_increment(pStubMsg, size);
1789 if (pFormat[0] != RPC_FC_STRUCT)
1790 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1791 return pStubMsg->MemorySize;
1794 /***********************************************************************
1795 * NdrSimpleStructFree [RPCRT4.@]
1797 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1798 unsigned char *pMemory,
1799 PFORMAT_STRING pFormat)
1801 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1802 if (pFormat[0] != RPC_FC_STRUCT)
1803 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1807 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE *pStubMsg,
1808 PFORMAT_STRING pFormat)
1810 switch (*pFormat) {
1811 case RPC_FC_STRUCT:
1812 case RPC_FC_PSTRUCT:
1813 case RPC_FC_CSTRUCT:
1814 case RPC_FC_BOGUS_STRUCT:
1815 case RPC_FC_SMFARRAY:
1816 case RPC_FC_SMVARRAY:
1817 return *(const WORD*)&pFormat[2];
1818 case RPC_FC_USER_MARSHAL:
1819 return *(const WORD*)&pFormat[4];
1820 case RPC_FC_NON_ENCAPSULATED_UNION:
1821 pFormat += 2;
1822 if (pStubMsg->fHasNewCorrDesc)
1823 pFormat += 6;
1824 else
1825 pFormat += 4;
1827 pFormat += *(const SHORT*)pFormat;
1828 return *(const SHORT*)pFormat;
1829 case RPC_FC_IP:
1830 return sizeof(void *);
1831 default:
1832 FIXME("unhandled embedded type %02x\n", *pFormat);
1834 return 0;
1838 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1839 PFORMAT_STRING pFormat)
1841 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1843 if (!m)
1845 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1846 return 0;
1849 return m(pStubMsg, pFormat);
1853 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1854 unsigned char *pMemory,
1855 PFORMAT_STRING pFormat,
1856 PFORMAT_STRING pPointer)
1858 PFORMAT_STRING desc;
1859 NDR_MARSHALL m;
1860 unsigned long size;
1862 while (*pFormat != RPC_FC_END) {
1863 switch (*pFormat) {
1864 case RPC_FC_BYTE:
1865 case RPC_FC_CHAR:
1866 case RPC_FC_SMALL:
1867 case RPC_FC_USMALL:
1868 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
1869 safe_copy_to_buffer(pStubMsg, pMemory, 1);
1870 pMemory += 1;
1871 break;
1872 case RPC_FC_WCHAR:
1873 case RPC_FC_SHORT:
1874 case RPC_FC_USHORT:
1875 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1876 safe_copy_to_buffer(pStubMsg, pMemory, 2);
1877 pMemory += 2;
1878 break;
1879 case RPC_FC_LONG:
1880 case RPC_FC_ULONG:
1881 case RPC_FC_ENUM32:
1882 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
1883 safe_copy_to_buffer(pStubMsg, pMemory, 4);
1884 pMemory += 4;
1885 break;
1886 case RPC_FC_HYPER:
1887 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1888 safe_copy_to_buffer(pStubMsg, pMemory, 8);
1889 pMemory += 8;
1890 break;
1891 case RPC_FC_POINTER:
1893 unsigned char *saved_buffer;
1894 int pointer_buffer_mark_set = 0;
1895 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1896 saved_buffer = pStubMsg->Buffer;
1897 if (pStubMsg->PointerBufferMark)
1899 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1900 pStubMsg->PointerBufferMark = NULL;
1901 pointer_buffer_mark_set = 1;
1903 else
1904 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
1905 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
1906 if (pointer_buffer_mark_set)
1908 STD_OVERFLOW_CHECK(pStubMsg);
1909 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1910 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
1912 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
1913 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
1914 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1916 pStubMsg->Buffer = saved_buffer + 4;
1918 pPointer += 4;
1919 pMemory += 4;
1920 break;
1922 case RPC_FC_ALIGNM4:
1923 ALIGN_POINTER(pMemory, 4);
1924 break;
1925 case RPC_FC_ALIGNM8:
1926 ALIGN_POINTER(pMemory, 8);
1927 break;
1928 case RPC_FC_STRUCTPAD1:
1929 case RPC_FC_STRUCTPAD2:
1930 case RPC_FC_STRUCTPAD3:
1931 case RPC_FC_STRUCTPAD4:
1932 case RPC_FC_STRUCTPAD5:
1933 case RPC_FC_STRUCTPAD6:
1934 case RPC_FC_STRUCTPAD7:
1935 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1936 break;
1937 case RPC_FC_EMBEDDED_COMPLEX:
1938 pMemory += pFormat[1];
1939 pFormat += 2;
1940 desc = pFormat + *(const SHORT*)pFormat;
1941 size = EmbeddedComplexSize(pStubMsg, desc);
1942 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1943 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1944 if (m)
1946 /* for some reason interface pointers aren't generated as
1947 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
1948 * they still need the derefencing treatment that pointers are
1949 * given */
1950 if (*desc == RPC_FC_IP)
1951 m(pStubMsg, *(unsigned char **)pMemory, desc);
1952 else
1953 m(pStubMsg, pMemory, desc);
1955 else FIXME("no marshaller for embedded type %02x\n", *desc);
1956 pMemory += size;
1957 pFormat += 2;
1958 continue;
1959 case RPC_FC_PAD:
1960 break;
1961 default:
1962 FIXME("unhandled format 0x%02x\n", *pFormat);
1964 pFormat++;
1967 return pMemory;
1970 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1971 unsigned char *pMemory,
1972 PFORMAT_STRING pFormat,
1973 PFORMAT_STRING pPointer)
1975 PFORMAT_STRING desc;
1976 NDR_UNMARSHALL m;
1977 unsigned long size;
1979 while (*pFormat != RPC_FC_END) {
1980 switch (*pFormat) {
1981 case RPC_FC_BYTE:
1982 case RPC_FC_CHAR:
1983 case RPC_FC_SMALL:
1984 case RPC_FC_USMALL:
1985 safe_copy_from_buffer(pStubMsg, pMemory, 1);
1986 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
1987 pMemory += 1;
1988 break;
1989 case RPC_FC_WCHAR:
1990 case RPC_FC_SHORT:
1991 case RPC_FC_USHORT:
1992 safe_copy_from_buffer(pStubMsg, pMemory, 2);
1993 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1994 pMemory += 2;
1995 break;
1996 case RPC_FC_LONG:
1997 case RPC_FC_ULONG:
1998 case RPC_FC_ENUM32:
1999 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2000 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2001 pMemory += 4;
2002 break;
2003 case RPC_FC_HYPER:
2004 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2005 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2006 pMemory += 8;
2007 break;
2008 case RPC_FC_POINTER:
2010 unsigned char *saved_buffer;
2011 int pointer_buffer_mark_set = 0;
2012 TRACE("pointer => %p\n", pMemory);
2013 ALIGN_POINTER(pStubMsg->Buffer, 4);
2014 saved_buffer = pStubMsg->Buffer;
2015 if (pStubMsg->PointerBufferMark)
2017 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2018 pStubMsg->PointerBufferMark = NULL;
2019 pointer_buffer_mark_set = 1;
2021 else
2022 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2024 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, TRUE);
2025 if (pointer_buffer_mark_set)
2027 STD_OVERFLOW_CHECK(pStubMsg);
2028 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2029 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2031 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2032 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2033 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2035 pStubMsg->Buffer = saved_buffer + 4;
2037 pPointer += 4;
2038 pMemory += 4;
2039 break;
2041 case RPC_FC_ALIGNM4:
2042 ALIGN_POINTER(pMemory, 4);
2043 break;
2044 case RPC_FC_ALIGNM8:
2045 ALIGN_POINTER(pMemory, 8);
2046 break;
2047 case RPC_FC_STRUCTPAD1:
2048 case RPC_FC_STRUCTPAD2:
2049 case RPC_FC_STRUCTPAD3:
2050 case RPC_FC_STRUCTPAD4:
2051 case RPC_FC_STRUCTPAD5:
2052 case RPC_FC_STRUCTPAD6:
2053 case RPC_FC_STRUCTPAD7:
2054 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2055 break;
2056 case RPC_FC_EMBEDDED_COMPLEX:
2057 pMemory += pFormat[1];
2058 pFormat += 2;
2059 desc = pFormat + *(const SHORT*)pFormat;
2060 size = EmbeddedComplexSize(pStubMsg, desc);
2061 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2062 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2063 memset(pMemory, 0, size); /* just in case */
2064 if (m)
2066 /* for some reason interface pointers aren't generated as
2067 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2068 * they still need the derefencing treatment that pointers are
2069 * given */
2070 if (*desc == RPC_FC_IP)
2071 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2072 else
2073 m(pStubMsg, &pMemory, desc, FALSE);
2075 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2076 pMemory += size;
2077 pFormat += 2;
2078 continue;
2079 case RPC_FC_PAD:
2080 break;
2081 default:
2082 FIXME("unhandled format %d\n", *pFormat);
2084 pFormat++;
2087 return pMemory;
2090 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2091 unsigned char *pMemory,
2092 PFORMAT_STRING pFormat,
2093 PFORMAT_STRING pPointer)
2095 PFORMAT_STRING desc;
2096 NDR_BUFFERSIZE m;
2097 unsigned long size;
2099 while (*pFormat != RPC_FC_END) {
2100 switch (*pFormat) {
2101 case RPC_FC_BYTE:
2102 case RPC_FC_CHAR:
2103 case RPC_FC_SMALL:
2104 case RPC_FC_USMALL:
2105 safe_buffer_length_increment(pStubMsg, 1);
2106 pMemory += 1;
2107 break;
2108 case RPC_FC_WCHAR:
2109 case RPC_FC_SHORT:
2110 case RPC_FC_USHORT:
2111 safe_buffer_length_increment(pStubMsg, 2);
2112 pMemory += 2;
2113 break;
2114 case RPC_FC_LONG:
2115 case RPC_FC_ULONG:
2116 case RPC_FC_ENUM32:
2117 safe_buffer_length_increment(pStubMsg, 4);
2118 pMemory += 4;
2119 break;
2120 case RPC_FC_HYPER:
2121 safe_buffer_length_increment(pStubMsg, 8);
2122 pMemory += 8;
2123 break;
2124 case RPC_FC_POINTER:
2125 if (!pStubMsg->IgnoreEmbeddedPointers)
2127 int saved_buffer_length = pStubMsg->BufferLength;
2128 pStubMsg->BufferLength = pStubMsg->PointerLength;
2129 pStubMsg->PointerLength = 0;
2130 if(!pStubMsg->BufferLength)
2131 ERR("BufferLength == 0??\n");
2132 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2133 pStubMsg->PointerLength = pStubMsg->BufferLength;
2134 pStubMsg->BufferLength = saved_buffer_length;
2136 safe_buffer_length_increment(pStubMsg, 4);
2137 pPointer += 4;
2138 pMemory += 4;
2139 break;
2140 case RPC_FC_ALIGNM4:
2141 ALIGN_POINTER(pMemory, 4);
2142 break;
2143 case RPC_FC_ALIGNM8:
2144 ALIGN_POINTER(pMemory, 8);
2145 break;
2146 case RPC_FC_STRUCTPAD1:
2147 case RPC_FC_STRUCTPAD2:
2148 case RPC_FC_STRUCTPAD3:
2149 case RPC_FC_STRUCTPAD4:
2150 case RPC_FC_STRUCTPAD5:
2151 case RPC_FC_STRUCTPAD6:
2152 case RPC_FC_STRUCTPAD7:
2153 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2154 break;
2155 case RPC_FC_EMBEDDED_COMPLEX:
2156 pMemory += pFormat[1];
2157 pFormat += 2;
2158 desc = pFormat + *(const SHORT*)pFormat;
2159 size = EmbeddedComplexSize(pStubMsg, desc);
2160 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2161 if (m)
2163 /* for some reason interface pointers aren't generated as
2164 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2165 * they still need the derefencing treatment that pointers are
2166 * given */
2167 if (*desc == RPC_FC_IP)
2168 m(pStubMsg, *(unsigned char **)pMemory, desc);
2169 else
2170 m(pStubMsg, pMemory, desc);
2172 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2173 pMemory += size;
2174 pFormat += 2;
2175 continue;
2176 case RPC_FC_PAD:
2177 break;
2178 default:
2179 FIXME("unhandled format 0x%02x\n", *pFormat);
2181 pFormat++;
2184 return pMemory;
2187 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2188 unsigned char *pMemory,
2189 PFORMAT_STRING pFormat,
2190 PFORMAT_STRING pPointer)
2192 PFORMAT_STRING desc;
2193 NDR_FREE m;
2194 unsigned long size;
2196 while (*pFormat != RPC_FC_END) {
2197 switch (*pFormat) {
2198 case RPC_FC_BYTE:
2199 case RPC_FC_CHAR:
2200 case RPC_FC_SMALL:
2201 case RPC_FC_USMALL:
2202 pMemory += 1;
2203 break;
2204 case RPC_FC_WCHAR:
2205 case RPC_FC_SHORT:
2206 case RPC_FC_USHORT:
2207 pMemory += 2;
2208 break;
2209 case RPC_FC_LONG:
2210 case RPC_FC_ULONG:
2211 case RPC_FC_ENUM32:
2212 pMemory += 4;
2213 break;
2214 case RPC_FC_HYPER:
2215 pMemory += 8;
2216 break;
2217 case RPC_FC_POINTER:
2218 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
2219 pPointer += 4;
2220 pMemory += 4;
2221 break;
2222 case RPC_FC_ALIGNM4:
2223 ALIGN_POINTER(pMemory, 4);
2224 break;
2225 case RPC_FC_ALIGNM8:
2226 ALIGN_POINTER(pMemory, 8);
2227 break;
2228 case RPC_FC_STRUCTPAD1:
2229 case RPC_FC_STRUCTPAD2:
2230 case RPC_FC_STRUCTPAD3:
2231 case RPC_FC_STRUCTPAD4:
2232 case RPC_FC_STRUCTPAD5:
2233 case RPC_FC_STRUCTPAD6:
2234 case RPC_FC_STRUCTPAD7:
2235 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2236 break;
2237 case RPC_FC_EMBEDDED_COMPLEX:
2238 pMemory += pFormat[1];
2239 pFormat += 2;
2240 desc = pFormat + *(const SHORT*)pFormat;
2241 size = EmbeddedComplexSize(pStubMsg, desc);
2242 m = NdrFreer[*desc & NDR_TABLE_MASK];
2243 if (m)
2245 /* for some reason interface pointers aren't generated as
2246 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2247 * they still need the derefencing treatment that pointers are
2248 * given */
2249 if (*desc == RPC_FC_IP)
2250 m(pStubMsg, *(unsigned char **)pMemory, desc);
2251 else
2252 m(pStubMsg, pMemory, desc);
2254 else FIXME("no freer for embedded type %02x\n", *desc);
2255 pMemory += size;
2256 pFormat += 2;
2257 continue;
2258 case RPC_FC_PAD:
2259 break;
2260 default:
2261 FIXME("unhandled format 0x%02x\n", *pFormat);
2263 pFormat++;
2266 return pMemory;
2269 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2270 PFORMAT_STRING pFormat)
2272 PFORMAT_STRING desc;
2273 unsigned long size = 0;
2275 while (*pFormat != RPC_FC_END) {
2276 switch (*pFormat) {
2277 case RPC_FC_BYTE:
2278 case RPC_FC_CHAR:
2279 case RPC_FC_SMALL:
2280 case RPC_FC_USMALL:
2281 size += 1;
2282 safe_buffer_increment(pStubMsg, 1);
2283 break;
2284 case RPC_FC_WCHAR:
2285 case RPC_FC_SHORT:
2286 case RPC_FC_USHORT:
2287 size += 2;
2288 safe_buffer_increment(pStubMsg, 2);
2289 break;
2290 case RPC_FC_LONG:
2291 case RPC_FC_ULONG:
2292 case RPC_FC_ENUM32:
2293 size += 4;
2294 safe_buffer_increment(pStubMsg, 4);
2295 break;
2296 case RPC_FC_HYPER:
2297 size += 8;
2298 safe_buffer_increment(pStubMsg, 8);
2299 break;
2300 case RPC_FC_POINTER:
2301 size += 4;
2302 safe_buffer_increment(pStubMsg, 4);
2303 if (!pStubMsg->IgnoreEmbeddedPointers)
2304 FIXME("embedded pointers\n");
2305 break;
2306 case RPC_FC_ALIGNM4:
2307 ALIGN_LENGTH(size, 4);
2308 ALIGN_POINTER(pStubMsg->Buffer, 4);
2309 break;
2310 case RPC_FC_ALIGNM8:
2311 ALIGN_LENGTH(size, 8);
2312 ALIGN_POINTER(pStubMsg->Buffer, 8);
2313 break;
2314 case RPC_FC_STRUCTPAD1:
2315 case RPC_FC_STRUCTPAD2:
2316 case RPC_FC_STRUCTPAD3:
2317 case RPC_FC_STRUCTPAD4:
2318 case RPC_FC_STRUCTPAD5:
2319 case RPC_FC_STRUCTPAD6:
2320 case RPC_FC_STRUCTPAD7:
2321 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2322 break;
2323 case RPC_FC_EMBEDDED_COMPLEX:
2324 size += pFormat[1];
2325 pFormat += 2;
2326 desc = pFormat + *(const SHORT*)pFormat;
2327 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2328 pFormat += 2;
2329 continue;
2330 case RPC_FC_PAD:
2331 break;
2332 default:
2333 FIXME("unhandled format 0x%02x\n", *pFormat);
2335 pFormat++;
2338 return size;
2341 /***********************************************************************
2342 * NdrComplexStructMarshall [RPCRT4.@]
2344 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2345 unsigned char *pMemory,
2346 PFORMAT_STRING pFormat)
2348 PFORMAT_STRING conf_array = NULL;
2349 PFORMAT_STRING pointer_desc = NULL;
2350 unsigned char *OldMemory = pStubMsg->Memory;
2351 int pointer_buffer_mark_set = 0;
2353 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2355 if (!pStubMsg->PointerBufferMark)
2357 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2358 /* save buffer length */
2359 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2361 /* get the buffer pointer after complex array data, but before
2362 * pointer data */
2363 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2364 pStubMsg->IgnoreEmbeddedPointers = 1;
2365 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2366 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2368 /* save it for use by embedded pointer code later */
2369 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2370 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
2371 pointer_buffer_mark_set = 1;
2373 /* restore the original buffer length */
2374 pStubMsg->BufferLength = saved_buffer_length;
2377 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2379 pFormat += 4;
2380 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2381 pFormat += 2;
2382 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2383 pFormat += 2;
2385 pStubMsg->Memory = pMemory;
2387 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2389 if (conf_array)
2390 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2392 pStubMsg->Memory = OldMemory;
2394 if (pointer_buffer_mark_set)
2396 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2397 pStubMsg->PointerBufferMark = NULL;
2400 STD_OVERFLOW_CHECK(pStubMsg);
2402 return NULL;
2405 /***********************************************************************
2406 * NdrComplexStructUnmarshall [RPCRT4.@]
2408 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2409 unsigned char **ppMemory,
2410 PFORMAT_STRING pFormat,
2411 unsigned char fMustAlloc)
2413 unsigned size = *(const WORD*)(pFormat+2);
2414 PFORMAT_STRING conf_array = NULL;
2415 PFORMAT_STRING pointer_desc = NULL;
2416 unsigned char *pMemory;
2417 int pointer_buffer_mark_set = 0;
2419 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2421 if (!pStubMsg->PointerBufferMark)
2423 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2424 /* save buffer pointer */
2425 unsigned char *saved_buffer = pStubMsg->Buffer;
2427 /* get the buffer pointer after complex array data, but before
2428 * pointer data */
2429 pStubMsg->IgnoreEmbeddedPointers = 1;
2430 NdrComplexStructMemorySize(pStubMsg, pFormat);
2431 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2433 /* save it for use by embedded pointer code later */
2434 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2435 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
2436 pointer_buffer_mark_set = 1;
2438 /* restore the original buffer */
2439 pStubMsg->Buffer = saved_buffer;
2442 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2444 if (fMustAlloc || !*ppMemory)
2446 *ppMemory = NdrAllocate(pStubMsg, size);
2447 memset(*ppMemory, 0, size);
2450 pFormat += 4;
2451 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2452 pFormat += 2;
2453 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2454 pFormat += 2;
2456 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2458 if (conf_array)
2459 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2461 if (pointer_buffer_mark_set)
2463 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2464 pStubMsg->PointerBufferMark = NULL;
2467 return NULL;
2470 /***********************************************************************
2471 * NdrComplexStructBufferSize [RPCRT4.@]
2473 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2474 unsigned char *pMemory,
2475 PFORMAT_STRING pFormat)
2477 PFORMAT_STRING conf_array = NULL;
2478 PFORMAT_STRING pointer_desc = NULL;
2479 unsigned char *OldMemory = pStubMsg->Memory;
2480 int pointer_length_set = 0;
2482 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2484 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2486 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2488 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2489 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2491 /* get the buffer length after complex struct data, but before
2492 * pointer data */
2493 pStubMsg->IgnoreEmbeddedPointers = 1;
2494 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2495 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2497 /* save it for use by embedded pointer code later */
2498 pStubMsg->PointerLength = pStubMsg->BufferLength;
2499 pointer_length_set = 1;
2500 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
2502 /* restore the original buffer length */
2503 pStubMsg->BufferLength = saved_buffer_length;
2506 pFormat += 4;
2507 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2508 pFormat += 2;
2509 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2510 pFormat += 2;
2512 pStubMsg->Memory = pMemory;
2514 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2516 if (conf_array)
2517 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2519 pStubMsg->Memory = OldMemory;
2521 if(pointer_length_set)
2523 pStubMsg->BufferLength = pStubMsg->PointerLength;
2524 pStubMsg->PointerLength = 0;
2529 /***********************************************************************
2530 * NdrComplexStructMemorySize [RPCRT4.@]
2532 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2533 PFORMAT_STRING pFormat)
2535 unsigned size = *(const WORD*)(pFormat+2);
2536 PFORMAT_STRING conf_array = NULL;
2537 PFORMAT_STRING pointer_desc = NULL;
2539 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2541 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2543 pFormat += 4;
2544 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2545 pFormat += 2;
2546 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2547 pFormat += 2;
2549 ComplexStructMemorySize(pStubMsg, pFormat);
2551 if (conf_array)
2552 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2554 return size;
2557 /***********************************************************************
2558 * NdrComplexStructFree [RPCRT4.@]
2560 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2561 unsigned char *pMemory,
2562 PFORMAT_STRING pFormat)
2564 PFORMAT_STRING conf_array = NULL;
2565 PFORMAT_STRING pointer_desc = NULL;
2566 unsigned char *OldMemory = pStubMsg->Memory;
2568 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2570 pFormat += 4;
2571 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2572 pFormat += 2;
2573 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2574 pFormat += 2;
2576 pStubMsg->Memory = pMemory;
2578 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2580 if (conf_array)
2581 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2583 pStubMsg->Memory = OldMemory;
2586 /***********************************************************************
2587 * NdrConformantArrayMarshall [RPCRT4.@]
2589 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2590 unsigned char *pMemory,
2591 PFORMAT_STRING pFormat)
2593 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2594 unsigned char alignment = pFormat[1] + 1;
2596 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2597 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2599 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2601 WriteConformance(pStubMsg);
2603 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2605 size = safe_multiply(esize, pStubMsg->MaxCount);
2606 pStubMsg->BufferMark = pStubMsg->Buffer;
2607 safe_copy_to_buffer(pStubMsg, pMemory, size);
2609 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2611 return NULL;
2614 /***********************************************************************
2615 * NdrConformantArrayUnmarshall [RPCRT4.@]
2617 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2618 unsigned char **ppMemory,
2619 PFORMAT_STRING pFormat,
2620 unsigned char fMustAlloc)
2622 DWORD size, esize = *(const WORD*)(pFormat+2);
2623 unsigned char alignment = pFormat[1] + 1;
2624 unsigned char *saved_buffer;
2626 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2627 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2629 pFormat = ReadConformance(pStubMsg, pFormat+4);
2631 size = safe_multiply(esize, pStubMsg->MaxCount);
2632 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2634 if (fMustAlloc)
2635 *ppMemory = NdrAllocate(pStubMsg, size);
2636 else
2638 if (!pStubMsg->IsClient && !*ppMemory)
2639 /* for servers, we just point straight into the RPC buffer */
2640 *ppMemory = pStubMsg->Buffer;
2643 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
2644 safe_buffer_increment(pStubMsg, size);
2645 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2647 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2648 if (*ppMemory != saved_buffer)
2649 memcpy(*ppMemory, saved_buffer, size);
2651 return NULL;
2654 /***********************************************************************
2655 * NdrConformantArrayBufferSize [RPCRT4.@]
2657 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2658 unsigned char *pMemory,
2659 PFORMAT_STRING pFormat)
2661 DWORD size, esize = *(const WORD*)(pFormat+2);
2662 unsigned char alignment = pFormat[1] + 1;
2664 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2665 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2667 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2669 SizeConformance(pStubMsg);
2671 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2673 size = safe_multiply(esize, pStubMsg->MaxCount);
2674 /* conformance value plus array */
2675 safe_buffer_length_increment(pStubMsg, size);
2677 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2680 /***********************************************************************
2681 * NdrConformantArrayMemorySize [RPCRT4.@]
2683 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2684 PFORMAT_STRING pFormat)
2686 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2687 unsigned char alignment = pFormat[1] + 1;
2689 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2690 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2692 pFormat = ReadConformance(pStubMsg, pFormat+4);
2693 size = safe_multiply(esize, pStubMsg->MaxCount);
2694 pStubMsg->MemorySize += size;
2696 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2697 pStubMsg->BufferMark = pStubMsg->Buffer;
2698 safe_buffer_increment(pStubMsg, size);
2700 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2702 return pStubMsg->MemorySize;
2705 /***********************************************************************
2706 * NdrConformantArrayFree [RPCRT4.@]
2708 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2709 unsigned char *pMemory,
2710 PFORMAT_STRING pFormat)
2712 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2713 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2715 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2717 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2721 /***********************************************************************
2722 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2724 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2725 unsigned char* pMemory,
2726 PFORMAT_STRING pFormat )
2728 ULONG bufsize;
2729 unsigned char alignment = pFormat[1] + 1;
2730 DWORD esize = *(const WORD*)(pFormat+2);
2732 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2734 if (pFormat[0] != RPC_FC_CVARRAY)
2736 ERR("invalid format type %x\n", pFormat[0]);
2737 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2738 return NULL;
2741 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2742 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2744 WriteConformance(pStubMsg);
2745 WriteVariance(pStubMsg);
2747 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2749 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2751 pStubMsg->BufferMark = pStubMsg->Buffer;
2752 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
2754 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2756 return NULL;
2760 /***********************************************************************
2761 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2763 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2764 unsigned char** ppMemory,
2765 PFORMAT_STRING pFormat,
2766 unsigned char fMustAlloc )
2768 ULONG bufsize, memsize;
2769 unsigned char alignment = pFormat[1] + 1;
2770 DWORD esize = *(const WORD*)(pFormat+2);
2772 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2774 if (pFormat[0] != RPC_FC_CVARRAY)
2776 ERR("invalid format type %x\n", pFormat[0]);
2777 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2778 return NULL;
2781 pFormat = ReadConformance(pStubMsg, pFormat+4);
2782 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2784 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2786 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2787 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2789 if (!*ppMemory || fMustAlloc)
2790 *ppMemory = NdrAllocate(pStubMsg, memsize);
2791 safe_copy_from_buffer(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize);
2793 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
2795 return NULL;
2799 /***********************************************************************
2800 * NdrConformantVaryingArrayFree [RPCRT4.@]
2802 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2803 unsigned char* pMemory,
2804 PFORMAT_STRING pFormat )
2806 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2808 if (pFormat[0] != RPC_FC_CVARRAY)
2810 ERR("invalid format type %x\n", pFormat[0]);
2811 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2812 return;
2815 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2816 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2818 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2822 /***********************************************************************
2823 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2825 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2826 unsigned char* pMemory, PFORMAT_STRING pFormat )
2828 unsigned char alignment = pFormat[1] + 1;
2829 DWORD esize = *(const WORD*)(pFormat+2);
2831 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2833 if (pFormat[0] != RPC_FC_CVARRAY)
2835 ERR("invalid format type %x\n", pFormat[0]);
2836 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2837 return;
2840 /* compute size */
2841 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2842 /* compute length */
2843 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2845 SizeConformance(pStubMsg);
2846 SizeVariance(pStubMsg);
2848 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2850 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2852 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2856 /***********************************************************************
2857 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2859 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2860 PFORMAT_STRING pFormat )
2862 FIXME( "stub\n" );
2863 return 0;
2867 /***********************************************************************
2868 * NdrComplexArrayMarshall [RPCRT4.@]
2870 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2871 unsigned char *pMemory,
2872 PFORMAT_STRING pFormat)
2874 ULONG i, count, def;
2875 BOOL variance_present;
2876 unsigned char alignment;
2877 int pointer_buffer_mark_set = 0;
2879 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2881 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2883 ERR("invalid format type %x\n", pFormat[0]);
2884 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2885 return NULL;
2888 alignment = pFormat[1] + 1;
2890 if (!pStubMsg->PointerBufferMark)
2892 /* save buffer fields that may be changed by buffer sizer functions
2893 * and that may be needed later on */
2894 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2895 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2896 unsigned long saved_max_count = pStubMsg->MaxCount;
2897 unsigned long saved_offset = pStubMsg->Offset;
2898 unsigned long saved_actual_count = pStubMsg->ActualCount;
2900 /* get the buffer pointer after complex array data, but before
2901 * pointer data */
2902 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2903 pStubMsg->IgnoreEmbeddedPointers = 1;
2904 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
2905 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2907 /* save it for use by embedded pointer code later */
2908 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2909 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
2910 pointer_buffer_mark_set = 1;
2912 /* restore fields */
2913 pStubMsg->ActualCount = saved_actual_count;
2914 pStubMsg->Offset = saved_offset;
2915 pStubMsg->MaxCount = saved_max_count;
2916 pStubMsg->BufferLength = saved_buffer_length;
2919 def = *(const WORD*)&pFormat[2];
2920 pFormat += 4;
2922 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2923 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2925 variance_present = IsConformanceOrVariancePresent(pFormat);
2926 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2927 TRACE("variance = %d\n", pStubMsg->ActualCount);
2929 WriteConformance(pStubMsg);
2930 if (variance_present)
2931 WriteVariance(pStubMsg);
2933 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2935 count = pStubMsg->ActualCount;
2936 for (i = 0; i < count; i++)
2937 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2939 STD_OVERFLOW_CHECK(pStubMsg);
2941 if (pointer_buffer_mark_set)
2943 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2944 pStubMsg->PointerBufferMark = NULL;
2947 return NULL;
2950 /***********************************************************************
2951 * NdrComplexArrayUnmarshall [RPCRT4.@]
2953 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2954 unsigned char **ppMemory,
2955 PFORMAT_STRING pFormat,
2956 unsigned char fMustAlloc)
2958 ULONG i, count, size;
2959 unsigned char alignment;
2960 unsigned char *pMemory;
2961 unsigned char *saved_buffer;
2962 int pointer_buffer_mark_set = 0;
2963 int saved_ignore_embedded;
2965 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2967 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2969 ERR("invalid format type %x\n", pFormat[0]);
2970 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2971 return NULL;
2974 alignment = pFormat[1] + 1;
2976 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2977 /* save buffer pointer */
2978 saved_buffer = pStubMsg->Buffer;
2979 /* get the buffer pointer after complex array data, but before
2980 * pointer data */
2981 pStubMsg->IgnoreEmbeddedPointers = 1;
2982 pStubMsg->MemorySize = 0;
2983 NdrComplexArrayMemorySize(pStubMsg, pFormat);
2984 size = pStubMsg->MemorySize;
2985 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2987 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
2988 if (!pStubMsg->PointerBufferMark)
2990 /* save it for use by embedded pointer code later */
2991 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2992 pointer_buffer_mark_set = 1;
2994 /* restore the original buffer */
2995 pStubMsg->Buffer = saved_buffer;
2997 pFormat += 4;
2999 pFormat = ReadConformance(pStubMsg, pFormat);
3000 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3002 if (fMustAlloc || !*ppMemory)
3004 *ppMemory = NdrAllocate(pStubMsg, size);
3005 memset(*ppMemory, 0, size);
3008 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3010 pMemory = *ppMemory;
3011 count = pStubMsg->ActualCount;
3012 for (i = 0; i < count; i++)
3013 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
3015 if (pointer_buffer_mark_set)
3017 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3018 pStubMsg->PointerBufferMark = NULL;
3021 return NULL;
3024 /***********************************************************************
3025 * NdrComplexArrayBufferSize [RPCRT4.@]
3027 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3028 unsigned char *pMemory,
3029 PFORMAT_STRING pFormat)
3031 ULONG i, count, def;
3032 unsigned char alignment;
3033 BOOL variance_present;
3034 int pointer_length_set = 0;
3036 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3038 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3040 ERR("invalid format type %x\n", pFormat[0]);
3041 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3042 return;
3045 alignment = pFormat[1] + 1;
3047 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3049 /* save buffer fields that may be changed by buffer sizer functions
3050 * and that may be needed later on */
3051 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3052 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3053 unsigned long saved_max_count = pStubMsg->MaxCount;
3054 unsigned long saved_offset = pStubMsg->Offset;
3055 unsigned long saved_actual_count = pStubMsg->ActualCount;
3057 /* get the buffer pointer after complex array data, but before
3058 * pointer data */
3059 pStubMsg->IgnoreEmbeddedPointers = 1;
3060 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3061 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3063 /* save it for use by embedded pointer code later */
3064 pStubMsg->PointerLength = pStubMsg->BufferLength;
3065 pointer_length_set = 1;
3067 /* restore fields */
3068 pStubMsg->ActualCount = saved_actual_count;
3069 pStubMsg->Offset = saved_offset;
3070 pStubMsg->MaxCount = saved_max_count;
3071 pStubMsg->BufferLength = saved_buffer_length;
3073 def = *(const WORD*)&pFormat[2];
3074 pFormat += 4;
3076 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3077 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3078 SizeConformance(pStubMsg);
3080 variance_present = IsConformanceOrVariancePresent(pFormat);
3081 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3082 TRACE("variance = %d\n", pStubMsg->ActualCount);
3084 if (variance_present)
3085 SizeVariance(pStubMsg);
3087 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3089 count = pStubMsg->ActualCount;
3090 for (i = 0; i < count; i++)
3091 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
3093 if(pointer_length_set)
3095 pStubMsg->BufferLength = pStubMsg->PointerLength;
3096 pStubMsg->PointerLength = 0;
3100 /***********************************************************************
3101 * NdrComplexArrayMemorySize [RPCRT4.@]
3103 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3104 PFORMAT_STRING pFormat)
3106 ULONG i, count, esize, SavedMemorySize, MemorySize;
3107 unsigned char alignment;
3108 unsigned char *Buffer;
3110 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3112 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3114 ERR("invalid format type %x\n", pFormat[0]);
3115 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3116 return 0;
3119 alignment = pFormat[1] + 1;
3121 pFormat += 4;
3123 pFormat = ReadConformance(pStubMsg, pFormat);
3124 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3126 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3128 SavedMemorySize = pStubMsg->MemorySize;
3130 Buffer = pStubMsg->Buffer;
3131 pStubMsg->MemorySize = 0;
3132 esize = ComplexStructMemorySize(pStubMsg, pFormat);
3133 pStubMsg->Buffer = Buffer;
3135 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
3137 count = pStubMsg->ActualCount;
3138 for (i = 0; i < count; i++)
3139 ComplexStructMemorySize(pStubMsg, pFormat);
3141 pStubMsg->MemorySize = SavedMemorySize;
3143 pStubMsg->MemorySize += MemorySize;
3144 return MemorySize;
3147 /***********************************************************************
3148 * NdrComplexArrayFree [RPCRT4.@]
3150 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3151 unsigned char *pMemory,
3152 PFORMAT_STRING pFormat)
3154 ULONG i, count, def;
3156 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3158 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3160 ERR("invalid format type %x\n", pFormat[0]);
3161 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3162 return;
3165 def = *(const WORD*)&pFormat[2];
3166 pFormat += 4;
3168 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3169 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3171 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3172 TRACE("variance = %d\n", pStubMsg->ActualCount);
3174 count = pStubMsg->ActualCount;
3175 for (i = 0; i < count; i++)
3176 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
3179 static ULONG UserMarshalFlags(const MIDL_STUB_MESSAGE *pStubMsg)
3181 return MAKELONG(pStubMsg->dwDestContext,
3182 pStubMsg->RpcMsg->DataRepresentation);
3185 #define USER_MARSHAL_PTR_PREFIX \
3186 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3187 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3189 /***********************************************************************
3190 * NdrUserMarshalMarshall [RPCRT4.@]
3192 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3193 unsigned char *pMemory,
3194 PFORMAT_STRING pFormat)
3196 unsigned flags = pFormat[1];
3197 unsigned index = *(const WORD*)&pFormat[2];
3198 unsigned char *saved_buffer = NULL;
3199 ULONG uflag = UserMarshalFlags(pStubMsg);
3200 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3201 TRACE("index=%d\n", index);
3203 if (flags & USER_MARSHAL_POINTER)
3205 ALIGN_POINTER(pStubMsg->Buffer, 4);
3206 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
3207 pStubMsg->Buffer += 4;
3208 if (pStubMsg->PointerBufferMark)
3210 saved_buffer = pStubMsg->Buffer;
3211 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3212 pStubMsg->PointerBufferMark = NULL;
3214 ALIGN_POINTER(pStubMsg->Buffer, 8);
3216 else
3217 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3219 pStubMsg->Buffer =
3220 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
3221 &uflag, pStubMsg->Buffer, pMemory);
3223 if (saved_buffer)
3225 STD_OVERFLOW_CHECK(pStubMsg);
3226 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3227 pStubMsg->Buffer = saved_buffer;
3230 STD_OVERFLOW_CHECK(pStubMsg);
3232 return NULL;
3235 /***********************************************************************
3236 * NdrUserMarshalUnmarshall [RPCRT4.@]
3238 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3239 unsigned char **ppMemory,
3240 PFORMAT_STRING pFormat,
3241 unsigned char fMustAlloc)
3243 unsigned flags = pFormat[1];
3244 unsigned index = *(const WORD*)&pFormat[2];
3245 DWORD memsize = *(const WORD*)&pFormat[4];
3246 unsigned char *saved_buffer = NULL;
3247 ULONG uflag = UserMarshalFlags(pStubMsg);
3248 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3249 TRACE("index=%d\n", index);
3251 if (flags & USER_MARSHAL_POINTER)
3253 ALIGN_POINTER(pStubMsg->Buffer, 4);
3254 /* skip pointer prefix */
3255 pStubMsg->Buffer += 4;
3256 if (pStubMsg->PointerBufferMark)
3258 saved_buffer = pStubMsg->Buffer;
3259 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3260 pStubMsg->PointerBufferMark = NULL;
3262 ALIGN_POINTER(pStubMsg->Buffer, 8);
3264 else
3265 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3267 if (fMustAlloc || !*ppMemory)
3268 *ppMemory = NdrAllocate(pStubMsg, memsize);
3270 pStubMsg->Buffer =
3271 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
3272 &uflag, pStubMsg->Buffer, *ppMemory);
3274 if (saved_buffer)
3276 STD_OVERFLOW_CHECK(pStubMsg);
3277 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3278 pStubMsg->Buffer = saved_buffer;
3281 return NULL;
3284 /***********************************************************************
3285 * NdrUserMarshalBufferSize [RPCRT4.@]
3287 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3288 unsigned char *pMemory,
3289 PFORMAT_STRING pFormat)
3291 unsigned flags = pFormat[1];
3292 unsigned index = *(const WORD*)&pFormat[2];
3293 DWORD bufsize = *(const WORD*)&pFormat[6];
3294 ULONG uflag = UserMarshalFlags(pStubMsg);
3295 unsigned long saved_buffer_length = 0;
3296 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3297 TRACE("index=%d\n", index);
3299 if (flags & USER_MARSHAL_POINTER)
3301 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3302 /* skip pointer prefix */
3303 safe_buffer_length_increment(pStubMsg, 4);
3304 if (pStubMsg->IgnoreEmbeddedPointers)
3305 return;
3306 if (pStubMsg->PointerLength)
3308 saved_buffer_length = pStubMsg->BufferLength;
3309 pStubMsg->BufferLength = pStubMsg->PointerLength;
3310 pStubMsg->PointerLength = 0;
3312 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
3314 else
3315 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
3317 if (bufsize) {
3318 TRACE("size=%d\n", bufsize);
3319 safe_buffer_length_increment(pStubMsg, bufsize);
3321 else
3322 pStubMsg->BufferLength =
3323 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
3324 &uflag, pStubMsg->BufferLength, pMemory);
3326 if (saved_buffer_length)
3328 pStubMsg->PointerLength = pStubMsg->BufferLength;
3329 pStubMsg->BufferLength = saved_buffer_length;
3334 /***********************************************************************
3335 * NdrUserMarshalMemorySize [RPCRT4.@]
3337 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3338 PFORMAT_STRING pFormat)
3340 unsigned flags = pFormat[1];
3341 unsigned index = *(const WORD*)&pFormat[2];
3342 DWORD memsize = *(const WORD*)&pFormat[4];
3343 DWORD bufsize = *(const WORD*)&pFormat[6];
3345 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3346 TRACE("index=%d\n", index);
3348 pStubMsg->MemorySize += memsize;
3350 if (flags & USER_MARSHAL_POINTER)
3352 ALIGN_POINTER(pStubMsg->Buffer, 4);
3353 /* skip pointer prefix */
3354 pStubMsg->Buffer += 4;
3355 if (pStubMsg->IgnoreEmbeddedPointers)
3356 return pStubMsg->MemorySize;
3357 ALIGN_POINTER(pStubMsg->Buffer, 8);
3359 else
3360 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3362 if (!bufsize)
3363 FIXME("not implemented for varying buffer size\n");
3365 pStubMsg->Buffer += bufsize;
3367 return pStubMsg->MemorySize;
3370 /***********************************************************************
3371 * NdrUserMarshalFree [RPCRT4.@]
3373 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
3374 unsigned char *pMemory,
3375 PFORMAT_STRING pFormat)
3377 /* unsigned flags = pFormat[1]; */
3378 unsigned index = *(const WORD*)&pFormat[2];
3379 ULONG uflag = UserMarshalFlags(pStubMsg);
3380 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3381 TRACE("index=%d\n", index);
3383 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
3384 &uflag, pMemory);
3387 /***********************************************************************
3388 * NdrClearOutParameters [RPCRT4.@]
3390 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
3391 PFORMAT_STRING pFormat,
3392 void *ArgAddr)
3394 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
3397 /***********************************************************************
3398 * NdrConvert [RPCRT4.@]
3400 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
3402 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
3403 /* FIXME: since this stub doesn't do any converting, the proper behavior
3404 is to raise an exception */
3407 /***********************************************************************
3408 * NdrConvert2 [RPCRT4.@]
3410 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
3412 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3413 pStubMsg, pFormat, NumberParams);
3414 /* FIXME: since this stub doesn't do any converting, the proper behavior
3415 is to raise an exception */
3418 #include "pshpack1.h"
3419 typedef struct _NDR_CSTRUCT_FORMAT
3421 unsigned char type;
3422 unsigned char alignment;
3423 unsigned short memory_size;
3424 short offset_to_array_description;
3425 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
3426 #include "poppack.h"
3428 /***********************************************************************
3429 * NdrConformantStructMarshall [RPCRT4.@]
3431 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3432 unsigned char *pMemory,
3433 PFORMAT_STRING pFormat)
3435 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3436 PFORMAT_STRING pCArrayFormat;
3437 ULONG esize, bufsize;
3439 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3441 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3442 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3444 ERR("invalid format type %x\n", pCStructFormat->type);
3445 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3446 return NULL;
3449 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3450 pCStructFormat->offset_to_array_description;
3451 if (*pCArrayFormat != RPC_FC_CARRAY)
3453 ERR("invalid array format type %x\n", pCStructFormat->type);
3454 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3455 return NULL;
3457 esize = *(const WORD*)(pCArrayFormat+2);
3459 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3460 pCArrayFormat + 4, 0);
3462 WriteConformance(pStubMsg);
3464 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3466 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3468 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3469 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3471 ERR("integer overflow of memory_size %u with bufsize %u\n",
3472 pCStructFormat->memory_size, bufsize);
3473 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3475 /* copy constant sized part of struct */
3476 pStubMsg->BufferMark = pStubMsg->Buffer;
3477 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
3479 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3480 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3482 return NULL;
3485 /***********************************************************************
3486 * NdrConformantStructUnmarshall [RPCRT4.@]
3488 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3489 unsigned char **ppMemory,
3490 PFORMAT_STRING pFormat,
3491 unsigned char fMustAlloc)
3493 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3494 PFORMAT_STRING pCArrayFormat;
3495 ULONG esize, bufsize;
3496 unsigned char *saved_buffer;
3498 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3500 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3501 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3503 ERR("invalid format type %x\n", pCStructFormat->type);
3504 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3505 return NULL;
3507 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3508 pCStructFormat->offset_to_array_description;
3509 if (*pCArrayFormat != RPC_FC_CARRAY)
3511 ERR("invalid array format type %x\n", pCStructFormat->type);
3512 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3513 return NULL;
3515 esize = *(const WORD*)(pCArrayFormat+2);
3517 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3519 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3521 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3523 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3524 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3526 ERR("integer overflow of memory_size %u with bufsize %u\n",
3527 pCStructFormat->memory_size, bufsize);
3528 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3531 if (fMustAlloc)
3533 SIZE_T size = pCStructFormat->memory_size + bufsize;
3534 *ppMemory = NdrAllocate(pStubMsg, size);
3536 else
3538 if (!pStubMsg->IsClient && !*ppMemory)
3539 /* for servers, we just point straight into the RPC buffer */
3540 *ppMemory = pStubMsg->Buffer;
3543 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3544 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
3545 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3546 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3548 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
3549 if (*ppMemory != saved_buffer)
3550 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
3552 return NULL;
3555 /***********************************************************************
3556 * NdrConformantStructBufferSize [RPCRT4.@]
3558 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3559 unsigned char *pMemory,
3560 PFORMAT_STRING pFormat)
3562 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3563 PFORMAT_STRING pCArrayFormat;
3564 ULONG esize;
3566 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3568 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3569 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3571 ERR("invalid format type %x\n", pCStructFormat->type);
3572 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3573 return;
3575 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3576 pCStructFormat->offset_to_array_description;
3577 if (*pCArrayFormat != RPC_FC_CARRAY)
3579 ERR("invalid array format type %x\n", pCStructFormat->type);
3580 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3581 return;
3583 esize = *(const WORD*)(pCArrayFormat+2);
3585 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
3586 SizeConformance(pStubMsg);
3588 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
3590 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3592 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
3593 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
3595 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3596 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3599 /***********************************************************************
3600 * NdrConformantStructMemorySize [RPCRT4.@]
3602 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3603 PFORMAT_STRING pFormat)
3605 FIXME("stub\n");
3606 return 0;
3609 /***********************************************************************
3610 * NdrConformantStructFree [RPCRT4.@]
3612 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3613 unsigned char *pMemory,
3614 PFORMAT_STRING pFormat)
3616 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3617 PFORMAT_STRING pCArrayFormat;
3618 ULONG esize;
3620 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3622 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3623 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3625 ERR("invalid format type %x\n", pCStructFormat->type);
3626 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3627 return;
3630 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3631 pCStructFormat->offset_to_array_description;
3632 if (*pCArrayFormat != RPC_FC_CARRAY)
3634 ERR("invalid array format type %x\n", pCStructFormat->type);
3635 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3636 return;
3638 esize = *(const WORD*)(pCArrayFormat+2);
3640 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3641 pCArrayFormat + 4, 0);
3643 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3645 /* copy constant sized part of struct */
3646 pStubMsg->BufferMark = pStubMsg->Buffer;
3648 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3649 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3652 /***********************************************************************
3653 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3655 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3656 unsigned char *pMemory,
3657 PFORMAT_STRING pFormat)
3659 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3660 PFORMAT_STRING pCVArrayFormat;
3661 ULONG esize, bufsize;
3663 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3665 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3666 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3668 ERR("invalid format type %x\n", pCVStructFormat->type);
3669 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3670 return NULL;
3673 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3674 pCVStructFormat->offset_to_array_description;
3675 switch (*pCVArrayFormat)
3677 case RPC_FC_CVARRAY:
3678 esize = *(const WORD*)(pCVArrayFormat+2);
3680 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3681 pCVArrayFormat + 4, 0);
3682 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3683 pCVArrayFormat, 0);
3684 break;
3685 case RPC_FC_C_CSTRING:
3686 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3687 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3688 esize = sizeof(char);
3689 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3690 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3691 pCVArrayFormat + 2, 0);
3692 else
3693 pStubMsg->MaxCount = pStubMsg->ActualCount;
3694 break;
3695 case RPC_FC_C_WSTRING:
3696 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3697 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3698 esize = sizeof(WCHAR);
3699 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3700 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3701 pCVArrayFormat + 2, 0);
3702 else
3703 pStubMsg->MaxCount = pStubMsg->ActualCount;
3704 break;
3705 default:
3706 ERR("invalid array format type %x\n", *pCVArrayFormat);
3707 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3708 return NULL;
3711 WriteConformance(pStubMsg);
3713 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3715 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3717 /* write constant sized part */
3718 pStubMsg->BufferMark = pStubMsg->Buffer;
3719 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
3721 WriteVariance(pStubMsg);
3723 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3725 /* write array part */
3726 safe_copy_to_buffer(pStubMsg, pMemory + pCVStructFormat->memory_size, bufsize);
3728 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3730 return NULL;
3733 /***********************************************************************
3734 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3736 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3737 unsigned char **ppMemory,
3738 PFORMAT_STRING pFormat,
3739 unsigned char fMustAlloc)
3741 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3742 PFORMAT_STRING pCVArrayFormat;
3743 ULONG esize, bufsize;
3744 unsigned char cvarray_type;
3746 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3748 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3749 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3751 ERR("invalid format type %x\n", pCVStructFormat->type);
3752 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3753 return NULL;
3756 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3757 pCVStructFormat->offset_to_array_description;
3758 cvarray_type = *pCVArrayFormat;
3759 switch (cvarray_type)
3761 case RPC_FC_CVARRAY:
3762 esize = *(const WORD*)(pCVArrayFormat+2);
3763 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3764 break;
3765 case RPC_FC_C_CSTRING:
3766 esize = sizeof(char);
3767 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3768 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3769 else
3770 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3771 break;
3772 case RPC_FC_C_WSTRING:
3773 esize = sizeof(WCHAR);
3774 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3775 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3776 else
3777 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3778 break;
3779 default:
3780 ERR("invalid array format type %x\n", *pCVArrayFormat);
3781 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3782 return NULL;
3785 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3787 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3789 /* work out how much memory to allocate if we need to do so */
3790 if (!*ppMemory || fMustAlloc)
3792 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3793 *ppMemory = NdrAllocate(pStubMsg, size);
3796 /* copy the constant data */
3797 pStubMsg->BufferMark = pStubMsg->Buffer;
3798 safe_copy_from_buffer(pStubMsg, *ppMemory, pCVStructFormat->memory_size);
3800 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3802 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3804 if ((cvarray_type == RPC_FC_C_CSTRING) ||
3805 (cvarray_type == RPC_FC_C_WSTRING))
3807 ULONG i;
3808 /* strings must always have null terminating bytes */
3809 if (bufsize < esize)
3811 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
3812 RpcRaiseException(RPC_S_INVALID_BOUND);
3813 return NULL;
3815 for (i = bufsize - esize; i < bufsize; i++)
3816 if (pStubMsg->Buffer[i] != 0)
3818 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3819 i, pStubMsg->Buffer[i]);
3820 RpcRaiseException(RPC_S_INVALID_BOUND);
3821 return NULL;
3825 /* copy the array data */
3826 safe_copy_from_buffer(pStubMsg, *ppMemory + pCVStructFormat->memory_size, bufsize);
3828 if (cvarray_type == RPC_FC_C_CSTRING)
3829 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3830 else if (cvarray_type == RPC_FC_C_WSTRING)
3831 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3833 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
3835 return NULL;
3838 /***********************************************************************
3839 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3841 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3842 unsigned char *pMemory,
3843 PFORMAT_STRING pFormat)
3845 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3846 PFORMAT_STRING pCVArrayFormat;
3847 ULONG esize;
3849 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3851 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3852 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3854 ERR("invalid format type %x\n", pCVStructFormat->type);
3855 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3856 return;
3859 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3860 pCVStructFormat->offset_to_array_description;
3861 switch (*pCVArrayFormat)
3863 case RPC_FC_CVARRAY:
3864 esize = *(const WORD*)(pCVArrayFormat+2);
3866 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3867 pCVArrayFormat + 4, 0);
3868 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3869 pCVArrayFormat, 0);
3870 break;
3871 case RPC_FC_C_CSTRING:
3872 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3873 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3874 esize = sizeof(char);
3875 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3876 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3877 pCVArrayFormat + 2, 0);
3878 else
3879 pStubMsg->MaxCount = pStubMsg->ActualCount;
3880 break;
3881 case RPC_FC_C_WSTRING:
3882 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3883 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3884 esize = sizeof(WCHAR);
3885 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3886 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3887 pCVArrayFormat + 2, 0);
3888 else
3889 pStubMsg->MaxCount = pStubMsg->ActualCount;
3890 break;
3891 default:
3892 ERR("invalid array format type %x\n", *pCVArrayFormat);
3893 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3894 return;
3897 SizeConformance(pStubMsg);
3899 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
3901 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3903 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
3904 SizeVariance(pStubMsg);
3905 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
3907 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3910 /***********************************************************************
3911 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3913 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3914 PFORMAT_STRING pFormat)
3916 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3917 PFORMAT_STRING pCVArrayFormat;
3918 ULONG esize;
3919 unsigned char cvarray_type;
3921 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3923 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3924 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3926 ERR("invalid format type %x\n", pCVStructFormat->type);
3927 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3928 return 0;
3931 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3932 pCVStructFormat->offset_to_array_description;
3933 cvarray_type = *pCVArrayFormat;
3934 switch (cvarray_type)
3936 case RPC_FC_CVARRAY:
3937 esize = *(const WORD*)(pCVArrayFormat+2);
3938 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3939 break;
3940 case RPC_FC_C_CSTRING:
3941 esize = sizeof(char);
3942 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3943 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3944 else
3945 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3946 break;
3947 case RPC_FC_C_WSTRING:
3948 esize = sizeof(WCHAR);
3949 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3950 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3951 else
3952 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3953 break;
3954 default:
3955 ERR("invalid array format type %x\n", *pCVArrayFormat);
3956 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3957 return 0;
3960 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3962 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3964 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
3965 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3966 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
3968 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3970 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3972 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3975 /***********************************************************************
3976 * NdrConformantVaryingStructFree [RPCRT4.@]
3978 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3979 unsigned char *pMemory,
3980 PFORMAT_STRING pFormat)
3982 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3983 PFORMAT_STRING pCVArrayFormat;
3984 ULONG esize;
3986 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3988 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3989 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3991 ERR("invalid format type %x\n", pCVStructFormat->type);
3992 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3993 return;
3996 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3997 pCVStructFormat->offset_to_array_description;
3998 switch (*pCVArrayFormat)
4000 case RPC_FC_CVARRAY:
4001 esize = *(const WORD*)(pCVArrayFormat+2);
4003 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4004 pCVArrayFormat + 4, 0);
4005 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4006 pCVArrayFormat, 0);
4007 break;
4008 case RPC_FC_C_CSTRING:
4009 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4010 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4011 esize = sizeof(char);
4012 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4013 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4014 pCVArrayFormat + 2, 0);
4015 else
4016 pStubMsg->MaxCount = pStubMsg->ActualCount;
4017 break;
4018 case RPC_FC_C_WSTRING:
4019 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4020 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4021 esize = sizeof(WCHAR);
4022 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4023 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4024 pCVArrayFormat + 2, 0);
4025 else
4026 pStubMsg->MaxCount = pStubMsg->ActualCount;
4027 break;
4028 default:
4029 ERR("invalid array format type %x\n", *pCVArrayFormat);
4030 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4031 return;
4034 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4036 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4039 #include "pshpack1.h"
4040 typedef struct
4042 unsigned char type;
4043 unsigned char alignment;
4044 unsigned short total_size;
4045 } NDR_SMFARRAY_FORMAT;
4047 typedef struct
4049 unsigned char type;
4050 unsigned char alignment;
4051 unsigned long total_size;
4052 } NDR_LGFARRAY_FORMAT;
4053 #include "poppack.h"
4055 /***********************************************************************
4056 * NdrFixedArrayMarshall [RPCRT4.@]
4058 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4059 unsigned char *pMemory,
4060 PFORMAT_STRING pFormat)
4062 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4063 unsigned long total_size;
4065 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4067 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4068 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4070 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4071 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4072 return NULL;
4075 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4077 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4079 total_size = pSmFArrayFormat->total_size;
4080 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4082 else
4084 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4085 total_size = pLgFArrayFormat->total_size;
4086 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4089 pStubMsg->BufferMark = pStubMsg->Buffer;
4090 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4092 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4094 return NULL;
4097 /***********************************************************************
4098 * NdrFixedArrayUnmarshall [RPCRT4.@]
4100 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4101 unsigned char **ppMemory,
4102 PFORMAT_STRING pFormat,
4103 unsigned char fMustAlloc)
4105 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4106 unsigned long total_size;
4107 unsigned char *saved_buffer;
4109 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4111 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4112 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4114 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4115 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4116 return NULL;
4119 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4121 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4123 total_size = pSmFArrayFormat->total_size;
4124 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4126 else
4128 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4129 total_size = pLgFArrayFormat->total_size;
4130 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4133 if (fMustAlloc)
4134 *ppMemory = NdrAllocate(pStubMsg, total_size);
4135 else
4137 if (!pStubMsg->IsClient && !*ppMemory)
4138 /* for servers, we just point straight into the RPC buffer */
4139 *ppMemory = pStubMsg->Buffer;
4142 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4143 safe_buffer_increment(pStubMsg, total_size);
4144 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4146 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4147 if (*ppMemory != saved_buffer)
4148 memcpy(*ppMemory, saved_buffer, total_size);
4150 return NULL;
4153 /***********************************************************************
4154 * NdrFixedArrayBufferSize [RPCRT4.@]
4156 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4157 unsigned char *pMemory,
4158 PFORMAT_STRING pFormat)
4160 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4161 unsigned long total_size;
4163 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4165 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4166 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4168 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4169 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4170 return;
4173 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4175 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4177 total_size = pSmFArrayFormat->total_size;
4178 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4180 else
4182 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4183 total_size = pLgFArrayFormat->total_size;
4184 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4186 safe_buffer_length_increment(pStubMsg, total_size);
4188 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4191 /***********************************************************************
4192 * NdrFixedArrayMemorySize [RPCRT4.@]
4194 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4195 PFORMAT_STRING pFormat)
4197 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4198 ULONG total_size;
4200 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4202 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4203 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4205 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4206 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4207 return 0;
4210 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4212 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4214 total_size = pSmFArrayFormat->total_size;
4215 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4217 else
4219 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4220 total_size = pLgFArrayFormat->total_size;
4221 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4223 pStubMsg->BufferMark = pStubMsg->Buffer;
4224 safe_buffer_increment(pStubMsg, total_size);
4225 pStubMsg->MemorySize += total_size;
4227 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4229 return total_size;
4232 /***********************************************************************
4233 * NdrFixedArrayFree [RPCRT4.@]
4235 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4236 unsigned char *pMemory,
4237 PFORMAT_STRING pFormat)
4239 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4241 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4243 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4244 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4246 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4247 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4248 return;
4251 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4252 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4253 else
4255 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4256 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4259 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4262 /***********************************************************************
4263 * NdrVaryingArrayMarshall [RPCRT4.@]
4265 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4266 unsigned char *pMemory,
4267 PFORMAT_STRING pFormat)
4269 unsigned char alignment;
4270 DWORD elements, esize;
4271 ULONG bufsize;
4273 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4275 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4276 (pFormat[0] != RPC_FC_LGVARRAY))
4278 ERR("invalid format type %x\n", pFormat[0]);
4279 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4280 return NULL;
4283 alignment = pFormat[1] + 1;
4285 if (pFormat[0] == RPC_FC_SMVARRAY)
4287 pFormat += 2;
4288 pFormat += sizeof(WORD);
4289 elements = *(const WORD*)pFormat;
4290 pFormat += sizeof(WORD);
4292 else
4294 pFormat += 2;
4295 pFormat += sizeof(DWORD);
4296 elements = *(const DWORD*)pFormat;
4297 pFormat += sizeof(DWORD);
4300 esize = *(const WORD*)pFormat;
4301 pFormat += sizeof(WORD);
4303 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4304 if ((pStubMsg->ActualCount > elements) ||
4305 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4307 RpcRaiseException(RPC_S_INVALID_BOUND);
4308 return NULL;
4311 WriteVariance(pStubMsg);
4313 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4315 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4316 pStubMsg->BufferMark = pStubMsg->Buffer;
4317 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
4319 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4321 return NULL;
4324 /***********************************************************************
4325 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4327 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4328 unsigned char **ppMemory,
4329 PFORMAT_STRING pFormat,
4330 unsigned char fMustAlloc)
4332 unsigned char alignment;
4333 DWORD size, elements, esize;
4334 ULONG bufsize;
4336 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4338 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4339 (pFormat[0] != RPC_FC_LGVARRAY))
4341 ERR("invalid format type %x\n", pFormat[0]);
4342 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4343 return NULL;
4346 alignment = pFormat[1] + 1;
4348 if (pFormat[0] == RPC_FC_SMVARRAY)
4350 pFormat += 2;
4351 size = *(const WORD*)pFormat;
4352 pFormat += sizeof(WORD);
4353 elements = *(const WORD*)pFormat;
4354 pFormat += sizeof(WORD);
4356 else
4358 pFormat += 2;
4359 size = *(const DWORD*)pFormat;
4360 pFormat += sizeof(DWORD);
4361 elements = *(const DWORD*)pFormat;
4362 pFormat += sizeof(DWORD);
4365 esize = *(const WORD*)pFormat;
4366 pFormat += sizeof(WORD);
4368 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4370 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4372 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4374 if (!*ppMemory || fMustAlloc)
4375 *ppMemory = NdrAllocate(pStubMsg, size);
4376 safe_copy_from_buffer(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize);
4378 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
4380 return NULL;
4383 /***********************************************************************
4384 * NdrVaryingArrayBufferSize [RPCRT4.@]
4386 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4387 unsigned char *pMemory,
4388 PFORMAT_STRING pFormat)
4390 unsigned char alignment;
4391 DWORD elements, esize;
4393 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4395 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4396 (pFormat[0] != RPC_FC_LGVARRAY))
4398 ERR("invalid format type %x\n", pFormat[0]);
4399 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4400 return;
4403 alignment = pFormat[1] + 1;
4405 if (pFormat[0] == RPC_FC_SMVARRAY)
4407 pFormat += 2;
4408 pFormat += sizeof(WORD);
4409 elements = *(const WORD*)pFormat;
4410 pFormat += sizeof(WORD);
4412 else
4414 pFormat += 2;
4415 pFormat += sizeof(DWORD);
4416 elements = *(const DWORD*)pFormat;
4417 pFormat += sizeof(DWORD);
4420 esize = *(const WORD*)pFormat;
4421 pFormat += sizeof(WORD);
4423 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4424 if ((pStubMsg->ActualCount > elements) ||
4425 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4427 RpcRaiseException(RPC_S_INVALID_BOUND);
4428 return;
4431 SizeVariance(pStubMsg);
4433 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4435 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4437 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4440 /***********************************************************************
4441 * NdrVaryingArrayMemorySize [RPCRT4.@]
4443 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4444 PFORMAT_STRING pFormat)
4446 unsigned char alignment;
4447 DWORD size, elements, esize;
4449 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4451 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4452 (pFormat[0] != RPC_FC_LGVARRAY))
4454 ERR("invalid format type %x\n", pFormat[0]);
4455 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4456 return 0;
4459 alignment = pFormat[1] + 1;
4461 if (pFormat[0] == RPC_FC_SMVARRAY)
4463 pFormat += 2;
4464 size = *(const WORD*)pFormat;
4465 pFormat += sizeof(WORD);
4466 elements = *(const WORD*)pFormat;
4467 pFormat += sizeof(WORD);
4469 else
4471 pFormat += 2;
4472 size = *(const DWORD*)pFormat;
4473 pFormat += sizeof(DWORD);
4474 elements = *(const DWORD*)pFormat;
4475 pFormat += sizeof(DWORD);
4478 esize = *(const WORD*)pFormat;
4479 pFormat += sizeof(WORD);
4481 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4483 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4485 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4486 pStubMsg->MemorySize += size;
4488 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4490 return pStubMsg->MemorySize;
4493 /***********************************************************************
4494 * NdrVaryingArrayFree [RPCRT4.@]
4496 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4497 unsigned char *pMemory,
4498 PFORMAT_STRING pFormat)
4500 unsigned char alignment;
4501 DWORD elements;
4503 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4505 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4506 (pFormat[0] != RPC_FC_LGVARRAY))
4508 ERR("invalid format type %x\n", pFormat[0]);
4509 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4510 return;
4513 alignment = pFormat[1] + 1;
4515 if (pFormat[0] == RPC_FC_SMVARRAY)
4517 pFormat += 2;
4518 pFormat += sizeof(WORD);
4519 elements = *(const WORD*)pFormat;
4520 pFormat += sizeof(WORD);
4522 else
4524 pFormat += 2;
4525 pFormat += sizeof(DWORD);
4526 elements = *(const DWORD*)pFormat;
4527 pFormat += sizeof(DWORD);
4530 pFormat += sizeof(WORD);
4532 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4533 if ((pStubMsg->ActualCount > elements) ||
4534 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4536 RpcRaiseException(RPC_S_INVALID_BOUND);
4537 return;
4540 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4543 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
4545 switch (fc)
4547 case RPC_FC_BYTE:
4548 case RPC_FC_CHAR:
4549 case RPC_FC_SMALL:
4550 case RPC_FC_USMALL:
4551 return *(const UCHAR *)pMemory;
4552 case RPC_FC_WCHAR:
4553 case RPC_FC_SHORT:
4554 case RPC_FC_USHORT:
4555 case RPC_FC_ENUM16:
4556 return *(const USHORT *)pMemory;
4557 case RPC_FC_LONG:
4558 case RPC_FC_ULONG:
4559 case RPC_FC_ENUM32:
4560 return *(const ULONG *)pMemory;
4561 default:
4562 FIXME("Unhandled base type: 0x%02x\n", fc);
4563 return 0;
4567 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4568 unsigned long discriminant,
4569 PFORMAT_STRING pFormat)
4571 unsigned short num_arms, arm, type;
4573 num_arms = *(const SHORT*)pFormat & 0x0fff;
4574 pFormat += 2;
4575 for(arm = 0; arm < num_arms; arm++)
4577 if(discriminant == *(const ULONG*)pFormat)
4579 pFormat += 4;
4580 break;
4582 pFormat += 6;
4585 type = *(const unsigned short*)pFormat;
4586 TRACE("type %04x\n", type);
4587 if(arm == num_arms) /* default arm extras */
4589 if(type == 0xffff)
4591 ERR("no arm for 0x%lx and no default case\n", discriminant);
4592 RpcRaiseException(RPC_S_INVALID_TAG);
4593 return NULL;
4595 if(type == 0)
4597 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
4598 return NULL;
4601 return pFormat;
4604 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
4606 unsigned short type;
4608 pFormat += 2;
4610 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4611 if(!pFormat)
4612 return NULL;
4614 type = *(const unsigned short*)pFormat;
4615 if((type & 0xff00) == 0x8000)
4617 unsigned char basetype = LOBYTE(type);
4618 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
4620 else
4622 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4623 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
4624 if (m)
4626 unsigned char *saved_buffer = NULL;
4627 int pointer_buffer_mark_set = 0;
4628 switch(*desc)
4630 case RPC_FC_RP:
4631 case RPC_FC_UP:
4632 case RPC_FC_OP:
4633 case RPC_FC_FP:
4634 ALIGN_POINTER(pStubMsg->Buffer, 4);
4635 saved_buffer = pStubMsg->Buffer;
4636 if (pStubMsg->PointerBufferMark)
4638 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4639 pStubMsg->PointerBufferMark = NULL;
4640 pointer_buffer_mark_set = 1;
4642 else
4643 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
4645 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
4646 if (pointer_buffer_mark_set)
4648 STD_OVERFLOW_CHECK(pStubMsg);
4649 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4650 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
4652 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4653 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
4654 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4656 pStubMsg->Buffer = saved_buffer + 4;
4658 break;
4659 default:
4660 m(pStubMsg, pMemory, desc);
4663 else FIXME("no marshaller for embedded type %02x\n", *desc);
4665 return NULL;
4668 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4669 unsigned char **ppMemory,
4670 ULONG discriminant,
4671 PFORMAT_STRING pFormat,
4672 unsigned char fMustAlloc)
4674 unsigned short type;
4676 pFormat += 2;
4678 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4679 if(!pFormat)
4680 return NULL;
4682 type = *(const unsigned short*)pFormat;
4683 if((type & 0xff00) == 0x8000)
4685 unsigned char basetype = LOBYTE(type);
4686 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
4688 else
4690 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4691 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
4692 if (m)
4694 unsigned char *saved_buffer = NULL;
4695 int pointer_buffer_mark_set = 0;
4696 switch(*desc)
4698 case RPC_FC_RP:
4699 case RPC_FC_UP:
4700 case RPC_FC_OP:
4701 case RPC_FC_FP:
4702 **(void***)ppMemory = NULL;
4703 ALIGN_POINTER(pStubMsg->Buffer, 4);
4704 saved_buffer = pStubMsg->Buffer;
4705 if (pStubMsg->PointerBufferMark)
4707 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4708 pStubMsg->PointerBufferMark = NULL;
4709 pointer_buffer_mark_set = 1;
4711 else
4712 pStubMsg->Buffer += 4; /* for pointer ID */
4714 if (saved_buffer + 4 > pStubMsg->BufferEnd)
4716 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4717 saved_buffer, pStubMsg->BufferEnd);
4718 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4721 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
4722 if (pointer_buffer_mark_set)
4724 STD_OVERFLOW_CHECK(pStubMsg);
4725 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4726 pStubMsg->Buffer = saved_buffer + 4;
4728 break;
4729 default:
4730 m(pStubMsg, ppMemory, desc, fMustAlloc);
4733 else FIXME("no marshaller for embedded type %02x\n", *desc);
4735 return NULL;
4738 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
4739 unsigned char *pMemory,
4740 ULONG discriminant,
4741 PFORMAT_STRING pFormat)
4743 unsigned short type;
4745 pFormat += 2;
4747 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4748 if(!pFormat)
4749 return;
4751 type = *(const unsigned short*)pFormat;
4752 if((type & 0xff00) == 0x8000)
4754 unsigned char basetype = LOBYTE(type);
4755 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
4757 else
4759 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4760 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
4761 if (m)
4763 switch(*desc)
4765 case RPC_FC_RP:
4766 case RPC_FC_UP:
4767 case RPC_FC_OP:
4768 case RPC_FC_FP:
4769 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4770 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
4771 if (!pStubMsg->IgnoreEmbeddedPointers)
4773 int saved_buffer_length = pStubMsg->BufferLength;
4774 pStubMsg->BufferLength = pStubMsg->PointerLength;
4775 pStubMsg->PointerLength = 0;
4776 if(!pStubMsg->BufferLength)
4777 ERR("BufferLength == 0??\n");
4778 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
4779 pStubMsg->PointerLength = pStubMsg->BufferLength;
4780 pStubMsg->BufferLength = saved_buffer_length;
4782 break;
4783 default:
4784 m(pStubMsg, pMemory, desc);
4787 else FIXME("no buffersizer for embedded type %02x\n", *desc);
4791 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
4792 ULONG discriminant,
4793 PFORMAT_STRING pFormat)
4795 unsigned short type, size;
4797 size = *(const unsigned short*)pFormat;
4798 pStubMsg->Memory += size;
4799 pFormat += 2;
4801 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4802 if(!pFormat)
4803 return 0;
4805 type = *(const unsigned short*)pFormat;
4806 if((type & 0xff00) == 0x8000)
4808 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
4810 else
4812 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4813 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
4814 unsigned char *saved_buffer;
4815 if (m)
4817 switch(*desc)
4819 case RPC_FC_RP:
4820 case RPC_FC_UP:
4821 case RPC_FC_OP:
4822 case RPC_FC_FP:
4823 ALIGN_POINTER(pStubMsg->Buffer, 4);
4824 saved_buffer = pStubMsg->Buffer;
4825 safe_buffer_increment(pStubMsg, 4);
4826 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
4827 pStubMsg->MemorySize += 4;
4828 if (!pStubMsg->IgnoreEmbeddedPointers)
4829 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
4830 break;
4831 default:
4832 return m(pStubMsg, desc);
4835 else FIXME("no marshaller for embedded type %02x\n", *desc);
4838 TRACE("size %d\n", size);
4839 return size;
4842 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
4843 unsigned char *pMemory,
4844 ULONG discriminant,
4845 PFORMAT_STRING pFormat)
4847 unsigned short type;
4849 pFormat += 2;
4851 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4852 if(!pFormat)
4853 return;
4855 type = *(const unsigned short*)pFormat;
4856 if((type & 0xff00) != 0x8000)
4858 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4859 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
4860 if (m)
4862 switch(*desc)
4864 case RPC_FC_RP:
4865 case RPC_FC_UP:
4866 case RPC_FC_OP:
4867 case RPC_FC_FP:
4868 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
4869 break;
4870 default:
4871 m(pStubMsg, pMemory, desc);
4874 else FIXME("no freer for embedded type %02x\n", *desc);
4878 /***********************************************************************
4879 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4881 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4882 unsigned char *pMemory,
4883 PFORMAT_STRING pFormat)
4885 unsigned char switch_type;
4886 unsigned char increment;
4887 ULONG switch_value;
4889 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4890 pFormat++;
4892 switch_type = *pFormat & 0xf;
4893 increment = (*pFormat & 0xf0) >> 4;
4894 pFormat++;
4896 ALIGN_POINTER(pStubMsg->Buffer, increment);
4898 switch_value = get_discriminant(switch_type, pMemory);
4899 TRACE("got switch value 0x%x\n", switch_value);
4901 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
4902 pMemory += increment;
4904 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
4907 /***********************************************************************
4908 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4910 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4911 unsigned char **ppMemory,
4912 PFORMAT_STRING pFormat,
4913 unsigned char fMustAlloc)
4915 unsigned char switch_type;
4916 unsigned char increment;
4917 ULONG switch_value;
4918 unsigned short size;
4919 unsigned char *pMemoryArm;
4921 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4922 pFormat++;
4924 switch_type = *pFormat & 0xf;
4925 increment = (*pFormat & 0xf0) >> 4;
4926 pFormat++;
4928 ALIGN_POINTER(pStubMsg->Buffer, increment);
4929 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
4930 TRACE("got switch value 0x%x\n", switch_value);
4932 size = *(const unsigned short*)pFormat + increment;
4933 if(!*ppMemory || fMustAlloc)
4934 *ppMemory = NdrAllocate(pStubMsg, size);
4936 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
4937 pMemoryArm = *ppMemory + increment;
4939 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
4942 /***********************************************************************
4943 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4945 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4946 unsigned char *pMemory,
4947 PFORMAT_STRING pFormat)
4949 unsigned char switch_type;
4950 unsigned char increment;
4951 ULONG switch_value;
4953 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4954 pFormat++;
4956 switch_type = *pFormat & 0xf;
4957 increment = (*pFormat & 0xf0) >> 4;
4958 pFormat++;
4960 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
4961 switch_value = get_discriminant(switch_type, pMemory);
4962 TRACE("got switch value 0x%x\n", switch_value);
4964 /* Add discriminant size */
4965 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
4966 pMemory += increment;
4968 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
4971 /***********************************************************************
4972 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4974 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4975 PFORMAT_STRING pFormat)
4977 unsigned char switch_type;
4978 unsigned char increment;
4979 ULONG switch_value;
4981 switch_type = *pFormat & 0xf;
4982 increment = (*pFormat & 0xf0) >> 4;
4983 pFormat++;
4985 ALIGN_POINTER(pStubMsg->Buffer, increment);
4986 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
4987 TRACE("got switch value 0x%x\n", switch_value);
4989 pStubMsg->Memory += increment;
4991 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
4994 /***********************************************************************
4995 * NdrEncapsulatedUnionFree [RPCRT4.@]
4997 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4998 unsigned char *pMemory,
4999 PFORMAT_STRING pFormat)
5001 unsigned char switch_type;
5002 unsigned char increment;
5003 ULONG switch_value;
5005 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5006 pFormat++;
5008 switch_type = *pFormat & 0xf;
5009 increment = (*pFormat & 0xf0) >> 4;
5010 pFormat++;
5012 switch_value = get_discriminant(switch_type, pMemory);
5013 TRACE("got switch value 0x%x\n", switch_value);
5015 pMemory += increment;
5017 return union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5020 /***********************************************************************
5021 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5023 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5024 unsigned char *pMemory,
5025 PFORMAT_STRING pFormat)
5027 unsigned char switch_type;
5029 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5030 pFormat++;
5032 switch_type = *pFormat;
5033 pFormat++;
5035 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5036 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5037 /* Marshall discriminant */
5038 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5040 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5043 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5044 PFORMAT_STRING *ppFormat)
5046 long discriminant = 0;
5048 switch(**ppFormat)
5050 case RPC_FC_BYTE:
5051 case RPC_FC_CHAR:
5052 case RPC_FC_SMALL:
5053 case RPC_FC_USMALL:
5055 UCHAR d;
5056 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5057 discriminant = d;
5058 break;
5060 case RPC_FC_WCHAR:
5061 case RPC_FC_SHORT:
5062 case RPC_FC_USHORT:
5064 USHORT d;
5065 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5066 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5067 discriminant = d;
5068 break;
5070 case RPC_FC_LONG:
5071 case RPC_FC_ULONG:
5073 ULONG d;
5074 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5075 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5076 discriminant = d;
5077 break;
5079 default:
5080 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5082 (*ppFormat)++;
5084 if (pStubMsg->fHasNewCorrDesc)
5085 *ppFormat += 6;
5086 else
5087 *ppFormat += 4;
5088 return discriminant;
5091 /**********************************************************************
5092 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5094 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5095 unsigned char **ppMemory,
5096 PFORMAT_STRING pFormat,
5097 unsigned char fMustAlloc)
5099 long discriminant;
5100 unsigned short size;
5102 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5103 pFormat++;
5105 /* Unmarshall discriminant */
5106 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5107 TRACE("unmarshalled discriminant %lx\n", discriminant);
5109 pFormat += *(const SHORT*)pFormat;
5111 size = *(const unsigned short*)pFormat;
5113 if(!*ppMemory || fMustAlloc)
5114 *ppMemory = NdrAllocate(pStubMsg, size);
5116 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5119 /***********************************************************************
5120 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5122 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5123 unsigned char *pMemory,
5124 PFORMAT_STRING pFormat)
5126 unsigned char switch_type;
5128 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5129 pFormat++;
5131 switch_type = *pFormat;
5132 pFormat++;
5134 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5135 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5136 /* Add discriminant size */
5137 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5139 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5142 /***********************************************************************
5143 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5145 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5146 PFORMAT_STRING pFormat)
5148 ULONG discriminant;
5150 pFormat++;
5151 /* Unmarshall discriminant */
5152 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5153 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
5155 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
5158 /***********************************************************************
5159 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5161 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5162 unsigned char *pMemory,
5163 PFORMAT_STRING pFormat)
5165 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5166 pFormat++;
5167 pFormat++;
5169 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5170 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5172 return union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5175 /***********************************************************************
5176 * NdrByteCountPointerMarshall [RPCRT4.@]
5178 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5179 unsigned char *pMemory,
5180 PFORMAT_STRING pFormat)
5182 FIXME("stub\n");
5183 return NULL;
5186 /***********************************************************************
5187 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5189 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5190 unsigned char **ppMemory,
5191 PFORMAT_STRING pFormat,
5192 unsigned char fMustAlloc)
5194 FIXME("stub\n");
5195 return NULL;
5198 /***********************************************************************
5199 * NdrByteCountPointerBufferSize [RPCRT4.@]
5201 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5202 unsigned char *pMemory,
5203 PFORMAT_STRING pFormat)
5205 FIXME("stub\n");
5208 /***********************************************************************
5209 * NdrByteCountPointerMemorySize [RPCRT4.@]
5211 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5212 PFORMAT_STRING pFormat)
5214 FIXME("stub\n");
5215 return 0;
5218 /***********************************************************************
5219 * NdrByteCountPointerFree [RPCRT4.@]
5221 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
5222 unsigned char *pMemory,
5223 PFORMAT_STRING pFormat)
5225 FIXME("stub\n");
5228 /***********************************************************************
5229 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5231 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5232 unsigned char *pMemory,
5233 PFORMAT_STRING pFormat)
5235 FIXME("stub\n");
5236 return NULL;
5239 /***********************************************************************
5240 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5242 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5243 unsigned char **ppMemory,
5244 PFORMAT_STRING pFormat,
5245 unsigned char fMustAlloc)
5247 FIXME("stub\n");
5248 return NULL;
5251 /***********************************************************************
5252 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5254 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5255 unsigned char *pMemory,
5256 PFORMAT_STRING pFormat)
5258 FIXME("stub\n");
5261 /***********************************************************************
5262 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5264 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5265 PFORMAT_STRING pFormat)
5267 FIXME("stub\n");
5268 return 0;
5271 /***********************************************************************
5272 * NdrXmitOrRepAsFree [RPCRT4.@]
5274 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
5275 unsigned char *pMemory,
5276 PFORMAT_STRING pFormat)
5278 FIXME("stub\n");
5281 #include "pshpack1.h"
5282 typedef struct
5284 unsigned char type;
5285 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
5286 ULONG low_value;
5287 ULONG high_value;
5288 } NDR_RANGE;
5289 #include "poppack.h"
5291 /***********************************************************************
5292 * NdrRangeMarshall [internal]
5294 unsigned char *WINAPI NdrRangeMarshall(
5295 PMIDL_STUB_MESSAGE pStubMsg,
5296 unsigned char *pMemory,
5297 PFORMAT_STRING pFormat)
5299 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5300 unsigned char base_type;
5302 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5304 if (pRange->type != RPC_FC_RANGE)
5306 ERR("invalid format type %x\n", pRange->type);
5307 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5308 return NULL;
5311 base_type = pRange->flags_type & 0xf;
5313 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
5316 /***********************************************************************
5317 * NdrRangeUnmarshall
5319 unsigned char *WINAPI NdrRangeUnmarshall(
5320 PMIDL_STUB_MESSAGE pStubMsg,
5321 unsigned char **ppMemory,
5322 PFORMAT_STRING pFormat,
5323 unsigned char fMustAlloc)
5325 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5326 unsigned char base_type;
5328 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5330 if (pRange->type != RPC_FC_RANGE)
5332 ERR("invalid format type %x\n", pRange->type);
5333 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5334 return NULL;
5336 base_type = pRange->flags_type & 0xf;
5338 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5339 base_type, pRange->low_value, pRange->high_value);
5341 #define RANGE_UNMARSHALL(type, format_spec) \
5342 do \
5344 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5345 if (fMustAlloc || !*ppMemory) \
5346 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5347 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5349 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5350 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5351 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5353 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5354 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5356 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5357 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5358 (type)pRange->high_value); \
5359 RpcRaiseException(RPC_S_INVALID_BOUND); \
5360 return NULL; \
5362 TRACE("*ppMemory: %p\n", *ppMemory); \
5363 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5364 pStubMsg->Buffer += sizeof(type); \
5365 } while (0)
5367 switch(base_type)
5369 case RPC_FC_CHAR:
5370 case RPC_FC_SMALL:
5371 RANGE_UNMARSHALL(UCHAR, "%d");
5372 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5373 break;
5374 case RPC_FC_BYTE:
5375 case RPC_FC_USMALL:
5376 RANGE_UNMARSHALL(CHAR, "%u");
5377 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5378 break;
5379 case RPC_FC_WCHAR: /* FIXME: valid? */
5380 case RPC_FC_USHORT:
5381 RANGE_UNMARSHALL(USHORT, "%u");
5382 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5383 break;
5384 case RPC_FC_SHORT:
5385 RANGE_UNMARSHALL(SHORT, "%d");
5386 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5387 break;
5388 case RPC_FC_LONG:
5389 RANGE_UNMARSHALL(LONG, "%d");
5390 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5391 break;
5392 case RPC_FC_ULONG:
5393 RANGE_UNMARSHALL(ULONG, "%u");
5394 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5395 break;
5396 case RPC_FC_ENUM16:
5397 case RPC_FC_ENUM32:
5398 FIXME("Unhandled enum type\n");
5399 break;
5400 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
5401 case RPC_FC_FLOAT:
5402 case RPC_FC_DOUBLE:
5403 case RPC_FC_HYPER:
5404 default:
5405 ERR("invalid range base type: 0x%02x\n", base_type);
5406 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5409 return NULL;
5412 /***********************************************************************
5413 * NdrRangeBufferSize [internal]
5415 void WINAPI NdrRangeBufferSize(
5416 PMIDL_STUB_MESSAGE pStubMsg,
5417 unsigned char *pMemory,
5418 PFORMAT_STRING pFormat)
5420 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5421 unsigned char base_type;
5423 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5425 if (pRange->type != RPC_FC_RANGE)
5427 ERR("invalid format type %x\n", pRange->type);
5428 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5430 base_type = pRange->flags_type & 0xf;
5432 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
5435 /***********************************************************************
5436 * NdrRangeMemorySize [internal]
5438 ULONG WINAPI NdrRangeMemorySize(
5439 PMIDL_STUB_MESSAGE pStubMsg,
5440 PFORMAT_STRING pFormat)
5442 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5443 unsigned char base_type;
5445 if (pRange->type != RPC_FC_RANGE)
5447 ERR("invalid format type %x\n", pRange->type);
5448 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5449 return 0;
5451 base_type = pRange->flags_type & 0xf;
5453 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
5456 /***********************************************************************
5457 * NdrRangeFree [internal]
5459 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
5460 unsigned char *pMemory,
5461 PFORMAT_STRING pFormat)
5463 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5465 /* nothing to do */
5468 /***********************************************************************
5469 * NdrBaseTypeMarshall [internal]
5471 static unsigned char *WINAPI NdrBaseTypeMarshall(
5472 PMIDL_STUB_MESSAGE pStubMsg,
5473 unsigned char *pMemory,
5474 PFORMAT_STRING pFormat)
5476 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5478 switch(*pFormat)
5480 case RPC_FC_BYTE:
5481 case RPC_FC_CHAR:
5482 case RPC_FC_SMALL:
5483 case RPC_FC_USMALL:
5484 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
5485 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
5486 break;
5487 case RPC_FC_WCHAR:
5488 case RPC_FC_SHORT:
5489 case RPC_FC_USHORT:
5490 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5491 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
5492 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
5493 break;
5494 case RPC_FC_LONG:
5495 case RPC_FC_ULONG:
5496 case RPC_FC_ERROR_STATUS_T:
5497 case RPC_FC_ENUM32:
5498 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5499 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
5500 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
5501 break;
5502 case RPC_FC_FLOAT:
5503 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
5504 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
5505 break;
5506 case RPC_FC_DOUBLE:
5507 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
5508 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
5509 break;
5510 case RPC_FC_HYPER:
5511 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
5512 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
5513 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
5514 break;
5515 case RPC_FC_ENUM16:
5516 /* only 16-bits on the wire, so do a sanity check */
5517 if (*(UINT *)pMemory > SHRT_MAX)
5518 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
5519 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5520 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5521 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5522 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
5523 pStubMsg->Buffer += sizeof(USHORT);
5524 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
5525 break;
5526 case RPC_FC_IGNORE:
5527 break;
5528 default:
5529 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5532 /* FIXME: what is the correct return value? */
5533 return NULL;
5536 /***********************************************************************
5537 * NdrBaseTypeUnmarshall [internal]
5539 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
5540 PMIDL_STUB_MESSAGE pStubMsg,
5541 unsigned char **ppMemory,
5542 PFORMAT_STRING pFormat,
5543 unsigned char fMustAlloc)
5545 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5547 #define BASE_TYPE_UNMARSHALL(type) \
5548 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5549 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
5551 *ppMemory = pStubMsg->Buffer; \
5552 TRACE("*ppMemory: %p\n", *ppMemory); \
5554 else \
5556 if (fMustAlloc) \
5557 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5558 TRACE("*ppMemory: %p\n", *ppMemory); \
5559 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5561 pStubMsg->Buffer += sizeof(type);
5563 switch(*pFormat)
5565 case RPC_FC_BYTE:
5566 case RPC_FC_CHAR:
5567 case RPC_FC_SMALL:
5568 case RPC_FC_USMALL:
5569 BASE_TYPE_UNMARSHALL(UCHAR);
5570 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5571 break;
5572 case RPC_FC_WCHAR:
5573 case RPC_FC_SHORT:
5574 case RPC_FC_USHORT:
5575 BASE_TYPE_UNMARSHALL(USHORT);
5576 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5577 break;
5578 case RPC_FC_LONG:
5579 case RPC_FC_ULONG:
5580 case RPC_FC_ERROR_STATUS_T:
5581 case RPC_FC_ENUM32:
5582 BASE_TYPE_UNMARSHALL(ULONG);
5583 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5584 break;
5585 case RPC_FC_FLOAT:
5586 BASE_TYPE_UNMARSHALL(float);
5587 TRACE("value: %f\n", **(float **)ppMemory);
5588 break;
5589 case RPC_FC_DOUBLE:
5590 BASE_TYPE_UNMARSHALL(double);
5591 TRACE("value: %f\n", **(double **)ppMemory);
5592 break;
5593 case RPC_FC_HYPER:
5594 BASE_TYPE_UNMARSHALL(ULONGLONG);
5595 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
5596 break;
5597 case RPC_FC_ENUM16:
5598 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5599 if (fMustAlloc || !*ppMemory)
5600 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
5601 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
5602 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5603 TRACE("*ppMemory: %p\n", *ppMemory);
5604 /* 16-bits on the wire, but int in memory */
5605 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
5606 pStubMsg->Buffer += sizeof(USHORT);
5607 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
5608 break;
5609 case RPC_FC_IGNORE:
5610 break;
5611 default:
5612 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5614 #undef BASE_TYPE_UNMARSHALL
5616 /* FIXME: what is the correct return value? */
5618 return NULL;
5621 /***********************************************************************
5622 * NdrBaseTypeBufferSize [internal]
5624 static void WINAPI NdrBaseTypeBufferSize(
5625 PMIDL_STUB_MESSAGE pStubMsg,
5626 unsigned char *pMemory,
5627 PFORMAT_STRING pFormat)
5629 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5631 switch(*pFormat)
5633 case RPC_FC_BYTE:
5634 case RPC_FC_CHAR:
5635 case RPC_FC_SMALL:
5636 case RPC_FC_USMALL:
5637 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
5638 break;
5639 case RPC_FC_WCHAR:
5640 case RPC_FC_SHORT:
5641 case RPC_FC_USHORT:
5642 case RPC_FC_ENUM16:
5643 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
5644 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
5645 break;
5646 case RPC_FC_LONG:
5647 case RPC_FC_ULONG:
5648 case RPC_FC_ENUM32:
5649 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
5650 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
5651 break;
5652 case RPC_FC_FLOAT:
5653 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
5654 safe_buffer_length_increment(pStubMsg, sizeof(float));
5655 break;
5656 case RPC_FC_DOUBLE:
5657 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
5658 safe_buffer_length_increment(pStubMsg, sizeof(double));
5659 break;
5660 case RPC_FC_HYPER:
5661 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
5662 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
5663 break;
5664 case RPC_FC_ERROR_STATUS_T:
5665 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
5666 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
5667 break;
5668 case RPC_FC_IGNORE:
5669 break;
5670 default:
5671 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5675 /***********************************************************************
5676 * NdrBaseTypeMemorySize [internal]
5678 static ULONG WINAPI NdrBaseTypeMemorySize(
5679 PMIDL_STUB_MESSAGE pStubMsg,
5680 PFORMAT_STRING pFormat)
5682 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
5684 switch(*pFormat)
5686 case RPC_FC_BYTE:
5687 case RPC_FC_CHAR:
5688 case RPC_FC_SMALL:
5689 case RPC_FC_USMALL:
5690 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
5691 pStubMsg->MemorySize += sizeof(UCHAR);
5692 return sizeof(UCHAR);
5693 case RPC_FC_WCHAR:
5694 case RPC_FC_SHORT:
5695 case RPC_FC_USHORT:
5696 safe_buffer_increment(pStubMsg, sizeof(USHORT));
5697 pStubMsg->MemorySize += sizeof(USHORT);
5698 return sizeof(USHORT);
5699 case RPC_FC_LONG:
5700 case RPC_FC_ULONG:
5701 case RPC_FC_ENUM32:
5702 safe_buffer_increment(pStubMsg, sizeof(ULONG));
5703 pStubMsg->MemorySize += sizeof(ULONG);
5704 return sizeof(ULONG);
5705 case RPC_FC_FLOAT:
5706 safe_buffer_increment(pStubMsg, sizeof(float));
5707 pStubMsg->MemorySize += sizeof(float);
5708 return sizeof(float);
5709 case RPC_FC_DOUBLE:
5710 safe_buffer_increment(pStubMsg, sizeof(double));
5711 pStubMsg->MemorySize += sizeof(double);
5712 return sizeof(double);
5713 case RPC_FC_HYPER:
5714 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
5715 pStubMsg->MemorySize += sizeof(ULONGLONG);
5716 return sizeof(ULONGLONG);
5717 case RPC_FC_ERROR_STATUS_T:
5718 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
5719 pStubMsg->MemorySize += sizeof(error_status_t);
5720 return sizeof(error_status_t);
5721 case RPC_FC_ENUM16:
5722 safe_buffer_increment(pStubMsg, sizeof(USHORT));
5723 pStubMsg->MemorySize += sizeof(UINT);
5724 return sizeof(UINT);
5725 case RPC_FC_IGNORE:
5726 pStubMsg->MemorySize += sizeof(void *);
5727 return sizeof(void *);
5728 default:
5729 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5730 return 0;
5734 /***********************************************************************
5735 * NdrBaseTypeFree [internal]
5737 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
5738 unsigned char *pMemory,
5739 PFORMAT_STRING pFormat)
5741 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5743 /* nothing to do */
5746 /***********************************************************************
5747 * NdrContextHandleBufferSize [internal]
5749 static void WINAPI NdrContextHandleBufferSize(
5750 PMIDL_STUB_MESSAGE pStubMsg,
5751 unsigned char *pMemory,
5752 PFORMAT_STRING pFormat)
5754 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5756 if (*pFormat != RPC_FC_BIND_CONTEXT)
5758 ERR("invalid format type %x\n", *pFormat);
5759 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5761 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5762 safe_buffer_length_increment(pStubMsg, cbNDRContext);
5765 /***********************************************************************
5766 * NdrContextHandleMarshall [internal]
5768 static unsigned char *WINAPI NdrContextHandleMarshall(
5769 PMIDL_STUB_MESSAGE pStubMsg,
5770 unsigned char *pMemory,
5771 PFORMAT_STRING pFormat)
5773 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5775 if (*pFormat != RPC_FC_BIND_CONTEXT)
5777 ERR("invalid format type %x\n", *pFormat);
5778 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5781 if (pFormat[1] & 0x80)
5782 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
5783 else
5784 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
5786 return NULL;
5789 /***********************************************************************
5790 * NdrContextHandleUnmarshall [internal]
5792 static unsigned char *WINAPI NdrContextHandleUnmarshall(
5793 PMIDL_STUB_MESSAGE pStubMsg,
5794 unsigned char **ppMemory,
5795 PFORMAT_STRING pFormat,
5796 unsigned char fMustAlloc)
5798 if (*pFormat != RPC_FC_BIND_CONTEXT)
5800 ERR("invalid format type %x\n", *pFormat);
5801 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5804 **(NDR_CCONTEXT **)ppMemory = NULL;
5805 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
5807 return NULL;
5810 /***********************************************************************
5811 * NdrClientContextMarshall [RPCRT4.@]
5813 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5814 NDR_CCONTEXT ContextHandle,
5815 int fCheck)
5817 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
5819 ALIGN_POINTER(pStubMsg->Buffer, 4);
5821 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5823 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
5824 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5825 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5828 /* FIXME: what does fCheck do? */
5829 NDRCContextMarshall(ContextHandle,
5830 pStubMsg->Buffer);
5832 pStubMsg->Buffer += cbNDRContext;
5835 /***********************************************************************
5836 * NdrClientContextUnmarshall [RPCRT4.@]
5838 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5839 NDR_CCONTEXT * pContextHandle,
5840 RPC_BINDING_HANDLE BindHandle)
5842 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
5844 ALIGN_POINTER(pStubMsg->Buffer, 4);
5846 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
5847 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5849 NDRCContextUnmarshall(pContextHandle,
5850 BindHandle,
5851 pStubMsg->Buffer,
5852 pStubMsg->RpcMsg->DataRepresentation);
5854 pStubMsg->Buffer += cbNDRContext;
5857 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5858 NDR_SCONTEXT ContextHandle,
5859 NDR_RUNDOWN RundownRoutine )
5861 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
5864 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
5866 FIXME("(%p): stub\n", pStubMsg);
5867 return NULL;
5870 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
5871 unsigned char* pMemory,
5872 PFORMAT_STRING pFormat)
5874 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
5877 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
5878 PFORMAT_STRING pFormat)
5880 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
5881 return NULL;
5884 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5885 NDR_SCONTEXT ContextHandle,
5886 NDR_RUNDOWN RundownRoutine,
5887 PFORMAT_STRING pFormat)
5889 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
5892 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5893 PFORMAT_STRING pFormat)
5895 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
5896 return NULL;
5899 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
5901 typedef struct ndr_context_handle
5903 DWORD attributes;
5904 GUID uuid;
5905 } ndr_context_handle;
5907 struct context_handle_entry
5909 struct list entry;
5910 DWORD magic;
5911 RPC_BINDING_HANDLE handle;
5912 ndr_context_handle wire_data;
5915 static struct list context_handle_list = LIST_INIT(context_handle_list);
5917 static CRITICAL_SECTION ndr_context_cs;
5918 static CRITICAL_SECTION_DEBUG ndr_context_debug =
5920 0, 0, &ndr_context_cs,
5921 { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
5922 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
5924 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
5926 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
5928 struct context_handle_entry *che = (struct context_handle_entry*) CContext;
5930 if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
5931 return NULL;
5932 return che;
5935 static struct context_handle_entry *context_entry_from_guid(LPCGUID uuid)
5937 struct context_handle_entry *che;
5938 LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
5939 if (IsEqualGUID(&che->wire_data.uuid, uuid))
5940 return che;
5941 return NULL;
5944 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
5946 struct context_handle_entry *che;
5947 RPC_BINDING_HANDLE handle = NULL;
5949 TRACE("%p\n", CContext);
5951 EnterCriticalSection(&ndr_context_cs);
5952 che = get_context_entry(CContext);
5953 if (che)
5954 handle = che->handle;
5955 LeaveCriticalSection(&ndr_context_cs);
5957 if (!handle)
5958 RpcRaiseException(ERROR_INVALID_HANDLE);
5959 return handle;
5962 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
5964 struct context_handle_entry *che;
5966 TRACE("%p %p\n", CContext, pBuff);
5968 if (CContext)
5970 EnterCriticalSection(&ndr_context_cs);
5971 che = get_context_entry(CContext);
5972 memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
5973 LeaveCriticalSection(&ndr_context_cs);
5975 else
5977 ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
5978 wire_data->attributes = 0;
5979 wire_data->uuid = GUID_NULL;
5983 /***********************************************************************
5984 * RpcSmDestroyClientContext [RPCRT4.@]
5986 RPC_STATUS WINAPI RpcSmDestroyClientContext(void **ContextHandle)
5988 RPC_STATUS status = RPC_X_SS_CONTEXT_MISMATCH;
5989 struct context_handle_entry *che = NULL;
5991 TRACE("(%p)\n", ContextHandle);
5993 EnterCriticalSection(&ndr_context_cs);
5994 che = get_context_entry(*ContextHandle);
5995 *ContextHandle = NULL;
5996 if (che)
5998 status = RPC_S_OK;
5999 list_remove(&che->entry);
6002 LeaveCriticalSection(&ndr_context_cs);
6004 if (che)
6006 RpcBindingFree(&che->handle);
6007 HeapFree(GetProcessHeap(), 0, che);
6010 return status;
6013 /***********************************************************************
6014 * RpcSsDestroyClientContext [RPCRT4.@]
6016 void WINAPI RpcSsDestroyClientContext(void **ContextHandle)
6018 RPC_STATUS status = RpcSmDestroyClientContext(ContextHandle);
6019 if (status != RPC_S_OK)
6020 RpcRaiseException(status);
6023 static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
6024 RPC_BINDING_HANDLE hBinding,
6025 const ndr_context_handle *chi)
6027 struct context_handle_entry *che = NULL;
6029 /* a null UUID means we should free the context handle */
6030 if (IsEqualGUID(&chi->uuid, &GUID_NULL))
6032 if (*CContext)
6034 che = get_context_entry(*CContext);
6035 if (!che)
6036 return ERROR_INVALID_HANDLE;
6037 list_remove(&che->entry);
6038 RpcBindingFree(&che->handle);
6039 HeapFree(GetProcessHeap(), 0, che);
6040 che = NULL;
6043 /* if there's no existing entry matching the GUID, allocate one */
6044 else if (!(che = context_entry_from_guid(&chi->uuid)))
6046 che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
6047 if (!che)
6048 return ERROR_NOT_ENOUGH_MEMORY;
6049 che->magic = NDR_CONTEXT_HANDLE_MAGIC;
6050 RpcBindingCopy(hBinding, &che->handle);
6051 list_add_tail(&context_handle_list, &che->entry);
6052 memcpy(&che->wire_data, chi, sizeof *chi);
6055 *CContext = che;
6057 return ERROR_SUCCESS;
6060 /***********************************************************************
6061 * NDRCContextUnmarshall [RPCRT4.@]
6063 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
6064 RPC_BINDING_HANDLE hBinding,
6065 void *pBuff, ULONG DataRepresentation)
6067 UINT r;
6069 TRACE("*%p=(%p) %p %p %08x\n",
6070 CContext, *CContext, hBinding, pBuff, DataRepresentation);
6072 EnterCriticalSection(&ndr_context_cs);
6073 r = ndr_update_context_handle(CContext, hBinding, pBuff);
6074 LeaveCriticalSection(&ndr_context_cs);
6075 if (r)
6076 RpcRaiseException(r);
6079 /***********************************************************************
6080 * NDRSContextMarshall [RPCRT4.@]
6082 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
6083 void *pBuff,
6084 NDR_RUNDOWN userRunDownIn)
6086 FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn);
6089 /***********************************************************************
6090 * NDRSContextMarshallEx [RPCRT4.@]
6092 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
6093 NDR_SCONTEXT CContext,
6094 void *pBuff,
6095 NDR_RUNDOWN userRunDownIn)
6097 FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn);
6100 /***********************************************************************
6101 * NDRSContextMarshall2 [RPCRT4.@]
6103 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
6104 NDR_SCONTEXT CContext,
6105 void *pBuff,
6106 NDR_RUNDOWN userRunDownIn,
6107 void *CtxGuard, ULONG Flags)
6109 FIXME("(%p %p %p %p %p %u): stub\n",
6110 hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags);
6113 /***********************************************************************
6114 * NDRSContextUnmarshall [RPCRT4.@]
6116 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
6117 ULONG DataRepresentation)
6119 FIXME("(%p %08x): stub\n", pBuff, DataRepresentation);
6120 return NULL;
6123 /***********************************************************************
6124 * NDRSContextUnmarshallEx [RPCRT4.@]
6126 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
6127 void *pBuff,
6128 ULONG DataRepresentation)
6130 FIXME("(%p %p %08x): stub\n", hBinding, pBuff, DataRepresentation);
6131 return NULL;
6134 /***********************************************************************
6135 * NDRSContextUnmarshall2 [RPCRT4.@]
6137 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
6138 void *pBuff,
6139 ULONG DataRepresentation,
6140 void *CtxGuard, ULONG Flags)
6142 FIXME("(%p %p %08x %p %u): stub\n",
6143 hBinding, pBuff, DataRepresentation, CtxGuard, Flags);
6144 return NULL;