rpcrt4: Fix buffer size calculation for arrays with embedded pointers.
[wine/multimedia.git] / dlls / rpcrt4 / ndr_marshall.c
blob0cb41bc64f56ae3047215d6c7e4ad4afc2b6b642
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 * - String structs
23 * - Byte count pointers
24 * - transmit_as/represent as
25 * - Multi-dimensional arrays
26 * - Conversion functions (NdrConvert)
27 * - Checks for integer addition overflow in user marshall functions
30 #include <assert.h>
31 #include <stdarg.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <limits.h>
36 #define NONAMELESSUNION
37 #include "windef.h"
38 #include "winbase.h"
39 #include "winerror.h"
41 #include "ndr_misc.h"
42 #include "rpcndr.h"
43 #include "ndrtypes.h"
45 #include "wine/unicode.h"
46 #include "wine/rpcfc.h"
48 #include "wine/debug.h"
50 WINE_DEFAULT_DEBUG_CHANNEL(ole);
52 #if defined(__i386__)
53 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
54 (*((UINT32 *)(pchar)) = (uint32))
56 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
57 (*((UINT32 *)(pchar)))
58 #else
59 /* these would work for i386 too, but less efficient */
60 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
61 (*(pchar) = LOBYTE(LOWORD(uint32)), \
62 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
63 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
64 *((pchar)+3) = HIBYTE(HIWORD(uint32)))
66 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
67 (MAKELONG( \
68 MAKEWORD(*(pchar), *((pchar)+1)), \
69 MAKEWORD(*((pchar)+2), *((pchar)+3))))
70 #endif
72 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
73 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
74 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
75 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
76 *(pchar) = HIBYTE(HIWORD(uint32)))
78 #define BIG_ENDIAN_UINT32_READ(pchar) \
79 (MAKELONG( \
80 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
81 MAKEWORD(*((pchar)+1), *(pchar))))
83 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
84 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
85 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
86 # define NDR_LOCAL_UINT32_READ(pchar) \
87 BIG_ENDIAN_UINT32_READ(pchar)
88 #else
89 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
90 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
91 # define NDR_LOCAL_UINT32_READ(pchar) \
92 LITTLE_ENDIAN_UINT32_READ(pchar)
93 #endif
95 static inline void align_length( ULONG *len, unsigned int align )
97 *len = (*len + align - 1) & ~(align - 1);
100 static inline void align_pointer( unsigned char **ptr, unsigned int align )
102 ULONG_PTR mask = align - 1;
103 *ptr = (unsigned char *)(((ULONG_PTR)*ptr + mask) & ~mask);
106 static inline void align_pointer_clear( unsigned char **ptr, unsigned int align )
108 ULONG_PTR mask = align - 1;
109 memset( *ptr, 0, (align - (ULONG_PTR)*ptr) & mask );
110 *ptr = (unsigned char *)(((ULONG_PTR)*ptr + mask) & ~mask);
113 #define STD_OVERFLOW_CHECK(_Msg) do { \
114 TRACE("buffer=%d/%d\n", (ULONG)(_Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer), _Msg->BufferLength); \
115 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
116 ERR("buffer overflow %d bytes\n", (ULONG)(_Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength))); \
117 } while (0)
119 #define NDR_POINTER_ID_BASE 0x20000
120 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
121 #define NDR_TABLE_SIZE 128
122 #define NDR_TABLE_MASK 127
124 #define NDRSContextFromValue(user_context) (NDR_SCONTEXT)((char *)(user_context) - (char *)NDRSContextValue((NDR_SCONTEXT)NULL))
126 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
127 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
128 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
129 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
130 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
132 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
133 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
134 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
136 static unsigned char *WINAPI NdrRangeMarshall(PMIDL_STUB_MESSAGE,unsigned char *, PFORMAT_STRING);
137 static void WINAPI NdrRangeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
138 static ULONG WINAPI NdrRangeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
139 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
141 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
143 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
144 unsigned char *pMemory,
145 PFORMAT_STRING pFormat,
146 PFORMAT_STRING pPointer);
147 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
148 unsigned char *pMemory,
149 PFORMAT_STRING pFormat,
150 PFORMAT_STRING pPointer);
151 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
152 unsigned char *pMemory,
153 PFORMAT_STRING pFormat,
154 PFORMAT_STRING pPointer,
155 unsigned char fMustAlloc);
156 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
157 PFORMAT_STRING pFormat,
158 PFORMAT_STRING pPointer);
159 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
160 unsigned char *pMemory,
161 PFORMAT_STRING pFormat,
162 PFORMAT_STRING pPointer);
164 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
166 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
167 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
168 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
169 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
170 /* 0x10 */
171 NdrBaseTypeMarshall,
172 /* 0x11 */
173 NdrPointerMarshall, NdrPointerMarshall,
174 NdrPointerMarshall, NdrPointerMarshall,
175 /* 0x15 */
176 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
177 NdrConformantStructMarshall, NdrConformantStructMarshall,
178 NdrConformantVaryingStructMarshall,
179 NdrComplexStructMarshall,
180 /* 0x1b */
181 NdrConformantArrayMarshall,
182 NdrConformantVaryingArrayMarshall,
183 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
184 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
185 NdrComplexArrayMarshall,
186 /* 0x22 */
187 NdrConformantStringMarshall, 0, 0,
188 NdrConformantStringMarshall,
189 NdrNonConformantStringMarshall, 0, 0, 0,
190 /* 0x2a */
191 NdrEncapsulatedUnionMarshall,
192 NdrNonEncapsulatedUnionMarshall,
193 NdrByteCountPointerMarshall,
194 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
195 /* 0x2f */
196 NdrInterfacePointerMarshall,
197 /* 0x30 */
198 NdrContextHandleMarshall,
199 /* 0xb1 */
200 0, 0, 0,
201 NdrUserMarshalMarshall,
202 0, 0,
203 /* 0xb7 */
204 NdrRangeMarshall
206 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
208 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
209 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
210 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
211 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
212 /* 0x10 */
213 NdrBaseTypeUnmarshall,
214 /* 0x11 */
215 NdrPointerUnmarshall, NdrPointerUnmarshall,
216 NdrPointerUnmarshall, NdrPointerUnmarshall,
217 /* 0x15 */
218 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
219 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
220 NdrConformantVaryingStructUnmarshall,
221 NdrComplexStructUnmarshall,
222 /* 0x1b */
223 NdrConformantArrayUnmarshall,
224 NdrConformantVaryingArrayUnmarshall,
225 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
226 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
227 NdrComplexArrayUnmarshall,
228 /* 0x22 */
229 NdrConformantStringUnmarshall, 0, 0,
230 NdrConformantStringUnmarshall,
231 NdrNonConformantStringUnmarshall, 0, 0, 0,
232 /* 0x2a */
233 NdrEncapsulatedUnionUnmarshall,
234 NdrNonEncapsulatedUnionUnmarshall,
235 NdrByteCountPointerUnmarshall,
236 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
237 /* 0x2f */
238 NdrInterfacePointerUnmarshall,
239 /* 0x30 */
240 NdrContextHandleUnmarshall,
241 /* 0xb1 */
242 0, 0, 0,
243 NdrUserMarshalUnmarshall,
244 0, 0,
245 /* 0xb7 */
246 NdrRangeUnmarshall
248 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
250 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
251 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
252 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
253 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
254 /* 0x10 */
255 NdrBaseTypeBufferSize,
256 /* 0x11 */
257 NdrPointerBufferSize, NdrPointerBufferSize,
258 NdrPointerBufferSize, NdrPointerBufferSize,
259 /* 0x15 */
260 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
261 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
262 NdrConformantVaryingStructBufferSize,
263 NdrComplexStructBufferSize,
264 /* 0x1b */
265 NdrConformantArrayBufferSize,
266 NdrConformantVaryingArrayBufferSize,
267 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
268 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
269 NdrComplexArrayBufferSize,
270 /* 0x22 */
271 NdrConformantStringBufferSize, 0, 0,
272 NdrConformantStringBufferSize,
273 NdrNonConformantStringBufferSize, 0, 0, 0,
274 /* 0x2a */
275 NdrEncapsulatedUnionBufferSize,
276 NdrNonEncapsulatedUnionBufferSize,
277 NdrByteCountPointerBufferSize,
278 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
279 /* 0x2f */
280 NdrInterfacePointerBufferSize,
281 /* 0x30 */
282 NdrContextHandleBufferSize,
283 /* 0xb1 */
284 0, 0, 0,
285 NdrUserMarshalBufferSize,
286 0, 0,
287 /* 0xb7 */
288 NdrRangeBufferSize
290 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
292 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
293 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
294 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
295 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
296 /* 0x10 */
297 NdrBaseTypeMemorySize,
298 /* 0x11 */
299 NdrPointerMemorySize, NdrPointerMemorySize,
300 NdrPointerMemorySize, NdrPointerMemorySize,
301 /* 0x15 */
302 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
303 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
304 NdrConformantVaryingStructMemorySize,
305 NdrComplexStructMemorySize,
306 /* 0x1b */
307 NdrConformantArrayMemorySize,
308 NdrConformantVaryingArrayMemorySize,
309 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
310 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
311 NdrComplexArrayMemorySize,
312 /* 0x22 */
313 NdrConformantStringMemorySize, 0, 0,
314 NdrConformantStringMemorySize,
315 NdrNonConformantStringMemorySize, 0, 0, 0,
316 /* 0x2a */
317 NdrEncapsulatedUnionMemorySize,
318 NdrNonEncapsulatedUnionMemorySize,
319 NdrByteCountPointerMemorySize,
320 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
321 /* 0x2f */
322 NdrInterfacePointerMemorySize,
323 /* 0x30 */
325 /* 0xb1 */
326 0, 0, 0,
327 NdrUserMarshalMemorySize,
328 0, 0,
329 /* 0xb7 */
330 NdrRangeMemorySize
332 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
334 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
335 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
336 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
337 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
338 /* 0x10 */
339 NdrBaseTypeFree,
340 /* 0x11 */
341 NdrPointerFree, NdrPointerFree,
342 NdrPointerFree, NdrPointerFree,
343 /* 0x15 */
344 NdrSimpleStructFree, NdrSimpleStructFree,
345 NdrConformantStructFree, NdrConformantStructFree,
346 NdrConformantVaryingStructFree,
347 NdrComplexStructFree,
348 /* 0x1b */
349 NdrConformantArrayFree,
350 NdrConformantVaryingArrayFree,
351 NdrFixedArrayFree, NdrFixedArrayFree,
352 NdrVaryingArrayFree, NdrVaryingArrayFree,
353 NdrComplexArrayFree,
354 /* 0x22 */
355 0, 0, 0,
356 0, 0, 0, 0, 0,
357 /* 0x2a */
358 NdrEncapsulatedUnionFree,
359 NdrNonEncapsulatedUnionFree,
361 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
362 /* 0x2f */
363 NdrInterfacePointerFree,
364 /* 0x30 */
366 /* 0xb1 */
367 0, 0, 0,
368 NdrUserMarshalFree,
369 0, 0,
370 /* 0xb7 */
371 NdrRangeFree
374 typedef struct _NDR_MEMORY_LIST
376 ULONG magic;
377 ULONG size;
378 ULONG reserved;
379 struct _NDR_MEMORY_LIST *next;
380 } NDR_MEMORY_LIST;
382 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
384 /***********************************************************************
385 * NdrAllocate [RPCRT4.@]
387 * Allocates a block of memory using pStubMsg->pfnAllocate.
389 * PARAMS
390 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
391 * len [I] Size of memory block to allocate.
393 * RETURNS
394 * The memory block of size len that was allocated.
396 * NOTES
397 * The memory block is always 8-byte aligned.
398 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
399 * exception is raised.
401 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, SIZE_T len)
403 SIZE_T aligned_len;
404 SIZE_T adjusted_len;
405 void *p;
406 NDR_MEMORY_LIST *mem_list;
408 aligned_len = (len + 7) & ~7;
409 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
410 /* check for overflow */
411 if (adjusted_len < len)
413 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len, len);
414 RpcRaiseException(RPC_X_BAD_STUB_DATA);
417 p = pStubMsg->pfnAllocate(adjusted_len);
418 if (!p) RpcRaiseException(ERROR_OUTOFMEMORY);
420 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
421 mem_list->magic = MEML_MAGIC;
422 mem_list->size = aligned_len;
423 mem_list->reserved = 0;
424 mem_list->next = pStubMsg->pMemoryList;
425 pStubMsg->pMemoryList = mem_list;
427 TRACE("-- %p\n", p);
428 return p;
431 static void NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
433 TRACE("(%p, %p)\n", pStubMsg, Pointer);
435 pStubMsg->pfnFree(Pointer);
438 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
440 return (*(const ULONG *)pFormat != -1);
443 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
445 align_pointer(&pStubMsg->Buffer, 4);
446 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
447 RpcRaiseException(RPC_X_BAD_STUB_DATA);
448 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
449 pStubMsg->Buffer += 4;
450 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
451 if (pStubMsg->fHasNewCorrDesc)
452 return pFormat+6;
453 else
454 return pFormat+4;
457 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
459 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
461 pStubMsg->Offset = 0;
462 pStubMsg->ActualCount = pStubMsg->MaxCount;
463 goto done;
466 align_pointer(&pStubMsg->Buffer, 4);
467 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
468 RpcRaiseException(RPC_X_BAD_STUB_DATA);
469 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
470 pStubMsg->Buffer += 4;
471 TRACE("offset is %d\n", pStubMsg->Offset);
472 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
473 pStubMsg->Buffer += 4;
474 TRACE("variance is %d\n", pStubMsg->ActualCount);
476 if ((pStubMsg->ActualCount > MaxValue) ||
477 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
479 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
480 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
481 RpcRaiseException(RPC_S_INVALID_BOUND);
482 return NULL;
485 done:
486 if (pStubMsg->fHasNewCorrDesc)
487 return pFormat+6;
488 else
489 return pFormat+4;
492 /* writes the conformance value to the buffer */
493 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
495 align_pointer_clear(&pStubMsg->Buffer, 4);
496 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
497 RpcRaiseException(RPC_X_BAD_STUB_DATA);
498 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
499 pStubMsg->Buffer += 4;
502 /* writes the variance values to the buffer */
503 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
505 align_pointer_clear(&pStubMsg->Buffer, 4);
506 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
507 RpcRaiseException(RPC_X_BAD_STUB_DATA);
508 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
509 pStubMsg->Buffer += 4;
510 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
511 pStubMsg->Buffer += 4;
514 /* requests buffer space for the conformance value */
515 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
517 align_length(&pStubMsg->BufferLength, 4);
518 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
519 RpcRaiseException(RPC_X_BAD_STUB_DATA);
520 pStubMsg->BufferLength += 4;
523 /* requests buffer space for the variance values */
524 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
526 align_length(&pStubMsg->BufferLength, 4);
527 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
528 RpcRaiseException(RPC_X_BAD_STUB_DATA);
529 pStubMsg->BufferLength += 8;
532 PFORMAT_STRING ComputeConformanceOrVariance(
533 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
534 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
536 BYTE dtype = pFormat[0] & 0xf;
537 short ofs = *(const short *)&pFormat[2];
538 LPVOID ptr = NULL;
539 ULONG_PTR data = 0;
541 if (!IsConformanceOrVariancePresent(pFormat)) {
542 /* null descriptor */
543 *pCount = def;
544 goto finish_conf;
547 switch (pFormat[0] & 0xf0) {
548 case RPC_FC_NORMAL_CONFORMANCE:
549 TRACE("normal conformance, ofs=%d\n", ofs);
550 ptr = pMemory;
551 break;
552 case RPC_FC_POINTER_CONFORMANCE:
553 TRACE("pointer conformance, ofs=%d\n", ofs);
554 ptr = pStubMsg->Memory;
555 break;
556 case RPC_FC_TOP_LEVEL_CONFORMANCE:
557 TRACE("toplevel conformance, ofs=%d\n", ofs);
558 if (pStubMsg->StackTop) {
559 ptr = pStubMsg->StackTop;
561 else {
562 /* -Os mode, *pCount is already set */
563 goto finish_conf;
565 break;
566 case RPC_FC_CONSTANT_CONFORMANCE:
567 data = ofs | ((DWORD)pFormat[1] << 16);
568 TRACE("constant conformance, val=%ld\n", data);
569 *pCount = data;
570 goto finish_conf;
571 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
572 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
573 if (pStubMsg->StackTop) {
574 ptr = pStubMsg->StackTop;
576 else {
577 /* ? */
578 goto done_conf_grab;
580 break;
581 default:
582 FIXME("unknown conformance type %x, expect crash.\n", pFormat[0] & 0xf0);
583 goto finish_conf;
586 switch (pFormat[1]) {
587 case RPC_FC_DEREFERENCE:
588 ptr = *(LPVOID*)((char *)ptr + ofs);
589 break;
590 case RPC_FC_CALLBACK:
592 unsigned char *old_stack_top = pStubMsg->StackTop;
593 ULONG_PTR max_count, old_max_count = pStubMsg->MaxCount;
595 pStubMsg->StackTop = ptr;
597 /* ofs is index into StubDesc->apfnExprEval */
598 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
599 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
601 pStubMsg->StackTop = old_stack_top;
603 /* the callback function always stores the computed value in MaxCount */
604 max_count = pStubMsg->MaxCount;
605 pStubMsg->MaxCount = old_max_count;
606 *pCount = max_count;
607 goto finish_conf;
609 default:
610 ptr = (char *)ptr + ofs;
611 break;
614 switch (dtype) {
615 case RPC_FC_LONG:
616 case RPC_FC_ULONG:
617 data = *(DWORD*)ptr;
618 break;
619 case RPC_FC_SHORT:
620 data = *(SHORT*)ptr;
621 break;
622 case RPC_FC_USHORT:
623 data = *(USHORT*)ptr;
624 break;
625 case RPC_FC_CHAR:
626 case RPC_FC_SMALL:
627 data = *(CHAR*)ptr;
628 break;
629 case RPC_FC_BYTE:
630 case RPC_FC_USMALL:
631 data = *(UCHAR*)ptr;
632 break;
633 case RPC_FC_HYPER:
634 data = *(ULONGLONG *)ptr;
635 break;
636 default:
637 FIXME("unknown conformance data type %x\n", dtype);
638 goto done_conf_grab;
640 TRACE("dereferenced data type %x at %p, got %ld\n", dtype, ptr, data);
642 done_conf_grab:
643 switch (pFormat[1]) {
644 case RPC_FC_DEREFERENCE: /* already handled */
645 case 0: /* no op */
646 *pCount = data;
647 break;
648 case RPC_FC_ADD_1:
649 *pCount = data + 1;
650 break;
651 case RPC_FC_SUB_1:
652 *pCount = data - 1;
653 break;
654 case RPC_FC_MULT_2:
655 *pCount = data * 2;
656 break;
657 case RPC_FC_DIV_2:
658 *pCount = data / 2;
659 break;
660 default:
661 FIXME("unknown conformance op %d\n", pFormat[1]);
662 goto finish_conf;
665 finish_conf:
666 TRACE("resulting conformance is %ld\n", *pCount);
667 if (pStubMsg->fHasNewCorrDesc)
668 return pFormat+6;
669 else
670 return pFormat+4;
673 static inline PFORMAT_STRING SkipConformance(PMIDL_STUB_MESSAGE pStubMsg,
674 PFORMAT_STRING pFormat)
676 if (pStubMsg->fHasNewCorrDesc)
677 pFormat += 6;
678 else
679 pFormat += 4;
680 return pFormat;
683 static inline PFORMAT_STRING SkipVariance(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
685 return SkipConformance( pStubMsg, pFormat );
688 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
689 * the result overflows 32-bits */
690 static inline ULONG safe_multiply(ULONG a, ULONG b)
692 ULONGLONG ret = (ULONGLONG)a * b;
693 if (ret > 0xffffffff)
695 RpcRaiseException(RPC_S_INVALID_BOUND);
696 return 0;
698 return ret;
701 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
703 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
704 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
705 RpcRaiseException(RPC_X_BAD_STUB_DATA);
706 pStubMsg->Buffer += size;
709 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
711 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
713 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
714 pStubMsg->BufferLength, size);
715 RpcRaiseException(RPC_X_BAD_STUB_DATA);
717 pStubMsg->BufferLength += size;
720 /* copies data from the buffer, checking that there is enough data in the buffer
721 * to do so */
722 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
724 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
725 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
727 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
728 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
729 RpcRaiseException(RPC_X_BAD_STUB_DATA);
731 if (p == pStubMsg->Buffer)
732 ERR("pointer is the same as the buffer\n");
733 memcpy(p, pStubMsg->Buffer, size);
734 pStubMsg->Buffer += size;
737 /* copies data to the buffer, checking that there is enough space to do so */
738 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
740 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
741 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
743 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
744 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
745 size);
746 RpcRaiseException(RPC_X_BAD_STUB_DATA);
748 memcpy(pStubMsg->Buffer, p, size);
749 pStubMsg->Buffer += size;
752 /* verify that string data sitting in the buffer is valid and safe to
753 * unmarshall */
754 static void validate_string_data(MIDL_STUB_MESSAGE *pStubMsg, ULONG bufsize, ULONG esize)
756 ULONG i;
758 /* verify the buffer is safe to access */
759 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
760 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
762 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
763 pStubMsg->BufferEnd, pStubMsg->Buffer);
764 RpcRaiseException(RPC_X_BAD_STUB_DATA);
767 /* strings must always have null terminating bytes */
768 if (bufsize < esize)
770 ERR("invalid string length of %d\n", bufsize / esize);
771 RpcRaiseException(RPC_S_INVALID_BOUND);
774 for (i = bufsize - esize; i < bufsize; i++)
775 if (pStubMsg->Buffer[i] != 0)
777 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
778 i, pStubMsg->Buffer[i]);
779 RpcRaiseException(RPC_S_INVALID_BOUND);
783 static inline void dump_pointer_attr(unsigned char attr)
785 if (attr & RPC_FC_P_ALLOCALLNODES)
786 TRACE(" RPC_FC_P_ALLOCALLNODES");
787 if (attr & RPC_FC_P_DONTFREE)
788 TRACE(" RPC_FC_P_DONTFREE");
789 if (attr & RPC_FC_P_ONSTACK)
790 TRACE(" RPC_FC_P_ONSTACK");
791 if (attr & RPC_FC_P_SIMPLEPOINTER)
792 TRACE(" RPC_FC_P_SIMPLEPOINTER");
793 if (attr & RPC_FC_P_DEREF)
794 TRACE(" RPC_FC_P_DEREF");
795 TRACE("\n");
798 /***********************************************************************
799 * PointerMarshall [internal]
801 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
802 unsigned char *Buffer,
803 unsigned char *Pointer,
804 PFORMAT_STRING pFormat)
806 unsigned type = pFormat[0], attr = pFormat[1];
807 PFORMAT_STRING desc;
808 NDR_MARSHALL m;
809 ULONG pointer_id;
810 BOOL pointer_needs_marshaling;
812 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
813 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
814 pFormat += 2;
815 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
816 else desc = pFormat + *(const SHORT*)pFormat;
818 switch (type) {
819 case RPC_FC_RP: /* ref pointer (always non-null) */
820 if (!Pointer)
822 ERR("NULL ref pointer is not allowed\n");
823 RpcRaiseException(RPC_X_NULL_REF_POINTER);
825 pointer_needs_marshaling = TRUE;
826 break;
827 case RPC_FC_UP: /* unique pointer */
828 case RPC_FC_OP: /* object pointer - same as unique here */
829 if (Pointer)
830 pointer_needs_marshaling = TRUE;
831 else
832 pointer_needs_marshaling = FALSE;
833 pointer_id = Pointer ? NDR_POINTER_ID(pStubMsg) : 0;
834 TRACE("writing 0x%08x to buffer\n", pointer_id);
835 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
836 break;
837 case RPC_FC_FP:
838 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
839 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
840 TRACE("writing 0x%08x to buffer\n", pointer_id);
841 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
842 break;
843 default:
844 FIXME("unhandled ptr type=%02x\n", type);
845 RpcRaiseException(RPC_X_BAD_STUB_DATA);
846 return;
849 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
851 if (pointer_needs_marshaling) {
852 if (attr & RPC_FC_P_DEREF) {
853 Pointer = *(unsigned char**)Pointer;
854 TRACE("deref => %p\n", Pointer);
856 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
857 if (m) m(pStubMsg, Pointer, desc);
858 else FIXME("no marshaller for data type=%02x\n", *desc);
861 STD_OVERFLOW_CHECK(pStubMsg);
864 /***********************************************************************
865 * PointerUnmarshall [internal]
867 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
868 unsigned char *Buffer,
869 unsigned char **pPointer,
870 unsigned char *pSrcPointer,
871 PFORMAT_STRING pFormat,
872 unsigned char fMustAlloc)
874 unsigned type = pFormat[0], attr = pFormat[1];
875 PFORMAT_STRING desc;
876 NDR_UNMARSHALL m;
877 DWORD pointer_id = 0;
878 BOOL pointer_needs_unmarshaling;
880 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
881 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
882 pFormat += 2;
883 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
884 else desc = pFormat + *(const SHORT*)pFormat;
886 switch (type) {
887 case RPC_FC_RP: /* ref pointer (always non-null) */
888 pointer_needs_unmarshaling = TRUE;
889 break;
890 case RPC_FC_UP: /* unique pointer */
891 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
892 TRACE("pointer_id is 0x%08x\n", pointer_id);
893 if (pointer_id)
894 pointer_needs_unmarshaling = TRUE;
895 else {
896 *pPointer = NULL;
897 pointer_needs_unmarshaling = FALSE;
899 break;
900 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
901 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
902 TRACE("pointer_id is 0x%08x\n", pointer_id);
903 if (!fMustAlloc && pSrcPointer)
905 FIXME("free object pointer %p\n", pSrcPointer);
906 fMustAlloc = TRUE;
908 if (pointer_id)
909 pointer_needs_unmarshaling = TRUE;
910 else
912 *pPointer = NULL;
913 pointer_needs_unmarshaling = FALSE;
915 break;
916 case RPC_FC_FP:
917 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
918 TRACE("pointer_id is 0x%08x\n", pointer_id);
919 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
920 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
921 break;
922 default:
923 FIXME("unhandled ptr type=%02x\n", type);
924 RpcRaiseException(RPC_X_BAD_STUB_DATA);
925 return;
928 if (pointer_needs_unmarshaling) {
929 unsigned char **current_ptr = pPointer;
930 if (pStubMsg->IsClient) {
931 TRACE("client\n");
932 /* if we aren't forcing allocation of memory then try to use the existing
933 * (source) pointer to unmarshall the data into so that [in,out]
934 * parameters behave correctly. it doesn't matter if the parameter is
935 * [out] only since in that case the pointer will be NULL. we force
936 * allocation when the source pointer is NULL here instead of in the type
937 * unmarshalling routine for the benefit of the deref code below */
938 if (!fMustAlloc) {
939 if (pSrcPointer) {
940 TRACE("setting *pPointer to %p\n", pSrcPointer);
941 *pPointer = pSrcPointer;
942 } else
943 fMustAlloc = TRUE;
945 } else {
946 TRACE("server\n");
947 /* the memory in a stub is never initialised, so we have to work out here
948 * whether we have to initialise it so we can use the optimisation of
949 * setting the pointer to the buffer, if possible, or set fMustAlloc to
950 * TRUE. */
951 if (attr & RPC_FC_P_DEREF) {
952 fMustAlloc = TRUE;
953 } else {
954 *current_ptr = NULL;
958 if (attr & RPC_FC_P_ALLOCALLNODES)
959 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
961 if (attr & RPC_FC_P_DEREF) {
962 if (fMustAlloc) {
963 unsigned char *base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
964 *pPointer = base_ptr_val;
965 current_ptr = (unsigned char **)base_ptr_val;
966 } else
967 current_ptr = *(unsigned char***)current_ptr;
968 TRACE("deref => %p\n", current_ptr);
969 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
971 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
972 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
973 else FIXME("no unmarshaller for data type=%02x\n", *desc);
975 if (type == RPC_FC_FP)
976 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
977 *pPointer);
980 TRACE("pointer=%p\n", *pPointer);
983 /***********************************************************************
984 * PointerBufferSize [internal]
986 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
987 unsigned char *Pointer,
988 PFORMAT_STRING pFormat)
990 unsigned type = pFormat[0], attr = pFormat[1];
991 PFORMAT_STRING desc;
992 NDR_BUFFERSIZE m;
993 BOOL pointer_needs_sizing;
994 ULONG pointer_id;
996 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
997 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
998 pFormat += 2;
999 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1000 else desc = pFormat + *(const SHORT*)pFormat;
1002 switch (type) {
1003 case RPC_FC_RP: /* ref pointer (always non-null) */
1004 if (!Pointer)
1006 ERR("NULL ref pointer is not allowed\n");
1007 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1009 break;
1010 case RPC_FC_OP:
1011 case RPC_FC_UP:
1012 /* NULL pointer has no further representation */
1013 if (!Pointer)
1014 return;
1015 break;
1016 case RPC_FC_FP:
1017 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1018 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1019 if (!pointer_needs_sizing)
1020 return;
1021 break;
1022 default:
1023 FIXME("unhandled ptr type=%02x\n", type);
1024 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1025 return;
1028 if (attr & RPC_FC_P_DEREF) {
1029 Pointer = *(unsigned char**)Pointer;
1030 TRACE("deref => %p\n", Pointer);
1033 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1034 if (m) m(pStubMsg, Pointer, desc);
1035 else FIXME("no buffersizer for data type=%02x\n", *desc);
1038 /***********************************************************************
1039 * PointerMemorySize [internal]
1041 static ULONG PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1042 unsigned char *Buffer, PFORMAT_STRING pFormat)
1044 unsigned type = pFormat[0], attr = pFormat[1];
1045 PFORMAT_STRING desc;
1046 NDR_MEMORYSIZE m;
1047 DWORD pointer_id = 0;
1048 BOOL pointer_needs_sizing;
1050 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1051 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1052 pFormat += 2;
1053 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1054 else desc = pFormat + *(const SHORT*)pFormat;
1056 switch (type) {
1057 case RPC_FC_RP: /* ref pointer (always non-null) */
1058 pointer_needs_sizing = TRUE;
1059 break;
1060 case RPC_FC_UP: /* unique pointer */
1061 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1062 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1063 TRACE("pointer_id is 0x%08x\n", pointer_id);
1064 if (pointer_id)
1065 pointer_needs_sizing = TRUE;
1066 else
1067 pointer_needs_sizing = FALSE;
1068 break;
1069 case RPC_FC_FP:
1071 void *pointer;
1072 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1073 TRACE("pointer_id is 0x%08x\n", pointer_id);
1074 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1075 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1076 break;
1078 default:
1079 FIXME("unhandled ptr type=%02x\n", type);
1080 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1081 return 0;
1084 if (attr & RPC_FC_P_DEREF) {
1085 align_length(&pStubMsg->MemorySize, sizeof(void*));
1086 pStubMsg->MemorySize += sizeof(void*);
1087 TRACE("deref\n");
1090 if (pointer_needs_sizing) {
1091 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1092 if (m) m(pStubMsg, desc);
1093 else FIXME("no memorysizer for data type=%02x\n", *desc);
1096 return pStubMsg->MemorySize;
1099 /***********************************************************************
1100 * PointerFree [internal]
1102 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1103 unsigned char *Pointer,
1104 PFORMAT_STRING pFormat)
1106 unsigned type = pFormat[0], attr = pFormat[1];
1107 PFORMAT_STRING desc;
1108 NDR_FREE m;
1109 unsigned char *current_pointer = Pointer;
1111 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1112 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1113 if (attr & RPC_FC_P_DONTFREE) return;
1114 pFormat += 2;
1115 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1116 else desc = pFormat + *(const SHORT*)pFormat;
1118 if (!Pointer) return;
1120 if (type == RPC_FC_FP) {
1121 int pointer_needs_freeing = NdrFullPointerFree(
1122 pStubMsg->FullPtrXlatTables, Pointer);
1123 if (!pointer_needs_freeing)
1124 return;
1127 if (attr & RPC_FC_P_DEREF) {
1128 current_pointer = *(unsigned char**)Pointer;
1129 TRACE("deref => %p\n", current_pointer);
1132 m = NdrFreer[*desc & NDR_TABLE_MASK];
1133 if (m) m(pStubMsg, current_pointer, desc);
1135 /* this check stops us from trying to free buffer memory. we don't have to
1136 * worry about clients, since they won't call this function.
1137 * we don't have to check for the buffer being reallocated because
1138 * BufferStart and BufferEnd won't be reset when allocating memory for
1139 * sending the response. we don't have to check for the new buffer here as
1140 * it won't be used a type memory, only for buffer memory */
1141 if (Pointer >= pStubMsg->BufferStart && Pointer <= pStubMsg->BufferEnd)
1142 goto notfree;
1144 if (attr & RPC_FC_P_ONSTACK) {
1145 TRACE("not freeing stack ptr %p\n", Pointer);
1146 return;
1148 TRACE("freeing %p\n", Pointer);
1149 NdrFree(pStubMsg, Pointer);
1150 return;
1151 notfree:
1152 TRACE("not freeing %p\n", Pointer);
1155 /***********************************************************************
1156 * EmbeddedPointerMarshall
1158 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1159 unsigned char *pMemory,
1160 PFORMAT_STRING pFormat)
1162 unsigned char *Mark = pStubMsg->BufferMark;
1163 unsigned rep, count, stride;
1164 unsigned i;
1165 unsigned char *saved_buffer = NULL;
1167 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1169 if (*pFormat != RPC_FC_PP) return NULL;
1170 pFormat += 2;
1172 if (pStubMsg->PointerBufferMark)
1174 saved_buffer = pStubMsg->Buffer;
1175 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1176 pStubMsg->PointerBufferMark = NULL;
1179 while (pFormat[0] != RPC_FC_END) {
1180 switch (pFormat[0]) {
1181 default:
1182 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1183 /* fallthrough */
1184 case RPC_FC_NO_REPEAT:
1185 rep = 1;
1186 stride = 0;
1187 count = 1;
1188 pFormat += 2;
1189 break;
1190 case RPC_FC_FIXED_REPEAT:
1191 rep = *(const WORD*)&pFormat[2];
1192 stride = *(const WORD*)&pFormat[4];
1193 count = *(const WORD*)&pFormat[8];
1194 pFormat += 10;
1195 break;
1196 case RPC_FC_VARIABLE_REPEAT:
1197 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1198 stride = *(const WORD*)&pFormat[2];
1199 count = *(const WORD*)&pFormat[6];
1200 pFormat += 8;
1201 break;
1203 for (i = 0; i < rep; i++) {
1204 PFORMAT_STRING info = pFormat;
1205 unsigned char *membase = pMemory + (i * stride);
1206 unsigned char *bufbase = Mark + (i * stride);
1207 unsigned u;
1209 for (u=0; u<count; u++,info+=8) {
1210 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1211 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1212 unsigned char *saved_memory = pStubMsg->Memory;
1214 pStubMsg->Memory = membase;
1215 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1216 pStubMsg->Memory = saved_memory;
1219 pFormat += 8 * count;
1222 if (saved_buffer)
1224 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1225 pStubMsg->Buffer = saved_buffer;
1228 STD_OVERFLOW_CHECK(pStubMsg);
1230 return NULL;
1233 /***********************************************************************
1234 * EmbeddedPointerUnmarshall
1236 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1237 unsigned char *pDstBuffer,
1238 unsigned char *pSrcMemoryPtrs,
1239 PFORMAT_STRING pFormat,
1240 unsigned char fMustAlloc)
1242 unsigned char *Mark = pStubMsg->BufferMark;
1243 unsigned rep, count, stride;
1244 unsigned i;
1245 unsigned char *saved_buffer = NULL;
1247 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc);
1249 if (*pFormat != RPC_FC_PP) return NULL;
1250 pFormat += 2;
1252 if (pStubMsg->PointerBufferMark)
1254 saved_buffer = pStubMsg->Buffer;
1255 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1256 pStubMsg->PointerBufferMark = NULL;
1259 while (pFormat[0] != RPC_FC_END) {
1260 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1261 switch (pFormat[0]) {
1262 default:
1263 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1264 /* fallthrough */
1265 case RPC_FC_NO_REPEAT:
1266 rep = 1;
1267 stride = 0;
1268 count = 1;
1269 pFormat += 2;
1270 break;
1271 case RPC_FC_FIXED_REPEAT:
1272 rep = *(const WORD*)&pFormat[2];
1273 stride = *(const WORD*)&pFormat[4];
1274 count = *(const WORD*)&pFormat[8];
1275 pFormat += 10;
1276 break;
1277 case RPC_FC_VARIABLE_REPEAT:
1278 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1279 stride = *(const WORD*)&pFormat[2];
1280 count = *(const WORD*)&pFormat[6];
1281 pFormat += 8;
1282 break;
1284 for (i = 0; i < rep; i++) {
1285 PFORMAT_STRING info = pFormat;
1286 unsigned char *bufdstbase = pDstBuffer + (i * stride);
1287 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1288 unsigned char *bufbase = Mark + (i * stride);
1289 unsigned u;
1291 for (u=0; u<count; u++,info+=8) {
1292 unsigned char **bufdstptr = (unsigned char **)(bufdstbase + *(const SHORT*)&info[2]);
1293 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1294 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1295 PointerUnmarshall(pStubMsg, bufptr, bufdstptr, *memsrcptr, info+4, fMustAlloc);
1298 pFormat += 8 * count;
1301 if (saved_buffer)
1303 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1304 pStubMsg->Buffer = saved_buffer;
1307 return NULL;
1310 /***********************************************************************
1311 * EmbeddedPointerBufferSize
1313 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1314 unsigned char *pMemory,
1315 PFORMAT_STRING pFormat)
1317 unsigned rep, count, stride;
1318 unsigned i;
1319 ULONG saved_buffer_length = 0;
1321 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1323 if (pStubMsg->IgnoreEmbeddedPointers) return;
1325 if (*pFormat != RPC_FC_PP) return;
1326 pFormat += 2;
1328 if (pStubMsg->PointerLength)
1330 saved_buffer_length = pStubMsg->BufferLength;
1331 pStubMsg->BufferLength = pStubMsg->PointerLength;
1332 pStubMsg->PointerLength = 0;
1335 while (pFormat[0] != RPC_FC_END) {
1336 switch (pFormat[0]) {
1337 default:
1338 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1339 /* fallthrough */
1340 case RPC_FC_NO_REPEAT:
1341 rep = 1;
1342 stride = 0;
1343 count = 1;
1344 pFormat += 2;
1345 break;
1346 case RPC_FC_FIXED_REPEAT:
1347 rep = *(const WORD*)&pFormat[2];
1348 stride = *(const WORD*)&pFormat[4];
1349 count = *(const WORD*)&pFormat[8];
1350 pFormat += 10;
1351 break;
1352 case RPC_FC_VARIABLE_REPEAT:
1353 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1354 stride = *(const WORD*)&pFormat[2];
1355 count = *(const WORD*)&pFormat[6];
1356 pFormat += 8;
1357 break;
1359 for (i = 0; i < rep; i++) {
1360 PFORMAT_STRING info = pFormat;
1361 unsigned char *membase = pMemory + (i * stride);
1362 unsigned u;
1364 for (u=0; u<count; u++,info+=8) {
1365 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1366 unsigned char *saved_memory = pStubMsg->Memory;
1368 pStubMsg->Memory = membase;
1369 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1370 pStubMsg->Memory = saved_memory;
1373 pFormat += 8 * count;
1376 if (saved_buffer_length)
1378 pStubMsg->PointerLength = pStubMsg->BufferLength;
1379 pStubMsg->BufferLength = saved_buffer_length;
1383 /***********************************************************************
1384 * EmbeddedPointerMemorySize [internal]
1386 static ULONG EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1387 PFORMAT_STRING pFormat)
1389 unsigned char *Mark = pStubMsg->BufferMark;
1390 unsigned rep, count, stride;
1391 unsigned i;
1392 unsigned char *saved_buffer = NULL;
1394 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1396 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1398 if (pStubMsg->PointerBufferMark)
1400 saved_buffer = pStubMsg->Buffer;
1401 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1402 pStubMsg->PointerBufferMark = NULL;
1405 if (*pFormat != RPC_FC_PP) return 0;
1406 pFormat += 2;
1408 while (pFormat[0] != RPC_FC_END) {
1409 switch (pFormat[0]) {
1410 default:
1411 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1412 /* fallthrough */
1413 case RPC_FC_NO_REPEAT:
1414 rep = 1;
1415 stride = 0;
1416 count = 1;
1417 pFormat += 2;
1418 break;
1419 case RPC_FC_FIXED_REPEAT:
1420 rep = *(const WORD*)&pFormat[2];
1421 stride = *(const WORD*)&pFormat[4];
1422 count = *(const WORD*)&pFormat[8];
1423 pFormat += 10;
1424 break;
1425 case RPC_FC_VARIABLE_REPEAT:
1426 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1427 stride = *(const WORD*)&pFormat[2];
1428 count = *(const WORD*)&pFormat[6];
1429 pFormat += 8;
1430 break;
1432 for (i = 0; i < rep; i++) {
1433 PFORMAT_STRING info = pFormat;
1434 unsigned char *bufbase = Mark + (i * stride);
1435 unsigned u;
1436 for (u=0; u<count; u++,info+=8) {
1437 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1438 PointerMemorySize(pStubMsg, bufptr, info+4);
1441 pFormat += 8 * count;
1444 if (saved_buffer)
1446 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1447 pStubMsg->Buffer = saved_buffer;
1450 return 0;
1453 /***********************************************************************
1454 * EmbeddedPointerFree [internal]
1456 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1457 unsigned char *pMemory,
1458 PFORMAT_STRING pFormat)
1460 unsigned rep, count, stride;
1461 unsigned i;
1463 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1464 if (*pFormat != RPC_FC_PP) return;
1465 pFormat += 2;
1467 while (pFormat[0] != RPC_FC_END) {
1468 switch (pFormat[0]) {
1469 default:
1470 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1471 /* fallthrough */
1472 case RPC_FC_NO_REPEAT:
1473 rep = 1;
1474 stride = 0;
1475 count = 1;
1476 pFormat += 2;
1477 break;
1478 case RPC_FC_FIXED_REPEAT:
1479 rep = *(const WORD*)&pFormat[2];
1480 stride = *(const WORD*)&pFormat[4];
1481 count = *(const WORD*)&pFormat[8];
1482 pFormat += 10;
1483 break;
1484 case RPC_FC_VARIABLE_REPEAT:
1485 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1486 stride = *(const WORD*)&pFormat[2];
1487 count = *(const WORD*)&pFormat[6];
1488 pFormat += 8;
1489 break;
1491 for (i = 0; i < rep; i++) {
1492 PFORMAT_STRING info = pFormat;
1493 unsigned char *membase = pMemory + (i * stride);
1494 unsigned u;
1496 for (u=0; u<count; u++,info+=8) {
1497 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1498 unsigned char *saved_memory = pStubMsg->Memory;
1500 pStubMsg->Memory = membase;
1501 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1502 pStubMsg->Memory = saved_memory;
1505 pFormat += 8 * count;
1509 /***********************************************************************
1510 * NdrPointerMarshall [RPCRT4.@]
1512 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1513 unsigned char *pMemory,
1514 PFORMAT_STRING pFormat)
1516 unsigned char *Buffer;
1518 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1520 /* Increment the buffer here instead of in PointerMarshall,
1521 * as that is used by embedded pointers which already handle the incrementing
1522 * the buffer, and shouldn't write any additional pointer data to the wire */
1523 if (*pFormat != RPC_FC_RP)
1525 align_pointer_clear(&pStubMsg->Buffer, 4);
1526 Buffer = pStubMsg->Buffer;
1527 safe_buffer_increment(pStubMsg, 4);
1529 else
1530 Buffer = pStubMsg->Buffer;
1532 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1534 return NULL;
1537 /***********************************************************************
1538 * NdrPointerUnmarshall [RPCRT4.@]
1540 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1541 unsigned char **ppMemory,
1542 PFORMAT_STRING pFormat,
1543 unsigned char fMustAlloc)
1545 unsigned char *Buffer;
1547 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1549 if (*pFormat == RPC_FC_RP)
1551 Buffer = pStubMsg->Buffer;
1552 /* Do the NULL ref pointer check here because embedded pointers can be
1553 * NULL if the type the pointer is embedded in was allocated rather than
1554 * being passed in by the client */
1555 if (pStubMsg->IsClient && !*ppMemory)
1557 ERR("NULL ref pointer is not allowed\n");
1558 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1561 else
1563 /* Increment the buffer here instead of in PointerUnmarshall,
1564 * as that is used by embedded pointers which already handle the incrementing
1565 * the buffer, and shouldn't read any additional pointer data from the
1566 * buffer */
1567 align_pointer(&pStubMsg->Buffer, 4);
1568 Buffer = pStubMsg->Buffer;
1569 safe_buffer_increment(pStubMsg, 4);
1572 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1574 return NULL;
1577 /***********************************************************************
1578 * NdrPointerBufferSize [RPCRT4.@]
1580 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1581 unsigned char *pMemory,
1582 PFORMAT_STRING pFormat)
1584 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1586 /* Increment the buffer length here instead of in PointerBufferSize,
1587 * as that is used by embedded pointers which already handle the buffer
1588 * length, and shouldn't write anything more to the wire */
1589 if (*pFormat != RPC_FC_RP)
1591 align_length(&pStubMsg->BufferLength, 4);
1592 safe_buffer_length_increment(pStubMsg, 4);
1595 PointerBufferSize(pStubMsg, pMemory, pFormat);
1598 /***********************************************************************
1599 * NdrPointerMemorySize [RPCRT4.@]
1601 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1602 PFORMAT_STRING pFormat)
1604 unsigned char *Buffer = pStubMsg->Buffer;
1605 if (*pFormat != RPC_FC_RP)
1607 align_pointer(&pStubMsg->Buffer, 4);
1608 safe_buffer_increment(pStubMsg, 4);
1610 align_length(&pStubMsg->MemorySize, sizeof(void *));
1611 return PointerMemorySize(pStubMsg, Buffer, pFormat);
1614 /***********************************************************************
1615 * NdrPointerFree [RPCRT4.@]
1617 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1618 unsigned char *pMemory,
1619 PFORMAT_STRING pFormat)
1621 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1622 PointerFree(pStubMsg, pMemory, pFormat);
1625 /***********************************************************************
1626 * NdrSimpleTypeMarshall [RPCRT4.@]
1628 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1629 unsigned char FormatChar )
1631 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1634 /***********************************************************************
1635 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1637 * Unmarshall a base type.
1639 * NOTES
1640 * Doesn't check that the buffer is long enough before copying, so the caller
1641 * should do this.
1643 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1644 unsigned char FormatChar )
1646 #define BASE_TYPE_UNMARSHALL(type) \
1647 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
1648 TRACE("pMemory: %p\n", pMemory); \
1649 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1650 pStubMsg->Buffer += sizeof(type);
1652 switch(FormatChar)
1654 case RPC_FC_BYTE:
1655 case RPC_FC_CHAR:
1656 case RPC_FC_SMALL:
1657 case RPC_FC_USMALL:
1658 BASE_TYPE_UNMARSHALL(UCHAR);
1659 TRACE("value: 0x%02x\n", *pMemory);
1660 break;
1661 case RPC_FC_WCHAR:
1662 case RPC_FC_SHORT:
1663 case RPC_FC_USHORT:
1664 BASE_TYPE_UNMARSHALL(USHORT);
1665 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
1666 break;
1667 case RPC_FC_LONG:
1668 case RPC_FC_ULONG:
1669 case RPC_FC_ERROR_STATUS_T:
1670 case RPC_FC_ENUM32:
1671 BASE_TYPE_UNMARSHALL(ULONG);
1672 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
1673 break;
1674 case RPC_FC_FLOAT:
1675 BASE_TYPE_UNMARSHALL(float);
1676 TRACE("value: %f\n", *(float *)pMemory);
1677 break;
1678 case RPC_FC_DOUBLE:
1679 BASE_TYPE_UNMARSHALL(double);
1680 TRACE("value: %f\n", *(double *)pMemory);
1681 break;
1682 case RPC_FC_HYPER:
1683 BASE_TYPE_UNMARSHALL(ULONGLONG);
1684 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
1685 break;
1686 case RPC_FC_ENUM16:
1687 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
1688 TRACE("pMemory: %p\n", pMemory);
1689 /* 16-bits on the wire, but int in memory */
1690 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
1691 pStubMsg->Buffer += sizeof(USHORT);
1692 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
1693 break;
1694 case RPC_FC_INT3264:
1695 align_pointer(&pStubMsg->Buffer, sizeof(INT));
1696 /* 32-bits on the wire, but int_ptr in memory */
1697 *(INT_PTR *)pMemory = *(INT *)pStubMsg->Buffer;
1698 pStubMsg->Buffer += sizeof(INT);
1699 TRACE("value: 0x%08lx\n", *(INT_PTR *)pMemory);
1700 break;
1701 case RPC_FC_UINT3264:
1702 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
1703 /* 32-bits on the wire, but int_ptr in memory */
1704 *(UINT_PTR *)pMemory = *(UINT *)pStubMsg->Buffer;
1705 pStubMsg->Buffer += sizeof(UINT);
1706 TRACE("value: 0x%08lx\n", *(UINT_PTR *)pMemory);
1707 break;
1708 case RPC_FC_IGNORE:
1709 break;
1710 default:
1711 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
1713 #undef BASE_TYPE_UNMARSHALL
1716 /***********************************************************************
1717 * NdrSimpleStructMarshall [RPCRT4.@]
1719 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1720 unsigned char *pMemory,
1721 PFORMAT_STRING pFormat)
1723 unsigned size = *(const WORD*)(pFormat+2);
1724 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1726 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1);
1728 pStubMsg->BufferMark = pStubMsg->Buffer;
1729 safe_copy_to_buffer(pStubMsg, pMemory, size);
1731 if (pFormat[0] != RPC_FC_STRUCT)
1732 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1734 return NULL;
1737 /***********************************************************************
1738 * NdrSimpleStructUnmarshall [RPCRT4.@]
1740 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1741 unsigned char **ppMemory,
1742 PFORMAT_STRING pFormat,
1743 unsigned char fMustAlloc)
1745 unsigned size = *(const WORD*)(pFormat+2);
1746 unsigned char *saved_buffer;
1747 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1749 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
1751 if (fMustAlloc)
1752 *ppMemory = NdrAllocate(pStubMsg, size);
1753 else
1755 if (!pStubMsg->IsClient && !*ppMemory)
1756 /* for servers, we just point straight into the RPC buffer */
1757 *ppMemory = pStubMsg->Buffer;
1760 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1761 safe_buffer_increment(pStubMsg, size);
1762 if (pFormat[0] == RPC_FC_PSTRUCT)
1763 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1765 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1766 if (*ppMemory != saved_buffer)
1767 memcpy(*ppMemory, saved_buffer, size);
1769 return NULL;
1772 /***********************************************************************
1773 * NdrSimpleStructBufferSize [RPCRT4.@]
1775 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1776 unsigned char *pMemory,
1777 PFORMAT_STRING pFormat)
1779 unsigned size = *(const WORD*)(pFormat+2);
1780 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1782 align_length(&pStubMsg->BufferLength, pFormat[1] + 1);
1784 safe_buffer_length_increment(pStubMsg, size);
1785 if (pFormat[0] != RPC_FC_STRUCT)
1786 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1789 /***********************************************************************
1790 * NdrSimpleStructMemorySize [RPCRT4.@]
1792 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1793 PFORMAT_STRING pFormat)
1795 unsigned short size = *(const WORD *)(pFormat+2);
1797 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1799 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
1800 pStubMsg->MemorySize += size;
1801 safe_buffer_increment(pStubMsg, size);
1803 if (pFormat[0] != RPC_FC_STRUCT)
1804 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1805 return pStubMsg->MemorySize;
1808 /***********************************************************************
1809 * NdrSimpleStructFree [RPCRT4.@]
1811 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1812 unsigned char *pMemory,
1813 PFORMAT_STRING pFormat)
1815 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1816 if (pFormat[0] != RPC_FC_STRUCT)
1817 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1820 /* Array helpers */
1822 static inline void array_compute_and_size_conformance(
1823 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1824 PFORMAT_STRING pFormat)
1826 DWORD count;
1828 switch (fc)
1830 case RPC_FC_CARRAY:
1831 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1832 SizeConformance(pStubMsg);
1833 break;
1834 case RPC_FC_CVARRAY:
1835 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1836 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1837 SizeConformance(pStubMsg);
1838 break;
1839 case RPC_FC_C_CSTRING:
1840 case RPC_FC_C_WSTRING:
1841 if (fc == RPC_FC_C_CSTRING)
1843 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1844 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1846 else
1848 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1849 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1852 if (pFormat[1] == RPC_FC_STRING_SIZED)
1853 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1854 else
1855 pStubMsg->MaxCount = pStubMsg->ActualCount;
1857 SizeConformance(pStubMsg);
1858 break;
1859 case RPC_FC_BOGUS_ARRAY:
1860 count = *(const WORD *)(pFormat + 2);
1861 pFormat += 4;
1862 if (IsConformanceOrVariancePresent(pFormat)) SizeConformance(pStubMsg);
1863 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, count);
1864 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
1865 break;
1866 default:
1867 ERR("unknown array format 0x%x\n", fc);
1868 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1872 static inline void array_buffer_size(
1873 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1874 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1876 DWORD i, size;
1877 DWORD esize;
1878 unsigned char alignment;
1880 switch (fc)
1882 case RPC_FC_CARRAY:
1883 esize = *(const WORD*)(pFormat+2);
1884 alignment = pFormat[1] + 1;
1886 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1888 align_length(&pStubMsg->BufferLength, alignment);
1890 size = safe_multiply(esize, pStubMsg->MaxCount);
1891 /* conformance value plus array */
1892 safe_buffer_length_increment(pStubMsg, size);
1894 if (fHasPointers)
1895 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1896 break;
1897 case RPC_FC_CVARRAY:
1898 esize = *(const WORD*)(pFormat+2);
1899 alignment = pFormat[1] + 1;
1901 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1902 pFormat = SkipVariance(pStubMsg, pFormat);
1904 SizeVariance(pStubMsg);
1906 align_length(&pStubMsg->BufferLength, alignment);
1908 size = safe_multiply(esize, pStubMsg->ActualCount);
1909 safe_buffer_length_increment(pStubMsg, size);
1911 if (fHasPointers)
1912 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1913 break;
1914 case RPC_FC_C_CSTRING:
1915 case RPC_FC_C_WSTRING:
1916 if (fc == RPC_FC_C_CSTRING)
1917 esize = 1;
1918 else
1919 esize = 2;
1921 SizeVariance(pStubMsg);
1923 size = safe_multiply(esize, pStubMsg->ActualCount);
1924 safe_buffer_length_increment(pStubMsg, size);
1925 break;
1926 case RPC_FC_BOGUS_ARRAY:
1927 alignment = pFormat[1] + 1;
1928 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1929 if (IsConformanceOrVariancePresent(pFormat)) SizeVariance(pStubMsg);
1930 pFormat = SkipVariance(pStubMsg, pFormat);
1932 align_length(&pStubMsg->BufferLength, alignment);
1934 size = pStubMsg->ActualCount;
1935 for (i = 0; i < size; i++)
1936 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
1937 break;
1938 default:
1939 ERR("unknown array format 0x%x\n", fc);
1940 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1944 static inline void array_compute_and_write_conformance(
1945 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1946 PFORMAT_STRING pFormat)
1948 ULONG def;
1949 BOOL conformance_present;
1951 switch (fc)
1953 case RPC_FC_CARRAY:
1954 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1955 WriteConformance(pStubMsg);
1956 break;
1957 case RPC_FC_CVARRAY:
1958 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1959 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1960 WriteConformance(pStubMsg);
1961 break;
1962 case RPC_FC_C_CSTRING:
1963 case RPC_FC_C_WSTRING:
1964 if (fc == RPC_FC_C_CSTRING)
1966 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1967 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1969 else
1971 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1972 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1974 if (pFormat[1] == RPC_FC_STRING_SIZED)
1975 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1976 else
1977 pStubMsg->MaxCount = pStubMsg->ActualCount;
1978 pStubMsg->Offset = 0;
1979 WriteConformance(pStubMsg);
1980 break;
1981 case RPC_FC_BOGUS_ARRAY:
1982 def = *(const WORD *)(pFormat + 2);
1983 pFormat += 4;
1984 conformance_present = IsConformanceOrVariancePresent(pFormat);
1985 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
1986 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
1987 if (conformance_present) WriteConformance(pStubMsg);
1988 break;
1989 default:
1990 ERR("unknown array format 0x%x\n", fc);
1991 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1995 static inline void array_write_variance_and_marshall(
1996 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1997 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1999 DWORD i, size;
2000 DWORD esize;
2001 unsigned char alignment;
2003 switch (fc)
2005 case RPC_FC_CARRAY:
2006 esize = *(const WORD*)(pFormat+2);
2007 alignment = pFormat[1] + 1;
2009 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2011 align_pointer_clear(&pStubMsg->Buffer, alignment);
2013 size = safe_multiply(esize, pStubMsg->MaxCount);
2014 if (fHasPointers)
2015 pStubMsg->BufferMark = pStubMsg->Buffer;
2016 safe_copy_to_buffer(pStubMsg, pMemory, size);
2018 if (fHasPointers)
2019 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2020 break;
2021 case RPC_FC_CVARRAY:
2022 esize = *(const WORD*)(pFormat+2);
2023 alignment = pFormat[1] + 1;
2025 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2026 pFormat = SkipVariance(pStubMsg, pFormat);
2028 WriteVariance(pStubMsg);
2030 align_pointer_clear(&pStubMsg->Buffer, alignment);
2032 size = safe_multiply(esize, pStubMsg->ActualCount);
2034 if (fHasPointers)
2035 pStubMsg->BufferMark = pStubMsg->Buffer;
2036 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size);
2038 if (fHasPointers)
2039 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2040 break;
2041 case RPC_FC_C_CSTRING:
2042 case RPC_FC_C_WSTRING:
2043 if (fc == RPC_FC_C_CSTRING)
2044 esize = 1;
2045 else
2046 esize = 2;
2048 WriteVariance(pStubMsg);
2050 size = safe_multiply(esize, pStubMsg->ActualCount);
2051 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2052 break;
2053 case RPC_FC_BOGUS_ARRAY:
2054 alignment = pFormat[1] + 1;
2055 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2056 if (IsConformanceOrVariancePresent(pFormat)) WriteVariance(pStubMsg);
2057 pFormat = SkipVariance(pStubMsg, pFormat);
2059 align_pointer_clear(&pStubMsg->Buffer, alignment);
2061 size = pStubMsg->ActualCount;
2062 for (i = 0; i < size; i++)
2063 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2064 break;
2065 default:
2066 ERR("unknown array format 0x%x\n", fc);
2067 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2071 static inline ULONG array_read_conformance(
2072 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
2074 DWORD def, esize;
2076 switch (fc)
2078 case RPC_FC_CARRAY:
2079 esize = *(const WORD*)(pFormat+2);
2080 pFormat = ReadConformance(pStubMsg, pFormat+4);
2081 return safe_multiply(esize, pStubMsg->MaxCount);
2082 case RPC_FC_CVARRAY:
2083 esize = *(const WORD*)(pFormat+2);
2084 pFormat = ReadConformance(pStubMsg, pFormat+4);
2085 return safe_multiply(esize, pStubMsg->MaxCount);
2086 case RPC_FC_C_CSTRING:
2087 case RPC_FC_C_WSTRING:
2088 if (fc == RPC_FC_C_CSTRING)
2089 esize = 1;
2090 else
2091 esize = 2;
2093 if (pFormat[1] == RPC_FC_STRING_SIZED)
2094 ReadConformance(pStubMsg, pFormat + 2);
2095 else
2096 ReadConformance(pStubMsg, NULL);
2097 return safe_multiply(esize, pStubMsg->MaxCount);
2098 case RPC_FC_BOGUS_ARRAY:
2099 def = *(const WORD *)(pFormat + 2);
2100 pFormat += 4;
2101 if (IsConformanceOrVariancePresent(pFormat)) pFormat = ReadConformance(pStubMsg, pFormat);
2102 else
2104 pStubMsg->MaxCount = def;
2105 pFormat = SkipConformance( pStubMsg, pFormat );
2107 pFormat = SkipVariance( pStubMsg, pFormat );
2109 esize = ComplexStructSize(pStubMsg, pFormat);
2110 return safe_multiply(pStubMsg->MaxCount, esize);
2111 default:
2112 ERR("unknown array format 0x%x\n", fc);
2113 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2117 static inline ULONG array_read_variance_and_unmarshall(
2118 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory,
2119 PFORMAT_STRING pFormat, unsigned char fMustAlloc,
2120 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall)
2122 ULONG bufsize, memsize;
2123 WORD esize;
2124 unsigned char alignment;
2125 unsigned char *saved_buffer, *pMemory;
2126 ULONG i, offset, count;
2128 switch (fc)
2130 case RPC_FC_CARRAY:
2131 esize = *(const WORD*)(pFormat+2);
2132 alignment = pFormat[1] + 1;
2134 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2136 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2138 align_pointer(&pStubMsg->Buffer, alignment);
2140 if (fUnmarshall)
2142 if (fMustAlloc)
2143 *ppMemory = NdrAllocate(pStubMsg, memsize);
2144 else
2146 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory)
2147 /* for servers, we just point straight into the RPC buffer */
2148 *ppMemory = pStubMsg->Buffer;
2151 saved_buffer = pStubMsg->Buffer;
2152 safe_buffer_increment(pStubMsg, bufsize);
2154 pStubMsg->BufferMark = saved_buffer;
2155 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2157 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2158 if (*ppMemory != saved_buffer)
2159 memcpy(*ppMemory, saved_buffer, bufsize);
2161 return bufsize;
2162 case RPC_FC_CVARRAY:
2163 esize = *(const WORD*)(pFormat+2);
2164 alignment = pFormat[1] + 1;
2166 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2168 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2170 align_pointer(&pStubMsg->Buffer, alignment);
2172 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2173 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2175 if (fUnmarshall)
2177 offset = pStubMsg->Offset;
2179 if (!fMustAlloc && !*ppMemory)
2180 fMustAlloc = TRUE;
2181 if (fMustAlloc)
2182 *ppMemory = NdrAllocate(pStubMsg, memsize);
2183 saved_buffer = pStubMsg->Buffer;
2184 safe_buffer_increment(pStubMsg, bufsize);
2186 pStubMsg->BufferMark = saved_buffer;
2187 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat,
2188 fMustAlloc);
2190 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2192 return bufsize;
2193 case RPC_FC_C_CSTRING:
2194 case RPC_FC_C_WSTRING:
2195 if (fc == RPC_FC_C_CSTRING)
2196 esize = 1;
2197 else
2198 esize = 2;
2200 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2202 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2204 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2205 pStubMsg->ActualCount, pStubMsg->MaxCount);
2206 RpcRaiseException(RPC_S_INVALID_BOUND);
2208 if (pStubMsg->Offset)
2210 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2211 RpcRaiseException(RPC_S_INVALID_BOUND);
2214 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2215 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2217 validate_string_data(pStubMsg, bufsize, esize);
2219 if (fUnmarshall)
2221 if (fMustAlloc)
2222 *ppMemory = NdrAllocate(pStubMsg, memsize);
2223 else
2225 if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
2226 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
2227 /* if the data in the RPC buffer is big enough, we just point
2228 * straight into it */
2229 *ppMemory = pStubMsg->Buffer;
2230 else if (!*ppMemory)
2231 *ppMemory = NdrAllocate(pStubMsg, memsize);
2234 if (*ppMemory == pStubMsg->Buffer)
2235 safe_buffer_increment(pStubMsg, bufsize);
2236 else
2237 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2239 if (*pFormat == RPC_FC_C_CSTRING)
2240 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
2241 else
2242 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
2244 return bufsize;
2246 case RPC_FC_BOGUS_ARRAY:
2247 alignment = pFormat[1] + 1;
2248 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2249 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2251 esize = ComplexStructSize(pStubMsg, pFormat);
2252 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2254 assert( fUnmarshall );
2256 if (!fMustAlloc && !*ppMemory)
2257 fMustAlloc = TRUE;
2258 if (fMustAlloc)
2259 *ppMemory = NdrAllocate(pStubMsg, memsize);
2261 align_pointer(&pStubMsg->Buffer, alignment);
2262 saved_buffer = pStubMsg->Buffer;
2264 pMemory = *ppMemory;
2265 count = pStubMsg->ActualCount;
2266 for (i = 0; i < count; i++)
2267 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
2268 return pStubMsg->Buffer - saved_buffer;
2270 default:
2271 ERR("unknown array format 0x%x\n", fc);
2272 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2276 static inline void array_memory_size(
2277 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
2278 unsigned char fHasPointers)
2280 ULONG i, count, SavedMemorySize;
2281 ULONG bufsize, memsize;
2282 DWORD esize;
2283 unsigned char alignment;
2285 switch (fc)
2287 case RPC_FC_CARRAY:
2288 esize = *(const WORD*)(pFormat+2);
2289 alignment = pFormat[1] + 1;
2291 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2293 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2294 pStubMsg->MemorySize += memsize;
2296 align_pointer(&pStubMsg->Buffer, alignment);
2297 if (fHasPointers)
2298 pStubMsg->BufferMark = pStubMsg->Buffer;
2299 safe_buffer_increment(pStubMsg, bufsize);
2301 if (fHasPointers)
2302 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2303 break;
2304 case RPC_FC_CVARRAY:
2305 esize = *(const WORD*)(pFormat+2);
2306 alignment = pFormat[1] + 1;
2308 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2310 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2312 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2313 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2314 pStubMsg->MemorySize += memsize;
2316 align_pointer(&pStubMsg->Buffer, alignment);
2317 if (fHasPointers)
2318 pStubMsg->BufferMark = pStubMsg->Buffer;
2319 safe_buffer_increment(pStubMsg, bufsize);
2321 if (fHasPointers)
2322 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2323 break;
2324 case RPC_FC_C_CSTRING:
2325 case RPC_FC_C_WSTRING:
2326 if (fc == RPC_FC_C_CSTRING)
2327 esize = 1;
2328 else
2329 esize = 2;
2331 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2333 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2335 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2336 pStubMsg->ActualCount, pStubMsg->MaxCount);
2337 RpcRaiseException(RPC_S_INVALID_BOUND);
2339 if (pStubMsg->Offset)
2341 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2342 RpcRaiseException(RPC_S_INVALID_BOUND);
2345 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2346 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2348 validate_string_data(pStubMsg, bufsize, esize);
2350 safe_buffer_increment(pStubMsg, bufsize);
2351 pStubMsg->MemorySize += memsize;
2352 break;
2353 case RPC_FC_BOGUS_ARRAY:
2354 alignment = pFormat[1] + 1;
2355 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2356 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2358 align_pointer(&pStubMsg->Buffer, alignment);
2360 SavedMemorySize = pStubMsg->MemorySize;
2362 esize = ComplexStructSize(pStubMsg, pFormat);
2363 memsize = safe_multiply(pStubMsg->MaxCount, esize);
2365 count = pStubMsg->ActualCount;
2366 for (i = 0; i < count; i++)
2367 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
2369 pStubMsg->MemorySize = SavedMemorySize + memsize;
2370 break;
2371 default:
2372 ERR("unknown array format 0x%x\n", fc);
2373 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2377 static inline void array_free(
2378 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
2379 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
2381 DWORD i, count;
2383 switch (fc)
2385 case RPC_FC_CARRAY:
2386 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2387 if (fHasPointers)
2388 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2389 break;
2390 case RPC_FC_CVARRAY:
2391 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2392 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2393 if (fHasPointers)
2394 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2395 break;
2396 case RPC_FC_C_CSTRING:
2397 case RPC_FC_C_WSTRING:
2398 /* No embedded pointers so nothing to do */
2399 break;
2400 case RPC_FC_BOGUS_ARRAY:
2401 count = *(const WORD *)(pFormat + 2);
2402 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, count);
2403 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2405 count = pStubMsg->ActualCount;
2406 for (i = 0; i < count; i++)
2407 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2408 break;
2409 default:
2410 ERR("unknown array format 0x%x\n", fc);
2411 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2416 * NdrConformantString:
2418 * What MS calls a ConformantString is, in DCE terminology,
2419 * a Varying-Conformant String.
2421 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2422 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2423 * into unmarshalled string)
2424 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2426 * data: CHARTYPE[maxlen]
2428 * ], where CHARTYPE is the appropriate character type (specified externally)
2432 /***********************************************************************
2433 * NdrConformantStringMarshall [RPCRT4.@]
2435 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
2436 unsigned char *pszMessage, PFORMAT_STRING pFormat)
2438 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
2440 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2441 ERR("Unhandled string type: %#x\n", pFormat[0]);
2442 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2445 /* allow compiler to optimise inline function by passing constant into
2446 * these functions */
2447 if (pFormat[0] == RPC_FC_C_CSTRING) {
2448 array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2449 pFormat);
2450 array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2451 pFormat, TRUE /* fHasPointers */);
2452 } else {
2453 array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2454 pFormat);
2455 array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2456 pFormat, TRUE /* fHasPointers */);
2459 return NULL;
2462 /***********************************************************************
2463 * NdrConformantStringBufferSize [RPCRT4.@]
2465 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2466 unsigned char* pMemory, PFORMAT_STRING pFormat)
2468 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2470 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2471 ERR("Unhandled string type: %#x\n", pFormat[0]);
2472 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2475 /* allow compiler to optimise inline function by passing constant into
2476 * these functions */
2477 if (pFormat[0] == RPC_FC_C_CSTRING) {
2478 array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory,
2479 pFormat);
2480 array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat,
2481 TRUE /* fHasPointers */);
2482 } else {
2483 array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory,
2484 pFormat);
2485 array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat,
2486 TRUE /* fHasPointers */);
2490 /************************************************************************
2491 * NdrConformantStringMemorySize [RPCRT4.@]
2493 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2494 PFORMAT_STRING pFormat )
2496 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2498 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2499 ERR("Unhandled string type: %#x\n", pFormat[0]);
2500 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2503 /* allow compiler to optimise inline function by passing constant into
2504 * these functions */
2505 if (pFormat[0] == RPC_FC_C_CSTRING) {
2506 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2507 array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat,
2508 TRUE /* fHasPointers */);
2509 } else {
2510 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2511 array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat,
2512 TRUE /* fHasPointers */);
2515 return pStubMsg->MemorySize;
2518 /************************************************************************
2519 * NdrConformantStringUnmarshall [RPCRT4.@]
2521 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2522 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
2524 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2525 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2527 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2528 ERR("Unhandled string type: %#x\n", *pFormat);
2529 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2532 /* allow compiler to optimise inline function by passing constant into
2533 * these functions */
2534 if (pFormat[0] == RPC_FC_C_CSTRING) {
2535 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2536 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory,
2537 pFormat, fMustAlloc,
2538 TRUE /* fUseBufferMemoryServer */,
2539 TRUE /* fUnmarshall */);
2540 } else {
2541 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2542 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory,
2543 pFormat, fMustAlloc,
2544 TRUE /* fUseBufferMemoryServer */,
2545 TRUE /* fUnmarshall */);
2548 return NULL;
2551 /***********************************************************************
2552 * NdrNonConformantStringMarshall [RPCRT4.@]
2554 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2555 unsigned char *pMemory,
2556 PFORMAT_STRING pFormat)
2558 ULONG esize, size, maxsize;
2560 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2562 maxsize = *(const USHORT *)&pFormat[2];
2564 if (*pFormat == RPC_FC_CSTRING)
2566 ULONG i = 0;
2567 const char *str = (const char *)pMemory;
2568 while (i < maxsize && str[i]) i++;
2569 TRACE("string=%s\n", debugstr_an(str, i));
2570 pStubMsg->ActualCount = i + 1;
2571 esize = 1;
2573 else if (*pFormat == RPC_FC_WSTRING)
2575 ULONG i = 0;
2576 const WCHAR *str = (const WCHAR *)pMemory;
2577 while (i < maxsize && str[i]) i++;
2578 TRACE("string=%s\n", debugstr_wn(str, i));
2579 pStubMsg->ActualCount = i + 1;
2580 esize = 2;
2582 else
2584 ERR("Unhandled string type: %#x\n", *pFormat);
2585 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2588 pStubMsg->Offset = 0;
2589 WriteVariance(pStubMsg);
2591 size = safe_multiply(esize, pStubMsg->ActualCount);
2592 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2594 return NULL;
2597 /***********************************************************************
2598 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2600 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2601 unsigned char **ppMemory,
2602 PFORMAT_STRING pFormat,
2603 unsigned char fMustAlloc)
2605 ULONG bufsize, memsize, esize, maxsize;
2607 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2608 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2610 maxsize = *(const USHORT *)&pFormat[2];
2612 ReadVariance(pStubMsg, NULL, maxsize);
2613 if (pStubMsg->Offset)
2615 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2616 RpcRaiseException(RPC_S_INVALID_BOUND);
2619 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2620 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2621 else
2623 ERR("Unhandled string type: %#x\n", *pFormat);
2624 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2627 memsize = esize * maxsize;
2628 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2630 validate_string_data(pStubMsg, bufsize, esize);
2632 if (!fMustAlloc && !*ppMemory)
2633 fMustAlloc = TRUE;
2634 if (fMustAlloc)
2635 *ppMemory = NdrAllocate(pStubMsg, memsize);
2637 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2639 if (*pFormat == RPC_FC_CSTRING) {
2640 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
2642 else if (*pFormat == RPC_FC_WSTRING) {
2643 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
2646 return NULL;
2649 /***********************************************************************
2650 * NdrNonConformantStringBufferSize [RPCRT4.@]
2652 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2653 unsigned char *pMemory,
2654 PFORMAT_STRING pFormat)
2656 ULONG esize, maxsize;
2658 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2660 maxsize = *(const USHORT *)&pFormat[2];
2662 SizeVariance(pStubMsg);
2664 if (*pFormat == RPC_FC_CSTRING)
2666 ULONG i = 0;
2667 const char *str = (const char *)pMemory;
2668 while (i < maxsize && str[i]) i++;
2669 TRACE("string=%s\n", debugstr_an(str, i));
2670 pStubMsg->ActualCount = i + 1;
2671 esize = 1;
2673 else if (*pFormat == RPC_FC_WSTRING)
2675 ULONG i = 0;
2676 const WCHAR *str = (const WCHAR *)pMemory;
2677 while (i < maxsize && str[i]) i++;
2678 TRACE("string=%s\n", debugstr_wn(str, i));
2679 pStubMsg->ActualCount = i + 1;
2680 esize = 2;
2682 else
2684 ERR("Unhandled string type: %#x\n", *pFormat);
2685 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2688 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2691 /***********************************************************************
2692 * NdrNonConformantStringMemorySize [RPCRT4.@]
2694 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2695 PFORMAT_STRING pFormat)
2697 ULONG bufsize, memsize, esize, maxsize;
2699 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2701 maxsize = *(const USHORT *)&pFormat[2];
2703 ReadVariance(pStubMsg, NULL, maxsize);
2705 if (pStubMsg->Offset)
2707 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2708 RpcRaiseException(RPC_S_INVALID_BOUND);
2711 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2712 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2713 else
2715 ERR("Unhandled string type: %#x\n", *pFormat);
2716 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2719 memsize = esize * maxsize;
2720 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2722 validate_string_data(pStubMsg, bufsize, esize);
2724 safe_buffer_increment(pStubMsg, bufsize);
2725 pStubMsg->MemorySize += memsize;
2727 return pStubMsg->MemorySize;
2730 /* Complex types */
2732 #include "pshpack1.h"
2733 typedef struct
2735 unsigned char type;
2736 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2737 ULONG low_value;
2738 ULONG high_value;
2739 } NDR_RANGE;
2740 #include "poppack.h"
2742 static ULONG EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2743 PFORMAT_STRING pFormat)
2745 switch (*pFormat) {
2746 case RPC_FC_STRUCT:
2747 case RPC_FC_PSTRUCT:
2748 case RPC_FC_CSTRUCT:
2749 case RPC_FC_BOGUS_STRUCT:
2750 case RPC_FC_SMFARRAY:
2751 case RPC_FC_SMVARRAY:
2752 case RPC_FC_CSTRING:
2753 return *(const WORD*)&pFormat[2];
2754 case RPC_FC_USER_MARSHAL:
2755 return *(const WORD*)&pFormat[4];
2756 case RPC_FC_RANGE: {
2757 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2758 case RPC_FC_BYTE:
2759 case RPC_FC_CHAR:
2760 case RPC_FC_SMALL:
2761 case RPC_FC_USMALL:
2762 return sizeof(UCHAR);
2763 case RPC_FC_WCHAR:
2764 case RPC_FC_SHORT:
2765 case RPC_FC_USHORT:
2766 return sizeof(USHORT);
2767 case RPC_FC_LONG:
2768 case RPC_FC_ULONG:
2769 case RPC_FC_ENUM32:
2770 case RPC_FC_INT3264:
2771 case RPC_FC_UINT3264:
2772 return sizeof(ULONG);
2773 case RPC_FC_FLOAT:
2774 return sizeof(float);
2775 case RPC_FC_DOUBLE:
2776 return sizeof(double);
2777 case RPC_FC_HYPER:
2778 return sizeof(ULONGLONG);
2779 case RPC_FC_ENUM16:
2780 return sizeof(UINT);
2781 default:
2782 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2783 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2786 case RPC_FC_NON_ENCAPSULATED_UNION:
2787 pFormat += 2;
2788 if (pStubMsg->fHasNewCorrDesc)
2789 pFormat += 6;
2790 else
2791 pFormat += 4;
2793 pFormat += *(const SHORT*)pFormat;
2794 return *(const SHORT*)pFormat;
2795 case RPC_FC_IP:
2796 return sizeof(void *);
2797 case RPC_FC_WSTRING:
2798 return *(const WORD*)&pFormat[2] * 2;
2799 default:
2800 FIXME("unhandled embedded type %02x\n", *pFormat);
2802 return 0;
2806 static ULONG EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2807 PFORMAT_STRING pFormat)
2809 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2811 if (!m)
2813 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2814 return 0;
2817 return m(pStubMsg, pFormat);
2821 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2822 unsigned char *pMemory,
2823 PFORMAT_STRING pFormat,
2824 PFORMAT_STRING pPointer)
2826 PFORMAT_STRING desc;
2827 NDR_MARSHALL m;
2828 ULONG size;
2830 while (*pFormat != RPC_FC_END) {
2831 switch (*pFormat) {
2832 case RPC_FC_BYTE:
2833 case RPC_FC_CHAR:
2834 case RPC_FC_SMALL:
2835 case RPC_FC_USMALL:
2836 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2837 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2838 pMemory += 1;
2839 break;
2840 case RPC_FC_WCHAR:
2841 case RPC_FC_SHORT:
2842 case RPC_FC_USHORT:
2843 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2844 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2845 pMemory += 2;
2846 break;
2847 case RPC_FC_ENUM16:
2849 USHORT val = *(DWORD *)pMemory;
2850 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2851 if (32767 < *(DWORD*)pMemory)
2852 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2853 safe_copy_to_buffer(pStubMsg, &val, 2);
2854 pMemory += 4;
2855 break;
2857 case RPC_FC_LONG:
2858 case RPC_FC_ULONG:
2859 case RPC_FC_ENUM32:
2860 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2861 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2862 pMemory += 4;
2863 break;
2864 case RPC_FC_INT3264:
2865 case RPC_FC_UINT3264:
2867 UINT val = *(UINT_PTR *)pMemory;
2868 TRACE("int3264=%ld <= %p\n", *(UINT_PTR *)pMemory, pMemory);
2869 safe_copy_to_buffer(pStubMsg, &val, sizeof(UINT));
2870 pMemory += sizeof(UINT_PTR);
2871 break;
2873 case RPC_FC_FLOAT:
2874 TRACE("float=%f <= %p\n", *(float*)pMemory, pMemory);
2875 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
2876 pMemory += sizeof(float);
2877 break;
2878 case RPC_FC_HYPER:
2879 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2880 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2881 pMemory += 8;
2882 break;
2883 case RPC_FC_DOUBLE:
2884 TRACE("double=%f <= %p\n", *(double*)pMemory, pMemory);
2885 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
2886 pMemory += sizeof(double);
2887 break;
2888 case RPC_FC_RP:
2889 case RPC_FC_UP:
2890 case RPC_FC_OP:
2891 case RPC_FC_FP:
2892 case RPC_FC_POINTER:
2894 unsigned char *saved_buffer;
2895 BOOL pointer_buffer_mark_set = FALSE;
2896 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2897 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2898 if (*pFormat != RPC_FC_POINTER)
2899 pPointer = pFormat;
2900 if (*pPointer != RPC_FC_RP)
2901 align_pointer_clear(&pStubMsg->Buffer, 4);
2902 saved_buffer = pStubMsg->Buffer;
2903 if (pStubMsg->PointerBufferMark)
2905 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2906 pStubMsg->PointerBufferMark = NULL;
2907 pointer_buffer_mark_set = TRUE;
2909 else if (*pPointer != RPC_FC_RP)
2910 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2911 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2912 if (pointer_buffer_mark_set)
2914 STD_OVERFLOW_CHECK(pStubMsg);
2915 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2916 pStubMsg->Buffer = saved_buffer;
2917 if (*pPointer != RPC_FC_RP)
2918 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2920 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2921 if (*pFormat == RPC_FC_POINTER)
2922 pPointer += 4;
2923 else
2924 pFormat += 4;
2925 pMemory += sizeof(void *);
2926 break;
2928 case RPC_FC_ALIGNM2:
2929 align_pointer(&pMemory, 2);
2930 break;
2931 case RPC_FC_ALIGNM4:
2932 align_pointer(&pMemory, 4);
2933 break;
2934 case RPC_FC_ALIGNM8:
2935 align_pointer(&pMemory, 8);
2936 break;
2937 case RPC_FC_STRUCTPAD1:
2938 case RPC_FC_STRUCTPAD2:
2939 case RPC_FC_STRUCTPAD3:
2940 case RPC_FC_STRUCTPAD4:
2941 case RPC_FC_STRUCTPAD5:
2942 case RPC_FC_STRUCTPAD6:
2943 case RPC_FC_STRUCTPAD7:
2944 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2945 break;
2946 case RPC_FC_EMBEDDED_COMPLEX:
2947 pMemory += pFormat[1];
2948 pFormat += 2;
2949 desc = pFormat + *(const SHORT*)pFormat;
2950 size = EmbeddedComplexSize(pStubMsg, desc);
2951 TRACE("embedded complex (size=%d) <= %p\n", size, pMemory);
2952 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2953 if (m)
2955 /* for some reason interface pointers aren't generated as
2956 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2957 * they still need the derefencing treatment that pointers are
2958 * given */
2959 if (*desc == RPC_FC_IP)
2960 m(pStubMsg, *(unsigned char **)pMemory, desc);
2961 else
2962 m(pStubMsg, pMemory, desc);
2964 else FIXME("no marshaller for embedded type %02x\n", *desc);
2965 pMemory += size;
2966 pFormat += 2;
2967 continue;
2968 case RPC_FC_PAD:
2969 break;
2970 default:
2971 FIXME("unhandled format 0x%02x\n", *pFormat);
2973 pFormat++;
2976 return pMemory;
2979 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2980 unsigned char *pMemory,
2981 PFORMAT_STRING pFormat,
2982 PFORMAT_STRING pPointer,
2983 unsigned char fMustAlloc)
2985 PFORMAT_STRING desc;
2986 NDR_UNMARSHALL m;
2987 ULONG size;
2989 while (*pFormat != RPC_FC_END) {
2990 switch (*pFormat) {
2991 case RPC_FC_BYTE:
2992 case RPC_FC_CHAR:
2993 case RPC_FC_SMALL:
2994 case RPC_FC_USMALL:
2995 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2996 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2997 pMemory += 1;
2998 break;
2999 case RPC_FC_WCHAR:
3000 case RPC_FC_SHORT:
3001 case RPC_FC_USHORT:
3002 safe_copy_from_buffer(pStubMsg, pMemory, 2);
3003 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
3004 pMemory += 2;
3005 break;
3006 case RPC_FC_ENUM16:
3008 WORD val;
3009 safe_copy_from_buffer(pStubMsg, &val, 2);
3010 *(DWORD*)pMemory = val;
3011 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
3012 if (32767 < *(DWORD*)pMemory)
3013 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
3014 pMemory += 4;
3015 break;
3017 case RPC_FC_LONG:
3018 case RPC_FC_ULONG:
3019 case RPC_FC_ENUM32:
3020 safe_copy_from_buffer(pStubMsg, pMemory, 4);
3021 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
3022 pMemory += 4;
3023 break;
3024 case RPC_FC_INT3264:
3026 INT val;
3027 safe_copy_from_buffer(pStubMsg, &val, 4);
3028 *(INT_PTR *)pMemory = val;
3029 TRACE("int3264=%ld => %p\n", *(INT_PTR*)pMemory, pMemory);
3030 pMemory += sizeof(INT_PTR);
3031 break;
3033 case RPC_FC_UINT3264:
3035 UINT val;
3036 safe_copy_from_buffer(pStubMsg, &val, 4);
3037 *(UINT_PTR *)pMemory = val;
3038 TRACE("uint3264=%ld => %p\n", *(UINT_PTR*)pMemory, pMemory);
3039 pMemory += sizeof(UINT_PTR);
3040 break;
3042 case RPC_FC_FLOAT:
3043 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(float));
3044 TRACE("float=%f => %p\n", *(float*)pMemory, pMemory);
3045 pMemory += sizeof(float);
3046 break;
3047 case RPC_FC_HYPER:
3048 safe_copy_from_buffer(pStubMsg, pMemory, 8);
3049 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
3050 pMemory += 8;
3051 break;
3052 case RPC_FC_DOUBLE:
3053 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(double));
3054 TRACE("double=%f => %p\n", *(double*)pMemory, pMemory);
3055 pMemory += sizeof(double);
3056 break;
3057 case RPC_FC_RP:
3058 case RPC_FC_UP:
3059 case RPC_FC_OP:
3060 case RPC_FC_FP:
3061 case RPC_FC_POINTER:
3063 unsigned char *saved_buffer;
3064 BOOL pointer_buffer_mark_set = FALSE;
3065 TRACE("pointer => %p\n", pMemory);
3066 if (*pFormat != RPC_FC_POINTER)
3067 pPointer = pFormat;
3068 if (*pPointer != RPC_FC_RP)
3069 align_pointer(&pStubMsg->Buffer, 4);
3070 saved_buffer = pStubMsg->Buffer;
3071 if (pStubMsg->PointerBufferMark)
3073 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3074 pStubMsg->PointerBufferMark = NULL;
3075 pointer_buffer_mark_set = TRUE;
3077 else if (*pPointer != RPC_FC_RP)
3078 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3080 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
3081 if (pointer_buffer_mark_set)
3083 STD_OVERFLOW_CHECK(pStubMsg);
3084 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3085 pStubMsg->Buffer = saved_buffer;
3086 if (*pPointer != RPC_FC_RP)
3087 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3089 if (*pFormat == RPC_FC_POINTER)
3090 pPointer += 4;
3091 else
3092 pFormat += 4;
3093 pMemory += sizeof(void *);
3094 break;
3096 case RPC_FC_ALIGNM2:
3097 align_pointer_clear(&pMemory, 2);
3098 break;
3099 case RPC_FC_ALIGNM4:
3100 align_pointer_clear(&pMemory, 4);
3101 break;
3102 case RPC_FC_ALIGNM8:
3103 align_pointer_clear(&pMemory, 8);
3104 break;
3105 case RPC_FC_STRUCTPAD1:
3106 case RPC_FC_STRUCTPAD2:
3107 case RPC_FC_STRUCTPAD3:
3108 case RPC_FC_STRUCTPAD4:
3109 case RPC_FC_STRUCTPAD5:
3110 case RPC_FC_STRUCTPAD6:
3111 case RPC_FC_STRUCTPAD7:
3112 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
3113 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3114 break;
3115 case RPC_FC_EMBEDDED_COMPLEX:
3116 pMemory += pFormat[1];
3117 pFormat += 2;
3118 desc = pFormat + *(const SHORT*)pFormat;
3119 size = EmbeddedComplexSize(pStubMsg, desc);
3120 TRACE("embedded complex (size=%d) => %p\n", size, pMemory);
3121 if (fMustAlloc)
3122 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
3123 * since the type is part of the memory block that is encompassed by
3124 * the whole complex type. Memory is forced to allocate when pointers
3125 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
3126 * clearing the memory we pass in to the unmarshaller */
3127 memset(pMemory, 0, size);
3128 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
3129 if (m)
3131 /* for some reason interface pointers aren't generated as
3132 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3133 * they still need the derefencing treatment that pointers are
3134 * given */
3135 if (*desc == RPC_FC_IP)
3136 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
3137 else
3138 m(pStubMsg, &pMemory, desc, FALSE);
3140 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
3141 pMemory += size;
3142 pFormat += 2;
3143 continue;
3144 case RPC_FC_PAD:
3145 break;
3146 default:
3147 FIXME("unhandled format %d\n", *pFormat);
3149 pFormat++;
3152 return pMemory;
3155 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3156 unsigned char *pMemory,
3157 PFORMAT_STRING pFormat,
3158 PFORMAT_STRING pPointer)
3160 PFORMAT_STRING desc;
3161 NDR_BUFFERSIZE m;
3162 ULONG size;
3164 while (*pFormat != RPC_FC_END) {
3165 switch (*pFormat) {
3166 case RPC_FC_BYTE:
3167 case RPC_FC_CHAR:
3168 case RPC_FC_SMALL:
3169 case RPC_FC_USMALL:
3170 safe_buffer_length_increment(pStubMsg, 1);
3171 pMemory += 1;
3172 break;
3173 case RPC_FC_WCHAR:
3174 case RPC_FC_SHORT:
3175 case RPC_FC_USHORT:
3176 safe_buffer_length_increment(pStubMsg, 2);
3177 pMemory += 2;
3178 break;
3179 case RPC_FC_ENUM16:
3180 safe_buffer_length_increment(pStubMsg, 2);
3181 pMemory += 4;
3182 break;
3183 case RPC_FC_LONG:
3184 case RPC_FC_ULONG:
3185 case RPC_FC_ENUM32:
3186 case RPC_FC_FLOAT:
3187 safe_buffer_length_increment(pStubMsg, 4);
3188 pMemory += 4;
3189 break;
3190 case RPC_FC_INT3264:
3191 case RPC_FC_UINT3264:
3192 safe_buffer_length_increment(pStubMsg, 4);
3193 pMemory += sizeof(INT_PTR);
3194 break;
3195 case RPC_FC_HYPER:
3196 case RPC_FC_DOUBLE:
3197 safe_buffer_length_increment(pStubMsg, 8);
3198 pMemory += 8;
3199 break;
3200 case RPC_FC_RP:
3201 case RPC_FC_UP:
3202 case RPC_FC_OP:
3203 case RPC_FC_FP:
3204 case RPC_FC_POINTER:
3205 if (*pFormat != RPC_FC_POINTER)
3206 pPointer = pFormat;
3207 if (!pStubMsg->IgnoreEmbeddedPointers)
3209 int saved_buffer_length = pStubMsg->BufferLength;
3210 pStubMsg->BufferLength = pStubMsg->PointerLength;
3211 pStubMsg->PointerLength = 0;
3212 if(!pStubMsg->BufferLength)
3213 ERR("BufferLength == 0??\n");
3214 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
3215 pStubMsg->PointerLength = pStubMsg->BufferLength;
3216 pStubMsg->BufferLength = saved_buffer_length;
3218 if (*pPointer != RPC_FC_RP)
3220 align_length(&pStubMsg->BufferLength, 4);
3221 safe_buffer_length_increment(pStubMsg, 4);
3223 if (*pFormat == RPC_FC_POINTER)
3224 pPointer += 4;
3225 else
3226 pFormat += 4;
3227 pMemory += sizeof(void*);
3228 break;
3229 case RPC_FC_ALIGNM2:
3230 align_pointer(&pMemory, 2);
3231 break;
3232 case RPC_FC_ALIGNM4:
3233 align_pointer(&pMemory, 4);
3234 break;
3235 case RPC_FC_ALIGNM8:
3236 align_pointer(&pMemory, 8);
3237 break;
3238 case RPC_FC_STRUCTPAD1:
3239 case RPC_FC_STRUCTPAD2:
3240 case RPC_FC_STRUCTPAD3:
3241 case RPC_FC_STRUCTPAD4:
3242 case RPC_FC_STRUCTPAD5:
3243 case RPC_FC_STRUCTPAD6:
3244 case RPC_FC_STRUCTPAD7:
3245 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3246 break;
3247 case RPC_FC_EMBEDDED_COMPLEX:
3248 pMemory += pFormat[1];
3249 pFormat += 2;
3250 desc = pFormat + *(const SHORT*)pFormat;
3251 size = EmbeddedComplexSize(pStubMsg, desc);
3252 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
3253 if (m)
3255 /* for some reason interface pointers aren't generated as
3256 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3257 * they still need the derefencing treatment that pointers are
3258 * given */
3259 if (*desc == RPC_FC_IP)
3260 m(pStubMsg, *(unsigned char **)pMemory, desc);
3261 else
3262 m(pStubMsg, pMemory, desc);
3264 else FIXME("no buffersizer for embedded type %02x\n", *desc);
3265 pMemory += size;
3266 pFormat += 2;
3267 continue;
3268 case RPC_FC_PAD:
3269 break;
3270 default:
3271 FIXME("unhandled format 0x%02x\n", *pFormat);
3273 pFormat++;
3276 return pMemory;
3279 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
3280 unsigned char *pMemory,
3281 PFORMAT_STRING pFormat,
3282 PFORMAT_STRING pPointer)
3284 PFORMAT_STRING desc;
3285 NDR_FREE m;
3286 ULONG size;
3288 while (*pFormat != RPC_FC_END) {
3289 switch (*pFormat) {
3290 case RPC_FC_BYTE:
3291 case RPC_FC_CHAR:
3292 case RPC_FC_SMALL:
3293 case RPC_FC_USMALL:
3294 pMemory += 1;
3295 break;
3296 case RPC_FC_WCHAR:
3297 case RPC_FC_SHORT:
3298 case RPC_FC_USHORT:
3299 pMemory += 2;
3300 break;
3301 case RPC_FC_LONG:
3302 case RPC_FC_ULONG:
3303 case RPC_FC_ENUM16:
3304 case RPC_FC_ENUM32:
3305 case RPC_FC_FLOAT:
3306 pMemory += 4;
3307 break;
3308 case RPC_FC_INT3264:
3309 case RPC_FC_UINT3264:
3310 pMemory += sizeof(INT_PTR);
3311 break;
3312 case RPC_FC_HYPER:
3313 case RPC_FC_DOUBLE:
3314 pMemory += 8;
3315 break;
3316 case RPC_FC_RP:
3317 case RPC_FC_UP:
3318 case RPC_FC_OP:
3319 case RPC_FC_FP:
3320 case RPC_FC_POINTER:
3321 if (*pFormat != RPC_FC_POINTER)
3322 pPointer = pFormat;
3323 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3324 if (*pFormat == RPC_FC_POINTER)
3325 pPointer += 4;
3326 else
3327 pFormat += 4;
3328 pMemory += sizeof(void *);
3329 break;
3330 case RPC_FC_ALIGNM2:
3331 align_pointer(&pMemory, 2);
3332 break;
3333 case RPC_FC_ALIGNM4:
3334 align_pointer(&pMemory, 4);
3335 break;
3336 case RPC_FC_ALIGNM8:
3337 align_pointer(&pMemory, 8);
3338 break;
3339 case RPC_FC_STRUCTPAD1:
3340 case RPC_FC_STRUCTPAD2:
3341 case RPC_FC_STRUCTPAD3:
3342 case RPC_FC_STRUCTPAD4:
3343 case RPC_FC_STRUCTPAD5:
3344 case RPC_FC_STRUCTPAD6:
3345 case RPC_FC_STRUCTPAD7:
3346 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3347 break;
3348 case RPC_FC_EMBEDDED_COMPLEX:
3349 pMemory += pFormat[1];
3350 pFormat += 2;
3351 desc = pFormat + *(const SHORT*)pFormat;
3352 size = EmbeddedComplexSize(pStubMsg, desc);
3353 m = NdrFreer[*desc & NDR_TABLE_MASK];
3354 if (m)
3356 /* for some reason interface pointers aren't generated as
3357 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3358 * they still need the derefencing treatment that pointers are
3359 * given */
3360 if (*desc == RPC_FC_IP)
3361 m(pStubMsg, *(unsigned char **)pMemory, desc);
3362 else
3363 m(pStubMsg, pMemory, desc);
3365 pMemory += size;
3366 pFormat += 2;
3367 continue;
3368 case RPC_FC_PAD:
3369 break;
3370 default:
3371 FIXME("unhandled format 0x%02x\n", *pFormat);
3373 pFormat++;
3376 return pMemory;
3379 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3380 PFORMAT_STRING pFormat,
3381 PFORMAT_STRING pPointer)
3383 PFORMAT_STRING desc;
3384 ULONG size = 0;
3386 while (*pFormat != RPC_FC_END) {
3387 switch (*pFormat) {
3388 case RPC_FC_BYTE:
3389 case RPC_FC_CHAR:
3390 case RPC_FC_SMALL:
3391 case RPC_FC_USMALL:
3392 size += 1;
3393 safe_buffer_increment(pStubMsg, 1);
3394 break;
3395 case RPC_FC_WCHAR:
3396 case RPC_FC_SHORT:
3397 case RPC_FC_USHORT:
3398 size += 2;
3399 safe_buffer_increment(pStubMsg, 2);
3400 break;
3401 case RPC_FC_ENUM16:
3402 size += 4;
3403 safe_buffer_increment(pStubMsg, 2);
3404 break;
3405 case RPC_FC_LONG:
3406 case RPC_FC_ULONG:
3407 case RPC_FC_ENUM32:
3408 case RPC_FC_FLOAT:
3409 size += 4;
3410 safe_buffer_increment(pStubMsg, 4);
3411 break;
3412 case RPC_FC_INT3264:
3413 case RPC_FC_UINT3264:
3414 size += sizeof(INT_PTR);
3415 safe_buffer_increment(pStubMsg, 4);
3416 break;
3417 case RPC_FC_HYPER:
3418 case RPC_FC_DOUBLE:
3419 size += 8;
3420 safe_buffer_increment(pStubMsg, 8);
3421 break;
3422 case RPC_FC_RP:
3423 case RPC_FC_UP:
3424 case RPC_FC_OP:
3425 case RPC_FC_FP:
3426 case RPC_FC_POINTER:
3428 unsigned char *saved_buffer;
3429 BOOL pointer_buffer_mark_set = FALSE;
3430 if (*pFormat != RPC_FC_POINTER)
3431 pPointer = pFormat;
3432 if (*pPointer != RPC_FC_RP)
3433 align_pointer(&pStubMsg->Buffer, 4);
3434 saved_buffer = pStubMsg->Buffer;
3435 if (pStubMsg->PointerBufferMark)
3437 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3438 pStubMsg->PointerBufferMark = NULL;
3439 pointer_buffer_mark_set = TRUE;
3441 else if (*pPointer != RPC_FC_RP)
3442 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3444 if (!pStubMsg->IgnoreEmbeddedPointers)
3445 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3446 if (pointer_buffer_mark_set)
3448 STD_OVERFLOW_CHECK(pStubMsg);
3449 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3450 pStubMsg->Buffer = saved_buffer;
3451 if (*pPointer != RPC_FC_RP)
3452 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3454 if (*pFormat == RPC_FC_POINTER)
3455 pPointer += 4;
3456 else
3457 pFormat += 4;
3458 size += sizeof(void *);
3459 break;
3461 case RPC_FC_ALIGNM2:
3462 align_length(&size, 2);
3463 break;
3464 case RPC_FC_ALIGNM4:
3465 align_length(&size, 4);
3466 break;
3467 case RPC_FC_ALIGNM8:
3468 align_length(&size, 8);
3469 break;
3470 case RPC_FC_STRUCTPAD1:
3471 case RPC_FC_STRUCTPAD2:
3472 case RPC_FC_STRUCTPAD3:
3473 case RPC_FC_STRUCTPAD4:
3474 case RPC_FC_STRUCTPAD5:
3475 case RPC_FC_STRUCTPAD6:
3476 case RPC_FC_STRUCTPAD7:
3477 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3478 break;
3479 case RPC_FC_EMBEDDED_COMPLEX:
3480 size += pFormat[1];
3481 pFormat += 2;
3482 desc = pFormat + *(const SHORT*)pFormat;
3483 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3484 pFormat += 2;
3485 continue;
3486 case RPC_FC_PAD:
3487 break;
3488 default:
3489 FIXME("unhandled format 0x%02x\n", *pFormat);
3491 pFormat++;
3494 return size;
3497 ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
3499 PFORMAT_STRING desc;
3500 ULONG size = 0;
3502 while (*pFormat != RPC_FC_END) {
3503 switch (*pFormat) {
3504 case RPC_FC_BYTE:
3505 case RPC_FC_CHAR:
3506 case RPC_FC_SMALL:
3507 case RPC_FC_USMALL:
3508 size += 1;
3509 break;
3510 case RPC_FC_WCHAR:
3511 case RPC_FC_SHORT:
3512 case RPC_FC_USHORT:
3513 size += 2;
3514 break;
3515 case RPC_FC_LONG:
3516 case RPC_FC_ULONG:
3517 case RPC_FC_ENUM16:
3518 case RPC_FC_ENUM32:
3519 case RPC_FC_FLOAT:
3520 size += 4;
3521 break;
3522 case RPC_FC_INT3264:
3523 case RPC_FC_UINT3264:
3524 size += sizeof(INT_PTR);
3525 break;
3526 case RPC_FC_HYPER:
3527 case RPC_FC_DOUBLE:
3528 size += 8;
3529 break;
3530 case RPC_FC_RP:
3531 case RPC_FC_UP:
3532 case RPC_FC_OP:
3533 case RPC_FC_FP:
3534 case RPC_FC_POINTER:
3535 size += sizeof(void *);
3536 if (*pFormat != RPC_FC_POINTER)
3537 pFormat += 4;
3538 break;
3539 case RPC_FC_ALIGNM2:
3540 align_length(&size, 2);
3541 break;
3542 case RPC_FC_ALIGNM4:
3543 align_length(&size, 4);
3544 break;
3545 case RPC_FC_ALIGNM8:
3546 align_length(&size, 8);
3547 break;
3548 case RPC_FC_STRUCTPAD1:
3549 case RPC_FC_STRUCTPAD2:
3550 case RPC_FC_STRUCTPAD3:
3551 case RPC_FC_STRUCTPAD4:
3552 case RPC_FC_STRUCTPAD5:
3553 case RPC_FC_STRUCTPAD6:
3554 case RPC_FC_STRUCTPAD7:
3555 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3556 break;
3557 case RPC_FC_EMBEDDED_COMPLEX:
3558 size += pFormat[1];
3559 pFormat += 2;
3560 desc = pFormat + *(const SHORT*)pFormat;
3561 size += EmbeddedComplexSize(pStubMsg, desc);
3562 pFormat += 2;
3563 continue;
3564 case RPC_FC_PAD:
3565 break;
3566 default:
3567 FIXME("unhandled format 0x%02x\n", *pFormat);
3569 pFormat++;
3572 return size;
3575 /***********************************************************************
3576 * NdrComplexStructMarshall [RPCRT4.@]
3578 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3579 unsigned char *pMemory,
3580 PFORMAT_STRING pFormat)
3582 PFORMAT_STRING conf_array = NULL;
3583 PFORMAT_STRING pointer_desc = NULL;
3584 unsigned char *OldMemory = pStubMsg->Memory;
3585 BOOL pointer_buffer_mark_set = FALSE;
3586 ULONG count = 0;
3587 ULONG max_count = 0;
3588 ULONG offset = 0;
3590 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3592 if (!pStubMsg->PointerBufferMark)
3594 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3595 /* save buffer length */
3596 ULONG saved_buffer_length = pStubMsg->BufferLength;
3598 /* get the buffer pointer after complex array data, but before
3599 * pointer data */
3600 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3601 pStubMsg->IgnoreEmbeddedPointers = 1;
3602 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3603 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3605 /* save it for use by embedded pointer code later */
3606 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3607 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - pStubMsg->Buffer));
3608 pointer_buffer_mark_set = TRUE;
3610 /* restore the original buffer length */
3611 pStubMsg->BufferLength = saved_buffer_length;
3614 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1);
3616 pFormat += 4;
3617 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3618 pFormat += 2;
3619 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3620 pFormat += 2;
3622 pStubMsg->Memory = pMemory;
3624 if (conf_array)
3626 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3627 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3628 pMemory + struct_size, conf_array);
3629 /* these could be changed in ComplexMarshall so save them for later */
3630 max_count = pStubMsg->MaxCount;
3631 count = pStubMsg->ActualCount;
3632 offset = pStubMsg->Offset;
3635 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3637 if (conf_array)
3639 pStubMsg->MaxCount = max_count;
3640 pStubMsg->ActualCount = count;
3641 pStubMsg->Offset = offset;
3642 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3643 conf_array, TRUE /* fHasPointers */);
3646 pStubMsg->Memory = OldMemory;
3648 if (pointer_buffer_mark_set)
3650 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3651 pStubMsg->PointerBufferMark = NULL;
3654 STD_OVERFLOW_CHECK(pStubMsg);
3656 return NULL;
3659 /***********************************************************************
3660 * NdrComplexStructUnmarshall [RPCRT4.@]
3662 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3663 unsigned char **ppMemory,
3664 PFORMAT_STRING pFormat,
3665 unsigned char fMustAlloc)
3667 unsigned size = *(const WORD*)(pFormat+2);
3668 PFORMAT_STRING conf_array = NULL;
3669 PFORMAT_STRING pointer_desc = NULL;
3670 unsigned char *pMemory;
3671 BOOL pointer_buffer_mark_set = FALSE;
3672 ULONG count = 0;
3673 ULONG max_count = 0;
3674 ULONG offset = 0;
3675 ULONG array_size = 0;
3677 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3679 if (!pStubMsg->PointerBufferMark)
3681 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3682 /* save buffer pointer */
3683 unsigned char *saved_buffer = pStubMsg->Buffer;
3685 /* get the buffer pointer after complex array data, but before
3686 * pointer data */
3687 pStubMsg->IgnoreEmbeddedPointers = 1;
3688 NdrComplexStructMemorySize(pStubMsg, pFormat);
3689 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3691 /* save it for use by embedded pointer code later */
3692 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3693 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - saved_buffer));
3694 pointer_buffer_mark_set = TRUE;
3696 /* restore the original buffer */
3697 pStubMsg->Buffer = saved_buffer;
3700 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3702 pFormat += 4;
3703 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3704 pFormat += 2;
3705 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3706 pFormat += 2;
3708 if (conf_array)
3710 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3711 size += array_size;
3713 /* these could be changed in ComplexMarshall so save them for later */
3714 max_count = pStubMsg->MaxCount;
3715 count = pStubMsg->ActualCount;
3716 offset = pStubMsg->Offset;
3719 if (!fMustAlloc && !*ppMemory)
3720 fMustAlloc = TRUE;
3721 if (fMustAlloc)
3722 *ppMemory = NdrAllocate(pStubMsg, size);
3724 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3726 if (conf_array)
3728 pStubMsg->MaxCount = max_count;
3729 pStubMsg->ActualCount = count;
3730 pStubMsg->Offset = offset;
3731 if (fMustAlloc)
3732 memset(pMemory, 0, array_size);
3733 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3734 conf_array, FALSE,
3735 FALSE /* fUseBufferMemoryServer */,
3736 TRUE /* fUnmarshall */);
3739 if (pointer_buffer_mark_set)
3741 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3742 pStubMsg->PointerBufferMark = NULL;
3745 return NULL;
3748 /***********************************************************************
3749 * NdrComplexStructBufferSize [RPCRT4.@]
3751 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3752 unsigned char *pMemory,
3753 PFORMAT_STRING pFormat)
3755 PFORMAT_STRING conf_array = NULL;
3756 PFORMAT_STRING pointer_desc = NULL;
3757 unsigned char *OldMemory = pStubMsg->Memory;
3758 int pointer_length_set = 0;
3759 ULONG count = 0;
3760 ULONG max_count = 0;
3761 ULONG offset = 0;
3763 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3765 align_length(&pStubMsg->BufferLength, pFormat[1] + 1);
3767 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3769 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3770 ULONG saved_buffer_length = pStubMsg->BufferLength;
3772 /* get the buffer length after complex struct data, but before
3773 * pointer data */
3774 pStubMsg->IgnoreEmbeddedPointers = 1;
3775 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3776 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3778 /* save it for use by embedded pointer code later */
3779 pStubMsg->PointerLength = pStubMsg->BufferLength;
3780 pointer_length_set = 1;
3781 TRACE("difference = 0x%x\n", pStubMsg->PointerLength - saved_buffer_length);
3783 /* restore the original buffer length */
3784 pStubMsg->BufferLength = saved_buffer_length;
3787 pFormat += 4;
3788 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3789 pFormat += 2;
3790 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3791 pFormat += 2;
3793 pStubMsg->Memory = pMemory;
3795 if (conf_array)
3797 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3798 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3799 conf_array);
3801 /* these could be changed in ComplexMarshall so save them for later */
3802 max_count = pStubMsg->MaxCount;
3803 count = pStubMsg->ActualCount;
3804 offset = pStubMsg->Offset;
3807 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3809 if (conf_array)
3811 pStubMsg->MaxCount = max_count;
3812 pStubMsg->ActualCount = count;
3813 pStubMsg->Offset = offset;
3814 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3815 TRUE /* fHasPointers */);
3818 pStubMsg->Memory = OldMemory;
3820 if(pointer_length_set)
3822 pStubMsg->BufferLength = pStubMsg->PointerLength;
3823 pStubMsg->PointerLength = 0;
3828 /***********************************************************************
3829 * NdrComplexStructMemorySize [RPCRT4.@]
3831 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3832 PFORMAT_STRING pFormat)
3834 unsigned size = *(const WORD*)(pFormat+2);
3835 PFORMAT_STRING conf_array = NULL;
3836 PFORMAT_STRING pointer_desc = NULL;
3837 ULONG count = 0;
3838 ULONG max_count = 0;
3839 ULONG offset = 0;
3841 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3843 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3845 pFormat += 4;
3846 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3847 pFormat += 2;
3848 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3849 pFormat += 2;
3851 if (conf_array)
3853 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3855 /* these could be changed in ComplexStructMemorySize so save them for
3856 * later */
3857 max_count = pStubMsg->MaxCount;
3858 count = pStubMsg->ActualCount;
3859 offset = pStubMsg->Offset;
3862 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3864 if (conf_array)
3866 pStubMsg->MaxCount = max_count;
3867 pStubMsg->ActualCount = count;
3868 pStubMsg->Offset = offset;
3869 array_memory_size(conf_array[0], pStubMsg, conf_array,
3870 TRUE /* fHasPointers */);
3873 return size;
3876 /***********************************************************************
3877 * NdrComplexStructFree [RPCRT4.@]
3879 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3880 unsigned char *pMemory,
3881 PFORMAT_STRING pFormat)
3883 PFORMAT_STRING conf_array = NULL;
3884 PFORMAT_STRING pointer_desc = NULL;
3885 unsigned char *OldMemory = pStubMsg->Memory;
3887 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3889 pFormat += 4;
3890 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3891 pFormat += 2;
3892 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3893 pFormat += 2;
3895 pStubMsg->Memory = pMemory;
3897 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3899 if (conf_array)
3900 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3901 TRUE /* fHasPointers */);
3903 pStubMsg->Memory = OldMemory;
3906 /***********************************************************************
3907 * NdrConformantArrayMarshall [RPCRT4.@]
3909 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3910 unsigned char *pMemory,
3911 PFORMAT_STRING pFormat)
3913 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3914 if (pFormat[0] != RPC_FC_CARRAY)
3916 ERR("invalid format = 0x%x\n", pFormat[0]);
3917 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3920 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory,
3921 pFormat);
3922 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3923 TRUE /* fHasPointers */);
3925 return NULL;
3928 /***********************************************************************
3929 * NdrConformantArrayUnmarshall [RPCRT4.@]
3931 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3932 unsigned char **ppMemory,
3933 PFORMAT_STRING pFormat,
3934 unsigned char fMustAlloc)
3936 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3937 if (pFormat[0] != RPC_FC_CARRAY)
3939 ERR("invalid format = 0x%x\n", pFormat[0]);
3940 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3943 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3944 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat,
3945 fMustAlloc,
3946 TRUE /* fUseBufferMemoryServer */,
3947 TRUE /* fUnmarshall */);
3949 return NULL;
3952 /***********************************************************************
3953 * NdrConformantArrayBufferSize [RPCRT4.@]
3955 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3956 unsigned char *pMemory,
3957 PFORMAT_STRING pFormat)
3959 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3960 if (pFormat[0] != RPC_FC_CARRAY)
3962 ERR("invalid format = 0x%x\n", pFormat[0]);
3963 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3966 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat);
3967 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3968 TRUE /* fHasPointers */);
3971 /***********************************************************************
3972 * NdrConformantArrayMemorySize [RPCRT4.@]
3974 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3975 PFORMAT_STRING pFormat)
3977 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3978 if (pFormat[0] != RPC_FC_CARRAY)
3980 ERR("invalid format = 0x%x\n", pFormat[0]);
3981 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3984 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3985 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
3987 return pStubMsg->MemorySize;
3990 /***********************************************************************
3991 * NdrConformantArrayFree [RPCRT4.@]
3993 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3994 unsigned char *pMemory,
3995 PFORMAT_STRING pFormat)
3997 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3998 if (pFormat[0] != RPC_FC_CARRAY)
4000 ERR("invalid format = 0x%x\n", pFormat[0]);
4001 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4004 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
4005 TRUE /* fHasPointers */);
4009 /***********************************************************************
4010 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
4012 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
4013 unsigned char* pMemory,
4014 PFORMAT_STRING pFormat )
4016 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4018 if (pFormat[0] != RPC_FC_CVARRAY)
4020 ERR("invalid format type %x\n", pFormat[0]);
4021 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4022 return NULL;
4025 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
4026 pFormat);
4027 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory,
4028 pFormat, TRUE /* fHasPointers */);
4030 return NULL;
4034 /***********************************************************************
4035 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
4037 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
4038 unsigned char** ppMemory,
4039 PFORMAT_STRING pFormat,
4040 unsigned char fMustAlloc )
4042 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4044 if (pFormat[0] != RPC_FC_CVARRAY)
4046 ERR("invalid format type %x\n", pFormat[0]);
4047 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4048 return NULL;
4051 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
4052 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory,
4053 pFormat, fMustAlloc,
4054 TRUE /* fUseBufferMemoryServer */,
4055 TRUE /* fUnmarshall */);
4057 return NULL;
4061 /***********************************************************************
4062 * NdrConformantVaryingArrayFree [RPCRT4.@]
4064 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
4065 unsigned char* pMemory,
4066 PFORMAT_STRING pFormat )
4068 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4070 if (pFormat[0] != RPC_FC_CVARRAY)
4072 ERR("invalid format type %x\n", pFormat[0]);
4073 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4074 return;
4077 array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
4078 TRUE /* fHasPointers */);
4082 /***********************************************************************
4083 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
4085 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
4086 unsigned char* pMemory, PFORMAT_STRING pFormat )
4088 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4090 if (pFormat[0] != RPC_FC_CVARRAY)
4092 ERR("invalid format type %x\n", pFormat[0]);
4093 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4094 return;
4097 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
4098 pFormat);
4099 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
4100 TRUE /* fHasPointers */);
4104 /***********************************************************************
4105 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
4107 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
4108 PFORMAT_STRING pFormat )
4110 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4112 if (pFormat[0] != RPC_FC_CVARRAY)
4114 ERR("invalid format type %x\n", pFormat[0]);
4115 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4116 return pStubMsg->MemorySize;
4119 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
4120 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat,
4121 TRUE /* fHasPointers */);
4123 return pStubMsg->MemorySize;
4127 /***********************************************************************
4128 * NdrComplexArrayMarshall [RPCRT4.@]
4130 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4131 unsigned char *pMemory,
4132 PFORMAT_STRING pFormat)
4134 BOOL pointer_buffer_mark_set = FALSE;
4136 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4138 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4140 ERR("invalid format type %x\n", pFormat[0]);
4141 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4142 return NULL;
4145 if (!pStubMsg->PointerBufferMark)
4147 /* save buffer fields that may be changed by buffer sizer functions
4148 * and that may be needed later on */
4149 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4150 ULONG saved_buffer_length = pStubMsg->BufferLength;
4151 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4152 ULONG saved_offset = pStubMsg->Offset;
4153 ULONG saved_actual_count = pStubMsg->ActualCount;
4155 /* get the buffer pointer after complex array data, but before
4156 * pointer data */
4157 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
4158 pStubMsg->IgnoreEmbeddedPointers = 1;
4159 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4160 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4162 /* save it for use by embedded pointer code later */
4163 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
4164 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer));
4165 pointer_buffer_mark_set = TRUE;
4167 /* restore fields */
4168 pStubMsg->ActualCount = saved_actual_count;
4169 pStubMsg->Offset = saved_offset;
4170 pStubMsg->MaxCount = saved_max_count;
4171 pStubMsg->BufferLength = saved_buffer_length;
4174 array_compute_and_write_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4175 array_write_variance_and_marshall(RPC_FC_BOGUS_ARRAY, pStubMsg,
4176 pMemory, pFormat, TRUE /* fHasPointers */);
4178 STD_OVERFLOW_CHECK(pStubMsg);
4180 if (pointer_buffer_mark_set)
4182 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4183 pStubMsg->PointerBufferMark = NULL;
4186 return NULL;
4189 /***********************************************************************
4190 * NdrComplexArrayUnmarshall [RPCRT4.@]
4192 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4193 unsigned char **ppMemory,
4194 PFORMAT_STRING pFormat,
4195 unsigned char fMustAlloc)
4197 unsigned char *saved_buffer;
4198 BOOL pointer_buffer_mark_set = FALSE;
4199 int saved_ignore_embedded;
4201 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4203 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4205 ERR("invalid format type %x\n", pFormat[0]);
4206 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4207 return NULL;
4210 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4211 /* save buffer pointer */
4212 saved_buffer = pStubMsg->Buffer;
4213 /* get the buffer pointer after complex array data, but before
4214 * pointer data */
4215 pStubMsg->IgnoreEmbeddedPointers = 1;
4216 pStubMsg->MemorySize = 0;
4217 NdrComplexArrayMemorySize(pStubMsg, pFormat);
4218 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4220 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - saved_buffer));
4221 if (!pStubMsg->PointerBufferMark)
4223 /* save it for use by embedded pointer code later */
4224 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4225 pointer_buffer_mark_set = TRUE;
4227 /* restore the original buffer */
4228 pStubMsg->Buffer = saved_buffer;
4230 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
4231 array_read_variance_and_unmarshall(RPC_FC_BOGUS_ARRAY, pStubMsg, ppMemory, pFormat, fMustAlloc,
4232 TRUE /* fUseBufferMemoryServer */, TRUE /* fUnmarshall */);
4234 if (pointer_buffer_mark_set)
4236 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4237 pStubMsg->PointerBufferMark = NULL;
4240 return NULL;
4243 /***********************************************************************
4244 * NdrComplexArrayBufferSize [RPCRT4.@]
4246 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4247 unsigned char *pMemory,
4248 PFORMAT_STRING pFormat)
4250 int pointer_length_set = 0;
4252 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4254 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4256 ERR("invalid format type %x\n", pFormat[0]);
4257 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4258 return;
4261 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
4263 /* save buffer fields that may be changed by buffer sizer functions
4264 * and that may be needed later on */
4265 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4266 ULONG saved_buffer_length = pStubMsg->BufferLength;
4267 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4268 ULONG saved_offset = pStubMsg->Offset;
4269 ULONG saved_actual_count = pStubMsg->ActualCount;
4271 /* get the buffer pointer after complex array data, but before
4272 * pointer data */
4273 pStubMsg->IgnoreEmbeddedPointers = 1;
4274 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4275 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4277 /* save it for use by embedded pointer code later */
4278 pStubMsg->PointerLength = pStubMsg->BufferLength;
4279 pointer_length_set = 1;
4281 /* restore fields */
4282 pStubMsg->ActualCount = saved_actual_count;
4283 pStubMsg->Offset = saved_offset;
4284 pStubMsg->MaxCount = saved_max_count;
4285 pStubMsg->BufferLength = saved_buffer_length;
4288 array_compute_and_size_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4289 array_buffer_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat, TRUE /* fHasPointers */);
4291 if(pointer_length_set)
4293 pStubMsg->BufferLength = pStubMsg->PointerLength;
4294 pStubMsg->PointerLength = 0;
4298 /***********************************************************************
4299 * NdrComplexArrayMemorySize [RPCRT4.@]
4301 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4302 PFORMAT_STRING pFormat)
4304 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4306 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4308 ERR("invalid format type %x\n", pFormat[0]);
4309 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4310 return 0;
4313 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
4314 array_memory_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
4315 return pStubMsg->MemorySize;
4318 /***********************************************************************
4319 * NdrComplexArrayFree [RPCRT4.@]
4321 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4322 unsigned char *pMemory,
4323 PFORMAT_STRING pFormat)
4325 ULONG i, count, def;
4327 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4329 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4331 ERR("invalid format type %x\n", pFormat[0]);
4332 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4333 return;
4336 def = *(const WORD*)&pFormat[2];
4337 pFormat += 4;
4339 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4340 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4342 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4343 TRACE("variance = %d\n", pStubMsg->ActualCount);
4345 count = pStubMsg->ActualCount;
4346 for (i = 0; i < count; i++)
4347 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4350 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4351 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4352 USER_MARSHAL_CB *umcb)
4354 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4355 pStubMsg->RpcMsg->DataRepresentation);
4356 umcb->pStubMsg = pStubMsg;
4357 umcb->pReserve = NULL;
4358 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4359 umcb->CBType = cbtype;
4360 umcb->pFormat = pFormat;
4361 umcb->pTypeFormat = NULL /* FIXME */;
4364 #define USER_MARSHAL_PTR_PREFIX \
4365 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4366 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4368 /***********************************************************************
4369 * NdrUserMarshalMarshall [RPCRT4.@]
4371 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4372 unsigned char *pMemory,
4373 PFORMAT_STRING pFormat)
4375 unsigned flags = pFormat[1];
4376 unsigned index = *(const WORD*)&pFormat[2];
4377 unsigned char *saved_buffer = NULL;
4378 USER_MARSHAL_CB umcb;
4380 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4381 TRACE("index=%d\n", index);
4383 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4385 if (flags & USER_MARSHAL_POINTER)
4387 align_pointer_clear(&pStubMsg->Buffer, 4);
4388 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4389 pStubMsg->Buffer += 4;
4390 if (pStubMsg->PointerBufferMark)
4392 saved_buffer = pStubMsg->Buffer;
4393 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4394 pStubMsg->PointerBufferMark = NULL;
4396 align_pointer_clear(&pStubMsg->Buffer, 8);
4398 else
4399 align_pointer_clear(&pStubMsg->Buffer, (flags & 0xf) + 1);
4401 pStubMsg->Buffer =
4402 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4403 &umcb.Flags, pStubMsg->Buffer, pMemory);
4405 if (saved_buffer)
4407 STD_OVERFLOW_CHECK(pStubMsg);
4408 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4409 pStubMsg->Buffer = saved_buffer;
4412 STD_OVERFLOW_CHECK(pStubMsg);
4414 return NULL;
4417 /***********************************************************************
4418 * NdrUserMarshalUnmarshall [RPCRT4.@]
4420 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4421 unsigned char **ppMemory,
4422 PFORMAT_STRING pFormat,
4423 unsigned char fMustAlloc)
4425 unsigned flags = pFormat[1];
4426 unsigned index = *(const WORD*)&pFormat[2];
4427 DWORD memsize = *(const WORD*)&pFormat[4];
4428 unsigned char *saved_buffer = NULL;
4429 USER_MARSHAL_CB umcb;
4431 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4432 TRACE("index=%d\n", index);
4434 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4436 if (flags & USER_MARSHAL_POINTER)
4438 align_pointer(&pStubMsg->Buffer, 4);
4439 /* skip pointer prefix */
4440 pStubMsg->Buffer += 4;
4441 if (pStubMsg->PointerBufferMark)
4443 saved_buffer = pStubMsg->Buffer;
4444 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4445 pStubMsg->PointerBufferMark = NULL;
4447 align_pointer(&pStubMsg->Buffer, 8);
4449 else
4450 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4452 if (!fMustAlloc && !*ppMemory)
4453 fMustAlloc = TRUE;
4454 if (fMustAlloc)
4456 *ppMemory = NdrAllocate(pStubMsg, memsize);
4457 memset(*ppMemory, 0, memsize);
4460 pStubMsg->Buffer =
4461 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4462 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4464 if (saved_buffer)
4466 STD_OVERFLOW_CHECK(pStubMsg);
4467 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4468 pStubMsg->Buffer = saved_buffer;
4471 return NULL;
4474 /***********************************************************************
4475 * NdrUserMarshalBufferSize [RPCRT4.@]
4477 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4478 unsigned char *pMemory,
4479 PFORMAT_STRING pFormat)
4481 unsigned flags = pFormat[1];
4482 unsigned index = *(const WORD*)&pFormat[2];
4483 DWORD bufsize = *(const WORD*)&pFormat[6];
4484 USER_MARSHAL_CB umcb;
4485 ULONG saved_buffer_length = 0;
4487 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4488 TRACE("index=%d\n", index);
4490 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4492 if (flags & USER_MARSHAL_POINTER)
4494 align_length(&pStubMsg->BufferLength, 4);
4495 /* skip pointer prefix */
4496 safe_buffer_length_increment(pStubMsg, 4);
4497 if (pStubMsg->IgnoreEmbeddedPointers)
4498 return;
4499 if (pStubMsg->PointerLength)
4501 saved_buffer_length = pStubMsg->BufferLength;
4502 pStubMsg->BufferLength = pStubMsg->PointerLength;
4503 pStubMsg->PointerLength = 0;
4505 align_length(&pStubMsg->BufferLength, 8);
4507 else
4508 align_length(&pStubMsg->BufferLength, (flags & 0xf) + 1);
4510 if (bufsize) {
4511 TRACE("size=%d\n", bufsize);
4512 safe_buffer_length_increment(pStubMsg, bufsize);
4514 else
4515 pStubMsg->BufferLength =
4516 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4517 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4519 if (saved_buffer_length)
4521 pStubMsg->PointerLength = pStubMsg->BufferLength;
4522 pStubMsg->BufferLength = saved_buffer_length;
4527 /***********************************************************************
4528 * NdrUserMarshalMemorySize [RPCRT4.@]
4530 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4531 PFORMAT_STRING pFormat)
4533 unsigned flags = pFormat[1];
4534 unsigned index = *(const WORD*)&pFormat[2];
4535 DWORD memsize = *(const WORD*)&pFormat[4];
4536 DWORD bufsize = *(const WORD*)&pFormat[6];
4538 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4539 TRACE("index=%d\n", index);
4541 pStubMsg->MemorySize += memsize;
4543 if (flags & USER_MARSHAL_POINTER)
4545 align_pointer(&pStubMsg->Buffer, 4);
4546 /* skip pointer prefix */
4547 pStubMsg->Buffer += 4;
4548 if (pStubMsg->IgnoreEmbeddedPointers)
4549 return pStubMsg->MemorySize;
4550 align_pointer(&pStubMsg->Buffer, 8);
4552 else
4553 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4555 if (!bufsize)
4556 FIXME("not implemented for varying buffer size\n");
4558 pStubMsg->Buffer += bufsize;
4560 return pStubMsg->MemorySize;
4563 /***********************************************************************
4564 * NdrUserMarshalFree [RPCRT4.@]
4566 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4567 unsigned char *pMemory,
4568 PFORMAT_STRING pFormat)
4570 /* unsigned flags = pFormat[1]; */
4571 unsigned index = *(const WORD*)&pFormat[2];
4572 USER_MARSHAL_CB umcb;
4574 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4575 TRACE("index=%d\n", index);
4577 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4579 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4580 &umcb.Flags, pMemory);
4583 /***********************************************************************
4584 * NdrGetUserMarshalInfo [RPCRT4.@]
4586 RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi)
4588 USER_MARSHAL_CB *umcb = CONTAINING_RECORD(flags, USER_MARSHAL_CB, Flags);
4590 TRACE("(%p,%u,%p)\n", flags, level, umi);
4592 if (level != 1)
4593 return RPC_S_INVALID_ARG;
4595 memset(&umi->u1.Level1, 0, sizeof(umi->u1.Level1));
4596 umi->InformationLevel = level;
4598 if (umcb->Signature != USER_MARSHAL_CB_SIGNATURE)
4599 return RPC_S_INVALID_ARG;
4601 umi->u1.Level1.pfnAllocate = umcb->pStubMsg->pfnAllocate;
4602 umi->u1.Level1.pfnFree = umcb->pStubMsg->pfnFree;
4603 umi->u1.Level1.pRpcChannelBuffer = umcb->pStubMsg->pRpcChannelBuffer;
4605 switch (umcb->CBType)
4607 case USER_MARSHAL_CB_MARSHALL:
4608 case USER_MARSHAL_CB_UNMARSHALL:
4610 RPC_MESSAGE *msg = umcb->pStubMsg->RpcMsg;
4611 unsigned char *buffer_start = msg->Buffer;
4612 unsigned char *buffer_end =
4613 (unsigned char *)msg->Buffer + msg->BufferLength;
4615 if (umcb->pStubMsg->Buffer < buffer_start ||
4616 umcb->pStubMsg->Buffer > buffer_end)
4617 return ERROR_INVALID_USER_BUFFER;
4619 umi->u1.Level1.Buffer = umcb->pStubMsg->Buffer;
4620 umi->u1.Level1.BufferSize = buffer_end - umcb->pStubMsg->Buffer;
4621 break;
4623 case USER_MARSHAL_CB_BUFFER_SIZE:
4624 case USER_MARSHAL_CB_FREE:
4625 break;
4626 default:
4627 WARN("unrecognised CBType %d\n", umcb->CBType);
4630 return RPC_S_OK;
4633 /***********************************************************************
4634 * NdrClearOutParameters [RPCRT4.@]
4636 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4637 PFORMAT_STRING pFormat,
4638 void *ArgAddr)
4640 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4643 /***********************************************************************
4644 * NdrConvert [RPCRT4.@]
4646 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4648 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4649 /* FIXME: since this stub doesn't do any converting, the proper behavior
4650 is to raise an exception */
4653 /***********************************************************************
4654 * NdrConvert2 [RPCRT4.@]
4656 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4658 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4659 pStubMsg, pFormat, NumberParams);
4660 /* FIXME: since this stub doesn't do any converting, the proper behavior
4661 is to raise an exception */
4664 #include "pshpack1.h"
4665 typedef struct _NDR_CSTRUCT_FORMAT
4667 unsigned char type;
4668 unsigned char alignment;
4669 unsigned short memory_size;
4670 short offset_to_array_description;
4671 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4672 #include "poppack.h"
4674 /***********************************************************************
4675 * NdrConformantStructMarshall [RPCRT4.@]
4677 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4678 unsigned char *pMemory,
4679 PFORMAT_STRING pFormat)
4681 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4682 PFORMAT_STRING pCArrayFormat;
4683 ULONG esize, bufsize;
4685 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4687 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4688 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4690 ERR("invalid format type %x\n", pCStructFormat->type);
4691 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4692 return NULL;
4695 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4696 pCStructFormat->offset_to_array_description;
4697 if (*pCArrayFormat != RPC_FC_CARRAY)
4699 ERR("invalid array format type %x\n", pCStructFormat->type);
4700 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4701 return NULL;
4703 esize = *(const WORD*)(pCArrayFormat+2);
4705 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4706 pCArrayFormat + 4, 0);
4708 WriteConformance(pStubMsg);
4710 align_pointer_clear(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4712 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4714 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4715 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4717 ERR("integer overflow of memory_size %u with bufsize %u\n",
4718 pCStructFormat->memory_size, bufsize);
4719 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4721 /* copy constant sized part of struct */
4722 pStubMsg->BufferMark = pStubMsg->Buffer;
4723 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4725 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4726 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4728 return NULL;
4731 /***********************************************************************
4732 * NdrConformantStructUnmarshall [RPCRT4.@]
4734 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4735 unsigned char **ppMemory,
4736 PFORMAT_STRING pFormat,
4737 unsigned char fMustAlloc)
4739 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4740 PFORMAT_STRING pCArrayFormat;
4741 ULONG esize, bufsize;
4742 unsigned char *saved_buffer;
4744 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4746 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4747 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4749 ERR("invalid format type %x\n", pCStructFormat->type);
4750 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4751 return NULL;
4753 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4754 pCStructFormat->offset_to_array_description;
4755 if (*pCArrayFormat != RPC_FC_CARRAY)
4757 ERR("invalid array format type %x\n", pCStructFormat->type);
4758 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4759 return NULL;
4761 esize = *(const WORD*)(pCArrayFormat+2);
4763 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4765 align_pointer(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4767 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4769 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4770 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4772 ERR("integer overflow of memory_size %u with bufsize %u\n",
4773 pCStructFormat->memory_size, bufsize);
4774 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4777 if (fMustAlloc)
4779 SIZE_T size = pCStructFormat->memory_size + bufsize;
4780 *ppMemory = NdrAllocate(pStubMsg, size);
4782 else
4784 if (!pStubMsg->IsClient && !*ppMemory)
4785 /* for servers, we just point straight into the RPC buffer */
4786 *ppMemory = pStubMsg->Buffer;
4789 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4790 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4791 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4792 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4794 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4795 if (*ppMemory != saved_buffer)
4796 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4798 return NULL;
4801 /***********************************************************************
4802 * NdrConformantStructBufferSize [RPCRT4.@]
4804 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4805 unsigned char *pMemory,
4806 PFORMAT_STRING pFormat)
4808 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4809 PFORMAT_STRING pCArrayFormat;
4810 ULONG esize;
4812 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4814 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4815 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4817 ERR("invalid format type %x\n", pCStructFormat->type);
4818 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4819 return;
4821 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4822 pCStructFormat->offset_to_array_description;
4823 if (*pCArrayFormat != RPC_FC_CARRAY)
4825 ERR("invalid array format type %x\n", pCStructFormat->type);
4826 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4827 return;
4829 esize = *(const WORD*)(pCArrayFormat+2);
4831 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4832 SizeConformance(pStubMsg);
4834 align_length(&pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4836 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4838 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4839 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4841 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4842 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4845 /***********************************************************************
4846 * NdrConformantStructMemorySize [RPCRT4.@]
4848 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4849 PFORMAT_STRING pFormat)
4851 FIXME("stub\n");
4852 return 0;
4855 /***********************************************************************
4856 * NdrConformantStructFree [RPCRT4.@]
4858 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4859 unsigned char *pMemory,
4860 PFORMAT_STRING pFormat)
4862 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4863 PFORMAT_STRING pCArrayFormat;
4865 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4867 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4868 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4870 ERR("invalid format type %x\n", pCStructFormat->type);
4871 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4872 return;
4875 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4876 pCStructFormat->offset_to_array_description;
4877 if (*pCArrayFormat != RPC_FC_CARRAY)
4879 ERR("invalid array format type %x\n", pCStructFormat->type);
4880 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4881 return;
4884 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4885 pCArrayFormat + 4, 0);
4887 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4889 /* copy constant sized part of struct */
4890 pStubMsg->BufferMark = pStubMsg->Buffer;
4892 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4893 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4896 /***********************************************************************
4897 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4899 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4900 unsigned char *pMemory,
4901 PFORMAT_STRING pFormat)
4903 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4904 PFORMAT_STRING pCVArrayFormat;
4906 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4908 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4909 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4911 ERR("invalid format type %x\n", pCVStructFormat->type);
4912 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4913 return NULL;
4916 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4917 pCVStructFormat->offset_to_array_description;
4919 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4920 pMemory + pCVStructFormat->memory_size,
4921 pCVArrayFormat);
4923 align_pointer_clear(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4925 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4927 /* write constant sized part */
4928 pStubMsg->BufferMark = pStubMsg->Buffer;
4929 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4931 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4932 pMemory + pCVStructFormat->memory_size,
4933 pCVArrayFormat, FALSE /* fHasPointers */);
4935 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4937 return NULL;
4940 /***********************************************************************
4941 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4943 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4944 unsigned char **ppMemory,
4945 PFORMAT_STRING pFormat,
4946 unsigned char fMustAlloc)
4948 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4949 PFORMAT_STRING pCVArrayFormat;
4950 ULONG memsize, bufsize;
4951 unsigned char *saved_buffer, *saved_array_buffer;
4952 ULONG offset;
4953 unsigned char *array_memory;
4955 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4957 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4958 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4960 ERR("invalid format type %x\n", pCVStructFormat->type);
4961 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4962 return NULL;
4965 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4966 pCVStructFormat->offset_to_array_description;
4968 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4969 pCVArrayFormat);
4971 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4973 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4975 /* work out how much memory to allocate if we need to do so */
4976 if (!fMustAlloc && !*ppMemory)
4977 fMustAlloc = TRUE;
4978 if (fMustAlloc)
4980 SIZE_T size = pCVStructFormat->memory_size + memsize;
4981 *ppMemory = NdrAllocate(pStubMsg, size);
4984 /* mark the start of the constant data */
4985 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4986 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4988 array_memory = *ppMemory + pCVStructFormat->memory_size;
4989 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
4990 &array_memory, pCVArrayFormat,
4991 FALSE /* fMustAlloc */,
4992 FALSE /* fUseServerBufferMemory */,
4993 FALSE /* fUnmarshall */);
4995 /* save offset in case unmarshalling pointers changes it */
4996 offset = pStubMsg->Offset;
4998 /* mark the start of the array data */
4999 saved_array_buffer = pStubMsg->Buffer;
5000 safe_buffer_increment(pStubMsg, bufsize);
5002 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5004 /* copy the constant data */
5005 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
5006 /* copy the array data */
5007 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
5008 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
5009 saved_array_buffer, bufsize);
5011 if (*pCVArrayFormat == RPC_FC_C_CSTRING)
5012 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
5013 else if (*pCVArrayFormat == RPC_FC_C_WSTRING)
5014 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
5016 return NULL;
5019 /***********************************************************************
5020 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
5022 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5023 unsigned char *pMemory,
5024 PFORMAT_STRING pFormat)
5026 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5027 PFORMAT_STRING pCVArrayFormat;
5029 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5031 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5032 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5034 ERR("invalid format type %x\n", pCVStructFormat->type);
5035 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5036 return;
5039 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5040 pCVStructFormat->offset_to_array_description;
5041 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
5042 pMemory + pCVStructFormat->memory_size,
5043 pCVArrayFormat);
5045 align_length(&pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
5047 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5049 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
5051 array_buffer_size(*pCVArrayFormat, pStubMsg,
5052 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5053 FALSE /* fHasPointers */);
5055 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5058 /***********************************************************************
5059 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
5061 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5062 PFORMAT_STRING pFormat)
5064 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5065 PFORMAT_STRING pCVArrayFormat;
5067 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5069 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5070 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5072 ERR("invalid format type %x\n", pCVStructFormat->type);
5073 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5074 return 0;
5077 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5078 pCVStructFormat->offset_to_array_description;
5079 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
5081 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
5083 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5085 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
5086 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
5087 FALSE /* fHasPointers */);
5089 pStubMsg->MemorySize += pCVStructFormat->memory_size;
5091 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5093 return pStubMsg->MemorySize;
5096 /***********************************************************************
5097 * NdrConformantVaryingStructFree [RPCRT4.@]
5099 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
5100 unsigned char *pMemory,
5101 PFORMAT_STRING pFormat)
5103 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5104 PFORMAT_STRING pCVArrayFormat;
5106 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5108 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5109 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5111 ERR("invalid format type %x\n", pCVStructFormat->type);
5112 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5113 return;
5116 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5117 pCVStructFormat->offset_to_array_description;
5118 array_free(*pCVArrayFormat, pStubMsg,
5119 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5120 FALSE /* fHasPointers */);
5122 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5124 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5127 #include "pshpack1.h"
5128 typedef struct
5130 unsigned char type;
5131 unsigned char alignment;
5132 unsigned short total_size;
5133 } NDR_SMFARRAY_FORMAT;
5135 typedef struct
5137 unsigned char type;
5138 unsigned char alignment;
5139 ULONG total_size;
5140 } NDR_LGFARRAY_FORMAT;
5141 #include "poppack.h"
5143 /***********************************************************************
5144 * NdrFixedArrayMarshall [RPCRT4.@]
5146 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5147 unsigned char *pMemory,
5148 PFORMAT_STRING pFormat)
5150 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5151 ULONG total_size;
5153 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5155 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5156 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5158 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5159 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5160 return NULL;
5163 align_pointer_clear(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5165 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5167 total_size = pSmFArrayFormat->total_size;
5168 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5170 else
5172 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5173 total_size = pLgFArrayFormat->total_size;
5174 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5177 pStubMsg->BufferMark = pStubMsg->Buffer;
5178 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
5180 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5182 return NULL;
5185 /***********************************************************************
5186 * NdrFixedArrayUnmarshall [RPCRT4.@]
5188 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5189 unsigned char **ppMemory,
5190 PFORMAT_STRING pFormat,
5191 unsigned char fMustAlloc)
5193 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5194 ULONG total_size;
5195 unsigned char *saved_buffer;
5197 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5199 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5200 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5202 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5203 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5204 return NULL;
5207 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5209 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5211 total_size = pSmFArrayFormat->total_size;
5212 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5214 else
5216 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5217 total_size = pLgFArrayFormat->total_size;
5218 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5221 if (fMustAlloc)
5222 *ppMemory = NdrAllocate(pStubMsg, total_size);
5223 else
5225 if (!pStubMsg->IsClient && !*ppMemory)
5226 /* for servers, we just point straight into the RPC buffer */
5227 *ppMemory = pStubMsg->Buffer;
5230 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5231 safe_buffer_increment(pStubMsg, total_size);
5232 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5234 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
5235 if (*ppMemory != saved_buffer)
5236 memcpy(*ppMemory, saved_buffer, total_size);
5238 return NULL;
5241 /***********************************************************************
5242 * NdrFixedArrayBufferSize [RPCRT4.@]
5244 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5245 unsigned char *pMemory,
5246 PFORMAT_STRING pFormat)
5248 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5249 ULONG total_size;
5251 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5253 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5254 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5256 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5257 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5258 return;
5261 align_length(&pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
5263 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5265 total_size = pSmFArrayFormat->total_size;
5266 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5268 else
5270 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5271 total_size = pLgFArrayFormat->total_size;
5272 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5274 safe_buffer_length_increment(pStubMsg, total_size);
5276 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5279 /***********************************************************************
5280 * NdrFixedArrayMemorySize [RPCRT4.@]
5282 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5283 PFORMAT_STRING pFormat)
5285 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5286 ULONG total_size;
5288 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5290 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5291 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5293 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5294 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5295 return 0;
5298 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5300 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5302 total_size = pSmFArrayFormat->total_size;
5303 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5305 else
5307 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5308 total_size = pLgFArrayFormat->total_size;
5309 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5311 pStubMsg->BufferMark = pStubMsg->Buffer;
5312 safe_buffer_increment(pStubMsg, total_size);
5313 pStubMsg->MemorySize += total_size;
5315 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5317 return total_size;
5320 /***********************************************************************
5321 * NdrFixedArrayFree [RPCRT4.@]
5323 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5324 unsigned char *pMemory,
5325 PFORMAT_STRING pFormat)
5327 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5329 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5331 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5332 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5334 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5335 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5336 return;
5339 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5340 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5341 else
5343 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5344 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5347 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5350 /***********************************************************************
5351 * NdrVaryingArrayMarshall [RPCRT4.@]
5353 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5354 unsigned char *pMemory,
5355 PFORMAT_STRING pFormat)
5357 unsigned char alignment;
5358 DWORD elements, esize;
5359 ULONG bufsize;
5361 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5363 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5364 (pFormat[0] != RPC_FC_LGVARRAY))
5366 ERR("invalid format type %x\n", pFormat[0]);
5367 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5368 return NULL;
5371 alignment = pFormat[1] + 1;
5373 if (pFormat[0] == RPC_FC_SMVARRAY)
5375 pFormat += 2;
5376 pFormat += sizeof(WORD);
5377 elements = *(const WORD*)pFormat;
5378 pFormat += sizeof(WORD);
5380 else
5382 pFormat += 2;
5383 pFormat += sizeof(DWORD);
5384 elements = *(const DWORD*)pFormat;
5385 pFormat += sizeof(DWORD);
5388 esize = *(const WORD*)pFormat;
5389 pFormat += sizeof(WORD);
5391 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5392 if ((pStubMsg->ActualCount > elements) ||
5393 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5395 RpcRaiseException(RPC_S_INVALID_BOUND);
5396 return NULL;
5399 WriteVariance(pStubMsg);
5401 align_pointer_clear(&pStubMsg->Buffer, alignment);
5403 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5404 pStubMsg->BufferMark = pStubMsg->Buffer;
5405 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5407 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5409 return NULL;
5412 /***********************************************************************
5413 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5415 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5416 unsigned char **ppMemory,
5417 PFORMAT_STRING pFormat,
5418 unsigned char fMustAlloc)
5420 unsigned char alignment;
5421 DWORD size, elements, esize;
5422 ULONG bufsize;
5423 unsigned char *saved_buffer;
5424 ULONG offset;
5426 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5428 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5429 (pFormat[0] != RPC_FC_LGVARRAY))
5431 ERR("invalid format type %x\n", pFormat[0]);
5432 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5433 return NULL;
5436 alignment = pFormat[1] + 1;
5438 if (pFormat[0] == RPC_FC_SMVARRAY)
5440 pFormat += 2;
5441 size = *(const WORD*)pFormat;
5442 pFormat += sizeof(WORD);
5443 elements = *(const WORD*)pFormat;
5444 pFormat += sizeof(WORD);
5446 else
5448 pFormat += 2;
5449 size = *(const DWORD*)pFormat;
5450 pFormat += sizeof(DWORD);
5451 elements = *(const DWORD*)pFormat;
5452 pFormat += sizeof(DWORD);
5455 esize = *(const WORD*)pFormat;
5456 pFormat += sizeof(WORD);
5458 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5460 align_pointer(&pStubMsg->Buffer, alignment);
5462 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5463 offset = pStubMsg->Offset;
5465 if (!fMustAlloc && !*ppMemory)
5466 fMustAlloc = TRUE;
5467 if (fMustAlloc)
5468 *ppMemory = NdrAllocate(pStubMsg, size);
5469 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5470 safe_buffer_increment(pStubMsg, bufsize);
5472 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5474 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5476 return NULL;
5479 /***********************************************************************
5480 * NdrVaryingArrayBufferSize [RPCRT4.@]
5482 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5483 unsigned char *pMemory,
5484 PFORMAT_STRING pFormat)
5486 unsigned char alignment;
5487 DWORD elements, esize;
5489 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5491 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5492 (pFormat[0] != RPC_FC_LGVARRAY))
5494 ERR("invalid format type %x\n", pFormat[0]);
5495 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5496 return;
5499 alignment = pFormat[1] + 1;
5501 if (pFormat[0] == RPC_FC_SMVARRAY)
5503 pFormat += 2;
5504 pFormat += sizeof(WORD);
5505 elements = *(const WORD*)pFormat;
5506 pFormat += sizeof(WORD);
5508 else
5510 pFormat += 2;
5511 pFormat += sizeof(DWORD);
5512 elements = *(const DWORD*)pFormat;
5513 pFormat += sizeof(DWORD);
5516 esize = *(const WORD*)pFormat;
5517 pFormat += sizeof(WORD);
5519 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5520 if ((pStubMsg->ActualCount > elements) ||
5521 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5523 RpcRaiseException(RPC_S_INVALID_BOUND);
5524 return;
5527 SizeVariance(pStubMsg);
5529 align_length(&pStubMsg->BufferLength, alignment);
5531 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5533 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5536 /***********************************************************************
5537 * NdrVaryingArrayMemorySize [RPCRT4.@]
5539 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5540 PFORMAT_STRING pFormat)
5542 unsigned char alignment;
5543 DWORD size, elements, esize;
5545 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5547 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5548 (pFormat[0] != RPC_FC_LGVARRAY))
5550 ERR("invalid format type %x\n", pFormat[0]);
5551 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5552 return 0;
5555 alignment = pFormat[1] + 1;
5557 if (pFormat[0] == RPC_FC_SMVARRAY)
5559 pFormat += 2;
5560 size = *(const WORD*)pFormat;
5561 pFormat += sizeof(WORD);
5562 elements = *(const WORD*)pFormat;
5563 pFormat += sizeof(WORD);
5565 else
5567 pFormat += 2;
5568 size = *(const DWORD*)pFormat;
5569 pFormat += sizeof(DWORD);
5570 elements = *(const DWORD*)pFormat;
5571 pFormat += sizeof(DWORD);
5574 esize = *(const WORD*)pFormat;
5575 pFormat += sizeof(WORD);
5577 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5579 align_pointer(&pStubMsg->Buffer, alignment);
5581 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5582 pStubMsg->MemorySize += size;
5584 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5586 return pStubMsg->MemorySize;
5589 /***********************************************************************
5590 * NdrVaryingArrayFree [RPCRT4.@]
5592 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5593 unsigned char *pMemory,
5594 PFORMAT_STRING pFormat)
5596 DWORD elements;
5598 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5600 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5601 (pFormat[0] != RPC_FC_LGVARRAY))
5603 ERR("invalid format type %x\n", pFormat[0]);
5604 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5605 return;
5608 if (pFormat[0] == RPC_FC_SMVARRAY)
5610 pFormat += 2;
5611 pFormat += sizeof(WORD);
5612 elements = *(const WORD*)pFormat;
5613 pFormat += sizeof(WORD);
5615 else
5617 pFormat += 2;
5618 pFormat += sizeof(DWORD);
5619 elements = *(const DWORD*)pFormat;
5620 pFormat += sizeof(DWORD);
5623 pFormat += sizeof(WORD);
5625 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5626 if ((pStubMsg->ActualCount > elements) ||
5627 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5629 RpcRaiseException(RPC_S_INVALID_BOUND);
5630 return;
5633 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5636 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5638 switch (fc)
5640 case RPC_FC_BYTE:
5641 case RPC_FC_CHAR:
5642 case RPC_FC_SMALL:
5643 case RPC_FC_USMALL:
5644 return *pMemory;
5645 case RPC_FC_WCHAR:
5646 case RPC_FC_SHORT:
5647 case RPC_FC_USHORT:
5648 case RPC_FC_ENUM16:
5649 return *(const USHORT *)pMemory;
5650 case RPC_FC_LONG:
5651 case RPC_FC_ULONG:
5652 case RPC_FC_ENUM32:
5653 return *(const ULONG *)pMemory;
5654 case RPC_FC_INT3264:
5655 case RPC_FC_UINT3264:
5656 return *(const ULONG_PTR *)pMemory;
5657 default:
5658 FIXME("Unhandled base type: 0x%02x\n", fc);
5659 return 0;
5663 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5664 ULONG discriminant,
5665 PFORMAT_STRING pFormat)
5667 unsigned short num_arms, arm, type;
5669 num_arms = *(const SHORT*)pFormat & 0x0fff;
5670 pFormat += 2;
5671 for(arm = 0; arm < num_arms; arm++)
5673 if(discriminant == *(const ULONG*)pFormat)
5675 pFormat += 4;
5676 break;
5678 pFormat += 6;
5681 type = *(const unsigned short*)pFormat;
5682 TRACE("type %04x\n", type);
5683 if(arm == num_arms) /* default arm extras */
5685 if(type == 0xffff)
5687 ERR("no arm for 0x%x and no default case\n", discriminant);
5688 RpcRaiseException(RPC_S_INVALID_TAG);
5689 return NULL;
5691 if(type == 0)
5693 TRACE("falling back to empty default case for 0x%x\n", discriminant);
5694 return NULL;
5697 return pFormat;
5700 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5702 unsigned short type;
5704 pFormat += 2;
5706 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5707 if(!pFormat)
5708 return NULL;
5710 type = *(const unsigned short*)pFormat;
5711 if((type & 0xff00) == 0x8000)
5713 unsigned char basetype = LOBYTE(type);
5714 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5716 else
5718 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5719 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5720 if (m)
5722 unsigned char *saved_buffer = NULL;
5723 BOOL pointer_buffer_mark_set = FALSE;
5724 switch(*desc)
5726 case RPC_FC_RP:
5727 case RPC_FC_UP:
5728 case RPC_FC_OP:
5729 case RPC_FC_FP:
5730 align_pointer_clear(&pStubMsg->Buffer, 4);
5731 saved_buffer = pStubMsg->Buffer;
5732 if (pStubMsg->PointerBufferMark)
5734 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5735 pStubMsg->PointerBufferMark = NULL;
5736 pointer_buffer_mark_set = TRUE;
5738 else
5739 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5741 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5742 if (pointer_buffer_mark_set)
5744 STD_OVERFLOW_CHECK(pStubMsg);
5745 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5746 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5748 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5749 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5750 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5752 pStubMsg->Buffer = saved_buffer + 4;
5754 break;
5755 default:
5756 m(pStubMsg, pMemory, desc);
5759 else FIXME("no marshaller for embedded type %02x\n", *desc);
5761 return NULL;
5764 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5765 unsigned char **ppMemory,
5766 ULONG discriminant,
5767 PFORMAT_STRING pFormat,
5768 unsigned char fMustAlloc)
5770 unsigned short type;
5772 pFormat += 2;
5774 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5775 if(!pFormat)
5776 return NULL;
5778 type = *(const unsigned short*)pFormat;
5779 if((type & 0xff00) == 0x8000)
5781 unsigned char basetype = LOBYTE(type);
5782 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5784 else
5786 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5787 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5788 if (m)
5790 unsigned char *saved_buffer = NULL;
5791 BOOL pointer_buffer_mark_set = FALSE;
5792 switch(*desc)
5794 case RPC_FC_RP:
5795 case RPC_FC_UP:
5796 case RPC_FC_OP:
5797 case RPC_FC_FP:
5798 align_pointer(&pStubMsg->Buffer, 4);
5799 saved_buffer = pStubMsg->Buffer;
5800 if (pStubMsg->PointerBufferMark)
5802 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5803 pStubMsg->PointerBufferMark = NULL;
5804 pointer_buffer_mark_set = TRUE;
5806 else
5807 pStubMsg->Buffer += 4; /* for pointer ID */
5809 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5811 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5812 saved_buffer, pStubMsg->BufferEnd);
5813 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5816 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5817 if (pointer_buffer_mark_set)
5819 STD_OVERFLOW_CHECK(pStubMsg);
5820 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5821 pStubMsg->Buffer = saved_buffer + 4;
5823 break;
5824 default:
5825 m(pStubMsg, ppMemory, desc, fMustAlloc);
5828 else FIXME("no marshaller for embedded type %02x\n", *desc);
5830 return NULL;
5833 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5834 unsigned char *pMemory,
5835 ULONG discriminant,
5836 PFORMAT_STRING pFormat)
5838 unsigned short type;
5840 pFormat += 2;
5842 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5843 if(!pFormat)
5844 return;
5846 type = *(const unsigned short*)pFormat;
5847 if((type & 0xff00) == 0x8000)
5849 unsigned char basetype = LOBYTE(type);
5850 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5852 else
5854 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5855 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5856 if (m)
5858 switch(*desc)
5860 case RPC_FC_RP:
5861 case RPC_FC_UP:
5862 case RPC_FC_OP:
5863 case RPC_FC_FP:
5864 align_length(&pStubMsg->BufferLength, 4);
5865 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5866 if (!pStubMsg->IgnoreEmbeddedPointers)
5868 int saved_buffer_length = pStubMsg->BufferLength;
5869 pStubMsg->BufferLength = pStubMsg->PointerLength;
5870 pStubMsg->PointerLength = 0;
5871 if(!pStubMsg->BufferLength)
5872 ERR("BufferLength == 0??\n");
5873 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5874 pStubMsg->PointerLength = pStubMsg->BufferLength;
5875 pStubMsg->BufferLength = saved_buffer_length;
5877 break;
5878 default:
5879 m(pStubMsg, pMemory, desc);
5882 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5886 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5887 ULONG discriminant,
5888 PFORMAT_STRING pFormat)
5890 unsigned short type, size;
5892 size = *(const unsigned short*)pFormat;
5893 pStubMsg->Memory += size;
5894 pFormat += 2;
5896 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5897 if(!pFormat)
5898 return 0;
5900 type = *(const unsigned short*)pFormat;
5901 if((type & 0xff00) == 0x8000)
5903 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5905 else
5907 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5908 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5909 unsigned char *saved_buffer;
5910 if (m)
5912 switch(*desc)
5914 case RPC_FC_RP:
5915 case RPC_FC_UP:
5916 case RPC_FC_OP:
5917 case RPC_FC_FP:
5918 align_pointer(&pStubMsg->Buffer, 4);
5919 saved_buffer = pStubMsg->Buffer;
5920 safe_buffer_increment(pStubMsg, 4);
5921 align_length(&pStubMsg->MemorySize, sizeof(void *));
5922 pStubMsg->MemorySize += sizeof(void *);
5923 if (!pStubMsg->IgnoreEmbeddedPointers)
5924 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5925 break;
5926 default:
5927 return m(pStubMsg, desc);
5930 else FIXME("no marshaller for embedded type %02x\n", *desc);
5933 TRACE("size %d\n", size);
5934 return size;
5937 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5938 unsigned char *pMemory,
5939 ULONG discriminant,
5940 PFORMAT_STRING pFormat)
5942 unsigned short type;
5944 pFormat += 2;
5946 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5947 if(!pFormat)
5948 return;
5950 type = *(const unsigned short*)pFormat;
5951 if((type & 0xff00) != 0x8000)
5953 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5954 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5955 if (m)
5957 switch(*desc)
5959 case RPC_FC_RP:
5960 case RPC_FC_UP:
5961 case RPC_FC_OP:
5962 case RPC_FC_FP:
5963 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5964 break;
5965 default:
5966 m(pStubMsg, pMemory, desc);
5972 /***********************************************************************
5973 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5975 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5976 unsigned char *pMemory,
5977 PFORMAT_STRING pFormat)
5979 unsigned char switch_type;
5980 unsigned char increment;
5981 ULONG switch_value;
5983 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5984 pFormat++;
5986 switch_type = *pFormat & 0xf;
5987 increment = (*pFormat & 0xf0) >> 4;
5988 pFormat++;
5990 align_pointer_clear(&pStubMsg->Buffer, increment);
5992 switch_value = get_discriminant(switch_type, pMemory);
5993 TRACE("got switch value 0x%x\n", switch_value);
5995 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5996 pMemory += increment;
5998 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
6001 /***********************************************************************
6002 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
6004 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6005 unsigned char **ppMemory,
6006 PFORMAT_STRING pFormat,
6007 unsigned char fMustAlloc)
6009 unsigned char switch_type;
6010 unsigned char increment;
6011 ULONG switch_value;
6012 unsigned short size;
6013 unsigned char *pMemoryArm;
6015 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6016 pFormat++;
6018 switch_type = *pFormat & 0xf;
6019 increment = (*pFormat & 0xf0) >> 4;
6020 pFormat++;
6022 align_pointer(&pStubMsg->Buffer, increment);
6023 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6024 TRACE("got switch value 0x%x\n", switch_value);
6026 size = *(const unsigned short*)pFormat + increment;
6027 if (!fMustAlloc && !*ppMemory)
6028 fMustAlloc = TRUE;
6029 if (fMustAlloc)
6030 *ppMemory = NdrAllocate(pStubMsg, size);
6032 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6033 * since the arm is part of the memory block that is encompassed by
6034 * the whole union. Memory is forced to allocate when pointers
6035 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6036 * clearing the memory we pass in to the unmarshaller */
6037 if (fMustAlloc)
6038 memset(*ppMemory, 0, size);
6040 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
6041 pMemoryArm = *ppMemory + increment;
6043 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, FALSE);
6046 /***********************************************************************
6047 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
6049 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6050 unsigned char *pMemory,
6051 PFORMAT_STRING pFormat)
6053 unsigned char switch_type;
6054 unsigned char increment;
6055 ULONG switch_value;
6057 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6058 pFormat++;
6060 switch_type = *pFormat & 0xf;
6061 increment = (*pFormat & 0xf0) >> 4;
6062 pFormat++;
6064 align_length(&pStubMsg->BufferLength, increment);
6065 switch_value = get_discriminant(switch_type, pMemory);
6066 TRACE("got switch value 0x%x\n", switch_value);
6068 /* Add discriminant size */
6069 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
6070 pMemory += increment;
6072 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
6075 /***********************************************************************
6076 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
6078 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6079 PFORMAT_STRING pFormat)
6081 unsigned char switch_type;
6082 unsigned char increment;
6083 ULONG switch_value;
6085 switch_type = *pFormat & 0xf;
6086 increment = (*pFormat & 0xf0) >> 4;
6087 pFormat++;
6089 align_pointer(&pStubMsg->Buffer, increment);
6090 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6091 TRACE("got switch value 0x%x\n", switch_value);
6093 pStubMsg->Memory += increment;
6095 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
6098 /***********************************************************************
6099 * NdrEncapsulatedUnionFree [RPCRT4.@]
6101 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6102 unsigned char *pMemory,
6103 PFORMAT_STRING pFormat)
6105 unsigned char switch_type;
6106 unsigned char increment;
6107 ULONG switch_value;
6109 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6110 pFormat++;
6112 switch_type = *pFormat & 0xf;
6113 increment = (*pFormat & 0xf0) >> 4;
6114 pFormat++;
6116 switch_value = get_discriminant(switch_type, pMemory);
6117 TRACE("got switch value 0x%x\n", switch_value);
6119 pMemory += increment;
6121 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
6124 /***********************************************************************
6125 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
6127 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6128 unsigned char *pMemory,
6129 PFORMAT_STRING pFormat)
6131 unsigned char switch_type;
6133 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6134 pFormat++;
6136 switch_type = *pFormat;
6137 pFormat++;
6139 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6140 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6141 /* Marshall discriminant */
6142 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6144 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6147 static LONG unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
6148 PFORMAT_STRING *ppFormat)
6150 LONG discriminant = 0;
6152 switch(**ppFormat)
6154 case RPC_FC_BYTE:
6155 case RPC_FC_CHAR:
6156 case RPC_FC_SMALL:
6157 case RPC_FC_USMALL:
6159 UCHAR d;
6160 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6161 discriminant = d;
6162 break;
6164 case RPC_FC_WCHAR:
6165 case RPC_FC_SHORT:
6166 case RPC_FC_USHORT:
6167 case RPC_FC_ENUM16:
6169 USHORT d;
6170 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6171 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6172 discriminant = d;
6173 break;
6175 case RPC_FC_LONG:
6176 case RPC_FC_ULONG:
6178 ULONG d;
6179 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6180 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6181 discriminant = d;
6182 break;
6184 default:
6185 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
6187 (*ppFormat)++;
6189 if (pStubMsg->fHasNewCorrDesc)
6190 *ppFormat += 6;
6191 else
6192 *ppFormat += 4;
6193 return discriminant;
6196 /**********************************************************************
6197 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6199 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6200 unsigned char **ppMemory,
6201 PFORMAT_STRING pFormat,
6202 unsigned char fMustAlloc)
6204 LONG discriminant;
6205 unsigned short size;
6207 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6208 pFormat++;
6210 /* Unmarshall discriminant */
6211 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6212 TRACE("unmarshalled discriminant %x\n", discriminant);
6214 pFormat += *(const SHORT*)pFormat;
6216 size = *(const unsigned short*)pFormat;
6218 if (!fMustAlloc && !*ppMemory)
6219 fMustAlloc = TRUE;
6220 if (fMustAlloc)
6221 *ppMemory = NdrAllocate(pStubMsg, size);
6223 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6224 * since the arm is part of the memory block that is encompassed by
6225 * the whole union. Memory is forced to allocate when pointers
6226 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6227 * clearing the memory we pass in to the unmarshaller */
6228 if (fMustAlloc)
6229 memset(*ppMemory, 0, size);
6231 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, FALSE);
6234 /***********************************************************************
6235 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6237 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6238 unsigned char *pMemory,
6239 PFORMAT_STRING pFormat)
6241 unsigned char switch_type;
6243 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6244 pFormat++;
6246 switch_type = *pFormat;
6247 pFormat++;
6249 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6250 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6251 /* Add discriminant size */
6252 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6254 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6257 /***********************************************************************
6258 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6260 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6261 PFORMAT_STRING pFormat)
6263 ULONG discriminant;
6265 pFormat++;
6266 /* Unmarshall discriminant */
6267 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6268 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
6270 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
6273 /***********************************************************************
6274 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6276 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6277 unsigned char *pMemory,
6278 PFORMAT_STRING pFormat)
6280 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6281 pFormat++;
6282 pFormat++;
6284 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6285 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6287 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6290 /***********************************************************************
6291 * NdrByteCountPointerMarshall [RPCRT4.@]
6293 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6294 unsigned char *pMemory,
6295 PFORMAT_STRING pFormat)
6297 FIXME("stub\n");
6298 return NULL;
6301 /***********************************************************************
6302 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6304 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6305 unsigned char **ppMemory,
6306 PFORMAT_STRING pFormat,
6307 unsigned char fMustAlloc)
6309 FIXME("stub\n");
6310 return NULL;
6313 /***********************************************************************
6314 * NdrByteCountPointerBufferSize [RPCRT4.@]
6316 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6317 unsigned char *pMemory,
6318 PFORMAT_STRING pFormat)
6320 FIXME("stub\n");
6323 /***********************************************************************
6324 * NdrByteCountPointerMemorySize [internal]
6326 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6327 PFORMAT_STRING pFormat)
6329 FIXME("stub\n");
6330 return 0;
6333 /***********************************************************************
6334 * NdrByteCountPointerFree [RPCRT4.@]
6336 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6337 unsigned char *pMemory,
6338 PFORMAT_STRING pFormat)
6340 FIXME("stub\n");
6343 /***********************************************************************
6344 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6346 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6347 unsigned char *pMemory,
6348 PFORMAT_STRING pFormat)
6350 FIXME("stub\n");
6351 return NULL;
6354 /***********************************************************************
6355 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6357 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6358 unsigned char **ppMemory,
6359 PFORMAT_STRING pFormat,
6360 unsigned char fMustAlloc)
6362 FIXME("stub\n");
6363 return NULL;
6366 /***********************************************************************
6367 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6369 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6370 unsigned char *pMemory,
6371 PFORMAT_STRING pFormat)
6373 FIXME("stub\n");
6376 /***********************************************************************
6377 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6379 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6380 PFORMAT_STRING pFormat)
6382 FIXME("stub\n");
6383 return 0;
6386 /***********************************************************************
6387 * NdrXmitOrRepAsFree [RPCRT4.@]
6389 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6390 unsigned char *pMemory,
6391 PFORMAT_STRING pFormat)
6393 FIXME("stub\n");
6396 /***********************************************************************
6397 * NdrRangeMarshall [internal]
6399 static unsigned char *WINAPI NdrRangeMarshall(
6400 PMIDL_STUB_MESSAGE pStubMsg,
6401 unsigned char *pMemory,
6402 PFORMAT_STRING pFormat)
6404 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6405 unsigned char base_type;
6407 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6409 if (pRange->type != RPC_FC_RANGE)
6411 ERR("invalid format type %x\n", pRange->type);
6412 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6413 return NULL;
6416 base_type = pRange->flags_type & 0xf;
6418 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6421 /***********************************************************************
6422 * NdrRangeUnmarshall [RPCRT4.@]
6424 unsigned char *WINAPI NdrRangeUnmarshall(
6425 PMIDL_STUB_MESSAGE pStubMsg,
6426 unsigned char **ppMemory,
6427 PFORMAT_STRING pFormat,
6428 unsigned char fMustAlloc)
6430 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6431 unsigned char base_type;
6433 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6435 if (pRange->type != RPC_FC_RANGE)
6437 ERR("invalid format type %x\n", pRange->type);
6438 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6439 return NULL;
6441 base_type = pRange->flags_type & 0xf;
6443 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6444 base_type, pRange->low_value, pRange->high_value);
6446 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6447 do \
6449 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \
6450 if (!fMustAlloc && !*ppMemory) \
6451 fMustAlloc = TRUE; \
6452 if (fMustAlloc) \
6453 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6454 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6456 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6457 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6458 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6460 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6461 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6463 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6464 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6465 (mem_type)pRange->high_value); \
6466 RpcRaiseException(RPC_S_INVALID_BOUND); \
6467 return NULL; \
6469 TRACE("*ppMemory: %p\n", *ppMemory); \
6470 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6471 pStubMsg->Buffer += sizeof(wire_type); \
6472 } while (0)
6474 switch(base_type)
6476 case RPC_FC_CHAR:
6477 case RPC_FC_SMALL:
6478 RANGE_UNMARSHALL(UCHAR, UCHAR, "%d");
6479 TRACE("value: 0x%02x\n", **ppMemory);
6480 break;
6481 case RPC_FC_BYTE:
6482 case RPC_FC_USMALL:
6483 RANGE_UNMARSHALL(CHAR, CHAR, "%u");
6484 TRACE("value: 0x%02x\n", **ppMemory);
6485 break;
6486 case RPC_FC_WCHAR: /* FIXME: valid? */
6487 case RPC_FC_USHORT:
6488 RANGE_UNMARSHALL(USHORT, USHORT, "%u");
6489 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6490 break;
6491 case RPC_FC_SHORT:
6492 RANGE_UNMARSHALL(SHORT, SHORT, "%d");
6493 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6494 break;
6495 case RPC_FC_LONG:
6496 case RPC_FC_ENUM32:
6497 RANGE_UNMARSHALL(LONG, LONG, "%d");
6498 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6499 break;
6500 case RPC_FC_ULONG:
6501 RANGE_UNMARSHALL(ULONG, ULONG, "%u");
6502 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6503 break;
6504 case RPC_FC_ENUM16:
6505 RANGE_UNMARSHALL(UINT, USHORT, "%u");
6506 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6507 break;
6508 case RPC_FC_FLOAT:
6509 case RPC_FC_DOUBLE:
6510 case RPC_FC_HYPER:
6511 default:
6512 ERR("invalid range base type: 0x%02x\n", base_type);
6513 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6516 return NULL;
6519 /***********************************************************************
6520 * NdrRangeBufferSize [internal]
6522 static void WINAPI NdrRangeBufferSize(
6523 PMIDL_STUB_MESSAGE pStubMsg,
6524 unsigned char *pMemory,
6525 PFORMAT_STRING pFormat)
6527 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6528 unsigned char base_type;
6530 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6532 if (pRange->type != RPC_FC_RANGE)
6534 ERR("invalid format type %x\n", pRange->type);
6535 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6537 base_type = pRange->flags_type & 0xf;
6539 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6542 /***********************************************************************
6543 * NdrRangeMemorySize [internal]
6545 static ULONG WINAPI NdrRangeMemorySize(
6546 PMIDL_STUB_MESSAGE pStubMsg,
6547 PFORMAT_STRING pFormat)
6549 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6550 unsigned char base_type;
6552 if (pRange->type != RPC_FC_RANGE)
6554 ERR("invalid format type %x\n", pRange->type);
6555 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6556 return 0;
6558 base_type = pRange->flags_type & 0xf;
6560 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6563 /***********************************************************************
6564 * NdrRangeFree [internal]
6566 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6567 unsigned char *pMemory,
6568 PFORMAT_STRING pFormat)
6570 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6572 /* nothing to do */
6575 /***********************************************************************
6576 * NdrBaseTypeMarshall [internal]
6578 static unsigned char *WINAPI NdrBaseTypeMarshall(
6579 PMIDL_STUB_MESSAGE pStubMsg,
6580 unsigned char *pMemory,
6581 PFORMAT_STRING pFormat)
6583 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6585 switch(*pFormat)
6587 case RPC_FC_BYTE:
6588 case RPC_FC_CHAR:
6589 case RPC_FC_SMALL:
6590 case RPC_FC_USMALL:
6591 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6592 TRACE("value: 0x%02x\n", *pMemory);
6593 break;
6594 case RPC_FC_WCHAR:
6595 case RPC_FC_SHORT:
6596 case RPC_FC_USHORT:
6597 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6598 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6599 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6600 break;
6601 case RPC_FC_LONG:
6602 case RPC_FC_ULONG:
6603 case RPC_FC_ERROR_STATUS_T:
6604 case RPC_FC_ENUM32:
6605 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONG));
6606 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6607 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6608 break;
6609 case RPC_FC_FLOAT:
6610 align_pointer_clear(&pStubMsg->Buffer, sizeof(float));
6611 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6612 break;
6613 case RPC_FC_DOUBLE:
6614 align_pointer_clear(&pStubMsg->Buffer, sizeof(double));
6615 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6616 break;
6617 case RPC_FC_HYPER:
6618 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONGLONG));
6619 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6620 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6621 break;
6622 case RPC_FC_ENUM16:
6624 USHORT val = *(UINT *)pMemory;
6625 /* only 16-bits on the wire, so do a sanity check */
6626 if (*(UINT *)pMemory > SHRT_MAX)
6627 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6628 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6629 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6630 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6631 break;
6633 case RPC_FC_INT3264:
6634 case RPC_FC_UINT3264:
6636 UINT val = *(UINT_PTR *)pMemory;
6637 align_pointer_clear(&pStubMsg->Buffer, sizeof(UINT));
6638 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6639 break;
6641 case RPC_FC_IGNORE:
6642 break;
6643 default:
6644 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6647 /* FIXME: what is the correct return value? */
6648 return NULL;
6651 /***********************************************************************
6652 * NdrBaseTypeUnmarshall [internal]
6654 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6655 PMIDL_STUB_MESSAGE pStubMsg,
6656 unsigned char **ppMemory,
6657 PFORMAT_STRING pFormat,
6658 unsigned char fMustAlloc)
6660 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6662 #define BASE_TYPE_UNMARSHALL(type) do { \
6663 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
6664 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6666 *ppMemory = pStubMsg->Buffer; \
6667 TRACE("*ppMemory: %p\n", *ppMemory); \
6668 safe_buffer_increment(pStubMsg, sizeof(type)); \
6670 else \
6672 if (fMustAlloc) \
6673 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6674 TRACE("*ppMemory: %p\n", *ppMemory); \
6675 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6677 } while (0)
6679 switch(*pFormat)
6681 case RPC_FC_BYTE:
6682 case RPC_FC_CHAR:
6683 case RPC_FC_SMALL:
6684 case RPC_FC_USMALL:
6685 BASE_TYPE_UNMARSHALL(UCHAR);
6686 TRACE("value: 0x%02x\n", **ppMemory);
6687 break;
6688 case RPC_FC_WCHAR:
6689 case RPC_FC_SHORT:
6690 case RPC_FC_USHORT:
6691 BASE_TYPE_UNMARSHALL(USHORT);
6692 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6693 break;
6694 case RPC_FC_LONG:
6695 case RPC_FC_ULONG:
6696 case RPC_FC_ERROR_STATUS_T:
6697 case RPC_FC_ENUM32:
6698 BASE_TYPE_UNMARSHALL(ULONG);
6699 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6700 break;
6701 case RPC_FC_FLOAT:
6702 BASE_TYPE_UNMARSHALL(float);
6703 TRACE("value: %f\n", **(float **)ppMemory);
6704 break;
6705 case RPC_FC_DOUBLE:
6706 BASE_TYPE_UNMARSHALL(double);
6707 TRACE("value: %f\n", **(double **)ppMemory);
6708 break;
6709 case RPC_FC_HYPER:
6710 BASE_TYPE_UNMARSHALL(ULONGLONG);
6711 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6712 break;
6713 case RPC_FC_ENUM16:
6715 USHORT val;
6716 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6717 if (!fMustAlloc && !*ppMemory)
6718 fMustAlloc = TRUE;
6719 if (fMustAlloc)
6720 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6721 safe_copy_from_buffer(pStubMsg, &val, sizeof(USHORT));
6722 /* 16-bits on the wire, but int in memory */
6723 **(UINT **)ppMemory = val;
6724 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6725 break;
6727 case RPC_FC_INT3264:
6728 if (sizeof(INT_PTR) == sizeof(INT)) BASE_TYPE_UNMARSHALL(INT);
6729 else
6731 INT val;
6732 align_pointer(&pStubMsg->Buffer, sizeof(INT));
6733 if (!fMustAlloc && !*ppMemory)
6734 fMustAlloc = TRUE;
6735 if (fMustAlloc)
6736 *ppMemory = NdrAllocate(pStubMsg, sizeof(INT_PTR));
6737 safe_copy_from_buffer(pStubMsg, &val, sizeof(INT));
6738 **(INT_PTR **)ppMemory = val;
6739 TRACE("value: 0x%08lx\n", **(INT_PTR **)ppMemory);
6741 break;
6742 case RPC_FC_UINT3264:
6743 if (sizeof(UINT_PTR) == sizeof(UINT)) BASE_TYPE_UNMARSHALL(UINT);
6744 else
6746 UINT val;
6747 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6748 if (!fMustAlloc && !*ppMemory)
6749 fMustAlloc = TRUE;
6750 if (fMustAlloc)
6751 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT_PTR));
6752 safe_copy_from_buffer(pStubMsg, &val, sizeof(UINT));
6753 **(UINT_PTR **)ppMemory = val;
6754 TRACE("value: 0x%08lx\n", **(UINT_PTR **)ppMemory);
6756 break;
6757 case RPC_FC_IGNORE:
6758 break;
6759 default:
6760 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6762 #undef BASE_TYPE_UNMARSHALL
6764 /* FIXME: what is the correct return value? */
6766 return NULL;
6769 /***********************************************************************
6770 * NdrBaseTypeBufferSize [internal]
6772 static void WINAPI NdrBaseTypeBufferSize(
6773 PMIDL_STUB_MESSAGE pStubMsg,
6774 unsigned char *pMemory,
6775 PFORMAT_STRING pFormat)
6777 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6779 switch(*pFormat)
6781 case RPC_FC_BYTE:
6782 case RPC_FC_CHAR:
6783 case RPC_FC_SMALL:
6784 case RPC_FC_USMALL:
6785 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6786 break;
6787 case RPC_FC_WCHAR:
6788 case RPC_FC_SHORT:
6789 case RPC_FC_USHORT:
6790 case RPC_FC_ENUM16:
6791 align_length(&pStubMsg->BufferLength, sizeof(USHORT));
6792 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6793 break;
6794 case RPC_FC_LONG:
6795 case RPC_FC_ULONG:
6796 case RPC_FC_ENUM32:
6797 case RPC_FC_INT3264:
6798 case RPC_FC_UINT3264:
6799 align_length(&pStubMsg->BufferLength, sizeof(ULONG));
6800 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6801 break;
6802 case RPC_FC_FLOAT:
6803 align_length(&pStubMsg->BufferLength, sizeof(float));
6804 safe_buffer_length_increment(pStubMsg, sizeof(float));
6805 break;
6806 case RPC_FC_DOUBLE:
6807 align_length(&pStubMsg->BufferLength, sizeof(double));
6808 safe_buffer_length_increment(pStubMsg, sizeof(double));
6809 break;
6810 case RPC_FC_HYPER:
6811 align_length(&pStubMsg->BufferLength, sizeof(ULONGLONG));
6812 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6813 break;
6814 case RPC_FC_ERROR_STATUS_T:
6815 align_length(&pStubMsg->BufferLength, sizeof(error_status_t));
6816 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6817 break;
6818 case RPC_FC_IGNORE:
6819 break;
6820 default:
6821 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6825 /***********************************************************************
6826 * NdrBaseTypeMemorySize [internal]
6828 static ULONG WINAPI NdrBaseTypeMemorySize(
6829 PMIDL_STUB_MESSAGE pStubMsg,
6830 PFORMAT_STRING pFormat)
6832 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6834 switch(*pFormat)
6836 case RPC_FC_BYTE:
6837 case RPC_FC_CHAR:
6838 case RPC_FC_SMALL:
6839 case RPC_FC_USMALL:
6840 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6841 pStubMsg->MemorySize += sizeof(UCHAR);
6842 return sizeof(UCHAR);
6843 case RPC_FC_WCHAR:
6844 case RPC_FC_SHORT:
6845 case RPC_FC_USHORT:
6846 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6847 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6848 align_length(&pStubMsg->MemorySize, sizeof(USHORT));
6849 pStubMsg->MemorySize += sizeof(USHORT);
6850 return sizeof(USHORT);
6851 case RPC_FC_LONG:
6852 case RPC_FC_ULONG:
6853 case RPC_FC_ENUM32:
6854 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6855 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6856 align_length(&pStubMsg->MemorySize, sizeof(ULONG));
6857 pStubMsg->MemorySize += sizeof(ULONG);
6858 return sizeof(ULONG);
6859 case RPC_FC_FLOAT:
6860 align_pointer(&pStubMsg->Buffer, sizeof(float));
6861 safe_buffer_increment(pStubMsg, sizeof(float));
6862 align_length(&pStubMsg->MemorySize, sizeof(float));
6863 pStubMsg->MemorySize += sizeof(float);
6864 return sizeof(float);
6865 case RPC_FC_DOUBLE:
6866 align_pointer(&pStubMsg->Buffer, sizeof(double));
6867 safe_buffer_increment(pStubMsg, sizeof(double));
6868 align_length(&pStubMsg->MemorySize, sizeof(double));
6869 pStubMsg->MemorySize += sizeof(double);
6870 return sizeof(double);
6871 case RPC_FC_HYPER:
6872 align_pointer(&pStubMsg->Buffer, sizeof(ULONGLONG));
6873 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6874 align_length(&pStubMsg->MemorySize, sizeof(ULONGLONG));
6875 pStubMsg->MemorySize += sizeof(ULONGLONG);
6876 return sizeof(ULONGLONG);
6877 case RPC_FC_ERROR_STATUS_T:
6878 align_pointer(&pStubMsg->Buffer, sizeof(error_status_t));
6879 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6880 align_length(&pStubMsg->MemorySize, sizeof(error_status_t));
6881 pStubMsg->MemorySize += sizeof(error_status_t);
6882 return sizeof(error_status_t);
6883 case RPC_FC_ENUM16:
6884 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6885 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6886 align_length(&pStubMsg->MemorySize, sizeof(UINT));
6887 pStubMsg->MemorySize += sizeof(UINT);
6888 return sizeof(UINT);
6889 case RPC_FC_INT3264:
6890 case RPC_FC_UINT3264:
6891 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6892 safe_buffer_increment(pStubMsg, sizeof(UINT));
6893 align_length(&pStubMsg->MemorySize, sizeof(UINT_PTR));
6894 pStubMsg->MemorySize += sizeof(UINT_PTR);
6895 return sizeof(UINT_PTR);
6896 case RPC_FC_IGNORE:
6897 align_length(&pStubMsg->MemorySize, sizeof(void *));
6898 pStubMsg->MemorySize += sizeof(void *);
6899 return sizeof(void *);
6900 default:
6901 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6902 return 0;
6906 /***********************************************************************
6907 * NdrBaseTypeFree [internal]
6909 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6910 unsigned char *pMemory,
6911 PFORMAT_STRING pFormat)
6913 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6915 /* nothing to do */
6918 /***********************************************************************
6919 * NdrContextHandleBufferSize [internal]
6921 static void WINAPI NdrContextHandleBufferSize(
6922 PMIDL_STUB_MESSAGE pStubMsg,
6923 unsigned char *pMemory,
6924 PFORMAT_STRING pFormat)
6926 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6928 if (*pFormat != RPC_FC_BIND_CONTEXT)
6930 ERR("invalid format type %x\n", *pFormat);
6931 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6933 align_length(&pStubMsg->BufferLength, 4);
6934 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6937 /***********************************************************************
6938 * NdrContextHandleMarshall [internal]
6940 static unsigned char *WINAPI NdrContextHandleMarshall(
6941 PMIDL_STUB_MESSAGE pStubMsg,
6942 unsigned char *pMemory,
6943 PFORMAT_STRING pFormat)
6945 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6947 if (*pFormat != RPC_FC_BIND_CONTEXT)
6949 ERR("invalid format type %x\n", *pFormat);
6950 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6952 TRACE("flags: 0x%02x\n", pFormat[1]);
6954 if (pStubMsg->IsClient)
6956 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6957 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6958 else
6959 NdrClientContextMarshall(pStubMsg, pMemory, FALSE);
6961 else
6963 NDR_SCONTEXT ctxt = NDRSContextFromValue(pMemory);
6964 NDR_RUNDOWN rundown = pStubMsg->StubDesc->apfnNdrRundownRoutines[pFormat[2]];
6965 NdrServerContextNewMarshall(pStubMsg, ctxt, rundown, pFormat);
6968 return NULL;
6971 /***********************************************************************
6972 * NdrContextHandleUnmarshall [internal]
6974 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6975 PMIDL_STUB_MESSAGE pStubMsg,
6976 unsigned char **ppMemory,
6977 PFORMAT_STRING pFormat,
6978 unsigned char fMustAlloc)
6980 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6981 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6983 if (*pFormat != RPC_FC_BIND_CONTEXT)
6985 ERR("invalid format type %x\n", *pFormat);
6986 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6988 TRACE("flags: 0x%02x\n", pFormat[1]);
6990 if (pStubMsg->IsClient)
6992 /* [out]-only or [ret] param */
6993 if ((pFormat[1] & (HANDLE_PARAM_IS_IN|HANDLE_PARAM_IS_OUT)) == HANDLE_PARAM_IS_OUT)
6994 **(NDR_CCONTEXT **)ppMemory = NULL;
6995 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6997 else
6999 NDR_SCONTEXT ctxt;
7000 ctxt = NdrServerContextNewUnmarshall(pStubMsg, pFormat);
7001 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
7002 *(void **)ppMemory = NDRSContextValue(ctxt);
7003 else
7004 *(void **)ppMemory = *NDRSContextValue(ctxt);
7007 return NULL;
7010 /***********************************************************************
7011 * NdrClientContextMarshall [RPCRT4.@]
7013 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7014 NDR_CCONTEXT ContextHandle,
7015 int fCheck)
7017 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
7019 align_pointer_clear(&pStubMsg->Buffer, 4);
7021 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7023 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7024 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7025 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7028 /* FIXME: what does fCheck do? */
7029 NDRCContextMarshall(ContextHandle,
7030 pStubMsg->Buffer);
7032 pStubMsg->Buffer += cbNDRContext;
7035 /***********************************************************************
7036 * NdrClientContextUnmarshall [RPCRT4.@]
7038 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7039 NDR_CCONTEXT * pContextHandle,
7040 RPC_BINDING_HANDLE BindHandle)
7042 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
7044 align_pointer(&pStubMsg->Buffer, 4);
7046 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
7047 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7049 NDRCContextUnmarshall(pContextHandle,
7050 BindHandle,
7051 pStubMsg->Buffer,
7052 pStubMsg->RpcMsg->DataRepresentation);
7054 pStubMsg->Buffer += cbNDRContext;
7057 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7058 NDR_SCONTEXT ContextHandle,
7059 NDR_RUNDOWN RundownRoutine )
7061 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
7063 align_pointer(&pStubMsg->Buffer, 4);
7065 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7067 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7068 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7069 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7072 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7073 pStubMsg->Buffer, RundownRoutine, NULL,
7074 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7075 pStubMsg->Buffer += cbNDRContext;
7078 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
7080 NDR_SCONTEXT ContextHandle;
7082 TRACE("(%p)\n", pStubMsg);
7084 align_pointer(&pStubMsg->Buffer, 4);
7086 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7088 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7089 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7090 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7093 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7094 pStubMsg->Buffer,
7095 pStubMsg->RpcMsg->DataRepresentation,
7096 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7097 pStubMsg->Buffer += cbNDRContext;
7099 return ContextHandle;
7102 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
7103 unsigned char* pMemory,
7104 PFORMAT_STRING pFormat)
7106 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
7109 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
7110 PFORMAT_STRING pFormat)
7112 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7113 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7115 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7117 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7118 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7119 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7120 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7121 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7123 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7124 if_id = &sif->InterfaceId;
7127 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
7128 pStubMsg->RpcMsg->DataRepresentation, if_id,
7129 flags);
7132 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7133 NDR_SCONTEXT ContextHandle,
7134 NDR_RUNDOWN RundownRoutine,
7135 PFORMAT_STRING pFormat)
7137 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7138 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7140 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
7142 align_pointer(&pStubMsg->Buffer, 4);
7144 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7146 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7147 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7148 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7151 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7152 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7153 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7154 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7155 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7157 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7158 if_id = &sif->InterfaceId;
7161 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7162 pStubMsg->Buffer, RundownRoutine, if_id, flags);
7163 pStubMsg->Buffer += cbNDRContext;
7166 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7167 PFORMAT_STRING pFormat)
7169 NDR_SCONTEXT ContextHandle;
7170 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7171 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7173 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7175 align_pointer(&pStubMsg->Buffer, 4);
7177 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7179 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7180 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7181 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7184 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7185 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7186 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7187 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7188 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7190 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7191 if_id = &sif->InterfaceId;
7194 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7195 pStubMsg->Buffer,
7196 pStubMsg->RpcMsg->DataRepresentation,
7197 if_id, flags);
7198 pStubMsg->Buffer += cbNDRContext;
7200 return ContextHandle;
7203 /***********************************************************************
7204 * NdrCorrelationInitialize [RPCRT4.@]
7206 * Initializes correlation validity checking.
7208 * PARAMS
7209 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7210 * pMemory [I] Pointer to memory to use as a cache.
7211 * CacheSize [I] Size of the memory pointed to by pMemory.
7212 * Flags [I] Reserved. Set to zero.
7214 * RETURNS
7215 * Nothing.
7217 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
7219 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
7220 pStubMsg->fHasNewCorrDesc = TRUE;
7223 /***********************************************************************
7224 * NdrCorrelationPass [RPCRT4.@]
7226 * Performs correlation validity checking.
7228 * PARAMS
7229 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7231 * RETURNS
7232 * Nothing.
7234 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
7236 FIXME("(%p): stub\n", pStubMsg);
7239 /***********************************************************************
7240 * NdrCorrelationFree [RPCRT4.@]
7242 * Frees any resources used while unmarshalling parameters that need
7243 * correlation validity checking.
7245 * PARAMS
7246 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7248 * RETURNS
7249 * Nothing.
7251 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
7253 FIXME("(%p): stub\n", pStubMsg);