rpcrt4: Don't align the buffer after reading the conformance, we need to read the...
[wine/hramrach.git] / dlls / rpcrt4 / ndr_marshall.c
blobdb8be60c37c75f0ec920bf34e71a41aa319e4cfb
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 DWORD 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=%d\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 pStubMsg->StackTop = ptr;
595 /* ofs is index into StubDesc->apfnExprEval */
596 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
597 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
599 pStubMsg->StackTop = old_stack_top;
601 /* the callback function always stores the computed value in MaxCount */
602 *pCount = pStubMsg->MaxCount;
603 goto finish_conf;
605 default:
606 ptr = (char *)ptr + ofs;
607 break;
610 switch (dtype) {
611 case RPC_FC_LONG:
612 case RPC_FC_ULONG:
613 data = *(DWORD*)ptr;
614 break;
615 case RPC_FC_SHORT:
616 data = *(SHORT*)ptr;
617 break;
618 case RPC_FC_USHORT:
619 data = *(USHORT*)ptr;
620 break;
621 case RPC_FC_CHAR:
622 case RPC_FC_SMALL:
623 data = *(CHAR*)ptr;
624 break;
625 case RPC_FC_BYTE:
626 case RPC_FC_USMALL:
627 data = *(UCHAR*)ptr;
628 break;
629 default:
630 FIXME("unknown conformance data type %x\n", dtype);
631 goto done_conf_grab;
633 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
635 done_conf_grab:
636 switch (pFormat[1]) {
637 case RPC_FC_DEREFERENCE: /* already handled */
638 case 0: /* no op */
639 *pCount = data;
640 break;
641 case RPC_FC_ADD_1:
642 *pCount = data + 1;
643 break;
644 case RPC_FC_SUB_1:
645 *pCount = data - 1;
646 break;
647 case RPC_FC_MULT_2:
648 *pCount = data * 2;
649 break;
650 case RPC_FC_DIV_2:
651 *pCount = data / 2;
652 break;
653 default:
654 FIXME("unknown conformance op %d\n", pFormat[1]);
655 goto finish_conf;
658 finish_conf:
659 TRACE("resulting conformance is %ld\n", *pCount);
660 if (pStubMsg->fHasNewCorrDesc)
661 return pFormat+6;
662 else
663 return pFormat+4;
666 static inline PFORMAT_STRING SkipConformance(PMIDL_STUB_MESSAGE pStubMsg,
667 PFORMAT_STRING pFormat)
669 if (pStubMsg->fHasNewCorrDesc)
670 pFormat += 6;
671 else
672 pFormat += 4;
673 return pFormat;
676 static inline PFORMAT_STRING SkipVariance(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
678 return SkipConformance( pStubMsg, pFormat );
681 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
682 * the result overflows 32-bits */
683 static inline ULONG safe_multiply(ULONG a, ULONG b)
685 ULONGLONG ret = (ULONGLONG)a * b;
686 if (ret > 0xffffffff)
688 RpcRaiseException(RPC_S_INVALID_BOUND);
689 return 0;
691 return ret;
694 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
696 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
697 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
698 RpcRaiseException(RPC_X_BAD_STUB_DATA);
699 pStubMsg->Buffer += size;
702 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
704 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
706 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
707 pStubMsg->BufferLength, size);
708 RpcRaiseException(RPC_X_BAD_STUB_DATA);
710 pStubMsg->BufferLength += size;
713 /* copies data from the buffer, checking that there is enough data in the buffer
714 * to do so */
715 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
717 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
718 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
720 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
721 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
722 RpcRaiseException(RPC_X_BAD_STUB_DATA);
724 if (p == pStubMsg->Buffer)
725 ERR("pointer is the same as the buffer\n");
726 memcpy(p, pStubMsg->Buffer, size);
727 pStubMsg->Buffer += size;
730 /* copies data to the buffer, checking that there is enough space to do so */
731 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
733 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
734 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
736 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
737 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
738 size);
739 RpcRaiseException(RPC_X_BAD_STUB_DATA);
741 memcpy(pStubMsg->Buffer, p, size);
742 pStubMsg->Buffer += size;
745 /* verify that string data sitting in the buffer is valid and safe to
746 * unmarshall */
747 static void validate_string_data(MIDL_STUB_MESSAGE *pStubMsg, ULONG bufsize, ULONG esize)
749 ULONG i;
751 /* verify the buffer is safe to access */
752 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
753 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
755 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
756 pStubMsg->BufferEnd, pStubMsg->Buffer);
757 RpcRaiseException(RPC_X_BAD_STUB_DATA);
760 /* strings must always have null terminating bytes */
761 if (bufsize < esize)
763 ERR("invalid string length of %d\n", bufsize / esize);
764 RpcRaiseException(RPC_S_INVALID_BOUND);
767 for (i = bufsize - esize; i < bufsize; i++)
768 if (pStubMsg->Buffer[i] != 0)
770 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
771 i, pStubMsg->Buffer[i]);
772 RpcRaiseException(RPC_S_INVALID_BOUND);
776 static inline void dump_pointer_attr(unsigned char attr)
778 if (attr & RPC_FC_P_ALLOCALLNODES)
779 TRACE(" RPC_FC_P_ALLOCALLNODES");
780 if (attr & RPC_FC_P_DONTFREE)
781 TRACE(" RPC_FC_P_DONTFREE");
782 if (attr & RPC_FC_P_ONSTACK)
783 TRACE(" RPC_FC_P_ONSTACK");
784 if (attr & RPC_FC_P_SIMPLEPOINTER)
785 TRACE(" RPC_FC_P_SIMPLEPOINTER");
786 if (attr & RPC_FC_P_DEREF)
787 TRACE(" RPC_FC_P_DEREF");
788 TRACE("\n");
791 /***********************************************************************
792 * PointerMarshall [internal]
794 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
795 unsigned char *Buffer,
796 unsigned char *Pointer,
797 PFORMAT_STRING pFormat)
799 unsigned type = pFormat[0], attr = pFormat[1];
800 PFORMAT_STRING desc;
801 NDR_MARSHALL m;
802 ULONG pointer_id;
803 int pointer_needs_marshaling;
805 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
806 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
807 pFormat += 2;
808 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
809 else desc = pFormat + *(const SHORT*)pFormat;
811 switch (type) {
812 case RPC_FC_RP: /* ref pointer (always non-null) */
813 if (!Pointer)
815 ERR("NULL ref pointer is not allowed\n");
816 RpcRaiseException(RPC_X_NULL_REF_POINTER);
818 pointer_needs_marshaling = 1;
819 break;
820 case RPC_FC_UP: /* unique pointer */
821 case RPC_FC_OP: /* object pointer - same as unique here */
822 if (Pointer)
823 pointer_needs_marshaling = 1;
824 else
825 pointer_needs_marshaling = 0;
826 pointer_id = Pointer ? NDR_POINTER_ID(pStubMsg) : 0;
827 TRACE("writing 0x%08x to buffer\n", pointer_id);
828 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
829 break;
830 case RPC_FC_FP:
831 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
832 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
833 TRACE("writing 0x%08x to buffer\n", pointer_id);
834 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
835 break;
836 default:
837 FIXME("unhandled ptr type=%02x\n", type);
838 RpcRaiseException(RPC_X_BAD_STUB_DATA);
839 return;
842 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
844 if (pointer_needs_marshaling) {
845 if (attr & RPC_FC_P_DEREF) {
846 Pointer = *(unsigned char**)Pointer;
847 TRACE("deref => %p\n", Pointer);
849 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
850 if (m) m(pStubMsg, Pointer, desc);
851 else FIXME("no marshaller for data type=%02x\n", *desc);
854 STD_OVERFLOW_CHECK(pStubMsg);
857 /***********************************************************************
858 * PointerUnmarshall [internal]
860 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
861 unsigned char *Buffer,
862 unsigned char **pPointer,
863 unsigned char *pSrcPointer,
864 PFORMAT_STRING pFormat,
865 unsigned char fMustAlloc)
867 unsigned type = pFormat[0], attr = pFormat[1];
868 PFORMAT_STRING desc;
869 NDR_UNMARSHALL m;
870 DWORD pointer_id = 0;
871 int pointer_needs_unmarshaling;
873 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
874 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
875 pFormat += 2;
876 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
877 else desc = pFormat + *(const SHORT*)pFormat;
879 switch (type) {
880 case RPC_FC_RP: /* ref pointer (always non-null) */
881 pointer_needs_unmarshaling = 1;
882 break;
883 case RPC_FC_UP: /* unique pointer */
884 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
885 TRACE("pointer_id is 0x%08x\n", pointer_id);
886 if (pointer_id)
887 pointer_needs_unmarshaling = 1;
888 else {
889 *pPointer = NULL;
890 pointer_needs_unmarshaling = 0;
892 break;
893 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
894 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
895 TRACE("pointer_id is 0x%08x\n", pointer_id);
896 if (!fMustAlloc && pSrcPointer)
898 FIXME("free object pointer %p\n", pSrcPointer);
899 fMustAlloc = TRUE;
901 if (pointer_id)
902 pointer_needs_unmarshaling = 1;
903 else
905 *pPointer = NULL;
906 pointer_needs_unmarshaling = 0;
908 break;
909 case RPC_FC_FP:
910 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
911 TRACE("pointer_id is 0x%08x\n", pointer_id);
912 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
913 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
914 break;
915 default:
916 FIXME("unhandled ptr type=%02x\n", type);
917 RpcRaiseException(RPC_X_BAD_STUB_DATA);
918 return;
921 if (pointer_needs_unmarshaling) {
922 unsigned char *base_ptr_val = *pPointer;
923 unsigned char **current_ptr = pPointer;
924 if (pStubMsg->IsClient) {
925 TRACE("client\n");
926 /* if we aren't forcing allocation of memory then try to use the existing
927 * (source) pointer to unmarshall the data into so that [in,out]
928 * parameters behave correctly. it doesn't matter if the parameter is
929 * [out] only since in that case the pointer will be NULL. we force
930 * allocation when the source pointer is NULL here instead of in the type
931 * unmarshalling routine for the benefit of the deref code below */
932 if (!fMustAlloc) {
933 if (pSrcPointer) {
934 TRACE("setting *pPointer to %p\n", pSrcPointer);
935 *pPointer = base_ptr_val = pSrcPointer;
936 } else
937 fMustAlloc = TRUE;
939 } else {
940 TRACE("server\n");
941 /* the memory in a stub is never initialised, so we have to work out here
942 * whether we have to initialise it so we can use the optimisation of
943 * setting the pointer to the buffer, if possible, or set fMustAlloc to
944 * TRUE. */
945 if (attr & RPC_FC_P_DEREF) {
946 fMustAlloc = TRUE;
947 } else {
948 base_ptr_val = NULL;
949 *current_ptr = NULL;
953 if (attr & RPC_FC_P_ALLOCALLNODES)
954 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
956 if (attr & RPC_FC_P_DEREF) {
957 if (fMustAlloc) {
958 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
959 *pPointer = base_ptr_val;
960 current_ptr = (unsigned char **)base_ptr_val;
961 } else
962 current_ptr = *(unsigned char***)current_ptr;
963 TRACE("deref => %p\n", current_ptr);
964 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
966 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
967 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
968 else FIXME("no unmarshaller for data type=%02x\n", *desc);
970 if (type == RPC_FC_FP)
971 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
972 *pPointer);
975 TRACE("pointer=%p\n", *pPointer);
978 /***********************************************************************
979 * PointerBufferSize [internal]
981 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
982 unsigned char *Pointer,
983 PFORMAT_STRING pFormat)
985 unsigned type = pFormat[0], attr = pFormat[1];
986 PFORMAT_STRING desc;
987 NDR_BUFFERSIZE m;
988 int pointer_needs_sizing;
989 ULONG pointer_id;
991 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
992 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
993 pFormat += 2;
994 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
995 else desc = pFormat + *(const SHORT*)pFormat;
997 switch (type) {
998 case RPC_FC_RP: /* ref pointer (always non-null) */
999 if (!Pointer)
1001 ERR("NULL ref pointer is not allowed\n");
1002 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1004 break;
1005 case RPC_FC_OP:
1006 case RPC_FC_UP:
1007 /* NULL pointer has no further representation */
1008 if (!Pointer)
1009 return;
1010 break;
1011 case RPC_FC_FP:
1012 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1013 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1014 if (!pointer_needs_sizing)
1015 return;
1016 break;
1017 default:
1018 FIXME("unhandled ptr type=%02x\n", type);
1019 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1020 return;
1023 if (attr & RPC_FC_P_DEREF) {
1024 Pointer = *(unsigned char**)Pointer;
1025 TRACE("deref => %p\n", Pointer);
1028 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1029 if (m) m(pStubMsg, Pointer, desc);
1030 else FIXME("no buffersizer for data type=%02x\n", *desc);
1033 /***********************************************************************
1034 * PointerMemorySize [internal]
1036 static ULONG PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1037 unsigned char *Buffer, PFORMAT_STRING pFormat)
1039 unsigned type = pFormat[0], attr = pFormat[1];
1040 PFORMAT_STRING desc;
1041 NDR_MEMORYSIZE m;
1042 DWORD pointer_id = 0;
1043 int pointer_needs_sizing;
1045 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1046 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1047 pFormat += 2;
1048 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1049 else desc = pFormat + *(const SHORT*)pFormat;
1051 switch (type) {
1052 case RPC_FC_RP: /* ref pointer (always non-null) */
1053 pointer_needs_sizing = 1;
1054 break;
1055 case RPC_FC_UP: /* unique pointer */
1056 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1057 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1058 TRACE("pointer_id is 0x%08x\n", pointer_id);
1059 if (pointer_id)
1060 pointer_needs_sizing = 1;
1061 else
1062 pointer_needs_sizing = 0;
1063 break;
1064 case RPC_FC_FP:
1066 void *pointer;
1067 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1068 TRACE("pointer_id is 0x%08x\n", pointer_id);
1069 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1070 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1071 break;
1073 default:
1074 FIXME("unhandled ptr type=%02x\n", type);
1075 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1076 return 0;
1079 if (attr & RPC_FC_P_DEREF) {
1080 align_length(&pStubMsg->MemorySize, sizeof(void*));
1081 pStubMsg->MemorySize += sizeof(void*);
1082 TRACE("deref\n");
1085 if (pointer_needs_sizing) {
1086 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1087 if (m) m(pStubMsg, desc);
1088 else FIXME("no memorysizer for data type=%02x\n", *desc);
1091 return pStubMsg->MemorySize;
1094 /***********************************************************************
1095 * PointerFree [internal]
1097 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1098 unsigned char *Pointer,
1099 PFORMAT_STRING pFormat)
1101 unsigned type = pFormat[0], attr = pFormat[1];
1102 PFORMAT_STRING desc;
1103 NDR_FREE m;
1104 unsigned char *current_pointer = Pointer;
1106 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1107 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1108 if (attr & RPC_FC_P_DONTFREE) return;
1109 pFormat += 2;
1110 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1111 else desc = pFormat + *(const SHORT*)pFormat;
1113 if (!Pointer) return;
1115 if (type == RPC_FC_FP) {
1116 int pointer_needs_freeing = NdrFullPointerFree(
1117 pStubMsg->FullPtrXlatTables, Pointer);
1118 if (!pointer_needs_freeing)
1119 return;
1122 if (attr & RPC_FC_P_DEREF) {
1123 current_pointer = *(unsigned char**)Pointer;
1124 TRACE("deref => %p\n", current_pointer);
1127 m = NdrFreer[*desc & NDR_TABLE_MASK];
1128 if (m) m(pStubMsg, current_pointer, desc);
1130 /* this check stops us from trying to free buffer memory. we don't have to
1131 * worry about clients, since they won't call this function.
1132 * we don't have to check for the buffer being reallocated because
1133 * BufferStart and BufferEnd won't be reset when allocating memory for
1134 * sending the response. we don't have to check for the new buffer here as
1135 * it won't be used a type memory, only for buffer memory */
1136 if (Pointer >= pStubMsg->BufferStart && Pointer < pStubMsg->BufferEnd)
1137 goto notfree;
1139 if (attr & RPC_FC_P_ONSTACK) {
1140 TRACE("not freeing stack ptr %p\n", Pointer);
1141 return;
1143 TRACE("freeing %p\n", Pointer);
1144 NdrFree(pStubMsg, Pointer);
1145 return;
1146 notfree:
1147 TRACE("not freeing %p\n", Pointer);
1150 /***********************************************************************
1151 * EmbeddedPointerMarshall
1153 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1154 unsigned char *pMemory,
1155 PFORMAT_STRING pFormat)
1157 unsigned char *Mark = pStubMsg->BufferMark;
1158 unsigned rep, count, stride;
1159 unsigned i;
1160 unsigned char *saved_buffer = NULL;
1162 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1164 if (*pFormat != RPC_FC_PP) return NULL;
1165 pFormat += 2;
1167 if (pStubMsg->PointerBufferMark)
1169 saved_buffer = pStubMsg->Buffer;
1170 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1171 pStubMsg->PointerBufferMark = NULL;
1174 while (pFormat[0] != RPC_FC_END) {
1175 switch (pFormat[0]) {
1176 default:
1177 FIXME("unknown repeat type %d\n", pFormat[0]);
1178 case RPC_FC_NO_REPEAT:
1179 rep = 1;
1180 stride = 0;
1181 count = 1;
1182 pFormat += 2;
1183 break;
1184 case RPC_FC_FIXED_REPEAT:
1185 rep = *(const WORD*)&pFormat[2];
1186 stride = *(const WORD*)&pFormat[4];
1187 count = *(const WORD*)&pFormat[8];
1188 pFormat += 10;
1189 break;
1190 case RPC_FC_VARIABLE_REPEAT:
1191 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1192 stride = *(const WORD*)&pFormat[2];
1193 count = *(const WORD*)&pFormat[6];
1194 pFormat += 8;
1195 break;
1197 for (i = 0; i < rep; i++) {
1198 PFORMAT_STRING info = pFormat;
1199 unsigned char *membase = pMemory + (i * stride);
1200 unsigned char *bufbase = Mark + (i * stride);
1201 unsigned u;
1203 for (u=0; u<count; u++,info+=8) {
1204 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1205 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1206 unsigned char *saved_memory = pStubMsg->Memory;
1208 pStubMsg->Memory = pMemory;
1209 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1210 pStubMsg->Memory = saved_memory;
1213 pFormat += 8 * count;
1216 if (saved_buffer)
1218 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1219 pStubMsg->Buffer = saved_buffer;
1222 STD_OVERFLOW_CHECK(pStubMsg);
1224 return NULL;
1227 /***********************************************************************
1228 * EmbeddedPointerUnmarshall
1230 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1231 unsigned char *pDstBuffer,
1232 unsigned char *pSrcMemoryPtrs,
1233 PFORMAT_STRING pFormat,
1234 unsigned char fMustAlloc)
1236 unsigned char *Mark = pStubMsg->BufferMark;
1237 unsigned rep, count, stride;
1238 unsigned i;
1239 unsigned char *saved_buffer = NULL;
1241 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc);
1243 if (*pFormat != RPC_FC_PP) return NULL;
1244 pFormat += 2;
1246 if (pStubMsg->PointerBufferMark)
1248 saved_buffer = pStubMsg->Buffer;
1249 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1250 pStubMsg->PointerBufferMark = NULL;
1253 while (pFormat[0] != RPC_FC_END) {
1254 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1255 switch (pFormat[0]) {
1256 default:
1257 FIXME("unknown repeat type %d\n", pFormat[0]);
1258 case RPC_FC_NO_REPEAT:
1259 rep = 1;
1260 stride = 0;
1261 count = 1;
1262 pFormat += 2;
1263 break;
1264 case RPC_FC_FIXED_REPEAT:
1265 rep = *(const WORD*)&pFormat[2];
1266 stride = *(const WORD*)&pFormat[4];
1267 count = *(const WORD*)&pFormat[8];
1268 pFormat += 10;
1269 break;
1270 case RPC_FC_VARIABLE_REPEAT:
1271 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1272 stride = *(const WORD*)&pFormat[2];
1273 count = *(const WORD*)&pFormat[6];
1274 pFormat += 8;
1275 break;
1277 for (i = 0; i < rep; i++) {
1278 PFORMAT_STRING info = pFormat;
1279 unsigned char *bufdstbase = pDstBuffer + (i * stride);
1280 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1281 unsigned char *bufbase = Mark + (i * stride);
1282 unsigned u;
1284 for (u=0; u<count; u++,info+=8) {
1285 unsigned char **bufdstptr = (unsigned char **)(bufdstbase + *(const SHORT*)&info[2]);
1286 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1287 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1288 PointerUnmarshall(pStubMsg, bufptr, bufdstptr, *memsrcptr, info+4, fMustAlloc);
1291 pFormat += 8 * count;
1294 if (saved_buffer)
1296 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1297 pStubMsg->Buffer = saved_buffer;
1300 return NULL;
1303 /***********************************************************************
1304 * EmbeddedPointerBufferSize
1306 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1307 unsigned char *pMemory,
1308 PFORMAT_STRING pFormat)
1310 unsigned rep, count, stride;
1311 unsigned i;
1312 ULONG saved_buffer_length = 0;
1314 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1316 if (pStubMsg->IgnoreEmbeddedPointers) return;
1318 if (*pFormat != RPC_FC_PP) return;
1319 pFormat += 2;
1321 if (pStubMsg->PointerLength)
1323 saved_buffer_length = pStubMsg->BufferLength;
1324 pStubMsg->BufferLength = pStubMsg->PointerLength;
1325 pStubMsg->PointerLength = 0;
1328 while (pFormat[0] != RPC_FC_END) {
1329 switch (pFormat[0]) {
1330 default:
1331 FIXME("unknown repeat type %d\n", pFormat[0]);
1332 case RPC_FC_NO_REPEAT:
1333 rep = 1;
1334 stride = 0;
1335 count = 1;
1336 pFormat += 2;
1337 break;
1338 case RPC_FC_FIXED_REPEAT:
1339 rep = *(const WORD*)&pFormat[2];
1340 stride = *(const WORD*)&pFormat[4];
1341 count = *(const WORD*)&pFormat[8];
1342 pFormat += 10;
1343 break;
1344 case RPC_FC_VARIABLE_REPEAT:
1345 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1346 stride = *(const WORD*)&pFormat[2];
1347 count = *(const WORD*)&pFormat[6];
1348 pFormat += 8;
1349 break;
1351 for (i = 0; i < rep; i++) {
1352 PFORMAT_STRING info = pFormat;
1353 unsigned char *membase = pMemory + (i * stride);
1354 unsigned u;
1356 for (u=0; u<count; u++,info+=8) {
1357 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1358 unsigned char *saved_memory = pStubMsg->Memory;
1360 pStubMsg->Memory = pMemory;
1361 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1362 pStubMsg->Memory = saved_memory;
1365 pFormat += 8 * count;
1368 if (saved_buffer_length)
1370 pStubMsg->PointerLength = pStubMsg->BufferLength;
1371 pStubMsg->BufferLength = saved_buffer_length;
1375 /***********************************************************************
1376 * EmbeddedPointerMemorySize [internal]
1378 static ULONG EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1379 PFORMAT_STRING pFormat)
1381 unsigned char *Mark = pStubMsg->BufferMark;
1382 unsigned rep, count, stride;
1383 unsigned i;
1384 unsigned char *saved_buffer = NULL;
1386 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1388 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1390 if (pStubMsg->PointerBufferMark)
1392 saved_buffer = pStubMsg->Buffer;
1393 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1394 pStubMsg->PointerBufferMark = NULL;
1397 if (*pFormat != RPC_FC_PP) return 0;
1398 pFormat += 2;
1400 while (pFormat[0] != RPC_FC_END) {
1401 switch (pFormat[0]) {
1402 default:
1403 FIXME("unknown repeat type %d\n", pFormat[0]);
1404 case RPC_FC_NO_REPEAT:
1405 rep = 1;
1406 stride = 0;
1407 count = 1;
1408 pFormat += 2;
1409 break;
1410 case RPC_FC_FIXED_REPEAT:
1411 rep = *(const WORD*)&pFormat[2];
1412 stride = *(const WORD*)&pFormat[4];
1413 count = *(const WORD*)&pFormat[8];
1414 pFormat += 10;
1415 break;
1416 case RPC_FC_VARIABLE_REPEAT:
1417 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1418 stride = *(const WORD*)&pFormat[2];
1419 count = *(const WORD*)&pFormat[6];
1420 pFormat += 8;
1421 break;
1423 for (i = 0; i < rep; i++) {
1424 PFORMAT_STRING info = pFormat;
1425 unsigned char *bufbase = Mark + (i * stride);
1426 unsigned u;
1427 for (u=0; u<count; u++,info+=8) {
1428 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1429 PointerMemorySize(pStubMsg, bufptr, info+4);
1432 pFormat += 8 * count;
1435 if (saved_buffer)
1437 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1438 pStubMsg->Buffer = saved_buffer;
1441 return 0;
1444 /***********************************************************************
1445 * EmbeddedPointerFree [internal]
1447 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1448 unsigned char *pMemory,
1449 PFORMAT_STRING pFormat)
1451 unsigned rep, count, stride;
1452 unsigned i;
1454 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1455 if (*pFormat != RPC_FC_PP) return;
1456 pFormat += 2;
1458 while (pFormat[0] != RPC_FC_END) {
1459 switch (pFormat[0]) {
1460 default:
1461 FIXME("unknown repeat type %d\n", pFormat[0]);
1462 case RPC_FC_NO_REPEAT:
1463 rep = 1;
1464 stride = 0;
1465 count = 1;
1466 pFormat += 2;
1467 break;
1468 case RPC_FC_FIXED_REPEAT:
1469 rep = *(const WORD*)&pFormat[2];
1470 stride = *(const WORD*)&pFormat[4];
1471 count = *(const WORD*)&pFormat[8];
1472 pFormat += 10;
1473 break;
1474 case RPC_FC_VARIABLE_REPEAT:
1475 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1476 stride = *(const WORD*)&pFormat[2];
1477 count = *(const WORD*)&pFormat[6];
1478 pFormat += 8;
1479 break;
1481 for (i = 0; i < rep; i++) {
1482 PFORMAT_STRING info = pFormat;
1483 unsigned char *membase = pMemory + (i * stride);
1484 unsigned u;
1486 for (u=0; u<count; u++,info+=8) {
1487 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1488 unsigned char *saved_memory = pStubMsg->Memory;
1490 pStubMsg->Memory = pMemory;
1491 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1492 pStubMsg->Memory = saved_memory;
1495 pFormat += 8 * count;
1499 /***********************************************************************
1500 * NdrPointerMarshall [RPCRT4.@]
1502 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1503 unsigned char *pMemory,
1504 PFORMAT_STRING pFormat)
1506 unsigned char *Buffer;
1508 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1510 /* Increment the buffer here instead of in PointerMarshall,
1511 * as that is used by embedded pointers which already handle the incrementing
1512 * the buffer, and shouldn't write any additional pointer data to the wire */
1513 if (*pFormat != RPC_FC_RP)
1515 align_pointer_clear(&pStubMsg->Buffer, 4);
1516 Buffer = pStubMsg->Buffer;
1517 safe_buffer_increment(pStubMsg, 4);
1519 else
1520 Buffer = pStubMsg->Buffer;
1522 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1524 return NULL;
1527 /***********************************************************************
1528 * NdrPointerUnmarshall [RPCRT4.@]
1530 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1531 unsigned char **ppMemory,
1532 PFORMAT_STRING pFormat,
1533 unsigned char fMustAlloc)
1535 unsigned char *Buffer;
1537 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1539 if (*pFormat == RPC_FC_RP)
1541 Buffer = pStubMsg->Buffer;
1542 /* Do the NULL ref pointer check here because embedded pointers can be
1543 * NULL if the type the pointer is embedded in was allocated rather than
1544 * being passed in by the client */
1545 if (pStubMsg->IsClient && !*ppMemory)
1547 ERR("NULL ref pointer is not allowed\n");
1548 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1551 else
1553 /* Increment the buffer here instead of in PointerUnmarshall,
1554 * as that is used by embedded pointers which already handle the incrementing
1555 * the buffer, and shouldn't read any additional pointer data from the
1556 * buffer */
1557 align_pointer(&pStubMsg->Buffer, 4);
1558 Buffer = pStubMsg->Buffer;
1559 safe_buffer_increment(pStubMsg, 4);
1562 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1564 return NULL;
1567 /***********************************************************************
1568 * NdrPointerBufferSize [RPCRT4.@]
1570 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1571 unsigned char *pMemory,
1572 PFORMAT_STRING pFormat)
1574 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1576 /* Increment the buffer length here instead of in PointerBufferSize,
1577 * as that is used by embedded pointers which already handle the buffer
1578 * length, and shouldn't write anything more to the wire */
1579 if (*pFormat != RPC_FC_RP)
1581 align_length(&pStubMsg->BufferLength, 4);
1582 safe_buffer_length_increment(pStubMsg, 4);
1585 PointerBufferSize(pStubMsg, pMemory, pFormat);
1588 /***********************************************************************
1589 * NdrPointerMemorySize [RPCRT4.@]
1591 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1592 PFORMAT_STRING pFormat)
1594 unsigned char *Buffer = pStubMsg->Buffer;
1595 if (*pFormat != RPC_FC_RP)
1597 align_pointer(&pStubMsg->Buffer, 4);
1598 safe_buffer_increment(pStubMsg, 4);
1600 align_length(&pStubMsg->MemorySize, sizeof(void *));
1601 return PointerMemorySize(pStubMsg, Buffer, pFormat);
1604 /***********************************************************************
1605 * NdrPointerFree [RPCRT4.@]
1607 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1608 unsigned char *pMemory,
1609 PFORMAT_STRING pFormat)
1611 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1612 PointerFree(pStubMsg, pMemory, pFormat);
1615 /***********************************************************************
1616 * NdrSimpleTypeMarshall [RPCRT4.@]
1618 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1619 unsigned char FormatChar )
1621 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1624 /***********************************************************************
1625 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1627 * Unmarshall a base type.
1629 * NOTES
1630 * Doesn't check that the buffer is long enough before copying, so the caller
1631 * should do this.
1633 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1634 unsigned char FormatChar )
1636 #define BASE_TYPE_UNMARSHALL(type) \
1637 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
1638 TRACE("pMemory: %p\n", pMemory); \
1639 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1640 pStubMsg->Buffer += sizeof(type);
1642 switch(FormatChar)
1644 case RPC_FC_BYTE:
1645 case RPC_FC_CHAR:
1646 case RPC_FC_SMALL:
1647 case RPC_FC_USMALL:
1648 BASE_TYPE_UNMARSHALL(UCHAR);
1649 TRACE("value: 0x%02x\n", *pMemory);
1650 break;
1651 case RPC_FC_WCHAR:
1652 case RPC_FC_SHORT:
1653 case RPC_FC_USHORT:
1654 BASE_TYPE_UNMARSHALL(USHORT);
1655 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
1656 break;
1657 case RPC_FC_LONG:
1658 case RPC_FC_ULONG:
1659 case RPC_FC_ERROR_STATUS_T:
1660 case RPC_FC_ENUM32:
1661 BASE_TYPE_UNMARSHALL(ULONG);
1662 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
1663 break;
1664 case RPC_FC_FLOAT:
1665 BASE_TYPE_UNMARSHALL(float);
1666 TRACE("value: %f\n", *(float *)pMemory);
1667 break;
1668 case RPC_FC_DOUBLE:
1669 BASE_TYPE_UNMARSHALL(double);
1670 TRACE("value: %f\n", *(double *)pMemory);
1671 break;
1672 case RPC_FC_HYPER:
1673 BASE_TYPE_UNMARSHALL(ULONGLONG);
1674 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
1675 break;
1676 case RPC_FC_ENUM16:
1677 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
1678 TRACE("pMemory: %p\n", pMemory);
1679 /* 16-bits on the wire, but int in memory */
1680 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
1681 pStubMsg->Buffer += sizeof(USHORT);
1682 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
1683 break;
1684 case RPC_FC_INT3264:
1685 align_pointer(&pStubMsg->Buffer, sizeof(INT));
1686 /* 32-bits on the wire, but int_ptr in memory */
1687 *(INT_PTR *)pMemory = *(INT *)pStubMsg->Buffer;
1688 pStubMsg->Buffer += sizeof(INT);
1689 TRACE("value: 0x%08lx\n", *(INT_PTR *)pMemory);
1690 break;
1691 case RPC_FC_UINT3264:
1692 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
1693 /* 32-bits on the wire, but int_ptr in memory */
1694 *(UINT_PTR *)pMemory = *(UINT *)pStubMsg->Buffer;
1695 pStubMsg->Buffer += sizeof(UINT);
1696 TRACE("value: 0x%08lx\n", *(UINT_PTR *)pMemory);
1697 break;
1698 case RPC_FC_IGNORE:
1699 break;
1700 default:
1701 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
1703 #undef BASE_TYPE_UNMARSHALL
1706 /***********************************************************************
1707 * NdrSimpleStructMarshall [RPCRT4.@]
1709 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1710 unsigned char *pMemory,
1711 PFORMAT_STRING pFormat)
1713 unsigned size = *(const WORD*)(pFormat+2);
1714 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1716 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1);
1718 pStubMsg->BufferMark = pStubMsg->Buffer;
1719 safe_copy_to_buffer(pStubMsg, pMemory, size);
1721 if (pFormat[0] != RPC_FC_STRUCT)
1722 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1724 return NULL;
1727 /***********************************************************************
1728 * NdrSimpleStructUnmarshall [RPCRT4.@]
1730 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1731 unsigned char **ppMemory,
1732 PFORMAT_STRING pFormat,
1733 unsigned char fMustAlloc)
1735 unsigned size = *(const WORD*)(pFormat+2);
1736 unsigned char *saved_buffer;
1737 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1739 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
1741 if (fMustAlloc)
1742 *ppMemory = NdrAllocate(pStubMsg, size);
1743 else
1745 if (!pStubMsg->IsClient && !*ppMemory)
1746 /* for servers, we just point straight into the RPC buffer */
1747 *ppMemory = pStubMsg->Buffer;
1750 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1751 safe_buffer_increment(pStubMsg, size);
1752 if (pFormat[0] == RPC_FC_PSTRUCT)
1753 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1755 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1756 if (*ppMemory != saved_buffer)
1757 memcpy(*ppMemory, saved_buffer, size);
1759 return NULL;
1762 /***********************************************************************
1763 * NdrSimpleStructBufferSize [RPCRT4.@]
1765 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1766 unsigned char *pMemory,
1767 PFORMAT_STRING pFormat)
1769 unsigned size = *(const WORD*)(pFormat+2);
1770 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1772 align_length(&pStubMsg->BufferLength, pFormat[1] + 1);
1774 safe_buffer_length_increment(pStubMsg, size);
1775 if (pFormat[0] != RPC_FC_STRUCT)
1776 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1779 /***********************************************************************
1780 * NdrSimpleStructMemorySize [RPCRT4.@]
1782 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1783 PFORMAT_STRING pFormat)
1785 unsigned short size = *(const WORD *)(pFormat+2);
1787 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1789 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
1790 pStubMsg->MemorySize += size;
1791 safe_buffer_increment(pStubMsg, size);
1793 if (pFormat[0] != RPC_FC_STRUCT)
1794 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1795 return pStubMsg->MemorySize;
1798 /***********************************************************************
1799 * NdrSimpleStructFree [RPCRT4.@]
1801 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1802 unsigned char *pMemory,
1803 PFORMAT_STRING pFormat)
1805 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1806 if (pFormat[0] != RPC_FC_STRUCT)
1807 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1810 /* Array helpers */
1812 static inline void array_compute_and_size_conformance(
1813 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1814 PFORMAT_STRING pFormat)
1816 DWORD count;
1818 switch (fc)
1820 case RPC_FC_CARRAY:
1821 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1822 SizeConformance(pStubMsg);
1823 break;
1824 case RPC_FC_CVARRAY:
1825 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1826 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1827 SizeConformance(pStubMsg);
1828 break;
1829 case RPC_FC_C_CSTRING:
1830 case RPC_FC_C_WSTRING:
1831 if (fc == RPC_FC_C_CSTRING)
1833 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1834 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1836 else
1838 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1839 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1842 if (pFormat[1] == RPC_FC_STRING_SIZED)
1843 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1844 else
1845 pStubMsg->MaxCount = pStubMsg->ActualCount;
1847 SizeConformance(pStubMsg);
1848 break;
1849 case RPC_FC_BOGUS_ARRAY:
1850 count = *(const WORD *)(pFormat + 2);
1851 pFormat += 4;
1852 if (IsConformanceOrVariancePresent(pFormat)) SizeConformance(pStubMsg);
1853 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, count);
1854 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
1855 break;
1856 default:
1857 ERR("unknown array format 0x%x\n", fc);
1858 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1862 static inline void array_buffer_size(
1863 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1864 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1866 DWORD i, size;
1867 DWORD esize;
1868 unsigned char alignment;
1870 switch (fc)
1872 case RPC_FC_CARRAY:
1873 esize = *(const WORD*)(pFormat+2);
1874 alignment = pFormat[1] + 1;
1876 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1878 align_length(&pStubMsg->BufferLength, alignment);
1880 size = safe_multiply(esize, pStubMsg->MaxCount);
1881 /* conformance value plus array */
1882 safe_buffer_length_increment(pStubMsg, size);
1884 if (fHasPointers)
1885 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1886 break;
1887 case RPC_FC_CVARRAY:
1888 esize = *(const WORD*)(pFormat+2);
1889 alignment = pFormat[1] + 1;
1891 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1892 pFormat = SkipVariance(pStubMsg, pFormat);
1894 SizeVariance(pStubMsg);
1896 align_length(&pStubMsg->BufferLength, alignment);
1898 size = safe_multiply(esize, pStubMsg->ActualCount);
1899 safe_buffer_length_increment(pStubMsg, size);
1901 if (fHasPointers)
1902 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1903 break;
1904 case RPC_FC_C_CSTRING:
1905 case RPC_FC_C_WSTRING:
1906 if (fc == RPC_FC_C_CSTRING)
1907 esize = 1;
1908 else
1909 esize = 2;
1911 SizeVariance(pStubMsg);
1913 size = safe_multiply(esize, pStubMsg->ActualCount);
1914 safe_buffer_length_increment(pStubMsg, size);
1915 break;
1916 case RPC_FC_BOGUS_ARRAY:
1917 alignment = pFormat[1] + 1;
1918 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1919 if (IsConformanceOrVariancePresent(pFormat)) SizeVariance(pStubMsg);
1920 pFormat = SkipVariance(pStubMsg, pFormat);
1922 align_length(&pStubMsg->BufferLength, alignment);
1924 size = pStubMsg->ActualCount;
1925 for (i = 0; i < size; i++)
1926 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
1927 break;
1928 default:
1929 ERR("unknown array format 0x%x\n", fc);
1930 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1934 static inline void array_compute_and_write_conformance(
1935 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1936 PFORMAT_STRING pFormat)
1938 ULONG def;
1939 BOOL conformance_present;
1941 switch (fc)
1943 case RPC_FC_CARRAY:
1944 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1945 WriteConformance(pStubMsg);
1946 break;
1947 case RPC_FC_CVARRAY:
1948 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1949 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1950 WriteConformance(pStubMsg);
1951 break;
1952 case RPC_FC_C_CSTRING:
1953 case RPC_FC_C_WSTRING:
1954 if (fc == RPC_FC_C_CSTRING)
1956 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1957 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1959 else
1961 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1962 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1964 if (pFormat[1] == RPC_FC_STRING_SIZED)
1965 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1966 else
1967 pStubMsg->MaxCount = pStubMsg->ActualCount;
1968 pStubMsg->Offset = 0;
1969 WriteConformance(pStubMsg);
1970 break;
1971 case RPC_FC_BOGUS_ARRAY:
1972 def = *(const WORD *)(pFormat + 2);
1973 pFormat += 4;
1974 conformance_present = IsConformanceOrVariancePresent(pFormat);
1975 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
1976 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
1977 if (conformance_present) WriteConformance(pStubMsg);
1978 break;
1979 default:
1980 ERR("unknown array format 0x%x\n", fc);
1981 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1985 static inline void array_write_variance_and_marshall(
1986 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1987 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1989 DWORD i, size;
1990 DWORD esize;
1991 unsigned char alignment;
1993 switch (fc)
1995 case RPC_FC_CARRAY:
1996 esize = *(const WORD*)(pFormat+2);
1997 alignment = pFormat[1] + 1;
1999 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2001 align_pointer_clear(&pStubMsg->Buffer, alignment);
2003 size = safe_multiply(esize, pStubMsg->MaxCount);
2004 if (fHasPointers)
2005 pStubMsg->BufferMark = pStubMsg->Buffer;
2006 safe_copy_to_buffer(pStubMsg, pMemory, size);
2008 if (fHasPointers)
2009 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2010 break;
2011 case RPC_FC_CVARRAY:
2012 esize = *(const WORD*)(pFormat+2);
2013 alignment = pFormat[1] + 1;
2015 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2016 pFormat = SkipVariance(pStubMsg, pFormat);
2018 WriteVariance(pStubMsg);
2020 align_pointer_clear(&pStubMsg->Buffer, alignment);
2022 size = safe_multiply(esize, pStubMsg->ActualCount);
2024 if (fHasPointers)
2025 pStubMsg->BufferMark = pStubMsg->Buffer;
2026 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size);
2028 if (fHasPointers)
2029 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2030 break;
2031 case RPC_FC_C_CSTRING:
2032 case RPC_FC_C_WSTRING:
2033 if (fc == RPC_FC_C_CSTRING)
2034 esize = 1;
2035 else
2036 esize = 2;
2038 WriteVariance(pStubMsg);
2040 size = safe_multiply(esize, pStubMsg->ActualCount);
2041 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2042 break;
2043 case RPC_FC_BOGUS_ARRAY:
2044 alignment = pFormat[1] + 1;
2045 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2046 if (IsConformanceOrVariancePresent(pFormat)) WriteVariance(pStubMsg);
2047 pFormat = SkipVariance(pStubMsg, pFormat);
2049 align_pointer_clear(&pStubMsg->Buffer, alignment);
2051 size = pStubMsg->ActualCount;
2052 for (i = 0; i < size; i++)
2053 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2054 break;
2055 default:
2056 ERR("unknown array format 0x%x\n", fc);
2057 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2061 static inline ULONG array_read_conformance(
2062 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
2064 DWORD def, esize;
2066 switch (fc)
2068 case RPC_FC_CARRAY:
2069 esize = *(const WORD*)(pFormat+2);
2070 pFormat = ReadConformance(pStubMsg, pFormat+4);
2071 return safe_multiply(esize, pStubMsg->MaxCount);
2072 case RPC_FC_CVARRAY:
2073 esize = *(const WORD*)(pFormat+2);
2074 pFormat = ReadConformance(pStubMsg, pFormat+4);
2075 return safe_multiply(esize, pStubMsg->MaxCount);
2076 case RPC_FC_C_CSTRING:
2077 case RPC_FC_C_WSTRING:
2078 if (fc == RPC_FC_C_CSTRING)
2079 esize = 1;
2080 else
2081 esize = 2;
2083 if (pFormat[1] == RPC_FC_STRING_SIZED)
2084 ReadConformance(pStubMsg, pFormat + 2);
2085 else
2086 ReadConformance(pStubMsg, NULL);
2087 return safe_multiply(esize, pStubMsg->MaxCount);
2088 case RPC_FC_BOGUS_ARRAY:
2089 def = *(const WORD *)(pFormat + 2);
2090 pFormat += 4;
2091 if (IsConformanceOrVariancePresent(pFormat)) pFormat = ReadConformance(pStubMsg, pFormat);
2092 else
2094 pStubMsg->MaxCount = def;
2095 pFormat = SkipConformance( pStubMsg, pFormat );
2097 pFormat = SkipVariance( pStubMsg, pFormat );
2099 esize = ComplexStructSize(pStubMsg, pFormat);
2100 return safe_multiply(pStubMsg->MaxCount, esize);
2101 default:
2102 ERR("unknown array format 0x%x\n", fc);
2103 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2107 static inline ULONG array_read_variance_and_unmarshall(
2108 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory,
2109 PFORMAT_STRING pFormat, unsigned char fMustAlloc,
2110 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall)
2112 ULONG bufsize, memsize;
2113 WORD esize;
2114 unsigned char alignment;
2115 unsigned char *saved_buffer, *pMemory;
2116 ULONG i, offset, count;
2118 switch (fc)
2120 case RPC_FC_CARRAY:
2121 esize = *(const WORD*)(pFormat+2);
2122 alignment = pFormat[1] + 1;
2124 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2126 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2128 align_pointer(&pStubMsg->Buffer, alignment);
2130 if (fUnmarshall)
2132 if (fMustAlloc)
2133 *ppMemory = NdrAllocate(pStubMsg, memsize);
2134 else
2136 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory)
2137 /* for servers, we just point straight into the RPC buffer */
2138 *ppMemory = pStubMsg->Buffer;
2141 saved_buffer = pStubMsg->Buffer;
2142 safe_buffer_increment(pStubMsg, bufsize);
2144 pStubMsg->BufferMark = saved_buffer;
2145 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2147 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2148 if (*ppMemory != saved_buffer)
2149 memcpy(*ppMemory, saved_buffer, bufsize);
2151 return bufsize;
2152 case RPC_FC_CVARRAY:
2153 esize = *(const WORD*)(pFormat+2);
2154 alignment = pFormat[1] + 1;
2156 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2158 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2160 align_pointer(&pStubMsg->Buffer, alignment);
2162 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2163 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2165 if (fUnmarshall)
2167 offset = pStubMsg->Offset;
2169 if (!fMustAlloc && !*ppMemory)
2170 fMustAlloc = TRUE;
2171 if (fMustAlloc)
2172 *ppMemory = NdrAllocate(pStubMsg, memsize);
2173 saved_buffer = pStubMsg->Buffer;
2174 safe_buffer_increment(pStubMsg, bufsize);
2176 pStubMsg->BufferMark = saved_buffer;
2177 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat,
2178 fMustAlloc);
2180 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2182 return bufsize;
2183 case RPC_FC_C_CSTRING:
2184 case RPC_FC_C_WSTRING:
2185 if (fc == RPC_FC_C_CSTRING)
2186 esize = 1;
2187 else
2188 esize = 2;
2190 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2192 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2194 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2195 pStubMsg->ActualCount, pStubMsg->MaxCount);
2196 RpcRaiseException(RPC_S_INVALID_BOUND);
2198 if (pStubMsg->Offset)
2200 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2201 RpcRaiseException(RPC_S_INVALID_BOUND);
2204 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2205 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2207 validate_string_data(pStubMsg, bufsize, esize);
2209 if (fUnmarshall)
2211 if (fMustAlloc)
2212 *ppMemory = NdrAllocate(pStubMsg, memsize);
2213 else
2215 if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
2216 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
2217 /* if the data in the RPC buffer is big enough, we just point
2218 * straight into it */
2219 *ppMemory = pStubMsg->Buffer;
2220 else if (!*ppMemory)
2221 *ppMemory = NdrAllocate(pStubMsg, memsize);
2224 if (*ppMemory == pStubMsg->Buffer)
2225 safe_buffer_increment(pStubMsg, bufsize);
2226 else
2227 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2229 if (*pFormat == RPC_FC_C_CSTRING)
2230 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
2231 else
2232 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
2234 return bufsize;
2236 case RPC_FC_BOGUS_ARRAY:
2237 alignment = pFormat[1] + 1;
2238 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2239 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2241 esize = ComplexStructSize(pStubMsg, pFormat);
2242 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2244 assert( fUnmarshall );
2246 if (!fMustAlloc && !*ppMemory)
2247 fMustAlloc = TRUE;
2248 if (fMustAlloc)
2249 *ppMemory = NdrAllocate(pStubMsg, memsize);
2251 align_pointer(&pStubMsg->Buffer, alignment);
2252 saved_buffer = pStubMsg->Buffer;
2254 pMemory = *ppMemory;
2255 count = pStubMsg->ActualCount;
2256 for (i = 0; i < count; i++)
2257 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
2258 return pStubMsg->Buffer - saved_buffer;
2260 default:
2261 ERR("unknown array format 0x%x\n", fc);
2262 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2266 static inline void array_memory_size(
2267 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
2268 unsigned char fHasPointers)
2270 ULONG i, count, SavedMemorySize;
2271 ULONG bufsize, memsize;
2272 DWORD esize;
2273 unsigned char alignment;
2275 switch (fc)
2277 case RPC_FC_CARRAY:
2278 esize = *(const WORD*)(pFormat+2);
2279 alignment = pFormat[1] + 1;
2281 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2283 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2284 pStubMsg->MemorySize += memsize;
2286 align_pointer(&pStubMsg->Buffer, alignment);
2287 if (fHasPointers)
2288 pStubMsg->BufferMark = pStubMsg->Buffer;
2289 safe_buffer_increment(pStubMsg, bufsize);
2291 if (fHasPointers)
2292 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2293 break;
2294 case RPC_FC_CVARRAY:
2295 esize = *(const WORD*)(pFormat+2);
2296 alignment = pFormat[1] + 1;
2298 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2300 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2302 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2303 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2304 pStubMsg->MemorySize += memsize;
2306 align_pointer(&pStubMsg->Buffer, alignment);
2307 if (fHasPointers)
2308 pStubMsg->BufferMark = pStubMsg->Buffer;
2309 safe_buffer_increment(pStubMsg, bufsize);
2311 if (fHasPointers)
2312 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2313 break;
2314 case RPC_FC_C_CSTRING:
2315 case RPC_FC_C_WSTRING:
2316 if (fc == RPC_FC_C_CSTRING)
2317 esize = 1;
2318 else
2319 esize = 2;
2321 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2323 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2325 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2326 pStubMsg->ActualCount, pStubMsg->MaxCount);
2327 RpcRaiseException(RPC_S_INVALID_BOUND);
2329 if (pStubMsg->Offset)
2331 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2332 RpcRaiseException(RPC_S_INVALID_BOUND);
2335 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2336 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2338 validate_string_data(pStubMsg, bufsize, esize);
2340 safe_buffer_increment(pStubMsg, bufsize);
2341 pStubMsg->MemorySize += memsize;
2342 break;
2343 case RPC_FC_BOGUS_ARRAY:
2344 alignment = pFormat[1] + 1;
2345 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2346 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2348 align_pointer(&pStubMsg->Buffer, alignment);
2350 SavedMemorySize = pStubMsg->MemorySize;
2352 esize = ComplexStructSize(pStubMsg, pFormat);
2353 memsize = safe_multiply(pStubMsg->MaxCount, esize);
2355 count = pStubMsg->ActualCount;
2356 for (i = 0; i < count; i++)
2357 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
2359 pStubMsg->MemorySize = SavedMemorySize + memsize;
2360 break;
2361 default:
2362 ERR("unknown array format 0x%x\n", fc);
2363 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2367 static inline void array_free(
2368 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
2369 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
2371 DWORD i, count;
2373 switch (fc)
2375 case RPC_FC_CARRAY:
2376 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2377 if (fHasPointers)
2378 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2379 break;
2380 case RPC_FC_CVARRAY:
2381 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2382 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2383 if (fHasPointers)
2384 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2385 break;
2386 case RPC_FC_C_CSTRING:
2387 case RPC_FC_C_WSTRING:
2388 /* No embedded pointers so nothing to do */
2389 break;
2390 case RPC_FC_BOGUS_ARRAY:
2391 count = *(const WORD *)(pFormat + 2);
2392 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, count);
2393 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2395 count = pStubMsg->ActualCount;
2396 for (i = 0; i < count; i++)
2397 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2398 break;
2399 default:
2400 ERR("unknown array format 0x%x\n", fc);
2401 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2406 * NdrConformantString:
2408 * What MS calls a ConformantString is, in DCE terminology,
2409 * a Varying-Conformant String.
2411 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2412 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2413 * into unmarshalled string)
2414 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2416 * data: CHARTYPE[maxlen]
2418 * ], where CHARTYPE is the appropriate character type (specified externally)
2422 /***********************************************************************
2423 * NdrConformantStringMarshall [RPCRT4.@]
2425 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
2426 unsigned char *pszMessage, PFORMAT_STRING pFormat)
2428 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
2430 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2431 ERR("Unhandled string type: %#x\n", pFormat[0]);
2432 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2435 /* allow compiler to optimise inline function by passing constant into
2436 * these functions */
2437 if (pFormat[0] == RPC_FC_C_CSTRING) {
2438 array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2439 pFormat);
2440 array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2441 pFormat, TRUE /* fHasPointers */);
2442 } else {
2443 array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2444 pFormat);
2445 array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2446 pFormat, TRUE /* fHasPointers */);
2449 return NULL;
2452 /***********************************************************************
2453 * NdrConformantStringBufferSize [RPCRT4.@]
2455 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2456 unsigned char* pMemory, PFORMAT_STRING pFormat)
2458 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2460 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2461 ERR("Unhandled string type: %#x\n", pFormat[0]);
2462 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2465 /* allow compiler to optimise inline function by passing constant into
2466 * these functions */
2467 if (pFormat[0] == RPC_FC_C_CSTRING) {
2468 array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory,
2469 pFormat);
2470 array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat,
2471 TRUE /* fHasPointers */);
2472 } else {
2473 array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory,
2474 pFormat);
2475 array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat,
2476 TRUE /* fHasPointers */);
2480 /************************************************************************
2481 * NdrConformantStringMemorySize [RPCRT4.@]
2483 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2484 PFORMAT_STRING pFormat )
2486 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2488 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2489 ERR("Unhandled string type: %#x\n", pFormat[0]);
2490 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2493 /* allow compiler to optimise inline function by passing constant into
2494 * these functions */
2495 if (pFormat[0] == RPC_FC_C_CSTRING) {
2496 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2497 array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat,
2498 TRUE /* fHasPointers */);
2499 } else {
2500 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2501 array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat,
2502 TRUE /* fHasPointers */);
2505 return pStubMsg->MemorySize;
2508 /************************************************************************
2509 * NdrConformantStringUnmarshall [RPCRT4.@]
2511 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2512 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
2514 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2515 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2517 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2518 ERR("Unhandled string type: %#x\n", *pFormat);
2519 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2522 /* allow compiler to optimise inline function by passing constant into
2523 * these functions */
2524 if (pFormat[0] == RPC_FC_C_CSTRING) {
2525 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2526 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory,
2527 pFormat, fMustAlloc,
2528 TRUE /* fUseBufferMemoryServer */,
2529 TRUE /* fUnmarshall */);
2530 } else {
2531 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2532 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory,
2533 pFormat, fMustAlloc,
2534 TRUE /* fUseBufferMemoryServer */,
2535 TRUE /* fUnmarshall */);
2538 return NULL;
2541 /***********************************************************************
2542 * NdrNonConformantStringMarshall [RPCRT4.@]
2544 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2545 unsigned char *pMemory,
2546 PFORMAT_STRING pFormat)
2548 ULONG esize, size, maxsize;
2550 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2552 maxsize = *(const USHORT *)&pFormat[2];
2554 if (*pFormat == RPC_FC_CSTRING)
2556 ULONG i = 0;
2557 const char *str = (const char *)pMemory;
2558 while (i < maxsize && str[i]) i++;
2559 TRACE("string=%s\n", debugstr_an(str, i));
2560 pStubMsg->ActualCount = i + 1;
2561 esize = 1;
2563 else if (*pFormat == RPC_FC_WSTRING)
2565 ULONG i = 0;
2566 const WCHAR *str = (const WCHAR *)pMemory;
2567 while (i < maxsize && str[i]) i++;
2568 TRACE("string=%s\n", debugstr_wn(str, i));
2569 pStubMsg->ActualCount = i + 1;
2570 esize = 2;
2572 else
2574 ERR("Unhandled string type: %#x\n", *pFormat);
2575 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2578 pStubMsg->Offset = 0;
2579 WriteVariance(pStubMsg);
2581 size = safe_multiply(esize, pStubMsg->ActualCount);
2582 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2584 return NULL;
2587 /***********************************************************************
2588 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2590 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2591 unsigned char **ppMemory,
2592 PFORMAT_STRING pFormat,
2593 unsigned char fMustAlloc)
2595 ULONG bufsize, memsize, esize, maxsize;
2597 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2598 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2600 maxsize = *(const USHORT *)&pFormat[2];
2602 ReadVariance(pStubMsg, NULL, maxsize);
2603 if (pStubMsg->Offset)
2605 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2606 RpcRaiseException(RPC_S_INVALID_BOUND);
2609 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2610 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2611 else
2613 ERR("Unhandled string type: %#x\n", *pFormat);
2614 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2617 memsize = esize * maxsize;
2618 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2620 validate_string_data(pStubMsg, bufsize, esize);
2622 if (!fMustAlloc && !*ppMemory)
2623 fMustAlloc = TRUE;
2624 if (fMustAlloc)
2625 *ppMemory = NdrAllocate(pStubMsg, memsize);
2627 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2629 if (*pFormat == RPC_FC_CSTRING) {
2630 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
2632 else if (*pFormat == RPC_FC_WSTRING) {
2633 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
2636 return NULL;
2639 /***********************************************************************
2640 * NdrNonConformantStringBufferSize [RPCRT4.@]
2642 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2643 unsigned char *pMemory,
2644 PFORMAT_STRING pFormat)
2646 ULONG esize, maxsize;
2648 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2650 maxsize = *(const USHORT *)&pFormat[2];
2652 SizeVariance(pStubMsg);
2654 if (*pFormat == RPC_FC_CSTRING)
2656 ULONG i = 0;
2657 const char *str = (const char *)pMemory;
2658 while (i < maxsize && str[i]) i++;
2659 TRACE("string=%s\n", debugstr_an(str, i));
2660 pStubMsg->ActualCount = i + 1;
2661 esize = 1;
2663 else if (*pFormat == RPC_FC_WSTRING)
2665 ULONG i = 0;
2666 const WCHAR *str = (const WCHAR *)pMemory;
2667 while (i < maxsize && str[i]) i++;
2668 TRACE("string=%s\n", debugstr_wn(str, i));
2669 pStubMsg->ActualCount = i + 1;
2670 esize = 2;
2672 else
2674 ERR("Unhandled string type: %#x\n", *pFormat);
2675 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2678 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2681 /***********************************************************************
2682 * NdrNonConformantStringMemorySize [RPCRT4.@]
2684 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2685 PFORMAT_STRING pFormat)
2687 ULONG bufsize, memsize, esize, maxsize;
2689 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2691 maxsize = *(const USHORT *)&pFormat[2];
2693 ReadVariance(pStubMsg, NULL, maxsize);
2695 if (pStubMsg->Offset)
2697 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2698 RpcRaiseException(RPC_S_INVALID_BOUND);
2701 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2702 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2703 else
2705 ERR("Unhandled string type: %#x\n", *pFormat);
2706 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2709 memsize = esize * maxsize;
2710 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2712 validate_string_data(pStubMsg, bufsize, esize);
2714 safe_buffer_increment(pStubMsg, bufsize);
2715 pStubMsg->MemorySize += memsize;
2717 return pStubMsg->MemorySize;
2720 /* Complex types */
2722 #include "pshpack1.h"
2723 typedef struct
2725 unsigned char type;
2726 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2727 ULONG low_value;
2728 ULONG high_value;
2729 } NDR_RANGE;
2730 #include "poppack.h"
2732 static ULONG EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2733 PFORMAT_STRING pFormat)
2735 switch (*pFormat) {
2736 case RPC_FC_STRUCT:
2737 case RPC_FC_PSTRUCT:
2738 case RPC_FC_CSTRUCT:
2739 case RPC_FC_BOGUS_STRUCT:
2740 case RPC_FC_SMFARRAY:
2741 case RPC_FC_SMVARRAY:
2742 case RPC_FC_CSTRING:
2743 return *(const WORD*)&pFormat[2];
2744 case RPC_FC_USER_MARSHAL:
2745 return *(const WORD*)&pFormat[4];
2746 case RPC_FC_RANGE: {
2747 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2748 case RPC_FC_BYTE:
2749 case RPC_FC_CHAR:
2750 case RPC_FC_SMALL:
2751 case RPC_FC_USMALL:
2752 return sizeof(UCHAR);
2753 case RPC_FC_WCHAR:
2754 case RPC_FC_SHORT:
2755 case RPC_FC_USHORT:
2756 return sizeof(USHORT);
2757 case RPC_FC_LONG:
2758 case RPC_FC_ULONG:
2759 case RPC_FC_ENUM32:
2760 case RPC_FC_INT3264:
2761 case RPC_FC_UINT3264:
2762 return sizeof(ULONG);
2763 case RPC_FC_FLOAT:
2764 return sizeof(float);
2765 case RPC_FC_DOUBLE:
2766 return sizeof(double);
2767 case RPC_FC_HYPER:
2768 return sizeof(ULONGLONG);
2769 case RPC_FC_ENUM16:
2770 return sizeof(UINT);
2771 default:
2772 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2773 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2776 case RPC_FC_NON_ENCAPSULATED_UNION:
2777 pFormat += 2;
2778 if (pStubMsg->fHasNewCorrDesc)
2779 pFormat += 6;
2780 else
2781 pFormat += 4;
2783 pFormat += *(const SHORT*)pFormat;
2784 return *(const SHORT*)pFormat;
2785 case RPC_FC_IP:
2786 return sizeof(void *);
2787 case RPC_FC_WSTRING:
2788 return *(const WORD*)&pFormat[2] * 2;
2789 default:
2790 FIXME("unhandled embedded type %02x\n", *pFormat);
2792 return 0;
2796 static ULONG EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2797 PFORMAT_STRING pFormat)
2799 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2801 if (!m)
2803 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2804 return 0;
2807 return m(pStubMsg, pFormat);
2811 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2812 unsigned char *pMemory,
2813 PFORMAT_STRING pFormat,
2814 PFORMAT_STRING pPointer)
2816 PFORMAT_STRING desc;
2817 NDR_MARSHALL m;
2818 ULONG size;
2820 while (*pFormat != RPC_FC_END) {
2821 switch (*pFormat) {
2822 case RPC_FC_BYTE:
2823 case RPC_FC_CHAR:
2824 case RPC_FC_SMALL:
2825 case RPC_FC_USMALL:
2826 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2827 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2828 pMemory += 1;
2829 break;
2830 case RPC_FC_WCHAR:
2831 case RPC_FC_SHORT:
2832 case RPC_FC_USHORT:
2833 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2834 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2835 pMemory += 2;
2836 break;
2837 case RPC_FC_ENUM16:
2839 USHORT val = *(DWORD *)pMemory;
2840 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2841 if (32767 < *(DWORD*)pMemory)
2842 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2843 safe_copy_to_buffer(pStubMsg, &val, 2);
2844 pMemory += 4;
2845 break;
2847 case RPC_FC_LONG:
2848 case RPC_FC_ULONG:
2849 case RPC_FC_ENUM32:
2850 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2851 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2852 pMemory += 4;
2853 break;
2854 case RPC_FC_INT3264:
2855 case RPC_FC_UINT3264:
2857 UINT val = *(UINT_PTR *)pMemory;
2858 TRACE("int3264=%ld <= %p\n", *(UINT_PTR *)pMemory, pMemory);
2859 safe_copy_to_buffer(pStubMsg, &val, sizeof(UINT));
2860 pMemory += sizeof(UINT_PTR);
2861 break;
2863 case RPC_FC_FLOAT:
2864 TRACE("float=%f <= %p\n", *(float*)pMemory, pMemory);
2865 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
2866 pMemory += sizeof(float);
2867 break;
2868 case RPC_FC_HYPER:
2869 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2870 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2871 pMemory += 8;
2872 break;
2873 case RPC_FC_DOUBLE:
2874 TRACE("double=%f <= %p\n", *(double*)pMemory, pMemory);
2875 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
2876 pMemory += sizeof(double);
2877 break;
2878 case RPC_FC_RP:
2879 case RPC_FC_UP:
2880 case RPC_FC_OP:
2881 case RPC_FC_FP:
2882 case RPC_FC_POINTER:
2884 unsigned char *saved_buffer;
2885 int pointer_buffer_mark_set = 0;
2886 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2887 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2888 if (*pFormat != RPC_FC_POINTER)
2889 pPointer = pFormat;
2890 if (*pPointer != RPC_FC_RP)
2891 align_pointer_clear(&pStubMsg->Buffer, 4);
2892 saved_buffer = pStubMsg->Buffer;
2893 if (pStubMsg->PointerBufferMark)
2895 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2896 pStubMsg->PointerBufferMark = NULL;
2897 pointer_buffer_mark_set = 1;
2899 else if (*pPointer != RPC_FC_RP)
2900 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2901 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2902 if (pointer_buffer_mark_set)
2904 STD_OVERFLOW_CHECK(pStubMsg);
2905 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2906 pStubMsg->Buffer = saved_buffer;
2907 if (*pPointer != RPC_FC_RP)
2908 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2910 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2911 if (*pFormat == RPC_FC_POINTER)
2912 pPointer += 4;
2913 else
2914 pFormat += 4;
2915 pMemory += sizeof(void *);
2916 break;
2918 case RPC_FC_ALIGNM2:
2919 align_pointer(&pMemory, 2);
2920 break;
2921 case RPC_FC_ALIGNM4:
2922 align_pointer(&pMemory, 4);
2923 break;
2924 case RPC_FC_ALIGNM8:
2925 align_pointer(&pMemory, 8);
2926 break;
2927 case RPC_FC_STRUCTPAD1:
2928 case RPC_FC_STRUCTPAD2:
2929 case RPC_FC_STRUCTPAD3:
2930 case RPC_FC_STRUCTPAD4:
2931 case RPC_FC_STRUCTPAD5:
2932 case RPC_FC_STRUCTPAD6:
2933 case RPC_FC_STRUCTPAD7:
2934 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2935 break;
2936 case RPC_FC_EMBEDDED_COMPLEX:
2937 pMemory += pFormat[1];
2938 pFormat += 2;
2939 desc = pFormat + *(const SHORT*)pFormat;
2940 size = EmbeddedComplexSize(pStubMsg, desc);
2941 TRACE("embedded complex (size=%d) <= %p\n", size, pMemory);
2942 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2943 if (m)
2945 /* for some reason interface pointers aren't generated as
2946 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2947 * they still need the derefencing treatment that pointers are
2948 * given */
2949 if (*desc == RPC_FC_IP)
2950 m(pStubMsg, *(unsigned char **)pMemory, desc);
2951 else
2952 m(pStubMsg, pMemory, desc);
2954 else FIXME("no marshaller for embedded type %02x\n", *desc);
2955 pMemory += size;
2956 pFormat += 2;
2957 continue;
2958 case RPC_FC_PAD:
2959 break;
2960 default:
2961 FIXME("unhandled format 0x%02x\n", *pFormat);
2963 pFormat++;
2966 return pMemory;
2969 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2970 unsigned char *pMemory,
2971 PFORMAT_STRING pFormat,
2972 PFORMAT_STRING pPointer,
2973 unsigned char fMustAlloc)
2975 PFORMAT_STRING desc;
2976 NDR_UNMARSHALL m;
2977 ULONG size;
2979 while (*pFormat != RPC_FC_END) {
2980 switch (*pFormat) {
2981 case RPC_FC_BYTE:
2982 case RPC_FC_CHAR:
2983 case RPC_FC_SMALL:
2984 case RPC_FC_USMALL:
2985 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2986 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2987 pMemory += 1;
2988 break;
2989 case RPC_FC_WCHAR:
2990 case RPC_FC_SHORT:
2991 case RPC_FC_USHORT:
2992 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2993 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2994 pMemory += 2;
2995 break;
2996 case RPC_FC_ENUM16:
2998 WORD val;
2999 safe_copy_from_buffer(pStubMsg, &val, 2);
3000 *(DWORD*)pMemory = val;
3001 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
3002 if (32767 < *(DWORD*)pMemory)
3003 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
3004 pMemory += 4;
3005 break;
3007 case RPC_FC_LONG:
3008 case RPC_FC_ULONG:
3009 case RPC_FC_ENUM32:
3010 safe_copy_from_buffer(pStubMsg, pMemory, 4);
3011 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
3012 pMemory += 4;
3013 break;
3014 case RPC_FC_INT3264:
3016 INT val;
3017 safe_copy_from_buffer(pStubMsg, &val, 4);
3018 *(INT_PTR *)pMemory = val;
3019 TRACE("int3264=%ld => %p\n", *(INT_PTR*)pMemory, pMemory);
3020 pMemory += sizeof(INT_PTR);
3021 break;
3023 case RPC_FC_UINT3264:
3025 UINT val;
3026 safe_copy_from_buffer(pStubMsg, &val, 4);
3027 *(UINT_PTR *)pMemory = val;
3028 TRACE("uint3264=%ld => %p\n", *(UINT_PTR*)pMemory, pMemory);
3029 pMemory += sizeof(UINT_PTR);
3030 break;
3032 case RPC_FC_FLOAT:
3033 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(float));
3034 TRACE("float=%f => %p\n", *(float*)pMemory, pMemory);
3035 pMemory += sizeof(float);
3036 break;
3037 case RPC_FC_HYPER:
3038 safe_copy_from_buffer(pStubMsg, pMemory, 8);
3039 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
3040 pMemory += 8;
3041 break;
3042 case RPC_FC_DOUBLE:
3043 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(double));
3044 TRACE("double=%f => %p\n", *(double*)pMemory, pMemory);
3045 pMemory += sizeof(double);
3046 break;
3047 case RPC_FC_RP:
3048 case RPC_FC_UP:
3049 case RPC_FC_OP:
3050 case RPC_FC_FP:
3051 case RPC_FC_POINTER:
3053 unsigned char *saved_buffer;
3054 int pointer_buffer_mark_set = 0;
3055 TRACE("pointer => %p\n", pMemory);
3056 if (*pFormat != RPC_FC_POINTER)
3057 pPointer = pFormat;
3058 if (*pPointer != RPC_FC_RP)
3059 align_pointer(&pStubMsg->Buffer, 4);
3060 saved_buffer = pStubMsg->Buffer;
3061 if (pStubMsg->PointerBufferMark)
3063 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3064 pStubMsg->PointerBufferMark = NULL;
3065 pointer_buffer_mark_set = 1;
3067 else if (*pPointer != RPC_FC_RP)
3068 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3070 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
3071 if (pointer_buffer_mark_set)
3073 STD_OVERFLOW_CHECK(pStubMsg);
3074 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3075 pStubMsg->Buffer = saved_buffer;
3076 if (*pPointer != RPC_FC_RP)
3077 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3079 if (*pFormat == RPC_FC_POINTER)
3080 pPointer += 4;
3081 else
3082 pFormat += 4;
3083 pMemory += sizeof(void *);
3084 break;
3086 case RPC_FC_ALIGNM2:
3087 align_pointer_clear(&pMemory, 2);
3088 break;
3089 case RPC_FC_ALIGNM4:
3090 align_pointer_clear(&pMemory, 4);
3091 break;
3092 case RPC_FC_ALIGNM8:
3093 align_pointer_clear(&pMemory, 8);
3094 break;
3095 case RPC_FC_STRUCTPAD1:
3096 case RPC_FC_STRUCTPAD2:
3097 case RPC_FC_STRUCTPAD3:
3098 case RPC_FC_STRUCTPAD4:
3099 case RPC_FC_STRUCTPAD5:
3100 case RPC_FC_STRUCTPAD6:
3101 case RPC_FC_STRUCTPAD7:
3102 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
3103 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3104 break;
3105 case RPC_FC_EMBEDDED_COMPLEX:
3106 pMemory += pFormat[1];
3107 pFormat += 2;
3108 desc = pFormat + *(const SHORT*)pFormat;
3109 size = EmbeddedComplexSize(pStubMsg, desc);
3110 TRACE("embedded complex (size=%d) => %p\n", size, pMemory);
3111 if (fMustAlloc)
3112 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
3113 * since the type is part of the memory block that is encompassed by
3114 * the whole complex type. Memory is forced to allocate when pointers
3115 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
3116 * clearing the memory we pass in to the unmarshaller */
3117 memset(pMemory, 0, size);
3118 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
3119 if (m)
3121 /* for some reason interface pointers aren't generated as
3122 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3123 * they still need the derefencing treatment that pointers are
3124 * given */
3125 if (*desc == RPC_FC_IP)
3126 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
3127 else
3128 m(pStubMsg, &pMemory, desc, FALSE);
3130 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
3131 pMemory += size;
3132 pFormat += 2;
3133 continue;
3134 case RPC_FC_PAD:
3135 break;
3136 default:
3137 FIXME("unhandled format %d\n", *pFormat);
3139 pFormat++;
3142 return pMemory;
3145 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3146 unsigned char *pMemory,
3147 PFORMAT_STRING pFormat,
3148 PFORMAT_STRING pPointer)
3150 PFORMAT_STRING desc;
3151 NDR_BUFFERSIZE m;
3152 ULONG size;
3154 while (*pFormat != RPC_FC_END) {
3155 switch (*pFormat) {
3156 case RPC_FC_BYTE:
3157 case RPC_FC_CHAR:
3158 case RPC_FC_SMALL:
3159 case RPC_FC_USMALL:
3160 safe_buffer_length_increment(pStubMsg, 1);
3161 pMemory += 1;
3162 break;
3163 case RPC_FC_WCHAR:
3164 case RPC_FC_SHORT:
3165 case RPC_FC_USHORT:
3166 safe_buffer_length_increment(pStubMsg, 2);
3167 pMemory += 2;
3168 break;
3169 case RPC_FC_ENUM16:
3170 safe_buffer_length_increment(pStubMsg, 2);
3171 pMemory += 4;
3172 break;
3173 case RPC_FC_LONG:
3174 case RPC_FC_ULONG:
3175 case RPC_FC_ENUM32:
3176 case RPC_FC_FLOAT:
3177 safe_buffer_length_increment(pStubMsg, 4);
3178 pMemory += 4;
3179 break;
3180 case RPC_FC_INT3264:
3181 case RPC_FC_UINT3264:
3182 safe_buffer_length_increment(pStubMsg, 4);
3183 pMemory += sizeof(INT_PTR);
3184 break;
3185 case RPC_FC_HYPER:
3186 case RPC_FC_DOUBLE:
3187 safe_buffer_length_increment(pStubMsg, 8);
3188 pMemory += 8;
3189 break;
3190 case RPC_FC_RP:
3191 case RPC_FC_UP:
3192 case RPC_FC_OP:
3193 case RPC_FC_FP:
3194 case RPC_FC_POINTER:
3195 if (*pFormat != RPC_FC_POINTER)
3196 pPointer = pFormat;
3197 if (!pStubMsg->IgnoreEmbeddedPointers)
3199 int saved_buffer_length = pStubMsg->BufferLength;
3200 pStubMsg->BufferLength = pStubMsg->PointerLength;
3201 pStubMsg->PointerLength = 0;
3202 if(!pStubMsg->BufferLength)
3203 ERR("BufferLength == 0??\n");
3204 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
3205 pStubMsg->PointerLength = pStubMsg->BufferLength;
3206 pStubMsg->BufferLength = saved_buffer_length;
3208 if (*pPointer != RPC_FC_RP)
3210 align_length(&pStubMsg->BufferLength, 4);
3211 safe_buffer_length_increment(pStubMsg, 4);
3213 if (*pFormat == RPC_FC_POINTER)
3214 pPointer += 4;
3215 else
3216 pFormat += 4;
3217 pMemory += sizeof(void*);
3218 break;
3219 case RPC_FC_ALIGNM2:
3220 align_pointer(&pMemory, 2);
3221 break;
3222 case RPC_FC_ALIGNM4:
3223 align_pointer(&pMemory, 4);
3224 break;
3225 case RPC_FC_ALIGNM8:
3226 align_pointer(&pMemory, 8);
3227 break;
3228 case RPC_FC_STRUCTPAD1:
3229 case RPC_FC_STRUCTPAD2:
3230 case RPC_FC_STRUCTPAD3:
3231 case RPC_FC_STRUCTPAD4:
3232 case RPC_FC_STRUCTPAD5:
3233 case RPC_FC_STRUCTPAD6:
3234 case RPC_FC_STRUCTPAD7:
3235 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3236 break;
3237 case RPC_FC_EMBEDDED_COMPLEX:
3238 pMemory += pFormat[1];
3239 pFormat += 2;
3240 desc = pFormat + *(const SHORT*)pFormat;
3241 size = EmbeddedComplexSize(pStubMsg, desc);
3242 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
3243 if (m)
3245 /* for some reason interface pointers aren't generated as
3246 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3247 * they still need the derefencing treatment that pointers are
3248 * given */
3249 if (*desc == RPC_FC_IP)
3250 m(pStubMsg, *(unsigned char **)pMemory, desc);
3251 else
3252 m(pStubMsg, pMemory, desc);
3254 else FIXME("no buffersizer for embedded type %02x\n", *desc);
3255 pMemory += size;
3256 pFormat += 2;
3257 continue;
3258 case RPC_FC_PAD:
3259 break;
3260 default:
3261 FIXME("unhandled format 0x%02x\n", *pFormat);
3263 pFormat++;
3266 return pMemory;
3269 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
3270 unsigned char *pMemory,
3271 PFORMAT_STRING pFormat,
3272 PFORMAT_STRING pPointer)
3274 PFORMAT_STRING desc;
3275 NDR_FREE m;
3276 ULONG size;
3278 while (*pFormat != RPC_FC_END) {
3279 switch (*pFormat) {
3280 case RPC_FC_BYTE:
3281 case RPC_FC_CHAR:
3282 case RPC_FC_SMALL:
3283 case RPC_FC_USMALL:
3284 pMemory += 1;
3285 break;
3286 case RPC_FC_WCHAR:
3287 case RPC_FC_SHORT:
3288 case RPC_FC_USHORT:
3289 pMemory += 2;
3290 break;
3291 case RPC_FC_LONG:
3292 case RPC_FC_ULONG:
3293 case RPC_FC_ENUM16:
3294 case RPC_FC_ENUM32:
3295 case RPC_FC_FLOAT:
3296 pMemory += 4;
3297 break;
3298 case RPC_FC_INT3264:
3299 case RPC_FC_UINT3264:
3300 pMemory += sizeof(INT_PTR);
3301 break;
3302 case RPC_FC_HYPER:
3303 case RPC_FC_DOUBLE:
3304 pMemory += 8;
3305 break;
3306 case RPC_FC_RP:
3307 case RPC_FC_UP:
3308 case RPC_FC_OP:
3309 case RPC_FC_FP:
3310 case RPC_FC_POINTER:
3311 if (*pFormat != RPC_FC_POINTER)
3312 pPointer = pFormat;
3313 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3314 if (*pFormat == RPC_FC_POINTER)
3315 pPointer += 4;
3316 else
3317 pFormat += 4;
3318 pMemory += sizeof(void *);
3319 break;
3320 case RPC_FC_ALIGNM2:
3321 align_pointer(&pMemory, 2);
3322 break;
3323 case RPC_FC_ALIGNM4:
3324 align_pointer(&pMemory, 4);
3325 break;
3326 case RPC_FC_ALIGNM8:
3327 align_pointer(&pMemory, 8);
3328 break;
3329 case RPC_FC_STRUCTPAD1:
3330 case RPC_FC_STRUCTPAD2:
3331 case RPC_FC_STRUCTPAD3:
3332 case RPC_FC_STRUCTPAD4:
3333 case RPC_FC_STRUCTPAD5:
3334 case RPC_FC_STRUCTPAD6:
3335 case RPC_FC_STRUCTPAD7:
3336 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3337 break;
3338 case RPC_FC_EMBEDDED_COMPLEX:
3339 pMemory += pFormat[1];
3340 pFormat += 2;
3341 desc = pFormat + *(const SHORT*)pFormat;
3342 size = EmbeddedComplexSize(pStubMsg, desc);
3343 m = NdrFreer[*desc & NDR_TABLE_MASK];
3344 if (m)
3346 /* for some reason interface pointers aren't generated as
3347 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3348 * they still need the derefencing treatment that pointers are
3349 * given */
3350 if (*desc == RPC_FC_IP)
3351 m(pStubMsg, *(unsigned char **)pMemory, desc);
3352 else
3353 m(pStubMsg, pMemory, desc);
3355 pMemory += size;
3356 pFormat += 2;
3357 continue;
3358 case RPC_FC_PAD:
3359 break;
3360 default:
3361 FIXME("unhandled format 0x%02x\n", *pFormat);
3363 pFormat++;
3366 return pMemory;
3369 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3370 PFORMAT_STRING pFormat,
3371 PFORMAT_STRING pPointer)
3373 PFORMAT_STRING desc;
3374 ULONG size = 0;
3376 while (*pFormat != RPC_FC_END) {
3377 switch (*pFormat) {
3378 case RPC_FC_BYTE:
3379 case RPC_FC_CHAR:
3380 case RPC_FC_SMALL:
3381 case RPC_FC_USMALL:
3382 size += 1;
3383 safe_buffer_increment(pStubMsg, 1);
3384 break;
3385 case RPC_FC_WCHAR:
3386 case RPC_FC_SHORT:
3387 case RPC_FC_USHORT:
3388 size += 2;
3389 safe_buffer_increment(pStubMsg, 2);
3390 break;
3391 case RPC_FC_ENUM16:
3392 size += 4;
3393 safe_buffer_increment(pStubMsg, 2);
3394 break;
3395 case RPC_FC_LONG:
3396 case RPC_FC_ULONG:
3397 case RPC_FC_ENUM32:
3398 case RPC_FC_FLOAT:
3399 size += 4;
3400 safe_buffer_increment(pStubMsg, 4);
3401 break;
3402 case RPC_FC_INT3264:
3403 case RPC_FC_UINT3264:
3404 size += sizeof(INT_PTR);
3405 safe_buffer_increment(pStubMsg, 4);
3406 break;
3407 case RPC_FC_HYPER:
3408 case RPC_FC_DOUBLE:
3409 size += 8;
3410 safe_buffer_increment(pStubMsg, 8);
3411 break;
3412 case RPC_FC_RP:
3413 case RPC_FC_UP:
3414 case RPC_FC_OP:
3415 case RPC_FC_FP:
3416 case RPC_FC_POINTER:
3418 unsigned char *saved_buffer;
3419 int pointer_buffer_mark_set = 0;
3420 if (*pFormat != RPC_FC_POINTER)
3421 pPointer = pFormat;
3422 if (*pPointer != RPC_FC_RP)
3423 align_pointer(&pStubMsg->Buffer, 4);
3424 saved_buffer = pStubMsg->Buffer;
3425 if (pStubMsg->PointerBufferMark)
3427 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3428 pStubMsg->PointerBufferMark = NULL;
3429 pointer_buffer_mark_set = 1;
3431 else if (*pPointer != RPC_FC_RP)
3432 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3434 if (!pStubMsg->IgnoreEmbeddedPointers)
3435 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3436 if (pointer_buffer_mark_set)
3438 STD_OVERFLOW_CHECK(pStubMsg);
3439 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3440 pStubMsg->Buffer = saved_buffer;
3441 if (*pPointer != RPC_FC_RP)
3442 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3444 if (*pFormat == RPC_FC_POINTER)
3445 pPointer += 4;
3446 else
3447 pFormat += 4;
3448 size += sizeof(void *);
3449 break;
3451 case RPC_FC_ALIGNM2:
3452 align_length(&size, 2);
3453 break;
3454 case RPC_FC_ALIGNM4:
3455 align_length(&size, 4);
3456 break;
3457 case RPC_FC_ALIGNM8:
3458 align_length(&size, 8);
3459 break;
3460 case RPC_FC_STRUCTPAD1:
3461 case RPC_FC_STRUCTPAD2:
3462 case RPC_FC_STRUCTPAD3:
3463 case RPC_FC_STRUCTPAD4:
3464 case RPC_FC_STRUCTPAD5:
3465 case RPC_FC_STRUCTPAD6:
3466 case RPC_FC_STRUCTPAD7:
3467 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3468 break;
3469 case RPC_FC_EMBEDDED_COMPLEX:
3470 size += pFormat[1];
3471 pFormat += 2;
3472 desc = pFormat + *(const SHORT*)pFormat;
3473 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3474 pFormat += 2;
3475 continue;
3476 case RPC_FC_PAD:
3477 break;
3478 default:
3479 FIXME("unhandled format 0x%02x\n", *pFormat);
3481 pFormat++;
3484 return size;
3487 ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
3489 PFORMAT_STRING desc;
3490 ULONG size = 0;
3492 while (*pFormat != RPC_FC_END) {
3493 switch (*pFormat) {
3494 case RPC_FC_BYTE:
3495 case RPC_FC_CHAR:
3496 case RPC_FC_SMALL:
3497 case RPC_FC_USMALL:
3498 size += 1;
3499 break;
3500 case RPC_FC_WCHAR:
3501 case RPC_FC_SHORT:
3502 case RPC_FC_USHORT:
3503 size += 2;
3504 break;
3505 case RPC_FC_LONG:
3506 case RPC_FC_ULONG:
3507 case RPC_FC_ENUM16:
3508 case RPC_FC_ENUM32:
3509 case RPC_FC_FLOAT:
3510 size += 4;
3511 break;
3512 case RPC_FC_INT3264:
3513 case RPC_FC_UINT3264:
3514 size += sizeof(INT_PTR);
3515 break;
3516 case RPC_FC_HYPER:
3517 case RPC_FC_DOUBLE:
3518 size += 8;
3519 break;
3520 case RPC_FC_RP:
3521 case RPC_FC_UP:
3522 case RPC_FC_OP:
3523 case RPC_FC_FP:
3524 case RPC_FC_POINTER:
3525 size += sizeof(void *);
3526 if (*pFormat != RPC_FC_POINTER)
3527 pFormat += 4;
3528 break;
3529 case RPC_FC_ALIGNM2:
3530 align_length(&size, 2);
3531 break;
3532 case RPC_FC_ALIGNM4:
3533 align_length(&size, 4);
3534 break;
3535 case RPC_FC_ALIGNM8:
3536 align_length(&size, 8);
3537 break;
3538 case RPC_FC_STRUCTPAD1:
3539 case RPC_FC_STRUCTPAD2:
3540 case RPC_FC_STRUCTPAD3:
3541 case RPC_FC_STRUCTPAD4:
3542 case RPC_FC_STRUCTPAD5:
3543 case RPC_FC_STRUCTPAD6:
3544 case RPC_FC_STRUCTPAD7:
3545 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3546 break;
3547 case RPC_FC_EMBEDDED_COMPLEX:
3548 size += pFormat[1];
3549 pFormat += 2;
3550 desc = pFormat + *(const SHORT*)pFormat;
3551 size += EmbeddedComplexSize(pStubMsg, desc);
3552 pFormat += 2;
3553 continue;
3554 case RPC_FC_PAD:
3555 break;
3556 default:
3557 FIXME("unhandled format 0x%02x\n", *pFormat);
3559 pFormat++;
3562 return size;
3565 /***********************************************************************
3566 * NdrComplexStructMarshall [RPCRT4.@]
3568 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3569 unsigned char *pMemory,
3570 PFORMAT_STRING pFormat)
3572 PFORMAT_STRING conf_array = NULL;
3573 PFORMAT_STRING pointer_desc = NULL;
3574 unsigned char *OldMemory = pStubMsg->Memory;
3575 int pointer_buffer_mark_set = 0;
3576 ULONG count = 0;
3577 ULONG max_count = 0;
3578 ULONG offset = 0;
3580 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3582 if (!pStubMsg->PointerBufferMark)
3584 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3585 /* save buffer length */
3586 ULONG saved_buffer_length = pStubMsg->BufferLength;
3588 /* get the buffer pointer after complex array data, but before
3589 * pointer data */
3590 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3591 pStubMsg->IgnoreEmbeddedPointers = 1;
3592 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3593 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3595 /* save it for use by embedded pointer code later */
3596 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3597 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - pStubMsg->Buffer));
3598 pointer_buffer_mark_set = 1;
3600 /* restore the original buffer length */
3601 pStubMsg->BufferLength = saved_buffer_length;
3604 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1);
3606 pFormat += 4;
3607 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3608 pFormat += 2;
3609 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3610 pFormat += 2;
3612 pStubMsg->Memory = pMemory;
3614 if (conf_array)
3616 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3617 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3618 pMemory + struct_size, conf_array);
3619 /* these could be changed in ComplexMarshall so save them for later */
3620 max_count = pStubMsg->MaxCount;
3621 count = pStubMsg->ActualCount;
3622 offset = pStubMsg->Offset;
3625 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3627 if (conf_array)
3629 pStubMsg->MaxCount = max_count;
3630 pStubMsg->ActualCount = count;
3631 pStubMsg->Offset = offset;
3632 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3633 conf_array, TRUE /* fHasPointers */);
3636 pStubMsg->Memory = OldMemory;
3638 if (pointer_buffer_mark_set)
3640 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3641 pStubMsg->PointerBufferMark = NULL;
3644 STD_OVERFLOW_CHECK(pStubMsg);
3646 return NULL;
3649 /***********************************************************************
3650 * NdrComplexStructUnmarshall [RPCRT4.@]
3652 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3653 unsigned char **ppMemory,
3654 PFORMAT_STRING pFormat,
3655 unsigned char fMustAlloc)
3657 unsigned size = *(const WORD*)(pFormat+2);
3658 PFORMAT_STRING conf_array = NULL;
3659 PFORMAT_STRING pointer_desc = NULL;
3660 unsigned char *pMemory;
3661 int pointer_buffer_mark_set = 0;
3662 ULONG count = 0;
3663 ULONG max_count = 0;
3664 ULONG offset = 0;
3665 ULONG array_size = 0;
3667 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3669 if (!pStubMsg->PointerBufferMark)
3671 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3672 /* save buffer pointer */
3673 unsigned char *saved_buffer = pStubMsg->Buffer;
3675 /* get the buffer pointer after complex array data, but before
3676 * pointer data */
3677 pStubMsg->IgnoreEmbeddedPointers = 1;
3678 NdrComplexStructMemorySize(pStubMsg, pFormat);
3679 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3681 /* save it for use by embedded pointer code later */
3682 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3683 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - saved_buffer));
3684 pointer_buffer_mark_set = 1;
3686 /* restore the original buffer */
3687 pStubMsg->Buffer = saved_buffer;
3690 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3692 pFormat += 4;
3693 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3694 pFormat += 2;
3695 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3696 pFormat += 2;
3698 if (conf_array)
3700 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3701 size += array_size;
3703 /* these could be changed in ComplexMarshall so save them for later */
3704 max_count = pStubMsg->MaxCount;
3705 count = pStubMsg->ActualCount;
3706 offset = pStubMsg->Offset;
3709 if (!fMustAlloc && !*ppMemory)
3710 fMustAlloc = TRUE;
3711 if (fMustAlloc)
3712 *ppMemory = NdrAllocate(pStubMsg, size);
3714 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3716 if (conf_array)
3718 pStubMsg->MaxCount = max_count;
3719 pStubMsg->ActualCount = count;
3720 pStubMsg->Offset = offset;
3721 if (fMustAlloc)
3722 memset(pMemory, 0, array_size);
3723 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3724 conf_array, FALSE,
3725 FALSE /* fUseBufferMemoryServer */,
3726 TRUE /* fUnmarshall */);
3729 if (pointer_buffer_mark_set)
3731 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3732 pStubMsg->PointerBufferMark = NULL;
3735 return NULL;
3738 /***********************************************************************
3739 * NdrComplexStructBufferSize [RPCRT4.@]
3741 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3742 unsigned char *pMemory,
3743 PFORMAT_STRING pFormat)
3745 PFORMAT_STRING conf_array = NULL;
3746 PFORMAT_STRING pointer_desc = NULL;
3747 unsigned char *OldMemory = pStubMsg->Memory;
3748 int pointer_length_set = 0;
3749 ULONG count = 0;
3750 ULONG max_count = 0;
3751 ULONG offset = 0;
3753 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3755 align_length(&pStubMsg->BufferLength, pFormat[1] + 1);
3757 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3759 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3760 ULONG saved_buffer_length = pStubMsg->BufferLength;
3762 /* get the buffer length after complex struct data, but before
3763 * pointer data */
3764 pStubMsg->IgnoreEmbeddedPointers = 1;
3765 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3766 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3768 /* save it for use by embedded pointer code later */
3769 pStubMsg->PointerLength = pStubMsg->BufferLength;
3770 pointer_length_set = 1;
3771 TRACE("difference = 0x%x\n", pStubMsg->PointerLength - saved_buffer_length);
3773 /* restore the original buffer length */
3774 pStubMsg->BufferLength = saved_buffer_length;
3777 pFormat += 4;
3778 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3779 pFormat += 2;
3780 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3781 pFormat += 2;
3783 pStubMsg->Memory = pMemory;
3785 if (conf_array)
3787 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3788 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3789 conf_array);
3791 /* these could be changed in ComplexMarshall so save them for later */
3792 max_count = pStubMsg->MaxCount;
3793 count = pStubMsg->ActualCount;
3794 offset = pStubMsg->Offset;
3797 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3799 if (conf_array)
3801 pStubMsg->MaxCount = max_count;
3802 pStubMsg->ActualCount = count;
3803 pStubMsg->Offset = offset;
3804 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3805 TRUE /* fHasPointers */);
3808 pStubMsg->Memory = OldMemory;
3810 if(pointer_length_set)
3812 pStubMsg->BufferLength = pStubMsg->PointerLength;
3813 pStubMsg->PointerLength = 0;
3818 /***********************************************************************
3819 * NdrComplexStructMemorySize [RPCRT4.@]
3821 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3822 PFORMAT_STRING pFormat)
3824 unsigned size = *(const WORD*)(pFormat+2);
3825 PFORMAT_STRING conf_array = NULL;
3826 PFORMAT_STRING pointer_desc = NULL;
3827 ULONG count = 0;
3828 ULONG max_count = 0;
3829 ULONG offset = 0;
3831 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3833 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3835 pFormat += 4;
3836 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3837 pFormat += 2;
3838 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3839 pFormat += 2;
3841 if (conf_array)
3843 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3845 /* these could be changed in ComplexStructMemorySize so save them for
3846 * later */
3847 max_count = pStubMsg->MaxCount;
3848 count = pStubMsg->ActualCount;
3849 offset = pStubMsg->Offset;
3852 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3854 if (conf_array)
3856 pStubMsg->MaxCount = max_count;
3857 pStubMsg->ActualCount = count;
3858 pStubMsg->Offset = offset;
3859 array_memory_size(conf_array[0], pStubMsg, conf_array,
3860 TRUE /* fHasPointers */);
3863 return size;
3866 /***********************************************************************
3867 * NdrComplexStructFree [RPCRT4.@]
3869 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3870 unsigned char *pMemory,
3871 PFORMAT_STRING pFormat)
3873 PFORMAT_STRING conf_array = NULL;
3874 PFORMAT_STRING pointer_desc = NULL;
3875 unsigned char *OldMemory = pStubMsg->Memory;
3877 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3879 pFormat += 4;
3880 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3881 pFormat += 2;
3882 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3883 pFormat += 2;
3885 pStubMsg->Memory = pMemory;
3887 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3889 if (conf_array)
3890 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3891 TRUE /* fHasPointers */);
3893 pStubMsg->Memory = OldMemory;
3896 /***********************************************************************
3897 * NdrConformantArrayMarshall [RPCRT4.@]
3899 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3900 unsigned char *pMemory,
3901 PFORMAT_STRING pFormat)
3903 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3904 if (pFormat[0] != RPC_FC_CARRAY)
3906 ERR("invalid format = 0x%x\n", pFormat[0]);
3907 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3910 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory,
3911 pFormat);
3912 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3913 TRUE /* fHasPointers */);
3915 return NULL;
3918 /***********************************************************************
3919 * NdrConformantArrayUnmarshall [RPCRT4.@]
3921 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3922 unsigned char **ppMemory,
3923 PFORMAT_STRING pFormat,
3924 unsigned char fMustAlloc)
3926 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3927 if (pFormat[0] != RPC_FC_CARRAY)
3929 ERR("invalid format = 0x%x\n", pFormat[0]);
3930 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3933 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3934 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat,
3935 fMustAlloc,
3936 TRUE /* fUseBufferMemoryServer */,
3937 TRUE /* fUnmarshall */);
3939 return NULL;
3942 /***********************************************************************
3943 * NdrConformantArrayBufferSize [RPCRT4.@]
3945 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3946 unsigned char *pMemory,
3947 PFORMAT_STRING pFormat)
3949 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3950 if (pFormat[0] != RPC_FC_CARRAY)
3952 ERR("invalid format = 0x%x\n", pFormat[0]);
3953 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3956 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat);
3957 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3958 TRUE /* fHasPointers */);
3961 /***********************************************************************
3962 * NdrConformantArrayMemorySize [RPCRT4.@]
3964 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3965 PFORMAT_STRING pFormat)
3967 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3968 if (pFormat[0] != RPC_FC_CARRAY)
3970 ERR("invalid format = 0x%x\n", pFormat[0]);
3971 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3974 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3975 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
3977 return pStubMsg->MemorySize;
3980 /***********************************************************************
3981 * NdrConformantArrayFree [RPCRT4.@]
3983 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3984 unsigned char *pMemory,
3985 PFORMAT_STRING pFormat)
3987 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3988 if (pFormat[0] != RPC_FC_CARRAY)
3990 ERR("invalid format = 0x%x\n", pFormat[0]);
3991 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3994 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3995 TRUE /* fHasPointers */);
3999 /***********************************************************************
4000 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
4002 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
4003 unsigned char* pMemory,
4004 PFORMAT_STRING pFormat )
4006 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4008 if (pFormat[0] != RPC_FC_CVARRAY)
4010 ERR("invalid format type %x\n", pFormat[0]);
4011 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4012 return NULL;
4015 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
4016 pFormat);
4017 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory,
4018 pFormat, TRUE /* fHasPointers */);
4020 return NULL;
4024 /***********************************************************************
4025 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
4027 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
4028 unsigned char** ppMemory,
4029 PFORMAT_STRING pFormat,
4030 unsigned char fMustAlloc )
4032 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4034 if (pFormat[0] != RPC_FC_CVARRAY)
4036 ERR("invalid format type %x\n", pFormat[0]);
4037 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4038 return NULL;
4041 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
4042 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory,
4043 pFormat, fMustAlloc,
4044 TRUE /* fUseBufferMemoryServer */,
4045 TRUE /* fUnmarshall */);
4047 return NULL;
4051 /***********************************************************************
4052 * NdrConformantVaryingArrayFree [RPCRT4.@]
4054 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
4055 unsigned char* pMemory,
4056 PFORMAT_STRING pFormat )
4058 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4060 if (pFormat[0] != RPC_FC_CVARRAY)
4062 ERR("invalid format type %x\n", pFormat[0]);
4063 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4064 return;
4067 array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
4068 TRUE /* fHasPointers */);
4072 /***********************************************************************
4073 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
4075 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
4076 unsigned char* pMemory, PFORMAT_STRING pFormat )
4078 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4080 if (pFormat[0] != RPC_FC_CVARRAY)
4082 ERR("invalid format type %x\n", pFormat[0]);
4083 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4084 return;
4087 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
4088 pFormat);
4089 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
4090 TRUE /* fHasPointers */);
4094 /***********************************************************************
4095 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
4097 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
4098 PFORMAT_STRING pFormat )
4100 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4102 if (pFormat[0] != RPC_FC_CVARRAY)
4104 ERR("invalid format type %x\n", pFormat[0]);
4105 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4106 return pStubMsg->MemorySize;
4109 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
4110 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat,
4111 TRUE /* fHasPointers */);
4113 return pStubMsg->MemorySize;
4117 /***********************************************************************
4118 * NdrComplexArrayMarshall [RPCRT4.@]
4120 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4121 unsigned char *pMemory,
4122 PFORMAT_STRING pFormat)
4124 int pointer_buffer_mark_set = 0;
4126 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4128 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4130 ERR("invalid format type %x\n", pFormat[0]);
4131 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4132 return NULL;
4135 if (!pStubMsg->PointerBufferMark)
4137 /* save buffer fields that may be changed by buffer sizer functions
4138 * and that may be needed later on */
4139 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4140 ULONG saved_buffer_length = pStubMsg->BufferLength;
4141 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4142 ULONG saved_offset = pStubMsg->Offset;
4143 ULONG saved_actual_count = pStubMsg->ActualCount;
4145 /* get the buffer pointer after complex array data, but before
4146 * pointer data */
4147 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
4148 pStubMsg->IgnoreEmbeddedPointers = 1;
4149 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4150 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4152 /* save it for use by embedded pointer code later */
4153 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
4154 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer));
4155 pointer_buffer_mark_set = 1;
4157 /* restore fields */
4158 pStubMsg->ActualCount = saved_actual_count;
4159 pStubMsg->Offset = saved_offset;
4160 pStubMsg->MaxCount = saved_max_count;
4161 pStubMsg->BufferLength = saved_buffer_length;
4164 array_compute_and_write_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4165 array_write_variance_and_marshall(RPC_FC_BOGUS_ARRAY, pStubMsg,
4166 pMemory, pFormat, TRUE /* fHasPointers */);
4168 STD_OVERFLOW_CHECK(pStubMsg);
4170 if (pointer_buffer_mark_set)
4172 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4173 pStubMsg->PointerBufferMark = NULL;
4176 return NULL;
4179 /***********************************************************************
4180 * NdrComplexArrayUnmarshall [RPCRT4.@]
4182 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4183 unsigned char **ppMemory,
4184 PFORMAT_STRING pFormat,
4185 unsigned char fMustAlloc)
4187 unsigned char *saved_buffer;
4188 int pointer_buffer_mark_set = 0;
4189 int saved_ignore_embedded;
4191 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4193 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4195 ERR("invalid format type %x\n", pFormat[0]);
4196 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4197 return NULL;
4200 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4201 /* save buffer pointer */
4202 saved_buffer = pStubMsg->Buffer;
4203 /* get the buffer pointer after complex array data, but before
4204 * pointer data */
4205 pStubMsg->IgnoreEmbeddedPointers = 1;
4206 pStubMsg->MemorySize = 0;
4207 NdrComplexArrayMemorySize(pStubMsg, pFormat);
4208 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4210 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - saved_buffer));
4211 if (!pStubMsg->PointerBufferMark)
4213 /* save it for use by embedded pointer code later */
4214 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4215 pointer_buffer_mark_set = 1;
4217 /* restore the original buffer */
4218 pStubMsg->Buffer = saved_buffer;
4220 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
4221 array_read_variance_and_unmarshall(RPC_FC_BOGUS_ARRAY, pStubMsg, ppMemory, pFormat, fMustAlloc,
4222 TRUE /* fUseBufferMemoryServer */, TRUE /* fUnmarshall */);
4224 if (pointer_buffer_mark_set)
4226 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4227 pStubMsg->PointerBufferMark = NULL;
4230 return NULL;
4233 /***********************************************************************
4234 * NdrComplexArrayBufferSize [RPCRT4.@]
4236 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4237 unsigned char *pMemory,
4238 PFORMAT_STRING pFormat)
4240 int pointer_length_set = 0;
4242 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4244 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4246 ERR("invalid format type %x\n", pFormat[0]);
4247 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4248 return;
4251 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
4253 /* save buffer fields that may be changed by buffer sizer functions
4254 * and that may be needed later on */
4255 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4256 ULONG saved_buffer_length = pStubMsg->BufferLength;
4257 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4258 ULONG saved_offset = pStubMsg->Offset;
4259 ULONG saved_actual_count = pStubMsg->ActualCount;
4261 /* get the buffer pointer after complex array data, but before
4262 * pointer data */
4263 pStubMsg->IgnoreEmbeddedPointers = 1;
4264 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4265 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4267 /* save it for use by embedded pointer code later */
4268 pStubMsg->PointerLength = pStubMsg->BufferLength;
4269 pointer_length_set = 1;
4271 /* restore fields */
4272 pStubMsg->ActualCount = saved_actual_count;
4273 pStubMsg->Offset = saved_offset;
4274 pStubMsg->MaxCount = saved_max_count;
4275 pStubMsg->BufferLength = saved_buffer_length;
4278 array_compute_and_size_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4279 array_buffer_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat, TRUE /* fHasPointers */);
4281 if(pointer_length_set)
4283 pStubMsg->BufferLength = pStubMsg->PointerLength;
4284 pStubMsg->PointerLength = 0;
4288 /***********************************************************************
4289 * NdrComplexArrayMemorySize [RPCRT4.@]
4291 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4292 PFORMAT_STRING pFormat)
4294 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4296 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4298 ERR("invalid format type %x\n", pFormat[0]);
4299 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4300 return 0;
4303 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
4304 array_memory_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
4305 return pStubMsg->MemorySize;
4308 /***********************************************************************
4309 * NdrComplexArrayFree [RPCRT4.@]
4311 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4312 unsigned char *pMemory,
4313 PFORMAT_STRING pFormat)
4315 ULONG i, count, def;
4317 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4319 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4321 ERR("invalid format type %x\n", pFormat[0]);
4322 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4323 return;
4326 def = *(const WORD*)&pFormat[2];
4327 pFormat += 4;
4329 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4330 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4332 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4333 TRACE("variance = %d\n", pStubMsg->ActualCount);
4335 count = pStubMsg->ActualCount;
4336 for (i = 0; i < count; i++)
4337 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4340 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4341 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4342 USER_MARSHAL_CB *umcb)
4344 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4345 pStubMsg->RpcMsg->DataRepresentation);
4346 umcb->pStubMsg = pStubMsg;
4347 umcb->pReserve = NULL;
4348 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4349 umcb->CBType = cbtype;
4350 umcb->pFormat = pFormat;
4351 umcb->pTypeFormat = NULL /* FIXME */;
4354 #define USER_MARSHAL_PTR_PREFIX \
4355 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4356 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4358 /***********************************************************************
4359 * NdrUserMarshalMarshall [RPCRT4.@]
4361 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4362 unsigned char *pMemory,
4363 PFORMAT_STRING pFormat)
4365 unsigned flags = pFormat[1];
4366 unsigned index = *(const WORD*)&pFormat[2];
4367 unsigned char *saved_buffer = NULL;
4368 USER_MARSHAL_CB umcb;
4370 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4371 TRACE("index=%d\n", index);
4373 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4375 if (flags & USER_MARSHAL_POINTER)
4377 align_pointer_clear(&pStubMsg->Buffer, 4);
4378 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4379 pStubMsg->Buffer += 4;
4380 if (pStubMsg->PointerBufferMark)
4382 saved_buffer = pStubMsg->Buffer;
4383 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4384 pStubMsg->PointerBufferMark = NULL;
4386 align_pointer_clear(&pStubMsg->Buffer, 8);
4388 else
4389 align_pointer_clear(&pStubMsg->Buffer, (flags & 0xf) + 1);
4391 pStubMsg->Buffer =
4392 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4393 &umcb.Flags, pStubMsg->Buffer, pMemory);
4395 if (saved_buffer)
4397 STD_OVERFLOW_CHECK(pStubMsg);
4398 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4399 pStubMsg->Buffer = saved_buffer;
4402 STD_OVERFLOW_CHECK(pStubMsg);
4404 return NULL;
4407 /***********************************************************************
4408 * NdrUserMarshalUnmarshall [RPCRT4.@]
4410 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4411 unsigned char **ppMemory,
4412 PFORMAT_STRING pFormat,
4413 unsigned char fMustAlloc)
4415 unsigned flags = pFormat[1];
4416 unsigned index = *(const WORD*)&pFormat[2];
4417 DWORD memsize = *(const WORD*)&pFormat[4];
4418 unsigned char *saved_buffer = NULL;
4419 USER_MARSHAL_CB umcb;
4421 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4422 TRACE("index=%d\n", index);
4424 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4426 if (flags & USER_MARSHAL_POINTER)
4428 align_pointer(&pStubMsg->Buffer, 4);
4429 /* skip pointer prefix */
4430 pStubMsg->Buffer += 4;
4431 if (pStubMsg->PointerBufferMark)
4433 saved_buffer = pStubMsg->Buffer;
4434 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4435 pStubMsg->PointerBufferMark = NULL;
4437 align_pointer(&pStubMsg->Buffer, 8);
4439 else
4440 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4442 if (!fMustAlloc && !*ppMemory)
4443 fMustAlloc = TRUE;
4444 if (fMustAlloc)
4446 *ppMemory = NdrAllocate(pStubMsg, memsize);
4447 memset(*ppMemory, 0, memsize);
4450 pStubMsg->Buffer =
4451 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4452 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4454 if (saved_buffer)
4456 STD_OVERFLOW_CHECK(pStubMsg);
4457 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4458 pStubMsg->Buffer = saved_buffer;
4461 return NULL;
4464 /***********************************************************************
4465 * NdrUserMarshalBufferSize [RPCRT4.@]
4467 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4468 unsigned char *pMemory,
4469 PFORMAT_STRING pFormat)
4471 unsigned flags = pFormat[1];
4472 unsigned index = *(const WORD*)&pFormat[2];
4473 DWORD bufsize = *(const WORD*)&pFormat[6];
4474 USER_MARSHAL_CB umcb;
4475 ULONG saved_buffer_length = 0;
4477 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4478 TRACE("index=%d\n", index);
4480 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4482 if (flags & USER_MARSHAL_POINTER)
4484 align_length(&pStubMsg->BufferLength, 4);
4485 /* skip pointer prefix */
4486 safe_buffer_length_increment(pStubMsg, 4);
4487 if (pStubMsg->IgnoreEmbeddedPointers)
4488 return;
4489 if (pStubMsg->PointerLength)
4491 saved_buffer_length = pStubMsg->BufferLength;
4492 pStubMsg->BufferLength = pStubMsg->PointerLength;
4493 pStubMsg->PointerLength = 0;
4495 align_length(&pStubMsg->BufferLength, 8);
4497 else
4498 align_length(&pStubMsg->BufferLength, (flags & 0xf) + 1);
4500 if (bufsize) {
4501 TRACE("size=%d\n", bufsize);
4502 safe_buffer_length_increment(pStubMsg, bufsize);
4504 else
4505 pStubMsg->BufferLength =
4506 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4507 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4509 if (saved_buffer_length)
4511 pStubMsg->PointerLength = pStubMsg->BufferLength;
4512 pStubMsg->BufferLength = saved_buffer_length;
4517 /***********************************************************************
4518 * NdrUserMarshalMemorySize [RPCRT4.@]
4520 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4521 PFORMAT_STRING pFormat)
4523 unsigned flags = pFormat[1];
4524 unsigned index = *(const WORD*)&pFormat[2];
4525 DWORD memsize = *(const WORD*)&pFormat[4];
4526 DWORD bufsize = *(const WORD*)&pFormat[6];
4528 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4529 TRACE("index=%d\n", index);
4531 pStubMsg->MemorySize += memsize;
4533 if (flags & USER_MARSHAL_POINTER)
4535 align_pointer(&pStubMsg->Buffer, 4);
4536 /* skip pointer prefix */
4537 pStubMsg->Buffer += 4;
4538 if (pStubMsg->IgnoreEmbeddedPointers)
4539 return pStubMsg->MemorySize;
4540 align_pointer(&pStubMsg->Buffer, 8);
4542 else
4543 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4545 if (!bufsize)
4546 FIXME("not implemented for varying buffer size\n");
4548 pStubMsg->Buffer += bufsize;
4550 return pStubMsg->MemorySize;
4553 /***********************************************************************
4554 * NdrUserMarshalFree [RPCRT4.@]
4556 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4557 unsigned char *pMemory,
4558 PFORMAT_STRING pFormat)
4560 /* unsigned flags = pFormat[1]; */
4561 unsigned index = *(const WORD*)&pFormat[2];
4562 USER_MARSHAL_CB umcb;
4564 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4565 TRACE("index=%d\n", index);
4567 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4569 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4570 &umcb.Flags, pMemory);
4573 /***********************************************************************
4574 * NdrGetUserMarshalInfo [RPCRT4.@]
4576 RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi)
4578 USER_MARSHAL_CB *umcb = CONTAINING_RECORD(flags, USER_MARSHAL_CB, Flags);
4580 TRACE("(%p,%u,%p)\n", flags, level, umi);
4582 if (level != 1)
4583 return RPC_S_INVALID_ARG;
4585 memset(&umi->u1.Level1, 0, sizeof(umi->u1.Level1));
4586 umi->InformationLevel = level;
4588 if (umcb->Signature != USER_MARSHAL_CB_SIGNATURE)
4589 return RPC_S_INVALID_ARG;
4591 umi->u1.Level1.pfnAllocate = umcb->pStubMsg->pfnAllocate;
4592 umi->u1.Level1.pfnFree = umcb->pStubMsg->pfnFree;
4593 umi->u1.Level1.pRpcChannelBuffer = umcb->pStubMsg->pRpcChannelBuffer;
4595 switch (umcb->CBType)
4597 case USER_MARSHAL_CB_MARSHALL:
4598 case USER_MARSHAL_CB_UNMARSHALL:
4600 RPC_MESSAGE *msg = umcb->pStubMsg->RpcMsg;
4601 unsigned char *buffer_start = msg->Buffer;
4602 unsigned char *buffer_end =
4603 (unsigned char *)msg->Buffer + msg->BufferLength;
4605 if (umcb->pStubMsg->Buffer < buffer_start ||
4606 umcb->pStubMsg->Buffer > buffer_end)
4607 return ERROR_INVALID_USER_BUFFER;
4609 umi->u1.Level1.Buffer = umcb->pStubMsg->Buffer;
4610 umi->u1.Level1.BufferSize = buffer_end - umcb->pStubMsg->Buffer;
4611 break;
4613 case USER_MARSHAL_CB_BUFFER_SIZE:
4614 case USER_MARSHAL_CB_FREE:
4615 break;
4616 default:
4617 WARN("unrecognised CBType %d\n", umcb->CBType);
4620 return RPC_S_OK;
4623 /***********************************************************************
4624 * NdrClearOutParameters [RPCRT4.@]
4626 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4627 PFORMAT_STRING pFormat,
4628 void *ArgAddr)
4630 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4633 /***********************************************************************
4634 * NdrConvert [RPCRT4.@]
4636 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4638 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4639 /* FIXME: since this stub doesn't do any converting, the proper behavior
4640 is to raise an exception */
4643 /***********************************************************************
4644 * NdrConvert2 [RPCRT4.@]
4646 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4648 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4649 pStubMsg, pFormat, NumberParams);
4650 /* FIXME: since this stub doesn't do any converting, the proper behavior
4651 is to raise an exception */
4654 #include "pshpack1.h"
4655 typedef struct _NDR_CSTRUCT_FORMAT
4657 unsigned char type;
4658 unsigned char alignment;
4659 unsigned short memory_size;
4660 short offset_to_array_description;
4661 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4662 #include "poppack.h"
4664 /***********************************************************************
4665 * NdrConformantStructMarshall [RPCRT4.@]
4667 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4668 unsigned char *pMemory,
4669 PFORMAT_STRING pFormat)
4671 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4672 PFORMAT_STRING pCArrayFormat;
4673 ULONG esize, bufsize;
4675 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4677 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4678 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4680 ERR("invalid format type %x\n", pCStructFormat->type);
4681 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4682 return NULL;
4685 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4686 pCStructFormat->offset_to_array_description;
4687 if (*pCArrayFormat != RPC_FC_CARRAY)
4689 ERR("invalid array format type %x\n", pCStructFormat->type);
4690 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4691 return NULL;
4693 esize = *(const WORD*)(pCArrayFormat+2);
4695 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4696 pCArrayFormat + 4, 0);
4698 WriteConformance(pStubMsg);
4700 align_pointer_clear(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4702 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4704 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4705 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4707 ERR("integer overflow of memory_size %u with bufsize %u\n",
4708 pCStructFormat->memory_size, bufsize);
4709 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4711 /* copy constant sized part of struct */
4712 pStubMsg->BufferMark = pStubMsg->Buffer;
4713 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4715 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4716 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4718 return NULL;
4721 /***********************************************************************
4722 * NdrConformantStructUnmarshall [RPCRT4.@]
4724 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4725 unsigned char **ppMemory,
4726 PFORMAT_STRING pFormat,
4727 unsigned char fMustAlloc)
4729 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4730 PFORMAT_STRING pCArrayFormat;
4731 ULONG esize, bufsize;
4732 unsigned char *saved_buffer;
4734 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4736 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4737 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4739 ERR("invalid format type %x\n", pCStructFormat->type);
4740 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4741 return NULL;
4743 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4744 pCStructFormat->offset_to_array_description;
4745 if (*pCArrayFormat != RPC_FC_CARRAY)
4747 ERR("invalid array format type %x\n", pCStructFormat->type);
4748 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4749 return NULL;
4751 esize = *(const WORD*)(pCArrayFormat+2);
4753 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4755 align_pointer(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4757 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4759 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4760 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4762 ERR("integer overflow of memory_size %u with bufsize %u\n",
4763 pCStructFormat->memory_size, bufsize);
4764 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4767 if (fMustAlloc)
4769 SIZE_T size = pCStructFormat->memory_size + bufsize;
4770 *ppMemory = NdrAllocate(pStubMsg, size);
4772 else
4774 if (!pStubMsg->IsClient && !*ppMemory)
4775 /* for servers, we just point straight into the RPC buffer */
4776 *ppMemory = pStubMsg->Buffer;
4779 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4780 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4781 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4782 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4784 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4785 if (*ppMemory != saved_buffer)
4786 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4788 return NULL;
4791 /***********************************************************************
4792 * NdrConformantStructBufferSize [RPCRT4.@]
4794 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4795 unsigned char *pMemory,
4796 PFORMAT_STRING pFormat)
4798 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4799 PFORMAT_STRING pCArrayFormat;
4800 ULONG esize;
4802 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4804 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4805 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4807 ERR("invalid format type %x\n", pCStructFormat->type);
4808 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4809 return;
4811 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4812 pCStructFormat->offset_to_array_description;
4813 if (*pCArrayFormat != RPC_FC_CARRAY)
4815 ERR("invalid array format type %x\n", pCStructFormat->type);
4816 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4817 return;
4819 esize = *(const WORD*)(pCArrayFormat+2);
4821 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4822 SizeConformance(pStubMsg);
4824 align_length(&pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4826 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4828 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4829 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4831 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4832 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4835 /***********************************************************************
4836 * NdrConformantStructMemorySize [RPCRT4.@]
4838 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4839 PFORMAT_STRING pFormat)
4841 FIXME("stub\n");
4842 return 0;
4845 /***********************************************************************
4846 * NdrConformantStructFree [RPCRT4.@]
4848 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4849 unsigned char *pMemory,
4850 PFORMAT_STRING pFormat)
4852 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4853 PFORMAT_STRING pCArrayFormat;
4855 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4857 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4858 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4860 ERR("invalid format type %x\n", pCStructFormat->type);
4861 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4862 return;
4865 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4866 pCStructFormat->offset_to_array_description;
4867 if (*pCArrayFormat != RPC_FC_CARRAY)
4869 ERR("invalid array format type %x\n", pCStructFormat->type);
4870 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4871 return;
4874 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4875 pCArrayFormat + 4, 0);
4877 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4879 /* copy constant sized part of struct */
4880 pStubMsg->BufferMark = pStubMsg->Buffer;
4882 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4883 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4886 /***********************************************************************
4887 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4889 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4890 unsigned char *pMemory,
4891 PFORMAT_STRING pFormat)
4893 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4894 PFORMAT_STRING pCVArrayFormat;
4896 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4898 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4899 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4901 ERR("invalid format type %x\n", pCVStructFormat->type);
4902 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4903 return NULL;
4906 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4907 pCVStructFormat->offset_to_array_description;
4909 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4910 pMemory + pCVStructFormat->memory_size,
4911 pCVArrayFormat);
4913 align_pointer_clear(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4915 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4917 /* write constant sized part */
4918 pStubMsg->BufferMark = pStubMsg->Buffer;
4919 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4921 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4922 pMemory + pCVStructFormat->memory_size,
4923 pCVArrayFormat, FALSE /* fHasPointers */);
4925 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4927 return NULL;
4930 /***********************************************************************
4931 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4933 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4934 unsigned char **ppMemory,
4935 PFORMAT_STRING pFormat,
4936 unsigned char fMustAlloc)
4938 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4939 PFORMAT_STRING pCVArrayFormat;
4940 ULONG memsize, bufsize;
4941 unsigned char *saved_buffer, *saved_array_buffer;
4942 ULONG offset;
4943 unsigned char *array_memory;
4945 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4947 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4948 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4950 ERR("invalid format type %x\n", pCVStructFormat->type);
4951 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4952 return NULL;
4955 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4956 pCVStructFormat->offset_to_array_description;
4958 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4959 pCVArrayFormat);
4961 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4963 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4965 /* work out how much memory to allocate if we need to do so */
4966 if (!fMustAlloc && !*ppMemory)
4967 fMustAlloc = TRUE;
4968 if (fMustAlloc)
4970 SIZE_T size = pCVStructFormat->memory_size + memsize;
4971 *ppMemory = NdrAllocate(pStubMsg, size);
4974 /* mark the start of the constant data */
4975 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4976 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4978 array_memory = *ppMemory + pCVStructFormat->memory_size;
4979 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
4980 &array_memory, pCVArrayFormat,
4981 FALSE /* fMustAlloc */,
4982 FALSE /* fUseServerBufferMemory */,
4983 FALSE /* fUnmarshall */);
4985 /* save offset in case unmarshalling pointers changes it */
4986 offset = pStubMsg->Offset;
4988 /* mark the start of the array data */
4989 saved_array_buffer = pStubMsg->Buffer;
4990 safe_buffer_increment(pStubMsg, bufsize);
4992 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4994 /* copy the constant data */
4995 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
4996 /* copy the array data */
4997 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
4998 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
4999 saved_array_buffer, bufsize);
5001 if (*pCVArrayFormat == RPC_FC_C_CSTRING)
5002 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
5003 else if (*pCVArrayFormat == RPC_FC_C_WSTRING)
5004 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
5006 return NULL;
5009 /***********************************************************************
5010 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
5012 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5013 unsigned char *pMemory,
5014 PFORMAT_STRING pFormat)
5016 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5017 PFORMAT_STRING pCVArrayFormat;
5019 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5021 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5022 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5024 ERR("invalid format type %x\n", pCVStructFormat->type);
5025 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5026 return;
5029 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5030 pCVStructFormat->offset_to_array_description;
5031 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
5032 pMemory + pCVStructFormat->memory_size,
5033 pCVArrayFormat);
5035 align_length(&pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
5037 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5039 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
5041 array_buffer_size(*pCVArrayFormat, pStubMsg,
5042 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5043 FALSE /* fHasPointers */);
5045 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5048 /***********************************************************************
5049 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
5051 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5052 PFORMAT_STRING pFormat)
5054 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5055 PFORMAT_STRING pCVArrayFormat;
5057 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5059 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5060 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5062 ERR("invalid format type %x\n", pCVStructFormat->type);
5063 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5064 return 0;
5067 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5068 pCVStructFormat->offset_to_array_description;
5069 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
5071 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
5073 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5075 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
5076 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
5077 FALSE /* fHasPointers */);
5079 pStubMsg->MemorySize += pCVStructFormat->memory_size;
5081 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5083 return pStubMsg->MemorySize;
5086 /***********************************************************************
5087 * NdrConformantVaryingStructFree [RPCRT4.@]
5089 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
5090 unsigned char *pMemory,
5091 PFORMAT_STRING pFormat)
5093 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5094 PFORMAT_STRING pCVArrayFormat;
5096 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5098 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5099 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5101 ERR("invalid format type %x\n", pCVStructFormat->type);
5102 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5103 return;
5106 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5107 pCVStructFormat->offset_to_array_description;
5108 array_free(*pCVArrayFormat, pStubMsg,
5109 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5110 FALSE /* fHasPointers */);
5112 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5114 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5117 #include "pshpack1.h"
5118 typedef struct
5120 unsigned char type;
5121 unsigned char alignment;
5122 unsigned short total_size;
5123 } NDR_SMFARRAY_FORMAT;
5125 typedef struct
5127 unsigned char type;
5128 unsigned char alignment;
5129 ULONG total_size;
5130 } NDR_LGFARRAY_FORMAT;
5131 #include "poppack.h"
5133 /***********************************************************************
5134 * NdrFixedArrayMarshall [RPCRT4.@]
5136 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5137 unsigned char *pMemory,
5138 PFORMAT_STRING pFormat)
5140 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5141 ULONG total_size;
5143 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5145 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5146 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5148 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5149 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5150 return NULL;
5153 align_pointer_clear(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5155 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5157 total_size = pSmFArrayFormat->total_size;
5158 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5160 else
5162 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5163 total_size = pLgFArrayFormat->total_size;
5164 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5167 pStubMsg->BufferMark = pStubMsg->Buffer;
5168 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
5170 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5172 return NULL;
5175 /***********************************************************************
5176 * NdrFixedArrayUnmarshall [RPCRT4.@]
5178 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5179 unsigned char **ppMemory,
5180 PFORMAT_STRING pFormat,
5181 unsigned char fMustAlloc)
5183 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5184 ULONG total_size;
5185 unsigned char *saved_buffer;
5187 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5189 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5190 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5192 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5193 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5194 return NULL;
5197 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5199 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5201 total_size = pSmFArrayFormat->total_size;
5202 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5204 else
5206 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5207 total_size = pLgFArrayFormat->total_size;
5208 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5211 if (fMustAlloc)
5212 *ppMemory = NdrAllocate(pStubMsg, total_size);
5213 else
5215 if (!pStubMsg->IsClient && !*ppMemory)
5216 /* for servers, we just point straight into the RPC buffer */
5217 *ppMemory = pStubMsg->Buffer;
5220 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5221 safe_buffer_increment(pStubMsg, total_size);
5222 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5224 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
5225 if (*ppMemory != saved_buffer)
5226 memcpy(*ppMemory, saved_buffer, total_size);
5228 return NULL;
5231 /***********************************************************************
5232 * NdrFixedArrayBufferSize [RPCRT4.@]
5234 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5235 unsigned char *pMemory,
5236 PFORMAT_STRING pFormat)
5238 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5239 ULONG total_size;
5241 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5243 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5244 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5246 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5247 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5248 return;
5251 align_length(&pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
5253 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5255 total_size = pSmFArrayFormat->total_size;
5256 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5258 else
5260 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5261 total_size = pLgFArrayFormat->total_size;
5262 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5264 safe_buffer_length_increment(pStubMsg, total_size);
5266 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5269 /***********************************************************************
5270 * NdrFixedArrayMemorySize [RPCRT4.@]
5272 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5273 PFORMAT_STRING pFormat)
5275 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5276 ULONG total_size;
5278 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5280 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5281 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5283 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5284 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5285 return 0;
5288 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5290 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5292 total_size = pSmFArrayFormat->total_size;
5293 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5295 else
5297 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5298 total_size = pLgFArrayFormat->total_size;
5299 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5301 pStubMsg->BufferMark = pStubMsg->Buffer;
5302 safe_buffer_increment(pStubMsg, total_size);
5303 pStubMsg->MemorySize += total_size;
5305 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5307 return total_size;
5310 /***********************************************************************
5311 * NdrFixedArrayFree [RPCRT4.@]
5313 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5314 unsigned char *pMemory,
5315 PFORMAT_STRING pFormat)
5317 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5319 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5321 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5322 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5324 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5325 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5326 return;
5329 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5330 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5331 else
5333 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5334 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5337 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5340 /***********************************************************************
5341 * NdrVaryingArrayMarshall [RPCRT4.@]
5343 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5344 unsigned char *pMemory,
5345 PFORMAT_STRING pFormat)
5347 unsigned char alignment;
5348 DWORD elements, esize;
5349 ULONG bufsize;
5351 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5353 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5354 (pFormat[0] != RPC_FC_LGVARRAY))
5356 ERR("invalid format type %x\n", pFormat[0]);
5357 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5358 return NULL;
5361 alignment = pFormat[1] + 1;
5363 if (pFormat[0] == RPC_FC_SMVARRAY)
5365 pFormat += 2;
5366 pFormat += sizeof(WORD);
5367 elements = *(const WORD*)pFormat;
5368 pFormat += sizeof(WORD);
5370 else
5372 pFormat += 2;
5373 pFormat += sizeof(DWORD);
5374 elements = *(const DWORD*)pFormat;
5375 pFormat += sizeof(DWORD);
5378 esize = *(const WORD*)pFormat;
5379 pFormat += sizeof(WORD);
5381 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5382 if ((pStubMsg->ActualCount > elements) ||
5383 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5385 RpcRaiseException(RPC_S_INVALID_BOUND);
5386 return NULL;
5389 WriteVariance(pStubMsg);
5391 align_pointer_clear(&pStubMsg->Buffer, alignment);
5393 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5394 pStubMsg->BufferMark = pStubMsg->Buffer;
5395 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5397 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5399 return NULL;
5402 /***********************************************************************
5403 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5405 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5406 unsigned char **ppMemory,
5407 PFORMAT_STRING pFormat,
5408 unsigned char fMustAlloc)
5410 unsigned char alignment;
5411 DWORD size, elements, esize;
5412 ULONG bufsize;
5413 unsigned char *saved_buffer;
5414 ULONG offset;
5416 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5418 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5419 (pFormat[0] != RPC_FC_LGVARRAY))
5421 ERR("invalid format type %x\n", pFormat[0]);
5422 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5423 return NULL;
5426 alignment = pFormat[1] + 1;
5428 if (pFormat[0] == RPC_FC_SMVARRAY)
5430 pFormat += 2;
5431 size = *(const WORD*)pFormat;
5432 pFormat += sizeof(WORD);
5433 elements = *(const WORD*)pFormat;
5434 pFormat += sizeof(WORD);
5436 else
5438 pFormat += 2;
5439 size = *(const DWORD*)pFormat;
5440 pFormat += sizeof(DWORD);
5441 elements = *(const DWORD*)pFormat;
5442 pFormat += sizeof(DWORD);
5445 esize = *(const WORD*)pFormat;
5446 pFormat += sizeof(WORD);
5448 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5450 align_pointer(&pStubMsg->Buffer, alignment);
5452 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5453 offset = pStubMsg->Offset;
5455 if (!fMustAlloc && !*ppMemory)
5456 fMustAlloc = TRUE;
5457 if (fMustAlloc)
5458 *ppMemory = NdrAllocate(pStubMsg, size);
5459 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5460 safe_buffer_increment(pStubMsg, bufsize);
5462 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5464 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5466 return NULL;
5469 /***********************************************************************
5470 * NdrVaryingArrayBufferSize [RPCRT4.@]
5472 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5473 unsigned char *pMemory,
5474 PFORMAT_STRING pFormat)
5476 unsigned char alignment;
5477 DWORD elements, esize;
5479 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5481 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5482 (pFormat[0] != RPC_FC_LGVARRAY))
5484 ERR("invalid format type %x\n", pFormat[0]);
5485 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5486 return;
5489 alignment = pFormat[1] + 1;
5491 if (pFormat[0] == RPC_FC_SMVARRAY)
5493 pFormat += 2;
5494 pFormat += sizeof(WORD);
5495 elements = *(const WORD*)pFormat;
5496 pFormat += sizeof(WORD);
5498 else
5500 pFormat += 2;
5501 pFormat += sizeof(DWORD);
5502 elements = *(const DWORD*)pFormat;
5503 pFormat += sizeof(DWORD);
5506 esize = *(const WORD*)pFormat;
5507 pFormat += sizeof(WORD);
5509 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5510 if ((pStubMsg->ActualCount > elements) ||
5511 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5513 RpcRaiseException(RPC_S_INVALID_BOUND);
5514 return;
5517 SizeVariance(pStubMsg);
5519 align_length(&pStubMsg->BufferLength, alignment);
5521 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5523 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5526 /***********************************************************************
5527 * NdrVaryingArrayMemorySize [RPCRT4.@]
5529 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5530 PFORMAT_STRING pFormat)
5532 unsigned char alignment;
5533 DWORD size, elements, esize;
5535 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5537 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5538 (pFormat[0] != RPC_FC_LGVARRAY))
5540 ERR("invalid format type %x\n", pFormat[0]);
5541 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5542 return 0;
5545 alignment = pFormat[1] + 1;
5547 if (pFormat[0] == RPC_FC_SMVARRAY)
5549 pFormat += 2;
5550 size = *(const WORD*)pFormat;
5551 pFormat += sizeof(WORD);
5552 elements = *(const WORD*)pFormat;
5553 pFormat += sizeof(WORD);
5555 else
5557 pFormat += 2;
5558 size = *(const DWORD*)pFormat;
5559 pFormat += sizeof(DWORD);
5560 elements = *(const DWORD*)pFormat;
5561 pFormat += sizeof(DWORD);
5564 esize = *(const WORD*)pFormat;
5565 pFormat += sizeof(WORD);
5567 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5569 align_pointer(&pStubMsg->Buffer, alignment);
5571 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5572 pStubMsg->MemorySize += size;
5574 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5576 return pStubMsg->MemorySize;
5579 /***********************************************************************
5580 * NdrVaryingArrayFree [RPCRT4.@]
5582 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5583 unsigned char *pMemory,
5584 PFORMAT_STRING pFormat)
5586 DWORD elements;
5588 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5590 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5591 (pFormat[0] != RPC_FC_LGVARRAY))
5593 ERR("invalid format type %x\n", pFormat[0]);
5594 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5595 return;
5598 if (pFormat[0] == RPC_FC_SMVARRAY)
5600 pFormat += 2;
5601 pFormat += sizeof(WORD);
5602 elements = *(const WORD*)pFormat;
5603 pFormat += sizeof(WORD);
5605 else
5607 pFormat += 2;
5608 pFormat += sizeof(DWORD);
5609 elements = *(const DWORD*)pFormat;
5610 pFormat += sizeof(DWORD);
5613 pFormat += sizeof(WORD);
5615 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5616 if ((pStubMsg->ActualCount > elements) ||
5617 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5619 RpcRaiseException(RPC_S_INVALID_BOUND);
5620 return;
5623 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5626 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5628 switch (fc)
5630 case RPC_FC_BYTE:
5631 case RPC_FC_CHAR:
5632 case RPC_FC_SMALL:
5633 case RPC_FC_USMALL:
5634 return *pMemory;
5635 case RPC_FC_WCHAR:
5636 case RPC_FC_SHORT:
5637 case RPC_FC_USHORT:
5638 case RPC_FC_ENUM16:
5639 return *(const USHORT *)pMemory;
5640 case RPC_FC_LONG:
5641 case RPC_FC_ULONG:
5642 case RPC_FC_ENUM32:
5643 return *(const ULONG *)pMemory;
5644 case RPC_FC_INT3264:
5645 case RPC_FC_UINT3264:
5646 return *(const ULONG_PTR *)pMemory;
5647 default:
5648 FIXME("Unhandled base type: 0x%02x\n", fc);
5649 return 0;
5653 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5654 ULONG discriminant,
5655 PFORMAT_STRING pFormat)
5657 unsigned short num_arms, arm, type;
5659 num_arms = *(const SHORT*)pFormat & 0x0fff;
5660 pFormat += 2;
5661 for(arm = 0; arm < num_arms; arm++)
5663 if(discriminant == *(const ULONG*)pFormat)
5665 pFormat += 4;
5666 break;
5668 pFormat += 6;
5671 type = *(const unsigned short*)pFormat;
5672 TRACE("type %04x\n", type);
5673 if(arm == num_arms) /* default arm extras */
5675 if(type == 0xffff)
5677 ERR("no arm for 0x%x and no default case\n", discriminant);
5678 RpcRaiseException(RPC_S_INVALID_TAG);
5679 return NULL;
5681 if(type == 0)
5683 TRACE("falling back to empty default case for 0x%x\n", discriminant);
5684 return NULL;
5687 return pFormat;
5690 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5692 unsigned short type;
5694 pFormat += 2;
5696 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5697 if(!pFormat)
5698 return NULL;
5700 type = *(const unsigned short*)pFormat;
5701 if((type & 0xff00) == 0x8000)
5703 unsigned char basetype = LOBYTE(type);
5704 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5706 else
5708 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5709 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5710 if (m)
5712 unsigned char *saved_buffer = NULL;
5713 int pointer_buffer_mark_set = 0;
5714 switch(*desc)
5716 case RPC_FC_RP:
5717 case RPC_FC_UP:
5718 case RPC_FC_OP:
5719 case RPC_FC_FP:
5720 align_pointer_clear(&pStubMsg->Buffer, 4);
5721 saved_buffer = pStubMsg->Buffer;
5722 if (pStubMsg->PointerBufferMark)
5724 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5725 pStubMsg->PointerBufferMark = NULL;
5726 pointer_buffer_mark_set = 1;
5728 else
5729 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5731 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5732 if (pointer_buffer_mark_set)
5734 STD_OVERFLOW_CHECK(pStubMsg);
5735 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5736 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5738 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5739 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5740 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5742 pStubMsg->Buffer = saved_buffer + 4;
5744 break;
5745 default:
5746 m(pStubMsg, pMemory, desc);
5749 else FIXME("no marshaller for embedded type %02x\n", *desc);
5751 return NULL;
5754 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5755 unsigned char **ppMemory,
5756 ULONG discriminant,
5757 PFORMAT_STRING pFormat,
5758 unsigned char fMustAlloc)
5760 unsigned short type;
5762 pFormat += 2;
5764 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5765 if(!pFormat)
5766 return NULL;
5768 type = *(const unsigned short*)pFormat;
5769 if((type & 0xff00) == 0x8000)
5771 unsigned char basetype = LOBYTE(type);
5772 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5774 else
5776 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5777 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5778 if (m)
5780 unsigned char *saved_buffer = NULL;
5781 int pointer_buffer_mark_set = 0;
5782 switch(*desc)
5784 case RPC_FC_RP:
5785 case RPC_FC_UP:
5786 case RPC_FC_OP:
5787 case RPC_FC_FP:
5788 align_pointer(&pStubMsg->Buffer, 4);
5789 saved_buffer = pStubMsg->Buffer;
5790 if (pStubMsg->PointerBufferMark)
5792 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5793 pStubMsg->PointerBufferMark = NULL;
5794 pointer_buffer_mark_set = 1;
5796 else
5797 pStubMsg->Buffer += 4; /* for pointer ID */
5799 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5801 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5802 saved_buffer, pStubMsg->BufferEnd);
5803 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5806 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5807 if (pointer_buffer_mark_set)
5809 STD_OVERFLOW_CHECK(pStubMsg);
5810 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5811 pStubMsg->Buffer = saved_buffer + 4;
5813 break;
5814 default:
5815 m(pStubMsg, ppMemory, desc, fMustAlloc);
5818 else FIXME("no marshaller for embedded type %02x\n", *desc);
5820 return NULL;
5823 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5824 unsigned char *pMemory,
5825 ULONG discriminant,
5826 PFORMAT_STRING pFormat)
5828 unsigned short type;
5830 pFormat += 2;
5832 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5833 if(!pFormat)
5834 return;
5836 type = *(const unsigned short*)pFormat;
5837 if((type & 0xff00) == 0x8000)
5839 unsigned char basetype = LOBYTE(type);
5840 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5842 else
5844 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5845 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5846 if (m)
5848 switch(*desc)
5850 case RPC_FC_RP:
5851 case RPC_FC_UP:
5852 case RPC_FC_OP:
5853 case RPC_FC_FP:
5854 align_length(&pStubMsg->BufferLength, 4);
5855 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5856 if (!pStubMsg->IgnoreEmbeddedPointers)
5858 int saved_buffer_length = pStubMsg->BufferLength;
5859 pStubMsg->BufferLength = pStubMsg->PointerLength;
5860 pStubMsg->PointerLength = 0;
5861 if(!pStubMsg->BufferLength)
5862 ERR("BufferLength == 0??\n");
5863 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5864 pStubMsg->PointerLength = pStubMsg->BufferLength;
5865 pStubMsg->BufferLength = saved_buffer_length;
5867 break;
5868 default:
5869 m(pStubMsg, pMemory, desc);
5872 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5876 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5877 ULONG discriminant,
5878 PFORMAT_STRING pFormat)
5880 unsigned short type, size;
5882 size = *(const unsigned short*)pFormat;
5883 pStubMsg->Memory += size;
5884 pFormat += 2;
5886 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5887 if(!pFormat)
5888 return 0;
5890 type = *(const unsigned short*)pFormat;
5891 if((type & 0xff00) == 0x8000)
5893 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5895 else
5897 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5898 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5899 unsigned char *saved_buffer;
5900 if (m)
5902 switch(*desc)
5904 case RPC_FC_RP:
5905 case RPC_FC_UP:
5906 case RPC_FC_OP:
5907 case RPC_FC_FP:
5908 align_pointer(&pStubMsg->Buffer, 4);
5909 saved_buffer = pStubMsg->Buffer;
5910 safe_buffer_increment(pStubMsg, 4);
5911 align_length(&pStubMsg->MemorySize, sizeof(void *));
5912 pStubMsg->MemorySize += sizeof(void *);
5913 if (!pStubMsg->IgnoreEmbeddedPointers)
5914 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5915 break;
5916 default:
5917 return m(pStubMsg, desc);
5920 else FIXME("no marshaller for embedded type %02x\n", *desc);
5923 TRACE("size %d\n", size);
5924 return size;
5927 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5928 unsigned char *pMemory,
5929 ULONG discriminant,
5930 PFORMAT_STRING pFormat)
5932 unsigned short type;
5934 pFormat += 2;
5936 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5937 if(!pFormat)
5938 return;
5940 type = *(const unsigned short*)pFormat;
5941 if((type & 0xff00) != 0x8000)
5943 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5944 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5945 if (m)
5947 switch(*desc)
5949 case RPC_FC_RP:
5950 case RPC_FC_UP:
5951 case RPC_FC_OP:
5952 case RPC_FC_FP:
5953 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5954 break;
5955 default:
5956 m(pStubMsg, pMemory, desc);
5962 /***********************************************************************
5963 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5965 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5966 unsigned char *pMemory,
5967 PFORMAT_STRING pFormat)
5969 unsigned char switch_type;
5970 unsigned char increment;
5971 ULONG switch_value;
5973 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5974 pFormat++;
5976 switch_type = *pFormat & 0xf;
5977 increment = (*pFormat & 0xf0) >> 4;
5978 pFormat++;
5980 align_pointer_clear(&pStubMsg->Buffer, increment);
5982 switch_value = get_discriminant(switch_type, pMemory);
5983 TRACE("got switch value 0x%x\n", switch_value);
5985 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5986 pMemory += increment;
5988 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5991 /***********************************************************************
5992 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5994 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5995 unsigned char **ppMemory,
5996 PFORMAT_STRING pFormat,
5997 unsigned char fMustAlloc)
5999 unsigned char switch_type;
6000 unsigned char increment;
6001 ULONG switch_value;
6002 unsigned short size;
6003 unsigned char *pMemoryArm;
6005 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6006 pFormat++;
6008 switch_type = *pFormat & 0xf;
6009 increment = (*pFormat & 0xf0) >> 4;
6010 pFormat++;
6012 align_pointer(&pStubMsg->Buffer, increment);
6013 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6014 TRACE("got switch value 0x%x\n", switch_value);
6016 size = *(const unsigned short*)pFormat + increment;
6017 if (!fMustAlloc && !*ppMemory)
6018 fMustAlloc = TRUE;
6019 if (fMustAlloc)
6020 *ppMemory = NdrAllocate(pStubMsg, size);
6022 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6023 * since the arm is part of the memory block that is encompassed by
6024 * the whole union. Memory is forced to allocate when pointers
6025 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6026 * clearing the memory we pass in to the unmarshaller */
6027 if (fMustAlloc)
6028 memset(*ppMemory, 0, size);
6030 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
6031 pMemoryArm = *ppMemory + increment;
6033 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, FALSE);
6036 /***********************************************************************
6037 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
6039 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6040 unsigned char *pMemory,
6041 PFORMAT_STRING pFormat)
6043 unsigned char switch_type;
6044 unsigned char increment;
6045 ULONG switch_value;
6047 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6048 pFormat++;
6050 switch_type = *pFormat & 0xf;
6051 increment = (*pFormat & 0xf0) >> 4;
6052 pFormat++;
6054 align_length(&pStubMsg->BufferLength, increment);
6055 switch_value = get_discriminant(switch_type, pMemory);
6056 TRACE("got switch value 0x%x\n", switch_value);
6058 /* Add discriminant size */
6059 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
6060 pMemory += increment;
6062 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
6065 /***********************************************************************
6066 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
6068 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6069 PFORMAT_STRING pFormat)
6071 unsigned char switch_type;
6072 unsigned char increment;
6073 ULONG switch_value;
6075 switch_type = *pFormat & 0xf;
6076 increment = (*pFormat & 0xf0) >> 4;
6077 pFormat++;
6079 align_pointer(&pStubMsg->Buffer, increment);
6080 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6081 TRACE("got switch value 0x%x\n", switch_value);
6083 pStubMsg->Memory += increment;
6085 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
6088 /***********************************************************************
6089 * NdrEncapsulatedUnionFree [RPCRT4.@]
6091 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6092 unsigned char *pMemory,
6093 PFORMAT_STRING pFormat)
6095 unsigned char switch_type;
6096 unsigned char increment;
6097 ULONG switch_value;
6099 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6100 pFormat++;
6102 switch_type = *pFormat & 0xf;
6103 increment = (*pFormat & 0xf0) >> 4;
6104 pFormat++;
6106 switch_value = get_discriminant(switch_type, pMemory);
6107 TRACE("got switch value 0x%x\n", switch_value);
6109 pMemory += increment;
6111 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
6114 /***********************************************************************
6115 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
6117 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6118 unsigned char *pMemory,
6119 PFORMAT_STRING pFormat)
6121 unsigned char switch_type;
6123 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6124 pFormat++;
6126 switch_type = *pFormat;
6127 pFormat++;
6129 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6130 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6131 /* Marshall discriminant */
6132 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6134 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6137 static LONG unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
6138 PFORMAT_STRING *ppFormat)
6140 LONG discriminant = 0;
6142 switch(**ppFormat)
6144 case RPC_FC_BYTE:
6145 case RPC_FC_CHAR:
6146 case RPC_FC_SMALL:
6147 case RPC_FC_USMALL:
6149 UCHAR d;
6150 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6151 discriminant = d;
6152 break;
6154 case RPC_FC_WCHAR:
6155 case RPC_FC_SHORT:
6156 case RPC_FC_USHORT:
6158 USHORT d;
6159 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6160 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6161 discriminant = d;
6162 break;
6164 case RPC_FC_LONG:
6165 case RPC_FC_ULONG:
6167 ULONG d;
6168 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6169 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6170 discriminant = d;
6171 break;
6173 default:
6174 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
6176 (*ppFormat)++;
6178 if (pStubMsg->fHasNewCorrDesc)
6179 *ppFormat += 6;
6180 else
6181 *ppFormat += 4;
6182 return discriminant;
6185 /**********************************************************************
6186 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6188 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6189 unsigned char **ppMemory,
6190 PFORMAT_STRING pFormat,
6191 unsigned char fMustAlloc)
6193 LONG discriminant;
6194 unsigned short size;
6196 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6197 pFormat++;
6199 /* Unmarshall discriminant */
6200 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6201 TRACE("unmarshalled discriminant %x\n", discriminant);
6203 pFormat += *(const SHORT*)pFormat;
6205 size = *(const unsigned short*)pFormat;
6207 if (!fMustAlloc && !*ppMemory)
6208 fMustAlloc = TRUE;
6209 if (fMustAlloc)
6210 *ppMemory = NdrAllocate(pStubMsg, size);
6212 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6213 * since the arm is part of the memory block that is encompassed by
6214 * the whole union. Memory is forced to allocate when pointers
6215 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6216 * clearing the memory we pass in to the unmarshaller */
6217 if (fMustAlloc)
6218 memset(*ppMemory, 0, size);
6220 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, FALSE);
6223 /***********************************************************************
6224 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6226 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6227 unsigned char *pMemory,
6228 PFORMAT_STRING pFormat)
6230 unsigned char switch_type;
6232 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6233 pFormat++;
6235 switch_type = *pFormat;
6236 pFormat++;
6238 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6239 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6240 /* Add discriminant size */
6241 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6243 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6246 /***********************************************************************
6247 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6249 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6250 PFORMAT_STRING pFormat)
6252 ULONG discriminant;
6254 pFormat++;
6255 /* Unmarshall discriminant */
6256 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6257 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
6259 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
6262 /***********************************************************************
6263 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6265 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6266 unsigned char *pMemory,
6267 PFORMAT_STRING pFormat)
6269 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6270 pFormat++;
6271 pFormat++;
6273 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6274 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6276 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6279 /***********************************************************************
6280 * NdrByteCountPointerMarshall [RPCRT4.@]
6282 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6283 unsigned char *pMemory,
6284 PFORMAT_STRING pFormat)
6286 FIXME("stub\n");
6287 return NULL;
6290 /***********************************************************************
6291 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6293 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6294 unsigned char **ppMemory,
6295 PFORMAT_STRING pFormat,
6296 unsigned char fMustAlloc)
6298 FIXME("stub\n");
6299 return NULL;
6302 /***********************************************************************
6303 * NdrByteCountPointerBufferSize [RPCRT4.@]
6305 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6306 unsigned char *pMemory,
6307 PFORMAT_STRING pFormat)
6309 FIXME("stub\n");
6312 /***********************************************************************
6313 * NdrByteCountPointerMemorySize [internal]
6315 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6316 PFORMAT_STRING pFormat)
6318 FIXME("stub\n");
6319 return 0;
6322 /***********************************************************************
6323 * NdrByteCountPointerFree [RPCRT4.@]
6325 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6326 unsigned char *pMemory,
6327 PFORMAT_STRING pFormat)
6329 FIXME("stub\n");
6332 /***********************************************************************
6333 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6335 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6336 unsigned char *pMemory,
6337 PFORMAT_STRING pFormat)
6339 FIXME("stub\n");
6340 return NULL;
6343 /***********************************************************************
6344 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6346 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6347 unsigned char **ppMemory,
6348 PFORMAT_STRING pFormat,
6349 unsigned char fMustAlloc)
6351 FIXME("stub\n");
6352 return NULL;
6355 /***********************************************************************
6356 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6358 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6359 unsigned char *pMemory,
6360 PFORMAT_STRING pFormat)
6362 FIXME("stub\n");
6365 /***********************************************************************
6366 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6368 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6369 PFORMAT_STRING pFormat)
6371 FIXME("stub\n");
6372 return 0;
6375 /***********************************************************************
6376 * NdrXmitOrRepAsFree [RPCRT4.@]
6378 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6379 unsigned char *pMemory,
6380 PFORMAT_STRING pFormat)
6382 FIXME("stub\n");
6385 /***********************************************************************
6386 * NdrRangeMarshall [internal]
6388 static unsigned char *WINAPI NdrRangeMarshall(
6389 PMIDL_STUB_MESSAGE pStubMsg,
6390 unsigned char *pMemory,
6391 PFORMAT_STRING pFormat)
6393 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6394 unsigned char base_type;
6396 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6398 if (pRange->type != RPC_FC_RANGE)
6400 ERR("invalid format type %x\n", pRange->type);
6401 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6402 return NULL;
6405 base_type = pRange->flags_type & 0xf;
6407 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6410 /***********************************************************************
6411 * NdrRangeUnmarshall [RPCRT4.@]
6413 unsigned char *WINAPI NdrRangeUnmarshall(
6414 PMIDL_STUB_MESSAGE pStubMsg,
6415 unsigned char **ppMemory,
6416 PFORMAT_STRING pFormat,
6417 unsigned char fMustAlloc)
6419 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6420 unsigned char base_type;
6422 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6424 if (pRange->type != RPC_FC_RANGE)
6426 ERR("invalid format type %x\n", pRange->type);
6427 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6428 return NULL;
6430 base_type = pRange->flags_type & 0xf;
6432 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6433 base_type, pRange->low_value, pRange->high_value);
6435 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6436 do \
6438 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \
6439 if (!fMustAlloc && !*ppMemory) \
6440 fMustAlloc = TRUE; \
6441 if (fMustAlloc) \
6442 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6443 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6445 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6446 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6447 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6449 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6450 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6452 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6453 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6454 (mem_type)pRange->high_value); \
6455 RpcRaiseException(RPC_S_INVALID_BOUND); \
6456 return NULL; \
6458 TRACE("*ppMemory: %p\n", *ppMemory); \
6459 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6460 pStubMsg->Buffer += sizeof(wire_type); \
6461 } while (0)
6463 switch(base_type)
6465 case RPC_FC_CHAR:
6466 case RPC_FC_SMALL:
6467 RANGE_UNMARSHALL(UCHAR, UCHAR, "%d");
6468 TRACE("value: 0x%02x\n", **ppMemory);
6469 break;
6470 case RPC_FC_BYTE:
6471 case RPC_FC_USMALL:
6472 RANGE_UNMARSHALL(CHAR, CHAR, "%u");
6473 TRACE("value: 0x%02x\n", **ppMemory);
6474 break;
6475 case RPC_FC_WCHAR: /* FIXME: valid? */
6476 case RPC_FC_USHORT:
6477 RANGE_UNMARSHALL(USHORT, USHORT, "%u");
6478 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6479 break;
6480 case RPC_FC_SHORT:
6481 RANGE_UNMARSHALL(SHORT, SHORT, "%d");
6482 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6483 break;
6484 case RPC_FC_LONG:
6485 case RPC_FC_ENUM32:
6486 RANGE_UNMARSHALL(LONG, LONG, "%d");
6487 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6488 break;
6489 case RPC_FC_ULONG:
6490 RANGE_UNMARSHALL(ULONG, ULONG, "%u");
6491 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6492 break;
6493 case RPC_FC_ENUM16:
6494 RANGE_UNMARSHALL(UINT, USHORT, "%u");
6495 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6496 break;
6497 case RPC_FC_FLOAT:
6498 case RPC_FC_DOUBLE:
6499 case RPC_FC_HYPER:
6500 default:
6501 ERR("invalid range base type: 0x%02x\n", base_type);
6502 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6505 return NULL;
6508 /***********************************************************************
6509 * NdrRangeBufferSize [internal]
6511 static void WINAPI NdrRangeBufferSize(
6512 PMIDL_STUB_MESSAGE pStubMsg,
6513 unsigned char *pMemory,
6514 PFORMAT_STRING pFormat)
6516 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6517 unsigned char base_type;
6519 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6521 if (pRange->type != RPC_FC_RANGE)
6523 ERR("invalid format type %x\n", pRange->type);
6524 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6526 base_type = pRange->flags_type & 0xf;
6528 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6531 /***********************************************************************
6532 * NdrRangeMemorySize [internal]
6534 static ULONG WINAPI NdrRangeMemorySize(
6535 PMIDL_STUB_MESSAGE pStubMsg,
6536 PFORMAT_STRING pFormat)
6538 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6539 unsigned char base_type;
6541 if (pRange->type != RPC_FC_RANGE)
6543 ERR("invalid format type %x\n", pRange->type);
6544 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6545 return 0;
6547 base_type = pRange->flags_type & 0xf;
6549 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6552 /***********************************************************************
6553 * NdrRangeFree [internal]
6555 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6556 unsigned char *pMemory,
6557 PFORMAT_STRING pFormat)
6559 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6561 /* nothing to do */
6564 /***********************************************************************
6565 * NdrBaseTypeMarshall [internal]
6567 static unsigned char *WINAPI NdrBaseTypeMarshall(
6568 PMIDL_STUB_MESSAGE pStubMsg,
6569 unsigned char *pMemory,
6570 PFORMAT_STRING pFormat)
6572 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6574 switch(*pFormat)
6576 case RPC_FC_BYTE:
6577 case RPC_FC_CHAR:
6578 case RPC_FC_SMALL:
6579 case RPC_FC_USMALL:
6580 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6581 TRACE("value: 0x%02x\n", *pMemory);
6582 break;
6583 case RPC_FC_WCHAR:
6584 case RPC_FC_SHORT:
6585 case RPC_FC_USHORT:
6586 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6587 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6588 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6589 break;
6590 case RPC_FC_LONG:
6591 case RPC_FC_ULONG:
6592 case RPC_FC_ERROR_STATUS_T:
6593 case RPC_FC_ENUM32:
6594 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONG));
6595 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6596 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6597 break;
6598 case RPC_FC_FLOAT:
6599 align_pointer_clear(&pStubMsg->Buffer, sizeof(float));
6600 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6601 break;
6602 case RPC_FC_DOUBLE:
6603 align_pointer_clear(&pStubMsg->Buffer, sizeof(double));
6604 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6605 break;
6606 case RPC_FC_HYPER:
6607 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONGLONG));
6608 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6609 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6610 break;
6611 case RPC_FC_ENUM16:
6613 USHORT val = *(UINT *)pMemory;
6614 /* only 16-bits on the wire, so do a sanity check */
6615 if (*(UINT *)pMemory > SHRT_MAX)
6616 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6617 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6618 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6619 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6620 break;
6622 case RPC_FC_INT3264:
6623 case RPC_FC_UINT3264:
6625 UINT val = *(UINT_PTR *)pMemory;
6626 align_pointer_clear(&pStubMsg->Buffer, sizeof(UINT));
6627 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6628 break;
6630 case RPC_FC_IGNORE:
6631 break;
6632 default:
6633 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6636 /* FIXME: what is the correct return value? */
6637 return NULL;
6640 /***********************************************************************
6641 * NdrBaseTypeUnmarshall [internal]
6643 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6644 PMIDL_STUB_MESSAGE pStubMsg,
6645 unsigned char **ppMemory,
6646 PFORMAT_STRING pFormat,
6647 unsigned char fMustAlloc)
6649 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6651 #define BASE_TYPE_UNMARSHALL(type) do { \
6652 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
6653 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6655 *ppMemory = pStubMsg->Buffer; \
6656 TRACE("*ppMemory: %p\n", *ppMemory); \
6657 safe_buffer_increment(pStubMsg, sizeof(type)); \
6659 else \
6661 if (fMustAlloc) \
6662 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6663 TRACE("*ppMemory: %p\n", *ppMemory); \
6664 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6666 } while (0)
6668 switch(*pFormat)
6670 case RPC_FC_BYTE:
6671 case RPC_FC_CHAR:
6672 case RPC_FC_SMALL:
6673 case RPC_FC_USMALL:
6674 BASE_TYPE_UNMARSHALL(UCHAR);
6675 TRACE("value: 0x%02x\n", **ppMemory);
6676 break;
6677 case RPC_FC_WCHAR:
6678 case RPC_FC_SHORT:
6679 case RPC_FC_USHORT:
6680 BASE_TYPE_UNMARSHALL(USHORT);
6681 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6682 break;
6683 case RPC_FC_LONG:
6684 case RPC_FC_ULONG:
6685 case RPC_FC_ERROR_STATUS_T:
6686 case RPC_FC_ENUM32:
6687 BASE_TYPE_UNMARSHALL(ULONG);
6688 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6689 break;
6690 case RPC_FC_FLOAT:
6691 BASE_TYPE_UNMARSHALL(float);
6692 TRACE("value: %f\n", **(float **)ppMemory);
6693 break;
6694 case RPC_FC_DOUBLE:
6695 BASE_TYPE_UNMARSHALL(double);
6696 TRACE("value: %f\n", **(double **)ppMemory);
6697 break;
6698 case RPC_FC_HYPER:
6699 BASE_TYPE_UNMARSHALL(ULONGLONG);
6700 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6701 break;
6702 case RPC_FC_ENUM16:
6704 USHORT val;
6705 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6706 if (!fMustAlloc && !*ppMemory)
6707 fMustAlloc = TRUE;
6708 if (fMustAlloc)
6709 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6710 safe_copy_from_buffer(pStubMsg, &val, sizeof(USHORT));
6711 /* 16-bits on the wire, but int in memory */
6712 **(UINT **)ppMemory = val;
6713 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6714 break;
6716 case RPC_FC_INT3264:
6717 if (sizeof(INT_PTR) == sizeof(INT)) BASE_TYPE_UNMARSHALL(INT);
6718 else
6720 INT val;
6721 align_pointer(&pStubMsg->Buffer, sizeof(INT));
6722 if (!fMustAlloc && !*ppMemory)
6723 fMustAlloc = TRUE;
6724 if (fMustAlloc)
6725 *ppMemory = NdrAllocate(pStubMsg, sizeof(INT_PTR));
6726 safe_copy_from_buffer(pStubMsg, &val, sizeof(INT));
6727 **(INT_PTR **)ppMemory = val;
6728 TRACE("value: 0x%08lx\n", **(INT_PTR **)ppMemory);
6730 break;
6731 case RPC_FC_UINT3264:
6732 if (sizeof(UINT_PTR) == sizeof(UINT)) BASE_TYPE_UNMARSHALL(UINT);
6733 else
6735 UINT val;
6736 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6737 if (!fMustAlloc && !*ppMemory)
6738 fMustAlloc = TRUE;
6739 if (fMustAlloc)
6740 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT_PTR));
6741 safe_copy_from_buffer(pStubMsg, &val, sizeof(UINT));
6742 **(UINT_PTR **)ppMemory = val;
6743 TRACE("value: 0x%08lx\n", **(UINT_PTR **)ppMemory);
6745 break;
6746 case RPC_FC_IGNORE:
6747 break;
6748 default:
6749 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6751 #undef BASE_TYPE_UNMARSHALL
6753 /* FIXME: what is the correct return value? */
6755 return NULL;
6758 /***********************************************************************
6759 * NdrBaseTypeBufferSize [internal]
6761 static void WINAPI NdrBaseTypeBufferSize(
6762 PMIDL_STUB_MESSAGE pStubMsg,
6763 unsigned char *pMemory,
6764 PFORMAT_STRING pFormat)
6766 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6768 switch(*pFormat)
6770 case RPC_FC_BYTE:
6771 case RPC_FC_CHAR:
6772 case RPC_FC_SMALL:
6773 case RPC_FC_USMALL:
6774 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6775 break;
6776 case RPC_FC_WCHAR:
6777 case RPC_FC_SHORT:
6778 case RPC_FC_USHORT:
6779 case RPC_FC_ENUM16:
6780 align_length(&pStubMsg->BufferLength, sizeof(USHORT));
6781 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6782 break;
6783 case RPC_FC_LONG:
6784 case RPC_FC_ULONG:
6785 case RPC_FC_ENUM32:
6786 case RPC_FC_INT3264:
6787 case RPC_FC_UINT3264:
6788 align_length(&pStubMsg->BufferLength, sizeof(ULONG));
6789 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6790 break;
6791 case RPC_FC_FLOAT:
6792 align_length(&pStubMsg->BufferLength, sizeof(float));
6793 safe_buffer_length_increment(pStubMsg, sizeof(float));
6794 break;
6795 case RPC_FC_DOUBLE:
6796 align_length(&pStubMsg->BufferLength, sizeof(double));
6797 safe_buffer_length_increment(pStubMsg, sizeof(double));
6798 break;
6799 case RPC_FC_HYPER:
6800 align_length(&pStubMsg->BufferLength, sizeof(ULONGLONG));
6801 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6802 break;
6803 case RPC_FC_ERROR_STATUS_T:
6804 align_length(&pStubMsg->BufferLength, sizeof(error_status_t));
6805 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6806 break;
6807 case RPC_FC_IGNORE:
6808 break;
6809 default:
6810 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6814 /***********************************************************************
6815 * NdrBaseTypeMemorySize [internal]
6817 static ULONG WINAPI NdrBaseTypeMemorySize(
6818 PMIDL_STUB_MESSAGE pStubMsg,
6819 PFORMAT_STRING pFormat)
6821 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6823 switch(*pFormat)
6825 case RPC_FC_BYTE:
6826 case RPC_FC_CHAR:
6827 case RPC_FC_SMALL:
6828 case RPC_FC_USMALL:
6829 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6830 pStubMsg->MemorySize += sizeof(UCHAR);
6831 return sizeof(UCHAR);
6832 case RPC_FC_WCHAR:
6833 case RPC_FC_SHORT:
6834 case RPC_FC_USHORT:
6835 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6836 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6837 align_length(&pStubMsg->MemorySize, sizeof(USHORT));
6838 pStubMsg->MemorySize += sizeof(USHORT);
6839 return sizeof(USHORT);
6840 case RPC_FC_LONG:
6841 case RPC_FC_ULONG:
6842 case RPC_FC_ENUM32:
6843 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6844 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6845 align_length(&pStubMsg->MemorySize, sizeof(ULONG));
6846 pStubMsg->MemorySize += sizeof(ULONG);
6847 return sizeof(ULONG);
6848 case RPC_FC_FLOAT:
6849 align_pointer(&pStubMsg->Buffer, sizeof(float));
6850 safe_buffer_increment(pStubMsg, sizeof(float));
6851 align_length(&pStubMsg->MemorySize, sizeof(float));
6852 pStubMsg->MemorySize += sizeof(float);
6853 return sizeof(float);
6854 case RPC_FC_DOUBLE:
6855 align_pointer(&pStubMsg->Buffer, sizeof(double));
6856 safe_buffer_increment(pStubMsg, sizeof(double));
6857 align_length(&pStubMsg->MemorySize, sizeof(double));
6858 pStubMsg->MemorySize += sizeof(double);
6859 return sizeof(double);
6860 case RPC_FC_HYPER:
6861 align_pointer(&pStubMsg->Buffer, sizeof(ULONGLONG));
6862 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6863 align_length(&pStubMsg->MemorySize, sizeof(ULONGLONG));
6864 pStubMsg->MemorySize += sizeof(ULONGLONG);
6865 return sizeof(ULONGLONG);
6866 case RPC_FC_ERROR_STATUS_T:
6867 align_pointer(&pStubMsg->Buffer, sizeof(error_status_t));
6868 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6869 align_length(&pStubMsg->MemorySize, sizeof(error_status_t));
6870 pStubMsg->MemorySize += sizeof(error_status_t);
6871 return sizeof(error_status_t);
6872 case RPC_FC_ENUM16:
6873 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6874 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6875 align_length(&pStubMsg->MemorySize, sizeof(UINT));
6876 pStubMsg->MemorySize += sizeof(UINT);
6877 return sizeof(UINT);
6878 case RPC_FC_INT3264:
6879 case RPC_FC_UINT3264:
6880 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6881 safe_buffer_increment(pStubMsg, sizeof(UINT));
6882 align_length(&pStubMsg->MemorySize, sizeof(UINT_PTR));
6883 pStubMsg->MemorySize += sizeof(UINT_PTR);
6884 return sizeof(UINT_PTR);
6885 case RPC_FC_IGNORE:
6886 align_length(&pStubMsg->MemorySize, sizeof(void *));
6887 pStubMsg->MemorySize += sizeof(void *);
6888 return sizeof(void *);
6889 default:
6890 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6891 return 0;
6895 /***********************************************************************
6896 * NdrBaseTypeFree [internal]
6898 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6899 unsigned char *pMemory,
6900 PFORMAT_STRING pFormat)
6902 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6904 /* nothing to do */
6907 /***********************************************************************
6908 * NdrContextHandleBufferSize [internal]
6910 static void WINAPI NdrContextHandleBufferSize(
6911 PMIDL_STUB_MESSAGE pStubMsg,
6912 unsigned char *pMemory,
6913 PFORMAT_STRING pFormat)
6915 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6917 if (*pFormat != RPC_FC_BIND_CONTEXT)
6919 ERR("invalid format type %x\n", *pFormat);
6920 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6922 align_length(&pStubMsg->BufferLength, 4);
6923 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6926 /***********************************************************************
6927 * NdrContextHandleMarshall [internal]
6929 static unsigned char *WINAPI NdrContextHandleMarshall(
6930 PMIDL_STUB_MESSAGE pStubMsg,
6931 unsigned char *pMemory,
6932 PFORMAT_STRING pFormat)
6934 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6936 if (*pFormat != RPC_FC_BIND_CONTEXT)
6938 ERR("invalid format type %x\n", *pFormat);
6939 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6941 TRACE("flags: 0x%02x\n", pFormat[1]);
6943 if (pStubMsg->IsClient)
6945 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6946 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6947 else
6948 NdrClientContextMarshall(pStubMsg, pMemory, FALSE);
6950 else
6952 NDR_SCONTEXT ctxt = NDRSContextFromValue(pMemory);
6953 NDR_RUNDOWN rundown = pStubMsg->StubDesc->apfnNdrRundownRoutines[pFormat[2]];
6954 NdrServerContextNewMarshall(pStubMsg, ctxt, rundown, pFormat);
6957 return NULL;
6960 /***********************************************************************
6961 * NdrContextHandleUnmarshall [internal]
6963 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6964 PMIDL_STUB_MESSAGE pStubMsg,
6965 unsigned char **ppMemory,
6966 PFORMAT_STRING pFormat,
6967 unsigned char fMustAlloc)
6969 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6970 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6972 if (*pFormat != RPC_FC_BIND_CONTEXT)
6974 ERR("invalid format type %x\n", *pFormat);
6975 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6977 TRACE("flags: 0x%02x\n", pFormat[1]);
6979 if (pStubMsg->IsClient)
6981 /* [out]-only or [ret] param */
6982 if ((pFormat[1] & (HANDLE_PARAM_IS_IN|HANDLE_PARAM_IS_OUT)) == HANDLE_PARAM_IS_OUT)
6983 **(NDR_CCONTEXT **)ppMemory = NULL;
6984 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6986 else
6988 NDR_SCONTEXT ctxt;
6989 ctxt = NdrServerContextNewUnmarshall(pStubMsg, pFormat);
6990 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6991 *(void **)ppMemory = NDRSContextValue(ctxt);
6992 else
6993 *(void **)ppMemory = *NDRSContextValue(ctxt);
6996 return NULL;
6999 /***********************************************************************
7000 * NdrClientContextMarshall [RPCRT4.@]
7002 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7003 NDR_CCONTEXT ContextHandle,
7004 int fCheck)
7006 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
7008 align_pointer_clear(&pStubMsg->Buffer, 4);
7010 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7012 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7013 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7014 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7017 /* FIXME: what does fCheck do? */
7018 NDRCContextMarshall(ContextHandle,
7019 pStubMsg->Buffer);
7021 pStubMsg->Buffer += cbNDRContext;
7024 /***********************************************************************
7025 * NdrClientContextUnmarshall [RPCRT4.@]
7027 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7028 NDR_CCONTEXT * pContextHandle,
7029 RPC_BINDING_HANDLE BindHandle)
7031 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
7033 align_pointer(&pStubMsg->Buffer, 4);
7035 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
7036 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7038 NDRCContextUnmarshall(pContextHandle,
7039 BindHandle,
7040 pStubMsg->Buffer,
7041 pStubMsg->RpcMsg->DataRepresentation);
7043 pStubMsg->Buffer += cbNDRContext;
7046 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7047 NDR_SCONTEXT ContextHandle,
7048 NDR_RUNDOWN RundownRoutine )
7050 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
7052 align_pointer(&pStubMsg->Buffer, 4);
7054 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7056 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7057 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7058 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7061 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7062 pStubMsg->Buffer, RundownRoutine, NULL,
7063 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7064 pStubMsg->Buffer += cbNDRContext;
7067 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
7069 NDR_SCONTEXT ContextHandle;
7071 TRACE("(%p)\n", pStubMsg);
7073 align_pointer(&pStubMsg->Buffer, 4);
7075 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7077 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7078 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7079 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7082 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7083 pStubMsg->Buffer,
7084 pStubMsg->RpcMsg->DataRepresentation,
7085 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7086 pStubMsg->Buffer += cbNDRContext;
7088 return ContextHandle;
7091 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
7092 unsigned char* pMemory,
7093 PFORMAT_STRING pFormat)
7095 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
7098 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
7099 PFORMAT_STRING pFormat)
7101 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7102 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7104 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7106 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7107 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7108 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7109 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7110 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7112 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7113 if_id = &sif->InterfaceId;
7116 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
7117 pStubMsg->RpcMsg->DataRepresentation, if_id,
7118 flags);
7121 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7122 NDR_SCONTEXT ContextHandle,
7123 NDR_RUNDOWN RundownRoutine,
7124 PFORMAT_STRING pFormat)
7126 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7127 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7129 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
7131 align_pointer(&pStubMsg->Buffer, 4);
7133 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7135 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7136 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7137 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7140 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7141 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7142 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7143 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7144 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7146 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7147 if_id = &sif->InterfaceId;
7150 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7151 pStubMsg->Buffer, RundownRoutine, if_id, flags);
7152 pStubMsg->Buffer += cbNDRContext;
7155 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7156 PFORMAT_STRING pFormat)
7158 NDR_SCONTEXT ContextHandle;
7159 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7160 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7162 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7164 align_pointer(&pStubMsg->Buffer, 4);
7166 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7168 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7169 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7170 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7173 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7174 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7175 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7176 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7177 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7179 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7180 if_id = &sif->InterfaceId;
7183 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7184 pStubMsg->Buffer,
7185 pStubMsg->RpcMsg->DataRepresentation,
7186 if_id, flags);
7187 pStubMsg->Buffer += cbNDRContext;
7189 return ContextHandle;
7192 /***********************************************************************
7193 * NdrCorrelationInitialize [RPCRT4.@]
7195 * Initializes correlation validity checking.
7197 * PARAMS
7198 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7199 * pMemory [I] Pointer to memory to use as a cache.
7200 * CacheSize [I] Size of the memory pointed to by pMemory.
7201 * Flags [I] Reserved. Set to zero.
7203 * RETURNS
7204 * Nothing.
7206 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
7208 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
7209 pStubMsg->fHasNewCorrDesc = TRUE;
7212 /***********************************************************************
7213 * NdrCorrelationPass [RPCRT4.@]
7215 * Performs correlation validity checking.
7217 * PARAMS
7218 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7220 * RETURNS
7221 * Nothing.
7223 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
7225 FIXME("(%p): stub\n", pStubMsg);
7228 /***********************************************************************
7229 * NdrCorrelationFree [RPCRT4.@]
7231 * Frees any resources used while unmarshalling parameters that need
7232 * correlation validity checking.
7234 * PARAMS
7235 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7237 * RETURNS
7238 * Nothing.
7240 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
7242 FIXME("(%p): stub\n", pStubMsg);