services: Move service cleanup code to separate function.
[wine/multimedia.git] / dlls / rpcrt4 / ndr_marshall.c
blobf0482e62dd3b381d4ccf46299d50d1b24d99eb9d
1 /*
2 * NDR data marshalling
4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 * TODO:
22 * - String structs
23 * - Byte count pointers
24 * - transmit_as/represent as
25 * - Multi-dimensional arrays
26 * - Conversion functions (NdrConvert)
27 * - Checks for integer addition overflow in user marshall functions
30 #include <assert.h>
31 #include <stdarg.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <limits.h>
36 #define NONAMELESSUNION
37 #include "windef.h"
38 #include "winbase.h"
39 #include "winerror.h"
41 #include "ndr_misc.h"
42 #include "rpcndr.h"
43 #include "ndrtypes.h"
45 #include "wine/unicode.h"
46 #include "wine/rpcfc.h"
48 #include "wine/debug.h"
50 WINE_DEFAULT_DEBUG_CHANNEL(ole);
52 #if defined(__i386__)
53 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
54 (*((UINT32 *)(pchar)) = (uint32))
56 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
57 (*((UINT32 *)(pchar)))
58 #else
59 /* these would work for i386 too, but less efficient */
60 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
61 (*(pchar) = LOBYTE(LOWORD(uint32)), \
62 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
63 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
64 *((pchar)+3) = HIBYTE(HIWORD(uint32)))
66 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
67 (MAKELONG( \
68 MAKEWORD(*(pchar), *((pchar)+1)), \
69 MAKEWORD(*((pchar)+2), *((pchar)+3))))
70 #endif
72 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
73 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
74 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
75 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
76 *(pchar) = HIBYTE(HIWORD(uint32)))
78 #define BIG_ENDIAN_UINT32_READ(pchar) \
79 (MAKELONG( \
80 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
81 MAKEWORD(*((pchar)+1), *(pchar))))
83 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
84 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
85 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
86 # define NDR_LOCAL_UINT32_READ(pchar) \
87 BIG_ENDIAN_UINT32_READ(pchar)
88 #else
89 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
90 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
91 # define NDR_LOCAL_UINT32_READ(pchar) \
92 LITTLE_ENDIAN_UINT32_READ(pchar)
93 #endif
95 static inline void align_length( ULONG *len, unsigned int align )
97 *len = (*len + align - 1) & ~(align - 1);
100 static inline void align_pointer( unsigned char **ptr, unsigned int align )
102 ULONG_PTR mask = align - 1;
103 *ptr = (unsigned char *)(((ULONG_PTR)*ptr + mask) & ~mask);
106 static inline void align_pointer_clear( unsigned char **ptr, unsigned int align )
108 ULONG_PTR mask = align - 1;
109 memset( *ptr, 0, (align - (ULONG_PTR)*ptr) & mask );
110 *ptr = (unsigned char *)(((ULONG_PTR)*ptr + mask) & ~mask);
113 #define STD_OVERFLOW_CHECK(_Msg) do { \
114 TRACE("buffer=%d/%d\n", (ULONG)(_Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer), _Msg->BufferLength); \
115 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
116 ERR("buffer overflow %d bytes\n", (ULONG)(_Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength))); \
117 } while (0)
119 #define NDR_POINTER_ID_BASE 0x20000
120 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
121 #define NDR_TABLE_SIZE 128
122 #define NDR_TABLE_MASK 127
124 #define NDRSContextFromValue(user_context) (NDR_SCONTEXT)((char *)(user_context) - (char *)NDRSContextValue((NDR_SCONTEXT)NULL))
126 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
127 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
128 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
129 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
130 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
132 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
133 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
134 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
136 static unsigned char *WINAPI NdrRangeMarshall(PMIDL_STUB_MESSAGE,unsigned char *, PFORMAT_STRING);
137 static void WINAPI NdrRangeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
138 static ULONG WINAPI NdrRangeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
139 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
141 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
143 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
144 unsigned char *pMemory,
145 PFORMAT_STRING pFormat,
146 PFORMAT_STRING pPointer);
147 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
148 unsigned char *pMemory,
149 PFORMAT_STRING pFormat,
150 PFORMAT_STRING pPointer);
151 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
152 unsigned char *pMemory,
153 PFORMAT_STRING pFormat,
154 PFORMAT_STRING pPointer,
155 unsigned char fMustAlloc);
156 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
157 PFORMAT_STRING pFormat,
158 PFORMAT_STRING pPointer);
159 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
160 unsigned char *pMemory,
161 PFORMAT_STRING pFormat,
162 PFORMAT_STRING pPointer);
164 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
166 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
167 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
168 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
169 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
170 /* 0x10 */
171 NdrBaseTypeMarshall,
172 /* 0x11 */
173 NdrPointerMarshall, NdrPointerMarshall,
174 NdrPointerMarshall, NdrPointerMarshall,
175 /* 0x15 */
176 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
177 NdrConformantStructMarshall, NdrConformantStructMarshall,
178 NdrConformantVaryingStructMarshall,
179 NdrComplexStructMarshall,
180 /* 0x1b */
181 NdrConformantArrayMarshall,
182 NdrConformantVaryingArrayMarshall,
183 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
184 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
185 NdrComplexArrayMarshall,
186 /* 0x22 */
187 NdrConformantStringMarshall, 0, 0,
188 NdrConformantStringMarshall,
189 NdrNonConformantStringMarshall, 0, 0, 0,
190 /* 0x2a */
191 NdrEncapsulatedUnionMarshall,
192 NdrNonEncapsulatedUnionMarshall,
193 NdrByteCountPointerMarshall,
194 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
195 /* 0x2f */
196 NdrInterfacePointerMarshall,
197 /* 0x30 */
198 NdrContextHandleMarshall,
199 /* 0xb1 */
200 0, 0, 0,
201 NdrUserMarshalMarshall,
202 0, 0,
203 /* 0xb7 */
204 NdrRangeMarshall
206 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
208 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
209 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
210 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
211 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
212 /* 0x10 */
213 NdrBaseTypeUnmarshall,
214 /* 0x11 */
215 NdrPointerUnmarshall, NdrPointerUnmarshall,
216 NdrPointerUnmarshall, NdrPointerUnmarshall,
217 /* 0x15 */
218 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
219 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
220 NdrConformantVaryingStructUnmarshall,
221 NdrComplexStructUnmarshall,
222 /* 0x1b */
223 NdrConformantArrayUnmarshall,
224 NdrConformantVaryingArrayUnmarshall,
225 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
226 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
227 NdrComplexArrayUnmarshall,
228 /* 0x22 */
229 NdrConformantStringUnmarshall, 0, 0,
230 NdrConformantStringUnmarshall,
231 NdrNonConformantStringUnmarshall, 0, 0, 0,
232 /* 0x2a */
233 NdrEncapsulatedUnionUnmarshall,
234 NdrNonEncapsulatedUnionUnmarshall,
235 NdrByteCountPointerUnmarshall,
236 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
237 /* 0x2f */
238 NdrInterfacePointerUnmarshall,
239 /* 0x30 */
240 NdrContextHandleUnmarshall,
241 /* 0xb1 */
242 0, 0, 0,
243 NdrUserMarshalUnmarshall,
244 0, 0,
245 /* 0xb7 */
246 NdrRangeUnmarshall
248 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
250 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
251 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
252 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
253 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
254 /* 0x10 */
255 NdrBaseTypeBufferSize,
256 /* 0x11 */
257 NdrPointerBufferSize, NdrPointerBufferSize,
258 NdrPointerBufferSize, NdrPointerBufferSize,
259 /* 0x15 */
260 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
261 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
262 NdrConformantVaryingStructBufferSize,
263 NdrComplexStructBufferSize,
264 /* 0x1b */
265 NdrConformantArrayBufferSize,
266 NdrConformantVaryingArrayBufferSize,
267 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
268 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
269 NdrComplexArrayBufferSize,
270 /* 0x22 */
271 NdrConformantStringBufferSize, 0, 0,
272 NdrConformantStringBufferSize,
273 NdrNonConformantStringBufferSize, 0, 0, 0,
274 /* 0x2a */
275 NdrEncapsulatedUnionBufferSize,
276 NdrNonEncapsulatedUnionBufferSize,
277 NdrByteCountPointerBufferSize,
278 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
279 /* 0x2f */
280 NdrInterfacePointerBufferSize,
281 /* 0x30 */
282 NdrContextHandleBufferSize,
283 /* 0xb1 */
284 0, 0, 0,
285 NdrUserMarshalBufferSize,
286 0, 0,
287 /* 0xb7 */
288 NdrRangeBufferSize
290 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
292 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
293 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
294 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
295 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
296 /* 0x10 */
297 NdrBaseTypeMemorySize,
298 /* 0x11 */
299 NdrPointerMemorySize, NdrPointerMemorySize,
300 NdrPointerMemorySize, NdrPointerMemorySize,
301 /* 0x15 */
302 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
303 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
304 NdrConformantVaryingStructMemorySize,
305 NdrComplexStructMemorySize,
306 /* 0x1b */
307 NdrConformantArrayMemorySize,
308 NdrConformantVaryingArrayMemorySize,
309 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
310 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
311 NdrComplexArrayMemorySize,
312 /* 0x22 */
313 NdrConformantStringMemorySize, 0, 0,
314 NdrConformantStringMemorySize,
315 NdrNonConformantStringMemorySize, 0, 0, 0,
316 /* 0x2a */
317 NdrEncapsulatedUnionMemorySize,
318 NdrNonEncapsulatedUnionMemorySize,
319 NdrByteCountPointerMemorySize,
320 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
321 /* 0x2f */
322 NdrInterfacePointerMemorySize,
323 /* 0x30 */
325 /* 0xb1 */
326 0, 0, 0,
327 NdrUserMarshalMemorySize,
328 0, 0,
329 /* 0xb7 */
330 NdrRangeMemorySize
332 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
334 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
335 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
336 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
337 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
338 /* 0x10 */
339 NdrBaseTypeFree,
340 /* 0x11 */
341 NdrPointerFree, NdrPointerFree,
342 NdrPointerFree, NdrPointerFree,
343 /* 0x15 */
344 NdrSimpleStructFree, NdrSimpleStructFree,
345 NdrConformantStructFree, NdrConformantStructFree,
346 NdrConformantVaryingStructFree,
347 NdrComplexStructFree,
348 /* 0x1b */
349 NdrConformantArrayFree,
350 NdrConformantVaryingArrayFree,
351 NdrFixedArrayFree, NdrFixedArrayFree,
352 NdrVaryingArrayFree, NdrVaryingArrayFree,
353 NdrComplexArrayFree,
354 /* 0x22 */
355 0, 0, 0,
356 0, 0, 0, 0, 0,
357 /* 0x2a */
358 NdrEncapsulatedUnionFree,
359 NdrNonEncapsulatedUnionFree,
361 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
362 /* 0x2f */
363 NdrInterfacePointerFree,
364 /* 0x30 */
366 /* 0xb1 */
367 0, 0, 0,
368 NdrUserMarshalFree,
369 0, 0,
370 /* 0xb7 */
371 NdrRangeFree
374 typedef struct _NDR_MEMORY_LIST
376 ULONG magic;
377 ULONG size;
378 ULONG reserved;
379 struct _NDR_MEMORY_LIST *next;
380 } NDR_MEMORY_LIST;
382 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
384 /***********************************************************************
385 * NdrAllocate [RPCRT4.@]
387 * Allocates a block of memory using pStubMsg->pfnAllocate.
389 * PARAMS
390 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
391 * len [I] Size of memory block to allocate.
393 * RETURNS
394 * The memory block of size len that was allocated.
396 * NOTES
397 * The memory block is always 8-byte aligned.
398 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
399 * exception is raised.
401 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, SIZE_T len)
403 SIZE_T aligned_len;
404 SIZE_T adjusted_len;
405 void *p;
406 NDR_MEMORY_LIST *mem_list;
408 aligned_len = (len + 7) & ~7;
409 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
410 /* check for overflow */
411 if (adjusted_len < len)
413 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len, len);
414 RpcRaiseException(RPC_X_BAD_STUB_DATA);
417 p = pStubMsg->pfnAllocate(adjusted_len);
418 if (!p) RpcRaiseException(ERROR_OUTOFMEMORY);
420 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
421 mem_list->magic = MEML_MAGIC;
422 mem_list->size = aligned_len;
423 mem_list->reserved = 0;
424 mem_list->next = pStubMsg->pMemoryList;
425 pStubMsg->pMemoryList = mem_list;
427 TRACE("-- %p\n", p);
428 return p;
431 static void NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
433 TRACE("(%p, %p)\n", pStubMsg, Pointer);
435 pStubMsg->pfnFree(Pointer);
438 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
440 return (*(const ULONG *)pFormat != -1);
443 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
445 align_pointer(&pStubMsg->Buffer, 4);
446 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
447 RpcRaiseException(RPC_X_BAD_STUB_DATA);
448 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
449 pStubMsg->Buffer += 4;
450 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
451 if (pStubMsg->fHasNewCorrDesc)
452 return pFormat+6;
453 else
454 return pFormat+4;
457 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
459 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
461 pStubMsg->Offset = 0;
462 pStubMsg->ActualCount = pStubMsg->MaxCount;
463 goto done;
466 align_pointer(&pStubMsg->Buffer, 4);
467 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
468 RpcRaiseException(RPC_X_BAD_STUB_DATA);
469 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
470 pStubMsg->Buffer += 4;
471 TRACE("offset is %d\n", pStubMsg->Offset);
472 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
473 pStubMsg->Buffer += 4;
474 TRACE("variance is %d\n", pStubMsg->ActualCount);
476 if ((pStubMsg->ActualCount > MaxValue) ||
477 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
479 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
480 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
481 RpcRaiseException(RPC_S_INVALID_BOUND);
482 return NULL;
485 done:
486 if (pStubMsg->fHasNewCorrDesc)
487 return pFormat+6;
488 else
489 return pFormat+4;
492 /* writes the conformance value to the buffer */
493 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
495 align_pointer_clear(&pStubMsg->Buffer, 4);
496 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
497 RpcRaiseException(RPC_X_BAD_STUB_DATA);
498 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
499 pStubMsg->Buffer += 4;
502 /* writes the variance values to the buffer */
503 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
505 align_pointer_clear(&pStubMsg->Buffer, 4);
506 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
507 RpcRaiseException(RPC_X_BAD_STUB_DATA);
508 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
509 pStubMsg->Buffer += 4;
510 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
511 pStubMsg->Buffer += 4;
514 /* requests buffer space for the conformance value */
515 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
517 align_length(&pStubMsg->BufferLength, 4);
518 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
519 RpcRaiseException(RPC_X_BAD_STUB_DATA);
520 pStubMsg->BufferLength += 4;
523 /* requests buffer space for the variance values */
524 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
526 align_length(&pStubMsg->BufferLength, 4);
527 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
528 RpcRaiseException(RPC_X_BAD_STUB_DATA);
529 pStubMsg->BufferLength += 8;
532 PFORMAT_STRING ComputeConformanceOrVariance(
533 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
534 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
536 BYTE dtype = pFormat[0] & 0xf;
537 short ofs = *(const short *)&pFormat[2];
538 LPVOID ptr = NULL;
539 ULONG_PTR data = 0;
541 if (!IsConformanceOrVariancePresent(pFormat)) {
542 /* null descriptor */
543 *pCount = def;
544 goto finish_conf;
547 switch (pFormat[0] & 0xf0) {
548 case RPC_FC_NORMAL_CONFORMANCE:
549 TRACE("normal conformance, ofs=%d\n", ofs);
550 ptr = pMemory;
551 break;
552 case RPC_FC_POINTER_CONFORMANCE:
553 TRACE("pointer conformance, ofs=%d\n", ofs);
554 ptr = pStubMsg->Memory;
555 break;
556 case RPC_FC_TOP_LEVEL_CONFORMANCE:
557 TRACE("toplevel conformance, ofs=%d\n", ofs);
558 if (pStubMsg->StackTop) {
559 ptr = pStubMsg->StackTop;
561 else {
562 /* -Os mode, *pCount is already set */
563 goto finish_conf;
565 break;
566 case RPC_FC_CONSTANT_CONFORMANCE:
567 data = ofs | ((DWORD)pFormat[1] << 16);
568 TRACE("constant conformance, val=%ld\n", data);
569 *pCount = data;
570 goto finish_conf;
571 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
572 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
573 if (pStubMsg->StackTop) {
574 ptr = pStubMsg->StackTop;
576 else {
577 /* ? */
578 goto done_conf_grab;
580 break;
581 default:
582 FIXME("unknown conformance type %x, expect crash.\n", pFormat[0] & 0xf0);
583 goto finish_conf;
586 switch (pFormat[1]) {
587 case RPC_FC_DEREFERENCE:
588 ptr = *(LPVOID*)((char *)ptr + ofs);
589 break;
590 case RPC_FC_CALLBACK:
592 unsigned char *old_stack_top = pStubMsg->StackTop;
593 ULONG_PTR max_count, old_max_count = pStubMsg->MaxCount;
595 pStubMsg->StackTop = ptr;
597 /* ofs is index into StubDesc->apfnExprEval */
598 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
599 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
601 pStubMsg->StackTop = old_stack_top;
603 /* the callback function always stores the computed value in MaxCount */
604 max_count = pStubMsg->MaxCount;
605 pStubMsg->MaxCount = old_max_count;
606 *pCount = max_count;
607 goto finish_conf;
609 default:
610 ptr = (char *)ptr + ofs;
611 break;
614 switch (dtype) {
615 case RPC_FC_LONG:
616 case RPC_FC_ULONG:
617 data = *(DWORD*)ptr;
618 break;
619 case RPC_FC_SHORT:
620 data = *(SHORT*)ptr;
621 break;
622 case RPC_FC_USHORT:
623 data = *(USHORT*)ptr;
624 break;
625 case RPC_FC_CHAR:
626 case RPC_FC_SMALL:
627 data = *(CHAR*)ptr;
628 break;
629 case RPC_FC_BYTE:
630 case RPC_FC_USMALL:
631 data = *(UCHAR*)ptr;
632 break;
633 case RPC_FC_HYPER:
634 data = *(ULONGLONG *)ptr;
635 break;
636 default:
637 FIXME("unknown conformance data type %x\n", dtype);
638 goto done_conf_grab;
640 TRACE("dereferenced data type %x at %p, got %ld\n", dtype, ptr, data);
642 done_conf_grab:
643 switch (pFormat[1]) {
644 case RPC_FC_DEREFERENCE: /* already handled */
645 case 0: /* no op */
646 *pCount = data;
647 break;
648 case RPC_FC_ADD_1:
649 *pCount = data + 1;
650 break;
651 case RPC_FC_SUB_1:
652 *pCount = data - 1;
653 break;
654 case RPC_FC_MULT_2:
655 *pCount = data * 2;
656 break;
657 case RPC_FC_DIV_2:
658 *pCount = data / 2;
659 break;
660 default:
661 FIXME("unknown conformance op %d\n", pFormat[1]);
662 goto finish_conf;
665 finish_conf:
666 TRACE("resulting conformance is %ld\n", *pCount);
667 if (pStubMsg->fHasNewCorrDesc)
668 return pFormat+6;
669 else
670 return pFormat+4;
673 static inline PFORMAT_STRING SkipConformance(PMIDL_STUB_MESSAGE pStubMsg,
674 PFORMAT_STRING pFormat)
676 if (pStubMsg->fHasNewCorrDesc)
677 pFormat += 6;
678 else
679 pFormat += 4;
680 return pFormat;
683 static inline PFORMAT_STRING SkipVariance(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
685 return SkipConformance( pStubMsg, pFormat );
688 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
689 * the result overflows 32-bits */
690 static inline ULONG safe_multiply(ULONG a, ULONG b)
692 ULONGLONG ret = (ULONGLONG)a * b;
693 if (ret > 0xffffffff)
695 RpcRaiseException(RPC_S_INVALID_BOUND);
696 return 0;
698 return ret;
701 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
703 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
704 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
705 RpcRaiseException(RPC_X_BAD_STUB_DATA);
706 pStubMsg->Buffer += size;
709 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
711 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
713 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
714 pStubMsg->BufferLength, size);
715 RpcRaiseException(RPC_X_BAD_STUB_DATA);
717 pStubMsg->BufferLength += size;
720 /* copies data from the buffer, checking that there is enough data in the buffer
721 * to do so */
722 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
724 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
725 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
727 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
728 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
729 RpcRaiseException(RPC_X_BAD_STUB_DATA);
731 if (p == pStubMsg->Buffer)
732 ERR("pointer is the same as the buffer\n");
733 memcpy(p, pStubMsg->Buffer, size);
734 pStubMsg->Buffer += size;
737 /* copies data to the buffer, checking that there is enough space to do so */
738 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
740 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
741 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
743 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
744 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
745 size);
746 RpcRaiseException(RPC_X_BAD_STUB_DATA);
748 memcpy(pStubMsg->Buffer, p, size);
749 pStubMsg->Buffer += size;
752 /* verify that string data sitting in the buffer is valid and safe to
753 * unmarshall */
754 static void validate_string_data(MIDL_STUB_MESSAGE *pStubMsg, ULONG bufsize, ULONG esize)
756 ULONG i;
758 /* verify the buffer is safe to access */
759 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
760 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
762 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
763 pStubMsg->BufferEnd, pStubMsg->Buffer);
764 RpcRaiseException(RPC_X_BAD_STUB_DATA);
767 /* strings must always have null terminating bytes */
768 if (bufsize < esize)
770 ERR("invalid string length of %d\n", bufsize / esize);
771 RpcRaiseException(RPC_S_INVALID_BOUND);
774 for (i = bufsize - esize; i < bufsize; i++)
775 if (pStubMsg->Buffer[i] != 0)
777 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
778 i, pStubMsg->Buffer[i]);
779 RpcRaiseException(RPC_S_INVALID_BOUND);
783 static inline void dump_pointer_attr(unsigned char attr)
785 if (attr & RPC_FC_P_ALLOCALLNODES)
786 TRACE(" RPC_FC_P_ALLOCALLNODES");
787 if (attr & RPC_FC_P_DONTFREE)
788 TRACE(" RPC_FC_P_DONTFREE");
789 if (attr & RPC_FC_P_ONSTACK)
790 TRACE(" RPC_FC_P_ONSTACK");
791 if (attr & RPC_FC_P_SIMPLEPOINTER)
792 TRACE(" RPC_FC_P_SIMPLEPOINTER");
793 if (attr & RPC_FC_P_DEREF)
794 TRACE(" RPC_FC_P_DEREF");
795 TRACE("\n");
798 /***********************************************************************
799 * PointerMarshall [internal]
801 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
802 unsigned char *Buffer,
803 unsigned char *Pointer,
804 PFORMAT_STRING pFormat)
806 unsigned type = pFormat[0], attr = pFormat[1];
807 PFORMAT_STRING desc;
808 NDR_MARSHALL m;
809 ULONG pointer_id;
810 int pointer_needs_marshaling;
812 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
813 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
814 pFormat += 2;
815 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
816 else desc = pFormat + *(const SHORT*)pFormat;
818 switch (type) {
819 case RPC_FC_RP: /* ref pointer (always non-null) */
820 if (!Pointer)
822 ERR("NULL ref pointer is not allowed\n");
823 RpcRaiseException(RPC_X_NULL_REF_POINTER);
825 pointer_needs_marshaling = 1;
826 break;
827 case RPC_FC_UP: /* unique pointer */
828 case RPC_FC_OP: /* object pointer - same as unique here */
829 if (Pointer)
830 pointer_needs_marshaling = 1;
831 else
832 pointer_needs_marshaling = 0;
833 pointer_id = Pointer ? NDR_POINTER_ID(pStubMsg) : 0;
834 TRACE("writing 0x%08x to buffer\n", pointer_id);
835 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
836 break;
837 case RPC_FC_FP:
838 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
839 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
840 TRACE("writing 0x%08x to buffer\n", pointer_id);
841 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
842 break;
843 default:
844 FIXME("unhandled ptr type=%02x\n", type);
845 RpcRaiseException(RPC_X_BAD_STUB_DATA);
846 return;
849 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
851 if (pointer_needs_marshaling) {
852 if (attr & RPC_FC_P_DEREF) {
853 Pointer = *(unsigned char**)Pointer;
854 TRACE("deref => %p\n", Pointer);
856 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
857 if (m) m(pStubMsg, Pointer, desc);
858 else FIXME("no marshaller for data type=%02x\n", *desc);
861 STD_OVERFLOW_CHECK(pStubMsg);
864 /***********************************************************************
865 * PointerUnmarshall [internal]
867 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
868 unsigned char *Buffer,
869 unsigned char **pPointer,
870 unsigned char *pSrcPointer,
871 PFORMAT_STRING pFormat,
872 unsigned char fMustAlloc)
874 unsigned type = pFormat[0], attr = pFormat[1];
875 PFORMAT_STRING desc;
876 NDR_UNMARSHALL m;
877 DWORD pointer_id = 0;
878 int pointer_needs_unmarshaling;
880 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
881 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
882 pFormat += 2;
883 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
884 else desc = pFormat + *(const SHORT*)pFormat;
886 switch (type) {
887 case RPC_FC_RP: /* ref pointer (always non-null) */
888 pointer_needs_unmarshaling = 1;
889 break;
890 case RPC_FC_UP: /* unique pointer */
891 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
892 TRACE("pointer_id is 0x%08x\n", pointer_id);
893 if (pointer_id)
894 pointer_needs_unmarshaling = 1;
895 else {
896 *pPointer = NULL;
897 pointer_needs_unmarshaling = 0;
899 break;
900 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
901 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
902 TRACE("pointer_id is 0x%08x\n", pointer_id);
903 if (!fMustAlloc && pSrcPointer)
905 FIXME("free object pointer %p\n", pSrcPointer);
906 fMustAlloc = TRUE;
908 if (pointer_id)
909 pointer_needs_unmarshaling = 1;
910 else
912 *pPointer = NULL;
913 pointer_needs_unmarshaling = 0;
915 break;
916 case RPC_FC_FP:
917 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
918 TRACE("pointer_id is 0x%08x\n", pointer_id);
919 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
920 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
921 break;
922 default:
923 FIXME("unhandled ptr type=%02x\n", type);
924 RpcRaiseException(RPC_X_BAD_STUB_DATA);
925 return;
928 if (pointer_needs_unmarshaling) {
929 unsigned char **current_ptr = pPointer;
930 if (pStubMsg->IsClient) {
931 TRACE("client\n");
932 /* if we aren't forcing allocation of memory then try to use the existing
933 * (source) pointer to unmarshall the data into so that [in,out]
934 * parameters behave correctly. it doesn't matter if the parameter is
935 * [out] only since in that case the pointer will be NULL. we force
936 * allocation when the source pointer is NULL here instead of in the type
937 * unmarshalling routine for the benefit of the deref code below */
938 if (!fMustAlloc) {
939 if (pSrcPointer) {
940 TRACE("setting *pPointer to %p\n", pSrcPointer);
941 *pPointer = pSrcPointer;
942 } else
943 fMustAlloc = TRUE;
945 } else {
946 TRACE("server\n");
947 /* the memory in a stub is never initialised, so we have to work out here
948 * whether we have to initialise it so we can use the optimisation of
949 * setting the pointer to the buffer, if possible, or set fMustAlloc to
950 * TRUE. */
951 if (attr & RPC_FC_P_DEREF) {
952 fMustAlloc = TRUE;
953 } else {
954 *current_ptr = NULL;
958 if (attr & RPC_FC_P_ALLOCALLNODES)
959 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
961 if (attr & RPC_FC_P_DEREF) {
962 if (fMustAlloc) {
963 unsigned char *base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
964 *pPointer = base_ptr_val;
965 current_ptr = (unsigned char **)base_ptr_val;
966 } else
967 current_ptr = *(unsigned char***)current_ptr;
968 TRACE("deref => %p\n", current_ptr);
969 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
971 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
972 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
973 else FIXME("no unmarshaller for data type=%02x\n", *desc);
975 if (type == RPC_FC_FP)
976 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
977 *pPointer);
980 TRACE("pointer=%p\n", *pPointer);
983 /***********************************************************************
984 * PointerBufferSize [internal]
986 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
987 unsigned char *Pointer,
988 PFORMAT_STRING pFormat)
990 unsigned type = pFormat[0], attr = pFormat[1];
991 PFORMAT_STRING desc;
992 NDR_BUFFERSIZE m;
993 int pointer_needs_sizing;
994 ULONG pointer_id;
996 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
997 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
998 pFormat += 2;
999 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1000 else desc = pFormat + *(const SHORT*)pFormat;
1002 switch (type) {
1003 case RPC_FC_RP: /* ref pointer (always non-null) */
1004 if (!Pointer)
1006 ERR("NULL ref pointer is not allowed\n");
1007 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1009 break;
1010 case RPC_FC_OP:
1011 case RPC_FC_UP:
1012 /* NULL pointer has no further representation */
1013 if (!Pointer)
1014 return;
1015 break;
1016 case RPC_FC_FP:
1017 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1018 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1019 if (!pointer_needs_sizing)
1020 return;
1021 break;
1022 default:
1023 FIXME("unhandled ptr type=%02x\n", type);
1024 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1025 return;
1028 if (attr & RPC_FC_P_DEREF) {
1029 Pointer = *(unsigned char**)Pointer;
1030 TRACE("deref => %p\n", Pointer);
1033 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1034 if (m) m(pStubMsg, Pointer, desc);
1035 else FIXME("no buffersizer for data type=%02x\n", *desc);
1038 /***********************************************************************
1039 * PointerMemorySize [internal]
1041 static ULONG PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1042 unsigned char *Buffer, PFORMAT_STRING pFormat)
1044 unsigned type = pFormat[0], attr = pFormat[1];
1045 PFORMAT_STRING desc;
1046 NDR_MEMORYSIZE m;
1047 DWORD pointer_id = 0;
1048 int pointer_needs_sizing;
1050 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1051 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1052 pFormat += 2;
1053 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1054 else desc = pFormat + *(const SHORT*)pFormat;
1056 switch (type) {
1057 case RPC_FC_RP: /* ref pointer (always non-null) */
1058 pointer_needs_sizing = 1;
1059 break;
1060 case RPC_FC_UP: /* unique pointer */
1061 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1062 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1063 TRACE("pointer_id is 0x%08x\n", pointer_id);
1064 if (pointer_id)
1065 pointer_needs_sizing = 1;
1066 else
1067 pointer_needs_sizing = 0;
1068 break;
1069 case RPC_FC_FP:
1071 void *pointer;
1072 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1073 TRACE("pointer_id is 0x%08x\n", pointer_id);
1074 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1075 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1076 break;
1078 default:
1079 FIXME("unhandled ptr type=%02x\n", type);
1080 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1081 return 0;
1084 if (attr & RPC_FC_P_DEREF) {
1085 align_length(&pStubMsg->MemorySize, sizeof(void*));
1086 pStubMsg->MemorySize += sizeof(void*);
1087 TRACE("deref\n");
1090 if (pointer_needs_sizing) {
1091 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1092 if (m) m(pStubMsg, desc);
1093 else FIXME("no memorysizer for data type=%02x\n", *desc);
1096 return pStubMsg->MemorySize;
1099 /***********************************************************************
1100 * PointerFree [internal]
1102 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1103 unsigned char *Pointer,
1104 PFORMAT_STRING pFormat)
1106 unsigned type = pFormat[0], attr = pFormat[1];
1107 PFORMAT_STRING desc;
1108 NDR_FREE m;
1109 unsigned char *current_pointer = Pointer;
1111 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1112 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1113 if (attr & RPC_FC_P_DONTFREE) return;
1114 pFormat += 2;
1115 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1116 else desc = pFormat + *(const SHORT*)pFormat;
1118 if (!Pointer) return;
1120 if (type == RPC_FC_FP) {
1121 int pointer_needs_freeing = NdrFullPointerFree(
1122 pStubMsg->FullPtrXlatTables, Pointer);
1123 if (!pointer_needs_freeing)
1124 return;
1127 if (attr & RPC_FC_P_DEREF) {
1128 current_pointer = *(unsigned char**)Pointer;
1129 TRACE("deref => %p\n", current_pointer);
1132 m = NdrFreer[*desc & NDR_TABLE_MASK];
1133 if (m) m(pStubMsg, current_pointer, desc);
1135 /* this check stops us from trying to free buffer memory. we don't have to
1136 * worry about clients, since they won't call this function.
1137 * we don't have to check for the buffer being reallocated because
1138 * BufferStart and BufferEnd won't be reset when allocating memory for
1139 * sending the response. we don't have to check for the new buffer here as
1140 * it won't be used a type memory, only for buffer memory */
1141 if (Pointer >= pStubMsg->BufferStart && Pointer < pStubMsg->BufferEnd)
1142 goto notfree;
1144 if (attr & RPC_FC_P_ONSTACK) {
1145 TRACE("not freeing stack ptr %p\n", Pointer);
1146 return;
1148 TRACE("freeing %p\n", Pointer);
1149 NdrFree(pStubMsg, Pointer);
1150 return;
1151 notfree:
1152 TRACE("not freeing %p\n", Pointer);
1155 /***********************************************************************
1156 * EmbeddedPointerMarshall
1158 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1159 unsigned char *pMemory,
1160 PFORMAT_STRING pFormat)
1162 unsigned char *Mark = pStubMsg->BufferMark;
1163 unsigned rep, count, stride;
1164 unsigned i;
1165 unsigned char *saved_buffer = NULL;
1167 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1169 if (*pFormat != RPC_FC_PP) return NULL;
1170 pFormat += 2;
1172 if (pStubMsg->PointerBufferMark)
1174 saved_buffer = pStubMsg->Buffer;
1175 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1176 pStubMsg->PointerBufferMark = NULL;
1179 while (pFormat[0] != RPC_FC_END) {
1180 switch (pFormat[0]) {
1181 default:
1182 FIXME("unknown repeat type %d\n", pFormat[0]);
1183 case RPC_FC_NO_REPEAT:
1184 rep = 1;
1185 stride = 0;
1186 count = 1;
1187 pFormat += 2;
1188 break;
1189 case RPC_FC_FIXED_REPEAT:
1190 rep = *(const WORD*)&pFormat[2];
1191 stride = *(const WORD*)&pFormat[4];
1192 count = *(const WORD*)&pFormat[8];
1193 pFormat += 10;
1194 break;
1195 case RPC_FC_VARIABLE_REPEAT:
1196 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1197 stride = *(const WORD*)&pFormat[2];
1198 count = *(const WORD*)&pFormat[6];
1199 pFormat += 8;
1200 break;
1202 for (i = 0; i < rep; i++) {
1203 PFORMAT_STRING info = pFormat;
1204 unsigned char *membase = pMemory + (i * stride);
1205 unsigned char *bufbase = Mark + (i * stride);
1206 unsigned u;
1208 for (u=0; u<count; u++,info+=8) {
1209 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1210 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1211 unsigned char *saved_memory = pStubMsg->Memory;
1213 pStubMsg->Memory = pMemory;
1214 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1215 pStubMsg->Memory = saved_memory;
1218 pFormat += 8 * count;
1221 if (saved_buffer)
1223 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1224 pStubMsg->Buffer = saved_buffer;
1227 STD_OVERFLOW_CHECK(pStubMsg);
1229 return NULL;
1232 /***********************************************************************
1233 * EmbeddedPointerUnmarshall
1235 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1236 unsigned char *pDstBuffer,
1237 unsigned char *pSrcMemoryPtrs,
1238 PFORMAT_STRING pFormat,
1239 unsigned char fMustAlloc)
1241 unsigned char *Mark = pStubMsg->BufferMark;
1242 unsigned rep, count, stride;
1243 unsigned i;
1244 unsigned char *saved_buffer = NULL;
1246 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc);
1248 if (*pFormat != RPC_FC_PP) return NULL;
1249 pFormat += 2;
1251 if (pStubMsg->PointerBufferMark)
1253 saved_buffer = pStubMsg->Buffer;
1254 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1255 pStubMsg->PointerBufferMark = NULL;
1258 while (pFormat[0] != RPC_FC_END) {
1259 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1260 switch (pFormat[0]) {
1261 default:
1262 FIXME("unknown repeat type %d\n", pFormat[0]);
1263 case RPC_FC_NO_REPEAT:
1264 rep = 1;
1265 stride = 0;
1266 count = 1;
1267 pFormat += 2;
1268 break;
1269 case RPC_FC_FIXED_REPEAT:
1270 rep = *(const WORD*)&pFormat[2];
1271 stride = *(const WORD*)&pFormat[4];
1272 count = *(const WORD*)&pFormat[8];
1273 pFormat += 10;
1274 break;
1275 case RPC_FC_VARIABLE_REPEAT:
1276 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1277 stride = *(const WORD*)&pFormat[2];
1278 count = *(const WORD*)&pFormat[6];
1279 pFormat += 8;
1280 break;
1282 for (i = 0; i < rep; i++) {
1283 PFORMAT_STRING info = pFormat;
1284 unsigned char *bufdstbase = pDstBuffer + (i * stride);
1285 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1286 unsigned char *bufbase = Mark + (i * stride);
1287 unsigned u;
1289 for (u=0; u<count; u++,info+=8) {
1290 unsigned char **bufdstptr = (unsigned char **)(bufdstbase + *(const SHORT*)&info[2]);
1291 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1292 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1293 PointerUnmarshall(pStubMsg, bufptr, bufdstptr, *memsrcptr, info+4, fMustAlloc);
1296 pFormat += 8 * count;
1299 if (saved_buffer)
1301 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1302 pStubMsg->Buffer = saved_buffer;
1305 return NULL;
1308 /***********************************************************************
1309 * EmbeddedPointerBufferSize
1311 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1312 unsigned char *pMemory,
1313 PFORMAT_STRING pFormat)
1315 unsigned rep, count, stride;
1316 unsigned i;
1317 ULONG saved_buffer_length = 0;
1319 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1321 if (pStubMsg->IgnoreEmbeddedPointers) return;
1323 if (*pFormat != RPC_FC_PP) return;
1324 pFormat += 2;
1326 if (pStubMsg->PointerLength)
1328 saved_buffer_length = pStubMsg->BufferLength;
1329 pStubMsg->BufferLength = pStubMsg->PointerLength;
1330 pStubMsg->PointerLength = 0;
1333 while (pFormat[0] != RPC_FC_END) {
1334 switch (pFormat[0]) {
1335 default:
1336 FIXME("unknown repeat type %d\n", pFormat[0]);
1337 case RPC_FC_NO_REPEAT:
1338 rep = 1;
1339 stride = 0;
1340 count = 1;
1341 pFormat += 2;
1342 break;
1343 case RPC_FC_FIXED_REPEAT:
1344 rep = *(const WORD*)&pFormat[2];
1345 stride = *(const WORD*)&pFormat[4];
1346 count = *(const WORD*)&pFormat[8];
1347 pFormat += 10;
1348 break;
1349 case RPC_FC_VARIABLE_REPEAT:
1350 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1351 stride = *(const WORD*)&pFormat[2];
1352 count = *(const WORD*)&pFormat[6];
1353 pFormat += 8;
1354 break;
1356 for (i = 0; i < rep; i++) {
1357 PFORMAT_STRING info = pFormat;
1358 unsigned char *membase = pMemory + (i * stride);
1359 unsigned u;
1361 for (u=0; u<count; u++,info+=8) {
1362 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1363 unsigned char *saved_memory = pStubMsg->Memory;
1365 pStubMsg->Memory = pMemory;
1366 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1367 pStubMsg->Memory = saved_memory;
1370 pFormat += 8 * count;
1373 if (saved_buffer_length)
1375 pStubMsg->PointerLength = pStubMsg->BufferLength;
1376 pStubMsg->BufferLength = saved_buffer_length;
1380 /***********************************************************************
1381 * EmbeddedPointerMemorySize [internal]
1383 static ULONG EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1384 PFORMAT_STRING pFormat)
1386 unsigned char *Mark = pStubMsg->BufferMark;
1387 unsigned rep, count, stride;
1388 unsigned i;
1389 unsigned char *saved_buffer = NULL;
1391 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1393 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1395 if (pStubMsg->PointerBufferMark)
1397 saved_buffer = pStubMsg->Buffer;
1398 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1399 pStubMsg->PointerBufferMark = NULL;
1402 if (*pFormat != RPC_FC_PP) return 0;
1403 pFormat += 2;
1405 while (pFormat[0] != RPC_FC_END) {
1406 switch (pFormat[0]) {
1407 default:
1408 FIXME("unknown repeat type %d\n", pFormat[0]);
1409 case RPC_FC_NO_REPEAT:
1410 rep = 1;
1411 stride = 0;
1412 count = 1;
1413 pFormat += 2;
1414 break;
1415 case RPC_FC_FIXED_REPEAT:
1416 rep = *(const WORD*)&pFormat[2];
1417 stride = *(const WORD*)&pFormat[4];
1418 count = *(const WORD*)&pFormat[8];
1419 pFormat += 10;
1420 break;
1421 case RPC_FC_VARIABLE_REPEAT:
1422 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1423 stride = *(const WORD*)&pFormat[2];
1424 count = *(const WORD*)&pFormat[6];
1425 pFormat += 8;
1426 break;
1428 for (i = 0; i < rep; i++) {
1429 PFORMAT_STRING info = pFormat;
1430 unsigned char *bufbase = Mark + (i * stride);
1431 unsigned u;
1432 for (u=0; u<count; u++,info+=8) {
1433 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1434 PointerMemorySize(pStubMsg, bufptr, info+4);
1437 pFormat += 8 * count;
1440 if (saved_buffer)
1442 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1443 pStubMsg->Buffer = saved_buffer;
1446 return 0;
1449 /***********************************************************************
1450 * EmbeddedPointerFree [internal]
1452 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1453 unsigned char *pMemory,
1454 PFORMAT_STRING pFormat)
1456 unsigned rep, count, stride;
1457 unsigned i;
1459 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1460 if (*pFormat != RPC_FC_PP) return;
1461 pFormat += 2;
1463 while (pFormat[0] != RPC_FC_END) {
1464 switch (pFormat[0]) {
1465 default:
1466 FIXME("unknown repeat type %d\n", pFormat[0]);
1467 case RPC_FC_NO_REPEAT:
1468 rep = 1;
1469 stride = 0;
1470 count = 1;
1471 pFormat += 2;
1472 break;
1473 case RPC_FC_FIXED_REPEAT:
1474 rep = *(const WORD*)&pFormat[2];
1475 stride = *(const WORD*)&pFormat[4];
1476 count = *(const WORD*)&pFormat[8];
1477 pFormat += 10;
1478 break;
1479 case RPC_FC_VARIABLE_REPEAT:
1480 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1481 stride = *(const WORD*)&pFormat[2];
1482 count = *(const WORD*)&pFormat[6];
1483 pFormat += 8;
1484 break;
1486 for (i = 0; i < rep; i++) {
1487 PFORMAT_STRING info = pFormat;
1488 unsigned char *membase = pMemory + (i * stride);
1489 unsigned u;
1491 for (u=0; u<count; u++,info+=8) {
1492 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1493 unsigned char *saved_memory = pStubMsg->Memory;
1495 pStubMsg->Memory = pMemory;
1496 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1497 pStubMsg->Memory = saved_memory;
1500 pFormat += 8 * count;
1504 /***********************************************************************
1505 * NdrPointerMarshall [RPCRT4.@]
1507 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1508 unsigned char *pMemory,
1509 PFORMAT_STRING pFormat)
1511 unsigned char *Buffer;
1513 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1515 /* Increment the buffer here instead of in PointerMarshall,
1516 * as that is used by embedded pointers which already handle the incrementing
1517 * the buffer, and shouldn't write any additional pointer data to the wire */
1518 if (*pFormat != RPC_FC_RP)
1520 align_pointer_clear(&pStubMsg->Buffer, 4);
1521 Buffer = pStubMsg->Buffer;
1522 safe_buffer_increment(pStubMsg, 4);
1524 else
1525 Buffer = pStubMsg->Buffer;
1527 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1529 return NULL;
1532 /***********************************************************************
1533 * NdrPointerUnmarshall [RPCRT4.@]
1535 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1536 unsigned char **ppMemory,
1537 PFORMAT_STRING pFormat,
1538 unsigned char fMustAlloc)
1540 unsigned char *Buffer;
1542 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1544 if (*pFormat == RPC_FC_RP)
1546 Buffer = pStubMsg->Buffer;
1547 /* Do the NULL ref pointer check here because embedded pointers can be
1548 * NULL if the type the pointer is embedded in was allocated rather than
1549 * being passed in by the client */
1550 if (pStubMsg->IsClient && !*ppMemory)
1552 ERR("NULL ref pointer is not allowed\n");
1553 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1556 else
1558 /* Increment the buffer here instead of in PointerUnmarshall,
1559 * as that is used by embedded pointers which already handle the incrementing
1560 * the buffer, and shouldn't read any additional pointer data from the
1561 * buffer */
1562 align_pointer(&pStubMsg->Buffer, 4);
1563 Buffer = pStubMsg->Buffer;
1564 safe_buffer_increment(pStubMsg, 4);
1567 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1569 return NULL;
1572 /***********************************************************************
1573 * NdrPointerBufferSize [RPCRT4.@]
1575 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1576 unsigned char *pMemory,
1577 PFORMAT_STRING pFormat)
1579 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1581 /* Increment the buffer length here instead of in PointerBufferSize,
1582 * as that is used by embedded pointers which already handle the buffer
1583 * length, and shouldn't write anything more to the wire */
1584 if (*pFormat != RPC_FC_RP)
1586 align_length(&pStubMsg->BufferLength, 4);
1587 safe_buffer_length_increment(pStubMsg, 4);
1590 PointerBufferSize(pStubMsg, pMemory, pFormat);
1593 /***********************************************************************
1594 * NdrPointerMemorySize [RPCRT4.@]
1596 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1597 PFORMAT_STRING pFormat)
1599 unsigned char *Buffer = pStubMsg->Buffer;
1600 if (*pFormat != RPC_FC_RP)
1602 align_pointer(&pStubMsg->Buffer, 4);
1603 safe_buffer_increment(pStubMsg, 4);
1605 align_length(&pStubMsg->MemorySize, sizeof(void *));
1606 return PointerMemorySize(pStubMsg, Buffer, pFormat);
1609 /***********************************************************************
1610 * NdrPointerFree [RPCRT4.@]
1612 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1613 unsigned char *pMemory,
1614 PFORMAT_STRING pFormat)
1616 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1617 PointerFree(pStubMsg, pMemory, pFormat);
1620 /***********************************************************************
1621 * NdrSimpleTypeMarshall [RPCRT4.@]
1623 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1624 unsigned char FormatChar )
1626 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1629 /***********************************************************************
1630 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1632 * Unmarshall a base type.
1634 * NOTES
1635 * Doesn't check that the buffer is long enough before copying, so the caller
1636 * should do this.
1638 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1639 unsigned char FormatChar )
1641 #define BASE_TYPE_UNMARSHALL(type) \
1642 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
1643 TRACE("pMemory: %p\n", pMemory); \
1644 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1645 pStubMsg->Buffer += sizeof(type);
1647 switch(FormatChar)
1649 case RPC_FC_BYTE:
1650 case RPC_FC_CHAR:
1651 case RPC_FC_SMALL:
1652 case RPC_FC_USMALL:
1653 BASE_TYPE_UNMARSHALL(UCHAR);
1654 TRACE("value: 0x%02x\n", *pMemory);
1655 break;
1656 case RPC_FC_WCHAR:
1657 case RPC_FC_SHORT:
1658 case RPC_FC_USHORT:
1659 BASE_TYPE_UNMARSHALL(USHORT);
1660 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
1661 break;
1662 case RPC_FC_LONG:
1663 case RPC_FC_ULONG:
1664 case RPC_FC_ERROR_STATUS_T:
1665 case RPC_FC_ENUM32:
1666 BASE_TYPE_UNMARSHALL(ULONG);
1667 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
1668 break;
1669 case RPC_FC_FLOAT:
1670 BASE_TYPE_UNMARSHALL(float);
1671 TRACE("value: %f\n", *(float *)pMemory);
1672 break;
1673 case RPC_FC_DOUBLE:
1674 BASE_TYPE_UNMARSHALL(double);
1675 TRACE("value: %f\n", *(double *)pMemory);
1676 break;
1677 case RPC_FC_HYPER:
1678 BASE_TYPE_UNMARSHALL(ULONGLONG);
1679 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
1680 break;
1681 case RPC_FC_ENUM16:
1682 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
1683 TRACE("pMemory: %p\n", pMemory);
1684 /* 16-bits on the wire, but int in memory */
1685 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
1686 pStubMsg->Buffer += sizeof(USHORT);
1687 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
1688 break;
1689 case RPC_FC_INT3264:
1690 align_pointer(&pStubMsg->Buffer, sizeof(INT));
1691 /* 32-bits on the wire, but int_ptr in memory */
1692 *(INT_PTR *)pMemory = *(INT *)pStubMsg->Buffer;
1693 pStubMsg->Buffer += sizeof(INT);
1694 TRACE("value: 0x%08lx\n", *(INT_PTR *)pMemory);
1695 break;
1696 case RPC_FC_UINT3264:
1697 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
1698 /* 32-bits on the wire, but int_ptr in memory */
1699 *(UINT_PTR *)pMemory = *(UINT *)pStubMsg->Buffer;
1700 pStubMsg->Buffer += sizeof(UINT);
1701 TRACE("value: 0x%08lx\n", *(UINT_PTR *)pMemory);
1702 break;
1703 case RPC_FC_IGNORE:
1704 break;
1705 default:
1706 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
1708 #undef BASE_TYPE_UNMARSHALL
1711 /***********************************************************************
1712 * NdrSimpleStructMarshall [RPCRT4.@]
1714 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1715 unsigned char *pMemory,
1716 PFORMAT_STRING pFormat)
1718 unsigned size = *(const WORD*)(pFormat+2);
1719 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1721 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1);
1723 pStubMsg->BufferMark = pStubMsg->Buffer;
1724 safe_copy_to_buffer(pStubMsg, pMemory, size);
1726 if (pFormat[0] != RPC_FC_STRUCT)
1727 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1729 return NULL;
1732 /***********************************************************************
1733 * NdrSimpleStructUnmarshall [RPCRT4.@]
1735 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1736 unsigned char **ppMemory,
1737 PFORMAT_STRING pFormat,
1738 unsigned char fMustAlloc)
1740 unsigned size = *(const WORD*)(pFormat+2);
1741 unsigned char *saved_buffer;
1742 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1744 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
1746 if (fMustAlloc)
1747 *ppMemory = NdrAllocate(pStubMsg, size);
1748 else
1750 if (!pStubMsg->IsClient && !*ppMemory)
1751 /* for servers, we just point straight into the RPC buffer */
1752 *ppMemory = pStubMsg->Buffer;
1755 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1756 safe_buffer_increment(pStubMsg, size);
1757 if (pFormat[0] == RPC_FC_PSTRUCT)
1758 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1760 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1761 if (*ppMemory != saved_buffer)
1762 memcpy(*ppMemory, saved_buffer, size);
1764 return NULL;
1767 /***********************************************************************
1768 * NdrSimpleStructBufferSize [RPCRT4.@]
1770 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1771 unsigned char *pMemory,
1772 PFORMAT_STRING pFormat)
1774 unsigned size = *(const WORD*)(pFormat+2);
1775 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1777 align_length(&pStubMsg->BufferLength, pFormat[1] + 1);
1779 safe_buffer_length_increment(pStubMsg, size);
1780 if (pFormat[0] != RPC_FC_STRUCT)
1781 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1784 /***********************************************************************
1785 * NdrSimpleStructMemorySize [RPCRT4.@]
1787 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1788 PFORMAT_STRING pFormat)
1790 unsigned short size = *(const WORD *)(pFormat+2);
1792 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1794 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
1795 pStubMsg->MemorySize += size;
1796 safe_buffer_increment(pStubMsg, size);
1798 if (pFormat[0] != RPC_FC_STRUCT)
1799 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1800 return pStubMsg->MemorySize;
1803 /***********************************************************************
1804 * NdrSimpleStructFree [RPCRT4.@]
1806 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1807 unsigned char *pMemory,
1808 PFORMAT_STRING pFormat)
1810 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1811 if (pFormat[0] != RPC_FC_STRUCT)
1812 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1815 /* Array helpers */
1817 static inline void array_compute_and_size_conformance(
1818 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1819 PFORMAT_STRING pFormat)
1821 DWORD count;
1823 switch (fc)
1825 case RPC_FC_CARRAY:
1826 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1827 SizeConformance(pStubMsg);
1828 break;
1829 case RPC_FC_CVARRAY:
1830 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1831 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1832 SizeConformance(pStubMsg);
1833 break;
1834 case RPC_FC_C_CSTRING:
1835 case RPC_FC_C_WSTRING:
1836 if (fc == RPC_FC_C_CSTRING)
1838 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1839 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1841 else
1843 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1844 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1847 if (pFormat[1] == RPC_FC_STRING_SIZED)
1848 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1849 else
1850 pStubMsg->MaxCount = pStubMsg->ActualCount;
1852 SizeConformance(pStubMsg);
1853 break;
1854 case RPC_FC_BOGUS_ARRAY:
1855 count = *(const WORD *)(pFormat + 2);
1856 pFormat += 4;
1857 if (IsConformanceOrVariancePresent(pFormat)) SizeConformance(pStubMsg);
1858 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, count);
1859 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
1860 break;
1861 default:
1862 ERR("unknown array format 0x%x\n", fc);
1863 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1867 static inline void array_buffer_size(
1868 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1869 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1871 DWORD i, size;
1872 DWORD esize;
1873 unsigned char alignment;
1875 switch (fc)
1877 case RPC_FC_CARRAY:
1878 esize = *(const WORD*)(pFormat+2);
1879 alignment = pFormat[1] + 1;
1881 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1883 align_length(&pStubMsg->BufferLength, alignment);
1885 size = safe_multiply(esize, pStubMsg->MaxCount);
1886 /* conformance value plus array */
1887 safe_buffer_length_increment(pStubMsg, size);
1889 if (fHasPointers)
1890 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1891 break;
1892 case RPC_FC_CVARRAY:
1893 esize = *(const WORD*)(pFormat+2);
1894 alignment = pFormat[1] + 1;
1896 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1897 pFormat = SkipVariance(pStubMsg, pFormat);
1899 SizeVariance(pStubMsg);
1901 align_length(&pStubMsg->BufferLength, alignment);
1903 size = safe_multiply(esize, pStubMsg->ActualCount);
1904 safe_buffer_length_increment(pStubMsg, size);
1906 if (fHasPointers)
1907 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1908 break;
1909 case RPC_FC_C_CSTRING:
1910 case RPC_FC_C_WSTRING:
1911 if (fc == RPC_FC_C_CSTRING)
1912 esize = 1;
1913 else
1914 esize = 2;
1916 SizeVariance(pStubMsg);
1918 size = safe_multiply(esize, pStubMsg->ActualCount);
1919 safe_buffer_length_increment(pStubMsg, size);
1920 break;
1921 case RPC_FC_BOGUS_ARRAY:
1922 alignment = pFormat[1] + 1;
1923 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1924 if (IsConformanceOrVariancePresent(pFormat)) SizeVariance(pStubMsg);
1925 pFormat = SkipVariance(pStubMsg, pFormat);
1927 align_length(&pStubMsg->BufferLength, alignment);
1929 size = pStubMsg->ActualCount;
1930 for (i = 0; i < size; i++)
1931 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
1932 break;
1933 default:
1934 ERR("unknown array format 0x%x\n", fc);
1935 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1939 static inline void array_compute_and_write_conformance(
1940 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1941 PFORMAT_STRING pFormat)
1943 ULONG def;
1944 BOOL conformance_present;
1946 switch (fc)
1948 case RPC_FC_CARRAY:
1949 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1950 WriteConformance(pStubMsg);
1951 break;
1952 case RPC_FC_CVARRAY:
1953 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1954 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1955 WriteConformance(pStubMsg);
1956 break;
1957 case RPC_FC_C_CSTRING:
1958 case RPC_FC_C_WSTRING:
1959 if (fc == RPC_FC_C_CSTRING)
1961 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1962 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1964 else
1966 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1967 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1969 if (pFormat[1] == RPC_FC_STRING_SIZED)
1970 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1971 else
1972 pStubMsg->MaxCount = pStubMsg->ActualCount;
1973 pStubMsg->Offset = 0;
1974 WriteConformance(pStubMsg);
1975 break;
1976 case RPC_FC_BOGUS_ARRAY:
1977 def = *(const WORD *)(pFormat + 2);
1978 pFormat += 4;
1979 conformance_present = IsConformanceOrVariancePresent(pFormat);
1980 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
1981 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
1982 if (conformance_present) WriteConformance(pStubMsg);
1983 break;
1984 default:
1985 ERR("unknown array format 0x%x\n", fc);
1986 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1990 static inline void array_write_variance_and_marshall(
1991 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1992 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1994 DWORD i, size;
1995 DWORD esize;
1996 unsigned char alignment;
1998 switch (fc)
2000 case RPC_FC_CARRAY:
2001 esize = *(const WORD*)(pFormat+2);
2002 alignment = pFormat[1] + 1;
2004 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2006 align_pointer_clear(&pStubMsg->Buffer, alignment);
2008 size = safe_multiply(esize, pStubMsg->MaxCount);
2009 if (fHasPointers)
2010 pStubMsg->BufferMark = pStubMsg->Buffer;
2011 safe_copy_to_buffer(pStubMsg, pMemory, size);
2013 if (fHasPointers)
2014 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2015 break;
2016 case RPC_FC_CVARRAY:
2017 esize = *(const WORD*)(pFormat+2);
2018 alignment = pFormat[1] + 1;
2020 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2021 pFormat = SkipVariance(pStubMsg, pFormat);
2023 WriteVariance(pStubMsg);
2025 align_pointer_clear(&pStubMsg->Buffer, alignment);
2027 size = safe_multiply(esize, pStubMsg->ActualCount);
2029 if (fHasPointers)
2030 pStubMsg->BufferMark = pStubMsg->Buffer;
2031 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size);
2033 if (fHasPointers)
2034 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2035 break;
2036 case RPC_FC_C_CSTRING:
2037 case RPC_FC_C_WSTRING:
2038 if (fc == RPC_FC_C_CSTRING)
2039 esize = 1;
2040 else
2041 esize = 2;
2043 WriteVariance(pStubMsg);
2045 size = safe_multiply(esize, pStubMsg->ActualCount);
2046 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2047 break;
2048 case RPC_FC_BOGUS_ARRAY:
2049 alignment = pFormat[1] + 1;
2050 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2051 if (IsConformanceOrVariancePresent(pFormat)) WriteVariance(pStubMsg);
2052 pFormat = SkipVariance(pStubMsg, pFormat);
2054 align_pointer_clear(&pStubMsg->Buffer, alignment);
2056 size = pStubMsg->ActualCount;
2057 for (i = 0; i < size; i++)
2058 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2059 break;
2060 default:
2061 ERR("unknown array format 0x%x\n", fc);
2062 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2066 static inline ULONG array_read_conformance(
2067 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
2069 DWORD def, esize;
2071 switch (fc)
2073 case RPC_FC_CARRAY:
2074 esize = *(const WORD*)(pFormat+2);
2075 pFormat = ReadConformance(pStubMsg, pFormat+4);
2076 return safe_multiply(esize, pStubMsg->MaxCount);
2077 case RPC_FC_CVARRAY:
2078 esize = *(const WORD*)(pFormat+2);
2079 pFormat = ReadConformance(pStubMsg, pFormat+4);
2080 return safe_multiply(esize, pStubMsg->MaxCount);
2081 case RPC_FC_C_CSTRING:
2082 case RPC_FC_C_WSTRING:
2083 if (fc == RPC_FC_C_CSTRING)
2084 esize = 1;
2085 else
2086 esize = 2;
2088 if (pFormat[1] == RPC_FC_STRING_SIZED)
2089 ReadConformance(pStubMsg, pFormat + 2);
2090 else
2091 ReadConformance(pStubMsg, NULL);
2092 return safe_multiply(esize, pStubMsg->MaxCount);
2093 case RPC_FC_BOGUS_ARRAY:
2094 def = *(const WORD *)(pFormat + 2);
2095 pFormat += 4;
2096 if (IsConformanceOrVariancePresent(pFormat)) pFormat = ReadConformance(pStubMsg, pFormat);
2097 else
2099 pStubMsg->MaxCount = def;
2100 pFormat = SkipConformance( pStubMsg, pFormat );
2102 pFormat = SkipVariance( pStubMsg, pFormat );
2104 esize = ComplexStructSize(pStubMsg, pFormat);
2105 return safe_multiply(pStubMsg->MaxCount, esize);
2106 default:
2107 ERR("unknown array format 0x%x\n", fc);
2108 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2112 static inline ULONG array_read_variance_and_unmarshall(
2113 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory,
2114 PFORMAT_STRING pFormat, unsigned char fMustAlloc,
2115 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall)
2117 ULONG bufsize, memsize;
2118 WORD esize;
2119 unsigned char alignment;
2120 unsigned char *saved_buffer, *pMemory;
2121 ULONG i, offset, count;
2123 switch (fc)
2125 case RPC_FC_CARRAY:
2126 esize = *(const WORD*)(pFormat+2);
2127 alignment = pFormat[1] + 1;
2129 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2131 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2133 align_pointer(&pStubMsg->Buffer, alignment);
2135 if (fUnmarshall)
2137 if (fMustAlloc)
2138 *ppMemory = NdrAllocate(pStubMsg, memsize);
2139 else
2141 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory)
2142 /* for servers, we just point straight into the RPC buffer */
2143 *ppMemory = pStubMsg->Buffer;
2146 saved_buffer = pStubMsg->Buffer;
2147 safe_buffer_increment(pStubMsg, bufsize);
2149 pStubMsg->BufferMark = saved_buffer;
2150 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2152 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2153 if (*ppMemory != saved_buffer)
2154 memcpy(*ppMemory, saved_buffer, bufsize);
2156 return bufsize;
2157 case RPC_FC_CVARRAY:
2158 esize = *(const WORD*)(pFormat+2);
2159 alignment = pFormat[1] + 1;
2161 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2163 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2165 align_pointer(&pStubMsg->Buffer, alignment);
2167 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2168 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2170 if (fUnmarshall)
2172 offset = pStubMsg->Offset;
2174 if (!fMustAlloc && !*ppMemory)
2175 fMustAlloc = TRUE;
2176 if (fMustAlloc)
2177 *ppMemory = NdrAllocate(pStubMsg, memsize);
2178 saved_buffer = pStubMsg->Buffer;
2179 safe_buffer_increment(pStubMsg, bufsize);
2181 pStubMsg->BufferMark = saved_buffer;
2182 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat,
2183 fMustAlloc);
2185 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2187 return bufsize;
2188 case RPC_FC_C_CSTRING:
2189 case RPC_FC_C_WSTRING:
2190 if (fc == RPC_FC_C_CSTRING)
2191 esize = 1;
2192 else
2193 esize = 2;
2195 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2197 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2199 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2200 pStubMsg->ActualCount, pStubMsg->MaxCount);
2201 RpcRaiseException(RPC_S_INVALID_BOUND);
2203 if (pStubMsg->Offset)
2205 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2206 RpcRaiseException(RPC_S_INVALID_BOUND);
2209 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2210 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2212 validate_string_data(pStubMsg, bufsize, esize);
2214 if (fUnmarshall)
2216 if (fMustAlloc)
2217 *ppMemory = NdrAllocate(pStubMsg, memsize);
2218 else
2220 if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
2221 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
2222 /* if the data in the RPC buffer is big enough, we just point
2223 * straight into it */
2224 *ppMemory = pStubMsg->Buffer;
2225 else if (!*ppMemory)
2226 *ppMemory = NdrAllocate(pStubMsg, memsize);
2229 if (*ppMemory == pStubMsg->Buffer)
2230 safe_buffer_increment(pStubMsg, bufsize);
2231 else
2232 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2234 if (*pFormat == RPC_FC_C_CSTRING)
2235 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
2236 else
2237 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
2239 return bufsize;
2241 case RPC_FC_BOGUS_ARRAY:
2242 alignment = pFormat[1] + 1;
2243 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2244 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2246 esize = ComplexStructSize(pStubMsg, pFormat);
2247 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2249 assert( fUnmarshall );
2251 if (!fMustAlloc && !*ppMemory)
2252 fMustAlloc = TRUE;
2253 if (fMustAlloc)
2254 *ppMemory = NdrAllocate(pStubMsg, memsize);
2256 align_pointer(&pStubMsg->Buffer, alignment);
2257 saved_buffer = pStubMsg->Buffer;
2259 pMemory = *ppMemory;
2260 count = pStubMsg->ActualCount;
2261 for (i = 0; i < count; i++)
2262 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
2263 return pStubMsg->Buffer - saved_buffer;
2265 default:
2266 ERR("unknown array format 0x%x\n", fc);
2267 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2271 static inline void array_memory_size(
2272 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
2273 unsigned char fHasPointers)
2275 ULONG i, count, SavedMemorySize;
2276 ULONG bufsize, memsize;
2277 DWORD esize;
2278 unsigned char alignment;
2280 switch (fc)
2282 case RPC_FC_CARRAY:
2283 esize = *(const WORD*)(pFormat+2);
2284 alignment = pFormat[1] + 1;
2286 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2288 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2289 pStubMsg->MemorySize += memsize;
2291 align_pointer(&pStubMsg->Buffer, alignment);
2292 if (fHasPointers)
2293 pStubMsg->BufferMark = pStubMsg->Buffer;
2294 safe_buffer_increment(pStubMsg, bufsize);
2296 if (fHasPointers)
2297 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2298 break;
2299 case RPC_FC_CVARRAY:
2300 esize = *(const WORD*)(pFormat+2);
2301 alignment = pFormat[1] + 1;
2303 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2305 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2307 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2308 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2309 pStubMsg->MemorySize += memsize;
2311 align_pointer(&pStubMsg->Buffer, alignment);
2312 if (fHasPointers)
2313 pStubMsg->BufferMark = pStubMsg->Buffer;
2314 safe_buffer_increment(pStubMsg, bufsize);
2316 if (fHasPointers)
2317 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2318 break;
2319 case RPC_FC_C_CSTRING:
2320 case RPC_FC_C_WSTRING:
2321 if (fc == RPC_FC_C_CSTRING)
2322 esize = 1;
2323 else
2324 esize = 2;
2326 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2328 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2330 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2331 pStubMsg->ActualCount, pStubMsg->MaxCount);
2332 RpcRaiseException(RPC_S_INVALID_BOUND);
2334 if (pStubMsg->Offset)
2336 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2337 RpcRaiseException(RPC_S_INVALID_BOUND);
2340 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2341 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2343 validate_string_data(pStubMsg, bufsize, esize);
2345 safe_buffer_increment(pStubMsg, bufsize);
2346 pStubMsg->MemorySize += memsize;
2347 break;
2348 case RPC_FC_BOGUS_ARRAY:
2349 alignment = pFormat[1] + 1;
2350 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2351 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2353 align_pointer(&pStubMsg->Buffer, alignment);
2355 SavedMemorySize = pStubMsg->MemorySize;
2357 esize = ComplexStructSize(pStubMsg, pFormat);
2358 memsize = safe_multiply(pStubMsg->MaxCount, esize);
2360 count = pStubMsg->ActualCount;
2361 for (i = 0; i < count; i++)
2362 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
2364 pStubMsg->MemorySize = SavedMemorySize + memsize;
2365 break;
2366 default:
2367 ERR("unknown array format 0x%x\n", fc);
2368 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2372 static inline void array_free(
2373 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
2374 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
2376 DWORD i, count;
2378 switch (fc)
2380 case RPC_FC_CARRAY:
2381 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2382 if (fHasPointers)
2383 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2384 break;
2385 case RPC_FC_CVARRAY:
2386 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2387 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2388 if (fHasPointers)
2389 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2390 break;
2391 case RPC_FC_C_CSTRING:
2392 case RPC_FC_C_WSTRING:
2393 /* No embedded pointers so nothing to do */
2394 break;
2395 case RPC_FC_BOGUS_ARRAY:
2396 count = *(const WORD *)(pFormat + 2);
2397 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, count);
2398 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2400 count = pStubMsg->ActualCount;
2401 for (i = 0; i < count; i++)
2402 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2403 break;
2404 default:
2405 ERR("unknown array format 0x%x\n", fc);
2406 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2411 * NdrConformantString:
2413 * What MS calls a ConformantString is, in DCE terminology,
2414 * a Varying-Conformant String.
2416 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2417 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2418 * into unmarshalled string)
2419 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2421 * data: CHARTYPE[maxlen]
2423 * ], where CHARTYPE is the appropriate character type (specified externally)
2427 /***********************************************************************
2428 * NdrConformantStringMarshall [RPCRT4.@]
2430 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
2431 unsigned char *pszMessage, PFORMAT_STRING pFormat)
2433 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
2435 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2436 ERR("Unhandled string type: %#x\n", pFormat[0]);
2437 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2440 /* allow compiler to optimise inline function by passing constant into
2441 * these functions */
2442 if (pFormat[0] == RPC_FC_C_CSTRING) {
2443 array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2444 pFormat);
2445 array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2446 pFormat, TRUE /* fHasPointers */);
2447 } else {
2448 array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2449 pFormat);
2450 array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2451 pFormat, TRUE /* fHasPointers */);
2454 return NULL;
2457 /***********************************************************************
2458 * NdrConformantStringBufferSize [RPCRT4.@]
2460 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2461 unsigned char* pMemory, PFORMAT_STRING pFormat)
2463 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2465 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2466 ERR("Unhandled string type: %#x\n", pFormat[0]);
2467 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2470 /* allow compiler to optimise inline function by passing constant into
2471 * these functions */
2472 if (pFormat[0] == RPC_FC_C_CSTRING) {
2473 array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory,
2474 pFormat);
2475 array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat,
2476 TRUE /* fHasPointers */);
2477 } else {
2478 array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory,
2479 pFormat);
2480 array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat,
2481 TRUE /* fHasPointers */);
2485 /************************************************************************
2486 * NdrConformantStringMemorySize [RPCRT4.@]
2488 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2489 PFORMAT_STRING pFormat )
2491 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2493 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2494 ERR("Unhandled string type: %#x\n", pFormat[0]);
2495 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2498 /* allow compiler to optimise inline function by passing constant into
2499 * these functions */
2500 if (pFormat[0] == RPC_FC_C_CSTRING) {
2501 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2502 array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat,
2503 TRUE /* fHasPointers */);
2504 } else {
2505 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2506 array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat,
2507 TRUE /* fHasPointers */);
2510 return pStubMsg->MemorySize;
2513 /************************************************************************
2514 * NdrConformantStringUnmarshall [RPCRT4.@]
2516 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2517 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
2519 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2520 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2522 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2523 ERR("Unhandled string type: %#x\n", *pFormat);
2524 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2527 /* allow compiler to optimise inline function by passing constant into
2528 * these functions */
2529 if (pFormat[0] == RPC_FC_C_CSTRING) {
2530 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2531 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory,
2532 pFormat, fMustAlloc,
2533 TRUE /* fUseBufferMemoryServer */,
2534 TRUE /* fUnmarshall */);
2535 } else {
2536 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2537 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory,
2538 pFormat, fMustAlloc,
2539 TRUE /* fUseBufferMemoryServer */,
2540 TRUE /* fUnmarshall */);
2543 return NULL;
2546 /***********************************************************************
2547 * NdrNonConformantStringMarshall [RPCRT4.@]
2549 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2550 unsigned char *pMemory,
2551 PFORMAT_STRING pFormat)
2553 ULONG esize, size, maxsize;
2555 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2557 maxsize = *(const USHORT *)&pFormat[2];
2559 if (*pFormat == RPC_FC_CSTRING)
2561 ULONG i = 0;
2562 const char *str = (const char *)pMemory;
2563 while (i < maxsize && str[i]) i++;
2564 TRACE("string=%s\n", debugstr_an(str, i));
2565 pStubMsg->ActualCount = i + 1;
2566 esize = 1;
2568 else if (*pFormat == RPC_FC_WSTRING)
2570 ULONG i = 0;
2571 const WCHAR *str = (const WCHAR *)pMemory;
2572 while (i < maxsize && str[i]) i++;
2573 TRACE("string=%s\n", debugstr_wn(str, i));
2574 pStubMsg->ActualCount = i + 1;
2575 esize = 2;
2577 else
2579 ERR("Unhandled string type: %#x\n", *pFormat);
2580 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2583 pStubMsg->Offset = 0;
2584 WriteVariance(pStubMsg);
2586 size = safe_multiply(esize, pStubMsg->ActualCount);
2587 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2589 return NULL;
2592 /***********************************************************************
2593 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2595 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2596 unsigned char **ppMemory,
2597 PFORMAT_STRING pFormat,
2598 unsigned char fMustAlloc)
2600 ULONG bufsize, memsize, esize, maxsize;
2602 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2603 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2605 maxsize = *(const USHORT *)&pFormat[2];
2607 ReadVariance(pStubMsg, NULL, maxsize);
2608 if (pStubMsg->Offset)
2610 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2611 RpcRaiseException(RPC_S_INVALID_BOUND);
2614 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2615 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2616 else
2618 ERR("Unhandled string type: %#x\n", *pFormat);
2619 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2622 memsize = esize * maxsize;
2623 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2625 validate_string_data(pStubMsg, bufsize, esize);
2627 if (!fMustAlloc && !*ppMemory)
2628 fMustAlloc = TRUE;
2629 if (fMustAlloc)
2630 *ppMemory = NdrAllocate(pStubMsg, memsize);
2632 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2634 if (*pFormat == RPC_FC_CSTRING) {
2635 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
2637 else if (*pFormat == RPC_FC_WSTRING) {
2638 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
2641 return NULL;
2644 /***********************************************************************
2645 * NdrNonConformantStringBufferSize [RPCRT4.@]
2647 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2648 unsigned char *pMemory,
2649 PFORMAT_STRING pFormat)
2651 ULONG esize, maxsize;
2653 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2655 maxsize = *(const USHORT *)&pFormat[2];
2657 SizeVariance(pStubMsg);
2659 if (*pFormat == RPC_FC_CSTRING)
2661 ULONG i = 0;
2662 const char *str = (const char *)pMemory;
2663 while (i < maxsize && str[i]) i++;
2664 TRACE("string=%s\n", debugstr_an(str, i));
2665 pStubMsg->ActualCount = i + 1;
2666 esize = 1;
2668 else if (*pFormat == RPC_FC_WSTRING)
2670 ULONG i = 0;
2671 const WCHAR *str = (const WCHAR *)pMemory;
2672 while (i < maxsize && str[i]) i++;
2673 TRACE("string=%s\n", debugstr_wn(str, i));
2674 pStubMsg->ActualCount = i + 1;
2675 esize = 2;
2677 else
2679 ERR("Unhandled string type: %#x\n", *pFormat);
2680 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2683 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2686 /***********************************************************************
2687 * NdrNonConformantStringMemorySize [RPCRT4.@]
2689 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2690 PFORMAT_STRING pFormat)
2692 ULONG bufsize, memsize, esize, maxsize;
2694 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2696 maxsize = *(const USHORT *)&pFormat[2];
2698 ReadVariance(pStubMsg, NULL, maxsize);
2700 if (pStubMsg->Offset)
2702 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2703 RpcRaiseException(RPC_S_INVALID_BOUND);
2706 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2707 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2708 else
2710 ERR("Unhandled string type: %#x\n", *pFormat);
2711 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2714 memsize = esize * maxsize;
2715 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2717 validate_string_data(pStubMsg, bufsize, esize);
2719 safe_buffer_increment(pStubMsg, bufsize);
2720 pStubMsg->MemorySize += memsize;
2722 return pStubMsg->MemorySize;
2725 /* Complex types */
2727 #include "pshpack1.h"
2728 typedef struct
2730 unsigned char type;
2731 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2732 ULONG low_value;
2733 ULONG high_value;
2734 } NDR_RANGE;
2735 #include "poppack.h"
2737 static ULONG EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2738 PFORMAT_STRING pFormat)
2740 switch (*pFormat) {
2741 case RPC_FC_STRUCT:
2742 case RPC_FC_PSTRUCT:
2743 case RPC_FC_CSTRUCT:
2744 case RPC_FC_BOGUS_STRUCT:
2745 case RPC_FC_SMFARRAY:
2746 case RPC_FC_SMVARRAY:
2747 case RPC_FC_CSTRING:
2748 return *(const WORD*)&pFormat[2];
2749 case RPC_FC_USER_MARSHAL:
2750 return *(const WORD*)&pFormat[4];
2751 case RPC_FC_RANGE: {
2752 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2753 case RPC_FC_BYTE:
2754 case RPC_FC_CHAR:
2755 case RPC_FC_SMALL:
2756 case RPC_FC_USMALL:
2757 return sizeof(UCHAR);
2758 case RPC_FC_WCHAR:
2759 case RPC_FC_SHORT:
2760 case RPC_FC_USHORT:
2761 return sizeof(USHORT);
2762 case RPC_FC_LONG:
2763 case RPC_FC_ULONG:
2764 case RPC_FC_ENUM32:
2765 case RPC_FC_INT3264:
2766 case RPC_FC_UINT3264:
2767 return sizeof(ULONG);
2768 case RPC_FC_FLOAT:
2769 return sizeof(float);
2770 case RPC_FC_DOUBLE:
2771 return sizeof(double);
2772 case RPC_FC_HYPER:
2773 return sizeof(ULONGLONG);
2774 case RPC_FC_ENUM16:
2775 return sizeof(UINT);
2776 default:
2777 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2778 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2781 case RPC_FC_NON_ENCAPSULATED_UNION:
2782 pFormat += 2;
2783 if (pStubMsg->fHasNewCorrDesc)
2784 pFormat += 6;
2785 else
2786 pFormat += 4;
2788 pFormat += *(const SHORT*)pFormat;
2789 return *(const SHORT*)pFormat;
2790 case RPC_FC_IP:
2791 return sizeof(void *);
2792 case RPC_FC_WSTRING:
2793 return *(const WORD*)&pFormat[2] * 2;
2794 default:
2795 FIXME("unhandled embedded type %02x\n", *pFormat);
2797 return 0;
2801 static ULONG EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2802 PFORMAT_STRING pFormat)
2804 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2806 if (!m)
2808 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2809 return 0;
2812 return m(pStubMsg, pFormat);
2816 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2817 unsigned char *pMemory,
2818 PFORMAT_STRING pFormat,
2819 PFORMAT_STRING pPointer)
2821 PFORMAT_STRING desc;
2822 NDR_MARSHALL m;
2823 ULONG size;
2825 while (*pFormat != RPC_FC_END) {
2826 switch (*pFormat) {
2827 case RPC_FC_BYTE:
2828 case RPC_FC_CHAR:
2829 case RPC_FC_SMALL:
2830 case RPC_FC_USMALL:
2831 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2832 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2833 pMemory += 1;
2834 break;
2835 case RPC_FC_WCHAR:
2836 case RPC_FC_SHORT:
2837 case RPC_FC_USHORT:
2838 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2839 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2840 pMemory += 2;
2841 break;
2842 case RPC_FC_ENUM16:
2844 USHORT val = *(DWORD *)pMemory;
2845 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2846 if (32767 < *(DWORD*)pMemory)
2847 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2848 safe_copy_to_buffer(pStubMsg, &val, 2);
2849 pMemory += 4;
2850 break;
2852 case RPC_FC_LONG:
2853 case RPC_FC_ULONG:
2854 case RPC_FC_ENUM32:
2855 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2856 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2857 pMemory += 4;
2858 break;
2859 case RPC_FC_INT3264:
2860 case RPC_FC_UINT3264:
2862 UINT val = *(UINT_PTR *)pMemory;
2863 TRACE("int3264=%ld <= %p\n", *(UINT_PTR *)pMemory, pMemory);
2864 safe_copy_to_buffer(pStubMsg, &val, sizeof(UINT));
2865 pMemory += sizeof(UINT_PTR);
2866 break;
2868 case RPC_FC_FLOAT:
2869 TRACE("float=%f <= %p\n", *(float*)pMemory, pMemory);
2870 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
2871 pMemory += sizeof(float);
2872 break;
2873 case RPC_FC_HYPER:
2874 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2875 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2876 pMemory += 8;
2877 break;
2878 case RPC_FC_DOUBLE:
2879 TRACE("double=%f <= %p\n", *(double*)pMemory, pMemory);
2880 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
2881 pMemory += sizeof(double);
2882 break;
2883 case RPC_FC_RP:
2884 case RPC_FC_UP:
2885 case RPC_FC_OP:
2886 case RPC_FC_FP:
2887 case RPC_FC_POINTER:
2889 unsigned char *saved_buffer;
2890 int pointer_buffer_mark_set = 0;
2891 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2892 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2893 if (*pFormat != RPC_FC_POINTER)
2894 pPointer = pFormat;
2895 if (*pPointer != RPC_FC_RP)
2896 align_pointer_clear(&pStubMsg->Buffer, 4);
2897 saved_buffer = pStubMsg->Buffer;
2898 if (pStubMsg->PointerBufferMark)
2900 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2901 pStubMsg->PointerBufferMark = NULL;
2902 pointer_buffer_mark_set = 1;
2904 else if (*pPointer != RPC_FC_RP)
2905 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2906 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2907 if (pointer_buffer_mark_set)
2909 STD_OVERFLOW_CHECK(pStubMsg);
2910 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2911 pStubMsg->Buffer = saved_buffer;
2912 if (*pPointer != RPC_FC_RP)
2913 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2915 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2916 if (*pFormat == RPC_FC_POINTER)
2917 pPointer += 4;
2918 else
2919 pFormat += 4;
2920 pMemory += sizeof(void *);
2921 break;
2923 case RPC_FC_ALIGNM2:
2924 align_pointer(&pMemory, 2);
2925 break;
2926 case RPC_FC_ALIGNM4:
2927 align_pointer(&pMemory, 4);
2928 break;
2929 case RPC_FC_ALIGNM8:
2930 align_pointer(&pMemory, 8);
2931 break;
2932 case RPC_FC_STRUCTPAD1:
2933 case RPC_FC_STRUCTPAD2:
2934 case RPC_FC_STRUCTPAD3:
2935 case RPC_FC_STRUCTPAD4:
2936 case RPC_FC_STRUCTPAD5:
2937 case RPC_FC_STRUCTPAD6:
2938 case RPC_FC_STRUCTPAD7:
2939 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2940 break;
2941 case RPC_FC_EMBEDDED_COMPLEX:
2942 pMemory += pFormat[1];
2943 pFormat += 2;
2944 desc = pFormat + *(const SHORT*)pFormat;
2945 size = EmbeddedComplexSize(pStubMsg, desc);
2946 TRACE("embedded complex (size=%d) <= %p\n", size, pMemory);
2947 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2948 if (m)
2950 /* for some reason interface pointers aren't generated as
2951 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2952 * they still need the derefencing treatment that pointers are
2953 * given */
2954 if (*desc == RPC_FC_IP)
2955 m(pStubMsg, *(unsigned char **)pMemory, desc);
2956 else
2957 m(pStubMsg, pMemory, desc);
2959 else FIXME("no marshaller for embedded type %02x\n", *desc);
2960 pMemory += size;
2961 pFormat += 2;
2962 continue;
2963 case RPC_FC_PAD:
2964 break;
2965 default:
2966 FIXME("unhandled format 0x%02x\n", *pFormat);
2968 pFormat++;
2971 return pMemory;
2974 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2975 unsigned char *pMemory,
2976 PFORMAT_STRING pFormat,
2977 PFORMAT_STRING pPointer,
2978 unsigned char fMustAlloc)
2980 PFORMAT_STRING desc;
2981 NDR_UNMARSHALL m;
2982 ULONG size;
2984 while (*pFormat != RPC_FC_END) {
2985 switch (*pFormat) {
2986 case RPC_FC_BYTE:
2987 case RPC_FC_CHAR:
2988 case RPC_FC_SMALL:
2989 case RPC_FC_USMALL:
2990 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2991 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2992 pMemory += 1;
2993 break;
2994 case RPC_FC_WCHAR:
2995 case RPC_FC_SHORT:
2996 case RPC_FC_USHORT:
2997 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2998 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2999 pMemory += 2;
3000 break;
3001 case RPC_FC_ENUM16:
3003 WORD val;
3004 safe_copy_from_buffer(pStubMsg, &val, 2);
3005 *(DWORD*)pMemory = val;
3006 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
3007 if (32767 < *(DWORD*)pMemory)
3008 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
3009 pMemory += 4;
3010 break;
3012 case RPC_FC_LONG:
3013 case RPC_FC_ULONG:
3014 case RPC_FC_ENUM32:
3015 safe_copy_from_buffer(pStubMsg, pMemory, 4);
3016 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
3017 pMemory += 4;
3018 break;
3019 case RPC_FC_INT3264:
3021 INT val;
3022 safe_copy_from_buffer(pStubMsg, &val, 4);
3023 *(INT_PTR *)pMemory = val;
3024 TRACE("int3264=%ld => %p\n", *(INT_PTR*)pMemory, pMemory);
3025 pMemory += sizeof(INT_PTR);
3026 break;
3028 case RPC_FC_UINT3264:
3030 UINT val;
3031 safe_copy_from_buffer(pStubMsg, &val, 4);
3032 *(UINT_PTR *)pMemory = val;
3033 TRACE("uint3264=%ld => %p\n", *(UINT_PTR*)pMemory, pMemory);
3034 pMemory += sizeof(UINT_PTR);
3035 break;
3037 case RPC_FC_FLOAT:
3038 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(float));
3039 TRACE("float=%f => %p\n", *(float*)pMemory, pMemory);
3040 pMemory += sizeof(float);
3041 break;
3042 case RPC_FC_HYPER:
3043 safe_copy_from_buffer(pStubMsg, pMemory, 8);
3044 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
3045 pMemory += 8;
3046 break;
3047 case RPC_FC_DOUBLE:
3048 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(double));
3049 TRACE("double=%f => %p\n", *(double*)pMemory, pMemory);
3050 pMemory += sizeof(double);
3051 break;
3052 case RPC_FC_RP:
3053 case RPC_FC_UP:
3054 case RPC_FC_OP:
3055 case RPC_FC_FP:
3056 case RPC_FC_POINTER:
3058 unsigned char *saved_buffer;
3059 int pointer_buffer_mark_set = 0;
3060 TRACE("pointer => %p\n", pMemory);
3061 if (*pFormat != RPC_FC_POINTER)
3062 pPointer = pFormat;
3063 if (*pPointer != RPC_FC_RP)
3064 align_pointer(&pStubMsg->Buffer, 4);
3065 saved_buffer = pStubMsg->Buffer;
3066 if (pStubMsg->PointerBufferMark)
3068 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3069 pStubMsg->PointerBufferMark = NULL;
3070 pointer_buffer_mark_set = 1;
3072 else if (*pPointer != RPC_FC_RP)
3073 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3075 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
3076 if (pointer_buffer_mark_set)
3078 STD_OVERFLOW_CHECK(pStubMsg);
3079 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3080 pStubMsg->Buffer = saved_buffer;
3081 if (*pPointer != RPC_FC_RP)
3082 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3084 if (*pFormat == RPC_FC_POINTER)
3085 pPointer += 4;
3086 else
3087 pFormat += 4;
3088 pMemory += sizeof(void *);
3089 break;
3091 case RPC_FC_ALIGNM2:
3092 align_pointer_clear(&pMemory, 2);
3093 break;
3094 case RPC_FC_ALIGNM4:
3095 align_pointer_clear(&pMemory, 4);
3096 break;
3097 case RPC_FC_ALIGNM8:
3098 align_pointer_clear(&pMemory, 8);
3099 break;
3100 case RPC_FC_STRUCTPAD1:
3101 case RPC_FC_STRUCTPAD2:
3102 case RPC_FC_STRUCTPAD3:
3103 case RPC_FC_STRUCTPAD4:
3104 case RPC_FC_STRUCTPAD5:
3105 case RPC_FC_STRUCTPAD6:
3106 case RPC_FC_STRUCTPAD7:
3107 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
3108 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3109 break;
3110 case RPC_FC_EMBEDDED_COMPLEX:
3111 pMemory += pFormat[1];
3112 pFormat += 2;
3113 desc = pFormat + *(const SHORT*)pFormat;
3114 size = EmbeddedComplexSize(pStubMsg, desc);
3115 TRACE("embedded complex (size=%d) => %p\n", size, pMemory);
3116 if (fMustAlloc)
3117 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
3118 * since the type is part of the memory block that is encompassed by
3119 * the whole complex type. Memory is forced to allocate when pointers
3120 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
3121 * clearing the memory we pass in to the unmarshaller */
3122 memset(pMemory, 0, size);
3123 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
3124 if (m)
3126 /* for some reason interface pointers aren't generated as
3127 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3128 * they still need the derefencing treatment that pointers are
3129 * given */
3130 if (*desc == RPC_FC_IP)
3131 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
3132 else
3133 m(pStubMsg, &pMemory, desc, FALSE);
3135 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
3136 pMemory += size;
3137 pFormat += 2;
3138 continue;
3139 case RPC_FC_PAD:
3140 break;
3141 default:
3142 FIXME("unhandled format %d\n", *pFormat);
3144 pFormat++;
3147 return pMemory;
3150 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3151 unsigned char *pMemory,
3152 PFORMAT_STRING pFormat,
3153 PFORMAT_STRING pPointer)
3155 PFORMAT_STRING desc;
3156 NDR_BUFFERSIZE m;
3157 ULONG size;
3159 while (*pFormat != RPC_FC_END) {
3160 switch (*pFormat) {
3161 case RPC_FC_BYTE:
3162 case RPC_FC_CHAR:
3163 case RPC_FC_SMALL:
3164 case RPC_FC_USMALL:
3165 safe_buffer_length_increment(pStubMsg, 1);
3166 pMemory += 1;
3167 break;
3168 case RPC_FC_WCHAR:
3169 case RPC_FC_SHORT:
3170 case RPC_FC_USHORT:
3171 safe_buffer_length_increment(pStubMsg, 2);
3172 pMemory += 2;
3173 break;
3174 case RPC_FC_ENUM16:
3175 safe_buffer_length_increment(pStubMsg, 2);
3176 pMemory += 4;
3177 break;
3178 case RPC_FC_LONG:
3179 case RPC_FC_ULONG:
3180 case RPC_FC_ENUM32:
3181 case RPC_FC_FLOAT:
3182 safe_buffer_length_increment(pStubMsg, 4);
3183 pMemory += 4;
3184 break;
3185 case RPC_FC_INT3264:
3186 case RPC_FC_UINT3264:
3187 safe_buffer_length_increment(pStubMsg, 4);
3188 pMemory += sizeof(INT_PTR);
3189 break;
3190 case RPC_FC_HYPER:
3191 case RPC_FC_DOUBLE:
3192 safe_buffer_length_increment(pStubMsg, 8);
3193 pMemory += 8;
3194 break;
3195 case RPC_FC_RP:
3196 case RPC_FC_UP:
3197 case RPC_FC_OP:
3198 case RPC_FC_FP:
3199 case RPC_FC_POINTER:
3200 if (*pFormat != RPC_FC_POINTER)
3201 pPointer = pFormat;
3202 if (!pStubMsg->IgnoreEmbeddedPointers)
3204 int saved_buffer_length = pStubMsg->BufferLength;
3205 pStubMsg->BufferLength = pStubMsg->PointerLength;
3206 pStubMsg->PointerLength = 0;
3207 if(!pStubMsg->BufferLength)
3208 ERR("BufferLength == 0??\n");
3209 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
3210 pStubMsg->PointerLength = pStubMsg->BufferLength;
3211 pStubMsg->BufferLength = saved_buffer_length;
3213 if (*pPointer != RPC_FC_RP)
3215 align_length(&pStubMsg->BufferLength, 4);
3216 safe_buffer_length_increment(pStubMsg, 4);
3218 if (*pFormat == RPC_FC_POINTER)
3219 pPointer += 4;
3220 else
3221 pFormat += 4;
3222 pMemory += sizeof(void*);
3223 break;
3224 case RPC_FC_ALIGNM2:
3225 align_pointer(&pMemory, 2);
3226 break;
3227 case RPC_FC_ALIGNM4:
3228 align_pointer(&pMemory, 4);
3229 break;
3230 case RPC_FC_ALIGNM8:
3231 align_pointer(&pMemory, 8);
3232 break;
3233 case RPC_FC_STRUCTPAD1:
3234 case RPC_FC_STRUCTPAD2:
3235 case RPC_FC_STRUCTPAD3:
3236 case RPC_FC_STRUCTPAD4:
3237 case RPC_FC_STRUCTPAD5:
3238 case RPC_FC_STRUCTPAD6:
3239 case RPC_FC_STRUCTPAD7:
3240 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3241 break;
3242 case RPC_FC_EMBEDDED_COMPLEX:
3243 pMemory += pFormat[1];
3244 pFormat += 2;
3245 desc = pFormat + *(const SHORT*)pFormat;
3246 size = EmbeddedComplexSize(pStubMsg, desc);
3247 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
3248 if (m)
3250 /* for some reason interface pointers aren't generated as
3251 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3252 * they still need the derefencing treatment that pointers are
3253 * given */
3254 if (*desc == RPC_FC_IP)
3255 m(pStubMsg, *(unsigned char **)pMemory, desc);
3256 else
3257 m(pStubMsg, pMemory, desc);
3259 else FIXME("no buffersizer for embedded type %02x\n", *desc);
3260 pMemory += size;
3261 pFormat += 2;
3262 continue;
3263 case RPC_FC_PAD:
3264 break;
3265 default:
3266 FIXME("unhandled format 0x%02x\n", *pFormat);
3268 pFormat++;
3271 return pMemory;
3274 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
3275 unsigned char *pMemory,
3276 PFORMAT_STRING pFormat,
3277 PFORMAT_STRING pPointer)
3279 PFORMAT_STRING desc;
3280 NDR_FREE m;
3281 ULONG size;
3283 while (*pFormat != RPC_FC_END) {
3284 switch (*pFormat) {
3285 case RPC_FC_BYTE:
3286 case RPC_FC_CHAR:
3287 case RPC_FC_SMALL:
3288 case RPC_FC_USMALL:
3289 pMemory += 1;
3290 break;
3291 case RPC_FC_WCHAR:
3292 case RPC_FC_SHORT:
3293 case RPC_FC_USHORT:
3294 pMemory += 2;
3295 break;
3296 case RPC_FC_LONG:
3297 case RPC_FC_ULONG:
3298 case RPC_FC_ENUM16:
3299 case RPC_FC_ENUM32:
3300 case RPC_FC_FLOAT:
3301 pMemory += 4;
3302 break;
3303 case RPC_FC_INT3264:
3304 case RPC_FC_UINT3264:
3305 pMemory += sizeof(INT_PTR);
3306 break;
3307 case RPC_FC_HYPER:
3308 case RPC_FC_DOUBLE:
3309 pMemory += 8;
3310 break;
3311 case RPC_FC_RP:
3312 case RPC_FC_UP:
3313 case RPC_FC_OP:
3314 case RPC_FC_FP:
3315 case RPC_FC_POINTER:
3316 if (*pFormat != RPC_FC_POINTER)
3317 pPointer = pFormat;
3318 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3319 if (*pFormat == RPC_FC_POINTER)
3320 pPointer += 4;
3321 else
3322 pFormat += 4;
3323 pMemory += sizeof(void *);
3324 break;
3325 case RPC_FC_ALIGNM2:
3326 align_pointer(&pMemory, 2);
3327 break;
3328 case RPC_FC_ALIGNM4:
3329 align_pointer(&pMemory, 4);
3330 break;
3331 case RPC_FC_ALIGNM8:
3332 align_pointer(&pMemory, 8);
3333 break;
3334 case RPC_FC_STRUCTPAD1:
3335 case RPC_FC_STRUCTPAD2:
3336 case RPC_FC_STRUCTPAD3:
3337 case RPC_FC_STRUCTPAD4:
3338 case RPC_FC_STRUCTPAD5:
3339 case RPC_FC_STRUCTPAD6:
3340 case RPC_FC_STRUCTPAD7:
3341 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3342 break;
3343 case RPC_FC_EMBEDDED_COMPLEX:
3344 pMemory += pFormat[1];
3345 pFormat += 2;
3346 desc = pFormat + *(const SHORT*)pFormat;
3347 size = EmbeddedComplexSize(pStubMsg, desc);
3348 m = NdrFreer[*desc & NDR_TABLE_MASK];
3349 if (m)
3351 /* for some reason interface pointers aren't generated as
3352 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3353 * they still need the derefencing treatment that pointers are
3354 * given */
3355 if (*desc == RPC_FC_IP)
3356 m(pStubMsg, *(unsigned char **)pMemory, desc);
3357 else
3358 m(pStubMsg, pMemory, desc);
3360 pMemory += size;
3361 pFormat += 2;
3362 continue;
3363 case RPC_FC_PAD:
3364 break;
3365 default:
3366 FIXME("unhandled format 0x%02x\n", *pFormat);
3368 pFormat++;
3371 return pMemory;
3374 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3375 PFORMAT_STRING pFormat,
3376 PFORMAT_STRING pPointer)
3378 PFORMAT_STRING desc;
3379 ULONG size = 0;
3381 while (*pFormat != RPC_FC_END) {
3382 switch (*pFormat) {
3383 case RPC_FC_BYTE:
3384 case RPC_FC_CHAR:
3385 case RPC_FC_SMALL:
3386 case RPC_FC_USMALL:
3387 size += 1;
3388 safe_buffer_increment(pStubMsg, 1);
3389 break;
3390 case RPC_FC_WCHAR:
3391 case RPC_FC_SHORT:
3392 case RPC_FC_USHORT:
3393 size += 2;
3394 safe_buffer_increment(pStubMsg, 2);
3395 break;
3396 case RPC_FC_ENUM16:
3397 size += 4;
3398 safe_buffer_increment(pStubMsg, 2);
3399 break;
3400 case RPC_FC_LONG:
3401 case RPC_FC_ULONG:
3402 case RPC_FC_ENUM32:
3403 case RPC_FC_FLOAT:
3404 size += 4;
3405 safe_buffer_increment(pStubMsg, 4);
3406 break;
3407 case RPC_FC_INT3264:
3408 case RPC_FC_UINT3264:
3409 size += sizeof(INT_PTR);
3410 safe_buffer_increment(pStubMsg, 4);
3411 break;
3412 case RPC_FC_HYPER:
3413 case RPC_FC_DOUBLE:
3414 size += 8;
3415 safe_buffer_increment(pStubMsg, 8);
3416 break;
3417 case RPC_FC_RP:
3418 case RPC_FC_UP:
3419 case RPC_FC_OP:
3420 case RPC_FC_FP:
3421 case RPC_FC_POINTER:
3423 unsigned char *saved_buffer;
3424 int pointer_buffer_mark_set = 0;
3425 if (*pFormat != RPC_FC_POINTER)
3426 pPointer = pFormat;
3427 if (*pPointer != RPC_FC_RP)
3428 align_pointer(&pStubMsg->Buffer, 4);
3429 saved_buffer = pStubMsg->Buffer;
3430 if (pStubMsg->PointerBufferMark)
3432 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3433 pStubMsg->PointerBufferMark = NULL;
3434 pointer_buffer_mark_set = 1;
3436 else if (*pPointer != RPC_FC_RP)
3437 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3439 if (!pStubMsg->IgnoreEmbeddedPointers)
3440 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3441 if (pointer_buffer_mark_set)
3443 STD_OVERFLOW_CHECK(pStubMsg);
3444 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3445 pStubMsg->Buffer = saved_buffer;
3446 if (*pPointer != RPC_FC_RP)
3447 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3449 if (*pFormat == RPC_FC_POINTER)
3450 pPointer += 4;
3451 else
3452 pFormat += 4;
3453 size += sizeof(void *);
3454 break;
3456 case RPC_FC_ALIGNM2:
3457 align_length(&size, 2);
3458 break;
3459 case RPC_FC_ALIGNM4:
3460 align_length(&size, 4);
3461 break;
3462 case RPC_FC_ALIGNM8:
3463 align_length(&size, 8);
3464 break;
3465 case RPC_FC_STRUCTPAD1:
3466 case RPC_FC_STRUCTPAD2:
3467 case RPC_FC_STRUCTPAD3:
3468 case RPC_FC_STRUCTPAD4:
3469 case RPC_FC_STRUCTPAD5:
3470 case RPC_FC_STRUCTPAD6:
3471 case RPC_FC_STRUCTPAD7:
3472 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3473 break;
3474 case RPC_FC_EMBEDDED_COMPLEX:
3475 size += pFormat[1];
3476 pFormat += 2;
3477 desc = pFormat + *(const SHORT*)pFormat;
3478 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3479 pFormat += 2;
3480 continue;
3481 case RPC_FC_PAD:
3482 break;
3483 default:
3484 FIXME("unhandled format 0x%02x\n", *pFormat);
3486 pFormat++;
3489 return size;
3492 ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
3494 PFORMAT_STRING desc;
3495 ULONG size = 0;
3497 while (*pFormat != RPC_FC_END) {
3498 switch (*pFormat) {
3499 case RPC_FC_BYTE:
3500 case RPC_FC_CHAR:
3501 case RPC_FC_SMALL:
3502 case RPC_FC_USMALL:
3503 size += 1;
3504 break;
3505 case RPC_FC_WCHAR:
3506 case RPC_FC_SHORT:
3507 case RPC_FC_USHORT:
3508 size += 2;
3509 break;
3510 case RPC_FC_LONG:
3511 case RPC_FC_ULONG:
3512 case RPC_FC_ENUM16:
3513 case RPC_FC_ENUM32:
3514 case RPC_FC_FLOAT:
3515 size += 4;
3516 break;
3517 case RPC_FC_INT3264:
3518 case RPC_FC_UINT3264:
3519 size += sizeof(INT_PTR);
3520 break;
3521 case RPC_FC_HYPER:
3522 case RPC_FC_DOUBLE:
3523 size += 8;
3524 break;
3525 case RPC_FC_RP:
3526 case RPC_FC_UP:
3527 case RPC_FC_OP:
3528 case RPC_FC_FP:
3529 case RPC_FC_POINTER:
3530 size += sizeof(void *);
3531 if (*pFormat != RPC_FC_POINTER)
3532 pFormat += 4;
3533 break;
3534 case RPC_FC_ALIGNM2:
3535 align_length(&size, 2);
3536 break;
3537 case RPC_FC_ALIGNM4:
3538 align_length(&size, 4);
3539 break;
3540 case RPC_FC_ALIGNM8:
3541 align_length(&size, 8);
3542 break;
3543 case RPC_FC_STRUCTPAD1:
3544 case RPC_FC_STRUCTPAD2:
3545 case RPC_FC_STRUCTPAD3:
3546 case RPC_FC_STRUCTPAD4:
3547 case RPC_FC_STRUCTPAD5:
3548 case RPC_FC_STRUCTPAD6:
3549 case RPC_FC_STRUCTPAD7:
3550 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3551 break;
3552 case RPC_FC_EMBEDDED_COMPLEX:
3553 size += pFormat[1];
3554 pFormat += 2;
3555 desc = pFormat + *(const SHORT*)pFormat;
3556 size += EmbeddedComplexSize(pStubMsg, desc);
3557 pFormat += 2;
3558 continue;
3559 case RPC_FC_PAD:
3560 break;
3561 default:
3562 FIXME("unhandled format 0x%02x\n", *pFormat);
3564 pFormat++;
3567 return size;
3570 /***********************************************************************
3571 * NdrComplexStructMarshall [RPCRT4.@]
3573 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3574 unsigned char *pMemory,
3575 PFORMAT_STRING pFormat)
3577 PFORMAT_STRING conf_array = NULL;
3578 PFORMAT_STRING pointer_desc = NULL;
3579 unsigned char *OldMemory = pStubMsg->Memory;
3580 int pointer_buffer_mark_set = 0;
3581 ULONG count = 0;
3582 ULONG max_count = 0;
3583 ULONG offset = 0;
3585 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3587 if (!pStubMsg->PointerBufferMark)
3589 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3590 /* save buffer length */
3591 ULONG saved_buffer_length = pStubMsg->BufferLength;
3593 /* get the buffer pointer after complex array data, but before
3594 * pointer data */
3595 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3596 pStubMsg->IgnoreEmbeddedPointers = 1;
3597 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3598 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3600 /* save it for use by embedded pointer code later */
3601 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3602 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - pStubMsg->Buffer));
3603 pointer_buffer_mark_set = 1;
3605 /* restore the original buffer length */
3606 pStubMsg->BufferLength = saved_buffer_length;
3609 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1);
3611 pFormat += 4;
3612 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3613 pFormat += 2;
3614 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3615 pFormat += 2;
3617 pStubMsg->Memory = pMemory;
3619 if (conf_array)
3621 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3622 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3623 pMemory + struct_size, conf_array);
3624 /* these could be changed in ComplexMarshall so save them for later */
3625 max_count = pStubMsg->MaxCount;
3626 count = pStubMsg->ActualCount;
3627 offset = pStubMsg->Offset;
3630 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3632 if (conf_array)
3634 pStubMsg->MaxCount = max_count;
3635 pStubMsg->ActualCount = count;
3636 pStubMsg->Offset = offset;
3637 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3638 conf_array, TRUE /* fHasPointers */);
3641 pStubMsg->Memory = OldMemory;
3643 if (pointer_buffer_mark_set)
3645 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3646 pStubMsg->PointerBufferMark = NULL;
3649 STD_OVERFLOW_CHECK(pStubMsg);
3651 return NULL;
3654 /***********************************************************************
3655 * NdrComplexStructUnmarshall [RPCRT4.@]
3657 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3658 unsigned char **ppMemory,
3659 PFORMAT_STRING pFormat,
3660 unsigned char fMustAlloc)
3662 unsigned size = *(const WORD*)(pFormat+2);
3663 PFORMAT_STRING conf_array = NULL;
3664 PFORMAT_STRING pointer_desc = NULL;
3665 unsigned char *pMemory;
3666 int pointer_buffer_mark_set = 0;
3667 ULONG count = 0;
3668 ULONG max_count = 0;
3669 ULONG offset = 0;
3670 ULONG array_size = 0;
3672 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3674 if (!pStubMsg->PointerBufferMark)
3676 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3677 /* save buffer pointer */
3678 unsigned char *saved_buffer = pStubMsg->Buffer;
3680 /* get the buffer pointer after complex array data, but before
3681 * pointer data */
3682 pStubMsg->IgnoreEmbeddedPointers = 1;
3683 NdrComplexStructMemorySize(pStubMsg, pFormat);
3684 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3686 /* save it for use by embedded pointer code later */
3687 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3688 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - saved_buffer));
3689 pointer_buffer_mark_set = 1;
3691 /* restore the original buffer */
3692 pStubMsg->Buffer = saved_buffer;
3695 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3697 pFormat += 4;
3698 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3699 pFormat += 2;
3700 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3701 pFormat += 2;
3703 if (conf_array)
3705 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3706 size += array_size;
3708 /* these could be changed in ComplexMarshall so save them for later */
3709 max_count = pStubMsg->MaxCount;
3710 count = pStubMsg->ActualCount;
3711 offset = pStubMsg->Offset;
3714 if (!fMustAlloc && !*ppMemory)
3715 fMustAlloc = TRUE;
3716 if (fMustAlloc)
3717 *ppMemory = NdrAllocate(pStubMsg, size);
3719 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3721 if (conf_array)
3723 pStubMsg->MaxCount = max_count;
3724 pStubMsg->ActualCount = count;
3725 pStubMsg->Offset = offset;
3726 if (fMustAlloc)
3727 memset(pMemory, 0, array_size);
3728 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3729 conf_array, FALSE,
3730 FALSE /* fUseBufferMemoryServer */,
3731 TRUE /* fUnmarshall */);
3734 if (pointer_buffer_mark_set)
3736 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3737 pStubMsg->PointerBufferMark = NULL;
3740 return NULL;
3743 /***********************************************************************
3744 * NdrComplexStructBufferSize [RPCRT4.@]
3746 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3747 unsigned char *pMemory,
3748 PFORMAT_STRING pFormat)
3750 PFORMAT_STRING conf_array = NULL;
3751 PFORMAT_STRING pointer_desc = NULL;
3752 unsigned char *OldMemory = pStubMsg->Memory;
3753 int pointer_length_set = 0;
3754 ULONG count = 0;
3755 ULONG max_count = 0;
3756 ULONG offset = 0;
3758 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3760 align_length(&pStubMsg->BufferLength, pFormat[1] + 1);
3762 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3764 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3765 ULONG saved_buffer_length = pStubMsg->BufferLength;
3767 /* get the buffer length after complex struct data, but before
3768 * pointer data */
3769 pStubMsg->IgnoreEmbeddedPointers = 1;
3770 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3771 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3773 /* save it for use by embedded pointer code later */
3774 pStubMsg->PointerLength = pStubMsg->BufferLength;
3775 pointer_length_set = 1;
3776 TRACE("difference = 0x%x\n", pStubMsg->PointerLength - saved_buffer_length);
3778 /* restore the original buffer length */
3779 pStubMsg->BufferLength = saved_buffer_length;
3782 pFormat += 4;
3783 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3784 pFormat += 2;
3785 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3786 pFormat += 2;
3788 pStubMsg->Memory = pMemory;
3790 if (conf_array)
3792 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3793 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3794 conf_array);
3796 /* these could be changed in ComplexMarshall so save them for later */
3797 max_count = pStubMsg->MaxCount;
3798 count = pStubMsg->ActualCount;
3799 offset = pStubMsg->Offset;
3802 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3804 if (conf_array)
3806 pStubMsg->MaxCount = max_count;
3807 pStubMsg->ActualCount = count;
3808 pStubMsg->Offset = offset;
3809 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3810 TRUE /* fHasPointers */);
3813 pStubMsg->Memory = OldMemory;
3815 if(pointer_length_set)
3817 pStubMsg->BufferLength = pStubMsg->PointerLength;
3818 pStubMsg->PointerLength = 0;
3823 /***********************************************************************
3824 * NdrComplexStructMemorySize [RPCRT4.@]
3826 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3827 PFORMAT_STRING pFormat)
3829 unsigned size = *(const WORD*)(pFormat+2);
3830 PFORMAT_STRING conf_array = NULL;
3831 PFORMAT_STRING pointer_desc = NULL;
3832 ULONG count = 0;
3833 ULONG max_count = 0;
3834 ULONG offset = 0;
3836 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3838 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3840 pFormat += 4;
3841 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3842 pFormat += 2;
3843 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3844 pFormat += 2;
3846 if (conf_array)
3848 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3850 /* these could be changed in ComplexStructMemorySize so save them for
3851 * later */
3852 max_count = pStubMsg->MaxCount;
3853 count = pStubMsg->ActualCount;
3854 offset = pStubMsg->Offset;
3857 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3859 if (conf_array)
3861 pStubMsg->MaxCount = max_count;
3862 pStubMsg->ActualCount = count;
3863 pStubMsg->Offset = offset;
3864 array_memory_size(conf_array[0], pStubMsg, conf_array,
3865 TRUE /* fHasPointers */);
3868 return size;
3871 /***********************************************************************
3872 * NdrComplexStructFree [RPCRT4.@]
3874 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3875 unsigned char *pMemory,
3876 PFORMAT_STRING pFormat)
3878 PFORMAT_STRING conf_array = NULL;
3879 PFORMAT_STRING pointer_desc = NULL;
3880 unsigned char *OldMemory = pStubMsg->Memory;
3882 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3884 pFormat += 4;
3885 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3886 pFormat += 2;
3887 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3888 pFormat += 2;
3890 pStubMsg->Memory = pMemory;
3892 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3894 if (conf_array)
3895 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3896 TRUE /* fHasPointers */);
3898 pStubMsg->Memory = OldMemory;
3901 /***********************************************************************
3902 * NdrConformantArrayMarshall [RPCRT4.@]
3904 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3905 unsigned char *pMemory,
3906 PFORMAT_STRING pFormat)
3908 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3909 if (pFormat[0] != RPC_FC_CARRAY)
3911 ERR("invalid format = 0x%x\n", pFormat[0]);
3912 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3915 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory,
3916 pFormat);
3917 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3918 TRUE /* fHasPointers */);
3920 return NULL;
3923 /***********************************************************************
3924 * NdrConformantArrayUnmarshall [RPCRT4.@]
3926 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3927 unsigned char **ppMemory,
3928 PFORMAT_STRING pFormat,
3929 unsigned char fMustAlloc)
3931 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3932 if (pFormat[0] != RPC_FC_CARRAY)
3934 ERR("invalid format = 0x%x\n", pFormat[0]);
3935 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3938 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3939 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat,
3940 fMustAlloc,
3941 TRUE /* fUseBufferMemoryServer */,
3942 TRUE /* fUnmarshall */);
3944 return NULL;
3947 /***********************************************************************
3948 * NdrConformantArrayBufferSize [RPCRT4.@]
3950 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3951 unsigned char *pMemory,
3952 PFORMAT_STRING pFormat)
3954 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3955 if (pFormat[0] != RPC_FC_CARRAY)
3957 ERR("invalid format = 0x%x\n", pFormat[0]);
3958 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3961 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat);
3962 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3963 TRUE /* fHasPointers */);
3966 /***********************************************************************
3967 * NdrConformantArrayMemorySize [RPCRT4.@]
3969 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3970 PFORMAT_STRING pFormat)
3972 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3973 if (pFormat[0] != RPC_FC_CARRAY)
3975 ERR("invalid format = 0x%x\n", pFormat[0]);
3976 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3979 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3980 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
3982 return pStubMsg->MemorySize;
3985 /***********************************************************************
3986 * NdrConformantArrayFree [RPCRT4.@]
3988 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3989 unsigned char *pMemory,
3990 PFORMAT_STRING pFormat)
3992 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3993 if (pFormat[0] != RPC_FC_CARRAY)
3995 ERR("invalid format = 0x%x\n", pFormat[0]);
3996 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3999 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
4000 TRUE /* fHasPointers */);
4004 /***********************************************************************
4005 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
4007 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
4008 unsigned char* pMemory,
4009 PFORMAT_STRING pFormat )
4011 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4013 if (pFormat[0] != RPC_FC_CVARRAY)
4015 ERR("invalid format type %x\n", pFormat[0]);
4016 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4017 return NULL;
4020 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
4021 pFormat);
4022 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory,
4023 pFormat, TRUE /* fHasPointers */);
4025 return NULL;
4029 /***********************************************************************
4030 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
4032 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
4033 unsigned char** ppMemory,
4034 PFORMAT_STRING pFormat,
4035 unsigned char fMustAlloc )
4037 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4039 if (pFormat[0] != RPC_FC_CVARRAY)
4041 ERR("invalid format type %x\n", pFormat[0]);
4042 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4043 return NULL;
4046 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
4047 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory,
4048 pFormat, fMustAlloc,
4049 TRUE /* fUseBufferMemoryServer */,
4050 TRUE /* fUnmarshall */);
4052 return NULL;
4056 /***********************************************************************
4057 * NdrConformantVaryingArrayFree [RPCRT4.@]
4059 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
4060 unsigned char* pMemory,
4061 PFORMAT_STRING pFormat )
4063 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4065 if (pFormat[0] != RPC_FC_CVARRAY)
4067 ERR("invalid format type %x\n", pFormat[0]);
4068 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4069 return;
4072 array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
4073 TRUE /* fHasPointers */);
4077 /***********************************************************************
4078 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
4080 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
4081 unsigned char* pMemory, PFORMAT_STRING pFormat )
4083 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4085 if (pFormat[0] != RPC_FC_CVARRAY)
4087 ERR("invalid format type %x\n", pFormat[0]);
4088 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4089 return;
4092 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
4093 pFormat);
4094 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
4095 TRUE /* fHasPointers */);
4099 /***********************************************************************
4100 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
4102 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
4103 PFORMAT_STRING pFormat )
4105 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4107 if (pFormat[0] != RPC_FC_CVARRAY)
4109 ERR("invalid format type %x\n", pFormat[0]);
4110 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4111 return pStubMsg->MemorySize;
4114 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
4115 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat,
4116 TRUE /* fHasPointers */);
4118 return pStubMsg->MemorySize;
4122 /***********************************************************************
4123 * NdrComplexArrayMarshall [RPCRT4.@]
4125 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4126 unsigned char *pMemory,
4127 PFORMAT_STRING pFormat)
4129 int pointer_buffer_mark_set = 0;
4131 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4133 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4135 ERR("invalid format type %x\n", pFormat[0]);
4136 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4137 return NULL;
4140 if (!pStubMsg->PointerBufferMark)
4142 /* save buffer fields that may be changed by buffer sizer functions
4143 * and that may be needed later on */
4144 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4145 ULONG saved_buffer_length = pStubMsg->BufferLength;
4146 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4147 ULONG saved_offset = pStubMsg->Offset;
4148 ULONG saved_actual_count = pStubMsg->ActualCount;
4150 /* get the buffer pointer after complex array data, but before
4151 * pointer data */
4152 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
4153 pStubMsg->IgnoreEmbeddedPointers = 1;
4154 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4155 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4157 /* save it for use by embedded pointer code later */
4158 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
4159 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer));
4160 pointer_buffer_mark_set = 1;
4162 /* restore fields */
4163 pStubMsg->ActualCount = saved_actual_count;
4164 pStubMsg->Offset = saved_offset;
4165 pStubMsg->MaxCount = saved_max_count;
4166 pStubMsg->BufferLength = saved_buffer_length;
4169 array_compute_and_write_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4170 array_write_variance_and_marshall(RPC_FC_BOGUS_ARRAY, pStubMsg,
4171 pMemory, pFormat, TRUE /* fHasPointers */);
4173 STD_OVERFLOW_CHECK(pStubMsg);
4175 if (pointer_buffer_mark_set)
4177 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4178 pStubMsg->PointerBufferMark = NULL;
4181 return NULL;
4184 /***********************************************************************
4185 * NdrComplexArrayUnmarshall [RPCRT4.@]
4187 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4188 unsigned char **ppMemory,
4189 PFORMAT_STRING pFormat,
4190 unsigned char fMustAlloc)
4192 unsigned char *saved_buffer;
4193 int pointer_buffer_mark_set = 0;
4194 int saved_ignore_embedded;
4196 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4198 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4200 ERR("invalid format type %x\n", pFormat[0]);
4201 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4202 return NULL;
4205 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4206 /* save buffer pointer */
4207 saved_buffer = pStubMsg->Buffer;
4208 /* get the buffer pointer after complex array data, but before
4209 * pointer data */
4210 pStubMsg->IgnoreEmbeddedPointers = 1;
4211 pStubMsg->MemorySize = 0;
4212 NdrComplexArrayMemorySize(pStubMsg, pFormat);
4213 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4215 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - saved_buffer));
4216 if (!pStubMsg->PointerBufferMark)
4218 /* save it for use by embedded pointer code later */
4219 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4220 pointer_buffer_mark_set = 1;
4222 /* restore the original buffer */
4223 pStubMsg->Buffer = saved_buffer;
4225 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
4226 array_read_variance_and_unmarshall(RPC_FC_BOGUS_ARRAY, pStubMsg, ppMemory, pFormat, fMustAlloc,
4227 TRUE /* fUseBufferMemoryServer */, TRUE /* fUnmarshall */);
4229 if (pointer_buffer_mark_set)
4231 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4232 pStubMsg->PointerBufferMark = NULL;
4235 return NULL;
4238 /***********************************************************************
4239 * NdrComplexArrayBufferSize [RPCRT4.@]
4241 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4242 unsigned char *pMemory,
4243 PFORMAT_STRING pFormat)
4245 int pointer_length_set = 0;
4247 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4249 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4251 ERR("invalid format type %x\n", pFormat[0]);
4252 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4253 return;
4256 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
4258 /* save buffer fields that may be changed by buffer sizer functions
4259 * and that may be needed later on */
4260 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4261 ULONG saved_buffer_length = pStubMsg->BufferLength;
4262 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4263 ULONG saved_offset = pStubMsg->Offset;
4264 ULONG saved_actual_count = pStubMsg->ActualCount;
4266 /* get the buffer pointer after complex array data, but before
4267 * pointer data */
4268 pStubMsg->IgnoreEmbeddedPointers = 1;
4269 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4270 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4272 /* save it for use by embedded pointer code later */
4273 pStubMsg->PointerLength = pStubMsg->BufferLength;
4274 pointer_length_set = 1;
4276 /* restore fields */
4277 pStubMsg->ActualCount = saved_actual_count;
4278 pStubMsg->Offset = saved_offset;
4279 pStubMsg->MaxCount = saved_max_count;
4280 pStubMsg->BufferLength = saved_buffer_length;
4283 array_compute_and_size_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4284 array_buffer_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat, TRUE /* fHasPointers */);
4286 if(pointer_length_set)
4288 pStubMsg->BufferLength = pStubMsg->PointerLength;
4289 pStubMsg->PointerLength = 0;
4293 /***********************************************************************
4294 * NdrComplexArrayMemorySize [RPCRT4.@]
4296 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4297 PFORMAT_STRING pFormat)
4299 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4301 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4303 ERR("invalid format type %x\n", pFormat[0]);
4304 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4305 return 0;
4308 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
4309 array_memory_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
4310 return pStubMsg->MemorySize;
4313 /***********************************************************************
4314 * NdrComplexArrayFree [RPCRT4.@]
4316 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4317 unsigned char *pMemory,
4318 PFORMAT_STRING pFormat)
4320 ULONG i, count, def;
4322 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4324 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4326 ERR("invalid format type %x\n", pFormat[0]);
4327 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4328 return;
4331 def = *(const WORD*)&pFormat[2];
4332 pFormat += 4;
4334 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4335 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4337 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4338 TRACE("variance = %d\n", pStubMsg->ActualCount);
4340 count = pStubMsg->ActualCount;
4341 for (i = 0; i < count; i++)
4342 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4345 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4346 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4347 USER_MARSHAL_CB *umcb)
4349 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4350 pStubMsg->RpcMsg->DataRepresentation);
4351 umcb->pStubMsg = pStubMsg;
4352 umcb->pReserve = NULL;
4353 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4354 umcb->CBType = cbtype;
4355 umcb->pFormat = pFormat;
4356 umcb->pTypeFormat = NULL /* FIXME */;
4359 #define USER_MARSHAL_PTR_PREFIX \
4360 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4361 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4363 /***********************************************************************
4364 * NdrUserMarshalMarshall [RPCRT4.@]
4366 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4367 unsigned char *pMemory,
4368 PFORMAT_STRING pFormat)
4370 unsigned flags = pFormat[1];
4371 unsigned index = *(const WORD*)&pFormat[2];
4372 unsigned char *saved_buffer = NULL;
4373 USER_MARSHAL_CB umcb;
4375 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4376 TRACE("index=%d\n", index);
4378 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4380 if (flags & USER_MARSHAL_POINTER)
4382 align_pointer_clear(&pStubMsg->Buffer, 4);
4383 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4384 pStubMsg->Buffer += 4;
4385 if (pStubMsg->PointerBufferMark)
4387 saved_buffer = pStubMsg->Buffer;
4388 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4389 pStubMsg->PointerBufferMark = NULL;
4391 align_pointer_clear(&pStubMsg->Buffer, 8);
4393 else
4394 align_pointer_clear(&pStubMsg->Buffer, (flags & 0xf) + 1);
4396 pStubMsg->Buffer =
4397 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4398 &umcb.Flags, pStubMsg->Buffer, pMemory);
4400 if (saved_buffer)
4402 STD_OVERFLOW_CHECK(pStubMsg);
4403 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4404 pStubMsg->Buffer = saved_buffer;
4407 STD_OVERFLOW_CHECK(pStubMsg);
4409 return NULL;
4412 /***********************************************************************
4413 * NdrUserMarshalUnmarshall [RPCRT4.@]
4415 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4416 unsigned char **ppMemory,
4417 PFORMAT_STRING pFormat,
4418 unsigned char fMustAlloc)
4420 unsigned flags = pFormat[1];
4421 unsigned index = *(const WORD*)&pFormat[2];
4422 DWORD memsize = *(const WORD*)&pFormat[4];
4423 unsigned char *saved_buffer = NULL;
4424 USER_MARSHAL_CB umcb;
4426 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4427 TRACE("index=%d\n", index);
4429 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4431 if (flags & USER_MARSHAL_POINTER)
4433 align_pointer(&pStubMsg->Buffer, 4);
4434 /* skip pointer prefix */
4435 pStubMsg->Buffer += 4;
4436 if (pStubMsg->PointerBufferMark)
4438 saved_buffer = pStubMsg->Buffer;
4439 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4440 pStubMsg->PointerBufferMark = NULL;
4442 align_pointer(&pStubMsg->Buffer, 8);
4444 else
4445 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4447 if (!fMustAlloc && !*ppMemory)
4448 fMustAlloc = TRUE;
4449 if (fMustAlloc)
4451 *ppMemory = NdrAllocate(pStubMsg, memsize);
4452 memset(*ppMemory, 0, memsize);
4455 pStubMsg->Buffer =
4456 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4457 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4459 if (saved_buffer)
4461 STD_OVERFLOW_CHECK(pStubMsg);
4462 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4463 pStubMsg->Buffer = saved_buffer;
4466 return NULL;
4469 /***********************************************************************
4470 * NdrUserMarshalBufferSize [RPCRT4.@]
4472 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4473 unsigned char *pMemory,
4474 PFORMAT_STRING pFormat)
4476 unsigned flags = pFormat[1];
4477 unsigned index = *(const WORD*)&pFormat[2];
4478 DWORD bufsize = *(const WORD*)&pFormat[6];
4479 USER_MARSHAL_CB umcb;
4480 ULONG saved_buffer_length = 0;
4482 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4483 TRACE("index=%d\n", index);
4485 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4487 if (flags & USER_MARSHAL_POINTER)
4489 align_length(&pStubMsg->BufferLength, 4);
4490 /* skip pointer prefix */
4491 safe_buffer_length_increment(pStubMsg, 4);
4492 if (pStubMsg->IgnoreEmbeddedPointers)
4493 return;
4494 if (pStubMsg->PointerLength)
4496 saved_buffer_length = pStubMsg->BufferLength;
4497 pStubMsg->BufferLength = pStubMsg->PointerLength;
4498 pStubMsg->PointerLength = 0;
4500 align_length(&pStubMsg->BufferLength, 8);
4502 else
4503 align_length(&pStubMsg->BufferLength, (flags & 0xf) + 1);
4505 if (bufsize) {
4506 TRACE("size=%d\n", bufsize);
4507 safe_buffer_length_increment(pStubMsg, bufsize);
4509 else
4510 pStubMsg->BufferLength =
4511 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4512 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4514 if (saved_buffer_length)
4516 pStubMsg->PointerLength = pStubMsg->BufferLength;
4517 pStubMsg->BufferLength = saved_buffer_length;
4522 /***********************************************************************
4523 * NdrUserMarshalMemorySize [RPCRT4.@]
4525 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4526 PFORMAT_STRING pFormat)
4528 unsigned flags = pFormat[1];
4529 unsigned index = *(const WORD*)&pFormat[2];
4530 DWORD memsize = *(const WORD*)&pFormat[4];
4531 DWORD bufsize = *(const WORD*)&pFormat[6];
4533 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4534 TRACE("index=%d\n", index);
4536 pStubMsg->MemorySize += memsize;
4538 if (flags & USER_MARSHAL_POINTER)
4540 align_pointer(&pStubMsg->Buffer, 4);
4541 /* skip pointer prefix */
4542 pStubMsg->Buffer += 4;
4543 if (pStubMsg->IgnoreEmbeddedPointers)
4544 return pStubMsg->MemorySize;
4545 align_pointer(&pStubMsg->Buffer, 8);
4547 else
4548 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4550 if (!bufsize)
4551 FIXME("not implemented for varying buffer size\n");
4553 pStubMsg->Buffer += bufsize;
4555 return pStubMsg->MemorySize;
4558 /***********************************************************************
4559 * NdrUserMarshalFree [RPCRT4.@]
4561 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4562 unsigned char *pMemory,
4563 PFORMAT_STRING pFormat)
4565 /* unsigned flags = pFormat[1]; */
4566 unsigned index = *(const WORD*)&pFormat[2];
4567 USER_MARSHAL_CB umcb;
4569 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4570 TRACE("index=%d\n", index);
4572 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4574 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4575 &umcb.Flags, pMemory);
4578 /***********************************************************************
4579 * NdrGetUserMarshalInfo [RPCRT4.@]
4581 RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi)
4583 USER_MARSHAL_CB *umcb = CONTAINING_RECORD(flags, USER_MARSHAL_CB, Flags);
4585 TRACE("(%p,%u,%p)\n", flags, level, umi);
4587 if (level != 1)
4588 return RPC_S_INVALID_ARG;
4590 memset(&umi->u1.Level1, 0, sizeof(umi->u1.Level1));
4591 umi->InformationLevel = level;
4593 if (umcb->Signature != USER_MARSHAL_CB_SIGNATURE)
4594 return RPC_S_INVALID_ARG;
4596 umi->u1.Level1.pfnAllocate = umcb->pStubMsg->pfnAllocate;
4597 umi->u1.Level1.pfnFree = umcb->pStubMsg->pfnFree;
4598 umi->u1.Level1.pRpcChannelBuffer = umcb->pStubMsg->pRpcChannelBuffer;
4600 switch (umcb->CBType)
4602 case USER_MARSHAL_CB_MARSHALL:
4603 case USER_MARSHAL_CB_UNMARSHALL:
4605 RPC_MESSAGE *msg = umcb->pStubMsg->RpcMsg;
4606 unsigned char *buffer_start = msg->Buffer;
4607 unsigned char *buffer_end =
4608 (unsigned char *)msg->Buffer + msg->BufferLength;
4610 if (umcb->pStubMsg->Buffer < buffer_start ||
4611 umcb->pStubMsg->Buffer > buffer_end)
4612 return ERROR_INVALID_USER_BUFFER;
4614 umi->u1.Level1.Buffer = umcb->pStubMsg->Buffer;
4615 umi->u1.Level1.BufferSize = buffer_end - umcb->pStubMsg->Buffer;
4616 break;
4618 case USER_MARSHAL_CB_BUFFER_SIZE:
4619 case USER_MARSHAL_CB_FREE:
4620 break;
4621 default:
4622 WARN("unrecognised CBType %d\n", umcb->CBType);
4625 return RPC_S_OK;
4628 /***********************************************************************
4629 * NdrClearOutParameters [RPCRT4.@]
4631 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4632 PFORMAT_STRING pFormat,
4633 void *ArgAddr)
4635 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4638 /***********************************************************************
4639 * NdrConvert [RPCRT4.@]
4641 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4643 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4644 /* FIXME: since this stub doesn't do any converting, the proper behavior
4645 is to raise an exception */
4648 /***********************************************************************
4649 * NdrConvert2 [RPCRT4.@]
4651 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4653 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4654 pStubMsg, pFormat, NumberParams);
4655 /* FIXME: since this stub doesn't do any converting, the proper behavior
4656 is to raise an exception */
4659 #include "pshpack1.h"
4660 typedef struct _NDR_CSTRUCT_FORMAT
4662 unsigned char type;
4663 unsigned char alignment;
4664 unsigned short memory_size;
4665 short offset_to_array_description;
4666 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4667 #include "poppack.h"
4669 /***********************************************************************
4670 * NdrConformantStructMarshall [RPCRT4.@]
4672 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4673 unsigned char *pMemory,
4674 PFORMAT_STRING pFormat)
4676 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4677 PFORMAT_STRING pCArrayFormat;
4678 ULONG esize, bufsize;
4680 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4682 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4683 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4685 ERR("invalid format type %x\n", pCStructFormat->type);
4686 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4687 return NULL;
4690 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4691 pCStructFormat->offset_to_array_description;
4692 if (*pCArrayFormat != RPC_FC_CARRAY)
4694 ERR("invalid array format type %x\n", pCStructFormat->type);
4695 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4696 return NULL;
4698 esize = *(const WORD*)(pCArrayFormat+2);
4700 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4701 pCArrayFormat + 4, 0);
4703 WriteConformance(pStubMsg);
4705 align_pointer_clear(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4707 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4709 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4710 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4712 ERR("integer overflow of memory_size %u with bufsize %u\n",
4713 pCStructFormat->memory_size, bufsize);
4714 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4716 /* copy constant sized part of struct */
4717 pStubMsg->BufferMark = pStubMsg->Buffer;
4718 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4720 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4721 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4723 return NULL;
4726 /***********************************************************************
4727 * NdrConformantStructUnmarshall [RPCRT4.@]
4729 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4730 unsigned char **ppMemory,
4731 PFORMAT_STRING pFormat,
4732 unsigned char fMustAlloc)
4734 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4735 PFORMAT_STRING pCArrayFormat;
4736 ULONG esize, bufsize;
4737 unsigned char *saved_buffer;
4739 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4741 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4742 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4744 ERR("invalid format type %x\n", pCStructFormat->type);
4745 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4746 return NULL;
4748 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4749 pCStructFormat->offset_to_array_description;
4750 if (*pCArrayFormat != RPC_FC_CARRAY)
4752 ERR("invalid array format type %x\n", pCStructFormat->type);
4753 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4754 return NULL;
4756 esize = *(const WORD*)(pCArrayFormat+2);
4758 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4760 align_pointer(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4762 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4764 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4765 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4767 ERR("integer overflow of memory_size %u with bufsize %u\n",
4768 pCStructFormat->memory_size, bufsize);
4769 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4772 if (fMustAlloc)
4774 SIZE_T size = pCStructFormat->memory_size + bufsize;
4775 *ppMemory = NdrAllocate(pStubMsg, size);
4777 else
4779 if (!pStubMsg->IsClient && !*ppMemory)
4780 /* for servers, we just point straight into the RPC buffer */
4781 *ppMemory = pStubMsg->Buffer;
4784 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4785 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4786 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4787 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4789 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4790 if (*ppMemory != saved_buffer)
4791 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4793 return NULL;
4796 /***********************************************************************
4797 * NdrConformantStructBufferSize [RPCRT4.@]
4799 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4800 unsigned char *pMemory,
4801 PFORMAT_STRING pFormat)
4803 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4804 PFORMAT_STRING pCArrayFormat;
4805 ULONG esize;
4807 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4809 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4810 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4812 ERR("invalid format type %x\n", pCStructFormat->type);
4813 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4814 return;
4816 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4817 pCStructFormat->offset_to_array_description;
4818 if (*pCArrayFormat != RPC_FC_CARRAY)
4820 ERR("invalid array format type %x\n", pCStructFormat->type);
4821 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4822 return;
4824 esize = *(const WORD*)(pCArrayFormat+2);
4826 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4827 SizeConformance(pStubMsg);
4829 align_length(&pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4831 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4833 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4834 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4836 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4837 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4840 /***********************************************************************
4841 * NdrConformantStructMemorySize [RPCRT4.@]
4843 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4844 PFORMAT_STRING pFormat)
4846 FIXME("stub\n");
4847 return 0;
4850 /***********************************************************************
4851 * NdrConformantStructFree [RPCRT4.@]
4853 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4854 unsigned char *pMemory,
4855 PFORMAT_STRING pFormat)
4857 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4858 PFORMAT_STRING pCArrayFormat;
4860 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4862 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4863 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4865 ERR("invalid format type %x\n", pCStructFormat->type);
4866 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4867 return;
4870 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4871 pCStructFormat->offset_to_array_description;
4872 if (*pCArrayFormat != RPC_FC_CARRAY)
4874 ERR("invalid array format type %x\n", pCStructFormat->type);
4875 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4876 return;
4879 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4880 pCArrayFormat + 4, 0);
4882 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4884 /* copy constant sized part of struct */
4885 pStubMsg->BufferMark = pStubMsg->Buffer;
4887 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4888 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4891 /***********************************************************************
4892 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4894 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4895 unsigned char *pMemory,
4896 PFORMAT_STRING pFormat)
4898 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4899 PFORMAT_STRING pCVArrayFormat;
4901 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4903 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4904 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4906 ERR("invalid format type %x\n", pCVStructFormat->type);
4907 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4908 return NULL;
4911 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4912 pCVStructFormat->offset_to_array_description;
4914 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4915 pMemory + pCVStructFormat->memory_size,
4916 pCVArrayFormat);
4918 align_pointer_clear(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4920 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4922 /* write constant sized part */
4923 pStubMsg->BufferMark = pStubMsg->Buffer;
4924 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4926 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4927 pMemory + pCVStructFormat->memory_size,
4928 pCVArrayFormat, FALSE /* fHasPointers */);
4930 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4932 return NULL;
4935 /***********************************************************************
4936 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4938 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4939 unsigned char **ppMemory,
4940 PFORMAT_STRING pFormat,
4941 unsigned char fMustAlloc)
4943 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4944 PFORMAT_STRING pCVArrayFormat;
4945 ULONG memsize, bufsize;
4946 unsigned char *saved_buffer, *saved_array_buffer;
4947 ULONG offset;
4948 unsigned char *array_memory;
4950 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4952 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4953 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4955 ERR("invalid format type %x\n", pCVStructFormat->type);
4956 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4957 return NULL;
4960 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4961 pCVStructFormat->offset_to_array_description;
4963 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4964 pCVArrayFormat);
4966 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4968 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4970 /* work out how much memory to allocate if we need to do so */
4971 if (!fMustAlloc && !*ppMemory)
4972 fMustAlloc = TRUE;
4973 if (fMustAlloc)
4975 SIZE_T size = pCVStructFormat->memory_size + memsize;
4976 *ppMemory = NdrAllocate(pStubMsg, size);
4979 /* mark the start of the constant data */
4980 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4981 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4983 array_memory = *ppMemory + pCVStructFormat->memory_size;
4984 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
4985 &array_memory, pCVArrayFormat,
4986 FALSE /* fMustAlloc */,
4987 FALSE /* fUseServerBufferMemory */,
4988 FALSE /* fUnmarshall */);
4990 /* save offset in case unmarshalling pointers changes it */
4991 offset = pStubMsg->Offset;
4993 /* mark the start of the array data */
4994 saved_array_buffer = pStubMsg->Buffer;
4995 safe_buffer_increment(pStubMsg, bufsize);
4997 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4999 /* copy the constant data */
5000 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
5001 /* copy the array data */
5002 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
5003 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
5004 saved_array_buffer, bufsize);
5006 if (*pCVArrayFormat == RPC_FC_C_CSTRING)
5007 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
5008 else if (*pCVArrayFormat == RPC_FC_C_WSTRING)
5009 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
5011 return NULL;
5014 /***********************************************************************
5015 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
5017 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5018 unsigned char *pMemory,
5019 PFORMAT_STRING pFormat)
5021 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5022 PFORMAT_STRING pCVArrayFormat;
5024 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5026 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5027 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5029 ERR("invalid format type %x\n", pCVStructFormat->type);
5030 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5031 return;
5034 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5035 pCVStructFormat->offset_to_array_description;
5036 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
5037 pMemory + pCVStructFormat->memory_size,
5038 pCVArrayFormat);
5040 align_length(&pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
5042 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5044 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
5046 array_buffer_size(*pCVArrayFormat, pStubMsg,
5047 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5048 FALSE /* fHasPointers */);
5050 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5053 /***********************************************************************
5054 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
5056 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5057 PFORMAT_STRING pFormat)
5059 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5060 PFORMAT_STRING pCVArrayFormat;
5062 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5064 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5065 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5067 ERR("invalid format type %x\n", pCVStructFormat->type);
5068 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5069 return 0;
5072 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5073 pCVStructFormat->offset_to_array_description;
5074 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
5076 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
5078 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5080 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
5081 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
5082 FALSE /* fHasPointers */);
5084 pStubMsg->MemorySize += pCVStructFormat->memory_size;
5086 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5088 return pStubMsg->MemorySize;
5091 /***********************************************************************
5092 * NdrConformantVaryingStructFree [RPCRT4.@]
5094 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
5095 unsigned char *pMemory,
5096 PFORMAT_STRING pFormat)
5098 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5099 PFORMAT_STRING pCVArrayFormat;
5101 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5103 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5104 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5106 ERR("invalid format type %x\n", pCVStructFormat->type);
5107 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5108 return;
5111 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5112 pCVStructFormat->offset_to_array_description;
5113 array_free(*pCVArrayFormat, pStubMsg,
5114 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5115 FALSE /* fHasPointers */);
5117 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5119 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5122 #include "pshpack1.h"
5123 typedef struct
5125 unsigned char type;
5126 unsigned char alignment;
5127 unsigned short total_size;
5128 } NDR_SMFARRAY_FORMAT;
5130 typedef struct
5132 unsigned char type;
5133 unsigned char alignment;
5134 ULONG total_size;
5135 } NDR_LGFARRAY_FORMAT;
5136 #include "poppack.h"
5138 /***********************************************************************
5139 * NdrFixedArrayMarshall [RPCRT4.@]
5141 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5142 unsigned char *pMemory,
5143 PFORMAT_STRING pFormat)
5145 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5146 ULONG total_size;
5148 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5150 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5151 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5153 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5154 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5155 return NULL;
5158 align_pointer_clear(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5160 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5162 total_size = pSmFArrayFormat->total_size;
5163 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5165 else
5167 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5168 total_size = pLgFArrayFormat->total_size;
5169 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5172 pStubMsg->BufferMark = pStubMsg->Buffer;
5173 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
5175 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5177 return NULL;
5180 /***********************************************************************
5181 * NdrFixedArrayUnmarshall [RPCRT4.@]
5183 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5184 unsigned char **ppMemory,
5185 PFORMAT_STRING pFormat,
5186 unsigned char fMustAlloc)
5188 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5189 ULONG total_size;
5190 unsigned char *saved_buffer;
5192 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5194 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5195 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5197 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5198 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5199 return NULL;
5202 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5204 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5206 total_size = pSmFArrayFormat->total_size;
5207 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5209 else
5211 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5212 total_size = pLgFArrayFormat->total_size;
5213 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5216 if (fMustAlloc)
5217 *ppMemory = NdrAllocate(pStubMsg, total_size);
5218 else
5220 if (!pStubMsg->IsClient && !*ppMemory)
5221 /* for servers, we just point straight into the RPC buffer */
5222 *ppMemory = pStubMsg->Buffer;
5225 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5226 safe_buffer_increment(pStubMsg, total_size);
5227 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5229 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
5230 if (*ppMemory != saved_buffer)
5231 memcpy(*ppMemory, saved_buffer, total_size);
5233 return NULL;
5236 /***********************************************************************
5237 * NdrFixedArrayBufferSize [RPCRT4.@]
5239 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5240 unsigned char *pMemory,
5241 PFORMAT_STRING pFormat)
5243 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5244 ULONG total_size;
5246 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5248 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5249 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5251 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5252 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5253 return;
5256 align_length(&pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
5258 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5260 total_size = pSmFArrayFormat->total_size;
5261 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5263 else
5265 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5266 total_size = pLgFArrayFormat->total_size;
5267 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5269 safe_buffer_length_increment(pStubMsg, total_size);
5271 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5274 /***********************************************************************
5275 * NdrFixedArrayMemorySize [RPCRT4.@]
5277 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5278 PFORMAT_STRING pFormat)
5280 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5281 ULONG total_size;
5283 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5285 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5286 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5288 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5289 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5290 return 0;
5293 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5295 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5297 total_size = pSmFArrayFormat->total_size;
5298 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5300 else
5302 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5303 total_size = pLgFArrayFormat->total_size;
5304 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5306 pStubMsg->BufferMark = pStubMsg->Buffer;
5307 safe_buffer_increment(pStubMsg, total_size);
5308 pStubMsg->MemorySize += total_size;
5310 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5312 return total_size;
5315 /***********************************************************************
5316 * NdrFixedArrayFree [RPCRT4.@]
5318 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5319 unsigned char *pMemory,
5320 PFORMAT_STRING pFormat)
5322 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5324 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5326 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5327 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5329 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5330 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5331 return;
5334 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5335 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5336 else
5338 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5339 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5342 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5345 /***********************************************************************
5346 * NdrVaryingArrayMarshall [RPCRT4.@]
5348 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5349 unsigned char *pMemory,
5350 PFORMAT_STRING pFormat)
5352 unsigned char alignment;
5353 DWORD elements, esize;
5354 ULONG bufsize;
5356 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5358 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5359 (pFormat[0] != RPC_FC_LGVARRAY))
5361 ERR("invalid format type %x\n", pFormat[0]);
5362 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5363 return NULL;
5366 alignment = pFormat[1] + 1;
5368 if (pFormat[0] == RPC_FC_SMVARRAY)
5370 pFormat += 2;
5371 pFormat += sizeof(WORD);
5372 elements = *(const WORD*)pFormat;
5373 pFormat += sizeof(WORD);
5375 else
5377 pFormat += 2;
5378 pFormat += sizeof(DWORD);
5379 elements = *(const DWORD*)pFormat;
5380 pFormat += sizeof(DWORD);
5383 esize = *(const WORD*)pFormat;
5384 pFormat += sizeof(WORD);
5386 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5387 if ((pStubMsg->ActualCount > elements) ||
5388 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5390 RpcRaiseException(RPC_S_INVALID_BOUND);
5391 return NULL;
5394 WriteVariance(pStubMsg);
5396 align_pointer_clear(&pStubMsg->Buffer, alignment);
5398 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5399 pStubMsg->BufferMark = pStubMsg->Buffer;
5400 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5402 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5404 return NULL;
5407 /***********************************************************************
5408 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5410 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5411 unsigned char **ppMemory,
5412 PFORMAT_STRING pFormat,
5413 unsigned char fMustAlloc)
5415 unsigned char alignment;
5416 DWORD size, elements, esize;
5417 ULONG bufsize;
5418 unsigned char *saved_buffer;
5419 ULONG offset;
5421 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5423 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5424 (pFormat[0] != RPC_FC_LGVARRAY))
5426 ERR("invalid format type %x\n", pFormat[0]);
5427 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5428 return NULL;
5431 alignment = pFormat[1] + 1;
5433 if (pFormat[0] == RPC_FC_SMVARRAY)
5435 pFormat += 2;
5436 size = *(const WORD*)pFormat;
5437 pFormat += sizeof(WORD);
5438 elements = *(const WORD*)pFormat;
5439 pFormat += sizeof(WORD);
5441 else
5443 pFormat += 2;
5444 size = *(const DWORD*)pFormat;
5445 pFormat += sizeof(DWORD);
5446 elements = *(const DWORD*)pFormat;
5447 pFormat += sizeof(DWORD);
5450 esize = *(const WORD*)pFormat;
5451 pFormat += sizeof(WORD);
5453 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5455 align_pointer(&pStubMsg->Buffer, alignment);
5457 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5458 offset = pStubMsg->Offset;
5460 if (!fMustAlloc && !*ppMemory)
5461 fMustAlloc = TRUE;
5462 if (fMustAlloc)
5463 *ppMemory = NdrAllocate(pStubMsg, size);
5464 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5465 safe_buffer_increment(pStubMsg, bufsize);
5467 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5469 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5471 return NULL;
5474 /***********************************************************************
5475 * NdrVaryingArrayBufferSize [RPCRT4.@]
5477 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5478 unsigned char *pMemory,
5479 PFORMAT_STRING pFormat)
5481 unsigned char alignment;
5482 DWORD elements, esize;
5484 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5486 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5487 (pFormat[0] != RPC_FC_LGVARRAY))
5489 ERR("invalid format type %x\n", pFormat[0]);
5490 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5491 return;
5494 alignment = pFormat[1] + 1;
5496 if (pFormat[0] == RPC_FC_SMVARRAY)
5498 pFormat += 2;
5499 pFormat += sizeof(WORD);
5500 elements = *(const WORD*)pFormat;
5501 pFormat += sizeof(WORD);
5503 else
5505 pFormat += 2;
5506 pFormat += sizeof(DWORD);
5507 elements = *(const DWORD*)pFormat;
5508 pFormat += sizeof(DWORD);
5511 esize = *(const WORD*)pFormat;
5512 pFormat += sizeof(WORD);
5514 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5515 if ((pStubMsg->ActualCount > elements) ||
5516 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5518 RpcRaiseException(RPC_S_INVALID_BOUND);
5519 return;
5522 SizeVariance(pStubMsg);
5524 align_length(&pStubMsg->BufferLength, alignment);
5526 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5528 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5531 /***********************************************************************
5532 * NdrVaryingArrayMemorySize [RPCRT4.@]
5534 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5535 PFORMAT_STRING pFormat)
5537 unsigned char alignment;
5538 DWORD size, elements, esize;
5540 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5542 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5543 (pFormat[0] != RPC_FC_LGVARRAY))
5545 ERR("invalid format type %x\n", pFormat[0]);
5546 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5547 return 0;
5550 alignment = pFormat[1] + 1;
5552 if (pFormat[0] == RPC_FC_SMVARRAY)
5554 pFormat += 2;
5555 size = *(const WORD*)pFormat;
5556 pFormat += sizeof(WORD);
5557 elements = *(const WORD*)pFormat;
5558 pFormat += sizeof(WORD);
5560 else
5562 pFormat += 2;
5563 size = *(const DWORD*)pFormat;
5564 pFormat += sizeof(DWORD);
5565 elements = *(const DWORD*)pFormat;
5566 pFormat += sizeof(DWORD);
5569 esize = *(const WORD*)pFormat;
5570 pFormat += sizeof(WORD);
5572 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5574 align_pointer(&pStubMsg->Buffer, alignment);
5576 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5577 pStubMsg->MemorySize += size;
5579 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5581 return pStubMsg->MemorySize;
5584 /***********************************************************************
5585 * NdrVaryingArrayFree [RPCRT4.@]
5587 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5588 unsigned char *pMemory,
5589 PFORMAT_STRING pFormat)
5591 DWORD elements;
5593 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5595 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5596 (pFormat[0] != RPC_FC_LGVARRAY))
5598 ERR("invalid format type %x\n", pFormat[0]);
5599 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5600 return;
5603 if (pFormat[0] == RPC_FC_SMVARRAY)
5605 pFormat += 2;
5606 pFormat += sizeof(WORD);
5607 elements = *(const WORD*)pFormat;
5608 pFormat += sizeof(WORD);
5610 else
5612 pFormat += 2;
5613 pFormat += sizeof(DWORD);
5614 elements = *(const DWORD*)pFormat;
5615 pFormat += sizeof(DWORD);
5618 pFormat += sizeof(WORD);
5620 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5621 if ((pStubMsg->ActualCount > elements) ||
5622 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5624 RpcRaiseException(RPC_S_INVALID_BOUND);
5625 return;
5628 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5631 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5633 switch (fc)
5635 case RPC_FC_BYTE:
5636 case RPC_FC_CHAR:
5637 case RPC_FC_SMALL:
5638 case RPC_FC_USMALL:
5639 return *pMemory;
5640 case RPC_FC_WCHAR:
5641 case RPC_FC_SHORT:
5642 case RPC_FC_USHORT:
5643 case RPC_FC_ENUM16:
5644 return *(const USHORT *)pMemory;
5645 case RPC_FC_LONG:
5646 case RPC_FC_ULONG:
5647 case RPC_FC_ENUM32:
5648 return *(const ULONG *)pMemory;
5649 case RPC_FC_INT3264:
5650 case RPC_FC_UINT3264:
5651 return *(const ULONG_PTR *)pMemory;
5652 default:
5653 FIXME("Unhandled base type: 0x%02x\n", fc);
5654 return 0;
5658 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5659 ULONG discriminant,
5660 PFORMAT_STRING pFormat)
5662 unsigned short num_arms, arm, type;
5664 num_arms = *(const SHORT*)pFormat & 0x0fff;
5665 pFormat += 2;
5666 for(arm = 0; arm < num_arms; arm++)
5668 if(discriminant == *(const ULONG*)pFormat)
5670 pFormat += 4;
5671 break;
5673 pFormat += 6;
5676 type = *(const unsigned short*)pFormat;
5677 TRACE("type %04x\n", type);
5678 if(arm == num_arms) /* default arm extras */
5680 if(type == 0xffff)
5682 ERR("no arm for 0x%x and no default case\n", discriminant);
5683 RpcRaiseException(RPC_S_INVALID_TAG);
5684 return NULL;
5686 if(type == 0)
5688 TRACE("falling back to empty default case for 0x%x\n", discriminant);
5689 return NULL;
5692 return pFormat;
5695 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5697 unsigned short type;
5699 pFormat += 2;
5701 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5702 if(!pFormat)
5703 return NULL;
5705 type = *(const unsigned short*)pFormat;
5706 if((type & 0xff00) == 0x8000)
5708 unsigned char basetype = LOBYTE(type);
5709 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5711 else
5713 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5714 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5715 if (m)
5717 unsigned char *saved_buffer = NULL;
5718 int pointer_buffer_mark_set = 0;
5719 switch(*desc)
5721 case RPC_FC_RP:
5722 case RPC_FC_UP:
5723 case RPC_FC_OP:
5724 case RPC_FC_FP:
5725 align_pointer_clear(&pStubMsg->Buffer, 4);
5726 saved_buffer = pStubMsg->Buffer;
5727 if (pStubMsg->PointerBufferMark)
5729 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5730 pStubMsg->PointerBufferMark = NULL;
5731 pointer_buffer_mark_set = 1;
5733 else
5734 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5736 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5737 if (pointer_buffer_mark_set)
5739 STD_OVERFLOW_CHECK(pStubMsg);
5740 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5741 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5743 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5744 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5745 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5747 pStubMsg->Buffer = saved_buffer + 4;
5749 break;
5750 default:
5751 m(pStubMsg, pMemory, desc);
5754 else FIXME("no marshaller for embedded type %02x\n", *desc);
5756 return NULL;
5759 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5760 unsigned char **ppMemory,
5761 ULONG discriminant,
5762 PFORMAT_STRING pFormat,
5763 unsigned char fMustAlloc)
5765 unsigned short type;
5767 pFormat += 2;
5769 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5770 if(!pFormat)
5771 return NULL;
5773 type = *(const unsigned short*)pFormat;
5774 if((type & 0xff00) == 0x8000)
5776 unsigned char basetype = LOBYTE(type);
5777 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5779 else
5781 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5782 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5783 if (m)
5785 unsigned char *saved_buffer = NULL;
5786 int pointer_buffer_mark_set = 0;
5787 switch(*desc)
5789 case RPC_FC_RP:
5790 case RPC_FC_UP:
5791 case RPC_FC_OP:
5792 case RPC_FC_FP:
5793 align_pointer(&pStubMsg->Buffer, 4);
5794 saved_buffer = pStubMsg->Buffer;
5795 if (pStubMsg->PointerBufferMark)
5797 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5798 pStubMsg->PointerBufferMark = NULL;
5799 pointer_buffer_mark_set = 1;
5801 else
5802 pStubMsg->Buffer += 4; /* for pointer ID */
5804 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5806 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5807 saved_buffer, pStubMsg->BufferEnd);
5808 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5811 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5812 if (pointer_buffer_mark_set)
5814 STD_OVERFLOW_CHECK(pStubMsg);
5815 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5816 pStubMsg->Buffer = saved_buffer + 4;
5818 break;
5819 default:
5820 m(pStubMsg, ppMemory, desc, fMustAlloc);
5823 else FIXME("no marshaller for embedded type %02x\n", *desc);
5825 return NULL;
5828 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5829 unsigned char *pMemory,
5830 ULONG discriminant,
5831 PFORMAT_STRING pFormat)
5833 unsigned short type;
5835 pFormat += 2;
5837 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5838 if(!pFormat)
5839 return;
5841 type = *(const unsigned short*)pFormat;
5842 if((type & 0xff00) == 0x8000)
5844 unsigned char basetype = LOBYTE(type);
5845 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5847 else
5849 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5850 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5851 if (m)
5853 switch(*desc)
5855 case RPC_FC_RP:
5856 case RPC_FC_UP:
5857 case RPC_FC_OP:
5858 case RPC_FC_FP:
5859 align_length(&pStubMsg->BufferLength, 4);
5860 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5861 if (!pStubMsg->IgnoreEmbeddedPointers)
5863 int saved_buffer_length = pStubMsg->BufferLength;
5864 pStubMsg->BufferLength = pStubMsg->PointerLength;
5865 pStubMsg->PointerLength = 0;
5866 if(!pStubMsg->BufferLength)
5867 ERR("BufferLength == 0??\n");
5868 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5869 pStubMsg->PointerLength = pStubMsg->BufferLength;
5870 pStubMsg->BufferLength = saved_buffer_length;
5872 break;
5873 default:
5874 m(pStubMsg, pMemory, desc);
5877 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5881 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5882 ULONG discriminant,
5883 PFORMAT_STRING pFormat)
5885 unsigned short type, size;
5887 size = *(const unsigned short*)pFormat;
5888 pStubMsg->Memory += size;
5889 pFormat += 2;
5891 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5892 if(!pFormat)
5893 return 0;
5895 type = *(const unsigned short*)pFormat;
5896 if((type & 0xff00) == 0x8000)
5898 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5900 else
5902 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5903 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5904 unsigned char *saved_buffer;
5905 if (m)
5907 switch(*desc)
5909 case RPC_FC_RP:
5910 case RPC_FC_UP:
5911 case RPC_FC_OP:
5912 case RPC_FC_FP:
5913 align_pointer(&pStubMsg->Buffer, 4);
5914 saved_buffer = pStubMsg->Buffer;
5915 safe_buffer_increment(pStubMsg, 4);
5916 align_length(&pStubMsg->MemorySize, sizeof(void *));
5917 pStubMsg->MemorySize += sizeof(void *);
5918 if (!pStubMsg->IgnoreEmbeddedPointers)
5919 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5920 break;
5921 default:
5922 return m(pStubMsg, desc);
5925 else FIXME("no marshaller for embedded type %02x\n", *desc);
5928 TRACE("size %d\n", size);
5929 return size;
5932 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5933 unsigned char *pMemory,
5934 ULONG discriminant,
5935 PFORMAT_STRING pFormat)
5937 unsigned short type;
5939 pFormat += 2;
5941 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5942 if(!pFormat)
5943 return;
5945 type = *(const unsigned short*)pFormat;
5946 if((type & 0xff00) != 0x8000)
5948 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5949 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5950 if (m)
5952 switch(*desc)
5954 case RPC_FC_RP:
5955 case RPC_FC_UP:
5956 case RPC_FC_OP:
5957 case RPC_FC_FP:
5958 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5959 break;
5960 default:
5961 m(pStubMsg, pMemory, desc);
5967 /***********************************************************************
5968 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5970 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5971 unsigned char *pMemory,
5972 PFORMAT_STRING pFormat)
5974 unsigned char switch_type;
5975 unsigned char increment;
5976 ULONG switch_value;
5978 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5979 pFormat++;
5981 switch_type = *pFormat & 0xf;
5982 increment = (*pFormat & 0xf0) >> 4;
5983 pFormat++;
5985 align_pointer_clear(&pStubMsg->Buffer, increment);
5987 switch_value = get_discriminant(switch_type, pMemory);
5988 TRACE("got switch value 0x%x\n", switch_value);
5990 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5991 pMemory += increment;
5993 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5996 /***********************************************************************
5997 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5999 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6000 unsigned char **ppMemory,
6001 PFORMAT_STRING pFormat,
6002 unsigned char fMustAlloc)
6004 unsigned char switch_type;
6005 unsigned char increment;
6006 ULONG switch_value;
6007 unsigned short size;
6008 unsigned char *pMemoryArm;
6010 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6011 pFormat++;
6013 switch_type = *pFormat & 0xf;
6014 increment = (*pFormat & 0xf0) >> 4;
6015 pFormat++;
6017 align_pointer(&pStubMsg->Buffer, increment);
6018 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6019 TRACE("got switch value 0x%x\n", switch_value);
6021 size = *(const unsigned short*)pFormat + increment;
6022 if (!fMustAlloc && !*ppMemory)
6023 fMustAlloc = TRUE;
6024 if (fMustAlloc)
6025 *ppMemory = NdrAllocate(pStubMsg, size);
6027 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6028 * since the arm is part of the memory block that is encompassed by
6029 * the whole union. Memory is forced to allocate when pointers
6030 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6031 * clearing the memory we pass in to the unmarshaller */
6032 if (fMustAlloc)
6033 memset(*ppMemory, 0, size);
6035 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
6036 pMemoryArm = *ppMemory + increment;
6038 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, FALSE);
6041 /***********************************************************************
6042 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
6044 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6045 unsigned char *pMemory,
6046 PFORMAT_STRING pFormat)
6048 unsigned char switch_type;
6049 unsigned char increment;
6050 ULONG switch_value;
6052 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6053 pFormat++;
6055 switch_type = *pFormat & 0xf;
6056 increment = (*pFormat & 0xf0) >> 4;
6057 pFormat++;
6059 align_length(&pStubMsg->BufferLength, increment);
6060 switch_value = get_discriminant(switch_type, pMemory);
6061 TRACE("got switch value 0x%x\n", switch_value);
6063 /* Add discriminant size */
6064 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
6065 pMemory += increment;
6067 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
6070 /***********************************************************************
6071 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
6073 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6074 PFORMAT_STRING pFormat)
6076 unsigned char switch_type;
6077 unsigned char increment;
6078 ULONG switch_value;
6080 switch_type = *pFormat & 0xf;
6081 increment = (*pFormat & 0xf0) >> 4;
6082 pFormat++;
6084 align_pointer(&pStubMsg->Buffer, increment);
6085 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6086 TRACE("got switch value 0x%x\n", switch_value);
6088 pStubMsg->Memory += increment;
6090 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
6093 /***********************************************************************
6094 * NdrEncapsulatedUnionFree [RPCRT4.@]
6096 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6097 unsigned char *pMemory,
6098 PFORMAT_STRING pFormat)
6100 unsigned char switch_type;
6101 unsigned char increment;
6102 ULONG switch_value;
6104 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6105 pFormat++;
6107 switch_type = *pFormat & 0xf;
6108 increment = (*pFormat & 0xf0) >> 4;
6109 pFormat++;
6111 switch_value = get_discriminant(switch_type, pMemory);
6112 TRACE("got switch value 0x%x\n", switch_value);
6114 pMemory += increment;
6116 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
6119 /***********************************************************************
6120 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
6122 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6123 unsigned char *pMemory,
6124 PFORMAT_STRING pFormat)
6126 unsigned char switch_type;
6128 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6129 pFormat++;
6131 switch_type = *pFormat;
6132 pFormat++;
6134 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6135 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6136 /* Marshall discriminant */
6137 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6139 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6142 static LONG unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
6143 PFORMAT_STRING *ppFormat)
6145 LONG discriminant = 0;
6147 switch(**ppFormat)
6149 case RPC_FC_BYTE:
6150 case RPC_FC_CHAR:
6151 case RPC_FC_SMALL:
6152 case RPC_FC_USMALL:
6154 UCHAR d;
6155 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6156 discriminant = d;
6157 break;
6159 case RPC_FC_WCHAR:
6160 case RPC_FC_SHORT:
6161 case RPC_FC_USHORT:
6162 case RPC_FC_ENUM16:
6164 USHORT d;
6165 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6166 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6167 discriminant = d;
6168 break;
6170 case RPC_FC_LONG:
6171 case RPC_FC_ULONG:
6173 ULONG d;
6174 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6175 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6176 discriminant = d;
6177 break;
6179 default:
6180 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
6182 (*ppFormat)++;
6184 if (pStubMsg->fHasNewCorrDesc)
6185 *ppFormat += 6;
6186 else
6187 *ppFormat += 4;
6188 return discriminant;
6191 /**********************************************************************
6192 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6194 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6195 unsigned char **ppMemory,
6196 PFORMAT_STRING pFormat,
6197 unsigned char fMustAlloc)
6199 LONG discriminant;
6200 unsigned short size;
6202 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6203 pFormat++;
6205 /* Unmarshall discriminant */
6206 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6207 TRACE("unmarshalled discriminant %x\n", discriminant);
6209 pFormat += *(const SHORT*)pFormat;
6211 size = *(const unsigned short*)pFormat;
6213 if (!fMustAlloc && !*ppMemory)
6214 fMustAlloc = TRUE;
6215 if (fMustAlloc)
6216 *ppMemory = NdrAllocate(pStubMsg, size);
6218 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6219 * since the arm is part of the memory block that is encompassed by
6220 * the whole union. Memory is forced to allocate when pointers
6221 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6222 * clearing the memory we pass in to the unmarshaller */
6223 if (fMustAlloc)
6224 memset(*ppMemory, 0, size);
6226 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, FALSE);
6229 /***********************************************************************
6230 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6232 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6233 unsigned char *pMemory,
6234 PFORMAT_STRING pFormat)
6236 unsigned char switch_type;
6238 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6239 pFormat++;
6241 switch_type = *pFormat;
6242 pFormat++;
6244 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6245 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6246 /* Add discriminant size */
6247 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6249 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6252 /***********************************************************************
6253 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6255 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6256 PFORMAT_STRING pFormat)
6258 ULONG discriminant;
6260 pFormat++;
6261 /* Unmarshall discriminant */
6262 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6263 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
6265 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
6268 /***********************************************************************
6269 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6271 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6272 unsigned char *pMemory,
6273 PFORMAT_STRING pFormat)
6275 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6276 pFormat++;
6277 pFormat++;
6279 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6280 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6282 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6285 /***********************************************************************
6286 * NdrByteCountPointerMarshall [RPCRT4.@]
6288 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6289 unsigned char *pMemory,
6290 PFORMAT_STRING pFormat)
6292 FIXME("stub\n");
6293 return NULL;
6296 /***********************************************************************
6297 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6299 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6300 unsigned char **ppMemory,
6301 PFORMAT_STRING pFormat,
6302 unsigned char fMustAlloc)
6304 FIXME("stub\n");
6305 return NULL;
6308 /***********************************************************************
6309 * NdrByteCountPointerBufferSize [RPCRT4.@]
6311 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6312 unsigned char *pMemory,
6313 PFORMAT_STRING pFormat)
6315 FIXME("stub\n");
6318 /***********************************************************************
6319 * NdrByteCountPointerMemorySize [internal]
6321 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6322 PFORMAT_STRING pFormat)
6324 FIXME("stub\n");
6325 return 0;
6328 /***********************************************************************
6329 * NdrByteCountPointerFree [RPCRT4.@]
6331 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6332 unsigned char *pMemory,
6333 PFORMAT_STRING pFormat)
6335 FIXME("stub\n");
6338 /***********************************************************************
6339 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6341 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6342 unsigned char *pMemory,
6343 PFORMAT_STRING pFormat)
6345 FIXME("stub\n");
6346 return NULL;
6349 /***********************************************************************
6350 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6352 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6353 unsigned char **ppMemory,
6354 PFORMAT_STRING pFormat,
6355 unsigned char fMustAlloc)
6357 FIXME("stub\n");
6358 return NULL;
6361 /***********************************************************************
6362 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6364 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6365 unsigned char *pMemory,
6366 PFORMAT_STRING pFormat)
6368 FIXME("stub\n");
6371 /***********************************************************************
6372 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6374 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6375 PFORMAT_STRING pFormat)
6377 FIXME("stub\n");
6378 return 0;
6381 /***********************************************************************
6382 * NdrXmitOrRepAsFree [RPCRT4.@]
6384 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6385 unsigned char *pMemory,
6386 PFORMAT_STRING pFormat)
6388 FIXME("stub\n");
6391 /***********************************************************************
6392 * NdrRangeMarshall [internal]
6394 static unsigned char *WINAPI NdrRangeMarshall(
6395 PMIDL_STUB_MESSAGE pStubMsg,
6396 unsigned char *pMemory,
6397 PFORMAT_STRING pFormat)
6399 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6400 unsigned char base_type;
6402 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6404 if (pRange->type != RPC_FC_RANGE)
6406 ERR("invalid format type %x\n", pRange->type);
6407 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6408 return NULL;
6411 base_type = pRange->flags_type & 0xf;
6413 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6416 /***********************************************************************
6417 * NdrRangeUnmarshall [RPCRT4.@]
6419 unsigned char *WINAPI NdrRangeUnmarshall(
6420 PMIDL_STUB_MESSAGE pStubMsg,
6421 unsigned char **ppMemory,
6422 PFORMAT_STRING pFormat,
6423 unsigned char fMustAlloc)
6425 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6426 unsigned char base_type;
6428 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6430 if (pRange->type != RPC_FC_RANGE)
6432 ERR("invalid format type %x\n", pRange->type);
6433 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6434 return NULL;
6436 base_type = pRange->flags_type & 0xf;
6438 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6439 base_type, pRange->low_value, pRange->high_value);
6441 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6442 do \
6444 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \
6445 if (!fMustAlloc && !*ppMemory) \
6446 fMustAlloc = TRUE; \
6447 if (fMustAlloc) \
6448 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6449 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6451 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6452 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6453 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6455 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6456 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6458 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6459 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6460 (mem_type)pRange->high_value); \
6461 RpcRaiseException(RPC_S_INVALID_BOUND); \
6462 return NULL; \
6464 TRACE("*ppMemory: %p\n", *ppMemory); \
6465 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6466 pStubMsg->Buffer += sizeof(wire_type); \
6467 } while (0)
6469 switch(base_type)
6471 case RPC_FC_CHAR:
6472 case RPC_FC_SMALL:
6473 RANGE_UNMARSHALL(UCHAR, UCHAR, "%d");
6474 TRACE("value: 0x%02x\n", **ppMemory);
6475 break;
6476 case RPC_FC_BYTE:
6477 case RPC_FC_USMALL:
6478 RANGE_UNMARSHALL(CHAR, CHAR, "%u");
6479 TRACE("value: 0x%02x\n", **ppMemory);
6480 break;
6481 case RPC_FC_WCHAR: /* FIXME: valid? */
6482 case RPC_FC_USHORT:
6483 RANGE_UNMARSHALL(USHORT, USHORT, "%u");
6484 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6485 break;
6486 case RPC_FC_SHORT:
6487 RANGE_UNMARSHALL(SHORT, SHORT, "%d");
6488 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6489 break;
6490 case RPC_FC_LONG:
6491 case RPC_FC_ENUM32:
6492 RANGE_UNMARSHALL(LONG, LONG, "%d");
6493 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6494 break;
6495 case RPC_FC_ULONG:
6496 RANGE_UNMARSHALL(ULONG, ULONG, "%u");
6497 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6498 break;
6499 case RPC_FC_ENUM16:
6500 RANGE_UNMARSHALL(UINT, USHORT, "%u");
6501 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6502 break;
6503 case RPC_FC_FLOAT:
6504 case RPC_FC_DOUBLE:
6505 case RPC_FC_HYPER:
6506 default:
6507 ERR("invalid range base type: 0x%02x\n", base_type);
6508 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6511 return NULL;
6514 /***********************************************************************
6515 * NdrRangeBufferSize [internal]
6517 static void WINAPI NdrRangeBufferSize(
6518 PMIDL_STUB_MESSAGE pStubMsg,
6519 unsigned char *pMemory,
6520 PFORMAT_STRING pFormat)
6522 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6523 unsigned char base_type;
6525 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6527 if (pRange->type != RPC_FC_RANGE)
6529 ERR("invalid format type %x\n", pRange->type);
6530 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6532 base_type = pRange->flags_type & 0xf;
6534 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6537 /***********************************************************************
6538 * NdrRangeMemorySize [internal]
6540 static ULONG WINAPI NdrRangeMemorySize(
6541 PMIDL_STUB_MESSAGE pStubMsg,
6542 PFORMAT_STRING pFormat)
6544 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6545 unsigned char base_type;
6547 if (pRange->type != RPC_FC_RANGE)
6549 ERR("invalid format type %x\n", pRange->type);
6550 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6551 return 0;
6553 base_type = pRange->flags_type & 0xf;
6555 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6558 /***********************************************************************
6559 * NdrRangeFree [internal]
6561 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6562 unsigned char *pMemory,
6563 PFORMAT_STRING pFormat)
6565 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6567 /* nothing to do */
6570 /***********************************************************************
6571 * NdrBaseTypeMarshall [internal]
6573 static unsigned char *WINAPI NdrBaseTypeMarshall(
6574 PMIDL_STUB_MESSAGE pStubMsg,
6575 unsigned char *pMemory,
6576 PFORMAT_STRING pFormat)
6578 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6580 switch(*pFormat)
6582 case RPC_FC_BYTE:
6583 case RPC_FC_CHAR:
6584 case RPC_FC_SMALL:
6585 case RPC_FC_USMALL:
6586 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6587 TRACE("value: 0x%02x\n", *pMemory);
6588 break;
6589 case RPC_FC_WCHAR:
6590 case RPC_FC_SHORT:
6591 case RPC_FC_USHORT:
6592 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6593 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6594 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6595 break;
6596 case RPC_FC_LONG:
6597 case RPC_FC_ULONG:
6598 case RPC_FC_ERROR_STATUS_T:
6599 case RPC_FC_ENUM32:
6600 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONG));
6601 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6602 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6603 break;
6604 case RPC_FC_FLOAT:
6605 align_pointer_clear(&pStubMsg->Buffer, sizeof(float));
6606 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6607 break;
6608 case RPC_FC_DOUBLE:
6609 align_pointer_clear(&pStubMsg->Buffer, sizeof(double));
6610 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6611 break;
6612 case RPC_FC_HYPER:
6613 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONGLONG));
6614 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6615 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6616 break;
6617 case RPC_FC_ENUM16:
6619 USHORT val = *(UINT *)pMemory;
6620 /* only 16-bits on the wire, so do a sanity check */
6621 if (*(UINT *)pMemory > SHRT_MAX)
6622 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6623 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6624 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6625 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6626 break;
6628 case RPC_FC_INT3264:
6629 case RPC_FC_UINT3264:
6631 UINT val = *(UINT_PTR *)pMemory;
6632 align_pointer_clear(&pStubMsg->Buffer, sizeof(UINT));
6633 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6634 break;
6636 case RPC_FC_IGNORE:
6637 break;
6638 default:
6639 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6642 /* FIXME: what is the correct return value? */
6643 return NULL;
6646 /***********************************************************************
6647 * NdrBaseTypeUnmarshall [internal]
6649 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6650 PMIDL_STUB_MESSAGE pStubMsg,
6651 unsigned char **ppMemory,
6652 PFORMAT_STRING pFormat,
6653 unsigned char fMustAlloc)
6655 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6657 #define BASE_TYPE_UNMARSHALL(type) do { \
6658 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
6659 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6661 *ppMemory = pStubMsg->Buffer; \
6662 TRACE("*ppMemory: %p\n", *ppMemory); \
6663 safe_buffer_increment(pStubMsg, sizeof(type)); \
6665 else \
6667 if (fMustAlloc) \
6668 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6669 TRACE("*ppMemory: %p\n", *ppMemory); \
6670 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6672 } while (0)
6674 switch(*pFormat)
6676 case RPC_FC_BYTE:
6677 case RPC_FC_CHAR:
6678 case RPC_FC_SMALL:
6679 case RPC_FC_USMALL:
6680 BASE_TYPE_UNMARSHALL(UCHAR);
6681 TRACE("value: 0x%02x\n", **ppMemory);
6682 break;
6683 case RPC_FC_WCHAR:
6684 case RPC_FC_SHORT:
6685 case RPC_FC_USHORT:
6686 BASE_TYPE_UNMARSHALL(USHORT);
6687 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6688 break;
6689 case RPC_FC_LONG:
6690 case RPC_FC_ULONG:
6691 case RPC_FC_ERROR_STATUS_T:
6692 case RPC_FC_ENUM32:
6693 BASE_TYPE_UNMARSHALL(ULONG);
6694 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6695 break;
6696 case RPC_FC_FLOAT:
6697 BASE_TYPE_UNMARSHALL(float);
6698 TRACE("value: %f\n", **(float **)ppMemory);
6699 break;
6700 case RPC_FC_DOUBLE:
6701 BASE_TYPE_UNMARSHALL(double);
6702 TRACE("value: %f\n", **(double **)ppMemory);
6703 break;
6704 case RPC_FC_HYPER:
6705 BASE_TYPE_UNMARSHALL(ULONGLONG);
6706 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6707 break;
6708 case RPC_FC_ENUM16:
6710 USHORT val;
6711 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6712 if (!fMustAlloc && !*ppMemory)
6713 fMustAlloc = TRUE;
6714 if (fMustAlloc)
6715 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6716 safe_copy_from_buffer(pStubMsg, &val, sizeof(USHORT));
6717 /* 16-bits on the wire, but int in memory */
6718 **(UINT **)ppMemory = val;
6719 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6720 break;
6722 case RPC_FC_INT3264:
6723 if (sizeof(INT_PTR) == sizeof(INT)) BASE_TYPE_UNMARSHALL(INT);
6724 else
6726 INT val;
6727 align_pointer(&pStubMsg->Buffer, sizeof(INT));
6728 if (!fMustAlloc && !*ppMemory)
6729 fMustAlloc = TRUE;
6730 if (fMustAlloc)
6731 *ppMemory = NdrAllocate(pStubMsg, sizeof(INT_PTR));
6732 safe_copy_from_buffer(pStubMsg, &val, sizeof(INT));
6733 **(INT_PTR **)ppMemory = val;
6734 TRACE("value: 0x%08lx\n", **(INT_PTR **)ppMemory);
6736 break;
6737 case RPC_FC_UINT3264:
6738 if (sizeof(UINT_PTR) == sizeof(UINT)) BASE_TYPE_UNMARSHALL(UINT);
6739 else
6741 UINT val;
6742 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6743 if (!fMustAlloc && !*ppMemory)
6744 fMustAlloc = TRUE;
6745 if (fMustAlloc)
6746 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT_PTR));
6747 safe_copy_from_buffer(pStubMsg, &val, sizeof(UINT));
6748 **(UINT_PTR **)ppMemory = val;
6749 TRACE("value: 0x%08lx\n", **(UINT_PTR **)ppMemory);
6751 break;
6752 case RPC_FC_IGNORE:
6753 break;
6754 default:
6755 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6757 #undef BASE_TYPE_UNMARSHALL
6759 /* FIXME: what is the correct return value? */
6761 return NULL;
6764 /***********************************************************************
6765 * NdrBaseTypeBufferSize [internal]
6767 static void WINAPI NdrBaseTypeBufferSize(
6768 PMIDL_STUB_MESSAGE pStubMsg,
6769 unsigned char *pMemory,
6770 PFORMAT_STRING pFormat)
6772 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6774 switch(*pFormat)
6776 case RPC_FC_BYTE:
6777 case RPC_FC_CHAR:
6778 case RPC_FC_SMALL:
6779 case RPC_FC_USMALL:
6780 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6781 break;
6782 case RPC_FC_WCHAR:
6783 case RPC_FC_SHORT:
6784 case RPC_FC_USHORT:
6785 case RPC_FC_ENUM16:
6786 align_length(&pStubMsg->BufferLength, sizeof(USHORT));
6787 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6788 break;
6789 case RPC_FC_LONG:
6790 case RPC_FC_ULONG:
6791 case RPC_FC_ENUM32:
6792 case RPC_FC_INT3264:
6793 case RPC_FC_UINT3264:
6794 align_length(&pStubMsg->BufferLength, sizeof(ULONG));
6795 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6796 break;
6797 case RPC_FC_FLOAT:
6798 align_length(&pStubMsg->BufferLength, sizeof(float));
6799 safe_buffer_length_increment(pStubMsg, sizeof(float));
6800 break;
6801 case RPC_FC_DOUBLE:
6802 align_length(&pStubMsg->BufferLength, sizeof(double));
6803 safe_buffer_length_increment(pStubMsg, sizeof(double));
6804 break;
6805 case RPC_FC_HYPER:
6806 align_length(&pStubMsg->BufferLength, sizeof(ULONGLONG));
6807 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6808 break;
6809 case RPC_FC_ERROR_STATUS_T:
6810 align_length(&pStubMsg->BufferLength, sizeof(error_status_t));
6811 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6812 break;
6813 case RPC_FC_IGNORE:
6814 break;
6815 default:
6816 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6820 /***********************************************************************
6821 * NdrBaseTypeMemorySize [internal]
6823 static ULONG WINAPI NdrBaseTypeMemorySize(
6824 PMIDL_STUB_MESSAGE pStubMsg,
6825 PFORMAT_STRING pFormat)
6827 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6829 switch(*pFormat)
6831 case RPC_FC_BYTE:
6832 case RPC_FC_CHAR:
6833 case RPC_FC_SMALL:
6834 case RPC_FC_USMALL:
6835 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6836 pStubMsg->MemorySize += sizeof(UCHAR);
6837 return sizeof(UCHAR);
6838 case RPC_FC_WCHAR:
6839 case RPC_FC_SHORT:
6840 case RPC_FC_USHORT:
6841 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6842 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6843 align_length(&pStubMsg->MemorySize, sizeof(USHORT));
6844 pStubMsg->MemorySize += sizeof(USHORT);
6845 return sizeof(USHORT);
6846 case RPC_FC_LONG:
6847 case RPC_FC_ULONG:
6848 case RPC_FC_ENUM32:
6849 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6850 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6851 align_length(&pStubMsg->MemorySize, sizeof(ULONG));
6852 pStubMsg->MemorySize += sizeof(ULONG);
6853 return sizeof(ULONG);
6854 case RPC_FC_FLOAT:
6855 align_pointer(&pStubMsg->Buffer, sizeof(float));
6856 safe_buffer_increment(pStubMsg, sizeof(float));
6857 align_length(&pStubMsg->MemorySize, sizeof(float));
6858 pStubMsg->MemorySize += sizeof(float);
6859 return sizeof(float);
6860 case RPC_FC_DOUBLE:
6861 align_pointer(&pStubMsg->Buffer, sizeof(double));
6862 safe_buffer_increment(pStubMsg, sizeof(double));
6863 align_length(&pStubMsg->MemorySize, sizeof(double));
6864 pStubMsg->MemorySize += sizeof(double);
6865 return sizeof(double);
6866 case RPC_FC_HYPER:
6867 align_pointer(&pStubMsg->Buffer, sizeof(ULONGLONG));
6868 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6869 align_length(&pStubMsg->MemorySize, sizeof(ULONGLONG));
6870 pStubMsg->MemorySize += sizeof(ULONGLONG);
6871 return sizeof(ULONGLONG);
6872 case RPC_FC_ERROR_STATUS_T:
6873 align_pointer(&pStubMsg->Buffer, sizeof(error_status_t));
6874 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6875 align_length(&pStubMsg->MemorySize, sizeof(error_status_t));
6876 pStubMsg->MemorySize += sizeof(error_status_t);
6877 return sizeof(error_status_t);
6878 case RPC_FC_ENUM16:
6879 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6880 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6881 align_length(&pStubMsg->MemorySize, sizeof(UINT));
6882 pStubMsg->MemorySize += sizeof(UINT);
6883 return sizeof(UINT);
6884 case RPC_FC_INT3264:
6885 case RPC_FC_UINT3264:
6886 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6887 safe_buffer_increment(pStubMsg, sizeof(UINT));
6888 align_length(&pStubMsg->MemorySize, sizeof(UINT_PTR));
6889 pStubMsg->MemorySize += sizeof(UINT_PTR);
6890 return sizeof(UINT_PTR);
6891 case RPC_FC_IGNORE:
6892 align_length(&pStubMsg->MemorySize, sizeof(void *));
6893 pStubMsg->MemorySize += sizeof(void *);
6894 return sizeof(void *);
6895 default:
6896 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6897 return 0;
6901 /***********************************************************************
6902 * NdrBaseTypeFree [internal]
6904 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6905 unsigned char *pMemory,
6906 PFORMAT_STRING pFormat)
6908 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6910 /* nothing to do */
6913 /***********************************************************************
6914 * NdrContextHandleBufferSize [internal]
6916 static void WINAPI NdrContextHandleBufferSize(
6917 PMIDL_STUB_MESSAGE pStubMsg,
6918 unsigned char *pMemory,
6919 PFORMAT_STRING pFormat)
6921 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6923 if (*pFormat != RPC_FC_BIND_CONTEXT)
6925 ERR("invalid format type %x\n", *pFormat);
6926 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6928 align_length(&pStubMsg->BufferLength, 4);
6929 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6932 /***********************************************************************
6933 * NdrContextHandleMarshall [internal]
6935 static unsigned char *WINAPI NdrContextHandleMarshall(
6936 PMIDL_STUB_MESSAGE pStubMsg,
6937 unsigned char *pMemory,
6938 PFORMAT_STRING pFormat)
6940 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6942 if (*pFormat != RPC_FC_BIND_CONTEXT)
6944 ERR("invalid format type %x\n", *pFormat);
6945 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6947 TRACE("flags: 0x%02x\n", pFormat[1]);
6949 if (pStubMsg->IsClient)
6951 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6952 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6953 else
6954 NdrClientContextMarshall(pStubMsg, pMemory, FALSE);
6956 else
6958 NDR_SCONTEXT ctxt = NDRSContextFromValue(pMemory);
6959 NDR_RUNDOWN rundown = pStubMsg->StubDesc->apfnNdrRundownRoutines[pFormat[2]];
6960 NdrServerContextNewMarshall(pStubMsg, ctxt, rundown, pFormat);
6963 return NULL;
6966 /***********************************************************************
6967 * NdrContextHandleUnmarshall [internal]
6969 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6970 PMIDL_STUB_MESSAGE pStubMsg,
6971 unsigned char **ppMemory,
6972 PFORMAT_STRING pFormat,
6973 unsigned char fMustAlloc)
6975 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6976 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6978 if (*pFormat != RPC_FC_BIND_CONTEXT)
6980 ERR("invalid format type %x\n", *pFormat);
6981 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6983 TRACE("flags: 0x%02x\n", pFormat[1]);
6985 if (pStubMsg->IsClient)
6987 /* [out]-only or [ret] param */
6988 if ((pFormat[1] & (HANDLE_PARAM_IS_IN|HANDLE_PARAM_IS_OUT)) == HANDLE_PARAM_IS_OUT)
6989 **(NDR_CCONTEXT **)ppMemory = NULL;
6990 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6992 else
6994 NDR_SCONTEXT ctxt;
6995 ctxt = NdrServerContextNewUnmarshall(pStubMsg, pFormat);
6996 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6997 *(void **)ppMemory = NDRSContextValue(ctxt);
6998 else
6999 *(void **)ppMemory = *NDRSContextValue(ctxt);
7002 return NULL;
7005 /***********************************************************************
7006 * NdrClientContextMarshall [RPCRT4.@]
7008 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7009 NDR_CCONTEXT ContextHandle,
7010 int fCheck)
7012 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
7014 align_pointer_clear(&pStubMsg->Buffer, 4);
7016 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7018 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7019 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7020 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7023 /* FIXME: what does fCheck do? */
7024 NDRCContextMarshall(ContextHandle,
7025 pStubMsg->Buffer);
7027 pStubMsg->Buffer += cbNDRContext;
7030 /***********************************************************************
7031 * NdrClientContextUnmarshall [RPCRT4.@]
7033 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7034 NDR_CCONTEXT * pContextHandle,
7035 RPC_BINDING_HANDLE BindHandle)
7037 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
7039 align_pointer(&pStubMsg->Buffer, 4);
7041 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
7042 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7044 NDRCContextUnmarshall(pContextHandle,
7045 BindHandle,
7046 pStubMsg->Buffer,
7047 pStubMsg->RpcMsg->DataRepresentation);
7049 pStubMsg->Buffer += cbNDRContext;
7052 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7053 NDR_SCONTEXT ContextHandle,
7054 NDR_RUNDOWN RundownRoutine )
7056 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
7058 align_pointer(&pStubMsg->Buffer, 4);
7060 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7062 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7063 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7064 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7067 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7068 pStubMsg->Buffer, RundownRoutine, NULL,
7069 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7070 pStubMsg->Buffer += cbNDRContext;
7073 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
7075 NDR_SCONTEXT ContextHandle;
7077 TRACE("(%p)\n", pStubMsg);
7079 align_pointer(&pStubMsg->Buffer, 4);
7081 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7083 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7084 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7085 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7088 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7089 pStubMsg->Buffer,
7090 pStubMsg->RpcMsg->DataRepresentation,
7091 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7092 pStubMsg->Buffer += cbNDRContext;
7094 return ContextHandle;
7097 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
7098 unsigned char* pMemory,
7099 PFORMAT_STRING pFormat)
7101 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
7104 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
7105 PFORMAT_STRING pFormat)
7107 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7108 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7110 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7112 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7113 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7114 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7115 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7116 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7118 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7119 if_id = &sif->InterfaceId;
7122 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
7123 pStubMsg->RpcMsg->DataRepresentation, if_id,
7124 flags);
7127 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7128 NDR_SCONTEXT ContextHandle,
7129 NDR_RUNDOWN RundownRoutine,
7130 PFORMAT_STRING pFormat)
7132 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7133 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7135 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
7137 align_pointer(&pStubMsg->Buffer, 4);
7139 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7141 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7142 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7143 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7146 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7147 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7148 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7149 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7150 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7152 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7153 if_id = &sif->InterfaceId;
7156 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7157 pStubMsg->Buffer, RundownRoutine, if_id, flags);
7158 pStubMsg->Buffer += cbNDRContext;
7161 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7162 PFORMAT_STRING pFormat)
7164 NDR_SCONTEXT ContextHandle;
7165 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7166 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7168 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7170 align_pointer(&pStubMsg->Buffer, 4);
7172 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7174 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7175 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7176 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7179 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7180 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7181 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7182 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7183 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7185 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7186 if_id = &sif->InterfaceId;
7189 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7190 pStubMsg->Buffer,
7191 pStubMsg->RpcMsg->DataRepresentation,
7192 if_id, flags);
7193 pStubMsg->Buffer += cbNDRContext;
7195 return ContextHandle;
7198 /***********************************************************************
7199 * NdrCorrelationInitialize [RPCRT4.@]
7201 * Initializes correlation validity checking.
7203 * PARAMS
7204 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7205 * pMemory [I] Pointer to memory to use as a cache.
7206 * CacheSize [I] Size of the memory pointed to by pMemory.
7207 * Flags [I] Reserved. Set to zero.
7209 * RETURNS
7210 * Nothing.
7212 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
7214 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
7215 pStubMsg->fHasNewCorrDesc = TRUE;
7218 /***********************************************************************
7219 * NdrCorrelationPass [RPCRT4.@]
7221 * Performs correlation validity checking.
7223 * PARAMS
7224 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7226 * RETURNS
7227 * Nothing.
7229 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
7231 FIXME("(%p): stub\n", pStubMsg);
7234 /***********************************************************************
7235 * NdrCorrelationFree [RPCRT4.@]
7237 * Frees any resources used while unmarshalling parameters that need
7238 * correlation validity checking.
7240 * PARAMS
7241 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7243 * RETURNS
7244 * Nothing.
7246 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
7248 FIXME("(%p): stub\n", pStubMsg);