server: Fixup input windows on thread_detach.
[wine/multimedia.git] / dlls / rpcrt4 / ndr_marshall.c
blob8a84ed7bec9bbefbd0422ba30c48b388e2c1e015
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 RPC_X_NO_MEMORY
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(RPC_X_NO_MEMORY);
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 inline PFORMAT_STRING SkipConformance(const PMIDL_STUB_MESSAGE pStubMsg, const PFORMAT_STRING pFormat)
445 return pStubMsg->fHasNewCorrDesc ? pFormat + 6 : pFormat + 4;
448 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
450 align_pointer(&pStubMsg->Buffer, 4);
451 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
452 RpcRaiseException(RPC_X_BAD_STUB_DATA);
453 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
454 pStubMsg->Buffer += 4;
455 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
456 return SkipConformance(pStubMsg, pFormat);
459 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
461 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
463 pStubMsg->Offset = 0;
464 pStubMsg->ActualCount = pStubMsg->MaxCount;
465 goto done;
468 align_pointer(&pStubMsg->Buffer, 4);
469 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
470 RpcRaiseException(RPC_X_BAD_STUB_DATA);
471 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
472 pStubMsg->Buffer += 4;
473 TRACE("offset is %d\n", pStubMsg->Offset);
474 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
475 pStubMsg->Buffer += 4;
476 TRACE("variance is %d\n", pStubMsg->ActualCount);
478 if ((pStubMsg->ActualCount > MaxValue) ||
479 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
481 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
482 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
483 RpcRaiseException(RPC_S_INVALID_BOUND);
484 return NULL;
487 done:
488 return SkipConformance(pStubMsg, pFormat);
491 /* writes the conformance value to the buffer */
492 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
494 align_pointer_clear(&pStubMsg->Buffer, 4);
495 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
496 RpcRaiseException(RPC_X_BAD_STUB_DATA);
497 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
498 pStubMsg->Buffer += 4;
501 /* writes the variance values to the buffer */
502 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
504 align_pointer_clear(&pStubMsg->Buffer, 4);
505 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
506 RpcRaiseException(RPC_X_BAD_STUB_DATA);
507 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
508 pStubMsg->Buffer += 4;
509 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
510 pStubMsg->Buffer += 4;
513 /* requests buffer space for the conformance value */
514 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
516 align_length(&pStubMsg->BufferLength, 4);
517 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
518 RpcRaiseException(RPC_X_BAD_STUB_DATA);
519 pStubMsg->BufferLength += 4;
522 /* requests buffer space for the variance values */
523 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
525 align_length(&pStubMsg->BufferLength, 4);
526 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
527 RpcRaiseException(RPC_X_BAD_STUB_DATA);
528 pStubMsg->BufferLength += 8;
531 PFORMAT_STRING ComputeConformanceOrVariance(
532 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
533 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
535 BYTE dtype = pFormat[0] & 0xf;
536 short ofs = *(const short *)&pFormat[2];
537 LPVOID ptr = NULL;
538 ULONG_PTR data = 0;
540 if (!IsConformanceOrVariancePresent(pFormat)) {
541 /* null descriptor */
542 *pCount = def;
543 goto finish_conf;
546 switch (pFormat[0] & 0xf0) {
547 case RPC_FC_NORMAL_CONFORMANCE:
548 TRACE("normal conformance, ofs=%d\n", ofs);
549 ptr = pMemory;
550 break;
551 case RPC_FC_POINTER_CONFORMANCE:
552 TRACE("pointer conformance, ofs=%d\n", ofs);
553 ptr = pStubMsg->Memory;
554 break;
555 case RPC_FC_TOP_LEVEL_CONFORMANCE:
556 TRACE("toplevel conformance, ofs=%d\n", ofs);
557 if (pStubMsg->StackTop) {
558 ptr = pStubMsg->StackTop;
560 else {
561 /* -Os mode, *pCount is already set */
562 goto finish_conf;
564 break;
565 case RPC_FC_CONSTANT_CONFORMANCE:
566 data = ofs | ((DWORD)pFormat[1] << 16);
567 TRACE("constant conformance, val=%ld\n", data);
568 *pCount = data;
569 goto finish_conf;
570 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
571 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
572 if (pStubMsg->StackTop) {
573 ptr = pStubMsg->StackTop;
575 else {
576 /* ? */
577 goto done_conf_grab;
579 break;
580 default:
581 FIXME("unknown conformance type %x, expect crash.\n", pFormat[0] & 0xf0);
582 goto finish_conf;
585 switch (pFormat[1]) {
586 case RPC_FC_DEREFERENCE:
587 ptr = *(LPVOID*)((char *)ptr + ofs);
588 break;
589 case RPC_FC_CALLBACK:
591 unsigned char *old_stack_top = pStubMsg->StackTop;
592 ULONG_PTR max_count, old_max_count = pStubMsg->MaxCount;
594 pStubMsg->StackTop = ptr;
596 /* ofs is index into StubDesc->apfnExprEval */
597 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
598 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
600 pStubMsg->StackTop = old_stack_top;
602 /* the callback function always stores the computed value in MaxCount */
603 max_count = pStubMsg->MaxCount;
604 pStubMsg->MaxCount = old_max_count;
605 *pCount = max_count;
606 goto finish_conf;
608 default:
609 ptr = (char *)ptr + ofs;
610 break;
613 switch (dtype) {
614 case RPC_FC_LONG:
615 case RPC_FC_ULONG:
616 data = *(DWORD*)ptr;
617 break;
618 case RPC_FC_SHORT:
619 data = *(SHORT*)ptr;
620 break;
621 case RPC_FC_USHORT:
622 data = *(USHORT*)ptr;
623 break;
624 case RPC_FC_CHAR:
625 case RPC_FC_SMALL:
626 data = *(CHAR*)ptr;
627 break;
628 case RPC_FC_BYTE:
629 case RPC_FC_USMALL:
630 data = *(UCHAR*)ptr;
631 break;
632 case RPC_FC_HYPER:
633 data = *(ULONGLONG *)ptr;
634 break;
635 default:
636 FIXME("unknown conformance data type %x\n", dtype);
637 goto done_conf_grab;
639 TRACE("dereferenced data type %x at %p, got %ld\n", dtype, ptr, data);
641 done_conf_grab:
642 switch (pFormat[1]) {
643 case RPC_FC_DEREFERENCE: /* already handled */
644 case 0: /* no op */
645 *pCount = data;
646 break;
647 case RPC_FC_ADD_1:
648 *pCount = data + 1;
649 break;
650 case RPC_FC_SUB_1:
651 *pCount = data - 1;
652 break;
653 case RPC_FC_MULT_2:
654 *pCount = data * 2;
655 break;
656 case RPC_FC_DIV_2:
657 *pCount = data / 2;
658 break;
659 default:
660 FIXME("unknown conformance op %d\n", pFormat[1]);
661 goto finish_conf;
664 finish_conf:
665 TRACE("resulting conformance is %ld\n", *pCount);
667 return SkipConformance(pStubMsg, pFormat);
670 static inline PFORMAT_STRING SkipVariance(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
672 return SkipConformance( pStubMsg, pFormat );
675 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
676 * the result overflows 32-bits */
677 static inline ULONG safe_multiply(ULONG a, ULONG b)
679 ULONGLONG ret = (ULONGLONG)a * b;
680 if (ret > 0xffffffff)
682 RpcRaiseException(RPC_S_INVALID_BOUND);
683 return 0;
685 return ret;
688 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
690 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
691 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
692 RpcRaiseException(RPC_X_BAD_STUB_DATA);
693 pStubMsg->Buffer += size;
696 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
698 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
700 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
701 pStubMsg->BufferLength, size);
702 RpcRaiseException(RPC_X_BAD_STUB_DATA);
704 pStubMsg->BufferLength += size;
707 /* copies data from the buffer, checking that there is enough data in the buffer
708 * to do so */
709 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
711 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
712 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
714 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
715 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
716 RpcRaiseException(RPC_X_BAD_STUB_DATA);
718 if (p == pStubMsg->Buffer)
719 ERR("pointer is the same as the buffer\n");
720 memcpy(p, pStubMsg->Buffer, size);
721 pStubMsg->Buffer += size;
724 /* copies data to the buffer, checking that there is enough space to do so */
725 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
727 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
728 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
730 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
731 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
732 size);
733 RpcRaiseException(RPC_X_BAD_STUB_DATA);
735 memcpy(pStubMsg->Buffer, p, size);
736 pStubMsg->Buffer += size;
739 /* verify that string data sitting in the buffer is valid and safe to
740 * unmarshall */
741 static void validate_string_data(MIDL_STUB_MESSAGE *pStubMsg, ULONG bufsize, ULONG esize)
743 ULONG i;
745 /* verify the buffer is safe to access */
746 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
747 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
749 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
750 pStubMsg->BufferEnd, pStubMsg->Buffer);
751 RpcRaiseException(RPC_X_BAD_STUB_DATA);
754 /* strings must always have null terminating bytes */
755 if (bufsize < esize)
757 ERR("invalid string length of %d\n", bufsize / esize);
758 RpcRaiseException(RPC_S_INVALID_BOUND);
761 for (i = bufsize - esize; i < bufsize; i++)
762 if (pStubMsg->Buffer[i] != 0)
764 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
765 i, pStubMsg->Buffer[i]);
766 RpcRaiseException(RPC_S_INVALID_BOUND);
770 static inline void dump_pointer_attr(unsigned char attr)
772 if (attr & RPC_FC_P_ALLOCALLNODES)
773 TRACE(" RPC_FC_P_ALLOCALLNODES");
774 if (attr & RPC_FC_P_DONTFREE)
775 TRACE(" RPC_FC_P_DONTFREE");
776 if (attr & RPC_FC_P_ONSTACK)
777 TRACE(" RPC_FC_P_ONSTACK");
778 if (attr & RPC_FC_P_SIMPLEPOINTER)
779 TRACE(" RPC_FC_P_SIMPLEPOINTER");
780 if (attr & RPC_FC_P_DEREF)
781 TRACE(" RPC_FC_P_DEREF");
782 TRACE("\n");
785 /***********************************************************************
786 * PointerMarshall [internal]
788 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
789 unsigned char *Buffer,
790 unsigned char *Pointer,
791 PFORMAT_STRING pFormat)
793 unsigned type = pFormat[0], attr = pFormat[1];
794 PFORMAT_STRING desc;
795 NDR_MARSHALL m;
796 ULONG pointer_id;
797 BOOL pointer_needs_marshaling;
799 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
800 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
801 pFormat += 2;
802 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
803 else desc = pFormat + *(const SHORT*)pFormat;
805 switch (type) {
806 case RPC_FC_RP: /* ref pointer (always non-null) */
807 if (!Pointer)
809 ERR("NULL ref pointer is not allowed\n");
810 RpcRaiseException(RPC_X_NULL_REF_POINTER);
812 pointer_needs_marshaling = TRUE;
813 break;
814 case RPC_FC_UP: /* unique pointer */
815 case RPC_FC_OP: /* object pointer - same as unique here */
816 if (Pointer)
817 pointer_needs_marshaling = TRUE;
818 else
819 pointer_needs_marshaling = FALSE;
820 pointer_id = Pointer ? NDR_POINTER_ID(pStubMsg) : 0;
821 TRACE("writing 0x%08x to buffer\n", pointer_id);
822 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
823 break;
824 case RPC_FC_FP:
825 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
826 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
827 TRACE("writing 0x%08x to buffer\n", pointer_id);
828 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
829 break;
830 default:
831 FIXME("unhandled ptr type=%02x\n", type);
832 RpcRaiseException(RPC_X_BAD_STUB_DATA);
833 return;
836 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
838 if (pointer_needs_marshaling) {
839 if (attr & RPC_FC_P_DEREF) {
840 Pointer = *(unsigned char**)Pointer;
841 TRACE("deref => %p\n", Pointer);
843 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
844 if (m) m(pStubMsg, Pointer, desc);
845 else FIXME("no marshaller for data type=%02x\n", *desc);
848 STD_OVERFLOW_CHECK(pStubMsg);
851 /***********************************************************************
852 * PointerUnmarshall [internal]
854 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
855 unsigned char *Buffer,
856 unsigned char **pPointer,
857 unsigned char *pSrcPointer,
858 PFORMAT_STRING pFormat,
859 unsigned char fMustAlloc)
861 unsigned type = pFormat[0], attr = pFormat[1];
862 PFORMAT_STRING desc;
863 NDR_UNMARSHALL m;
864 DWORD pointer_id = 0;
865 BOOL pointer_needs_unmarshaling;
867 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
868 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
869 pFormat += 2;
870 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
871 else desc = pFormat + *(const SHORT*)pFormat;
873 switch (type) {
874 case RPC_FC_RP: /* ref pointer (always non-null) */
875 pointer_needs_unmarshaling = TRUE;
876 break;
877 case RPC_FC_UP: /* unique pointer */
878 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
879 TRACE("pointer_id is 0x%08x\n", pointer_id);
880 if (pointer_id)
881 pointer_needs_unmarshaling = TRUE;
882 else {
883 *pPointer = NULL;
884 pointer_needs_unmarshaling = FALSE;
886 break;
887 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
888 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
889 TRACE("pointer_id is 0x%08x\n", pointer_id);
890 if (!fMustAlloc && pSrcPointer)
892 FIXME("free object pointer %p\n", pSrcPointer);
893 fMustAlloc = TRUE;
895 if (pointer_id)
896 pointer_needs_unmarshaling = TRUE;
897 else
899 *pPointer = NULL;
900 pointer_needs_unmarshaling = FALSE;
902 break;
903 case RPC_FC_FP:
904 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
905 TRACE("pointer_id is 0x%08x\n", pointer_id);
906 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
907 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
908 break;
909 default:
910 FIXME("unhandled ptr type=%02x\n", type);
911 RpcRaiseException(RPC_X_BAD_STUB_DATA);
912 return;
915 if (pointer_needs_unmarshaling) {
916 unsigned char **current_ptr = pPointer;
917 if (pStubMsg->IsClient) {
918 TRACE("client\n");
919 /* if we aren't forcing allocation of memory then try to use the existing
920 * (source) pointer to unmarshall the data into so that [in,out]
921 * parameters behave correctly. it doesn't matter if the parameter is
922 * [out] only since in that case the pointer will be NULL. we force
923 * allocation when the source pointer is NULL here instead of in the type
924 * unmarshalling routine for the benefit of the deref code below */
925 if (!fMustAlloc) {
926 if (pSrcPointer) {
927 TRACE("setting *pPointer to %p\n", pSrcPointer);
928 *pPointer = pSrcPointer;
929 } else
930 fMustAlloc = TRUE;
932 } else {
933 TRACE("server\n");
934 /* the memory in a stub is never initialised, so we have to work out here
935 * whether we have to initialise it so we can use the optimisation of
936 * setting the pointer to the buffer, if possible, or set fMustAlloc to
937 * TRUE. */
938 if (attr & RPC_FC_P_DEREF) {
939 fMustAlloc = TRUE;
940 } else {
941 *current_ptr = NULL;
945 if (attr & RPC_FC_P_ALLOCALLNODES)
946 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
948 if (attr & RPC_FC_P_DEREF) {
949 if (fMustAlloc) {
950 unsigned char *base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
951 *pPointer = base_ptr_val;
952 current_ptr = (unsigned char **)base_ptr_val;
953 } else
954 current_ptr = *(unsigned char***)current_ptr;
955 TRACE("deref => %p\n", current_ptr);
956 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
958 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
959 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
960 else FIXME("no unmarshaller for data type=%02x\n", *desc);
962 if (type == RPC_FC_FP)
963 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
964 *pPointer);
967 TRACE("pointer=%p\n", *pPointer);
970 /***********************************************************************
971 * PointerBufferSize [internal]
973 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
974 unsigned char *Pointer,
975 PFORMAT_STRING pFormat)
977 unsigned type = pFormat[0], attr = pFormat[1];
978 PFORMAT_STRING desc;
979 NDR_BUFFERSIZE m;
980 BOOL pointer_needs_sizing;
981 ULONG pointer_id;
983 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
984 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
985 pFormat += 2;
986 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
987 else desc = pFormat + *(const SHORT*)pFormat;
989 switch (type) {
990 case RPC_FC_RP: /* ref pointer (always non-null) */
991 if (!Pointer)
993 ERR("NULL ref pointer is not allowed\n");
994 RpcRaiseException(RPC_X_NULL_REF_POINTER);
996 break;
997 case RPC_FC_OP:
998 case RPC_FC_UP:
999 /* NULL pointer has no further representation */
1000 if (!Pointer)
1001 return;
1002 break;
1003 case RPC_FC_FP:
1004 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1005 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1006 if (!pointer_needs_sizing)
1007 return;
1008 break;
1009 default:
1010 FIXME("unhandled ptr type=%02x\n", type);
1011 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1012 return;
1015 if (attr & RPC_FC_P_DEREF) {
1016 Pointer = *(unsigned char**)Pointer;
1017 TRACE("deref => %p\n", Pointer);
1020 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1021 if (m) m(pStubMsg, Pointer, desc);
1022 else FIXME("no buffersizer for data type=%02x\n", *desc);
1025 /***********************************************************************
1026 * PointerMemorySize [internal]
1028 static ULONG PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1029 unsigned char *Buffer, PFORMAT_STRING pFormat)
1031 unsigned type = pFormat[0], attr = pFormat[1];
1032 PFORMAT_STRING desc;
1033 NDR_MEMORYSIZE m;
1034 DWORD pointer_id = 0;
1035 BOOL pointer_needs_sizing;
1037 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1038 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1039 pFormat += 2;
1040 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1041 else desc = pFormat + *(const SHORT*)pFormat;
1043 switch (type) {
1044 case RPC_FC_RP: /* ref pointer (always non-null) */
1045 pointer_needs_sizing = TRUE;
1046 break;
1047 case RPC_FC_UP: /* unique pointer */
1048 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1049 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1050 TRACE("pointer_id is 0x%08x\n", pointer_id);
1051 if (pointer_id)
1052 pointer_needs_sizing = TRUE;
1053 else
1054 pointer_needs_sizing = FALSE;
1055 break;
1056 case RPC_FC_FP:
1058 void *pointer;
1059 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1060 TRACE("pointer_id is 0x%08x\n", pointer_id);
1061 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1062 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1063 break;
1065 default:
1066 FIXME("unhandled ptr type=%02x\n", type);
1067 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1068 return 0;
1071 if (attr & RPC_FC_P_DEREF) {
1072 align_length(&pStubMsg->MemorySize, sizeof(void*));
1073 pStubMsg->MemorySize += sizeof(void*);
1074 TRACE("deref\n");
1077 if (pointer_needs_sizing) {
1078 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1079 if (m) m(pStubMsg, desc);
1080 else FIXME("no memorysizer for data type=%02x\n", *desc);
1083 return pStubMsg->MemorySize;
1086 /***********************************************************************
1087 * PointerFree [internal]
1089 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1090 unsigned char *Pointer,
1091 PFORMAT_STRING pFormat)
1093 unsigned type = pFormat[0], attr = pFormat[1];
1094 PFORMAT_STRING desc;
1095 NDR_FREE m;
1096 unsigned char *current_pointer = Pointer;
1098 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1099 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1100 if (attr & RPC_FC_P_DONTFREE) return;
1101 pFormat += 2;
1102 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1103 else desc = pFormat + *(const SHORT*)pFormat;
1105 if (!Pointer) return;
1107 if (type == RPC_FC_FP) {
1108 int pointer_needs_freeing = NdrFullPointerFree(
1109 pStubMsg->FullPtrXlatTables, Pointer);
1110 if (!pointer_needs_freeing)
1111 return;
1114 if (attr & RPC_FC_P_DEREF) {
1115 current_pointer = *(unsigned char**)Pointer;
1116 TRACE("deref => %p\n", current_pointer);
1119 m = NdrFreer[*desc & NDR_TABLE_MASK];
1120 if (m) m(pStubMsg, current_pointer, desc);
1122 /* this check stops us from trying to free buffer memory. we don't have to
1123 * worry about clients, since they won't call this function.
1124 * we don't have to check for the buffer being reallocated because
1125 * BufferStart and BufferEnd won't be reset when allocating memory for
1126 * sending the response. we don't have to check for the new buffer here as
1127 * it won't be used a type memory, only for buffer memory */
1128 if (Pointer >= pStubMsg->BufferStart && Pointer <= pStubMsg->BufferEnd)
1129 goto notfree;
1131 if (attr & RPC_FC_P_ONSTACK) {
1132 TRACE("not freeing stack ptr %p\n", Pointer);
1133 return;
1135 TRACE("freeing %p\n", Pointer);
1136 NdrFree(pStubMsg, Pointer);
1137 return;
1138 notfree:
1139 TRACE("not freeing %p\n", Pointer);
1142 /***********************************************************************
1143 * EmbeddedPointerMarshall
1145 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1146 unsigned char *pMemory,
1147 PFORMAT_STRING pFormat)
1149 unsigned char *Mark = pStubMsg->BufferMark;
1150 unsigned rep, count, stride;
1151 unsigned i;
1152 unsigned char *saved_buffer = NULL;
1154 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1156 if (*pFormat != RPC_FC_PP) return NULL;
1157 pFormat += 2;
1159 if (pStubMsg->PointerBufferMark)
1161 saved_buffer = pStubMsg->Buffer;
1162 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1163 pStubMsg->PointerBufferMark = NULL;
1166 while (pFormat[0] != RPC_FC_END) {
1167 switch (pFormat[0]) {
1168 default:
1169 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1170 /* fallthrough */
1171 case RPC_FC_NO_REPEAT:
1172 rep = 1;
1173 stride = 0;
1174 count = 1;
1175 pFormat += 2;
1176 break;
1177 case RPC_FC_FIXED_REPEAT:
1178 rep = *(const WORD*)&pFormat[2];
1179 stride = *(const WORD*)&pFormat[4];
1180 count = *(const WORD*)&pFormat[8];
1181 pFormat += 10;
1182 break;
1183 case RPC_FC_VARIABLE_REPEAT:
1184 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1185 stride = *(const WORD*)&pFormat[2];
1186 count = *(const WORD*)&pFormat[6];
1187 pFormat += 8;
1188 break;
1190 for (i = 0; i < rep; i++) {
1191 PFORMAT_STRING info = pFormat;
1192 unsigned char *membase = pMemory + (i * stride);
1193 unsigned char *bufbase = Mark + (i * stride);
1194 unsigned u;
1196 for (u=0; u<count; u++,info+=8) {
1197 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1198 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1199 unsigned char *saved_memory = pStubMsg->Memory;
1201 pStubMsg->Memory = membase;
1202 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1203 pStubMsg->Memory = saved_memory;
1206 pFormat += 8 * count;
1209 if (saved_buffer)
1211 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1212 pStubMsg->Buffer = saved_buffer;
1215 STD_OVERFLOW_CHECK(pStubMsg);
1217 return NULL;
1220 /***********************************************************************
1221 * EmbeddedPointerUnmarshall
1223 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1224 unsigned char *pDstBuffer,
1225 unsigned char *pSrcMemoryPtrs,
1226 PFORMAT_STRING pFormat,
1227 unsigned char fMustAlloc)
1229 unsigned char *Mark = pStubMsg->BufferMark;
1230 unsigned rep, count, stride;
1231 unsigned i;
1232 unsigned char *saved_buffer = NULL;
1234 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc);
1236 if (*pFormat != RPC_FC_PP) return NULL;
1237 pFormat += 2;
1239 if (pStubMsg->PointerBufferMark)
1241 saved_buffer = pStubMsg->Buffer;
1242 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1243 pStubMsg->PointerBufferMark = NULL;
1246 while (pFormat[0] != RPC_FC_END) {
1247 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1248 switch (pFormat[0]) {
1249 default:
1250 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1251 /* fallthrough */
1252 case RPC_FC_NO_REPEAT:
1253 rep = 1;
1254 stride = 0;
1255 count = 1;
1256 pFormat += 2;
1257 break;
1258 case RPC_FC_FIXED_REPEAT:
1259 rep = *(const WORD*)&pFormat[2];
1260 stride = *(const WORD*)&pFormat[4];
1261 count = *(const WORD*)&pFormat[8];
1262 pFormat += 10;
1263 break;
1264 case RPC_FC_VARIABLE_REPEAT:
1265 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1266 stride = *(const WORD*)&pFormat[2];
1267 count = *(const WORD*)&pFormat[6];
1268 pFormat += 8;
1269 break;
1271 for (i = 0; i < rep; i++) {
1272 PFORMAT_STRING info = pFormat;
1273 unsigned char *bufdstbase = pDstBuffer + (i * stride);
1274 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1275 unsigned char *bufbase = Mark + (i * stride);
1276 unsigned u;
1278 for (u=0; u<count; u++,info+=8) {
1279 unsigned char **bufdstptr = (unsigned char **)(bufdstbase + *(const SHORT*)&info[2]);
1280 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1281 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1282 PointerUnmarshall(pStubMsg, bufptr, bufdstptr, *memsrcptr, info+4, fMustAlloc);
1285 pFormat += 8 * count;
1288 if (saved_buffer)
1290 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1291 pStubMsg->Buffer = saved_buffer;
1294 return NULL;
1297 /***********************************************************************
1298 * EmbeddedPointerBufferSize
1300 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1301 unsigned char *pMemory,
1302 PFORMAT_STRING pFormat)
1304 unsigned rep, count, stride;
1305 unsigned i;
1306 ULONG saved_buffer_length = 0;
1308 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1310 if (pStubMsg->IgnoreEmbeddedPointers) return;
1312 if (*pFormat != RPC_FC_PP) return;
1313 pFormat += 2;
1315 if (pStubMsg->PointerLength)
1317 saved_buffer_length = pStubMsg->BufferLength;
1318 pStubMsg->BufferLength = pStubMsg->PointerLength;
1319 pStubMsg->PointerLength = 0;
1322 while (pFormat[0] != RPC_FC_END) {
1323 switch (pFormat[0]) {
1324 default:
1325 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1326 /* fallthrough */
1327 case RPC_FC_NO_REPEAT:
1328 rep = 1;
1329 stride = 0;
1330 count = 1;
1331 pFormat += 2;
1332 break;
1333 case RPC_FC_FIXED_REPEAT:
1334 rep = *(const WORD*)&pFormat[2];
1335 stride = *(const WORD*)&pFormat[4];
1336 count = *(const WORD*)&pFormat[8];
1337 pFormat += 10;
1338 break;
1339 case RPC_FC_VARIABLE_REPEAT:
1340 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1341 stride = *(const WORD*)&pFormat[2];
1342 count = *(const WORD*)&pFormat[6];
1343 pFormat += 8;
1344 break;
1346 for (i = 0; i < rep; i++) {
1347 PFORMAT_STRING info = pFormat;
1348 unsigned char *membase = pMemory + (i * stride);
1349 unsigned u;
1351 for (u=0; u<count; u++,info+=8) {
1352 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1353 unsigned char *saved_memory = pStubMsg->Memory;
1355 pStubMsg->Memory = membase;
1356 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1357 pStubMsg->Memory = saved_memory;
1360 pFormat += 8 * count;
1363 if (saved_buffer_length)
1365 pStubMsg->PointerLength = pStubMsg->BufferLength;
1366 pStubMsg->BufferLength = saved_buffer_length;
1370 /***********************************************************************
1371 * EmbeddedPointerMemorySize [internal]
1373 static ULONG EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1374 PFORMAT_STRING pFormat)
1376 unsigned char *Mark = pStubMsg->BufferMark;
1377 unsigned rep, count, stride;
1378 unsigned i;
1379 unsigned char *saved_buffer = NULL;
1381 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1383 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1385 if (pStubMsg->PointerBufferMark)
1387 saved_buffer = pStubMsg->Buffer;
1388 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1389 pStubMsg->PointerBufferMark = NULL;
1392 if (*pFormat != RPC_FC_PP) return 0;
1393 pFormat += 2;
1395 while (pFormat[0] != RPC_FC_END) {
1396 switch (pFormat[0]) {
1397 default:
1398 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1399 /* fallthrough */
1400 case RPC_FC_NO_REPEAT:
1401 rep = 1;
1402 stride = 0;
1403 count = 1;
1404 pFormat += 2;
1405 break;
1406 case RPC_FC_FIXED_REPEAT:
1407 rep = *(const WORD*)&pFormat[2];
1408 stride = *(const WORD*)&pFormat[4];
1409 count = *(const WORD*)&pFormat[8];
1410 pFormat += 10;
1411 break;
1412 case RPC_FC_VARIABLE_REPEAT:
1413 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1414 stride = *(const WORD*)&pFormat[2];
1415 count = *(const WORD*)&pFormat[6];
1416 pFormat += 8;
1417 break;
1419 for (i = 0; i < rep; i++) {
1420 PFORMAT_STRING info = pFormat;
1421 unsigned char *bufbase = Mark + (i * stride);
1422 unsigned u;
1423 for (u=0; u<count; u++,info+=8) {
1424 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1425 PointerMemorySize(pStubMsg, bufptr, info+4);
1428 pFormat += 8 * count;
1431 if (saved_buffer)
1433 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1434 pStubMsg->Buffer = saved_buffer;
1437 return 0;
1440 /***********************************************************************
1441 * EmbeddedPointerFree [internal]
1443 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1444 unsigned char *pMemory,
1445 PFORMAT_STRING pFormat)
1447 unsigned rep, count, stride;
1448 unsigned i;
1450 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1451 if (*pFormat != RPC_FC_PP) return;
1452 pFormat += 2;
1454 while (pFormat[0] != RPC_FC_END) {
1455 switch (pFormat[0]) {
1456 default:
1457 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1458 /* fallthrough */
1459 case RPC_FC_NO_REPEAT:
1460 rep = 1;
1461 stride = 0;
1462 count = 1;
1463 pFormat += 2;
1464 break;
1465 case RPC_FC_FIXED_REPEAT:
1466 rep = *(const WORD*)&pFormat[2];
1467 stride = *(const WORD*)&pFormat[4];
1468 count = *(const WORD*)&pFormat[8];
1469 pFormat += 10;
1470 break;
1471 case RPC_FC_VARIABLE_REPEAT:
1472 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1473 stride = *(const WORD*)&pFormat[2];
1474 count = *(const WORD*)&pFormat[6];
1475 pFormat += 8;
1476 break;
1478 for (i = 0; i < rep; i++) {
1479 PFORMAT_STRING info = pFormat;
1480 unsigned char *membase = pMemory + (i * stride);
1481 unsigned u;
1483 for (u=0; u<count; u++,info+=8) {
1484 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1485 unsigned char *saved_memory = pStubMsg->Memory;
1487 pStubMsg->Memory = membase;
1488 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1489 pStubMsg->Memory = saved_memory;
1492 pFormat += 8 * count;
1496 /***********************************************************************
1497 * NdrPointerMarshall [RPCRT4.@]
1499 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1500 unsigned char *pMemory,
1501 PFORMAT_STRING pFormat)
1503 unsigned char *Buffer;
1505 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1507 /* Increment the buffer here instead of in PointerMarshall,
1508 * as that is used by embedded pointers which already handle the incrementing
1509 * the buffer, and shouldn't write any additional pointer data to the wire */
1510 if (*pFormat != RPC_FC_RP)
1512 align_pointer_clear(&pStubMsg->Buffer, 4);
1513 Buffer = pStubMsg->Buffer;
1514 safe_buffer_increment(pStubMsg, 4);
1516 else
1517 Buffer = pStubMsg->Buffer;
1519 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1521 return NULL;
1524 /***********************************************************************
1525 * NdrPointerUnmarshall [RPCRT4.@]
1527 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1528 unsigned char **ppMemory,
1529 PFORMAT_STRING pFormat,
1530 unsigned char fMustAlloc)
1532 unsigned char *Buffer;
1534 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1536 if (*pFormat == RPC_FC_RP)
1538 Buffer = pStubMsg->Buffer;
1539 /* Do the NULL ref pointer check here because embedded pointers can be
1540 * NULL if the type the pointer is embedded in was allocated rather than
1541 * being passed in by the client */
1542 if (pStubMsg->IsClient && !*ppMemory)
1544 ERR("NULL ref pointer is not allowed\n");
1545 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1548 else
1550 /* Increment the buffer here instead of in PointerUnmarshall,
1551 * as that is used by embedded pointers which already handle the incrementing
1552 * the buffer, and shouldn't read any additional pointer data from the
1553 * buffer */
1554 align_pointer(&pStubMsg->Buffer, 4);
1555 Buffer = pStubMsg->Buffer;
1556 safe_buffer_increment(pStubMsg, 4);
1559 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1561 return NULL;
1564 /***********************************************************************
1565 * NdrPointerBufferSize [RPCRT4.@]
1567 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1568 unsigned char *pMemory,
1569 PFORMAT_STRING pFormat)
1571 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1573 /* Increment the buffer length here instead of in PointerBufferSize,
1574 * as that is used by embedded pointers which already handle the buffer
1575 * length, and shouldn't write anything more to the wire */
1576 if (*pFormat != RPC_FC_RP)
1578 align_length(&pStubMsg->BufferLength, 4);
1579 safe_buffer_length_increment(pStubMsg, 4);
1582 PointerBufferSize(pStubMsg, pMemory, pFormat);
1585 /***********************************************************************
1586 * NdrPointerMemorySize [RPCRT4.@]
1588 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1589 PFORMAT_STRING pFormat)
1591 unsigned char *Buffer = pStubMsg->Buffer;
1592 if (*pFormat != RPC_FC_RP)
1594 align_pointer(&pStubMsg->Buffer, 4);
1595 safe_buffer_increment(pStubMsg, 4);
1597 align_length(&pStubMsg->MemorySize, sizeof(void *));
1598 return PointerMemorySize(pStubMsg, Buffer, pFormat);
1601 /***********************************************************************
1602 * NdrPointerFree [RPCRT4.@]
1604 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1605 unsigned char *pMemory,
1606 PFORMAT_STRING pFormat)
1608 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1609 PointerFree(pStubMsg, pMemory, pFormat);
1612 /***********************************************************************
1613 * NdrSimpleTypeMarshall [RPCRT4.@]
1615 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1616 unsigned char FormatChar )
1618 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1621 /***********************************************************************
1622 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1624 * Unmarshall a base type.
1626 * NOTES
1627 * Doesn't check that the buffer is long enough before copying, so the caller
1628 * should do this.
1630 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1631 unsigned char FormatChar )
1633 #define BASE_TYPE_UNMARSHALL(type) \
1634 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
1635 TRACE("pMemory: %p\n", pMemory); \
1636 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1637 pStubMsg->Buffer += sizeof(type);
1639 switch(FormatChar)
1641 case RPC_FC_BYTE:
1642 case RPC_FC_CHAR:
1643 case RPC_FC_SMALL:
1644 case RPC_FC_USMALL:
1645 BASE_TYPE_UNMARSHALL(UCHAR);
1646 TRACE("value: 0x%02x\n", *pMemory);
1647 break;
1648 case RPC_FC_WCHAR:
1649 case RPC_FC_SHORT:
1650 case RPC_FC_USHORT:
1651 BASE_TYPE_UNMARSHALL(USHORT);
1652 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
1653 break;
1654 case RPC_FC_LONG:
1655 case RPC_FC_ULONG:
1656 case RPC_FC_ERROR_STATUS_T:
1657 case RPC_FC_ENUM32:
1658 BASE_TYPE_UNMARSHALL(ULONG);
1659 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
1660 break;
1661 case RPC_FC_FLOAT:
1662 BASE_TYPE_UNMARSHALL(float);
1663 TRACE("value: %f\n", *(float *)pMemory);
1664 break;
1665 case RPC_FC_DOUBLE:
1666 BASE_TYPE_UNMARSHALL(double);
1667 TRACE("value: %f\n", *(double *)pMemory);
1668 break;
1669 case RPC_FC_HYPER:
1670 BASE_TYPE_UNMARSHALL(ULONGLONG);
1671 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
1672 break;
1673 case RPC_FC_ENUM16:
1674 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
1675 TRACE("pMemory: %p\n", pMemory);
1676 /* 16-bits on the wire, but int in memory */
1677 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
1678 pStubMsg->Buffer += sizeof(USHORT);
1679 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
1680 break;
1681 case RPC_FC_INT3264:
1682 align_pointer(&pStubMsg->Buffer, sizeof(INT));
1683 /* 32-bits on the wire, but int_ptr in memory */
1684 *(INT_PTR *)pMemory = *(INT *)pStubMsg->Buffer;
1685 pStubMsg->Buffer += sizeof(INT);
1686 TRACE("value: 0x%08lx\n", *(INT_PTR *)pMemory);
1687 break;
1688 case RPC_FC_UINT3264:
1689 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
1690 /* 32-bits on the wire, but int_ptr in memory */
1691 *(UINT_PTR *)pMemory = *(UINT *)pStubMsg->Buffer;
1692 pStubMsg->Buffer += sizeof(UINT);
1693 TRACE("value: 0x%08lx\n", *(UINT_PTR *)pMemory);
1694 break;
1695 case RPC_FC_IGNORE:
1696 break;
1697 default:
1698 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
1700 #undef BASE_TYPE_UNMARSHALL
1703 /***********************************************************************
1704 * NdrSimpleStructMarshall [RPCRT4.@]
1706 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1707 unsigned char *pMemory,
1708 PFORMAT_STRING pFormat)
1710 unsigned size = *(const WORD*)(pFormat+2);
1711 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1713 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1);
1715 pStubMsg->BufferMark = pStubMsg->Buffer;
1716 safe_copy_to_buffer(pStubMsg, pMemory, size);
1718 if (pFormat[0] != RPC_FC_STRUCT)
1719 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1721 return NULL;
1724 /***********************************************************************
1725 * NdrSimpleStructUnmarshall [RPCRT4.@]
1727 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1728 unsigned char **ppMemory,
1729 PFORMAT_STRING pFormat,
1730 unsigned char fMustAlloc)
1732 unsigned size = *(const WORD*)(pFormat+2);
1733 unsigned char *saved_buffer;
1734 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1736 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
1738 if (fMustAlloc)
1739 *ppMemory = NdrAllocate(pStubMsg, size);
1740 else
1742 if (!pStubMsg->IsClient && !*ppMemory)
1743 /* for servers, we just point straight into the RPC buffer */
1744 *ppMemory = pStubMsg->Buffer;
1747 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1748 safe_buffer_increment(pStubMsg, size);
1749 if (pFormat[0] == RPC_FC_PSTRUCT)
1750 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1752 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1753 if (*ppMemory != saved_buffer)
1754 memcpy(*ppMemory, saved_buffer, size);
1756 return NULL;
1759 /***********************************************************************
1760 * NdrSimpleStructBufferSize [RPCRT4.@]
1762 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1763 unsigned char *pMemory,
1764 PFORMAT_STRING pFormat)
1766 unsigned size = *(const WORD*)(pFormat+2);
1767 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1769 align_length(&pStubMsg->BufferLength, pFormat[1] + 1);
1771 safe_buffer_length_increment(pStubMsg, size);
1772 if (pFormat[0] != RPC_FC_STRUCT)
1773 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1776 /***********************************************************************
1777 * NdrSimpleStructMemorySize [RPCRT4.@]
1779 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1780 PFORMAT_STRING pFormat)
1782 unsigned short size = *(const WORD *)(pFormat+2);
1784 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1786 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
1787 pStubMsg->MemorySize += size;
1788 safe_buffer_increment(pStubMsg, size);
1790 if (pFormat[0] != RPC_FC_STRUCT)
1791 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1792 return pStubMsg->MemorySize;
1795 /***********************************************************************
1796 * NdrSimpleStructFree [RPCRT4.@]
1798 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1799 unsigned char *pMemory,
1800 PFORMAT_STRING pFormat)
1802 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1803 if (pFormat[0] != RPC_FC_STRUCT)
1804 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1807 /* Array helpers */
1809 static inline void array_compute_and_size_conformance(
1810 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1811 PFORMAT_STRING pFormat)
1813 DWORD count;
1815 switch (fc)
1817 case RPC_FC_CARRAY:
1818 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1819 SizeConformance(pStubMsg);
1820 break;
1821 case RPC_FC_CVARRAY:
1822 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1823 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1824 SizeConformance(pStubMsg);
1825 break;
1826 case RPC_FC_C_CSTRING:
1827 case RPC_FC_C_WSTRING:
1828 if (fc == RPC_FC_C_CSTRING)
1830 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1831 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1833 else
1835 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1836 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1839 if (pFormat[1] == RPC_FC_STRING_SIZED)
1840 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1841 else
1842 pStubMsg->MaxCount = pStubMsg->ActualCount;
1844 SizeConformance(pStubMsg);
1845 break;
1846 case RPC_FC_BOGUS_ARRAY:
1847 count = *(const WORD *)(pFormat + 2);
1848 pFormat += 4;
1849 if (IsConformanceOrVariancePresent(pFormat)) SizeConformance(pStubMsg);
1850 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, count);
1851 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
1852 break;
1853 default:
1854 ERR("unknown array format 0x%x\n", fc);
1855 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1859 static inline void array_buffer_size(
1860 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1861 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1863 DWORD i, size;
1864 DWORD esize;
1865 unsigned char alignment;
1867 switch (fc)
1869 case RPC_FC_CARRAY:
1870 esize = *(const WORD*)(pFormat+2);
1871 alignment = pFormat[1] + 1;
1873 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1875 align_length(&pStubMsg->BufferLength, alignment);
1877 size = safe_multiply(esize, pStubMsg->MaxCount);
1878 /* conformance value plus array */
1879 safe_buffer_length_increment(pStubMsg, size);
1881 if (fHasPointers)
1882 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1883 break;
1884 case RPC_FC_CVARRAY:
1885 esize = *(const WORD*)(pFormat+2);
1886 alignment = pFormat[1] + 1;
1888 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1889 pFormat = SkipVariance(pStubMsg, pFormat);
1891 SizeVariance(pStubMsg);
1893 align_length(&pStubMsg->BufferLength, alignment);
1895 size = safe_multiply(esize, pStubMsg->ActualCount);
1896 safe_buffer_length_increment(pStubMsg, size);
1898 if (fHasPointers)
1899 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1900 break;
1901 case RPC_FC_C_CSTRING:
1902 case RPC_FC_C_WSTRING:
1903 if (fc == RPC_FC_C_CSTRING)
1904 esize = 1;
1905 else
1906 esize = 2;
1908 SizeVariance(pStubMsg);
1910 size = safe_multiply(esize, pStubMsg->ActualCount);
1911 safe_buffer_length_increment(pStubMsg, size);
1912 break;
1913 case RPC_FC_BOGUS_ARRAY:
1914 alignment = pFormat[1] + 1;
1915 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1916 if (IsConformanceOrVariancePresent(pFormat)) SizeVariance(pStubMsg);
1917 pFormat = SkipVariance(pStubMsg, pFormat);
1919 align_length(&pStubMsg->BufferLength, alignment);
1921 size = pStubMsg->ActualCount;
1922 for (i = 0; i < size; i++)
1923 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
1924 break;
1925 default:
1926 ERR("unknown array format 0x%x\n", fc);
1927 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1931 static inline void array_compute_and_write_conformance(
1932 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1933 PFORMAT_STRING pFormat)
1935 ULONG def;
1936 BOOL conformance_present;
1938 switch (fc)
1940 case RPC_FC_CARRAY:
1941 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1942 WriteConformance(pStubMsg);
1943 break;
1944 case RPC_FC_CVARRAY:
1945 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1946 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1947 WriteConformance(pStubMsg);
1948 break;
1949 case RPC_FC_C_CSTRING:
1950 case RPC_FC_C_WSTRING:
1951 if (fc == RPC_FC_C_CSTRING)
1953 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1954 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1956 else
1958 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1959 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1961 if (pFormat[1] == RPC_FC_STRING_SIZED)
1962 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1963 else
1964 pStubMsg->MaxCount = pStubMsg->ActualCount;
1965 pStubMsg->Offset = 0;
1966 WriteConformance(pStubMsg);
1967 break;
1968 case RPC_FC_BOGUS_ARRAY:
1969 def = *(const WORD *)(pFormat + 2);
1970 pFormat += 4;
1971 conformance_present = IsConformanceOrVariancePresent(pFormat);
1972 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
1973 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
1974 if (conformance_present) WriteConformance(pStubMsg);
1975 break;
1976 default:
1977 ERR("unknown array format 0x%x\n", fc);
1978 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1982 static inline void array_write_variance_and_marshall(
1983 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1984 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1986 DWORD i, size;
1987 DWORD esize;
1988 unsigned char alignment;
1990 switch (fc)
1992 case RPC_FC_CARRAY:
1993 esize = *(const WORD*)(pFormat+2);
1994 alignment = pFormat[1] + 1;
1996 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1998 align_pointer_clear(&pStubMsg->Buffer, alignment);
2000 size = safe_multiply(esize, pStubMsg->MaxCount);
2001 if (fHasPointers)
2002 pStubMsg->BufferMark = pStubMsg->Buffer;
2003 safe_copy_to_buffer(pStubMsg, pMemory, size);
2005 if (fHasPointers)
2006 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2007 break;
2008 case RPC_FC_CVARRAY:
2009 esize = *(const WORD*)(pFormat+2);
2010 alignment = pFormat[1] + 1;
2012 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2013 pFormat = SkipVariance(pStubMsg, pFormat);
2015 WriteVariance(pStubMsg);
2017 align_pointer_clear(&pStubMsg->Buffer, alignment);
2019 size = safe_multiply(esize, pStubMsg->ActualCount);
2021 if (fHasPointers)
2022 pStubMsg->BufferMark = pStubMsg->Buffer;
2023 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size);
2025 if (fHasPointers)
2026 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2027 break;
2028 case RPC_FC_C_CSTRING:
2029 case RPC_FC_C_WSTRING:
2030 if (fc == RPC_FC_C_CSTRING)
2031 esize = 1;
2032 else
2033 esize = 2;
2035 WriteVariance(pStubMsg);
2037 size = safe_multiply(esize, pStubMsg->ActualCount);
2038 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2039 break;
2040 case RPC_FC_BOGUS_ARRAY:
2041 alignment = pFormat[1] + 1;
2042 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2043 if (IsConformanceOrVariancePresent(pFormat)) WriteVariance(pStubMsg);
2044 pFormat = SkipVariance(pStubMsg, pFormat);
2046 align_pointer_clear(&pStubMsg->Buffer, alignment);
2048 size = pStubMsg->ActualCount;
2049 for (i = 0; i < size; i++)
2050 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2051 break;
2052 default:
2053 ERR("unknown array format 0x%x\n", fc);
2054 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2058 static inline ULONG array_read_conformance(
2059 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
2061 DWORD def, esize;
2063 switch (fc)
2065 case RPC_FC_CARRAY:
2066 esize = *(const WORD*)(pFormat+2);
2067 pFormat = ReadConformance(pStubMsg, pFormat+4);
2068 return safe_multiply(esize, pStubMsg->MaxCount);
2069 case RPC_FC_CVARRAY:
2070 esize = *(const WORD*)(pFormat+2);
2071 pFormat = ReadConformance(pStubMsg, pFormat+4);
2072 return safe_multiply(esize, pStubMsg->MaxCount);
2073 case RPC_FC_C_CSTRING:
2074 case RPC_FC_C_WSTRING:
2075 if (fc == RPC_FC_C_CSTRING)
2076 esize = 1;
2077 else
2078 esize = 2;
2080 if (pFormat[1] == RPC_FC_STRING_SIZED)
2081 ReadConformance(pStubMsg, pFormat + 2);
2082 else
2083 ReadConformance(pStubMsg, NULL);
2084 return safe_multiply(esize, pStubMsg->MaxCount);
2085 case RPC_FC_BOGUS_ARRAY:
2086 def = *(const WORD *)(pFormat + 2);
2087 pFormat += 4;
2088 if (IsConformanceOrVariancePresent(pFormat)) pFormat = ReadConformance(pStubMsg, pFormat);
2089 else
2091 pStubMsg->MaxCount = def;
2092 pFormat = SkipConformance( pStubMsg, pFormat );
2094 pFormat = SkipVariance( pStubMsg, pFormat );
2096 esize = ComplexStructSize(pStubMsg, pFormat);
2097 return safe_multiply(pStubMsg->MaxCount, esize);
2098 default:
2099 ERR("unknown array format 0x%x\n", fc);
2100 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2104 static inline ULONG array_read_variance_and_unmarshall(
2105 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory,
2106 PFORMAT_STRING pFormat, unsigned char fMustAlloc,
2107 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall)
2109 ULONG bufsize, memsize;
2110 WORD esize;
2111 unsigned char alignment;
2112 unsigned char *saved_buffer, *pMemory;
2113 ULONG i, offset, count;
2115 switch (fc)
2117 case RPC_FC_CARRAY:
2118 esize = *(const WORD*)(pFormat+2);
2119 alignment = pFormat[1] + 1;
2121 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2123 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2125 align_pointer(&pStubMsg->Buffer, alignment);
2127 if (fUnmarshall)
2129 if (fMustAlloc)
2130 *ppMemory = NdrAllocate(pStubMsg, memsize);
2131 else
2133 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory)
2134 /* for servers, we just point straight into the RPC buffer */
2135 *ppMemory = pStubMsg->Buffer;
2138 saved_buffer = pStubMsg->Buffer;
2139 safe_buffer_increment(pStubMsg, bufsize);
2141 pStubMsg->BufferMark = saved_buffer;
2142 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2144 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2145 if (*ppMemory != saved_buffer)
2146 memcpy(*ppMemory, saved_buffer, bufsize);
2148 return bufsize;
2149 case RPC_FC_CVARRAY:
2150 esize = *(const WORD*)(pFormat+2);
2151 alignment = pFormat[1] + 1;
2153 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2155 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2157 align_pointer(&pStubMsg->Buffer, alignment);
2159 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2160 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2162 if (fUnmarshall)
2164 offset = pStubMsg->Offset;
2166 if (!fMustAlloc && !*ppMemory)
2167 fMustAlloc = TRUE;
2168 if (fMustAlloc)
2169 *ppMemory = NdrAllocate(pStubMsg, memsize);
2170 saved_buffer = pStubMsg->Buffer;
2171 safe_buffer_increment(pStubMsg, bufsize);
2173 pStubMsg->BufferMark = saved_buffer;
2174 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat,
2175 fMustAlloc);
2177 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2179 return bufsize;
2180 case RPC_FC_C_CSTRING:
2181 case RPC_FC_C_WSTRING:
2182 if (fc == RPC_FC_C_CSTRING)
2183 esize = 1;
2184 else
2185 esize = 2;
2187 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2189 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2191 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2192 pStubMsg->ActualCount, pStubMsg->MaxCount);
2193 RpcRaiseException(RPC_S_INVALID_BOUND);
2195 if (pStubMsg->Offset)
2197 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2198 RpcRaiseException(RPC_S_INVALID_BOUND);
2201 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2202 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2204 validate_string_data(pStubMsg, bufsize, esize);
2206 if (fUnmarshall)
2208 if (fMustAlloc)
2209 *ppMemory = NdrAllocate(pStubMsg, memsize);
2210 else
2212 if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
2213 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
2214 /* if the data in the RPC buffer is big enough, we just point
2215 * straight into it */
2216 *ppMemory = pStubMsg->Buffer;
2217 else if (!*ppMemory)
2218 *ppMemory = NdrAllocate(pStubMsg, memsize);
2221 if (*ppMemory == pStubMsg->Buffer)
2222 safe_buffer_increment(pStubMsg, bufsize);
2223 else
2224 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2226 if (*pFormat == RPC_FC_C_CSTRING)
2227 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
2228 else
2229 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
2231 return bufsize;
2233 case RPC_FC_BOGUS_ARRAY:
2234 alignment = pFormat[1] + 1;
2235 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2236 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2238 esize = ComplexStructSize(pStubMsg, pFormat);
2239 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2241 assert( fUnmarshall );
2243 if (!fMustAlloc && !*ppMemory)
2244 fMustAlloc = TRUE;
2245 if (fMustAlloc)
2246 *ppMemory = NdrAllocate(pStubMsg, memsize);
2248 align_pointer(&pStubMsg->Buffer, alignment);
2249 saved_buffer = pStubMsg->Buffer;
2251 pMemory = *ppMemory;
2252 count = pStubMsg->ActualCount;
2253 for (i = 0; i < count; i++)
2254 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
2255 return pStubMsg->Buffer - saved_buffer;
2257 default:
2258 ERR("unknown array format 0x%x\n", fc);
2259 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2263 static inline void array_memory_size(
2264 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
2265 unsigned char fHasPointers)
2267 ULONG i, count, SavedMemorySize;
2268 ULONG bufsize, memsize;
2269 DWORD esize;
2270 unsigned char alignment;
2272 switch (fc)
2274 case RPC_FC_CARRAY:
2275 esize = *(const WORD*)(pFormat+2);
2276 alignment = pFormat[1] + 1;
2278 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2280 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2281 pStubMsg->MemorySize += memsize;
2283 align_pointer(&pStubMsg->Buffer, alignment);
2284 if (fHasPointers)
2285 pStubMsg->BufferMark = pStubMsg->Buffer;
2286 safe_buffer_increment(pStubMsg, bufsize);
2288 if (fHasPointers)
2289 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2290 break;
2291 case RPC_FC_CVARRAY:
2292 esize = *(const WORD*)(pFormat+2);
2293 alignment = pFormat[1] + 1;
2295 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2297 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2299 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2300 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2301 pStubMsg->MemorySize += memsize;
2303 align_pointer(&pStubMsg->Buffer, alignment);
2304 if (fHasPointers)
2305 pStubMsg->BufferMark = pStubMsg->Buffer;
2306 safe_buffer_increment(pStubMsg, bufsize);
2308 if (fHasPointers)
2309 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2310 break;
2311 case RPC_FC_C_CSTRING:
2312 case RPC_FC_C_WSTRING:
2313 if (fc == RPC_FC_C_CSTRING)
2314 esize = 1;
2315 else
2316 esize = 2;
2318 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2320 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2322 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2323 pStubMsg->ActualCount, pStubMsg->MaxCount);
2324 RpcRaiseException(RPC_S_INVALID_BOUND);
2326 if (pStubMsg->Offset)
2328 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2329 RpcRaiseException(RPC_S_INVALID_BOUND);
2332 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2333 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2335 validate_string_data(pStubMsg, bufsize, esize);
2337 safe_buffer_increment(pStubMsg, bufsize);
2338 pStubMsg->MemorySize += memsize;
2339 break;
2340 case RPC_FC_BOGUS_ARRAY:
2341 alignment = pFormat[1] + 1;
2342 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2343 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2345 align_pointer(&pStubMsg->Buffer, alignment);
2347 SavedMemorySize = pStubMsg->MemorySize;
2349 esize = ComplexStructSize(pStubMsg, pFormat);
2350 memsize = safe_multiply(pStubMsg->MaxCount, esize);
2352 count = pStubMsg->ActualCount;
2353 for (i = 0; i < count; i++)
2354 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
2356 pStubMsg->MemorySize = SavedMemorySize + memsize;
2357 break;
2358 default:
2359 ERR("unknown array format 0x%x\n", fc);
2360 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2364 static inline void array_free(
2365 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
2366 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
2368 DWORD i, count;
2370 switch (fc)
2372 case RPC_FC_CARRAY:
2373 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2374 if (fHasPointers)
2375 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2376 break;
2377 case RPC_FC_CVARRAY:
2378 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2379 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2380 if (fHasPointers)
2381 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2382 break;
2383 case RPC_FC_C_CSTRING:
2384 case RPC_FC_C_WSTRING:
2385 /* No embedded pointers so nothing to do */
2386 break;
2387 case RPC_FC_BOGUS_ARRAY:
2388 count = *(const WORD *)(pFormat + 2);
2389 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, count);
2390 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2392 count = pStubMsg->ActualCount;
2393 for (i = 0; i < count; i++)
2394 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2395 break;
2396 default:
2397 ERR("unknown array format 0x%x\n", fc);
2398 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2403 * NdrConformantString:
2405 * What MS calls a ConformantString is, in DCE terminology,
2406 * a Varying-Conformant String.
2408 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2409 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2410 * into unmarshalled string)
2411 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2413 * data: CHARTYPE[maxlen]
2415 * ], where CHARTYPE is the appropriate character type (specified externally)
2419 /***********************************************************************
2420 * NdrConformantStringMarshall [RPCRT4.@]
2422 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
2423 unsigned char *pszMessage, PFORMAT_STRING pFormat)
2425 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
2427 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2428 ERR("Unhandled string type: %#x\n", pFormat[0]);
2429 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2432 /* allow compiler to optimise inline function by passing constant into
2433 * these functions */
2434 if (pFormat[0] == RPC_FC_C_CSTRING) {
2435 array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2436 pFormat);
2437 array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2438 pFormat, TRUE /* fHasPointers */);
2439 } else {
2440 array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2441 pFormat);
2442 array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2443 pFormat, TRUE /* fHasPointers */);
2446 return NULL;
2449 /***********************************************************************
2450 * NdrConformantStringBufferSize [RPCRT4.@]
2452 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2453 unsigned char* pMemory, PFORMAT_STRING pFormat)
2455 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2457 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2458 ERR("Unhandled string type: %#x\n", pFormat[0]);
2459 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2462 /* allow compiler to optimise inline function by passing constant into
2463 * these functions */
2464 if (pFormat[0] == RPC_FC_C_CSTRING) {
2465 array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory,
2466 pFormat);
2467 array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat,
2468 TRUE /* fHasPointers */);
2469 } else {
2470 array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory,
2471 pFormat);
2472 array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat,
2473 TRUE /* fHasPointers */);
2477 /************************************************************************
2478 * NdrConformantStringMemorySize [RPCRT4.@]
2480 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2481 PFORMAT_STRING pFormat )
2483 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2485 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2486 ERR("Unhandled string type: %#x\n", pFormat[0]);
2487 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2490 /* allow compiler to optimise inline function by passing constant into
2491 * these functions */
2492 if (pFormat[0] == RPC_FC_C_CSTRING) {
2493 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2494 array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat,
2495 TRUE /* fHasPointers */);
2496 } else {
2497 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2498 array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat,
2499 TRUE /* fHasPointers */);
2502 return pStubMsg->MemorySize;
2505 /************************************************************************
2506 * NdrConformantStringUnmarshall [RPCRT4.@]
2508 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2509 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
2511 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2512 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2514 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2515 ERR("Unhandled string type: %#x\n", *pFormat);
2516 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2519 /* allow compiler to optimise inline function by passing constant into
2520 * these functions */
2521 if (pFormat[0] == RPC_FC_C_CSTRING) {
2522 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2523 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory,
2524 pFormat, fMustAlloc,
2525 TRUE /* fUseBufferMemoryServer */,
2526 TRUE /* fUnmarshall */);
2527 } else {
2528 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2529 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory,
2530 pFormat, fMustAlloc,
2531 TRUE /* fUseBufferMemoryServer */,
2532 TRUE /* fUnmarshall */);
2535 return NULL;
2538 /***********************************************************************
2539 * NdrNonConformantStringMarshall [RPCRT4.@]
2541 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2542 unsigned char *pMemory,
2543 PFORMAT_STRING pFormat)
2545 ULONG esize, size, maxsize;
2547 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2549 maxsize = *(const USHORT *)&pFormat[2];
2551 if (*pFormat == RPC_FC_CSTRING)
2553 ULONG i = 0;
2554 const char *str = (const char *)pMemory;
2555 while (i < maxsize && str[i]) i++;
2556 TRACE("string=%s\n", debugstr_an(str, i));
2557 pStubMsg->ActualCount = i + 1;
2558 esize = 1;
2560 else if (*pFormat == RPC_FC_WSTRING)
2562 ULONG i = 0;
2563 const WCHAR *str = (const WCHAR *)pMemory;
2564 while (i < maxsize && str[i]) i++;
2565 TRACE("string=%s\n", debugstr_wn(str, i));
2566 pStubMsg->ActualCount = i + 1;
2567 esize = 2;
2569 else
2571 ERR("Unhandled string type: %#x\n", *pFormat);
2572 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2575 pStubMsg->Offset = 0;
2576 WriteVariance(pStubMsg);
2578 size = safe_multiply(esize, pStubMsg->ActualCount);
2579 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2581 return NULL;
2584 /***********************************************************************
2585 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2587 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2588 unsigned char **ppMemory,
2589 PFORMAT_STRING pFormat,
2590 unsigned char fMustAlloc)
2592 ULONG bufsize, memsize, esize, maxsize;
2594 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2595 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2597 maxsize = *(const USHORT *)&pFormat[2];
2599 ReadVariance(pStubMsg, NULL, maxsize);
2600 if (pStubMsg->Offset)
2602 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2603 RpcRaiseException(RPC_S_INVALID_BOUND);
2606 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2607 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2608 else
2610 ERR("Unhandled string type: %#x\n", *pFormat);
2611 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2614 memsize = esize * maxsize;
2615 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2617 validate_string_data(pStubMsg, bufsize, esize);
2619 if (!fMustAlloc && !*ppMemory)
2620 fMustAlloc = TRUE;
2621 if (fMustAlloc)
2622 *ppMemory = NdrAllocate(pStubMsg, memsize);
2624 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2626 if (*pFormat == RPC_FC_CSTRING) {
2627 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
2629 else if (*pFormat == RPC_FC_WSTRING) {
2630 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
2633 return NULL;
2636 /***********************************************************************
2637 * NdrNonConformantStringBufferSize [RPCRT4.@]
2639 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2640 unsigned char *pMemory,
2641 PFORMAT_STRING pFormat)
2643 ULONG esize, maxsize;
2645 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2647 maxsize = *(const USHORT *)&pFormat[2];
2649 SizeVariance(pStubMsg);
2651 if (*pFormat == RPC_FC_CSTRING)
2653 ULONG i = 0;
2654 const char *str = (const char *)pMemory;
2655 while (i < maxsize && str[i]) i++;
2656 TRACE("string=%s\n", debugstr_an(str, i));
2657 pStubMsg->ActualCount = i + 1;
2658 esize = 1;
2660 else if (*pFormat == RPC_FC_WSTRING)
2662 ULONG i = 0;
2663 const WCHAR *str = (const WCHAR *)pMemory;
2664 while (i < maxsize && str[i]) i++;
2665 TRACE("string=%s\n", debugstr_wn(str, i));
2666 pStubMsg->ActualCount = i + 1;
2667 esize = 2;
2669 else
2671 ERR("Unhandled string type: %#x\n", *pFormat);
2672 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2675 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2678 /***********************************************************************
2679 * NdrNonConformantStringMemorySize [RPCRT4.@]
2681 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2682 PFORMAT_STRING pFormat)
2684 ULONG bufsize, memsize, esize, maxsize;
2686 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2688 maxsize = *(const USHORT *)&pFormat[2];
2690 ReadVariance(pStubMsg, NULL, maxsize);
2692 if (pStubMsg->Offset)
2694 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2695 RpcRaiseException(RPC_S_INVALID_BOUND);
2698 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2699 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2700 else
2702 ERR("Unhandled string type: %#x\n", *pFormat);
2703 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2706 memsize = esize * maxsize;
2707 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2709 validate_string_data(pStubMsg, bufsize, esize);
2711 safe_buffer_increment(pStubMsg, bufsize);
2712 pStubMsg->MemorySize += memsize;
2714 return pStubMsg->MemorySize;
2717 /* Complex types */
2719 #include "pshpack1.h"
2720 typedef struct
2722 unsigned char type;
2723 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2724 ULONG low_value;
2725 ULONG high_value;
2726 } NDR_RANGE;
2727 #include "poppack.h"
2729 static ULONG EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2730 PFORMAT_STRING pFormat)
2732 switch (*pFormat) {
2733 case RPC_FC_STRUCT:
2734 case RPC_FC_PSTRUCT:
2735 case RPC_FC_CSTRUCT:
2736 case RPC_FC_BOGUS_STRUCT:
2737 case RPC_FC_SMFARRAY:
2738 case RPC_FC_SMVARRAY:
2739 case RPC_FC_CSTRING:
2740 return *(const WORD*)&pFormat[2];
2741 case RPC_FC_USER_MARSHAL:
2742 return *(const WORD*)&pFormat[4];
2743 case RPC_FC_RANGE: {
2744 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2745 case RPC_FC_BYTE:
2746 case RPC_FC_CHAR:
2747 case RPC_FC_SMALL:
2748 case RPC_FC_USMALL:
2749 return sizeof(UCHAR);
2750 case RPC_FC_WCHAR:
2751 case RPC_FC_SHORT:
2752 case RPC_FC_USHORT:
2753 return sizeof(USHORT);
2754 case RPC_FC_LONG:
2755 case RPC_FC_ULONG:
2756 case RPC_FC_ENUM32:
2757 case RPC_FC_INT3264:
2758 case RPC_FC_UINT3264:
2759 return sizeof(ULONG);
2760 case RPC_FC_FLOAT:
2761 return sizeof(float);
2762 case RPC_FC_DOUBLE:
2763 return sizeof(double);
2764 case RPC_FC_HYPER:
2765 return sizeof(ULONGLONG);
2766 case RPC_FC_ENUM16:
2767 return sizeof(UINT);
2768 default:
2769 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2770 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2773 case RPC_FC_NON_ENCAPSULATED_UNION:
2774 pFormat += 2;
2775 pFormat = SkipConformance(pStubMsg, pFormat);
2776 pFormat += *(const SHORT*)pFormat;
2777 return *(const SHORT*)pFormat;
2778 case RPC_FC_IP:
2779 return sizeof(void *);
2780 case RPC_FC_WSTRING:
2781 return *(const WORD*)&pFormat[2] * 2;
2782 default:
2783 FIXME("unhandled embedded type %02x\n", *pFormat);
2785 return 0;
2789 static ULONG EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2790 PFORMAT_STRING pFormat)
2792 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2794 if (!m)
2796 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2797 return 0;
2800 return m(pStubMsg, pFormat);
2804 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2805 unsigned char *pMemory,
2806 PFORMAT_STRING pFormat,
2807 PFORMAT_STRING pPointer)
2809 PFORMAT_STRING desc;
2810 NDR_MARSHALL m;
2811 ULONG size;
2813 while (*pFormat != RPC_FC_END) {
2814 switch (*pFormat) {
2815 case RPC_FC_BYTE:
2816 case RPC_FC_CHAR:
2817 case RPC_FC_SMALL:
2818 case RPC_FC_USMALL:
2819 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2820 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2821 pMemory += 1;
2822 break;
2823 case RPC_FC_WCHAR:
2824 case RPC_FC_SHORT:
2825 case RPC_FC_USHORT:
2826 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2827 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2828 pMemory += 2;
2829 break;
2830 case RPC_FC_ENUM16:
2832 USHORT val = *(DWORD *)pMemory;
2833 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2834 if (32767 < *(DWORD*)pMemory)
2835 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2836 safe_copy_to_buffer(pStubMsg, &val, 2);
2837 pMemory += 4;
2838 break;
2840 case RPC_FC_LONG:
2841 case RPC_FC_ULONG:
2842 case RPC_FC_ENUM32:
2843 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2844 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2845 pMemory += 4;
2846 break;
2847 case RPC_FC_INT3264:
2848 case RPC_FC_UINT3264:
2850 UINT val = *(UINT_PTR *)pMemory;
2851 TRACE("int3264=%ld <= %p\n", *(UINT_PTR *)pMemory, pMemory);
2852 safe_copy_to_buffer(pStubMsg, &val, sizeof(UINT));
2853 pMemory += sizeof(UINT_PTR);
2854 break;
2856 case RPC_FC_FLOAT:
2857 TRACE("float=%f <= %p\n", *(float*)pMemory, pMemory);
2858 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
2859 pMemory += sizeof(float);
2860 break;
2861 case RPC_FC_HYPER:
2862 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2863 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2864 pMemory += 8;
2865 break;
2866 case RPC_FC_DOUBLE:
2867 TRACE("double=%f <= %p\n", *(double*)pMemory, pMemory);
2868 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
2869 pMemory += sizeof(double);
2870 break;
2871 case RPC_FC_RP:
2872 case RPC_FC_UP:
2873 case RPC_FC_OP:
2874 case RPC_FC_FP:
2875 case RPC_FC_POINTER:
2877 unsigned char *saved_buffer;
2878 BOOL pointer_buffer_mark_set = FALSE;
2879 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2880 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2881 if (*pFormat != RPC_FC_POINTER)
2882 pPointer = pFormat;
2883 if (*pPointer != RPC_FC_RP)
2884 align_pointer_clear(&pStubMsg->Buffer, 4);
2885 saved_buffer = pStubMsg->Buffer;
2886 if (pStubMsg->PointerBufferMark)
2888 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2889 pStubMsg->PointerBufferMark = NULL;
2890 pointer_buffer_mark_set = TRUE;
2892 else if (*pPointer != RPC_FC_RP)
2893 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2894 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2895 if (pointer_buffer_mark_set)
2897 STD_OVERFLOW_CHECK(pStubMsg);
2898 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2899 pStubMsg->Buffer = saved_buffer;
2900 if (*pPointer != RPC_FC_RP)
2901 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2903 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2904 if (*pFormat == RPC_FC_POINTER)
2905 pPointer += 4;
2906 else
2907 pFormat += 4;
2908 pMemory += sizeof(void *);
2909 break;
2911 case RPC_FC_ALIGNM2:
2912 align_pointer(&pMemory, 2);
2913 break;
2914 case RPC_FC_ALIGNM4:
2915 align_pointer(&pMemory, 4);
2916 break;
2917 case RPC_FC_ALIGNM8:
2918 align_pointer(&pMemory, 8);
2919 break;
2920 case RPC_FC_STRUCTPAD1:
2921 case RPC_FC_STRUCTPAD2:
2922 case RPC_FC_STRUCTPAD3:
2923 case RPC_FC_STRUCTPAD4:
2924 case RPC_FC_STRUCTPAD5:
2925 case RPC_FC_STRUCTPAD6:
2926 case RPC_FC_STRUCTPAD7:
2927 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2928 break;
2929 case RPC_FC_EMBEDDED_COMPLEX:
2930 pMemory += pFormat[1];
2931 pFormat += 2;
2932 desc = pFormat + *(const SHORT*)pFormat;
2933 size = EmbeddedComplexSize(pStubMsg, desc);
2934 TRACE("embedded complex (size=%d) <= %p\n", size, pMemory);
2935 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2936 if (m)
2938 /* for some reason interface pointers aren't generated as
2939 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2940 * they still need the derefencing treatment that pointers are
2941 * given */
2942 if (*desc == RPC_FC_IP)
2943 m(pStubMsg, *(unsigned char **)pMemory, desc);
2944 else
2945 m(pStubMsg, pMemory, desc);
2947 else FIXME("no marshaller for embedded type %02x\n", *desc);
2948 pMemory += size;
2949 pFormat += 2;
2950 continue;
2951 case RPC_FC_PAD:
2952 break;
2953 default:
2954 FIXME("unhandled format 0x%02x\n", *pFormat);
2956 pFormat++;
2959 return pMemory;
2962 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2963 unsigned char *pMemory,
2964 PFORMAT_STRING pFormat,
2965 PFORMAT_STRING pPointer,
2966 unsigned char fMustAlloc)
2968 PFORMAT_STRING desc;
2969 NDR_UNMARSHALL m;
2970 ULONG size;
2972 while (*pFormat != RPC_FC_END) {
2973 switch (*pFormat) {
2974 case RPC_FC_BYTE:
2975 case RPC_FC_CHAR:
2976 case RPC_FC_SMALL:
2977 case RPC_FC_USMALL:
2978 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2979 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2980 pMemory += 1;
2981 break;
2982 case RPC_FC_WCHAR:
2983 case RPC_FC_SHORT:
2984 case RPC_FC_USHORT:
2985 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2986 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2987 pMemory += 2;
2988 break;
2989 case RPC_FC_ENUM16:
2991 WORD val;
2992 safe_copy_from_buffer(pStubMsg, &val, 2);
2993 *(DWORD*)pMemory = val;
2994 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
2995 if (32767 < *(DWORD*)pMemory)
2996 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2997 pMemory += 4;
2998 break;
3000 case RPC_FC_LONG:
3001 case RPC_FC_ULONG:
3002 case RPC_FC_ENUM32:
3003 safe_copy_from_buffer(pStubMsg, pMemory, 4);
3004 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
3005 pMemory += 4;
3006 break;
3007 case RPC_FC_INT3264:
3009 INT val;
3010 safe_copy_from_buffer(pStubMsg, &val, 4);
3011 *(INT_PTR *)pMemory = val;
3012 TRACE("int3264=%ld => %p\n", *(INT_PTR*)pMemory, pMemory);
3013 pMemory += sizeof(INT_PTR);
3014 break;
3016 case RPC_FC_UINT3264:
3018 UINT val;
3019 safe_copy_from_buffer(pStubMsg, &val, 4);
3020 *(UINT_PTR *)pMemory = val;
3021 TRACE("uint3264=%ld => %p\n", *(UINT_PTR*)pMemory, pMemory);
3022 pMemory += sizeof(UINT_PTR);
3023 break;
3025 case RPC_FC_FLOAT:
3026 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(float));
3027 TRACE("float=%f => %p\n", *(float*)pMemory, pMemory);
3028 pMemory += sizeof(float);
3029 break;
3030 case RPC_FC_HYPER:
3031 safe_copy_from_buffer(pStubMsg, pMemory, 8);
3032 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
3033 pMemory += 8;
3034 break;
3035 case RPC_FC_DOUBLE:
3036 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(double));
3037 TRACE("double=%f => %p\n", *(double*)pMemory, pMemory);
3038 pMemory += sizeof(double);
3039 break;
3040 case RPC_FC_RP:
3041 case RPC_FC_UP:
3042 case RPC_FC_OP:
3043 case RPC_FC_FP:
3044 case RPC_FC_POINTER:
3046 unsigned char *saved_buffer;
3047 BOOL pointer_buffer_mark_set = FALSE;
3048 TRACE("pointer => %p\n", pMemory);
3049 if (*pFormat != RPC_FC_POINTER)
3050 pPointer = pFormat;
3051 if (*pPointer != RPC_FC_RP)
3052 align_pointer(&pStubMsg->Buffer, 4);
3053 saved_buffer = pStubMsg->Buffer;
3054 if (pStubMsg->PointerBufferMark)
3056 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3057 pStubMsg->PointerBufferMark = NULL;
3058 pointer_buffer_mark_set = TRUE;
3060 else if (*pPointer != RPC_FC_RP)
3061 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3063 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
3064 if (pointer_buffer_mark_set)
3066 STD_OVERFLOW_CHECK(pStubMsg);
3067 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3068 pStubMsg->Buffer = saved_buffer;
3069 if (*pPointer != RPC_FC_RP)
3070 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3072 if (*pFormat == RPC_FC_POINTER)
3073 pPointer += 4;
3074 else
3075 pFormat += 4;
3076 pMemory += sizeof(void *);
3077 break;
3079 case RPC_FC_ALIGNM2:
3080 align_pointer_clear(&pMemory, 2);
3081 break;
3082 case RPC_FC_ALIGNM4:
3083 align_pointer_clear(&pMemory, 4);
3084 break;
3085 case RPC_FC_ALIGNM8:
3086 align_pointer_clear(&pMemory, 8);
3087 break;
3088 case RPC_FC_STRUCTPAD1:
3089 case RPC_FC_STRUCTPAD2:
3090 case RPC_FC_STRUCTPAD3:
3091 case RPC_FC_STRUCTPAD4:
3092 case RPC_FC_STRUCTPAD5:
3093 case RPC_FC_STRUCTPAD6:
3094 case RPC_FC_STRUCTPAD7:
3095 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
3096 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3097 break;
3098 case RPC_FC_EMBEDDED_COMPLEX:
3099 pMemory += pFormat[1];
3100 pFormat += 2;
3101 desc = pFormat + *(const SHORT*)pFormat;
3102 size = EmbeddedComplexSize(pStubMsg, desc);
3103 TRACE("embedded complex (size=%d) => %p\n", size, pMemory);
3104 if (fMustAlloc)
3105 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
3106 * since the type is part of the memory block that is encompassed by
3107 * the whole complex type. Memory is forced to allocate when pointers
3108 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
3109 * clearing the memory we pass in to the unmarshaller */
3110 memset(pMemory, 0, size);
3111 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
3112 if (m)
3114 /* for some reason interface pointers aren't generated as
3115 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3116 * they still need the derefencing treatment that pointers are
3117 * given */
3118 if (*desc == RPC_FC_IP)
3119 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
3120 else
3121 m(pStubMsg, &pMemory, desc, FALSE);
3123 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
3124 pMemory += size;
3125 pFormat += 2;
3126 continue;
3127 case RPC_FC_PAD:
3128 break;
3129 default:
3130 FIXME("unhandled format %d\n", *pFormat);
3132 pFormat++;
3135 return pMemory;
3138 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3139 unsigned char *pMemory,
3140 PFORMAT_STRING pFormat,
3141 PFORMAT_STRING pPointer)
3143 PFORMAT_STRING desc;
3144 NDR_BUFFERSIZE m;
3145 ULONG size;
3147 while (*pFormat != RPC_FC_END) {
3148 switch (*pFormat) {
3149 case RPC_FC_BYTE:
3150 case RPC_FC_CHAR:
3151 case RPC_FC_SMALL:
3152 case RPC_FC_USMALL:
3153 safe_buffer_length_increment(pStubMsg, 1);
3154 pMemory += 1;
3155 break;
3156 case RPC_FC_WCHAR:
3157 case RPC_FC_SHORT:
3158 case RPC_FC_USHORT:
3159 safe_buffer_length_increment(pStubMsg, 2);
3160 pMemory += 2;
3161 break;
3162 case RPC_FC_ENUM16:
3163 safe_buffer_length_increment(pStubMsg, 2);
3164 pMemory += 4;
3165 break;
3166 case RPC_FC_LONG:
3167 case RPC_FC_ULONG:
3168 case RPC_FC_ENUM32:
3169 case RPC_FC_FLOAT:
3170 safe_buffer_length_increment(pStubMsg, 4);
3171 pMemory += 4;
3172 break;
3173 case RPC_FC_INT3264:
3174 case RPC_FC_UINT3264:
3175 safe_buffer_length_increment(pStubMsg, 4);
3176 pMemory += sizeof(INT_PTR);
3177 break;
3178 case RPC_FC_HYPER:
3179 case RPC_FC_DOUBLE:
3180 safe_buffer_length_increment(pStubMsg, 8);
3181 pMemory += 8;
3182 break;
3183 case RPC_FC_RP:
3184 case RPC_FC_UP:
3185 case RPC_FC_OP:
3186 case RPC_FC_FP:
3187 case RPC_FC_POINTER:
3188 if (*pFormat != RPC_FC_POINTER)
3189 pPointer = pFormat;
3190 if (!pStubMsg->IgnoreEmbeddedPointers)
3192 int saved_buffer_length = pStubMsg->BufferLength;
3193 pStubMsg->BufferLength = pStubMsg->PointerLength;
3194 pStubMsg->PointerLength = 0;
3195 if(!pStubMsg->BufferLength)
3196 ERR("BufferLength == 0??\n");
3197 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
3198 pStubMsg->PointerLength = pStubMsg->BufferLength;
3199 pStubMsg->BufferLength = saved_buffer_length;
3201 if (*pPointer != RPC_FC_RP)
3203 align_length(&pStubMsg->BufferLength, 4);
3204 safe_buffer_length_increment(pStubMsg, 4);
3206 if (*pFormat == RPC_FC_POINTER)
3207 pPointer += 4;
3208 else
3209 pFormat += 4;
3210 pMemory += sizeof(void*);
3211 break;
3212 case RPC_FC_ALIGNM2:
3213 align_pointer(&pMemory, 2);
3214 break;
3215 case RPC_FC_ALIGNM4:
3216 align_pointer(&pMemory, 4);
3217 break;
3218 case RPC_FC_ALIGNM8:
3219 align_pointer(&pMemory, 8);
3220 break;
3221 case RPC_FC_STRUCTPAD1:
3222 case RPC_FC_STRUCTPAD2:
3223 case RPC_FC_STRUCTPAD3:
3224 case RPC_FC_STRUCTPAD4:
3225 case RPC_FC_STRUCTPAD5:
3226 case RPC_FC_STRUCTPAD6:
3227 case RPC_FC_STRUCTPAD7:
3228 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3229 break;
3230 case RPC_FC_EMBEDDED_COMPLEX:
3231 pMemory += pFormat[1];
3232 pFormat += 2;
3233 desc = pFormat + *(const SHORT*)pFormat;
3234 size = EmbeddedComplexSize(pStubMsg, desc);
3235 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
3236 if (m)
3238 /* for some reason interface pointers aren't generated as
3239 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3240 * they still need the derefencing treatment that pointers are
3241 * given */
3242 if (*desc == RPC_FC_IP)
3243 m(pStubMsg, *(unsigned char **)pMemory, desc);
3244 else
3245 m(pStubMsg, pMemory, desc);
3247 else FIXME("no buffersizer for embedded type %02x\n", *desc);
3248 pMemory += size;
3249 pFormat += 2;
3250 continue;
3251 case RPC_FC_PAD:
3252 break;
3253 default:
3254 FIXME("unhandled format 0x%02x\n", *pFormat);
3256 pFormat++;
3259 return pMemory;
3262 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
3263 unsigned char *pMemory,
3264 PFORMAT_STRING pFormat,
3265 PFORMAT_STRING pPointer)
3267 PFORMAT_STRING desc;
3268 NDR_FREE m;
3269 ULONG size;
3271 while (*pFormat != RPC_FC_END) {
3272 switch (*pFormat) {
3273 case RPC_FC_BYTE:
3274 case RPC_FC_CHAR:
3275 case RPC_FC_SMALL:
3276 case RPC_FC_USMALL:
3277 pMemory += 1;
3278 break;
3279 case RPC_FC_WCHAR:
3280 case RPC_FC_SHORT:
3281 case RPC_FC_USHORT:
3282 pMemory += 2;
3283 break;
3284 case RPC_FC_LONG:
3285 case RPC_FC_ULONG:
3286 case RPC_FC_ENUM16:
3287 case RPC_FC_ENUM32:
3288 case RPC_FC_FLOAT:
3289 pMemory += 4;
3290 break;
3291 case RPC_FC_INT3264:
3292 case RPC_FC_UINT3264:
3293 pMemory += sizeof(INT_PTR);
3294 break;
3295 case RPC_FC_HYPER:
3296 case RPC_FC_DOUBLE:
3297 pMemory += 8;
3298 break;
3299 case RPC_FC_RP:
3300 case RPC_FC_UP:
3301 case RPC_FC_OP:
3302 case RPC_FC_FP:
3303 case RPC_FC_POINTER:
3304 if (*pFormat != RPC_FC_POINTER)
3305 pPointer = pFormat;
3306 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3307 if (*pFormat == RPC_FC_POINTER)
3308 pPointer += 4;
3309 else
3310 pFormat += 4;
3311 pMemory += sizeof(void *);
3312 break;
3313 case RPC_FC_ALIGNM2:
3314 align_pointer(&pMemory, 2);
3315 break;
3316 case RPC_FC_ALIGNM4:
3317 align_pointer(&pMemory, 4);
3318 break;
3319 case RPC_FC_ALIGNM8:
3320 align_pointer(&pMemory, 8);
3321 break;
3322 case RPC_FC_STRUCTPAD1:
3323 case RPC_FC_STRUCTPAD2:
3324 case RPC_FC_STRUCTPAD3:
3325 case RPC_FC_STRUCTPAD4:
3326 case RPC_FC_STRUCTPAD5:
3327 case RPC_FC_STRUCTPAD6:
3328 case RPC_FC_STRUCTPAD7:
3329 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3330 break;
3331 case RPC_FC_EMBEDDED_COMPLEX:
3332 pMemory += pFormat[1];
3333 pFormat += 2;
3334 desc = pFormat + *(const SHORT*)pFormat;
3335 size = EmbeddedComplexSize(pStubMsg, desc);
3336 m = NdrFreer[*desc & NDR_TABLE_MASK];
3337 if (m)
3339 /* for some reason interface pointers aren't generated as
3340 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3341 * they still need the derefencing treatment that pointers are
3342 * given */
3343 if (*desc == RPC_FC_IP)
3344 m(pStubMsg, *(unsigned char **)pMemory, desc);
3345 else
3346 m(pStubMsg, pMemory, desc);
3348 pMemory += size;
3349 pFormat += 2;
3350 continue;
3351 case RPC_FC_PAD:
3352 break;
3353 default:
3354 FIXME("unhandled format 0x%02x\n", *pFormat);
3356 pFormat++;
3359 return pMemory;
3362 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3363 PFORMAT_STRING pFormat,
3364 PFORMAT_STRING pPointer)
3366 PFORMAT_STRING desc;
3367 ULONG size = 0;
3369 while (*pFormat != RPC_FC_END) {
3370 switch (*pFormat) {
3371 case RPC_FC_BYTE:
3372 case RPC_FC_CHAR:
3373 case RPC_FC_SMALL:
3374 case RPC_FC_USMALL:
3375 size += 1;
3376 safe_buffer_increment(pStubMsg, 1);
3377 break;
3378 case RPC_FC_WCHAR:
3379 case RPC_FC_SHORT:
3380 case RPC_FC_USHORT:
3381 size += 2;
3382 safe_buffer_increment(pStubMsg, 2);
3383 break;
3384 case RPC_FC_ENUM16:
3385 size += 4;
3386 safe_buffer_increment(pStubMsg, 2);
3387 break;
3388 case RPC_FC_LONG:
3389 case RPC_FC_ULONG:
3390 case RPC_FC_ENUM32:
3391 case RPC_FC_FLOAT:
3392 size += 4;
3393 safe_buffer_increment(pStubMsg, 4);
3394 break;
3395 case RPC_FC_INT3264:
3396 case RPC_FC_UINT3264:
3397 size += sizeof(INT_PTR);
3398 safe_buffer_increment(pStubMsg, 4);
3399 break;
3400 case RPC_FC_HYPER:
3401 case RPC_FC_DOUBLE:
3402 size += 8;
3403 safe_buffer_increment(pStubMsg, 8);
3404 break;
3405 case RPC_FC_RP:
3406 case RPC_FC_UP:
3407 case RPC_FC_OP:
3408 case RPC_FC_FP:
3409 case RPC_FC_POINTER:
3411 unsigned char *saved_buffer;
3412 BOOL pointer_buffer_mark_set = FALSE;
3413 if (*pFormat != RPC_FC_POINTER)
3414 pPointer = pFormat;
3415 if (*pPointer != RPC_FC_RP)
3416 align_pointer(&pStubMsg->Buffer, 4);
3417 saved_buffer = pStubMsg->Buffer;
3418 if (pStubMsg->PointerBufferMark)
3420 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3421 pStubMsg->PointerBufferMark = NULL;
3422 pointer_buffer_mark_set = TRUE;
3424 else if (*pPointer != RPC_FC_RP)
3425 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3427 if (!pStubMsg->IgnoreEmbeddedPointers)
3428 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3429 if (pointer_buffer_mark_set)
3431 STD_OVERFLOW_CHECK(pStubMsg);
3432 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3433 pStubMsg->Buffer = saved_buffer;
3434 if (*pPointer != RPC_FC_RP)
3435 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3437 if (*pFormat == RPC_FC_POINTER)
3438 pPointer += 4;
3439 else
3440 pFormat += 4;
3441 size += sizeof(void *);
3442 break;
3444 case RPC_FC_ALIGNM2:
3445 align_length(&size, 2);
3446 break;
3447 case RPC_FC_ALIGNM4:
3448 align_length(&size, 4);
3449 break;
3450 case RPC_FC_ALIGNM8:
3451 align_length(&size, 8);
3452 break;
3453 case RPC_FC_STRUCTPAD1:
3454 case RPC_FC_STRUCTPAD2:
3455 case RPC_FC_STRUCTPAD3:
3456 case RPC_FC_STRUCTPAD4:
3457 case RPC_FC_STRUCTPAD5:
3458 case RPC_FC_STRUCTPAD6:
3459 case RPC_FC_STRUCTPAD7:
3460 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3461 break;
3462 case RPC_FC_EMBEDDED_COMPLEX:
3463 size += pFormat[1];
3464 pFormat += 2;
3465 desc = pFormat + *(const SHORT*)pFormat;
3466 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3467 pFormat += 2;
3468 continue;
3469 case RPC_FC_PAD:
3470 break;
3471 default:
3472 FIXME("unhandled format 0x%02x\n", *pFormat);
3474 pFormat++;
3477 return size;
3480 ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
3482 PFORMAT_STRING desc;
3483 ULONG size = 0;
3485 while (*pFormat != RPC_FC_END) {
3486 switch (*pFormat) {
3487 case RPC_FC_BYTE:
3488 case RPC_FC_CHAR:
3489 case RPC_FC_SMALL:
3490 case RPC_FC_USMALL:
3491 size += 1;
3492 break;
3493 case RPC_FC_WCHAR:
3494 case RPC_FC_SHORT:
3495 case RPC_FC_USHORT:
3496 size += 2;
3497 break;
3498 case RPC_FC_LONG:
3499 case RPC_FC_ULONG:
3500 case RPC_FC_ENUM16:
3501 case RPC_FC_ENUM32:
3502 case RPC_FC_FLOAT:
3503 size += 4;
3504 break;
3505 case RPC_FC_INT3264:
3506 case RPC_FC_UINT3264:
3507 size += sizeof(INT_PTR);
3508 break;
3509 case RPC_FC_HYPER:
3510 case RPC_FC_DOUBLE:
3511 size += 8;
3512 break;
3513 case RPC_FC_RP:
3514 case RPC_FC_UP:
3515 case RPC_FC_OP:
3516 case RPC_FC_FP:
3517 case RPC_FC_POINTER:
3518 size += sizeof(void *);
3519 if (*pFormat != RPC_FC_POINTER)
3520 pFormat += 4;
3521 break;
3522 case RPC_FC_ALIGNM2:
3523 align_length(&size, 2);
3524 break;
3525 case RPC_FC_ALIGNM4:
3526 align_length(&size, 4);
3527 break;
3528 case RPC_FC_ALIGNM8:
3529 align_length(&size, 8);
3530 break;
3531 case RPC_FC_STRUCTPAD1:
3532 case RPC_FC_STRUCTPAD2:
3533 case RPC_FC_STRUCTPAD3:
3534 case RPC_FC_STRUCTPAD4:
3535 case RPC_FC_STRUCTPAD5:
3536 case RPC_FC_STRUCTPAD6:
3537 case RPC_FC_STRUCTPAD7:
3538 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3539 break;
3540 case RPC_FC_EMBEDDED_COMPLEX:
3541 size += pFormat[1];
3542 pFormat += 2;
3543 desc = pFormat + *(const SHORT*)pFormat;
3544 size += EmbeddedComplexSize(pStubMsg, desc);
3545 pFormat += 2;
3546 continue;
3547 case RPC_FC_PAD:
3548 break;
3549 default:
3550 FIXME("unhandled format 0x%02x\n", *pFormat);
3552 pFormat++;
3555 return size;
3558 /***********************************************************************
3559 * NdrComplexStructMarshall [RPCRT4.@]
3561 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3562 unsigned char *pMemory,
3563 PFORMAT_STRING pFormat)
3565 PFORMAT_STRING conf_array = NULL;
3566 PFORMAT_STRING pointer_desc = NULL;
3567 unsigned char *OldMemory = pStubMsg->Memory;
3568 BOOL pointer_buffer_mark_set = FALSE;
3569 ULONG count = 0;
3570 ULONG max_count = 0;
3571 ULONG offset = 0;
3573 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3575 if (!pStubMsg->PointerBufferMark)
3577 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3578 /* save buffer length */
3579 ULONG saved_buffer_length = pStubMsg->BufferLength;
3581 /* get the buffer pointer after complex array data, but before
3582 * pointer data */
3583 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3584 pStubMsg->IgnoreEmbeddedPointers = 1;
3585 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3586 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3588 /* save it for use by embedded pointer code later */
3589 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3590 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - pStubMsg->Buffer));
3591 pointer_buffer_mark_set = TRUE;
3593 /* restore the original buffer length */
3594 pStubMsg->BufferLength = saved_buffer_length;
3597 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1);
3599 pFormat += 4;
3600 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3601 pFormat += 2;
3602 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3603 pFormat += 2;
3605 pStubMsg->Memory = pMemory;
3607 if (conf_array)
3609 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3610 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3611 pMemory + struct_size, conf_array);
3612 /* these could be changed in ComplexMarshall so save them for later */
3613 max_count = pStubMsg->MaxCount;
3614 count = pStubMsg->ActualCount;
3615 offset = pStubMsg->Offset;
3618 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3620 if (conf_array)
3622 pStubMsg->MaxCount = max_count;
3623 pStubMsg->ActualCount = count;
3624 pStubMsg->Offset = offset;
3625 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3626 conf_array, TRUE /* fHasPointers */);
3629 pStubMsg->Memory = OldMemory;
3631 if (pointer_buffer_mark_set)
3633 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3634 pStubMsg->PointerBufferMark = NULL;
3637 STD_OVERFLOW_CHECK(pStubMsg);
3639 return NULL;
3642 /***********************************************************************
3643 * NdrComplexStructUnmarshall [RPCRT4.@]
3645 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3646 unsigned char **ppMemory,
3647 PFORMAT_STRING pFormat,
3648 unsigned char fMustAlloc)
3650 unsigned size = *(const WORD*)(pFormat+2);
3651 PFORMAT_STRING conf_array = NULL;
3652 PFORMAT_STRING pointer_desc = NULL;
3653 unsigned char *pMemory;
3654 BOOL pointer_buffer_mark_set = FALSE;
3655 ULONG count = 0;
3656 ULONG max_count = 0;
3657 ULONG offset = 0;
3658 ULONG array_size = 0;
3660 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3662 if (!pStubMsg->PointerBufferMark)
3664 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3665 /* save buffer pointer */
3666 unsigned char *saved_buffer = pStubMsg->Buffer;
3668 /* get the buffer pointer after complex array data, but before
3669 * pointer data */
3670 pStubMsg->IgnoreEmbeddedPointers = 1;
3671 NdrComplexStructMemorySize(pStubMsg, pFormat);
3672 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3674 /* save it for use by embedded pointer code later */
3675 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3676 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - saved_buffer));
3677 pointer_buffer_mark_set = TRUE;
3679 /* restore the original buffer */
3680 pStubMsg->Buffer = saved_buffer;
3683 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3685 pFormat += 4;
3686 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3687 pFormat += 2;
3688 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3689 pFormat += 2;
3691 if (conf_array)
3693 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3694 size += array_size;
3696 /* these could be changed in ComplexMarshall so save them for later */
3697 max_count = pStubMsg->MaxCount;
3698 count = pStubMsg->ActualCount;
3699 offset = pStubMsg->Offset;
3702 if (!fMustAlloc && !*ppMemory)
3703 fMustAlloc = TRUE;
3704 if (fMustAlloc)
3705 *ppMemory = NdrAllocate(pStubMsg, size);
3707 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3709 if (conf_array)
3711 pStubMsg->MaxCount = max_count;
3712 pStubMsg->ActualCount = count;
3713 pStubMsg->Offset = offset;
3714 if (fMustAlloc)
3715 memset(pMemory, 0, array_size);
3716 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3717 conf_array, FALSE,
3718 FALSE /* fUseBufferMemoryServer */,
3719 TRUE /* fUnmarshall */);
3722 if (pointer_buffer_mark_set)
3724 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3725 pStubMsg->PointerBufferMark = NULL;
3728 return NULL;
3731 /***********************************************************************
3732 * NdrComplexStructBufferSize [RPCRT4.@]
3734 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3735 unsigned char *pMemory,
3736 PFORMAT_STRING pFormat)
3738 PFORMAT_STRING conf_array = NULL;
3739 PFORMAT_STRING pointer_desc = NULL;
3740 unsigned char *OldMemory = pStubMsg->Memory;
3741 int pointer_length_set = 0;
3742 ULONG count = 0;
3743 ULONG max_count = 0;
3744 ULONG offset = 0;
3746 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3748 align_length(&pStubMsg->BufferLength, pFormat[1] + 1);
3750 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3752 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3753 ULONG saved_buffer_length = pStubMsg->BufferLength;
3755 /* get the buffer length after complex struct data, but before
3756 * pointer data */
3757 pStubMsg->IgnoreEmbeddedPointers = 1;
3758 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3759 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3761 /* save it for use by embedded pointer code later */
3762 pStubMsg->PointerLength = pStubMsg->BufferLength;
3763 pointer_length_set = 1;
3764 TRACE("difference = 0x%x\n", pStubMsg->PointerLength - saved_buffer_length);
3766 /* restore the original buffer length */
3767 pStubMsg->BufferLength = saved_buffer_length;
3770 pFormat += 4;
3771 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3772 pFormat += 2;
3773 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3774 pFormat += 2;
3776 pStubMsg->Memory = pMemory;
3778 if (conf_array)
3780 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3781 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3782 conf_array);
3784 /* these could be changed in ComplexMarshall so save them for later */
3785 max_count = pStubMsg->MaxCount;
3786 count = pStubMsg->ActualCount;
3787 offset = pStubMsg->Offset;
3790 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3792 if (conf_array)
3794 pStubMsg->MaxCount = max_count;
3795 pStubMsg->ActualCount = count;
3796 pStubMsg->Offset = offset;
3797 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3798 TRUE /* fHasPointers */);
3801 pStubMsg->Memory = OldMemory;
3803 if(pointer_length_set)
3805 pStubMsg->BufferLength = pStubMsg->PointerLength;
3806 pStubMsg->PointerLength = 0;
3811 /***********************************************************************
3812 * NdrComplexStructMemorySize [RPCRT4.@]
3814 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3815 PFORMAT_STRING pFormat)
3817 unsigned size = *(const WORD*)(pFormat+2);
3818 PFORMAT_STRING conf_array = NULL;
3819 PFORMAT_STRING pointer_desc = NULL;
3820 ULONG count = 0;
3821 ULONG max_count = 0;
3822 ULONG offset = 0;
3824 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3826 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3828 pFormat += 4;
3829 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3830 pFormat += 2;
3831 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3832 pFormat += 2;
3834 if (conf_array)
3836 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3838 /* these could be changed in ComplexStructMemorySize so save them for
3839 * later */
3840 max_count = pStubMsg->MaxCount;
3841 count = pStubMsg->ActualCount;
3842 offset = pStubMsg->Offset;
3845 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3847 if (conf_array)
3849 pStubMsg->MaxCount = max_count;
3850 pStubMsg->ActualCount = count;
3851 pStubMsg->Offset = offset;
3852 array_memory_size(conf_array[0], pStubMsg, conf_array,
3853 TRUE /* fHasPointers */);
3856 return size;
3859 /***********************************************************************
3860 * NdrComplexStructFree [RPCRT4.@]
3862 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3863 unsigned char *pMemory,
3864 PFORMAT_STRING pFormat)
3866 PFORMAT_STRING conf_array = NULL;
3867 PFORMAT_STRING pointer_desc = NULL;
3868 unsigned char *OldMemory = pStubMsg->Memory;
3870 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3872 pFormat += 4;
3873 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3874 pFormat += 2;
3875 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3876 pFormat += 2;
3878 pStubMsg->Memory = pMemory;
3880 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3882 if (conf_array)
3883 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3884 TRUE /* fHasPointers */);
3886 pStubMsg->Memory = OldMemory;
3889 /***********************************************************************
3890 * NdrConformantArrayMarshall [RPCRT4.@]
3892 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3893 unsigned char *pMemory,
3894 PFORMAT_STRING pFormat)
3896 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3897 if (pFormat[0] != RPC_FC_CARRAY)
3899 ERR("invalid format = 0x%x\n", pFormat[0]);
3900 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3903 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory,
3904 pFormat);
3905 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3906 TRUE /* fHasPointers */);
3908 return NULL;
3911 /***********************************************************************
3912 * NdrConformantArrayUnmarshall [RPCRT4.@]
3914 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3915 unsigned char **ppMemory,
3916 PFORMAT_STRING pFormat,
3917 unsigned char fMustAlloc)
3919 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3920 if (pFormat[0] != RPC_FC_CARRAY)
3922 ERR("invalid format = 0x%x\n", pFormat[0]);
3923 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3926 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3927 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat,
3928 fMustAlloc,
3929 TRUE /* fUseBufferMemoryServer */,
3930 TRUE /* fUnmarshall */);
3932 return NULL;
3935 /***********************************************************************
3936 * NdrConformantArrayBufferSize [RPCRT4.@]
3938 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3939 unsigned char *pMemory,
3940 PFORMAT_STRING pFormat)
3942 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3943 if (pFormat[0] != RPC_FC_CARRAY)
3945 ERR("invalid format = 0x%x\n", pFormat[0]);
3946 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3949 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat);
3950 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3951 TRUE /* fHasPointers */);
3954 /***********************************************************************
3955 * NdrConformantArrayMemorySize [RPCRT4.@]
3957 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3958 PFORMAT_STRING pFormat)
3960 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3961 if (pFormat[0] != RPC_FC_CARRAY)
3963 ERR("invalid format = 0x%x\n", pFormat[0]);
3964 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3967 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3968 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
3970 return pStubMsg->MemorySize;
3973 /***********************************************************************
3974 * NdrConformantArrayFree [RPCRT4.@]
3976 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3977 unsigned char *pMemory,
3978 PFORMAT_STRING pFormat)
3980 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3981 if (pFormat[0] != RPC_FC_CARRAY)
3983 ERR("invalid format = 0x%x\n", pFormat[0]);
3984 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3987 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3988 TRUE /* fHasPointers */);
3992 /***********************************************************************
3993 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3995 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
3996 unsigned char* pMemory,
3997 PFORMAT_STRING pFormat )
3999 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4001 if (pFormat[0] != RPC_FC_CVARRAY)
4003 ERR("invalid format type %x\n", pFormat[0]);
4004 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4005 return NULL;
4008 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
4009 pFormat);
4010 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory,
4011 pFormat, TRUE /* fHasPointers */);
4013 return NULL;
4017 /***********************************************************************
4018 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
4020 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
4021 unsigned char** ppMemory,
4022 PFORMAT_STRING pFormat,
4023 unsigned char fMustAlloc )
4025 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4027 if (pFormat[0] != RPC_FC_CVARRAY)
4029 ERR("invalid format type %x\n", pFormat[0]);
4030 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4031 return NULL;
4034 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
4035 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory,
4036 pFormat, fMustAlloc,
4037 TRUE /* fUseBufferMemoryServer */,
4038 TRUE /* fUnmarshall */);
4040 return NULL;
4044 /***********************************************************************
4045 * NdrConformantVaryingArrayFree [RPCRT4.@]
4047 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
4048 unsigned char* pMemory,
4049 PFORMAT_STRING pFormat )
4051 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4053 if (pFormat[0] != RPC_FC_CVARRAY)
4055 ERR("invalid format type %x\n", pFormat[0]);
4056 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4057 return;
4060 array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
4061 TRUE /* fHasPointers */);
4065 /***********************************************************************
4066 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
4068 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
4069 unsigned char* pMemory, PFORMAT_STRING pFormat )
4071 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4073 if (pFormat[0] != RPC_FC_CVARRAY)
4075 ERR("invalid format type %x\n", pFormat[0]);
4076 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4077 return;
4080 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
4081 pFormat);
4082 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
4083 TRUE /* fHasPointers */);
4087 /***********************************************************************
4088 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
4090 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
4091 PFORMAT_STRING pFormat )
4093 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4095 if (pFormat[0] != RPC_FC_CVARRAY)
4097 ERR("invalid format type %x\n", pFormat[0]);
4098 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4099 return pStubMsg->MemorySize;
4102 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
4103 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat,
4104 TRUE /* fHasPointers */);
4106 return pStubMsg->MemorySize;
4110 /***********************************************************************
4111 * NdrComplexArrayMarshall [RPCRT4.@]
4113 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4114 unsigned char *pMemory,
4115 PFORMAT_STRING pFormat)
4117 BOOL pointer_buffer_mark_set = FALSE;
4119 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4121 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4123 ERR("invalid format type %x\n", pFormat[0]);
4124 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4125 return NULL;
4128 if (!pStubMsg->PointerBufferMark)
4130 /* save buffer fields that may be changed by buffer sizer functions
4131 * and that may be needed later on */
4132 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4133 ULONG saved_buffer_length = pStubMsg->BufferLength;
4134 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4135 ULONG saved_offset = pStubMsg->Offset;
4136 ULONG saved_actual_count = pStubMsg->ActualCount;
4138 /* get the buffer pointer after complex array data, but before
4139 * pointer data */
4140 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
4141 pStubMsg->IgnoreEmbeddedPointers = 1;
4142 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4143 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4145 /* save it for use by embedded pointer code later */
4146 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
4147 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer));
4148 pointer_buffer_mark_set = TRUE;
4150 /* restore fields */
4151 pStubMsg->ActualCount = saved_actual_count;
4152 pStubMsg->Offset = saved_offset;
4153 pStubMsg->MaxCount = saved_max_count;
4154 pStubMsg->BufferLength = saved_buffer_length;
4157 array_compute_and_write_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4158 array_write_variance_and_marshall(RPC_FC_BOGUS_ARRAY, pStubMsg,
4159 pMemory, pFormat, TRUE /* fHasPointers */);
4161 STD_OVERFLOW_CHECK(pStubMsg);
4163 if (pointer_buffer_mark_set)
4165 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4166 pStubMsg->PointerBufferMark = NULL;
4169 return NULL;
4172 /***********************************************************************
4173 * NdrComplexArrayUnmarshall [RPCRT4.@]
4175 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4176 unsigned char **ppMemory,
4177 PFORMAT_STRING pFormat,
4178 unsigned char fMustAlloc)
4180 unsigned char *saved_buffer;
4181 BOOL pointer_buffer_mark_set = FALSE;
4182 int saved_ignore_embedded;
4184 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4186 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4188 ERR("invalid format type %x\n", pFormat[0]);
4189 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4190 return NULL;
4193 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4194 /* save buffer pointer */
4195 saved_buffer = pStubMsg->Buffer;
4196 /* get the buffer pointer after complex array data, but before
4197 * pointer data */
4198 pStubMsg->IgnoreEmbeddedPointers = 1;
4199 pStubMsg->MemorySize = 0;
4200 NdrComplexArrayMemorySize(pStubMsg, pFormat);
4201 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4203 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - saved_buffer));
4204 if (!pStubMsg->PointerBufferMark)
4206 /* save it for use by embedded pointer code later */
4207 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4208 pointer_buffer_mark_set = TRUE;
4210 /* restore the original buffer */
4211 pStubMsg->Buffer = saved_buffer;
4213 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
4214 array_read_variance_and_unmarshall(RPC_FC_BOGUS_ARRAY, pStubMsg, ppMemory, pFormat, fMustAlloc,
4215 TRUE /* fUseBufferMemoryServer */, TRUE /* fUnmarshall */);
4217 if (pointer_buffer_mark_set)
4219 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4220 pStubMsg->PointerBufferMark = NULL;
4223 return NULL;
4226 /***********************************************************************
4227 * NdrComplexArrayBufferSize [RPCRT4.@]
4229 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4230 unsigned char *pMemory,
4231 PFORMAT_STRING pFormat)
4233 int pointer_length_set = 0;
4235 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4237 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4239 ERR("invalid format type %x\n", pFormat[0]);
4240 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4241 return;
4244 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
4246 /* save buffer fields that may be changed by buffer sizer functions
4247 * and that may be needed later on */
4248 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4249 ULONG saved_buffer_length = pStubMsg->BufferLength;
4250 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4251 ULONG saved_offset = pStubMsg->Offset;
4252 ULONG saved_actual_count = pStubMsg->ActualCount;
4254 /* get the buffer pointer after complex array data, but before
4255 * pointer data */
4256 pStubMsg->IgnoreEmbeddedPointers = 1;
4257 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4258 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4260 /* save it for use by embedded pointer code later */
4261 pStubMsg->PointerLength = pStubMsg->BufferLength;
4262 pointer_length_set = 1;
4264 /* restore fields */
4265 pStubMsg->ActualCount = saved_actual_count;
4266 pStubMsg->Offset = saved_offset;
4267 pStubMsg->MaxCount = saved_max_count;
4268 pStubMsg->BufferLength = saved_buffer_length;
4271 array_compute_and_size_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4272 array_buffer_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat, TRUE /* fHasPointers */);
4274 if(pointer_length_set)
4276 pStubMsg->BufferLength = pStubMsg->PointerLength;
4277 pStubMsg->PointerLength = 0;
4281 /***********************************************************************
4282 * NdrComplexArrayMemorySize [RPCRT4.@]
4284 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4285 PFORMAT_STRING pFormat)
4287 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4289 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4291 ERR("invalid format type %x\n", pFormat[0]);
4292 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4293 return 0;
4296 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
4297 array_memory_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
4298 return pStubMsg->MemorySize;
4301 /***********************************************************************
4302 * NdrComplexArrayFree [RPCRT4.@]
4304 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4305 unsigned char *pMemory,
4306 PFORMAT_STRING pFormat)
4308 ULONG i, count, def;
4310 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4312 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4314 ERR("invalid format type %x\n", pFormat[0]);
4315 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4316 return;
4319 def = *(const WORD*)&pFormat[2];
4320 pFormat += 4;
4322 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4323 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4325 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4326 TRACE("variance = %d\n", pStubMsg->ActualCount);
4328 count = pStubMsg->ActualCount;
4329 for (i = 0; i < count; i++)
4330 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4333 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4334 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4335 USER_MARSHAL_CB *umcb)
4337 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4338 pStubMsg->RpcMsg->DataRepresentation);
4339 umcb->pStubMsg = pStubMsg;
4340 umcb->pReserve = NULL;
4341 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4342 umcb->CBType = cbtype;
4343 umcb->pFormat = pFormat;
4344 umcb->pTypeFormat = NULL /* FIXME */;
4347 #define USER_MARSHAL_PTR_PREFIX \
4348 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4349 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4351 /***********************************************************************
4352 * NdrUserMarshalMarshall [RPCRT4.@]
4354 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4355 unsigned char *pMemory,
4356 PFORMAT_STRING pFormat)
4358 unsigned flags = pFormat[1];
4359 unsigned index = *(const WORD*)&pFormat[2];
4360 unsigned char *saved_buffer = NULL;
4361 USER_MARSHAL_CB umcb;
4363 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4364 TRACE("index=%d\n", index);
4366 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4368 if (flags & USER_MARSHAL_POINTER)
4370 align_pointer_clear(&pStubMsg->Buffer, 4);
4371 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4372 pStubMsg->Buffer += 4;
4373 if (pStubMsg->PointerBufferMark)
4375 saved_buffer = pStubMsg->Buffer;
4376 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4377 pStubMsg->PointerBufferMark = NULL;
4379 align_pointer_clear(&pStubMsg->Buffer, 8);
4381 else
4382 align_pointer_clear(&pStubMsg->Buffer, (flags & 0xf) + 1);
4384 pStubMsg->Buffer =
4385 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4386 &umcb.Flags, pStubMsg->Buffer, pMemory);
4388 if (saved_buffer)
4390 STD_OVERFLOW_CHECK(pStubMsg);
4391 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4392 pStubMsg->Buffer = saved_buffer;
4395 STD_OVERFLOW_CHECK(pStubMsg);
4397 return NULL;
4400 /***********************************************************************
4401 * NdrUserMarshalUnmarshall [RPCRT4.@]
4403 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4404 unsigned char **ppMemory,
4405 PFORMAT_STRING pFormat,
4406 unsigned char fMustAlloc)
4408 unsigned flags = pFormat[1];
4409 unsigned index = *(const WORD*)&pFormat[2];
4410 DWORD memsize = *(const WORD*)&pFormat[4];
4411 unsigned char *saved_buffer = NULL;
4412 USER_MARSHAL_CB umcb;
4414 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4415 TRACE("index=%d\n", index);
4417 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4419 if (flags & USER_MARSHAL_POINTER)
4421 align_pointer(&pStubMsg->Buffer, 4);
4422 /* skip pointer prefix */
4423 pStubMsg->Buffer += 4;
4424 if (pStubMsg->PointerBufferMark)
4426 saved_buffer = pStubMsg->Buffer;
4427 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4428 pStubMsg->PointerBufferMark = NULL;
4430 align_pointer(&pStubMsg->Buffer, 8);
4432 else
4433 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4435 if (!fMustAlloc && !*ppMemory)
4436 fMustAlloc = TRUE;
4437 if (fMustAlloc)
4439 *ppMemory = NdrAllocate(pStubMsg, memsize);
4440 memset(*ppMemory, 0, memsize);
4443 pStubMsg->Buffer =
4444 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4445 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4447 if (saved_buffer)
4449 STD_OVERFLOW_CHECK(pStubMsg);
4450 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4451 pStubMsg->Buffer = saved_buffer;
4454 return NULL;
4457 /***********************************************************************
4458 * NdrUserMarshalBufferSize [RPCRT4.@]
4460 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4461 unsigned char *pMemory,
4462 PFORMAT_STRING pFormat)
4464 unsigned flags = pFormat[1];
4465 unsigned index = *(const WORD*)&pFormat[2];
4466 DWORD bufsize = *(const WORD*)&pFormat[6];
4467 USER_MARSHAL_CB umcb;
4468 ULONG saved_buffer_length = 0;
4470 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4471 TRACE("index=%d\n", index);
4473 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4475 if (flags & USER_MARSHAL_POINTER)
4477 align_length(&pStubMsg->BufferLength, 4);
4478 /* skip pointer prefix */
4479 safe_buffer_length_increment(pStubMsg, 4);
4480 if (pStubMsg->IgnoreEmbeddedPointers)
4481 return;
4482 if (pStubMsg->PointerLength)
4484 saved_buffer_length = pStubMsg->BufferLength;
4485 pStubMsg->BufferLength = pStubMsg->PointerLength;
4486 pStubMsg->PointerLength = 0;
4488 align_length(&pStubMsg->BufferLength, 8);
4490 else
4491 align_length(&pStubMsg->BufferLength, (flags & 0xf) + 1);
4493 if (bufsize) {
4494 TRACE("size=%d\n", bufsize);
4495 safe_buffer_length_increment(pStubMsg, bufsize);
4497 else
4498 pStubMsg->BufferLength =
4499 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4500 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4502 if (saved_buffer_length)
4504 pStubMsg->PointerLength = pStubMsg->BufferLength;
4505 pStubMsg->BufferLength = saved_buffer_length;
4510 /***********************************************************************
4511 * NdrUserMarshalMemorySize [RPCRT4.@]
4513 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4514 PFORMAT_STRING pFormat)
4516 unsigned flags = pFormat[1];
4517 unsigned index = *(const WORD*)&pFormat[2];
4518 DWORD memsize = *(const WORD*)&pFormat[4];
4519 DWORD bufsize = *(const WORD*)&pFormat[6];
4521 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4522 TRACE("index=%d\n", index);
4524 pStubMsg->MemorySize += memsize;
4526 if (flags & USER_MARSHAL_POINTER)
4528 align_pointer(&pStubMsg->Buffer, 4);
4529 /* skip pointer prefix */
4530 pStubMsg->Buffer += 4;
4531 if (pStubMsg->IgnoreEmbeddedPointers)
4532 return pStubMsg->MemorySize;
4533 align_pointer(&pStubMsg->Buffer, 8);
4535 else
4536 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4538 if (!bufsize)
4539 FIXME("not implemented for varying buffer size\n");
4541 pStubMsg->Buffer += bufsize;
4543 return pStubMsg->MemorySize;
4546 /***********************************************************************
4547 * NdrUserMarshalFree [RPCRT4.@]
4549 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4550 unsigned char *pMemory,
4551 PFORMAT_STRING pFormat)
4553 /* unsigned flags = pFormat[1]; */
4554 unsigned index = *(const WORD*)&pFormat[2];
4555 USER_MARSHAL_CB umcb;
4557 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4558 TRACE("index=%d\n", index);
4560 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4562 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4563 &umcb.Flags, pMemory);
4566 /***********************************************************************
4567 * NdrGetUserMarshalInfo [RPCRT4.@]
4569 RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi)
4571 USER_MARSHAL_CB *umcb = CONTAINING_RECORD(flags, USER_MARSHAL_CB, Flags);
4573 TRACE("(%p,%u,%p)\n", flags, level, umi);
4575 if (level != 1)
4576 return RPC_S_INVALID_ARG;
4578 memset(&umi->u1.Level1, 0, sizeof(umi->u1.Level1));
4579 umi->InformationLevel = level;
4581 if (umcb->Signature != USER_MARSHAL_CB_SIGNATURE)
4582 return RPC_S_INVALID_ARG;
4584 umi->u1.Level1.pfnAllocate = umcb->pStubMsg->pfnAllocate;
4585 umi->u1.Level1.pfnFree = umcb->pStubMsg->pfnFree;
4586 umi->u1.Level1.pRpcChannelBuffer = umcb->pStubMsg->pRpcChannelBuffer;
4588 switch (umcb->CBType)
4590 case USER_MARSHAL_CB_MARSHALL:
4591 case USER_MARSHAL_CB_UNMARSHALL:
4593 RPC_MESSAGE *msg = umcb->pStubMsg->RpcMsg;
4594 unsigned char *buffer_start = msg->Buffer;
4595 unsigned char *buffer_end =
4596 (unsigned char *)msg->Buffer + msg->BufferLength;
4598 if (umcb->pStubMsg->Buffer < buffer_start ||
4599 umcb->pStubMsg->Buffer > buffer_end)
4600 return RPC_X_INVALID_BUFFER;
4602 umi->u1.Level1.Buffer = umcb->pStubMsg->Buffer;
4603 umi->u1.Level1.BufferSize = buffer_end - umcb->pStubMsg->Buffer;
4604 break;
4606 case USER_MARSHAL_CB_BUFFER_SIZE:
4607 case USER_MARSHAL_CB_FREE:
4608 break;
4609 default:
4610 WARN("unrecognised CBType %d\n", umcb->CBType);
4613 return RPC_S_OK;
4616 /***********************************************************************
4617 * NdrClearOutParameters [RPCRT4.@]
4619 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4620 PFORMAT_STRING pFormat,
4621 void *ArgAddr)
4623 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4626 /***********************************************************************
4627 * NdrConvert [RPCRT4.@]
4629 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4631 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4632 /* FIXME: since this stub doesn't do any converting, the proper behavior
4633 is to raise an exception */
4636 /***********************************************************************
4637 * NdrConvert2 [RPCRT4.@]
4639 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4641 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4642 pStubMsg, pFormat, NumberParams);
4643 /* FIXME: since this stub doesn't do any converting, the proper behavior
4644 is to raise an exception */
4647 #include "pshpack1.h"
4648 typedef struct _NDR_CSTRUCT_FORMAT
4650 unsigned char type;
4651 unsigned char alignment;
4652 unsigned short memory_size;
4653 short offset_to_array_description;
4654 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4655 #include "poppack.h"
4657 /***********************************************************************
4658 * NdrConformantStructMarshall [RPCRT4.@]
4660 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4661 unsigned char *pMemory,
4662 PFORMAT_STRING pFormat)
4664 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4665 PFORMAT_STRING pCArrayFormat;
4666 ULONG esize, bufsize;
4668 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4670 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4671 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4673 ERR("invalid format type %x\n", pCStructFormat->type);
4674 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4675 return NULL;
4678 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4679 pCStructFormat->offset_to_array_description;
4680 if (*pCArrayFormat != RPC_FC_CARRAY)
4682 ERR("invalid array format type %x\n", pCStructFormat->type);
4683 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4684 return NULL;
4686 esize = *(const WORD*)(pCArrayFormat+2);
4688 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4689 pCArrayFormat + 4, 0);
4691 WriteConformance(pStubMsg);
4693 align_pointer_clear(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4695 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4697 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4698 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4700 ERR("integer overflow of memory_size %u with bufsize %u\n",
4701 pCStructFormat->memory_size, bufsize);
4702 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4704 /* copy constant sized part of struct */
4705 pStubMsg->BufferMark = pStubMsg->Buffer;
4706 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4708 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4709 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4711 return NULL;
4714 /***********************************************************************
4715 * NdrConformantStructUnmarshall [RPCRT4.@]
4717 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4718 unsigned char **ppMemory,
4719 PFORMAT_STRING pFormat,
4720 unsigned char fMustAlloc)
4722 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4723 PFORMAT_STRING pCArrayFormat;
4724 ULONG esize, bufsize;
4725 unsigned char *saved_buffer;
4727 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4729 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4730 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4732 ERR("invalid format type %x\n", pCStructFormat->type);
4733 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4734 return NULL;
4736 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4737 pCStructFormat->offset_to_array_description;
4738 if (*pCArrayFormat != RPC_FC_CARRAY)
4740 ERR("invalid array format type %x\n", pCStructFormat->type);
4741 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4742 return NULL;
4744 esize = *(const WORD*)(pCArrayFormat+2);
4746 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4748 align_pointer(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4750 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4752 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4753 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4755 ERR("integer overflow of memory_size %u with bufsize %u\n",
4756 pCStructFormat->memory_size, bufsize);
4757 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4760 if (fMustAlloc)
4762 SIZE_T size = pCStructFormat->memory_size + bufsize;
4763 *ppMemory = NdrAllocate(pStubMsg, size);
4765 else
4767 if (!pStubMsg->IsClient && !*ppMemory)
4768 /* for servers, we just point straight into the RPC buffer */
4769 *ppMemory = pStubMsg->Buffer;
4772 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4773 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4774 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4775 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4777 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4778 if (*ppMemory != saved_buffer)
4779 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4781 return NULL;
4784 /***********************************************************************
4785 * NdrConformantStructBufferSize [RPCRT4.@]
4787 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4788 unsigned char *pMemory,
4789 PFORMAT_STRING pFormat)
4791 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4792 PFORMAT_STRING pCArrayFormat;
4793 ULONG esize;
4795 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4797 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4798 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4800 ERR("invalid format type %x\n", pCStructFormat->type);
4801 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4802 return;
4804 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4805 pCStructFormat->offset_to_array_description;
4806 if (*pCArrayFormat != RPC_FC_CARRAY)
4808 ERR("invalid array format type %x\n", pCStructFormat->type);
4809 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4810 return;
4812 esize = *(const WORD*)(pCArrayFormat+2);
4814 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4815 SizeConformance(pStubMsg);
4817 align_length(&pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4819 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4821 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4822 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4824 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4825 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4828 /***********************************************************************
4829 * NdrConformantStructMemorySize [RPCRT4.@]
4831 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4832 PFORMAT_STRING pFormat)
4834 FIXME("stub\n");
4835 return 0;
4838 /***********************************************************************
4839 * NdrConformantStructFree [RPCRT4.@]
4841 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4842 unsigned char *pMemory,
4843 PFORMAT_STRING pFormat)
4845 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4846 PFORMAT_STRING pCArrayFormat;
4848 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4850 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4851 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4853 ERR("invalid format type %x\n", pCStructFormat->type);
4854 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4855 return;
4858 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4859 pCStructFormat->offset_to_array_description;
4860 if (*pCArrayFormat != RPC_FC_CARRAY)
4862 ERR("invalid array format type %x\n", pCStructFormat->type);
4863 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4864 return;
4867 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4868 pCArrayFormat + 4, 0);
4870 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4872 /* copy constant sized part of struct */
4873 pStubMsg->BufferMark = pStubMsg->Buffer;
4875 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4876 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4879 /***********************************************************************
4880 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4882 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4883 unsigned char *pMemory,
4884 PFORMAT_STRING pFormat)
4886 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4887 PFORMAT_STRING pCVArrayFormat;
4889 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4891 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4892 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4894 ERR("invalid format type %x\n", pCVStructFormat->type);
4895 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4896 return NULL;
4899 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4900 pCVStructFormat->offset_to_array_description;
4902 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4903 pMemory + pCVStructFormat->memory_size,
4904 pCVArrayFormat);
4906 align_pointer_clear(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4908 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4910 /* write constant sized part */
4911 pStubMsg->BufferMark = pStubMsg->Buffer;
4912 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4914 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4915 pMemory + pCVStructFormat->memory_size,
4916 pCVArrayFormat, FALSE /* fHasPointers */);
4918 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4920 return NULL;
4923 /***********************************************************************
4924 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4926 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4927 unsigned char **ppMemory,
4928 PFORMAT_STRING pFormat,
4929 unsigned char fMustAlloc)
4931 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4932 PFORMAT_STRING pCVArrayFormat;
4933 ULONG memsize, bufsize;
4934 unsigned char *saved_buffer, *saved_array_buffer;
4935 ULONG offset;
4936 unsigned char *array_memory;
4938 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4940 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4941 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4943 ERR("invalid format type %x\n", pCVStructFormat->type);
4944 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4945 return NULL;
4948 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4949 pCVStructFormat->offset_to_array_description;
4951 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4952 pCVArrayFormat);
4954 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4956 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4958 /* work out how much memory to allocate if we need to do so */
4959 if (!fMustAlloc && !*ppMemory)
4960 fMustAlloc = TRUE;
4961 if (fMustAlloc)
4963 SIZE_T size = pCVStructFormat->memory_size + memsize;
4964 *ppMemory = NdrAllocate(pStubMsg, size);
4967 /* mark the start of the constant data */
4968 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4969 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4971 array_memory = *ppMemory + pCVStructFormat->memory_size;
4972 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
4973 &array_memory, pCVArrayFormat,
4974 FALSE /* fMustAlloc */,
4975 FALSE /* fUseServerBufferMemory */,
4976 FALSE /* fUnmarshall */);
4978 /* save offset in case unmarshalling pointers changes it */
4979 offset = pStubMsg->Offset;
4981 /* mark the start of the array data */
4982 saved_array_buffer = pStubMsg->Buffer;
4983 safe_buffer_increment(pStubMsg, bufsize);
4985 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4987 /* copy the constant data */
4988 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
4989 /* copy the array data */
4990 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
4991 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
4992 saved_array_buffer, bufsize);
4994 if (*pCVArrayFormat == RPC_FC_C_CSTRING)
4995 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
4996 else if (*pCVArrayFormat == RPC_FC_C_WSTRING)
4997 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
4999 return NULL;
5002 /***********************************************************************
5003 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
5005 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5006 unsigned char *pMemory,
5007 PFORMAT_STRING pFormat)
5009 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5010 PFORMAT_STRING pCVArrayFormat;
5012 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5014 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5015 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5017 ERR("invalid format type %x\n", pCVStructFormat->type);
5018 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5019 return;
5022 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5023 pCVStructFormat->offset_to_array_description;
5024 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
5025 pMemory + pCVStructFormat->memory_size,
5026 pCVArrayFormat);
5028 align_length(&pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
5030 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5032 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
5034 array_buffer_size(*pCVArrayFormat, pStubMsg,
5035 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5036 FALSE /* fHasPointers */);
5038 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5041 /***********************************************************************
5042 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
5044 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5045 PFORMAT_STRING pFormat)
5047 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5048 PFORMAT_STRING pCVArrayFormat;
5050 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5052 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5053 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5055 ERR("invalid format type %x\n", pCVStructFormat->type);
5056 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5057 return 0;
5060 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5061 pCVStructFormat->offset_to_array_description;
5062 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
5064 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
5066 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5068 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
5069 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
5070 FALSE /* fHasPointers */);
5072 pStubMsg->MemorySize += pCVStructFormat->memory_size;
5074 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5076 return pStubMsg->MemorySize;
5079 /***********************************************************************
5080 * NdrConformantVaryingStructFree [RPCRT4.@]
5082 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
5083 unsigned char *pMemory,
5084 PFORMAT_STRING pFormat)
5086 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5087 PFORMAT_STRING pCVArrayFormat;
5089 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5091 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5092 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5094 ERR("invalid format type %x\n", pCVStructFormat->type);
5095 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5096 return;
5099 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5100 pCVStructFormat->offset_to_array_description;
5101 array_free(*pCVArrayFormat, pStubMsg,
5102 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5103 FALSE /* fHasPointers */);
5105 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5107 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5110 #include "pshpack1.h"
5111 typedef struct
5113 unsigned char type;
5114 unsigned char alignment;
5115 unsigned short total_size;
5116 } NDR_SMFARRAY_FORMAT;
5118 typedef struct
5120 unsigned char type;
5121 unsigned char alignment;
5122 ULONG total_size;
5123 } NDR_LGFARRAY_FORMAT;
5124 #include "poppack.h"
5126 /***********************************************************************
5127 * NdrFixedArrayMarshall [RPCRT4.@]
5129 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5130 unsigned char *pMemory,
5131 PFORMAT_STRING pFormat)
5133 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5134 ULONG total_size;
5136 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5138 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5139 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5141 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5142 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5143 return NULL;
5146 align_pointer_clear(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5148 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5150 total_size = pSmFArrayFormat->total_size;
5151 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5153 else
5155 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5156 total_size = pLgFArrayFormat->total_size;
5157 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5160 pStubMsg->BufferMark = pStubMsg->Buffer;
5161 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
5163 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5165 return NULL;
5168 /***********************************************************************
5169 * NdrFixedArrayUnmarshall [RPCRT4.@]
5171 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5172 unsigned char **ppMemory,
5173 PFORMAT_STRING pFormat,
5174 unsigned char fMustAlloc)
5176 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5177 ULONG total_size;
5178 unsigned char *saved_buffer;
5180 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5182 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5183 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5185 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5186 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5187 return NULL;
5190 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5192 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5194 total_size = pSmFArrayFormat->total_size;
5195 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5197 else
5199 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5200 total_size = pLgFArrayFormat->total_size;
5201 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5204 if (fMustAlloc)
5205 *ppMemory = NdrAllocate(pStubMsg, total_size);
5206 else
5208 if (!pStubMsg->IsClient && !*ppMemory)
5209 /* for servers, we just point straight into the RPC buffer */
5210 *ppMemory = pStubMsg->Buffer;
5213 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5214 safe_buffer_increment(pStubMsg, total_size);
5215 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5217 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
5218 if (*ppMemory != saved_buffer)
5219 memcpy(*ppMemory, saved_buffer, total_size);
5221 return NULL;
5224 /***********************************************************************
5225 * NdrFixedArrayBufferSize [RPCRT4.@]
5227 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5228 unsigned char *pMemory,
5229 PFORMAT_STRING pFormat)
5231 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5232 ULONG total_size;
5234 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5236 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5237 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5239 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5240 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5241 return;
5244 align_length(&pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
5246 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5248 total_size = pSmFArrayFormat->total_size;
5249 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5251 else
5253 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5254 total_size = pLgFArrayFormat->total_size;
5255 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5257 safe_buffer_length_increment(pStubMsg, total_size);
5259 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5262 /***********************************************************************
5263 * NdrFixedArrayMemorySize [RPCRT4.@]
5265 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5266 PFORMAT_STRING pFormat)
5268 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5269 ULONG total_size;
5271 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5273 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5274 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5276 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5277 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5278 return 0;
5281 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5283 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5285 total_size = pSmFArrayFormat->total_size;
5286 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5288 else
5290 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5291 total_size = pLgFArrayFormat->total_size;
5292 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5294 pStubMsg->BufferMark = pStubMsg->Buffer;
5295 safe_buffer_increment(pStubMsg, total_size);
5296 pStubMsg->MemorySize += total_size;
5298 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5300 return total_size;
5303 /***********************************************************************
5304 * NdrFixedArrayFree [RPCRT4.@]
5306 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5307 unsigned char *pMemory,
5308 PFORMAT_STRING pFormat)
5310 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5312 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5314 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5315 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5317 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5318 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5319 return;
5322 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5323 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5324 else
5326 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5327 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5330 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5333 /***********************************************************************
5334 * NdrVaryingArrayMarshall [RPCRT4.@]
5336 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5337 unsigned char *pMemory,
5338 PFORMAT_STRING pFormat)
5340 unsigned char alignment;
5341 DWORD elements, esize;
5342 ULONG bufsize;
5344 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5346 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5347 (pFormat[0] != RPC_FC_LGVARRAY))
5349 ERR("invalid format type %x\n", pFormat[0]);
5350 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5351 return NULL;
5354 alignment = pFormat[1] + 1;
5356 if (pFormat[0] == RPC_FC_SMVARRAY)
5358 pFormat += 2;
5359 pFormat += sizeof(WORD);
5360 elements = *(const WORD*)pFormat;
5361 pFormat += sizeof(WORD);
5363 else
5365 pFormat += 2;
5366 pFormat += sizeof(DWORD);
5367 elements = *(const DWORD*)pFormat;
5368 pFormat += sizeof(DWORD);
5371 esize = *(const WORD*)pFormat;
5372 pFormat += sizeof(WORD);
5374 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5375 if ((pStubMsg->ActualCount > elements) ||
5376 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5378 RpcRaiseException(RPC_S_INVALID_BOUND);
5379 return NULL;
5382 WriteVariance(pStubMsg);
5384 align_pointer_clear(&pStubMsg->Buffer, alignment);
5386 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5387 pStubMsg->BufferMark = pStubMsg->Buffer;
5388 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5390 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5392 return NULL;
5395 /***********************************************************************
5396 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5398 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5399 unsigned char **ppMemory,
5400 PFORMAT_STRING pFormat,
5401 unsigned char fMustAlloc)
5403 unsigned char alignment;
5404 DWORD size, elements, esize;
5405 ULONG bufsize;
5406 unsigned char *saved_buffer;
5407 ULONG offset;
5409 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5411 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5412 (pFormat[0] != RPC_FC_LGVARRAY))
5414 ERR("invalid format type %x\n", pFormat[0]);
5415 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5416 return NULL;
5419 alignment = pFormat[1] + 1;
5421 if (pFormat[0] == RPC_FC_SMVARRAY)
5423 pFormat += 2;
5424 size = *(const WORD*)pFormat;
5425 pFormat += sizeof(WORD);
5426 elements = *(const WORD*)pFormat;
5427 pFormat += sizeof(WORD);
5429 else
5431 pFormat += 2;
5432 size = *(const DWORD*)pFormat;
5433 pFormat += sizeof(DWORD);
5434 elements = *(const DWORD*)pFormat;
5435 pFormat += sizeof(DWORD);
5438 esize = *(const WORD*)pFormat;
5439 pFormat += sizeof(WORD);
5441 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5443 align_pointer(&pStubMsg->Buffer, alignment);
5445 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5446 offset = pStubMsg->Offset;
5448 if (!fMustAlloc && !*ppMemory)
5449 fMustAlloc = TRUE;
5450 if (fMustAlloc)
5451 *ppMemory = NdrAllocate(pStubMsg, size);
5452 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5453 safe_buffer_increment(pStubMsg, bufsize);
5455 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5457 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5459 return NULL;
5462 /***********************************************************************
5463 * NdrVaryingArrayBufferSize [RPCRT4.@]
5465 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5466 unsigned char *pMemory,
5467 PFORMAT_STRING pFormat)
5469 unsigned char alignment;
5470 DWORD elements, esize;
5472 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5474 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5475 (pFormat[0] != RPC_FC_LGVARRAY))
5477 ERR("invalid format type %x\n", pFormat[0]);
5478 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5479 return;
5482 alignment = pFormat[1] + 1;
5484 if (pFormat[0] == RPC_FC_SMVARRAY)
5486 pFormat += 2;
5487 pFormat += sizeof(WORD);
5488 elements = *(const WORD*)pFormat;
5489 pFormat += sizeof(WORD);
5491 else
5493 pFormat += 2;
5494 pFormat += sizeof(DWORD);
5495 elements = *(const DWORD*)pFormat;
5496 pFormat += sizeof(DWORD);
5499 esize = *(const WORD*)pFormat;
5500 pFormat += sizeof(WORD);
5502 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5503 if ((pStubMsg->ActualCount > elements) ||
5504 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5506 RpcRaiseException(RPC_S_INVALID_BOUND);
5507 return;
5510 SizeVariance(pStubMsg);
5512 align_length(&pStubMsg->BufferLength, alignment);
5514 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5516 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5519 /***********************************************************************
5520 * NdrVaryingArrayMemorySize [RPCRT4.@]
5522 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5523 PFORMAT_STRING pFormat)
5525 unsigned char alignment;
5526 DWORD size, elements, esize;
5528 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5530 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5531 (pFormat[0] != RPC_FC_LGVARRAY))
5533 ERR("invalid format type %x\n", pFormat[0]);
5534 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5535 return 0;
5538 alignment = pFormat[1] + 1;
5540 if (pFormat[0] == RPC_FC_SMVARRAY)
5542 pFormat += 2;
5543 size = *(const WORD*)pFormat;
5544 pFormat += sizeof(WORD);
5545 elements = *(const WORD*)pFormat;
5546 pFormat += sizeof(WORD);
5548 else
5550 pFormat += 2;
5551 size = *(const DWORD*)pFormat;
5552 pFormat += sizeof(DWORD);
5553 elements = *(const DWORD*)pFormat;
5554 pFormat += sizeof(DWORD);
5557 esize = *(const WORD*)pFormat;
5558 pFormat += sizeof(WORD);
5560 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5562 align_pointer(&pStubMsg->Buffer, alignment);
5564 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5565 pStubMsg->MemorySize += size;
5567 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5569 return pStubMsg->MemorySize;
5572 /***********************************************************************
5573 * NdrVaryingArrayFree [RPCRT4.@]
5575 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5576 unsigned char *pMemory,
5577 PFORMAT_STRING pFormat)
5579 DWORD elements;
5581 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5583 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5584 (pFormat[0] != RPC_FC_LGVARRAY))
5586 ERR("invalid format type %x\n", pFormat[0]);
5587 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5588 return;
5591 if (pFormat[0] == RPC_FC_SMVARRAY)
5593 pFormat += 2;
5594 pFormat += sizeof(WORD);
5595 elements = *(const WORD*)pFormat;
5596 pFormat += sizeof(WORD);
5598 else
5600 pFormat += 2;
5601 pFormat += sizeof(DWORD);
5602 elements = *(const DWORD*)pFormat;
5603 pFormat += sizeof(DWORD);
5606 pFormat += sizeof(WORD);
5608 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5609 if ((pStubMsg->ActualCount > elements) ||
5610 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5612 RpcRaiseException(RPC_S_INVALID_BOUND);
5613 return;
5616 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5619 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5621 switch (fc)
5623 case RPC_FC_BYTE:
5624 case RPC_FC_CHAR:
5625 case RPC_FC_SMALL:
5626 case RPC_FC_USMALL:
5627 return *pMemory;
5628 case RPC_FC_WCHAR:
5629 case RPC_FC_SHORT:
5630 case RPC_FC_USHORT:
5631 case RPC_FC_ENUM16:
5632 return *(const USHORT *)pMemory;
5633 case RPC_FC_LONG:
5634 case RPC_FC_ULONG:
5635 case RPC_FC_ENUM32:
5636 return *(const ULONG *)pMemory;
5637 case RPC_FC_INT3264:
5638 case RPC_FC_UINT3264:
5639 return *(const ULONG_PTR *)pMemory;
5640 default:
5641 FIXME("Unhandled base type: 0x%02x\n", fc);
5642 return 0;
5646 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5647 ULONG discriminant,
5648 PFORMAT_STRING pFormat)
5650 unsigned short num_arms, arm, type;
5652 num_arms = *(const SHORT*)pFormat & 0x0fff;
5653 pFormat += 2;
5654 for(arm = 0; arm < num_arms; arm++)
5656 if(discriminant == *(const ULONG*)pFormat)
5658 pFormat += 4;
5659 break;
5661 pFormat += 6;
5664 type = *(const unsigned short*)pFormat;
5665 TRACE("type %04x\n", type);
5666 if(arm == num_arms) /* default arm extras */
5668 if(type == 0xffff)
5670 ERR("no arm for 0x%x and no default case\n", discriminant);
5671 RpcRaiseException(RPC_S_INVALID_TAG);
5672 return NULL;
5674 if(type == 0)
5676 TRACE("falling back to empty default case for 0x%x\n", discriminant);
5677 return NULL;
5680 return pFormat;
5683 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5685 unsigned short type;
5687 pFormat += 2;
5689 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5690 if(!pFormat)
5691 return NULL;
5693 type = *(const unsigned short*)pFormat;
5694 if((type & 0xff00) == 0x8000)
5696 unsigned char basetype = LOBYTE(type);
5697 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5699 else
5701 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5702 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5703 if (m)
5705 unsigned char *saved_buffer = NULL;
5706 BOOL pointer_buffer_mark_set = FALSE;
5707 switch(*desc)
5709 case RPC_FC_RP:
5710 case RPC_FC_UP:
5711 case RPC_FC_OP:
5712 case RPC_FC_FP:
5713 align_pointer_clear(&pStubMsg->Buffer, 4);
5714 saved_buffer = pStubMsg->Buffer;
5715 if (pStubMsg->PointerBufferMark)
5717 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5718 pStubMsg->PointerBufferMark = NULL;
5719 pointer_buffer_mark_set = TRUE;
5721 else
5722 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5724 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5725 if (pointer_buffer_mark_set)
5727 STD_OVERFLOW_CHECK(pStubMsg);
5728 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5729 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5731 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5732 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5733 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5735 pStubMsg->Buffer = saved_buffer + 4;
5737 break;
5738 default:
5739 m(pStubMsg, pMemory, desc);
5742 else FIXME("no marshaller for embedded type %02x\n", *desc);
5744 return NULL;
5747 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5748 unsigned char **ppMemory,
5749 ULONG discriminant,
5750 PFORMAT_STRING pFormat,
5751 unsigned char fMustAlloc)
5753 unsigned short type;
5755 pFormat += 2;
5757 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5758 if(!pFormat)
5759 return NULL;
5761 type = *(const unsigned short*)pFormat;
5762 if((type & 0xff00) == 0x8000)
5764 unsigned char basetype = LOBYTE(type);
5765 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5767 else
5769 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5770 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5771 if (m)
5773 unsigned char *saved_buffer = NULL;
5774 BOOL pointer_buffer_mark_set = FALSE;
5775 switch(*desc)
5777 case RPC_FC_RP:
5778 case RPC_FC_UP:
5779 case RPC_FC_OP:
5780 case RPC_FC_FP:
5781 align_pointer(&pStubMsg->Buffer, 4);
5782 saved_buffer = pStubMsg->Buffer;
5783 if (pStubMsg->PointerBufferMark)
5785 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5786 pStubMsg->PointerBufferMark = NULL;
5787 pointer_buffer_mark_set = TRUE;
5789 else
5790 pStubMsg->Buffer += 4; /* for pointer ID */
5792 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5794 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5795 saved_buffer, pStubMsg->BufferEnd);
5796 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5799 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5800 if (pointer_buffer_mark_set)
5802 STD_OVERFLOW_CHECK(pStubMsg);
5803 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5804 pStubMsg->Buffer = saved_buffer + 4;
5806 break;
5807 default:
5808 m(pStubMsg, ppMemory, desc, fMustAlloc);
5811 else FIXME("no marshaller for embedded type %02x\n", *desc);
5813 return NULL;
5816 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5817 unsigned char *pMemory,
5818 ULONG discriminant,
5819 PFORMAT_STRING pFormat)
5821 unsigned short type;
5823 pFormat += 2;
5825 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5826 if(!pFormat)
5827 return;
5829 type = *(const unsigned short*)pFormat;
5830 if((type & 0xff00) == 0x8000)
5832 unsigned char basetype = LOBYTE(type);
5833 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5835 else
5837 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5838 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5839 if (m)
5841 switch(*desc)
5843 case RPC_FC_RP:
5844 case RPC_FC_UP:
5845 case RPC_FC_OP:
5846 case RPC_FC_FP:
5847 align_length(&pStubMsg->BufferLength, 4);
5848 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5849 if (!pStubMsg->IgnoreEmbeddedPointers)
5851 int saved_buffer_length = pStubMsg->BufferLength;
5852 pStubMsg->BufferLength = pStubMsg->PointerLength;
5853 pStubMsg->PointerLength = 0;
5854 if(!pStubMsg->BufferLength)
5855 ERR("BufferLength == 0??\n");
5856 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5857 pStubMsg->PointerLength = pStubMsg->BufferLength;
5858 pStubMsg->BufferLength = saved_buffer_length;
5860 break;
5861 default:
5862 m(pStubMsg, pMemory, desc);
5865 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5869 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5870 ULONG discriminant,
5871 PFORMAT_STRING pFormat)
5873 unsigned short type, size;
5875 size = *(const unsigned short*)pFormat;
5876 pStubMsg->Memory += size;
5877 pFormat += 2;
5879 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5880 if(!pFormat)
5881 return 0;
5883 type = *(const unsigned short*)pFormat;
5884 if((type & 0xff00) == 0x8000)
5886 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5888 else
5890 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5891 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5892 unsigned char *saved_buffer;
5893 if (m)
5895 switch(*desc)
5897 case RPC_FC_RP:
5898 case RPC_FC_UP:
5899 case RPC_FC_OP:
5900 case RPC_FC_FP:
5901 align_pointer(&pStubMsg->Buffer, 4);
5902 saved_buffer = pStubMsg->Buffer;
5903 safe_buffer_increment(pStubMsg, 4);
5904 align_length(&pStubMsg->MemorySize, sizeof(void *));
5905 pStubMsg->MemorySize += sizeof(void *);
5906 if (!pStubMsg->IgnoreEmbeddedPointers)
5907 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5908 break;
5909 default:
5910 return m(pStubMsg, desc);
5913 else FIXME("no marshaller for embedded type %02x\n", *desc);
5916 TRACE("size %d\n", size);
5917 return size;
5920 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5921 unsigned char *pMemory,
5922 ULONG discriminant,
5923 PFORMAT_STRING pFormat)
5925 unsigned short type;
5927 pFormat += 2;
5929 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5930 if(!pFormat)
5931 return;
5933 type = *(const unsigned short*)pFormat;
5934 if((type & 0xff00) != 0x8000)
5936 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5937 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5938 if (m)
5940 switch(*desc)
5942 case RPC_FC_RP:
5943 case RPC_FC_UP:
5944 case RPC_FC_OP:
5945 case RPC_FC_FP:
5946 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5947 break;
5948 default:
5949 m(pStubMsg, pMemory, desc);
5955 /***********************************************************************
5956 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5958 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5959 unsigned char *pMemory,
5960 PFORMAT_STRING pFormat)
5962 unsigned char switch_type;
5963 unsigned char increment;
5964 ULONG switch_value;
5966 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5967 pFormat++;
5969 switch_type = *pFormat & 0xf;
5970 increment = (*pFormat & 0xf0) >> 4;
5971 pFormat++;
5973 align_pointer_clear(&pStubMsg->Buffer, increment);
5975 switch_value = get_discriminant(switch_type, pMemory);
5976 TRACE("got switch value 0x%x\n", switch_value);
5978 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5979 pMemory += increment;
5981 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5984 /***********************************************************************
5985 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5987 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5988 unsigned char **ppMemory,
5989 PFORMAT_STRING pFormat,
5990 unsigned char fMustAlloc)
5992 unsigned char switch_type;
5993 unsigned char increment;
5994 ULONG switch_value;
5995 unsigned short size;
5996 unsigned char *pMemoryArm;
5998 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5999 pFormat++;
6001 switch_type = *pFormat & 0xf;
6002 increment = (*pFormat & 0xf0) >> 4;
6003 pFormat++;
6005 align_pointer(&pStubMsg->Buffer, increment);
6006 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6007 TRACE("got switch value 0x%x\n", switch_value);
6009 size = *(const unsigned short*)pFormat + increment;
6010 if (!fMustAlloc && !*ppMemory)
6011 fMustAlloc = TRUE;
6012 if (fMustAlloc)
6013 *ppMemory = NdrAllocate(pStubMsg, size);
6015 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6016 * since the arm is part of the memory block that is encompassed by
6017 * the whole union. Memory is forced to allocate when pointers
6018 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6019 * clearing the memory we pass in to the unmarshaller */
6020 if (fMustAlloc)
6021 memset(*ppMemory, 0, size);
6023 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
6024 pMemoryArm = *ppMemory + increment;
6026 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, FALSE);
6029 /***********************************************************************
6030 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
6032 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6033 unsigned char *pMemory,
6034 PFORMAT_STRING pFormat)
6036 unsigned char switch_type;
6037 unsigned char increment;
6038 ULONG switch_value;
6040 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6041 pFormat++;
6043 switch_type = *pFormat & 0xf;
6044 increment = (*pFormat & 0xf0) >> 4;
6045 pFormat++;
6047 align_length(&pStubMsg->BufferLength, increment);
6048 switch_value = get_discriminant(switch_type, pMemory);
6049 TRACE("got switch value 0x%x\n", switch_value);
6051 /* Add discriminant size */
6052 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
6053 pMemory += increment;
6055 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
6058 /***********************************************************************
6059 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
6061 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6062 PFORMAT_STRING pFormat)
6064 unsigned char switch_type;
6065 unsigned char increment;
6066 ULONG switch_value;
6068 switch_type = *pFormat & 0xf;
6069 increment = (*pFormat & 0xf0) >> 4;
6070 pFormat++;
6072 align_pointer(&pStubMsg->Buffer, increment);
6073 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6074 TRACE("got switch value 0x%x\n", switch_value);
6076 pStubMsg->Memory += increment;
6078 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
6081 /***********************************************************************
6082 * NdrEncapsulatedUnionFree [RPCRT4.@]
6084 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6085 unsigned char *pMemory,
6086 PFORMAT_STRING pFormat)
6088 unsigned char switch_type;
6089 unsigned char increment;
6090 ULONG switch_value;
6092 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6093 pFormat++;
6095 switch_type = *pFormat & 0xf;
6096 increment = (*pFormat & 0xf0) >> 4;
6097 pFormat++;
6099 switch_value = get_discriminant(switch_type, pMemory);
6100 TRACE("got switch value 0x%x\n", switch_value);
6102 pMemory += increment;
6104 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
6107 /***********************************************************************
6108 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
6110 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6111 unsigned char *pMemory,
6112 PFORMAT_STRING pFormat)
6114 unsigned char switch_type;
6116 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6117 pFormat++;
6119 switch_type = *pFormat;
6120 pFormat++;
6122 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6123 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6124 /* Marshall discriminant */
6125 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6127 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6130 static LONG unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
6131 PFORMAT_STRING *ppFormat)
6133 LONG discriminant = 0;
6135 switch(**ppFormat)
6137 case RPC_FC_BYTE:
6138 case RPC_FC_CHAR:
6139 case RPC_FC_SMALL:
6140 case RPC_FC_USMALL:
6142 UCHAR d;
6143 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6144 discriminant = d;
6145 break;
6147 case RPC_FC_WCHAR:
6148 case RPC_FC_SHORT:
6149 case RPC_FC_USHORT:
6150 case RPC_FC_ENUM16:
6152 USHORT d;
6153 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6154 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6155 discriminant = d;
6156 break;
6158 case RPC_FC_LONG:
6159 case RPC_FC_ULONG:
6161 ULONG d;
6162 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6163 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6164 discriminant = d;
6165 break;
6167 default:
6168 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
6170 (*ppFormat)++;
6172 *ppFormat = SkipConformance(pStubMsg, *ppFormat);
6173 return discriminant;
6176 /**********************************************************************
6177 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6179 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6180 unsigned char **ppMemory,
6181 PFORMAT_STRING pFormat,
6182 unsigned char fMustAlloc)
6184 LONG discriminant;
6185 unsigned short size;
6187 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6188 pFormat++;
6190 /* Unmarshall discriminant */
6191 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6192 TRACE("unmarshalled discriminant %x\n", discriminant);
6194 pFormat += *(const SHORT*)pFormat;
6196 size = *(const unsigned short*)pFormat;
6198 if (!fMustAlloc && !*ppMemory)
6199 fMustAlloc = TRUE;
6200 if (fMustAlloc)
6201 *ppMemory = NdrAllocate(pStubMsg, size);
6203 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6204 * since the arm is part of the memory block that is encompassed by
6205 * the whole union. Memory is forced to allocate when pointers
6206 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6207 * clearing the memory we pass in to the unmarshaller */
6208 if (fMustAlloc)
6209 memset(*ppMemory, 0, size);
6211 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, FALSE);
6214 /***********************************************************************
6215 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6217 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6218 unsigned char *pMemory,
6219 PFORMAT_STRING pFormat)
6221 unsigned char switch_type;
6223 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6224 pFormat++;
6226 switch_type = *pFormat;
6227 pFormat++;
6229 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6230 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6231 /* Add discriminant size */
6232 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6234 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6237 /***********************************************************************
6238 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6240 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6241 PFORMAT_STRING pFormat)
6243 ULONG discriminant;
6245 pFormat++;
6246 /* Unmarshall discriminant */
6247 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6248 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
6250 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
6253 /***********************************************************************
6254 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6256 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6257 unsigned char *pMemory,
6258 PFORMAT_STRING pFormat)
6260 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6261 pFormat++;
6262 pFormat++;
6264 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6265 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6267 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6270 /***********************************************************************
6271 * NdrByteCountPointerMarshall [RPCRT4.@]
6273 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6274 unsigned char *pMemory,
6275 PFORMAT_STRING pFormat)
6277 FIXME("stub\n");
6278 return NULL;
6281 /***********************************************************************
6282 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6284 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6285 unsigned char **ppMemory,
6286 PFORMAT_STRING pFormat,
6287 unsigned char fMustAlloc)
6289 FIXME("stub\n");
6290 return NULL;
6293 /***********************************************************************
6294 * NdrByteCountPointerBufferSize [RPCRT4.@]
6296 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6297 unsigned char *pMemory,
6298 PFORMAT_STRING pFormat)
6300 FIXME("stub\n");
6303 /***********************************************************************
6304 * NdrByteCountPointerMemorySize [internal]
6306 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6307 PFORMAT_STRING pFormat)
6309 FIXME("stub\n");
6310 return 0;
6313 /***********************************************************************
6314 * NdrByteCountPointerFree [RPCRT4.@]
6316 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6317 unsigned char *pMemory,
6318 PFORMAT_STRING pFormat)
6320 FIXME("stub\n");
6323 /***********************************************************************
6324 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6326 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6327 unsigned char *pMemory,
6328 PFORMAT_STRING pFormat)
6330 FIXME("stub\n");
6331 return NULL;
6334 /***********************************************************************
6335 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6337 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6338 unsigned char **ppMemory,
6339 PFORMAT_STRING pFormat,
6340 unsigned char fMustAlloc)
6342 FIXME("stub\n");
6343 return NULL;
6346 /***********************************************************************
6347 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6349 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6350 unsigned char *pMemory,
6351 PFORMAT_STRING pFormat)
6353 FIXME("stub\n");
6356 /***********************************************************************
6357 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6359 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6360 PFORMAT_STRING pFormat)
6362 FIXME("stub\n");
6363 return 0;
6366 /***********************************************************************
6367 * NdrXmitOrRepAsFree [RPCRT4.@]
6369 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6370 unsigned char *pMemory,
6371 PFORMAT_STRING pFormat)
6373 FIXME("stub\n");
6376 /***********************************************************************
6377 * NdrRangeMarshall [internal]
6379 static unsigned char *WINAPI NdrRangeMarshall(
6380 PMIDL_STUB_MESSAGE pStubMsg,
6381 unsigned char *pMemory,
6382 PFORMAT_STRING pFormat)
6384 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6385 unsigned char base_type;
6387 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6389 if (pRange->type != RPC_FC_RANGE)
6391 ERR("invalid format type %x\n", pRange->type);
6392 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6393 return NULL;
6396 base_type = pRange->flags_type & 0xf;
6398 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6401 /***********************************************************************
6402 * NdrRangeUnmarshall [RPCRT4.@]
6404 unsigned char *WINAPI NdrRangeUnmarshall(
6405 PMIDL_STUB_MESSAGE pStubMsg,
6406 unsigned char **ppMemory,
6407 PFORMAT_STRING pFormat,
6408 unsigned char fMustAlloc)
6410 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6411 unsigned char base_type;
6413 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6415 if (pRange->type != RPC_FC_RANGE)
6417 ERR("invalid format type %x\n", pRange->type);
6418 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6419 return NULL;
6421 base_type = pRange->flags_type & 0xf;
6423 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6424 base_type, pRange->low_value, pRange->high_value);
6426 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6427 do \
6429 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \
6430 if (!fMustAlloc && !*ppMemory) \
6431 fMustAlloc = TRUE; \
6432 if (fMustAlloc) \
6433 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6434 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6436 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6437 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6438 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6440 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6441 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6443 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6444 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6445 (mem_type)pRange->high_value); \
6446 RpcRaiseException(RPC_S_INVALID_BOUND); \
6447 return NULL; \
6449 TRACE("*ppMemory: %p\n", *ppMemory); \
6450 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6451 pStubMsg->Buffer += sizeof(wire_type); \
6452 } while (0)
6454 switch(base_type)
6456 case RPC_FC_CHAR:
6457 case RPC_FC_SMALL:
6458 RANGE_UNMARSHALL(UCHAR, UCHAR, "%d");
6459 TRACE("value: 0x%02x\n", **ppMemory);
6460 break;
6461 case RPC_FC_BYTE:
6462 case RPC_FC_USMALL:
6463 RANGE_UNMARSHALL(CHAR, CHAR, "%u");
6464 TRACE("value: 0x%02x\n", **ppMemory);
6465 break;
6466 case RPC_FC_WCHAR: /* FIXME: valid? */
6467 case RPC_FC_USHORT:
6468 RANGE_UNMARSHALL(USHORT, USHORT, "%u");
6469 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6470 break;
6471 case RPC_FC_SHORT:
6472 RANGE_UNMARSHALL(SHORT, SHORT, "%d");
6473 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6474 break;
6475 case RPC_FC_LONG:
6476 case RPC_FC_ENUM32:
6477 RANGE_UNMARSHALL(LONG, LONG, "%d");
6478 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6479 break;
6480 case RPC_FC_ULONG:
6481 RANGE_UNMARSHALL(ULONG, ULONG, "%u");
6482 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6483 break;
6484 case RPC_FC_ENUM16:
6485 RANGE_UNMARSHALL(UINT, USHORT, "%u");
6486 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6487 break;
6488 case RPC_FC_FLOAT:
6489 case RPC_FC_DOUBLE:
6490 case RPC_FC_HYPER:
6491 default:
6492 ERR("invalid range base type: 0x%02x\n", base_type);
6493 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6496 return NULL;
6499 /***********************************************************************
6500 * NdrRangeBufferSize [internal]
6502 static void WINAPI NdrRangeBufferSize(
6503 PMIDL_STUB_MESSAGE pStubMsg,
6504 unsigned char *pMemory,
6505 PFORMAT_STRING pFormat)
6507 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6508 unsigned char base_type;
6510 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6512 if (pRange->type != RPC_FC_RANGE)
6514 ERR("invalid format type %x\n", pRange->type);
6515 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6517 base_type = pRange->flags_type & 0xf;
6519 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6522 /***********************************************************************
6523 * NdrRangeMemorySize [internal]
6525 static ULONG WINAPI NdrRangeMemorySize(
6526 PMIDL_STUB_MESSAGE pStubMsg,
6527 PFORMAT_STRING pFormat)
6529 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6530 unsigned char base_type;
6532 if (pRange->type != RPC_FC_RANGE)
6534 ERR("invalid format type %x\n", pRange->type);
6535 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6536 return 0;
6538 base_type = pRange->flags_type & 0xf;
6540 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6543 /***********************************************************************
6544 * NdrRangeFree [internal]
6546 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6547 unsigned char *pMemory,
6548 PFORMAT_STRING pFormat)
6550 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6552 /* nothing to do */
6555 /***********************************************************************
6556 * NdrBaseTypeMarshall [internal]
6558 static unsigned char *WINAPI NdrBaseTypeMarshall(
6559 PMIDL_STUB_MESSAGE pStubMsg,
6560 unsigned char *pMemory,
6561 PFORMAT_STRING pFormat)
6563 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6565 switch(*pFormat)
6567 case RPC_FC_BYTE:
6568 case RPC_FC_CHAR:
6569 case RPC_FC_SMALL:
6570 case RPC_FC_USMALL:
6571 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6572 TRACE("value: 0x%02x\n", *pMemory);
6573 break;
6574 case RPC_FC_WCHAR:
6575 case RPC_FC_SHORT:
6576 case RPC_FC_USHORT:
6577 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6578 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6579 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6580 break;
6581 case RPC_FC_LONG:
6582 case RPC_FC_ULONG:
6583 case RPC_FC_ERROR_STATUS_T:
6584 case RPC_FC_ENUM32:
6585 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONG));
6586 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6587 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6588 break;
6589 case RPC_FC_FLOAT:
6590 align_pointer_clear(&pStubMsg->Buffer, sizeof(float));
6591 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6592 break;
6593 case RPC_FC_DOUBLE:
6594 align_pointer_clear(&pStubMsg->Buffer, sizeof(double));
6595 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6596 break;
6597 case RPC_FC_HYPER:
6598 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONGLONG));
6599 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6600 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6601 break;
6602 case RPC_FC_ENUM16:
6604 USHORT val = *(UINT *)pMemory;
6605 /* only 16-bits on the wire, so do a sanity check */
6606 if (*(UINT *)pMemory > SHRT_MAX)
6607 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6608 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6609 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6610 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6611 break;
6613 case RPC_FC_INT3264:
6614 case RPC_FC_UINT3264:
6616 UINT val = *(UINT_PTR *)pMemory;
6617 align_pointer_clear(&pStubMsg->Buffer, sizeof(UINT));
6618 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6619 break;
6621 case RPC_FC_IGNORE:
6622 break;
6623 default:
6624 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6627 /* FIXME: what is the correct return value? */
6628 return NULL;
6631 /***********************************************************************
6632 * NdrBaseTypeUnmarshall [internal]
6634 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6635 PMIDL_STUB_MESSAGE pStubMsg,
6636 unsigned char **ppMemory,
6637 PFORMAT_STRING pFormat,
6638 unsigned char fMustAlloc)
6640 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6642 #define BASE_TYPE_UNMARSHALL(type) do { \
6643 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
6644 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6646 *ppMemory = pStubMsg->Buffer; \
6647 TRACE("*ppMemory: %p\n", *ppMemory); \
6648 safe_buffer_increment(pStubMsg, sizeof(type)); \
6650 else \
6652 if (fMustAlloc) \
6653 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6654 TRACE("*ppMemory: %p\n", *ppMemory); \
6655 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6657 } while (0)
6659 switch(*pFormat)
6661 case RPC_FC_BYTE:
6662 case RPC_FC_CHAR:
6663 case RPC_FC_SMALL:
6664 case RPC_FC_USMALL:
6665 BASE_TYPE_UNMARSHALL(UCHAR);
6666 TRACE("value: 0x%02x\n", **ppMemory);
6667 break;
6668 case RPC_FC_WCHAR:
6669 case RPC_FC_SHORT:
6670 case RPC_FC_USHORT:
6671 BASE_TYPE_UNMARSHALL(USHORT);
6672 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6673 break;
6674 case RPC_FC_LONG:
6675 case RPC_FC_ULONG:
6676 case RPC_FC_ERROR_STATUS_T:
6677 case RPC_FC_ENUM32:
6678 BASE_TYPE_UNMARSHALL(ULONG);
6679 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6680 break;
6681 case RPC_FC_FLOAT:
6682 BASE_TYPE_UNMARSHALL(float);
6683 TRACE("value: %f\n", **(float **)ppMemory);
6684 break;
6685 case RPC_FC_DOUBLE:
6686 BASE_TYPE_UNMARSHALL(double);
6687 TRACE("value: %f\n", **(double **)ppMemory);
6688 break;
6689 case RPC_FC_HYPER:
6690 BASE_TYPE_UNMARSHALL(ULONGLONG);
6691 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6692 break;
6693 case RPC_FC_ENUM16:
6695 USHORT val;
6696 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6697 if (!fMustAlloc && !*ppMemory)
6698 fMustAlloc = TRUE;
6699 if (fMustAlloc)
6700 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6701 safe_copy_from_buffer(pStubMsg, &val, sizeof(USHORT));
6702 /* 16-bits on the wire, but int in memory */
6703 **(UINT **)ppMemory = val;
6704 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6705 break;
6707 case RPC_FC_INT3264:
6708 if (sizeof(INT_PTR) == sizeof(INT)) BASE_TYPE_UNMARSHALL(INT);
6709 else
6711 INT val;
6712 align_pointer(&pStubMsg->Buffer, sizeof(INT));
6713 if (!fMustAlloc && !*ppMemory)
6714 fMustAlloc = TRUE;
6715 if (fMustAlloc)
6716 *ppMemory = NdrAllocate(pStubMsg, sizeof(INT_PTR));
6717 safe_copy_from_buffer(pStubMsg, &val, sizeof(INT));
6718 **(INT_PTR **)ppMemory = val;
6719 TRACE("value: 0x%08lx\n", **(INT_PTR **)ppMemory);
6721 break;
6722 case RPC_FC_UINT3264:
6723 if (sizeof(UINT_PTR) == sizeof(UINT)) BASE_TYPE_UNMARSHALL(UINT);
6724 else
6726 UINT val;
6727 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6728 if (!fMustAlloc && !*ppMemory)
6729 fMustAlloc = TRUE;
6730 if (fMustAlloc)
6731 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT_PTR));
6732 safe_copy_from_buffer(pStubMsg, &val, sizeof(UINT));
6733 **(UINT_PTR **)ppMemory = val;
6734 TRACE("value: 0x%08lx\n", **(UINT_PTR **)ppMemory);
6736 break;
6737 case RPC_FC_IGNORE:
6738 break;
6739 default:
6740 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6742 #undef BASE_TYPE_UNMARSHALL
6744 /* FIXME: what is the correct return value? */
6746 return NULL;
6749 /***********************************************************************
6750 * NdrBaseTypeBufferSize [internal]
6752 static void WINAPI NdrBaseTypeBufferSize(
6753 PMIDL_STUB_MESSAGE pStubMsg,
6754 unsigned char *pMemory,
6755 PFORMAT_STRING pFormat)
6757 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6759 switch(*pFormat)
6761 case RPC_FC_BYTE:
6762 case RPC_FC_CHAR:
6763 case RPC_FC_SMALL:
6764 case RPC_FC_USMALL:
6765 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6766 break;
6767 case RPC_FC_WCHAR:
6768 case RPC_FC_SHORT:
6769 case RPC_FC_USHORT:
6770 case RPC_FC_ENUM16:
6771 align_length(&pStubMsg->BufferLength, sizeof(USHORT));
6772 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6773 break;
6774 case RPC_FC_LONG:
6775 case RPC_FC_ULONG:
6776 case RPC_FC_ENUM32:
6777 case RPC_FC_INT3264:
6778 case RPC_FC_UINT3264:
6779 align_length(&pStubMsg->BufferLength, sizeof(ULONG));
6780 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6781 break;
6782 case RPC_FC_FLOAT:
6783 align_length(&pStubMsg->BufferLength, sizeof(float));
6784 safe_buffer_length_increment(pStubMsg, sizeof(float));
6785 break;
6786 case RPC_FC_DOUBLE:
6787 align_length(&pStubMsg->BufferLength, sizeof(double));
6788 safe_buffer_length_increment(pStubMsg, sizeof(double));
6789 break;
6790 case RPC_FC_HYPER:
6791 align_length(&pStubMsg->BufferLength, sizeof(ULONGLONG));
6792 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6793 break;
6794 case RPC_FC_ERROR_STATUS_T:
6795 align_length(&pStubMsg->BufferLength, sizeof(error_status_t));
6796 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6797 break;
6798 case RPC_FC_IGNORE:
6799 break;
6800 default:
6801 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6805 /***********************************************************************
6806 * NdrBaseTypeMemorySize [internal]
6808 static ULONG WINAPI NdrBaseTypeMemorySize(
6809 PMIDL_STUB_MESSAGE pStubMsg,
6810 PFORMAT_STRING pFormat)
6812 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6814 switch(*pFormat)
6816 case RPC_FC_BYTE:
6817 case RPC_FC_CHAR:
6818 case RPC_FC_SMALL:
6819 case RPC_FC_USMALL:
6820 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6821 pStubMsg->MemorySize += sizeof(UCHAR);
6822 return sizeof(UCHAR);
6823 case RPC_FC_WCHAR:
6824 case RPC_FC_SHORT:
6825 case RPC_FC_USHORT:
6826 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6827 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6828 align_length(&pStubMsg->MemorySize, sizeof(USHORT));
6829 pStubMsg->MemorySize += sizeof(USHORT);
6830 return sizeof(USHORT);
6831 case RPC_FC_LONG:
6832 case RPC_FC_ULONG:
6833 case RPC_FC_ENUM32:
6834 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6835 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6836 align_length(&pStubMsg->MemorySize, sizeof(ULONG));
6837 pStubMsg->MemorySize += sizeof(ULONG);
6838 return sizeof(ULONG);
6839 case RPC_FC_FLOAT:
6840 align_pointer(&pStubMsg->Buffer, sizeof(float));
6841 safe_buffer_increment(pStubMsg, sizeof(float));
6842 align_length(&pStubMsg->MemorySize, sizeof(float));
6843 pStubMsg->MemorySize += sizeof(float);
6844 return sizeof(float);
6845 case RPC_FC_DOUBLE:
6846 align_pointer(&pStubMsg->Buffer, sizeof(double));
6847 safe_buffer_increment(pStubMsg, sizeof(double));
6848 align_length(&pStubMsg->MemorySize, sizeof(double));
6849 pStubMsg->MemorySize += sizeof(double);
6850 return sizeof(double);
6851 case RPC_FC_HYPER:
6852 align_pointer(&pStubMsg->Buffer, sizeof(ULONGLONG));
6853 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6854 align_length(&pStubMsg->MemorySize, sizeof(ULONGLONG));
6855 pStubMsg->MemorySize += sizeof(ULONGLONG);
6856 return sizeof(ULONGLONG);
6857 case RPC_FC_ERROR_STATUS_T:
6858 align_pointer(&pStubMsg->Buffer, sizeof(error_status_t));
6859 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6860 align_length(&pStubMsg->MemorySize, sizeof(error_status_t));
6861 pStubMsg->MemorySize += sizeof(error_status_t);
6862 return sizeof(error_status_t);
6863 case RPC_FC_ENUM16:
6864 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6865 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6866 align_length(&pStubMsg->MemorySize, sizeof(UINT));
6867 pStubMsg->MemorySize += sizeof(UINT);
6868 return sizeof(UINT);
6869 case RPC_FC_INT3264:
6870 case RPC_FC_UINT3264:
6871 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6872 safe_buffer_increment(pStubMsg, sizeof(UINT));
6873 align_length(&pStubMsg->MemorySize, sizeof(UINT_PTR));
6874 pStubMsg->MemorySize += sizeof(UINT_PTR);
6875 return sizeof(UINT_PTR);
6876 case RPC_FC_IGNORE:
6877 align_length(&pStubMsg->MemorySize, sizeof(void *));
6878 pStubMsg->MemorySize += sizeof(void *);
6879 return sizeof(void *);
6880 default:
6881 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6882 return 0;
6886 /***********************************************************************
6887 * NdrBaseTypeFree [internal]
6889 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6890 unsigned char *pMemory,
6891 PFORMAT_STRING pFormat)
6893 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6895 /* nothing to do */
6898 /***********************************************************************
6899 * NdrContextHandleBufferSize [internal]
6901 static void WINAPI NdrContextHandleBufferSize(
6902 PMIDL_STUB_MESSAGE pStubMsg,
6903 unsigned char *pMemory,
6904 PFORMAT_STRING pFormat)
6906 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6908 if (*pFormat != RPC_FC_BIND_CONTEXT)
6910 ERR("invalid format type %x\n", *pFormat);
6911 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6913 align_length(&pStubMsg->BufferLength, 4);
6914 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6917 /***********************************************************************
6918 * NdrContextHandleMarshall [internal]
6920 static unsigned char *WINAPI NdrContextHandleMarshall(
6921 PMIDL_STUB_MESSAGE pStubMsg,
6922 unsigned char *pMemory,
6923 PFORMAT_STRING pFormat)
6925 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6927 if (*pFormat != RPC_FC_BIND_CONTEXT)
6929 ERR("invalid format type %x\n", *pFormat);
6930 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6932 TRACE("flags: 0x%02x\n", pFormat[1]);
6934 if (pStubMsg->IsClient)
6936 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6937 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6938 else
6939 NdrClientContextMarshall(pStubMsg, pMemory, FALSE);
6941 else
6943 NDR_SCONTEXT ctxt = NDRSContextFromValue(pMemory);
6944 NDR_RUNDOWN rundown = pStubMsg->StubDesc->apfnNdrRundownRoutines[pFormat[2]];
6945 NdrServerContextNewMarshall(pStubMsg, ctxt, rundown, pFormat);
6948 return NULL;
6951 /***********************************************************************
6952 * NdrContextHandleUnmarshall [internal]
6954 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6955 PMIDL_STUB_MESSAGE pStubMsg,
6956 unsigned char **ppMemory,
6957 PFORMAT_STRING pFormat,
6958 unsigned char fMustAlloc)
6960 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6961 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6963 if (*pFormat != RPC_FC_BIND_CONTEXT)
6965 ERR("invalid format type %x\n", *pFormat);
6966 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6968 TRACE("flags: 0x%02x\n", pFormat[1]);
6970 if (pStubMsg->IsClient)
6972 /* [out]-only or [ret] param */
6973 if ((pFormat[1] & (HANDLE_PARAM_IS_IN|HANDLE_PARAM_IS_OUT)) == HANDLE_PARAM_IS_OUT)
6974 **(NDR_CCONTEXT **)ppMemory = NULL;
6975 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6977 else
6979 NDR_SCONTEXT ctxt;
6980 ctxt = NdrServerContextNewUnmarshall(pStubMsg, pFormat);
6981 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6982 *(void **)ppMemory = NDRSContextValue(ctxt);
6983 else
6984 *(void **)ppMemory = *NDRSContextValue(ctxt);
6987 return NULL;
6990 /***********************************************************************
6991 * NdrClientContextMarshall [RPCRT4.@]
6993 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6994 NDR_CCONTEXT ContextHandle,
6995 int fCheck)
6997 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
6999 align_pointer_clear(&pStubMsg->Buffer, 4);
7001 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7003 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7004 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7005 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7008 /* FIXME: what does fCheck do? */
7009 NDRCContextMarshall(ContextHandle,
7010 pStubMsg->Buffer);
7012 pStubMsg->Buffer += cbNDRContext;
7015 /***********************************************************************
7016 * NdrClientContextUnmarshall [RPCRT4.@]
7018 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7019 NDR_CCONTEXT * pContextHandle,
7020 RPC_BINDING_HANDLE BindHandle)
7022 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
7024 align_pointer(&pStubMsg->Buffer, 4);
7026 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
7027 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7029 NDRCContextUnmarshall(pContextHandle,
7030 BindHandle,
7031 pStubMsg->Buffer,
7032 pStubMsg->RpcMsg->DataRepresentation);
7034 pStubMsg->Buffer += cbNDRContext;
7037 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7038 NDR_SCONTEXT ContextHandle,
7039 NDR_RUNDOWN RundownRoutine )
7041 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
7043 align_pointer(&pStubMsg->Buffer, 4);
7045 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7047 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7048 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7049 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7052 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7053 pStubMsg->Buffer, RundownRoutine, NULL,
7054 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7055 pStubMsg->Buffer += cbNDRContext;
7058 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
7060 NDR_SCONTEXT ContextHandle;
7062 TRACE("(%p)\n", pStubMsg);
7064 align_pointer(&pStubMsg->Buffer, 4);
7066 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7068 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7069 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7070 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7073 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7074 pStubMsg->Buffer,
7075 pStubMsg->RpcMsg->DataRepresentation,
7076 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7077 pStubMsg->Buffer += cbNDRContext;
7079 return ContextHandle;
7082 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
7083 unsigned char* pMemory,
7084 PFORMAT_STRING pFormat)
7086 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
7089 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
7090 PFORMAT_STRING pFormat)
7092 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7093 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7095 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7097 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7098 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7099 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7100 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7101 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7103 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7104 if_id = &sif->InterfaceId;
7107 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
7108 pStubMsg->RpcMsg->DataRepresentation, if_id,
7109 flags);
7112 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7113 NDR_SCONTEXT ContextHandle,
7114 NDR_RUNDOWN RundownRoutine,
7115 PFORMAT_STRING pFormat)
7117 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7118 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7120 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
7122 align_pointer(&pStubMsg->Buffer, 4);
7124 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7126 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7127 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7128 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7131 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7132 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7133 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7134 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7135 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7137 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7138 if_id = &sif->InterfaceId;
7141 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7142 pStubMsg->Buffer, RundownRoutine, if_id, flags);
7143 pStubMsg->Buffer += cbNDRContext;
7146 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7147 PFORMAT_STRING pFormat)
7149 NDR_SCONTEXT ContextHandle;
7150 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7151 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7153 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7155 align_pointer(&pStubMsg->Buffer, 4);
7157 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7159 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7160 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7161 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7164 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7165 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7166 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7167 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7168 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7170 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7171 if_id = &sif->InterfaceId;
7174 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7175 pStubMsg->Buffer,
7176 pStubMsg->RpcMsg->DataRepresentation,
7177 if_id, flags);
7178 pStubMsg->Buffer += cbNDRContext;
7180 return ContextHandle;
7183 /***********************************************************************
7184 * NdrCorrelationInitialize [RPCRT4.@]
7186 * Initializes correlation validity checking.
7188 * PARAMS
7189 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7190 * pMemory [I] Pointer to memory to use as a cache.
7191 * CacheSize [I] Size of the memory pointed to by pMemory.
7192 * Flags [I] Reserved. Set to zero.
7194 * RETURNS
7195 * Nothing.
7197 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
7199 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
7200 pStubMsg->fHasNewCorrDesc = TRUE;
7203 /***********************************************************************
7204 * NdrCorrelationPass [RPCRT4.@]
7206 * Performs correlation validity checking.
7208 * PARAMS
7209 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7211 * RETURNS
7212 * Nothing.
7214 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
7216 FIXME("(%p): stub\n", pStubMsg);
7219 /***********************************************************************
7220 * NdrCorrelationFree [RPCRT4.@]
7222 * Frees any resources used while unmarshalling parameters that need
7223 * correlation validity checking.
7225 * PARAMS
7226 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7228 * RETURNS
7229 * Nothing.
7231 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
7233 FIXME("(%p): stub\n", pStubMsg);