usp10: Handle Ligature Substitution Subtable from GSUB.
[wine/testsucceed.git] / dlls / rpcrt4 / ndr_marshall.c
blob3ad55aa95b333077b931f52573c48725fde0a01d
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;
2065 unsigned char alignment;
2067 switch (fc)
2069 case RPC_FC_CARRAY:
2070 esize = *(const WORD*)(pFormat+2);
2071 pFormat = ReadConformance(pStubMsg, pFormat+4);
2072 return safe_multiply(esize, pStubMsg->MaxCount);
2073 case RPC_FC_CVARRAY:
2074 esize = *(const WORD*)(pFormat+2);
2075 pFormat = ReadConformance(pStubMsg, pFormat+4);
2076 return safe_multiply(esize, pStubMsg->MaxCount);
2077 case RPC_FC_C_CSTRING:
2078 case RPC_FC_C_WSTRING:
2079 if (fc == RPC_FC_C_CSTRING)
2080 esize = 1;
2081 else
2082 esize = 2;
2084 if (pFormat[1] == RPC_FC_STRING_SIZED)
2085 ReadConformance(pStubMsg, pFormat + 2);
2086 else
2087 ReadConformance(pStubMsg, NULL);
2088 return safe_multiply(esize, pStubMsg->MaxCount);
2089 case RPC_FC_BOGUS_ARRAY:
2090 alignment = pFormat[1] + 1;
2091 def = *(const WORD *)(pFormat + 2);
2092 pFormat += 4;
2093 if (IsConformanceOrVariancePresent(pFormat)) pFormat = ReadConformance(pStubMsg, pFormat);
2094 else
2096 pStubMsg->MaxCount = def;
2097 pFormat = SkipConformance( pStubMsg, pFormat );
2099 pFormat = SkipVariance( pStubMsg, pFormat );
2101 align_pointer(&pStubMsg->Buffer, alignment);
2102 esize = ComplexStructSize(pStubMsg, pFormat);
2103 return safe_multiply(pStubMsg->MaxCount, esize);
2104 default:
2105 ERR("unknown array format 0x%x\n", fc);
2106 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2110 static inline ULONG array_read_variance_and_unmarshall(
2111 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory,
2112 PFORMAT_STRING pFormat, unsigned char fMustAlloc,
2113 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall)
2115 ULONG bufsize, memsize;
2116 WORD esize;
2117 unsigned char alignment;
2118 unsigned char *saved_buffer, *pMemory;
2119 ULONG i, offset, count;
2121 switch (fc)
2123 case RPC_FC_CARRAY:
2124 esize = *(const WORD*)(pFormat+2);
2125 alignment = pFormat[1] + 1;
2127 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2129 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2131 align_pointer(&pStubMsg->Buffer, alignment);
2133 if (fUnmarshall)
2135 if (fMustAlloc)
2136 *ppMemory = NdrAllocate(pStubMsg, memsize);
2137 else
2139 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory)
2140 /* for servers, we just point straight into the RPC buffer */
2141 *ppMemory = pStubMsg->Buffer;
2144 saved_buffer = pStubMsg->Buffer;
2145 safe_buffer_increment(pStubMsg, bufsize);
2147 pStubMsg->BufferMark = saved_buffer;
2148 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2150 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2151 if (*ppMemory != saved_buffer)
2152 memcpy(*ppMemory, saved_buffer, bufsize);
2154 return bufsize;
2155 case RPC_FC_CVARRAY:
2156 esize = *(const WORD*)(pFormat+2);
2157 alignment = pFormat[1] + 1;
2159 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2161 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2163 align_pointer(&pStubMsg->Buffer, alignment);
2165 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2166 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2168 if (fUnmarshall)
2170 offset = pStubMsg->Offset;
2172 if (!fMustAlloc && !*ppMemory)
2173 fMustAlloc = TRUE;
2174 if (fMustAlloc)
2175 *ppMemory = NdrAllocate(pStubMsg, memsize);
2176 saved_buffer = pStubMsg->Buffer;
2177 safe_buffer_increment(pStubMsg, bufsize);
2179 pStubMsg->BufferMark = saved_buffer;
2180 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat,
2181 fMustAlloc);
2183 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2185 return bufsize;
2186 case RPC_FC_C_CSTRING:
2187 case RPC_FC_C_WSTRING:
2188 if (fc == RPC_FC_C_CSTRING)
2189 esize = 1;
2190 else
2191 esize = 2;
2193 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2195 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2197 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2198 pStubMsg->ActualCount, pStubMsg->MaxCount);
2199 RpcRaiseException(RPC_S_INVALID_BOUND);
2201 if (pStubMsg->Offset)
2203 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2204 RpcRaiseException(RPC_S_INVALID_BOUND);
2207 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2208 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2210 validate_string_data(pStubMsg, bufsize, esize);
2212 if (fUnmarshall)
2214 if (fMustAlloc)
2215 *ppMemory = NdrAllocate(pStubMsg, memsize);
2216 else
2218 if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
2219 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
2220 /* if the data in the RPC buffer is big enough, we just point
2221 * straight into it */
2222 *ppMemory = pStubMsg->Buffer;
2223 else if (!*ppMemory)
2224 *ppMemory = NdrAllocate(pStubMsg, memsize);
2227 if (*ppMemory == pStubMsg->Buffer)
2228 safe_buffer_increment(pStubMsg, bufsize);
2229 else
2230 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2232 if (*pFormat == RPC_FC_C_CSTRING)
2233 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
2234 else
2235 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
2237 return bufsize;
2239 case RPC_FC_BOGUS_ARRAY:
2240 alignment = pFormat[1] + 1;
2241 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2242 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2244 esize = ComplexStructSize(pStubMsg, pFormat);
2245 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2247 assert( fUnmarshall );
2249 if (!fMustAlloc && !*ppMemory)
2250 fMustAlloc = TRUE;
2251 if (fMustAlloc)
2252 *ppMemory = NdrAllocate(pStubMsg, memsize);
2254 align_pointer(&pStubMsg->Buffer, alignment);
2255 saved_buffer = pStubMsg->Buffer;
2257 pMemory = *ppMemory;
2258 count = pStubMsg->ActualCount;
2259 for (i = 0; i < count; i++)
2260 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
2261 return pStubMsg->Buffer - saved_buffer;
2263 default:
2264 ERR("unknown array format 0x%x\n", fc);
2265 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2269 static inline void array_memory_size(
2270 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
2271 unsigned char fHasPointers)
2273 ULONG i, count, SavedMemorySize;
2274 ULONG bufsize, memsize;
2275 DWORD esize;
2276 unsigned char alignment;
2278 switch (fc)
2280 case RPC_FC_CARRAY:
2281 esize = *(const WORD*)(pFormat+2);
2282 alignment = pFormat[1] + 1;
2284 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2286 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2287 pStubMsg->MemorySize += memsize;
2289 align_pointer(&pStubMsg->Buffer, alignment);
2290 if (fHasPointers)
2291 pStubMsg->BufferMark = pStubMsg->Buffer;
2292 safe_buffer_increment(pStubMsg, bufsize);
2294 if (fHasPointers)
2295 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2296 break;
2297 case RPC_FC_CVARRAY:
2298 esize = *(const WORD*)(pFormat+2);
2299 alignment = pFormat[1] + 1;
2301 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2303 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2305 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2306 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2307 pStubMsg->MemorySize += memsize;
2309 align_pointer(&pStubMsg->Buffer, alignment);
2310 if (fHasPointers)
2311 pStubMsg->BufferMark = pStubMsg->Buffer;
2312 safe_buffer_increment(pStubMsg, bufsize);
2314 if (fHasPointers)
2315 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2316 break;
2317 case RPC_FC_C_CSTRING:
2318 case RPC_FC_C_WSTRING:
2319 if (fc == RPC_FC_C_CSTRING)
2320 esize = 1;
2321 else
2322 esize = 2;
2324 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2326 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2328 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2329 pStubMsg->ActualCount, pStubMsg->MaxCount);
2330 RpcRaiseException(RPC_S_INVALID_BOUND);
2332 if (pStubMsg->Offset)
2334 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2335 RpcRaiseException(RPC_S_INVALID_BOUND);
2338 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2339 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2341 validate_string_data(pStubMsg, bufsize, esize);
2343 safe_buffer_increment(pStubMsg, bufsize);
2344 pStubMsg->MemorySize += memsize;
2345 break;
2346 case RPC_FC_BOGUS_ARRAY:
2347 alignment = pFormat[1] + 1;
2348 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2349 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2351 align_pointer(&pStubMsg->Buffer, alignment);
2353 SavedMemorySize = pStubMsg->MemorySize;
2355 esize = ComplexStructSize(pStubMsg, pFormat);
2356 memsize = safe_multiply(pStubMsg->MaxCount, esize);
2358 count = pStubMsg->ActualCount;
2359 for (i = 0; i < count; i++)
2360 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
2362 pStubMsg->MemorySize = SavedMemorySize + memsize;
2363 break;
2364 default:
2365 ERR("unknown array format 0x%x\n", fc);
2366 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2370 static inline void array_free(
2371 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
2372 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
2374 DWORD i, count;
2376 switch (fc)
2378 case RPC_FC_CARRAY:
2379 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2380 if (fHasPointers)
2381 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2382 break;
2383 case RPC_FC_CVARRAY:
2384 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2385 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2386 if (fHasPointers)
2387 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2388 break;
2389 case RPC_FC_C_CSTRING:
2390 case RPC_FC_C_WSTRING:
2391 /* No embedded pointers so nothing to do */
2392 break;
2393 case RPC_FC_BOGUS_ARRAY:
2394 count = *(const WORD *)(pFormat + 2);
2395 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, count);
2396 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2398 count = pStubMsg->ActualCount;
2399 for (i = 0; i < count; i++)
2400 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2401 break;
2402 default:
2403 ERR("unknown array format 0x%x\n", fc);
2404 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2409 * NdrConformantString:
2411 * What MS calls a ConformantString is, in DCE terminology,
2412 * a Varying-Conformant String.
2414 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2415 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2416 * into unmarshalled string)
2417 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2419 * data: CHARTYPE[maxlen]
2421 * ], where CHARTYPE is the appropriate character type (specified externally)
2425 /***********************************************************************
2426 * NdrConformantStringMarshall [RPCRT4.@]
2428 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
2429 unsigned char *pszMessage, PFORMAT_STRING pFormat)
2431 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
2433 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2434 ERR("Unhandled string type: %#x\n", pFormat[0]);
2435 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2438 /* allow compiler to optimise inline function by passing constant into
2439 * these functions */
2440 if (pFormat[0] == RPC_FC_C_CSTRING) {
2441 array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2442 pFormat);
2443 array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2444 pFormat, TRUE /* fHasPointers */);
2445 } else {
2446 array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2447 pFormat);
2448 array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2449 pFormat, TRUE /* fHasPointers */);
2452 return NULL;
2455 /***********************************************************************
2456 * NdrConformantStringBufferSize [RPCRT4.@]
2458 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2459 unsigned char* pMemory, PFORMAT_STRING pFormat)
2461 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2463 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2464 ERR("Unhandled string type: %#x\n", pFormat[0]);
2465 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2468 /* allow compiler to optimise inline function by passing constant into
2469 * these functions */
2470 if (pFormat[0] == RPC_FC_C_CSTRING) {
2471 array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory,
2472 pFormat);
2473 array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat,
2474 TRUE /* fHasPointers */);
2475 } else {
2476 array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory,
2477 pFormat);
2478 array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat,
2479 TRUE /* fHasPointers */);
2483 /************************************************************************
2484 * NdrConformantStringMemorySize [RPCRT4.@]
2486 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2487 PFORMAT_STRING pFormat )
2489 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2491 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2492 ERR("Unhandled string type: %#x\n", pFormat[0]);
2493 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2496 /* allow compiler to optimise inline function by passing constant into
2497 * these functions */
2498 if (pFormat[0] == RPC_FC_C_CSTRING) {
2499 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2500 array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat,
2501 TRUE /* fHasPointers */);
2502 } else {
2503 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2504 array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat,
2505 TRUE /* fHasPointers */);
2508 return pStubMsg->MemorySize;
2511 /************************************************************************
2512 * NdrConformantStringUnmarshall [RPCRT4.@]
2514 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2515 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
2517 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2518 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2520 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2521 ERR("Unhandled string type: %#x\n", *pFormat);
2522 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2525 /* allow compiler to optimise inline function by passing constant into
2526 * these functions */
2527 if (pFormat[0] == RPC_FC_C_CSTRING) {
2528 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2529 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory,
2530 pFormat, fMustAlloc,
2531 TRUE /* fUseBufferMemoryServer */,
2532 TRUE /* fUnmarshall */);
2533 } else {
2534 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2535 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory,
2536 pFormat, fMustAlloc,
2537 TRUE /* fUseBufferMemoryServer */,
2538 TRUE /* fUnmarshall */);
2541 return NULL;
2544 /***********************************************************************
2545 * NdrNonConformantStringMarshall [RPCRT4.@]
2547 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2548 unsigned char *pMemory,
2549 PFORMAT_STRING pFormat)
2551 ULONG esize, size, maxsize;
2553 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2555 maxsize = *(const USHORT *)&pFormat[2];
2557 if (*pFormat == RPC_FC_CSTRING)
2559 ULONG i = 0;
2560 const char *str = (const char *)pMemory;
2561 while (i < maxsize && str[i]) i++;
2562 TRACE("string=%s\n", debugstr_an(str, i));
2563 pStubMsg->ActualCount = i + 1;
2564 esize = 1;
2566 else if (*pFormat == RPC_FC_WSTRING)
2568 ULONG i = 0;
2569 const WCHAR *str = (const WCHAR *)pMemory;
2570 while (i < maxsize && str[i]) i++;
2571 TRACE("string=%s\n", debugstr_wn(str, i));
2572 pStubMsg->ActualCount = i + 1;
2573 esize = 2;
2575 else
2577 ERR("Unhandled string type: %#x\n", *pFormat);
2578 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2581 pStubMsg->Offset = 0;
2582 WriteVariance(pStubMsg);
2584 size = safe_multiply(esize, pStubMsg->ActualCount);
2585 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2587 return NULL;
2590 /***********************************************************************
2591 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2593 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2594 unsigned char **ppMemory,
2595 PFORMAT_STRING pFormat,
2596 unsigned char fMustAlloc)
2598 ULONG bufsize, memsize, esize, maxsize;
2600 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2601 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2603 maxsize = *(const USHORT *)&pFormat[2];
2605 ReadVariance(pStubMsg, NULL, maxsize);
2606 if (pStubMsg->Offset)
2608 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2609 RpcRaiseException(RPC_S_INVALID_BOUND);
2612 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2613 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2614 else
2616 ERR("Unhandled string type: %#x\n", *pFormat);
2617 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2620 memsize = esize * maxsize;
2621 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2623 validate_string_data(pStubMsg, bufsize, esize);
2625 if (!fMustAlloc && !*ppMemory)
2626 fMustAlloc = TRUE;
2627 if (fMustAlloc)
2628 *ppMemory = NdrAllocate(pStubMsg, memsize);
2630 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2632 if (*pFormat == RPC_FC_CSTRING) {
2633 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
2635 else if (*pFormat == RPC_FC_WSTRING) {
2636 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
2639 return NULL;
2642 /***********************************************************************
2643 * NdrNonConformantStringBufferSize [RPCRT4.@]
2645 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2646 unsigned char *pMemory,
2647 PFORMAT_STRING pFormat)
2649 ULONG esize, maxsize;
2651 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2653 maxsize = *(const USHORT *)&pFormat[2];
2655 SizeVariance(pStubMsg);
2657 if (*pFormat == RPC_FC_CSTRING)
2659 ULONG i = 0;
2660 const char *str = (const char *)pMemory;
2661 while (i < maxsize && str[i]) i++;
2662 TRACE("string=%s\n", debugstr_an(str, i));
2663 pStubMsg->ActualCount = i + 1;
2664 esize = 1;
2666 else if (*pFormat == RPC_FC_WSTRING)
2668 ULONG i = 0;
2669 const WCHAR *str = (const WCHAR *)pMemory;
2670 while (i < maxsize && str[i]) i++;
2671 TRACE("string=%s\n", debugstr_wn(str, i));
2672 pStubMsg->ActualCount = i + 1;
2673 esize = 2;
2675 else
2677 ERR("Unhandled string type: %#x\n", *pFormat);
2678 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2681 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2684 /***********************************************************************
2685 * NdrNonConformantStringMemorySize [RPCRT4.@]
2687 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2688 PFORMAT_STRING pFormat)
2690 ULONG bufsize, memsize, esize, maxsize;
2692 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2694 maxsize = *(const USHORT *)&pFormat[2];
2696 ReadVariance(pStubMsg, NULL, maxsize);
2698 if (pStubMsg->Offset)
2700 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2701 RpcRaiseException(RPC_S_INVALID_BOUND);
2704 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2705 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2706 else
2708 ERR("Unhandled string type: %#x\n", *pFormat);
2709 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2712 memsize = esize * maxsize;
2713 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2715 validate_string_data(pStubMsg, bufsize, esize);
2717 safe_buffer_increment(pStubMsg, bufsize);
2718 pStubMsg->MemorySize += memsize;
2720 return pStubMsg->MemorySize;
2723 /* Complex types */
2725 #include "pshpack1.h"
2726 typedef struct
2728 unsigned char type;
2729 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2730 ULONG low_value;
2731 ULONG high_value;
2732 } NDR_RANGE;
2733 #include "poppack.h"
2735 static ULONG EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2736 PFORMAT_STRING pFormat)
2738 switch (*pFormat) {
2739 case RPC_FC_STRUCT:
2740 case RPC_FC_PSTRUCT:
2741 case RPC_FC_CSTRUCT:
2742 case RPC_FC_BOGUS_STRUCT:
2743 case RPC_FC_SMFARRAY:
2744 case RPC_FC_SMVARRAY:
2745 case RPC_FC_CSTRING:
2746 return *(const WORD*)&pFormat[2];
2747 case RPC_FC_USER_MARSHAL:
2748 return *(const WORD*)&pFormat[4];
2749 case RPC_FC_RANGE: {
2750 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2751 case RPC_FC_BYTE:
2752 case RPC_FC_CHAR:
2753 case RPC_FC_SMALL:
2754 case RPC_FC_USMALL:
2755 return sizeof(UCHAR);
2756 case RPC_FC_WCHAR:
2757 case RPC_FC_SHORT:
2758 case RPC_FC_USHORT:
2759 return sizeof(USHORT);
2760 case RPC_FC_LONG:
2761 case RPC_FC_ULONG:
2762 case RPC_FC_ENUM32:
2763 case RPC_FC_INT3264:
2764 case RPC_FC_UINT3264:
2765 return sizeof(ULONG);
2766 case RPC_FC_FLOAT:
2767 return sizeof(float);
2768 case RPC_FC_DOUBLE:
2769 return sizeof(double);
2770 case RPC_FC_HYPER:
2771 return sizeof(ULONGLONG);
2772 case RPC_FC_ENUM16:
2773 return sizeof(UINT);
2774 default:
2775 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2776 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2779 case RPC_FC_NON_ENCAPSULATED_UNION:
2780 pFormat += 2;
2781 if (pStubMsg->fHasNewCorrDesc)
2782 pFormat += 6;
2783 else
2784 pFormat += 4;
2786 pFormat += *(const SHORT*)pFormat;
2787 return *(const SHORT*)pFormat;
2788 case RPC_FC_IP:
2789 return sizeof(void *);
2790 case RPC_FC_WSTRING:
2791 return *(const WORD*)&pFormat[2] * 2;
2792 default:
2793 FIXME("unhandled embedded type %02x\n", *pFormat);
2795 return 0;
2799 static ULONG EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2800 PFORMAT_STRING pFormat)
2802 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2804 if (!m)
2806 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2807 return 0;
2810 return m(pStubMsg, pFormat);
2814 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2815 unsigned char *pMemory,
2816 PFORMAT_STRING pFormat,
2817 PFORMAT_STRING pPointer)
2819 PFORMAT_STRING desc;
2820 NDR_MARSHALL m;
2821 ULONG size;
2823 while (*pFormat != RPC_FC_END) {
2824 switch (*pFormat) {
2825 case RPC_FC_BYTE:
2826 case RPC_FC_CHAR:
2827 case RPC_FC_SMALL:
2828 case RPC_FC_USMALL:
2829 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2830 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2831 pMemory += 1;
2832 break;
2833 case RPC_FC_WCHAR:
2834 case RPC_FC_SHORT:
2835 case RPC_FC_USHORT:
2836 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2837 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2838 pMemory += 2;
2839 break;
2840 case RPC_FC_ENUM16:
2842 USHORT val = *(DWORD *)pMemory;
2843 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2844 if (32767 < *(DWORD*)pMemory)
2845 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2846 safe_copy_to_buffer(pStubMsg, &val, 2);
2847 pMemory += 4;
2848 break;
2850 case RPC_FC_LONG:
2851 case RPC_FC_ULONG:
2852 case RPC_FC_ENUM32:
2853 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2854 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2855 pMemory += 4;
2856 break;
2857 case RPC_FC_INT3264:
2858 case RPC_FC_UINT3264:
2860 UINT val = *(UINT_PTR *)pMemory;
2861 TRACE("int3264=%ld <= %p\n", *(UINT_PTR *)pMemory, pMemory);
2862 safe_copy_to_buffer(pStubMsg, &val, sizeof(UINT));
2863 pMemory += sizeof(UINT_PTR);
2864 break;
2866 case RPC_FC_FLOAT:
2867 TRACE("float=%f <= %p\n", *(float*)pMemory, pMemory);
2868 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
2869 pMemory += sizeof(float);
2870 break;
2871 case RPC_FC_HYPER:
2872 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2873 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2874 pMemory += 8;
2875 break;
2876 case RPC_FC_DOUBLE:
2877 TRACE("double=%f <= %p\n", *(double*)pMemory, pMemory);
2878 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
2879 pMemory += sizeof(double);
2880 break;
2881 case RPC_FC_RP:
2882 case RPC_FC_UP:
2883 case RPC_FC_OP:
2884 case RPC_FC_FP:
2885 case RPC_FC_POINTER:
2887 unsigned char *saved_buffer;
2888 int pointer_buffer_mark_set = 0;
2889 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2890 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2891 if (*pFormat != RPC_FC_POINTER)
2892 pPointer = pFormat;
2893 if (*pPointer != RPC_FC_RP)
2894 align_pointer_clear(&pStubMsg->Buffer, 4);
2895 saved_buffer = pStubMsg->Buffer;
2896 if (pStubMsg->PointerBufferMark)
2898 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2899 pStubMsg->PointerBufferMark = NULL;
2900 pointer_buffer_mark_set = 1;
2902 else if (*pPointer != RPC_FC_RP)
2903 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2904 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2905 if (pointer_buffer_mark_set)
2907 STD_OVERFLOW_CHECK(pStubMsg);
2908 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2909 pStubMsg->Buffer = saved_buffer;
2910 if (*pPointer != RPC_FC_RP)
2911 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2913 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2914 if (*pFormat == RPC_FC_POINTER)
2915 pPointer += 4;
2916 else
2917 pFormat += 4;
2918 pMemory += sizeof(void *);
2919 break;
2921 case RPC_FC_ALIGNM2:
2922 align_pointer(&pMemory, 2);
2923 break;
2924 case RPC_FC_ALIGNM4:
2925 align_pointer(&pMemory, 4);
2926 break;
2927 case RPC_FC_ALIGNM8:
2928 align_pointer(&pMemory, 8);
2929 break;
2930 case RPC_FC_STRUCTPAD1:
2931 case RPC_FC_STRUCTPAD2:
2932 case RPC_FC_STRUCTPAD3:
2933 case RPC_FC_STRUCTPAD4:
2934 case RPC_FC_STRUCTPAD5:
2935 case RPC_FC_STRUCTPAD6:
2936 case RPC_FC_STRUCTPAD7:
2937 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2938 break;
2939 case RPC_FC_EMBEDDED_COMPLEX:
2940 pMemory += pFormat[1];
2941 pFormat += 2;
2942 desc = pFormat + *(const SHORT*)pFormat;
2943 size = EmbeddedComplexSize(pStubMsg, desc);
2944 TRACE("embedded complex (size=%d) <= %p\n", size, pMemory);
2945 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2946 if (m)
2948 /* for some reason interface pointers aren't generated as
2949 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2950 * they still need the derefencing treatment that pointers are
2951 * given */
2952 if (*desc == RPC_FC_IP)
2953 m(pStubMsg, *(unsigned char **)pMemory, desc);
2954 else
2955 m(pStubMsg, pMemory, desc);
2957 else FIXME("no marshaller for embedded type %02x\n", *desc);
2958 pMemory += size;
2959 pFormat += 2;
2960 continue;
2961 case RPC_FC_PAD:
2962 break;
2963 default:
2964 FIXME("unhandled format 0x%02x\n", *pFormat);
2966 pFormat++;
2969 return pMemory;
2972 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2973 unsigned char *pMemory,
2974 PFORMAT_STRING pFormat,
2975 PFORMAT_STRING pPointer,
2976 unsigned char fMustAlloc)
2978 PFORMAT_STRING desc;
2979 NDR_UNMARSHALL m;
2980 ULONG size;
2982 while (*pFormat != RPC_FC_END) {
2983 switch (*pFormat) {
2984 case RPC_FC_BYTE:
2985 case RPC_FC_CHAR:
2986 case RPC_FC_SMALL:
2987 case RPC_FC_USMALL:
2988 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2989 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2990 pMemory += 1;
2991 break;
2992 case RPC_FC_WCHAR:
2993 case RPC_FC_SHORT:
2994 case RPC_FC_USHORT:
2995 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2996 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2997 pMemory += 2;
2998 break;
2999 case RPC_FC_ENUM16:
3001 WORD val;
3002 safe_copy_from_buffer(pStubMsg, &val, 2);
3003 *(DWORD*)pMemory = val;
3004 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
3005 if (32767 < *(DWORD*)pMemory)
3006 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
3007 pMemory += 4;
3008 break;
3010 case RPC_FC_LONG:
3011 case RPC_FC_ULONG:
3012 case RPC_FC_ENUM32:
3013 safe_copy_from_buffer(pStubMsg, pMemory, 4);
3014 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
3015 pMemory += 4;
3016 break;
3017 case RPC_FC_INT3264:
3019 INT val;
3020 safe_copy_from_buffer(pStubMsg, &val, 4);
3021 *(INT_PTR *)pMemory = val;
3022 TRACE("int3264=%ld => %p\n", *(INT_PTR*)pMemory, pMemory);
3023 pMemory += sizeof(INT_PTR);
3024 break;
3026 case RPC_FC_UINT3264:
3028 UINT val;
3029 safe_copy_from_buffer(pStubMsg, &val, 4);
3030 *(UINT_PTR *)pMemory = val;
3031 TRACE("uint3264=%ld => %p\n", *(UINT_PTR*)pMemory, pMemory);
3032 pMemory += sizeof(UINT_PTR);
3033 break;
3035 case RPC_FC_FLOAT:
3036 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(float));
3037 TRACE("float=%f => %p\n", *(float*)pMemory, pMemory);
3038 pMemory += sizeof(float);
3039 break;
3040 case RPC_FC_HYPER:
3041 safe_copy_from_buffer(pStubMsg, pMemory, 8);
3042 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
3043 pMemory += 8;
3044 break;
3045 case RPC_FC_DOUBLE:
3046 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(double));
3047 TRACE("double=%f => %p\n", *(double*)pMemory, pMemory);
3048 pMemory += sizeof(double);
3049 break;
3050 case RPC_FC_RP:
3051 case RPC_FC_UP:
3052 case RPC_FC_OP:
3053 case RPC_FC_FP:
3054 case RPC_FC_POINTER:
3056 unsigned char *saved_buffer;
3057 int pointer_buffer_mark_set = 0;
3058 TRACE("pointer => %p\n", pMemory);
3059 if (*pFormat != RPC_FC_POINTER)
3060 pPointer = pFormat;
3061 if (*pPointer != RPC_FC_RP)
3062 align_pointer(&pStubMsg->Buffer, 4);
3063 saved_buffer = pStubMsg->Buffer;
3064 if (pStubMsg->PointerBufferMark)
3066 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3067 pStubMsg->PointerBufferMark = NULL;
3068 pointer_buffer_mark_set = 1;
3070 else if (*pPointer != RPC_FC_RP)
3071 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3073 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
3074 if (pointer_buffer_mark_set)
3076 STD_OVERFLOW_CHECK(pStubMsg);
3077 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3078 pStubMsg->Buffer = saved_buffer;
3079 if (*pPointer != RPC_FC_RP)
3080 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3082 if (*pFormat == RPC_FC_POINTER)
3083 pPointer += 4;
3084 else
3085 pFormat += 4;
3086 pMemory += sizeof(void *);
3087 break;
3089 case RPC_FC_ALIGNM2:
3090 align_pointer_clear(&pMemory, 2);
3091 break;
3092 case RPC_FC_ALIGNM4:
3093 align_pointer_clear(&pMemory, 4);
3094 break;
3095 case RPC_FC_ALIGNM8:
3096 align_pointer_clear(&pMemory, 8);
3097 break;
3098 case RPC_FC_STRUCTPAD1:
3099 case RPC_FC_STRUCTPAD2:
3100 case RPC_FC_STRUCTPAD3:
3101 case RPC_FC_STRUCTPAD4:
3102 case RPC_FC_STRUCTPAD5:
3103 case RPC_FC_STRUCTPAD6:
3104 case RPC_FC_STRUCTPAD7:
3105 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
3106 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3107 break;
3108 case RPC_FC_EMBEDDED_COMPLEX:
3109 pMemory += pFormat[1];
3110 pFormat += 2;
3111 desc = pFormat + *(const SHORT*)pFormat;
3112 size = EmbeddedComplexSize(pStubMsg, desc);
3113 TRACE("embedded complex (size=%d) => %p\n", size, pMemory);
3114 if (fMustAlloc)
3115 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
3116 * since the type is part of the memory block that is encompassed by
3117 * the whole complex type. Memory is forced to allocate when pointers
3118 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
3119 * clearing the memory we pass in to the unmarshaller */
3120 memset(pMemory, 0, size);
3121 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
3122 if (m)
3124 /* for some reason interface pointers aren't generated as
3125 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3126 * they still need the derefencing treatment that pointers are
3127 * given */
3128 if (*desc == RPC_FC_IP)
3129 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
3130 else
3131 m(pStubMsg, &pMemory, desc, FALSE);
3133 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
3134 pMemory += size;
3135 pFormat += 2;
3136 continue;
3137 case RPC_FC_PAD:
3138 break;
3139 default:
3140 FIXME("unhandled format %d\n", *pFormat);
3142 pFormat++;
3145 return pMemory;
3148 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3149 unsigned char *pMemory,
3150 PFORMAT_STRING pFormat,
3151 PFORMAT_STRING pPointer)
3153 PFORMAT_STRING desc;
3154 NDR_BUFFERSIZE m;
3155 ULONG size;
3157 while (*pFormat != RPC_FC_END) {
3158 switch (*pFormat) {
3159 case RPC_FC_BYTE:
3160 case RPC_FC_CHAR:
3161 case RPC_FC_SMALL:
3162 case RPC_FC_USMALL:
3163 safe_buffer_length_increment(pStubMsg, 1);
3164 pMemory += 1;
3165 break;
3166 case RPC_FC_WCHAR:
3167 case RPC_FC_SHORT:
3168 case RPC_FC_USHORT:
3169 safe_buffer_length_increment(pStubMsg, 2);
3170 pMemory += 2;
3171 break;
3172 case RPC_FC_ENUM16:
3173 safe_buffer_length_increment(pStubMsg, 2);
3174 pMemory += 4;
3175 break;
3176 case RPC_FC_LONG:
3177 case RPC_FC_ULONG:
3178 case RPC_FC_ENUM32:
3179 case RPC_FC_FLOAT:
3180 safe_buffer_length_increment(pStubMsg, 4);
3181 pMemory += 4;
3182 break;
3183 case RPC_FC_INT3264:
3184 case RPC_FC_UINT3264:
3185 safe_buffer_length_increment(pStubMsg, 4);
3186 pMemory += sizeof(INT_PTR);
3187 break;
3188 case RPC_FC_HYPER:
3189 case RPC_FC_DOUBLE:
3190 safe_buffer_length_increment(pStubMsg, 8);
3191 pMemory += 8;
3192 break;
3193 case RPC_FC_RP:
3194 case RPC_FC_UP:
3195 case RPC_FC_OP:
3196 case RPC_FC_FP:
3197 case RPC_FC_POINTER:
3198 if (*pFormat != RPC_FC_POINTER)
3199 pPointer = pFormat;
3200 if (!pStubMsg->IgnoreEmbeddedPointers)
3202 int saved_buffer_length = pStubMsg->BufferLength;
3203 pStubMsg->BufferLength = pStubMsg->PointerLength;
3204 pStubMsg->PointerLength = 0;
3205 if(!pStubMsg->BufferLength)
3206 ERR("BufferLength == 0??\n");
3207 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
3208 pStubMsg->PointerLength = pStubMsg->BufferLength;
3209 pStubMsg->BufferLength = saved_buffer_length;
3211 if (*pPointer != RPC_FC_RP)
3213 align_length(&pStubMsg->BufferLength, 4);
3214 safe_buffer_length_increment(pStubMsg, 4);
3216 if (*pFormat == RPC_FC_POINTER)
3217 pPointer += 4;
3218 else
3219 pFormat += 4;
3220 pMemory += sizeof(void*);
3221 break;
3222 case RPC_FC_ALIGNM2:
3223 align_pointer(&pMemory, 2);
3224 break;
3225 case RPC_FC_ALIGNM4:
3226 align_pointer(&pMemory, 4);
3227 break;
3228 case RPC_FC_ALIGNM8:
3229 align_pointer(&pMemory, 8);
3230 break;
3231 case RPC_FC_STRUCTPAD1:
3232 case RPC_FC_STRUCTPAD2:
3233 case RPC_FC_STRUCTPAD3:
3234 case RPC_FC_STRUCTPAD4:
3235 case RPC_FC_STRUCTPAD5:
3236 case RPC_FC_STRUCTPAD6:
3237 case RPC_FC_STRUCTPAD7:
3238 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3239 break;
3240 case RPC_FC_EMBEDDED_COMPLEX:
3241 pMemory += pFormat[1];
3242 pFormat += 2;
3243 desc = pFormat + *(const SHORT*)pFormat;
3244 size = EmbeddedComplexSize(pStubMsg, desc);
3245 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
3246 if (m)
3248 /* for some reason interface pointers aren't generated as
3249 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3250 * they still need the derefencing treatment that pointers are
3251 * given */
3252 if (*desc == RPC_FC_IP)
3253 m(pStubMsg, *(unsigned char **)pMemory, desc);
3254 else
3255 m(pStubMsg, pMemory, desc);
3257 else FIXME("no buffersizer for embedded type %02x\n", *desc);
3258 pMemory += size;
3259 pFormat += 2;
3260 continue;
3261 case RPC_FC_PAD:
3262 break;
3263 default:
3264 FIXME("unhandled format 0x%02x\n", *pFormat);
3266 pFormat++;
3269 return pMemory;
3272 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
3273 unsigned char *pMemory,
3274 PFORMAT_STRING pFormat,
3275 PFORMAT_STRING pPointer)
3277 PFORMAT_STRING desc;
3278 NDR_FREE m;
3279 ULONG size;
3281 while (*pFormat != RPC_FC_END) {
3282 switch (*pFormat) {
3283 case RPC_FC_BYTE:
3284 case RPC_FC_CHAR:
3285 case RPC_FC_SMALL:
3286 case RPC_FC_USMALL:
3287 pMemory += 1;
3288 break;
3289 case RPC_FC_WCHAR:
3290 case RPC_FC_SHORT:
3291 case RPC_FC_USHORT:
3292 pMemory += 2;
3293 break;
3294 case RPC_FC_LONG:
3295 case RPC_FC_ULONG:
3296 case RPC_FC_ENUM16:
3297 case RPC_FC_ENUM32:
3298 case RPC_FC_FLOAT:
3299 pMemory += 4;
3300 break;
3301 case RPC_FC_INT3264:
3302 case RPC_FC_UINT3264:
3303 pMemory += sizeof(INT_PTR);
3304 break;
3305 case RPC_FC_HYPER:
3306 case RPC_FC_DOUBLE:
3307 pMemory += 8;
3308 break;
3309 case RPC_FC_RP:
3310 case RPC_FC_UP:
3311 case RPC_FC_OP:
3312 case RPC_FC_FP:
3313 case RPC_FC_POINTER:
3314 if (*pFormat != RPC_FC_POINTER)
3315 pPointer = pFormat;
3316 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3317 if (*pFormat == RPC_FC_POINTER)
3318 pPointer += 4;
3319 else
3320 pFormat += 4;
3321 pMemory += sizeof(void *);
3322 break;
3323 case RPC_FC_ALIGNM2:
3324 align_pointer(&pMemory, 2);
3325 break;
3326 case RPC_FC_ALIGNM4:
3327 align_pointer(&pMemory, 4);
3328 break;
3329 case RPC_FC_ALIGNM8:
3330 align_pointer(&pMemory, 8);
3331 break;
3332 case RPC_FC_STRUCTPAD1:
3333 case RPC_FC_STRUCTPAD2:
3334 case RPC_FC_STRUCTPAD3:
3335 case RPC_FC_STRUCTPAD4:
3336 case RPC_FC_STRUCTPAD5:
3337 case RPC_FC_STRUCTPAD6:
3338 case RPC_FC_STRUCTPAD7:
3339 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3340 break;
3341 case RPC_FC_EMBEDDED_COMPLEX:
3342 pMemory += pFormat[1];
3343 pFormat += 2;
3344 desc = pFormat + *(const SHORT*)pFormat;
3345 size = EmbeddedComplexSize(pStubMsg, desc);
3346 m = NdrFreer[*desc & NDR_TABLE_MASK];
3347 if (m)
3349 /* for some reason interface pointers aren't generated as
3350 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3351 * they still need the derefencing treatment that pointers are
3352 * given */
3353 if (*desc == RPC_FC_IP)
3354 m(pStubMsg, *(unsigned char **)pMemory, desc);
3355 else
3356 m(pStubMsg, pMemory, desc);
3358 pMemory += size;
3359 pFormat += 2;
3360 continue;
3361 case RPC_FC_PAD:
3362 break;
3363 default:
3364 FIXME("unhandled format 0x%02x\n", *pFormat);
3366 pFormat++;
3369 return pMemory;
3372 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3373 PFORMAT_STRING pFormat,
3374 PFORMAT_STRING pPointer)
3376 PFORMAT_STRING desc;
3377 ULONG size = 0;
3379 while (*pFormat != RPC_FC_END) {
3380 switch (*pFormat) {
3381 case RPC_FC_BYTE:
3382 case RPC_FC_CHAR:
3383 case RPC_FC_SMALL:
3384 case RPC_FC_USMALL:
3385 size += 1;
3386 safe_buffer_increment(pStubMsg, 1);
3387 break;
3388 case RPC_FC_WCHAR:
3389 case RPC_FC_SHORT:
3390 case RPC_FC_USHORT:
3391 size += 2;
3392 safe_buffer_increment(pStubMsg, 2);
3393 break;
3394 case RPC_FC_ENUM16:
3395 size += 4;
3396 safe_buffer_increment(pStubMsg, 2);
3397 break;
3398 case RPC_FC_LONG:
3399 case RPC_FC_ULONG:
3400 case RPC_FC_ENUM32:
3401 case RPC_FC_FLOAT:
3402 size += 4;
3403 safe_buffer_increment(pStubMsg, 4);
3404 break;
3405 case RPC_FC_INT3264:
3406 case RPC_FC_UINT3264:
3407 size += sizeof(INT_PTR);
3408 safe_buffer_increment(pStubMsg, 4);
3409 break;
3410 case RPC_FC_HYPER:
3411 case RPC_FC_DOUBLE:
3412 size += 8;
3413 safe_buffer_increment(pStubMsg, 8);
3414 break;
3415 case RPC_FC_RP:
3416 case RPC_FC_UP:
3417 case RPC_FC_OP:
3418 case RPC_FC_FP:
3419 case RPC_FC_POINTER:
3421 unsigned char *saved_buffer;
3422 int pointer_buffer_mark_set = 0;
3423 if (*pFormat != RPC_FC_POINTER)
3424 pPointer = pFormat;
3425 if (*pPointer != RPC_FC_RP)
3426 align_pointer(&pStubMsg->Buffer, 4);
3427 saved_buffer = pStubMsg->Buffer;
3428 if (pStubMsg->PointerBufferMark)
3430 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3431 pStubMsg->PointerBufferMark = NULL;
3432 pointer_buffer_mark_set = 1;
3434 else if (*pPointer != RPC_FC_RP)
3435 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3437 if (!pStubMsg->IgnoreEmbeddedPointers)
3438 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3439 if (pointer_buffer_mark_set)
3441 STD_OVERFLOW_CHECK(pStubMsg);
3442 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3443 pStubMsg->Buffer = saved_buffer;
3444 if (*pPointer != RPC_FC_RP)
3445 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3447 if (*pFormat == RPC_FC_POINTER)
3448 pPointer += 4;
3449 else
3450 pFormat += 4;
3451 size += sizeof(void *);
3452 break;
3454 case RPC_FC_ALIGNM2:
3455 align_length(&size, 2);
3456 break;
3457 case RPC_FC_ALIGNM4:
3458 align_length(&size, 4);
3459 break;
3460 case RPC_FC_ALIGNM8:
3461 align_length(&size, 8);
3462 break;
3463 case RPC_FC_STRUCTPAD1:
3464 case RPC_FC_STRUCTPAD2:
3465 case RPC_FC_STRUCTPAD3:
3466 case RPC_FC_STRUCTPAD4:
3467 case RPC_FC_STRUCTPAD5:
3468 case RPC_FC_STRUCTPAD6:
3469 case RPC_FC_STRUCTPAD7:
3470 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3471 break;
3472 case RPC_FC_EMBEDDED_COMPLEX:
3473 size += pFormat[1];
3474 pFormat += 2;
3475 desc = pFormat + *(const SHORT*)pFormat;
3476 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3477 pFormat += 2;
3478 continue;
3479 case RPC_FC_PAD:
3480 break;
3481 default:
3482 FIXME("unhandled format 0x%02x\n", *pFormat);
3484 pFormat++;
3487 return size;
3490 ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
3492 PFORMAT_STRING desc;
3493 ULONG size = 0;
3495 while (*pFormat != RPC_FC_END) {
3496 switch (*pFormat) {
3497 case RPC_FC_BYTE:
3498 case RPC_FC_CHAR:
3499 case RPC_FC_SMALL:
3500 case RPC_FC_USMALL:
3501 size += 1;
3502 break;
3503 case RPC_FC_WCHAR:
3504 case RPC_FC_SHORT:
3505 case RPC_FC_USHORT:
3506 size += 2;
3507 break;
3508 case RPC_FC_LONG:
3509 case RPC_FC_ULONG:
3510 case RPC_FC_ENUM16:
3511 case RPC_FC_ENUM32:
3512 case RPC_FC_FLOAT:
3513 size += 4;
3514 break;
3515 case RPC_FC_INT3264:
3516 case RPC_FC_UINT3264:
3517 size += sizeof(INT_PTR);
3518 break;
3519 case RPC_FC_HYPER:
3520 case RPC_FC_DOUBLE:
3521 size += 8;
3522 break;
3523 case RPC_FC_RP:
3524 case RPC_FC_UP:
3525 case RPC_FC_OP:
3526 case RPC_FC_FP:
3527 case RPC_FC_POINTER:
3528 size += sizeof(void *);
3529 if (*pFormat != RPC_FC_POINTER)
3530 pFormat += 4;
3531 break;
3532 case RPC_FC_ALIGNM2:
3533 align_length(&size, 2);
3534 break;
3535 case RPC_FC_ALIGNM4:
3536 align_length(&size, 4);
3537 break;
3538 case RPC_FC_ALIGNM8:
3539 align_length(&size, 8);
3540 break;
3541 case RPC_FC_STRUCTPAD1:
3542 case RPC_FC_STRUCTPAD2:
3543 case RPC_FC_STRUCTPAD3:
3544 case RPC_FC_STRUCTPAD4:
3545 case RPC_FC_STRUCTPAD5:
3546 case RPC_FC_STRUCTPAD6:
3547 case RPC_FC_STRUCTPAD7:
3548 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3549 break;
3550 case RPC_FC_EMBEDDED_COMPLEX:
3551 size += pFormat[1];
3552 pFormat += 2;
3553 desc = pFormat + *(const SHORT*)pFormat;
3554 size += EmbeddedComplexSize(pStubMsg, desc);
3555 pFormat += 2;
3556 continue;
3557 case RPC_FC_PAD:
3558 break;
3559 default:
3560 FIXME("unhandled format 0x%02x\n", *pFormat);
3562 pFormat++;
3565 return size;
3568 /***********************************************************************
3569 * NdrComplexStructMarshall [RPCRT4.@]
3571 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3572 unsigned char *pMemory,
3573 PFORMAT_STRING pFormat)
3575 PFORMAT_STRING conf_array = NULL;
3576 PFORMAT_STRING pointer_desc = NULL;
3577 unsigned char *OldMemory = pStubMsg->Memory;
3578 int pointer_buffer_mark_set = 0;
3579 ULONG count = 0;
3580 ULONG max_count = 0;
3581 ULONG offset = 0;
3583 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3585 if (!pStubMsg->PointerBufferMark)
3587 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3588 /* save buffer length */
3589 ULONG saved_buffer_length = pStubMsg->BufferLength;
3591 /* get the buffer pointer after complex array data, but before
3592 * pointer data */
3593 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3594 pStubMsg->IgnoreEmbeddedPointers = 1;
3595 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3596 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3598 /* save it for use by embedded pointer code later */
3599 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3600 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - pStubMsg->Buffer));
3601 pointer_buffer_mark_set = 1;
3603 /* restore the original buffer length */
3604 pStubMsg->BufferLength = saved_buffer_length;
3607 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1);
3609 pFormat += 4;
3610 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3611 pFormat += 2;
3612 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3613 pFormat += 2;
3615 pStubMsg->Memory = pMemory;
3617 if (conf_array)
3619 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3620 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3621 pMemory + struct_size, conf_array);
3622 /* these could be changed in ComplexMarshall so save them for later */
3623 max_count = pStubMsg->MaxCount;
3624 count = pStubMsg->ActualCount;
3625 offset = pStubMsg->Offset;
3628 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3630 if (conf_array)
3632 pStubMsg->MaxCount = max_count;
3633 pStubMsg->ActualCount = count;
3634 pStubMsg->Offset = offset;
3635 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3636 conf_array, TRUE /* fHasPointers */);
3639 pStubMsg->Memory = OldMemory;
3641 if (pointer_buffer_mark_set)
3643 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3644 pStubMsg->PointerBufferMark = NULL;
3647 STD_OVERFLOW_CHECK(pStubMsg);
3649 return NULL;
3652 /***********************************************************************
3653 * NdrComplexStructUnmarshall [RPCRT4.@]
3655 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3656 unsigned char **ppMemory,
3657 PFORMAT_STRING pFormat,
3658 unsigned char fMustAlloc)
3660 unsigned size = *(const WORD*)(pFormat+2);
3661 PFORMAT_STRING conf_array = NULL;
3662 PFORMAT_STRING pointer_desc = NULL;
3663 unsigned char *pMemory;
3664 int pointer_buffer_mark_set = 0;
3665 ULONG count = 0;
3666 ULONG max_count = 0;
3667 ULONG offset = 0;
3668 ULONG array_size = 0;
3670 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3672 if (!pStubMsg->PointerBufferMark)
3674 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3675 /* save buffer pointer */
3676 unsigned char *saved_buffer = pStubMsg->Buffer;
3678 /* get the buffer pointer after complex array data, but before
3679 * pointer data */
3680 pStubMsg->IgnoreEmbeddedPointers = 1;
3681 NdrComplexStructMemorySize(pStubMsg, pFormat);
3682 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3684 /* save it for use by embedded pointer code later */
3685 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3686 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - saved_buffer));
3687 pointer_buffer_mark_set = 1;
3689 /* restore the original buffer */
3690 pStubMsg->Buffer = saved_buffer;
3693 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3695 pFormat += 4;
3696 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3697 pFormat += 2;
3698 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3699 pFormat += 2;
3701 if (conf_array)
3703 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3704 size += array_size;
3706 /* these could be changed in ComplexMarshall so save them for later */
3707 max_count = pStubMsg->MaxCount;
3708 count = pStubMsg->ActualCount;
3709 offset = pStubMsg->Offset;
3712 if (!fMustAlloc && !*ppMemory)
3713 fMustAlloc = TRUE;
3714 if (fMustAlloc)
3715 *ppMemory = NdrAllocate(pStubMsg, size);
3717 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3719 if (conf_array)
3721 pStubMsg->MaxCount = max_count;
3722 pStubMsg->ActualCount = count;
3723 pStubMsg->Offset = offset;
3724 if (fMustAlloc)
3725 memset(pMemory, 0, array_size);
3726 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3727 conf_array, FALSE,
3728 FALSE /* fUseBufferMemoryServer */,
3729 TRUE /* fUnmarshall */);
3732 if (pointer_buffer_mark_set)
3734 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3735 pStubMsg->PointerBufferMark = NULL;
3738 return NULL;
3741 /***********************************************************************
3742 * NdrComplexStructBufferSize [RPCRT4.@]
3744 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3745 unsigned char *pMemory,
3746 PFORMAT_STRING pFormat)
3748 PFORMAT_STRING conf_array = NULL;
3749 PFORMAT_STRING pointer_desc = NULL;
3750 unsigned char *OldMemory = pStubMsg->Memory;
3751 int pointer_length_set = 0;
3752 ULONG count = 0;
3753 ULONG max_count = 0;
3754 ULONG offset = 0;
3756 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3758 align_length(&pStubMsg->BufferLength, pFormat[1] + 1);
3760 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3762 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3763 ULONG saved_buffer_length = pStubMsg->BufferLength;
3765 /* get the buffer length after complex struct data, but before
3766 * pointer data */
3767 pStubMsg->IgnoreEmbeddedPointers = 1;
3768 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3769 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3771 /* save it for use by embedded pointer code later */
3772 pStubMsg->PointerLength = pStubMsg->BufferLength;
3773 pointer_length_set = 1;
3774 TRACE("difference = 0x%x\n", pStubMsg->PointerLength - saved_buffer_length);
3776 /* restore the original buffer length */
3777 pStubMsg->BufferLength = saved_buffer_length;
3780 pFormat += 4;
3781 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3782 pFormat += 2;
3783 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3784 pFormat += 2;
3786 pStubMsg->Memory = pMemory;
3788 if (conf_array)
3790 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3791 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3792 conf_array);
3794 /* these could be changed in ComplexMarshall so save them for later */
3795 max_count = pStubMsg->MaxCount;
3796 count = pStubMsg->ActualCount;
3797 offset = pStubMsg->Offset;
3800 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3802 if (conf_array)
3804 pStubMsg->MaxCount = max_count;
3805 pStubMsg->ActualCount = count;
3806 pStubMsg->Offset = offset;
3807 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3808 TRUE /* fHasPointers */);
3811 pStubMsg->Memory = OldMemory;
3813 if(pointer_length_set)
3815 pStubMsg->BufferLength = pStubMsg->PointerLength;
3816 pStubMsg->PointerLength = 0;
3821 /***********************************************************************
3822 * NdrComplexStructMemorySize [RPCRT4.@]
3824 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3825 PFORMAT_STRING pFormat)
3827 unsigned size = *(const WORD*)(pFormat+2);
3828 PFORMAT_STRING conf_array = NULL;
3829 PFORMAT_STRING pointer_desc = NULL;
3830 ULONG count = 0;
3831 ULONG max_count = 0;
3832 ULONG offset = 0;
3834 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3836 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3838 pFormat += 4;
3839 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3840 pFormat += 2;
3841 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3842 pFormat += 2;
3844 if (conf_array)
3846 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3848 /* these could be changed in ComplexStructMemorySize so save them for
3849 * later */
3850 max_count = pStubMsg->MaxCount;
3851 count = pStubMsg->ActualCount;
3852 offset = pStubMsg->Offset;
3855 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3857 if (conf_array)
3859 pStubMsg->MaxCount = max_count;
3860 pStubMsg->ActualCount = count;
3861 pStubMsg->Offset = offset;
3862 array_memory_size(conf_array[0], pStubMsg, conf_array,
3863 TRUE /* fHasPointers */);
3866 return size;
3869 /***********************************************************************
3870 * NdrComplexStructFree [RPCRT4.@]
3872 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3873 unsigned char *pMemory,
3874 PFORMAT_STRING pFormat)
3876 PFORMAT_STRING conf_array = NULL;
3877 PFORMAT_STRING pointer_desc = NULL;
3878 unsigned char *OldMemory = pStubMsg->Memory;
3880 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3882 pFormat += 4;
3883 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3884 pFormat += 2;
3885 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3886 pFormat += 2;
3888 pStubMsg->Memory = pMemory;
3890 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3892 if (conf_array)
3893 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3894 TRUE /* fHasPointers */);
3896 pStubMsg->Memory = OldMemory;
3899 /***********************************************************************
3900 * NdrConformantArrayMarshall [RPCRT4.@]
3902 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3903 unsigned char *pMemory,
3904 PFORMAT_STRING pFormat)
3906 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3907 if (pFormat[0] != RPC_FC_CARRAY)
3909 ERR("invalid format = 0x%x\n", pFormat[0]);
3910 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3913 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory,
3914 pFormat);
3915 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3916 TRUE /* fHasPointers */);
3918 return NULL;
3921 /***********************************************************************
3922 * NdrConformantArrayUnmarshall [RPCRT4.@]
3924 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3925 unsigned char **ppMemory,
3926 PFORMAT_STRING pFormat,
3927 unsigned char fMustAlloc)
3929 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3930 if (pFormat[0] != RPC_FC_CARRAY)
3932 ERR("invalid format = 0x%x\n", pFormat[0]);
3933 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3936 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3937 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat,
3938 fMustAlloc,
3939 TRUE /* fUseBufferMemoryServer */,
3940 TRUE /* fUnmarshall */);
3942 return NULL;
3945 /***********************************************************************
3946 * NdrConformantArrayBufferSize [RPCRT4.@]
3948 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3949 unsigned char *pMemory,
3950 PFORMAT_STRING pFormat)
3952 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3953 if (pFormat[0] != RPC_FC_CARRAY)
3955 ERR("invalid format = 0x%x\n", pFormat[0]);
3956 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3959 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat);
3960 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3961 TRUE /* fHasPointers */);
3964 /***********************************************************************
3965 * NdrConformantArrayMemorySize [RPCRT4.@]
3967 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3968 PFORMAT_STRING pFormat)
3970 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3971 if (pFormat[0] != RPC_FC_CARRAY)
3973 ERR("invalid format = 0x%x\n", pFormat[0]);
3974 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3977 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3978 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
3980 return pStubMsg->MemorySize;
3983 /***********************************************************************
3984 * NdrConformantArrayFree [RPCRT4.@]
3986 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3987 unsigned char *pMemory,
3988 PFORMAT_STRING pFormat)
3990 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3991 if (pFormat[0] != RPC_FC_CARRAY)
3993 ERR("invalid format = 0x%x\n", pFormat[0]);
3994 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3997 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3998 TRUE /* fHasPointers */);
4002 /***********************************************************************
4003 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
4005 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
4006 unsigned char* pMemory,
4007 PFORMAT_STRING pFormat )
4009 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4011 if (pFormat[0] != RPC_FC_CVARRAY)
4013 ERR("invalid format type %x\n", pFormat[0]);
4014 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4015 return NULL;
4018 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
4019 pFormat);
4020 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory,
4021 pFormat, TRUE /* fHasPointers */);
4023 return NULL;
4027 /***********************************************************************
4028 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
4030 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
4031 unsigned char** ppMemory,
4032 PFORMAT_STRING pFormat,
4033 unsigned char fMustAlloc )
4035 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4037 if (pFormat[0] != RPC_FC_CVARRAY)
4039 ERR("invalid format type %x\n", pFormat[0]);
4040 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4041 return NULL;
4044 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
4045 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory,
4046 pFormat, fMustAlloc,
4047 TRUE /* fUseBufferMemoryServer */,
4048 TRUE /* fUnmarshall */);
4050 return NULL;
4054 /***********************************************************************
4055 * NdrConformantVaryingArrayFree [RPCRT4.@]
4057 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
4058 unsigned char* pMemory,
4059 PFORMAT_STRING pFormat )
4061 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4063 if (pFormat[0] != RPC_FC_CVARRAY)
4065 ERR("invalid format type %x\n", pFormat[0]);
4066 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4067 return;
4070 array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
4071 TRUE /* fHasPointers */);
4075 /***********************************************************************
4076 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
4078 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
4079 unsigned char* pMemory, PFORMAT_STRING pFormat )
4081 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4083 if (pFormat[0] != RPC_FC_CVARRAY)
4085 ERR("invalid format type %x\n", pFormat[0]);
4086 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4087 return;
4090 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
4091 pFormat);
4092 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
4093 TRUE /* fHasPointers */);
4097 /***********************************************************************
4098 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
4100 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
4101 PFORMAT_STRING pFormat )
4103 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4105 if (pFormat[0] != RPC_FC_CVARRAY)
4107 ERR("invalid format type %x\n", pFormat[0]);
4108 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4109 return pStubMsg->MemorySize;
4112 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
4113 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat,
4114 TRUE /* fHasPointers */);
4116 return pStubMsg->MemorySize;
4120 /***********************************************************************
4121 * NdrComplexArrayMarshall [RPCRT4.@]
4123 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4124 unsigned char *pMemory,
4125 PFORMAT_STRING pFormat)
4127 int pointer_buffer_mark_set = 0;
4129 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4131 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4133 ERR("invalid format type %x\n", pFormat[0]);
4134 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4135 return NULL;
4138 if (!pStubMsg->PointerBufferMark)
4140 /* save buffer fields that may be changed by buffer sizer functions
4141 * and that may be needed later on */
4142 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4143 ULONG saved_buffer_length = pStubMsg->BufferLength;
4144 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4145 ULONG saved_offset = pStubMsg->Offset;
4146 ULONG saved_actual_count = pStubMsg->ActualCount;
4148 /* get the buffer pointer after complex array data, but before
4149 * pointer data */
4150 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
4151 pStubMsg->IgnoreEmbeddedPointers = 1;
4152 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4153 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4155 /* save it for use by embedded pointer code later */
4156 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
4157 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer));
4158 pointer_buffer_mark_set = 1;
4160 /* restore fields */
4161 pStubMsg->ActualCount = saved_actual_count;
4162 pStubMsg->Offset = saved_offset;
4163 pStubMsg->MaxCount = saved_max_count;
4164 pStubMsg->BufferLength = saved_buffer_length;
4167 array_compute_and_write_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4168 array_write_variance_and_marshall(RPC_FC_BOGUS_ARRAY, pStubMsg,
4169 pMemory, pFormat, TRUE /* fHasPointers */);
4171 STD_OVERFLOW_CHECK(pStubMsg);
4173 if (pointer_buffer_mark_set)
4175 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4176 pStubMsg->PointerBufferMark = NULL;
4179 return NULL;
4182 /***********************************************************************
4183 * NdrComplexArrayUnmarshall [RPCRT4.@]
4185 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4186 unsigned char **ppMemory,
4187 PFORMAT_STRING pFormat,
4188 unsigned char fMustAlloc)
4190 unsigned char *saved_buffer;
4191 int pointer_buffer_mark_set = 0;
4192 int saved_ignore_embedded;
4194 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4196 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4198 ERR("invalid format type %x\n", pFormat[0]);
4199 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4200 return NULL;
4203 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4204 /* save buffer pointer */
4205 saved_buffer = pStubMsg->Buffer;
4206 /* get the buffer pointer after complex array data, but before
4207 * pointer data */
4208 pStubMsg->IgnoreEmbeddedPointers = 1;
4209 pStubMsg->MemorySize = 0;
4210 NdrComplexArrayMemorySize(pStubMsg, pFormat);
4211 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4213 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - saved_buffer));
4214 if (!pStubMsg->PointerBufferMark)
4216 /* save it for use by embedded pointer code later */
4217 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4218 pointer_buffer_mark_set = 1;
4220 /* restore the original buffer */
4221 pStubMsg->Buffer = saved_buffer;
4223 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
4224 array_read_variance_and_unmarshall(RPC_FC_BOGUS_ARRAY, pStubMsg, ppMemory, pFormat, fMustAlloc,
4225 TRUE /* fUseBufferMemoryServer */, TRUE /* fUnmarshall */);
4227 if (pointer_buffer_mark_set)
4229 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4230 pStubMsg->PointerBufferMark = NULL;
4233 return NULL;
4236 /***********************************************************************
4237 * NdrComplexArrayBufferSize [RPCRT4.@]
4239 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4240 unsigned char *pMemory,
4241 PFORMAT_STRING pFormat)
4243 int pointer_length_set = 0;
4245 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4247 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4249 ERR("invalid format type %x\n", pFormat[0]);
4250 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4251 return;
4254 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
4256 /* save buffer fields that may be changed by buffer sizer functions
4257 * and that may be needed later on */
4258 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4259 ULONG saved_buffer_length = pStubMsg->BufferLength;
4260 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4261 ULONG saved_offset = pStubMsg->Offset;
4262 ULONG saved_actual_count = pStubMsg->ActualCount;
4264 /* get the buffer pointer after complex array data, but before
4265 * pointer data */
4266 pStubMsg->IgnoreEmbeddedPointers = 1;
4267 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4268 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4270 /* save it for use by embedded pointer code later */
4271 pStubMsg->PointerLength = pStubMsg->BufferLength;
4272 pointer_length_set = 1;
4274 /* restore fields */
4275 pStubMsg->ActualCount = saved_actual_count;
4276 pStubMsg->Offset = saved_offset;
4277 pStubMsg->MaxCount = saved_max_count;
4278 pStubMsg->BufferLength = saved_buffer_length;
4281 array_compute_and_size_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4282 array_buffer_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat, TRUE /* fHasPointers */);
4284 if(pointer_length_set)
4286 pStubMsg->BufferLength = pStubMsg->PointerLength;
4287 pStubMsg->PointerLength = 0;
4291 /***********************************************************************
4292 * NdrComplexArrayMemorySize [RPCRT4.@]
4294 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4295 PFORMAT_STRING pFormat)
4297 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4299 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4301 ERR("invalid format type %x\n", pFormat[0]);
4302 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4303 return 0;
4306 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
4307 array_memory_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
4308 return pStubMsg->MemorySize;
4311 /***********************************************************************
4312 * NdrComplexArrayFree [RPCRT4.@]
4314 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4315 unsigned char *pMemory,
4316 PFORMAT_STRING pFormat)
4318 ULONG i, count, def;
4320 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4322 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4324 ERR("invalid format type %x\n", pFormat[0]);
4325 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4326 return;
4329 def = *(const WORD*)&pFormat[2];
4330 pFormat += 4;
4332 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4333 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4335 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4336 TRACE("variance = %d\n", pStubMsg->ActualCount);
4338 count = pStubMsg->ActualCount;
4339 for (i = 0; i < count; i++)
4340 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4343 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4344 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4345 USER_MARSHAL_CB *umcb)
4347 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4348 pStubMsg->RpcMsg->DataRepresentation);
4349 umcb->pStubMsg = pStubMsg;
4350 umcb->pReserve = NULL;
4351 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4352 umcb->CBType = cbtype;
4353 umcb->pFormat = pFormat;
4354 umcb->pTypeFormat = NULL /* FIXME */;
4357 #define USER_MARSHAL_PTR_PREFIX \
4358 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4359 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4361 /***********************************************************************
4362 * NdrUserMarshalMarshall [RPCRT4.@]
4364 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4365 unsigned char *pMemory,
4366 PFORMAT_STRING pFormat)
4368 unsigned flags = pFormat[1];
4369 unsigned index = *(const WORD*)&pFormat[2];
4370 unsigned char *saved_buffer = NULL;
4371 USER_MARSHAL_CB umcb;
4373 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4374 TRACE("index=%d\n", index);
4376 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4378 if (flags & USER_MARSHAL_POINTER)
4380 align_pointer_clear(&pStubMsg->Buffer, 4);
4381 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4382 pStubMsg->Buffer += 4;
4383 if (pStubMsg->PointerBufferMark)
4385 saved_buffer = pStubMsg->Buffer;
4386 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4387 pStubMsg->PointerBufferMark = NULL;
4389 align_pointer_clear(&pStubMsg->Buffer, 8);
4391 else
4392 align_pointer_clear(&pStubMsg->Buffer, (flags & 0xf) + 1);
4394 pStubMsg->Buffer =
4395 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4396 &umcb.Flags, pStubMsg->Buffer, pMemory);
4398 if (saved_buffer)
4400 STD_OVERFLOW_CHECK(pStubMsg);
4401 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4402 pStubMsg->Buffer = saved_buffer;
4405 STD_OVERFLOW_CHECK(pStubMsg);
4407 return NULL;
4410 /***********************************************************************
4411 * NdrUserMarshalUnmarshall [RPCRT4.@]
4413 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4414 unsigned char **ppMemory,
4415 PFORMAT_STRING pFormat,
4416 unsigned char fMustAlloc)
4418 unsigned flags = pFormat[1];
4419 unsigned index = *(const WORD*)&pFormat[2];
4420 DWORD memsize = *(const WORD*)&pFormat[4];
4421 unsigned char *saved_buffer = NULL;
4422 USER_MARSHAL_CB umcb;
4424 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4425 TRACE("index=%d\n", index);
4427 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4429 if (flags & USER_MARSHAL_POINTER)
4431 align_pointer(&pStubMsg->Buffer, 4);
4432 /* skip pointer prefix */
4433 pStubMsg->Buffer += 4;
4434 if (pStubMsg->PointerBufferMark)
4436 saved_buffer = pStubMsg->Buffer;
4437 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4438 pStubMsg->PointerBufferMark = NULL;
4440 align_pointer(&pStubMsg->Buffer, 8);
4442 else
4443 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4445 if (!fMustAlloc && !*ppMemory)
4446 fMustAlloc = TRUE;
4447 if (fMustAlloc)
4449 *ppMemory = NdrAllocate(pStubMsg, memsize);
4450 memset(*ppMemory, 0, memsize);
4453 pStubMsg->Buffer =
4454 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4455 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4457 if (saved_buffer)
4459 STD_OVERFLOW_CHECK(pStubMsg);
4460 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4461 pStubMsg->Buffer = saved_buffer;
4464 return NULL;
4467 /***********************************************************************
4468 * NdrUserMarshalBufferSize [RPCRT4.@]
4470 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4471 unsigned char *pMemory,
4472 PFORMAT_STRING pFormat)
4474 unsigned flags = pFormat[1];
4475 unsigned index = *(const WORD*)&pFormat[2];
4476 DWORD bufsize = *(const WORD*)&pFormat[6];
4477 USER_MARSHAL_CB umcb;
4478 ULONG saved_buffer_length = 0;
4480 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4481 TRACE("index=%d\n", index);
4483 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4485 if (flags & USER_MARSHAL_POINTER)
4487 align_length(&pStubMsg->BufferLength, 4);
4488 /* skip pointer prefix */
4489 safe_buffer_length_increment(pStubMsg, 4);
4490 if (pStubMsg->IgnoreEmbeddedPointers)
4491 return;
4492 if (pStubMsg->PointerLength)
4494 saved_buffer_length = pStubMsg->BufferLength;
4495 pStubMsg->BufferLength = pStubMsg->PointerLength;
4496 pStubMsg->PointerLength = 0;
4498 align_length(&pStubMsg->BufferLength, 8);
4500 else
4501 align_length(&pStubMsg->BufferLength, (flags & 0xf) + 1);
4503 if (bufsize) {
4504 TRACE("size=%d\n", bufsize);
4505 safe_buffer_length_increment(pStubMsg, bufsize);
4507 else
4508 pStubMsg->BufferLength =
4509 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4510 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4512 if (saved_buffer_length)
4514 pStubMsg->PointerLength = pStubMsg->BufferLength;
4515 pStubMsg->BufferLength = saved_buffer_length;
4520 /***********************************************************************
4521 * NdrUserMarshalMemorySize [RPCRT4.@]
4523 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4524 PFORMAT_STRING pFormat)
4526 unsigned flags = pFormat[1];
4527 unsigned index = *(const WORD*)&pFormat[2];
4528 DWORD memsize = *(const WORD*)&pFormat[4];
4529 DWORD bufsize = *(const WORD*)&pFormat[6];
4531 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4532 TRACE("index=%d\n", index);
4534 pStubMsg->MemorySize += memsize;
4536 if (flags & USER_MARSHAL_POINTER)
4538 align_pointer(&pStubMsg->Buffer, 4);
4539 /* skip pointer prefix */
4540 pStubMsg->Buffer += 4;
4541 if (pStubMsg->IgnoreEmbeddedPointers)
4542 return pStubMsg->MemorySize;
4543 align_pointer(&pStubMsg->Buffer, 8);
4545 else
4546 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4548 if (!bufsize)
4549 FIXME("not implemented for varying buffer size\n");
4551 pStubMsg->Buffer += bufsize;
4553 return pStubMsg->MemorySize;
4556 /***********************************************************************
4557 * NdrUserMarshalFree [RPCRT4.@]
4559 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4560 unsigned char *pMemory,
4561 PFORMAT_STRING pFormat)
4563 /* unsigned flags = pFormat[1]; */
4564 unsigned index = *(const WORD*)&pFormat[2];
4565 USER_MARSHAL_CB umcb;
4567 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4568 TRACE("index=%d\n", index);
4570 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4572 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4573 &umcb.Flags, pMemory);
4576 /***********************************************************************
4577 * NdrGetUserMarshalInfo [RPCRT4.@]
4579 RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi)
4581 USER_MARSHAL_CB *umcb = CONTAINING_RECORD(flags, USER_MARSHAL_CB, Flags);
4583 TRACE("(%p,%u,%p)\n", flags, level, umi);
4585 if (level != 1)
4586 return RPC_S_INVALID_ARG;
4588 memset(&umi->u1.Level1, 0, sizeof(umi->u1.Level1));
4589 umi->InformationLevel = level;
4591 if (umcb->Signature != USER_MARSHAL_CB_SIGNATURE)
4592 return RPC_S_INVALID_ARG;
4594 umi->u1.Level1.pfnAllocate = umcb->pStubMsg->pfnAllocate;
4595 umi->u1.Level1.pfnFree = umcb->pStubMsg->pfnFree;
4596 umi->u1.Level1.pRpcChannelBuffer = umcb->pStubMsg->pRpcChannelBuffer;
4598 switch (umcb->CBType)
4600 case USER_MARSHAL_CB_MARSHALL:
4601 case USER_MARSHAL_CB_UNMARSHALL:
4603 RPC_MESSAGE *msg = umcb->pStubMsg->RpcMsg;
4604 unsigned char *buffer_start = msg->Buffer;
4605 unsigned char *buffer_end =
4606 (unsigned char *)msg->Buffer + msg->BufferLength;
4608 if (umcb->pStubMsg->Buffer < buffer_start ||
4609 umcb->pStubMsg->Buffer > buffer_end)
4610 return ERROR_INVALID_USER_BUFFER;
4612 umi->u1.Level1.Buffer = umcb->pStubMsg->Buffer;
4613 umi->u1.Level1.BufferSize = buffer_end - umcb->pStubMsg->Buffer;
4614 break;
4616 case USER_MARSHAL_CB_BUFFER_SIZE:
4617 case USER_MARSHAL_CB_FREE:
4618 break;
4619 default:
4620 WARN("unrecognised CBType %d\n", umcb->CBType);
4623 return RPC_S_OK;
4626 /***********************************************************************
4627 * NdrClearOutParameters [RPCRT4.@]
4629 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4630 PFORMAT_STRING pFormat,
4631 void *ArgAddr)
4633 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4636 /***********************************************************************
4637 * NdrConvert [RPCRT4.@]
4639 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4641 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4642 /* FIXME: since this stub doesn't do any converting, the proper behavior
4643 is to raise an exception */
4646 /***********************************************************************
4647 * NdrConvert2 [RPCRT4.@]
4649 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4651 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4652 pStubMsg, pFormat, NumberParams);
4653 /* FIXME: since this stub doesn't do any converting, the proper behavior
4654 is to raise an exception */
4657 #include "pshpack1.h"
4658 typedef struct _NDR_CSTRUCT_FORMAT
4660 unsigned char type;
4661 unsigned char alignment;
4662 unsigned short memory_size;
4663 short offset_to_array_description;
4664 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4665 #include "poppack.h"
4667 /***********************************************************************
4668 * NdrConformantStructMarshall [RPCRT4.@]
4670 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4671 unsigned char *pMemory,
4672 PFORMAT_STRING pFormat)
4674 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4675 PFORMAT_STRING pCArrayFormat;
4676 ULONG esize, bufsize;
4678 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4680 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4681 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4683 ERR("invalid format type %x\n", pCStructFormat->type);
4684 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4685 return NULL;
4688 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4689 pCStructFormat->offset_to_array_description;
4690 if (*pCArrayFormat != RPC_FC_CARRAY)
4692 ERR("invalid array format type %x\n", pCStructFormat->type);
4693 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4694 return NULL;
4696 esize = *(const WORD*)(pCArrayFormat+2);
4698 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4699 pCArrayFormat + 4, 0);
4701 WriteConformance(pStubMsg);
4703 align_pointer_clear(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4705 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4707 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4708 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4710 ERR("integer overflow of memory_size %u with bufsize %u\n",
4711 pCStructFormat->memory_size, bufsize);
4712 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4714 /* copy constant sized part of struct */
4715 pStubMsg->BufferMark = pStubMsg->Buffer;
4716 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4718 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4719 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4721 return NULL;
4724 /***********************************************************************
4725 * NdrConformantStructUnmarshall [RPCRT4.@]
4727 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4728 unsigned char **ppMemory,
4729 PFORMAT_STRING pFormat,
4730 unsigned char fMustAlloc)
4732 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4733 PFORMAT_STRING pCArrayFormat;
4734 ULONG esize, bufsize;
4735 unsigned char *saved_buffer;
4737 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4739 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4740 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4742 ERR("invalid format type %x\n", pCStructFormat->type);
4743 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4744 return NULL;
4746 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4747 pCStructFormat->offset_to_array_description;
4748 if (*pCArrayFormat != RPC_FC_CARRAY)
4750 ERR("invalid array format type %x\n", pCStructFormat->type);
4751 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4752 return NULL;
4754 esize = *(const WORD*)(pCArrayFormat+2);
4756 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4758 align_pointer(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4760 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4762 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4763 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4765 ERR("integer overflow of memory_size %u with bufsize %u\n",
4766 pCStructFormat->memory_size, bufsize);
4767 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4770 if (fMustAlloc)
4772 SIZE_T size = pCStructFormat->memory_size + bufsize;
4773 *ppMemory = NdrAllocate(pStubMsg, size);
4775 else
4777 if (!pStubMsg->IsClient && !*ppMemory)
4778 /* for servers, we just point straight into the RPC buffer */
4779 *ppMemory = pStubMsg->Buffer;
4782 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4783 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4784 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4785 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4787 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4788 if (*ppMemory != saved_buffer)
4789 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4791 return NULL;
4794 /***********************************************************************
4795 * NdrConformantStructBufferSize [RPCRT4.@]
4797 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4798 unsigned char *pMemory,
4799 PFORMAT_STRING pFormat)
4801 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4802 PFORMAT_STRING pCArrayFormat;
4803 ULONG esize;
4805 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4807 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4808 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4810 ERR("invalid format type %x\n", pCStructFormat->type);
4811 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4812 return;
4814 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4815 pCStructFormat->offset_to_array_description;
4816 if (*pCArrayFormat != RPC_FC_CARRAY)
4818 ERR("invalid array format type %x\n", pCStructFormat->type);
4819 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4820 return;
4822 esize = *(const WORD*)(pCArrayFormat+2);
4824 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4825 SizeConformance(pStubMsg);
4827 align_length(&pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4829 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4831 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4832 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4834 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4835 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4838 /***********************************************************************
4839 * NdrConformantStructMemorySize [RPCRT4.@]
4841 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4842 PFORMAT_STRING pFormat)
4844 FIXME("stub\n");
4845 return 0;
4848 /***********************************************************************
4849 * NdrConformantStructFree [RPCRT4.@]
4851 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4852 unsigned char *pMemory,
4853 PFORMAT_STRING pFormat)
4855 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4856 PFORMAT_STRING pCArrayFormat;
4858 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4860 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4861 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4863 ERR("invalid format type %x\n", pCStructFormat->type);
4864 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4865 return;
4868 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4869 pCStructFormat->offset_to_array_description;
4870 if (*pCArrayFormat != RPC_FC_CARRAY)
4872 ERR("invalid array format type %x\n", pCStructFormat->type);
4873 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4874 return;
4877 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4878 pCArrayFormat + 4, 0);
4880 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4882 /* copy constant sized part of struct */
4883 pStubMsg->BufferMark = pStubMsg->Buffer;
4885 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4886 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4889 /***********************************************************************
4890 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4892 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4893 unsigned char *pMemory,
4894 PFORMAT_STRING pFormat)
4896 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4897 PFORMAT_STRING pCVArrayFormat;
4899 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4901 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4902 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4904 ERR("invalid format type %x\n", pCVStructFormat->type);
4905 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4906 return NULL;
4909 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4910 pCVStructFormat->offset_to_array_description;
4912 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4913 pMemory + pCVStructFormat->memory_size,
4914 pCVArrayFormat);
4916 align_pointer_clear(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4918 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4920 /* write constant sized part */
4921 pStubMsg->BufferMark = pStubMsg->Buffer;
4922 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4924 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4925 pMemory + pCVStructFormat->memory_size,
4926 pCVArrayFormat, FALSE /* fHasPointers */);
4928 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4930 return NULL;
4933 /***********************************************************************
4934 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4936 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4937 unsigned char **ppMemory,
4938 PFORMAT_STRING pFormat,
4939 unsigned char fMustAlloc)
4941 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4942 PFORMAT_STRING pCVArrayFormat;
4943 ULONG memsize, bufsize;
4944 unsigned char *saved_buffer, *saved_array_buffer;
4945 ULONG offset;
4946 unsigned char *array_memory;
4948 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4950 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4951 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4953 ERR("invalid format type %x\n", pCVStructFormat->type);
4954 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4955 return NULL;
4958 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4959 pCVStructFormat->offset_to_array_description;
4961 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4962 pCVArrayFormat);
4964 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4966 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4968 /* work out how much memory to allocate if we need to do so */
4969 if (!fMustAlloc && !*ppMemory)
4970 fMustAlloc = TRUE;
4971 if (fMustAlloc)
4973 SIZE_T size = pCVStructFormat->memory_size + memsize;
4974 *ppMemory = NdrAllocate(pStubMsg, size);
4977 /* mark the start of the constant data */
4978 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4979 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4981 array_memory = *ppMemory + pCVStructFormat->memory_size;
4982 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
4983 &array_memory, pCVArrayFormat,
4984 FALSE /* fMustAlloc */,
4985 FALSE /* fUseServerBufferMemory */,
4986 FALSE /* fUnmarshall */);
4988 /* save offset in case unmarshalling pointers changes it */
4989 offset = pStubMsg->Offset;
4991 /* mark the start of the array data */
4992 saved_array_buffer = pStubMsg->Buffer;
4993 safe_buffer_increment(pStubMsg, bufsize);
4995 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4997 /* copy the constant data */
4998 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
4999 /* copy the array data */
5000 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
5001 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
5002 saved_array_buffer, bufsize);
5004 if (*pCVArrayFormat == RPC_FC_C_CSTRING)
5005 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
5006 else if (*pCVArrayFormat == RPC_FC_C_WSTRING)
5007 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
5009 return NULL;
5012 /***********************************************************************
5013 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
5015 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5016 unsigned char *pMemory,
5017 PFORMAT_STRING pFormat)
5019 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5020 PFORMAT_STRING pCVArrayFormat;
5022 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5024 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5025 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5027 ERR("invalid format type %x\n", pCVStructFormat->type);
5028 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5029 return;
5032 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5033 pCVStructFormat->offset_to_array_description;
5034 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
5035 pMemory + pCVStructFormat->memory_size,
5036 pCVArrayFormat);
5038 align_length(&pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
5040 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5042 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
5044 array_buffer_size(*pCVArrayFormat, pStubMsg,
5045 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5046 FALSE /* fHasPointers */);
5048 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5051 /***********************************************************************
5052 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
5054 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5055 PFORMAT_STRING pFormat)
5057 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5058 PFORMAT_STRING pCVArrayFormat;
5060 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5062 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5063 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5065 ERR("invalid format type %x\n", pCVStructFormat->type);
5066 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5067 return 0;
5070 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5071 pCVStructFormat->offset_to_array_description;
5072 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
5074 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
5076 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5078 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
5079 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
5080 FALSE /* fHasPointers */);
5082 pStubMsg->MemorySize += pCVStructFormat->memory_size;
5084 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5086 return pStubMsg->MemorySize;
5089 /***********************************************************************
5090 * NdrConformantVaryingStructFree [RPCRT4.@]
5092 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
5093 unsigned char *pMemory,
5094 PFORMAT_STRING pFormat)
5096 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5097 PFORMAT_STRING pCVArrayFormat;
5099 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5101 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5102 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5104 ERR("invalid format type %x\n", pCVStructFormat->type);
5105 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5106 return;
5109 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5110 pCVStructFormat->offset_to_array_description;
5111 array_free(*pCVArrayFormat, pStubMsg,
5112 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5113 FALSE /* fHasPointers */);
5115 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5117 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5120 #include "pshpack1.h"
5121 typedef struct
5123 unsigned char type;
5124 unsigned char alignment;
5125 unsigned short total_size;
5126 } NDR_SMFARRAY_FORMAT;
5128 typedef struct
5130 unsigned char type;
5131 unsigned char alignment;
5132 ULONG total_size;
5133 } NDR_LGFARRAY_FORMAT;
5134 #include "poppack.h"
5136 /***********************************************************************
5137 * NdrFixedArrayMarshall [RPCRT4.@]
5139 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5140 unsigned char *pMemory,
5141 PFORMAT_STRING pFormat)
5143 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5144 ULONG total_size;
5146 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5148 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5149 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5151 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5152 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5153 return NULL;
5156 align_pointer_clear(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5158 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5160 total_size = pSmFArrayFormat->total_size;
5161 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5163 else
5165 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5166 total_size = pLgFArrayFormat->total_size;
5167 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5170 pStubMsg->BufferMark = pStubMsg->Buffer;
5171 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
5173 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5175 return NULL;
5178 /***********************************************************************
5179 * NdrFixedArrayUnmarshall [RPCRT4.@]
5181 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5182 unsigned char **ppMemory,
5183 PFORMAT_STRING pFormat,
5184 unsigned char fMustAlloc)
5186 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5187 ULONG total_size;
5188 unsigned char *saved_buffer;
5190 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5192 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5193 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5195 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5196 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5197 return NULL;
5200 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5202 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5204 total_size = pSmFArrayFormat->total_size;
5205 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5207 else
5209 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5210 total_size = pLgFArrayFormat->total_size;
5211 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5214 if (fMustAlloc)
5215 *ppMemory = NdrAllocate(pStubMsg, total_size);
5216 else
5218 if (!pStubMsg->IsClient && !*ppMemory)
5219 /* for servers, we just point straight into the RPC buffer */
5220 *ppMemory = pStubMsg->Buffer;
5223 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5224 safe_buffer_increment(pStubMsg, total_size);
5225 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5227 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
5228 if (*ppMemory != saved_buffer)
5229 memcpy(*ppMemory, saved_buffer, total_size);
5231 return NULL;
5234 /***********************************************************************
5235 * NdrFixedArrayBufferSize [RPCRT4.@]
5237 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5238 unsigned char *pMemory,
5239 PFORMAT_STRING pFormat)
5241 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5242 ULONG total_size;
5244 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5246 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5247 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5249 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5250 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5251 return;
5254 align_length(&pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
5256 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5258 total_size = pSmFArrayFormat->total_size;
5259 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5261 else
5263 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5264 total_size = pLgFArrayFormat->total_size;
5265 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5267 safe_buffer_length_increment(pStubMsg, total_size);
5269 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5272 /***********************************************************************
5273 * NdrFixedArrayMemorySize [RPCRT4.@]
5275 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5276 PFORMAT_STRING pFormat)
5278 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5279 ULONG total_size;
5281 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5283 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5284 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5286 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5287 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5288 return 0;
5291 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5293 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5295 total_size = pSmFArrayFormat->total_size;
5296 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5298 else
5300 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5301 total_size = pLgFArrayFormat->total_size;
5302 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5304 pStubMsg->BufferMark = pStubMsg->Buffer;
5305 safe_buffer_increment(pStubMsg, total_size);
5306 pStubMsg->MemorySize += total_size;
5308 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5310 return total_size;
5313 /***********************************************************************
5314 * NdrFixedArrayFree [RPCRT4.@]
5316 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5317 unsigned char *pMemory,
5318 PFORMAT_STRING pFormat)
5320 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5322 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5324 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5325 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5327 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5328 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5329 return;
5332 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5333 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5334 else
5336 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5337 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5340 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5343 /***********************************************************************
5344 * NdrVaryingArrayMarshall [RPCRT4.@]
5346 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5347 unsigned char *pMemory,
5348 PFORMAT_STRING pFormat)
5350 unsigned char alignment;
5351 DWORD elements, esize;
5352 ULONG bufsize;
5354 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5356 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5357 (pFormat[0] != RPC_FC_LGVARRAY))
5359 ERR("invalid format type %x\n", pFormat[0]);
5360 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5361 return NULL;
5364 alignment = pFormat[1] + 1;
5366 if (pFormat[0] == RPC_FC_SMVARRAY)
5368 pFormat += 2;
5369 pFormat += sizeof(WORD);
5370 elements = *(const WORD*)pFormat;
5371 pFormat += sizeof(WORD);
5373 else
5375 pFormat += 2;
5376 pFormat += sizeof(DWORD);
5377 elements = *(const DWORD*)pFormat;
5378 pFormat += sizeof(DWORD);
5381 esize = *(const WORD*)pFormat;
5382 pFormat += sizeof(WORD);
5384 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5385 if ((pStubMsg->ActualCount > elements) ||
5386 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5388 RpcRaiseException(RPC_S_INVALID_BOUND);
5389 return NULL;
5392 WriteVariance(pStubMsg);
5394 align_pointer_clear(&pStubMsg->Buffer, alignment);
5396 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5397 pStubMsg->BufferMark = pStubMsg->Buffer;
5398 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5400 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5402 return NULL;
5405 /***********************************************************************
5406 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5408 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5409 unsigned char **ppMemory,
5410 PFORMAT_STRING pFormat,
5411 unsigned char fMustAlloc)
5413 unsigned char alignment;
5414 DWORD size, elements, esize;
5415 ULONG bufsize;
5416 unsigned char *saved_buffer;
5417 ULONG offset;
5419 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5421 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5422 (pFormat[0] != RPC_FC_LGVARRAY))
5424 ERR("invalid format type %x\n", pFormat[0]);
5425 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5426 return NULL;
5429 alignment = pFormat[1] + 1;
5431 if (pFormat[0] == RPC_FC_SMVARRAY)
5433 pFormat += 2;
5434 size = *(const WORD*)pFormat;
5435 pFormat += sizeof(WORD);
5436 elements = *(const WORD*)pFormat;
5437 pFormat += sizeof(WORD);
5439 else
5441 pFormat += 2;
5442 size = *(const DWORD*)pFormat;
5443 pFormat += sizeof(DWORD);
5444 elements = *(const DWORD*)pFormat;
5445 pFormat += sizeof(DWORD);
5448 esize = *(const WORD*)pFormat;
5449 pFormat += sizeof(WORD);
5451 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5453 align_pointer(&pStubMsg->Buffer, alignment);
5455 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5456 offset = pStubMsg->Offset;
5458 if (!fMustAlloc && !*ppMemory)
5459 fMustAlloc = TRUE;
5460 if (fMustAlloc)
5461 *ppMemory = NdrAllocate(pStubMsg, size);
5462 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5463 safe_buffer_increment(pStubMsg, bufsize);
5465 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5467 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5469 return NULL;
5472 /***********************************************************************
5473 * NdrVaryingArrayBufferSize [RPCRT4.@]
5475 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5476 unsigned char *pMemory,
5477 PFORMAT_STRING pFormat)
5479 unsigned char alignment;
5480 DWORD elements, esize;
5482 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5484 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5485 (pFormat[0] != RPC_FC_LGVARRAY))
5487 ERR("invalid format type %x\n", pFormat[0]);
5488 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5489 return;
5492 alignment = pFormat[1] + 1;
5494 if (pFormat[0] == RPC_FC_SMVARRAY)
5496 pFormat += 2;
5497 pFormat += sizeof(WORD);
5498 elements = *(const WORD*)pFormat;
5499 pFormat += sizeof(WORD);
5501 else
5503 pFormat += 2;
5504 pFormat += sizeof(DWORD);
5505 elements = *(const DWORD*)pFormat;
5506 pFormat += sizeof(DWORD);
5509 esize = *(const WORD*)pFormat;
5510 pFormat += sizeof(WORD);
5512 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5513 if ((pStubMsg->ActualCount > elements) ||
5514 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5516 RpcRaiseException(RPC_S_INVALID_BOUND);
5517 return;
5520 SizeVariance(pStubMsg);
5522 align_length(&pStubMsg->BufferLength, alignment);
5524 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5526 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5529 /***********************************************************************
5530 * NdrVaryingArrayMemorySize [RPCRT4.@]
5532 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5533 PFORMAT_STRING pFormat)
5535 unsigned char alignment;
5536 DWORD size, elements, esize;
5538 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5540 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5541 (pFormat[0] != RPC_FC_LGVARRAY))
5543 ERR("invalid format type %x\n", pFormat[0]);
5544 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5545 return 0;
5548 alignment = pFormat[1] + 1;
5550 if (pFormat[0] == RPC_FC_SMVARRAY)
5552 pFormat += 2;
5553 size = *(const WORD*)pFormat;
5554 pFormat += sizeof(WORD);
5555 elements = *(const WORD*)pFormat;
5556 pFormat += sizeof(WORD);
5558 else
5560 pFormat += 2;
5561 size = *(const DWORD*)pFormat;
5562 pFormat += sizeof(DWORD);
5563 elements = *(const DWORD*)pFormat;
5564 pFormat += sizeof(DWORD);
5567 esize = *(const WORD*)pFormat;
5568 pFormat += sizeof(WORD);
5570 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5572 align_pointer(&pStubMsg->Buffer, alignment);
5574 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5575 pStubMsg->MemorySize += size;
5577 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5579 return pStubMsg->MemorySize;
5582 /***********************************************************************
5583 * NdrVaryingArrayFree [RPCRT4.@]
5585 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5586 unsigned char *pMemory,
5587 PFORMAT_STRING pFormat)
5589 DWORD elements;
5591 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5593 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5594 (pFormat[0] != RPC_FC_LGVARRAY))
5596 ERR("invalid format type %x\n", pFormat[0]);
5597 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5598 return;
5601 if (pFormat[0] == RPC_FC_SMVARRAY)
5603 pFormat += 2;
5604 pFormat += sizeof(WORD);
5605 elements = *(const WORD*)pFormat;
5606 pFormat += sizeof(WORD);
5608 else
5610 pFormat += 2;
5611 pFormat += sizeof(DWORD);
5612 elements = *(const DWORD*)pFormat;
5613 pFormat += sizeof(DWORD);
5616 pFormat += sizeof(WORD);
5618 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5619 if ((pStubMsg->ActualCount > elements) ||
5620 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5622 RpcRaiseException(RPC_S_INVALID_BOUND);
5623 return;
5626 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5629 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5631 switch (fc)
5633 case RPC_FC_BYTE:
5634 case RPC_FC_CHAR:
5635 case RPC_FC_SMALL:
5636 case RPC_FC_USMALL:
5637 return *pMemory;
5638 case RPC_FC_WCHAR:
5639 case RPC_FC_SHORT:
5640 case RPC_FC_USHORT:
5641 case RPC_FC_ENUM16:
5642 return *(const USHORT *)pMemory;
5643 case RPC_FC_LONG:
5644 case RPC_FC_ULONG:
5645 case RPC_FC_ENUM32:
5646 return *(const ULONG *)pMemory;
5647 case RPC_FC_INT3264:
5648 case RPC_FC_UINT3264:
5649 return *(const ULONG_PTR *)pMemory;
5650 default:
5651 FIXME("Unhandled base type: 0x%02x\n", fc);
5652 return 0;
5656 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5657 ULONG discriminant,
5658 PFORMAT_STRING pFormat)
5660 unsigned short num_arms, arm, type;
5662 num_arms = *(const SHORT*)pFormat & 0x0fff;
5663 pFormat += 2;
5664 for(arm = 0; arm < num_arms; arm++)
5666 if(discriminant == *(const ULONG*)pFormat)
5668 pFormat += 4;
5669 break;
5671 pFormat += 6;
5674 type = *(const unsigned short*)pFormat;
5675 TRACE("type %04x\n", type);
5676 if(arm == num_arms) /* default arm extras */
5678 if(type == 0xffff)
5680 ERR("no arm for 0x%x and no default case\n", discriminant);
5681 RpcRaiseException(RPC_S_INVALID_TAG);
5682 return NULL;
5684 if(type == 0)
5686 TRACE("falling back to empty default case for 0x%x\n", discriminant);
5687 return NULL;
5690 return pFormat;
5693 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5695 unsigned short type;
5697 pFormat += 2;
5699 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5700 if(!pFormat)
5701 return NULL;
5703 type = *(const unsigned short*)pFormat;
5704 if((type & 0xff00) == 0x8000)
5706 unsigned char basetype = LOBYTE(type);
5707 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5709 else
5711 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5712 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5713 if (m)
5715 unsigned char *saved_buffer = NULL;
5716 int pointer_buffer_mark_set = 0;
5717 switch(*desc)
5719 case RPC_FC_RP:
5720 case RPC_FC_UP:
5721 case RPC_FC_OP:
5722 case RPC_FC_FP:
5723 align_pointer_clear(&pStubMsg->Buffer, 4);
5724 saved_buffer = pStubMsg->Buffer;
5725 if (pStubMsg->PointerBufferMark)
5727 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5728 pStubMsg->PointerBufferMark = NULL;
5729 pointer_buffer_mark_set = 1;
5731 else
5732 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5734 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5735 if (pointer_buffer_mark_set)
5737 STD_OVERFLOW_CHECK(pStubMsg);
5738 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5739 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5741 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5742 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5743 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5745 pStubMsg->Buffer = saved_buffer + 4;
5747 break;
5748 default:
5749 m(pStubMsg, pMemory, desc);
5752 else FIXME("no marshaller for embedded type %02x\n", *desc);
5754 return NULL;
5757 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5758 unsigned char **ppMemory,
5759 ULONG discriminant,
5760 PFORMAT_STRING pFormat,
5761 unsigned char fMustAlloc)
5763 unsigned short type;
5765 pFormat += 2;
5767 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5768 if(!pFormat)
5769 return NULL;
5771 type = *(const unsigned short*)pFormat;
5772 if((type & 0xff00) == 0x8000)
5774 unsigned char basetype = LOBYTE(type);
5775 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5777 else
5779 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5780 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5781 if (m)
5783 unsigned char *saved_buffer = NULL;
5784 int pointer_buffer_mark_set = 0;
5785 switch(*desc)
5787 case RPC_FC_RP:
5788 case RPC_FC_UP:
5789 case RPC_FC_OP:
5790 case RPC_FC_FP:
5791 align_pointer(&pStubMsg->Buffer, 4);
5792 saved_buffer = pStubMsg->Buffer;
5793 if (pStubMsg->PointerBufferMark)
5795 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5796 pStubMsg->PointerBufferMark = NULL;
5797 pointer_buffer_mark_set = 1;
5799 else
5800 pStubMsg->Buffer += 4; /* for pointer ID */
5802 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5804 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5805 saved_buffer, pStubMsg->BufferEnd);
5806 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5809 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5810 if (pointer_buffer_mark_set)
5812 STD_OVERFLOW_CHECK(pStubMsg);
5813 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5814 pStubMsg->Buffer = saved_buffer + 4;
5816 break;
5817 default:
5818 m(pStubMsg, ppMemory, desc, fMustAlloc);
5821 else FIXME("no marshaller for embedded type %02x\n", *desc);
5823 return NULL;
5826 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5827 unsigned char *pMemory,
5828 ULONG discriminant,
5829 PFORMAT_STRING pFormat)
5831 unsigned short type;
5833 pFormat += 2;
5835 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5836 if(!pFormat)
5837 return;
5839 type = *(const unsigned short*)pFormat;
5840 if((type & 0xff00) == 0x8000)
5842 unsigned char basetype = LOBYTE(type);
5843 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5845 else
5847 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5848 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5849 if (m)
5851 switch(*desc)
5853 case RPC_FC_RP:
5854 case RPC_FC_UP:
5855 case RPC_FC_OP:
5856 case RPC_FC_FP:
5857 align_length(&pStubMsg->BufferLength, 4);
5858 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5859 if (!pStubMsg->IgnoreEmbeddedPointers)
5861 int saved_buffer_length = pStubMsg->BufferLength;
5862 pStubMsg->BufferLength = pStubMsg->PointerLength;
5863 pStubMsg->PointerLength = 0;
5864 if(!pStubMsg->BufferLength)
5865 ERR("BufferLength == 0??\n");
5866 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5867 pStubMsg->PointerLength = pStubMsg->BufferLength;
5868 pStubMsg->BufferLength = saved_buffer_length;
5870 break;
5871 default:
5872 m(pStubMsg, pMemory, desc);
5875 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5879 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5880 ULONG discriminant,
5881 PFORMAT_STRING pFormat)
5883 unsigned short type, size;
5885 size = *(const unsigned short*)pFormat;
5886 pStubMsg->Memory += size;
5887 pFormat += 2;
5889 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5890 if(!pFormat)
5891 return 0;
5893 type = *(const unsigned short*)pFormat;
5894 if((type & 0xff00) == 0x8000)
5896 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5898 else
5900 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5901 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5902 unsigned char *saved_buffer;
5903 if (m)
5905 switch(*desc)
5907 case RPC_FC_RP:
5908 case RPC_FC_UP:
5909 case RPC_FC_OP:
5910 case RPC_FC_FP:
5911 align_pointer(&pStubMsg->Buffer, 4);
5912 saved_buffer = pStubMsg->Buffer;
5913 safe_buffer_increment(pStubMsg, 4);
5914 align_length(&pStubMsg->MemorySize, sizeof(void *));
5915 pStubMsg->MemorySize += sizeof(void *);
5916 if (!pStubMsg->IgnoreEmbeddedPointers)
5917 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5918 break;
5919 default:
5920 return m(pStubMsg, desc);
5923 else FIXME("no marshaller for embedded type %02x\n", *desc);
5926 TRACE("size %d\n", size);
5927 return size;
5930 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5931 unsigned char *pMemory,
5932 ULONG discriminant,
5933 PFORMAT_STRING pFormat)
5935 unsigned short type;
5937 pFormat += 2;
5939 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5940 if(!pFormat)
5941 return;
5943 type = *(const unsigned short*)pFormat;
5944 if((type & 0xff00) != 0x8000)
5946 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5947 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5948 if (m)
5950 switch(*desc)
5952 case RPC_FC_RP:
5953 case RPC_FC_UP:
5954 case RPC_FC_OP:
5955 case RPC_FC_FP:
5956 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5957 break;
5958 default:
5959 m(pStubMsg, pMemory, desc);
5965 /***********************************************************************
5966 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5968 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5969 unsigned char *pMemory,
5970 PFORMAT_STRING pFormat)
5972 unsigned char switch_type;
5973 unsigned char increment;
5974 ULONG switch_value;
5976 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5977 pFormat++;
5979 switch_type = *pFormat & 0xf;
5980 increment = (*pFormat & 0xf0) >> 4;
5981 pFormat++;
5983 align_pointer_clear(&pStubMsg->Buffer, increment);
5985 switch_value = get_discriminant(switch_type, pMemory);
5986 TRACE("got switch value 0x%x\n", switch_value);
5988 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5989 pMemory += increment;
5991 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5994 /***********************************************************************
5995 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5997 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5998 unsigned char **ppMemory,
5999 PFORMAT_STRING pFormat,
6000 unsigned char fMustAlloc)
6002 unsigned char switch_type;
6003 unsigned char increment;
6004 ULONG switch_value;
6005 unsigned short size;
6006 unsigned char *pMemoryArm;
6008 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6009 pFormat++;
6011 switch_type = *pFormat & 0xf;
6012 increment = (*pFormat & 0xf0) >> 4;
6013 pFormat++;
6015 align_pointer(&pStubMsg->Buffer, increment);
6016 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6017 TRACE("got switch value 0x%x\n", switch_value);
6019 size = *(const unsigned short*)pFormat + increment;
6020 if (!fMustAlloc && !*ppMemory)
6021 fMustAlloc = TRUE;
6022 if (fMustAlloc)
6023 *ppMemory = NdrAllocate(pStubMsg, size);
6025 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6026 * since the arm is part of the memory block that is encompassed by
6027 * the whole union. Memory is forced to allocate when pointers
6028 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6029 * clearing the memory we pass in to the unmarshaller */
6030 if (fMustAlloc)
6031 memset(*ppMemory, 0, size);
6033 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
6034 pMemoryArm = *ppMemory + increment;
6036 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, FALSE);
6039 /***********************************************************************
6040 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
6042 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6043 unsigned char *pMemory,
6044 PFORMAT_STRING pFormat)
6046 unsigned char switch_type;
6047 unsigned char increment;
6048 ULONG switch_value;
6050 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6051 pFormat++;
6053 switch_type = *pFormat & 0xf;
6054 increment = (*pFormat & 0xf0) >> 4;
6055 pFormat++;
6057 align_length(&pStubMsg->BufferLength, increment);
6058 switch_value = get_discriminant(switch_type, pMemory);
6059 TRACE("got switch value 0x%x\n", switch_value);
6061 /* Add discriminant size */
6062 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
6063 pMemory += increment;
6065 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
6068 /***********************************************************************
6069 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
6071 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6072 PFORMAT_STRING pFormat)
6074 unsigned char switch_type;
6075 unsigned char increment;
6076 ULONG switch_value;
6078 switch_type = *pFormat & 0xf;
6079 increment = (*pFormat & 0xf0) >> 4;
6080 pFormat++;
6082 align_pointer(&pStubMsg->Buffer, increment);
6083 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6084 TRACE("got switch value 0x%x\n", switch_value);
6086 pStubMsg->Memory += increment;
6088 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
6091 /***********************************************************************
6092 * NdrEncapsulatedUnionFree [RPCRT4.@]
6094 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6095 unsigned char *pMemory,
6096 PFORMAT_STRING pFormat)
6098 unsigned char switch_type;
6099 unsigned char increment;
6100 ULONG switch_value;
6102 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6103 pFormat++;
6105 switch_type = *pFormat & 0xf;
6106 increment = (*pFormat & 0xf0) >> 4;
6107 pFormat++;
6109 switch_value = get_discriminant(switch_type, pMemory);
6110 TRACE("got switch value 0x%x\n", switch_value);
6112 pMemory += increment;
6114 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
6117 /***********************************************************************
6118 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
6120 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6121 unsigned char *pMemory,
6122 PFORMAT_STRING pFormat)
6124 unsigned char switch_type;
6126 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6127 pFormat++;
6129 switch_type = *pFormat;
6130 pFormat++;
6132 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6133 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6134 /* Marshall discriminant */
6135 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6137 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6140 static LONG unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
6141 PFORMAT_STRING *ppFormat)
6143 LONG discriminant = 0;
6145 switch(**ppFormat)
6147 case RPC_FC_BYTE:
6148 case RPC_FC_CHAR:
6149 case RPC_FC_SMALL:
6150 case RPC_FC_USMALL:
6152 UCHAR d;
6153 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6154 discriminant = d;
6155 break;
6157 case RPC_FC_WCHAR:
6158 case RPC_FC_SHORT:
6159 case RPC_FC_USHORT:
6161 USHORT d;
6162 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6163 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6164 discriminant = d;
6165 break;
6167 case RPC_FC_LONG:
6168 case RPC_FC_ULONG:
6170 ULONG d;
6171 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6172 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6173 discriminant = d;
6174 break;
6176 default:
6177 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
6179 (*ppFormat)++;
6181 if (pStubMsg->fHasNewCorrDesc)
6182 *ppFormat += 6;
6183 else
6184 *ppFormat += 4;
6185 return discriminant;
6188 /**********************************************************************
6189 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6191 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6192 unsigned char **ppMemory,
6193 PFORMAT_STRING pFormat,
6194 unsigned char fMustAlloc)
6196 LONG discriminant;
6197 unsigned short size;
6199 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6200 pFormat++;
6202 /* Unmarshall discriminant */
6203 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6204 TRACE("unmarshalled discriminant %x\n", discriminant);
6206 pFormat += *(const SHORT*)pFormat;
6208 size = *(const unsigned short*)pFormat;
6210 if (!fMustAlloc && !*ppMemory)
6211 fMustAlloc = TRUE;
6212 if (fMustAlloc)
6213 *ppMemory = NdrAllocate(pStubMsg, size);
6215 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6216 * since the arm is part of the memory block that is encompassed by
6217 * the whole union. Memory is forced to allocate when pointers
6218 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6219 * clearing the memory we pass in to the unmarshaller */
6220 if (fMustAlloc)
6221 memset(*ppMemory, 0, size);
6223 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, FALSE);
6226 /***********************************************************************
6227 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6229 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6230 unsigned char *pMemory,
6231 PFORMAT_STRING pFormat)
6233 unsigned char switch_type;
6235 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6236 pFormat++;
6238 switch_type = *pFormat;
6239 pFormat++;
6241 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6242 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6243 /* Add discriminant size */
6244 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6246 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6249 /***********************************************************************
6250 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6252 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6253 PFORMAT_STRING pFormat)
6255 ULONG discriminant;
6257 pFormat++;
6258 /* Unmarshall discriminant */
6259 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6260 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
6262 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
6265 /***********************************************************************
6266 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6268 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6269 unsigned char *pMemory,
6270 PFORMAT_STRING pFormat)
6272 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6273 pFormat++;
6274 pFormat++;
6276 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6277 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6279 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6282 /***********************************************************************
6283 * NdrByteCountPointerMarshall [RPCRT4.@]
6285 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6286 unsigned char *pMemory,
6287 PFORMAT_STRING pFormat)
6289 FIXME("stub\n");
6290 return NULL;
6293 /***********************************************************************
6294 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6296 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6297 unsigned char **ppMemory,
6298 PFORMAT_STRING pFormat,
6299 unsigned char fMustAlloc)
6301 FIXME("stub\n");
6302 return NULL;
6305 /***********************************************************************
6306 * NdrByteCountPointerBufferSize [RPCRT4.@]
6308 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6309 unsigned char *pMemory,
6310 PFORMAT_STRING pFormat)
6312 FIXME("stub\n");
6315 /***********************************************************************
6316 * NdrByteCountPointerMemorySize [internal]
6318 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6319 PFORMAT_STRING pFormat)
6321 FIXME("stub\n");
6322 return 0;
6325 /***********************************************************************
6326 * NdrByteCountPointerFree [RPCRT4.@]
6328 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6329 unsigned char *pMemory,
6330 PFORMAT_STRING pFormat)
6332 FIXME("stub\n");
6335 /***********************************************************************
6336 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6338 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6339 unsigned char *pMemory,
6340 PFORMAT_STRING pFormat)
6342 FIXME("stub\n");
6343 return NULL;
6346 /***********************************************************************
6347 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6349 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6350 unsigned char **ppMemory,
6351 PFORMAT_STRING pFormat,
6352 unsigned char fMustAlloc)
6354 FIXME("stub\n");
6355 return NULL;
6358 /***********************************************************************
6359 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6361 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6362 unsigned char *pMemory,
6363 PFORMAT_STRING pFormat)
6365 FIXME("stub\n");
6368 /***********************************************************************
6369 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6371 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6372 PFORMAT_STRING pFormat)
6374 FIXME("stub\n");
6375 return 0;
6378 /***********************************************************************
6379 * NdrXmitOrRepAsFree [RPCRT4.@]
6381 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6382 unsigned char *pMemory,
6383 PFORMAT_STRING pFormat)
6385 FIXME("stub\n");
6388 /***********************************************************************
6389 * NdrRangeMarshall [internal]
6391 static unsigned char *WINAPI NdrRangeMarshall(
6392 PMIDL_STUB_MESSAGE pStubMsg,
6393 unsigned char *pMemory,
6394 PFORMAT_STRING pFormat)
6396 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6397 unsigned char base_type;
6399 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6401 if (pRange->type != RPC_FC_RANGE)
6403 ERR("invalid format type %x\n", pRange->type);
6404 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6405 return NULL;
6408 base_type = pRange->flags_type & 0xf;
6410 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6413 /***********************************************************************
6414 * NdrRangeUnmarshall [RPCRT4.@]
6416 unsigned char *WINAPI NdrRangeUnmarshall(
6417 PMIDL_STUB_MESSAGE pStubMsg,
6418 unsigned char **ppMemory,
6419 PFORMAT_STRING pFormat,
6420 unsigned char fMustAlloc)
6422 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6423 unsigned char base_type;
6425 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6427 if (pRange->type != RPC_FC_RANGE)
6429 ERR("invalid format type %x\n", pRange->type);
6430 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6431 return NULL;
6433 base_type = pRange->flags_type & 0xf;
6435 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6436 base_type, pRange->low_value, pRange->high_value);
6438 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6439 do \
6441 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \
6442 if (!fMustAlloc && !*ppMemory) \
6443 fMustAlloc = TRUE; \
6444 if (fMustAlloc) \
6445 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6446 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6448 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6449 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6450 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6452 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6453 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6455 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6456 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6457 (mem_type)pRange->high_value); \
6458 RpcRaiseException(RPC_S_INVALID_BOUND); \
6459 return NULL; \
6461 TRACE("*ppMemory: %p\n", *ppMemory); \
6462 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6463 pStubMsg->Buffer += sizeof(wire_type); \
6464 } while (0)
6466 switch(base_type)
6468 case RPC_FC_CHAR:
6469 case RPC_FC_SMALL:
6470 RANGE_UNMARSHALL(UCHAR, UCHAR, "%d");
6471 TRACE("value: 0x%02x\n", **ppMemory);
6472 break;
6473 case RPC_FC_BYTE:
6474 case RPC_FC_USMALL:
6475 RANGE_UNMARSHALL(CHAR, CHAR, "%u");
6476 TRACE("value: 0x%02x\n", **ppMemory);
6477 break;
6478 case RPC_FC_WCHAR: /* FIXME: valid? */
6479 case RPC_FC_USHORT:
6480 RANGE_UNMARSHALL(USHORT, USHORT, "%u");
6481 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6482 break;
6483 case RPC_FC_SHORT:
6484 RANGE_UNMARSHALL(SHORT, SHORT, "%d");
6485 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6486 break;
6487 case RPC_FC_LONG:
6488 case RPC_FC_ENUM32:
6489 RANGE_UNMARSHALL(LONG, LONG, "%d");
6490 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6491 break;
6492 case RPC_FC_ULONG:
6493 RANGE_UNMARSHALL(ULONG, ULONG, "%u");
6494 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6495 break;
6496 case RPC_FC_ENUM16:
6497 RANGE_UNMARSHALL(UINT, USHORT, "%u");
6498 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6499 break;
6500 case RPC_FC_FLOAT:
6501 case RPC_FC_DOUBLE:
6502 case RPC_FC_HYPER:
6503 default:
6504 ERR("invalid range base type: 0x%02x\n", base_type);
6505 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6508 return NULL;
6511 /***********************************************************************
6512 * NdrRangeBufferSize [internal]
6514 static void WINAPI NdrRangeBufferSize(
6515 PMIDL_STUB_MESSAGE pStubMsg,
6516 unsigned char *pMemory,
6517 PFORMAT_STRING pFormat)
6519 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6520 unsigned char base_type;
6522 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6524 if (pRange->type != RPC_FC_RANGE)
6526 ERR("invalid format type %x\n", pRange->type);
6527 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6529 base_type = pRange->flags_type & 0xf;
6531 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6534 /***********************************************************************
6535 * NdrRangeMemorySize [internal]
6537 static ULONG WINAPI NdrRangeMemorySize(
6538 PMIDL_STUB_MESSAGE pStubMsg,
6539 PFORMAT_STRING pFormat)
6541 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6542 unsigned char base_type;
6544 if (pRange->type != RPC_FC_RANGE)
6546 ERR("invalid format type %x\n", pRange->type);
6547 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6548 return 0;
6550 base_type = pRange->flags_type & 0xf;
6552 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6555 /***********************************************************************
6556 * NdrRangeFree [internal]
6558 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6559 unsigned char *pMemory,
6560 PFORMAT_STRING pFormat)
6562 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6564 /* nothing to do */
6567 /***********************************************************************
6568 * NdrBaseTypeMarshall [internal]
6570 static unsigned char *WINAPI NdrBaseTypeMarshall(
6571 PMIDL_STUB_MESSAGE pStubMsg,
6572 unsigned char *pMemory,
6573 PFORMAT_STRING pFormat)
6575 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6577 switch(*pFormat)
6579 case RPC_FC_BYTE:
6580 case RPC_FC_CHAR:
6581 case RPC_FC_SMALL:
6582 case RPC_FC_USMALL:
6583 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6584 TRACE("value: 0x%02x\n", *pMemory);
6585 break;
6586 case RPC_FC_WCHAR:
6587 case RPC_FC_SHORT:
6588 case RPC_FC_USHORT:
6589 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6590 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6591 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6592 break;
6593 case RPC_FC_LONG:
6594 case RPC_FC_ULONG:
6595 case RPC_FC_ERROR_STATUS_T:
6596 case RPC_FC_ENUM32:
6597 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONG));
6598 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6599 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6600 break;
6601 case RPC_FC_FLOAT:
6602 align_pointer_clear(&pStubMsg->Buffer, sizeof(float));
6603 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6604 break;
6605 case RPC_FC_DOUBLE:
6606 align_pointer_clear(&pStubMsg->Buffer, sizeof(double));
6607 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6608 break;
6609 case RPC_FC_HYPER:
6610 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONGLONG));
6611 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6612 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6613 break;
6614 case RPC_FC_ENUM16:
6616 USHORT val = *(UINT *)pMemory;
6617 /* only 16-bits on the wire, so do a sanity check */
6618 if (*(UINT *)pMemory > SHRT_MAX)
6619 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6620 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6621 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6622 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6623 break;
6625 case RPC_FC_INT3264:
6626 case RPC_FC_UINT3264:
6628 UINT val = *(UINT_PTR *)pMemory;
6629 align_pointer_clear(&pStubMsg->Buffer, sizeof(UINT));
6630 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6631 break;
6633 case RPC_FC_IGNORE:
6634 break;
6635 default:
6636 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6639 /* FIXME: what is the correct return value? */
6640 return NULL;
6643 /***********************************************************************
6644 * NdrBaseTypeUnmarshall [internal]
6646 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6647 PMIDL_STUB_MESSAGE pStubMsg,
6648 unsigned char **ppMemory,
6649 PFORMAT_STRING pFormat,
6650 unsigned char fMustAlloc)
6652 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6654 #define BASE_TYPE_UNMARSHALL(type) do { \
6655 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
6656 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6658 *ppMemory = pStubMsg->Buffer; \
6659 TRACE("*ppMemory: %p\n", *ppMemory); \
6660 safe_buffer_increment(pStubMsg, sizeof(type)); \
6662 else \
6664 if (fMustAlloc) \
6665 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6666 TRACE("*ppMemory: %p\n", *ppMemory); \
6667 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6669 } while (0)
6671 switch(*pFormat)
6673 case RPC_FC_BYTE:
6674 case RPC_FC_CHAR:
6675 case RPC_FC_SMALL:
6676 case RPC_FC_USMALL:
6677 BASE_TYPE_UNMARSHALL(UCHAR);
6678 TRACE("value: 0x%02x\n", **ppMemory);
6679 break;
6680 case RPC_FC_WCHAR:
6681 case RPC_FC_SHORT:
6682 case RPC_FC_USHORT:
6683 BASE_TYPE_UNMARSHALL(USHORT);
6684 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6685 break;
6686 case RPC_FC_LONG:
6687 case RPC_FC_ULONG:
6688 case RPC_FC_ERROR_STATUS_T:
6689 case RPC_FC_ENUM32:
6690 BASE_TYPE_UNMARSHALL(ULONG);
6691 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6692 break;
6693 case RPC_FC_FLOAT:
6694 BASE_TYPE_UNMARSHALL(float);
6695 TRACE("value: %f\n", **(float **)ppMemory);
6696 break;
6697 case RPC_FC_DOUBLE:
6698 BASE_TYPE_UNMARSHALL(double);
6699 TRACE("value: %f\n", **(double **)ppMemory);
6700 break;
6701 case RPC_FC_HYPER:
6702 BASE_TYPE_UNMARSHALL(ULONGLONG);
6703 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6704 break;
6705 case RPC_FC_ENUM16:
6707 USHORT val;
6708 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6709 if (!fMustAlloc && !*ppMemory)
6710 fMustAlloc = TRUE;
6711 if (fMustAlloc)
6712 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6713 safe_copy_from_buffer(pStubMsg, &val, sizeof(USHORT));
6714 /* 16-bits on the wire, but int in memory */
6715 **(UINT **)ppMemory = val;
6716 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6717 break;
6719 case RPC_FC_INT3264:
6720 if (sizeof(INT_PTR) == sizeof(INT)) BASE_TYPE_UNMARSHALL(INT);
6721 else
6723 INT val;
6724 align_pointer(&pStubMsg->Buffer, sizeof(INT));
6725 if (!fMustAlloc && !*ppMemory)
6726 fMustAlloc = TRUE;
6727 if (fMustAlloc)
6728 *ppMemory = NdrAllocate(pStubMsg, sizeof(INT_PTR));
6729 safe_copy_from_buffer(pStubMsg, &val, sizeof(INT));
6730 **(INT_PTR **)ppMemory = val;
6731 TRACE("value: 0x%08lx\n", **(INT_PTR **)ppMemory);
6733 break;
6734 case RPC_FC_UINT3264:
6735 if (sizeof(UINT_PTR) == sizeof(UINT)) BASE_TYPE_UNMARSHALL(UINT);
6736 else
6738 UINT val;
6739 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6740 if (!fMustAlloc && !*ppMemory)
6741 fMustAlloc = TRUE;
6742 if (fMustAlloc)
6743 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT_PTR));
6744 safe_copy_from_buffer(pStubMsg, &val, sizeof(UINT));
6745 **(UINT_PTR **)ppMemory = val;
6746 TRACE("value: 0x%08lx\n", **(UINT_PTR **)ppMemory);
6748 break;
6749 case RPC_FC_IGNORE:
6750 break;
6751 default:
6752 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6754 #undef BASE_TYPE_UNMARSHALL
6756 /* FIXME: what is the correct return value? */
6758 return NULL;
6761 /***********************************************************************
6762 * NdrBaseTypeBufferSize [internal]
6764 static void WINAPI NdrBaseTypeBufferSize(
6765 PMIDL_STUB_MESSAGE pStubMsg,
6766 unsigned char *pMemory,
6767 PFORMAT_STRING pFormat)
6769 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6771 switch(*pFormat)
6773 case RPC_FC_BYTE:
6774 case RPC_FC_CHAR:
6775 case RPC_FC_SMALL:
6776 case RPC_FC_USMALL:
6777 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6778 break;
6779 case RPC_FC_WCHAR:
6780 case RPC_FC_SHORT:
6781 case RPC_FC_USHORT:
6782 case RPC_FC_ENUM16:
6783 align_length(&pStubMsg->BufferLength, sizeof(USHORT));
6784 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6785 break;
6786 case RPC_FC_LONG:
6787 case RPC_FC_ULONG:
6788 case RPC_FC_ENUM32:
6789 case RPC_FC_INT3264:
6790 case RPC_FC_UINT3264:
6791 align_length(&pStubMsg->BufferLength, sizeof(ULONG));
6792 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6793 break;
6794 case RPC_FC_FLOAT:
6795 align_length(&pStubMsg->BufferLength, sizeof(float));
6796 safe_buffer_length_increment(pStubMsg, sizeof(float));
6797 break;
6798 case RPC_FC_DOUBLE:
6799 align_length(&pStubMsg->BufferLength, sizeof(double));
6800 safe_buffer_length_increment(pStubMsg, sizeof(double));
6801 break;
6802 case RPC_FC_HYPER:
6803 align_length(&pStubMsg->BufferLength, sizeof(ULONGLONG));
6804 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6805 break;
6806 case RPC_FC_ERROR_STATUS_T:
6807 align_length(&pStubMsg->BufferLength, sizeof(error_status_t));
6808 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6809 break;
6810 case RPC_FC_IGNORE:
6811 break;
6812 default:
6813 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6817 /***********************************************************************
6818 * NdrBaseTypeMemorySize [internal]
6820 static ULONG WINAPI NdrBaseTypeMemorySize(
6821 PMIDL_STUB_MESSAGE pStubMsg,
6822 PFORMAT_STRING pFormat)
6824 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6826 switch(*pFormat)
6828 case RPC_FC_BYTE:
6829 case RPC_FC_CHAR:
6830 case RPC_FC_SMALL:
6831 case RPC_FC_USMALL:
6832 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6833 pStubMsg->MemorySize += sizeof(UCHAR);
6834 return sizeof(UCHAR);
6835 case RPC_FC_WCHAR:
6836 case RPC_FC_SHORT:
6837 case RPC_FC_USHORT:
6838 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6839 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6840 align_length(&pStubMsg->MemorySize, sizeof(USHORT));
6841 pStubMsg->MemorySize += sizeof(USHORT);
6842 return sizeof(USHORT);
6843 case RPC_FC_LONG:
6844 case RPC_FC_ULONG:
6845 case RPC_FC_ENUM32:
6846 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6847 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6848 align_length(&pStubMsg->MemorySize, sizeof(ULONG));
6849 pStubMsg->MemorySize += sizeof(ULONG);
6850 return sizeof(ULONG);
6851 case RPC_FC_FLOAT:
6852 align_pointer(&pStubMsg->Buffer, sizeof(float));
6853 safe_buffer_increment(pStubMsg, sizeof(float));
6854 align_length(&pStubMsg->MemorySize, sizeof(float));
6855 pStubMsg->MemorySize += sizeof(float);
6856 return sizeof(float);
6857 case RPC_FC_DOUBLE:
6858 align_pointer(&pStubMsg->Buffer, sizeof(double));
6859 safe_buffer_increment(pStubMsg, sizeof(double));
6860 align_length(&pStubMsg->MemorySize, sizeof(double));
6861 pStubMsg->MemorySize += sizeof(double);
6862 return sizeof(double);
6863 case RPC_FC_HYPER:
6864 align_pointer(&pStubMsg->Buffer, sizeof(ULONGLONG));
6865 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6866 align_length(&pStubMsg->MemorySize, sizeof(ULONGLONG));
6867 pStubMsg->MemorySize += sizeof(ULONGLONG);
6868 return sizeof(ULONGLONG);
6869 case RPC_FC_ERROR_STATUS_T:
6870 align_pointer(&pStubMsg->Buffer, sizeof(error_status_t));
6871 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6872 align_length(&pStubMsg->MemorySize, sizeof(error_status_t));
6873 pStubMsg->MemorySize += sizeof(error_status_t);
6874 return sizeof(error_status_t);
6875 case RPC_FC_ENUM16:
6876 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6877 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6878 align_length(&pStubMsg->MemorySize, sizeof(UINT));
6879 pStubMsg->MemorySize += sizeof(UINT);
6880 return sizeof(UINT);
6881 case RPC_FC_INT3264:
6882 case RPC_FC_UINT3264:
6883 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6884 safe_buffer_increment(pStubMsg, sizeof(UINT));
6885 align_length(&pStubMsg->MemorySize, sizeof(UINT_PTR));
6886 pStubMsg->MemorySize += sizeof(UINT_PTR);
6887 return sizeof(UINT_PTR);
6888 case RPC_FC_IGNORE:
6889 align_length(&pStubMsg->MemorySize, sizeof(void *));
6890 pStubMsg->MemorySize += sizeof(void *);
6891 return sizeof(void *);
6892 default:
6893 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6894 return 0;
6898 /***********************************************************************
6899 * NdrBaseTypeFree [internal]
6901 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6902 unsigned char *pMemory,
6903 PFORMAT_STRING pFormat)
6905 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6907 /* nothing to do */
6910 /***********************************************************************
6911 * NdrContextHandleBufferSize [internal]
6913 static void WINAPI NdrContextHandleBufferSize(
6914 PMIDL_STUB_MESSAGE pStubMsg,
6915 unsigned char *pMemory,
6916 PFORMAT_STRING pFormat)
6918 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6920 if (*pFormat != RPC_FC_BIND_CONTEXT)
6922 ERR("invalid format type %x\n", *pFormat);
6923 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6925 align_length(&pStubMsg->BufferLength, 4);
6926 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6929 /***********************************************************************
6930 * NdrContextHandleMarshall [internal]
6932 static unsigned char *WINAPI NdrContextHandleMarshall(
6933 PMIDL_STUB_MESSAGE pStubMsg,
6934 unsigned char *pMemory,
6935 PFORMAT_STRING pFormat)
6937 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6939 if (*pFormat != RPC_FC_BIND_CONTEXT)
6941 ERR("invalid format type %x\n", *pFormat);
6942 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6944 TRACE("flags: 0x%02x\n", pFormat[1]);
6946 if (pStubMsg->IsClient)
6948 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6949 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6950 else
6951 NdrClientContextMarshall(pStubMsg, pMemory, FALSE);
6953 else
6955 NDR_SCONTEXT ctxt = NDRSContextFromValue(pMemory);
6956 NDR_RUNDOWN rundown = pStubMsg->StubDesc->apfnNdrRundownRoutines[pFormat[2]];
6957 NdrServerContextNewMarshall(pStubMsg, ctxt, rundown, pFormat);
6960 return NULL;
6963 /***********************************************************************
6964 * NdrContextHandleUnmarshall [internal]
6966 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6967 PMIDL_STUB_MESSAGE pStubMsg,
6968 unsigned char **ppMemory,
6969 PFORMAT_STRING pFormat,
6970 unsigned char fMustAlloc)
6972 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6973 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6975 if (*pFormat != RPC_FC_BIND_CONTEXT)
6977 ERR("invalid format type %x\n", *pFormat);
6978 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6980 TRACE("flags: 0x%02x\n", pFormat[1]);
6982 if (pStubMsg->IsClient)
6984 /* [out]-only or [ret] param */
6985 if ((pFormat[1] & (HANDLE_PARAM_IS_IN|HANDLE_PARAM_IS_OUT)) == HANDLE_PARAM_IS_OUT)
6986 **(NDR_CCONTEXT **)ppMemory = NULL;
6987 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6989 else
6991 NDR_SCONTEXT ctxt;
6992 ctxt = NdrServerContextNewUnmarshall(pStubMsg, pFormat);
6993 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6994 *(void **)ppMemory = NDRSContextValue(ctxt);
6995 else
6996 *(void **)ppMemory = *NDRSContextValue(ctxt);
6999 return NULL;
7002 /***********************************************************************
7003 * NdrClientContextMarshall [RPCRT4.@]
7005 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7006 NDR_CCONTEXT ContextHandle,
7007 int fCheck)
7009 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
7011 align_pointer_clear(&pStubMsg->Buffer, 4);
7013 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7015 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7016 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7017 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7020 /* FIXME: what does fCheck do? */
7021 NDRCContextMarshall(ContextHandle,
7022 pStubMsg->Buffer);
7024 pStubMsg->Buffer += cbNDRContext;
7027 /***********************************************************************
7028 * NdrClientContextUnmarshall [RPCRT4.@]
7030 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7031 NDR_CCONTEXT * pContextHandle,
7032 RPC_BINDING_HANDLE BindHandle)
7034 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
7036 align_pointer(&pStubMsg->Buffer, 4);
7038 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
7039 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7041 NDRCContextUnmarshall(pContextHandle,
7042 BindHandle,
7043 pStubMsg->Buffer,
7044 pStubMsg->RpcMsg->DataRepresentation);
7046 pStubMsg->Buffer += cbNDRContext;
7049 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7050 NDR_SCONTEXT ContextHandle,
7051 NDR_RUNDOWN RundownRoutine )
7053 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
7055 align_pointer(&pStubMsg->Buffer, 4);
7057 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7059 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7060 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7061 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7064 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7065 pStubMsg->Buffer, RundownRoutine, NULL,
7066 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7067 pStubMsg->Buffer += cbNDRContext;
7070 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
7072 NDR_SCONTEXT ContextHandle;
7074 TRACE("(%p)\n", pStubMsg);
7076 align_pointer(&pStubMsg->Buffer, 4);
7078 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7080 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7081 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7082 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7085 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7086 pStubMsg->Buffer,
7087 pStubMsg->RpcMsg->DataRepresentation,
7088 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7089 pStubMsg->Buffer += cbNDRContext;
7091 return ContextHandle;
7094 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
7095 unsigned char* pMemory,
7096 PFORMAT_STRING pFormat)
7098 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
7101 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
7102 PFORMAT_STRING pFormat)
7104 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7105 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7107 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7109 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7110 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7111 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7112 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7113 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7115 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7116 if_id = &sif->InterfaceId;
7119 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
7120 pStubMsg->RpcMsg->DataRepresentation, if_id,
7121 flags);
7124 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7125 NDR_SCONTEXT ContextHandle,
7126 NDR_RUNDOWN RundownRoutine,
7127 PFORMAT_STRING pFormat)
7129 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7130 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7132 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
7134 align_pointer(&pStubMsg->Buffer, 4);
7136 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7138 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7139 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7140 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7143 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7144 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7145 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7146 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7147 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7149 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7150 if_id = &sif->InterfaceId;
7153 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7154 pStubMsg->Buffer, RundownRoutine, if_id, flags);
7155 pStubMsg->Buffer += cbNDRContext;
7158 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7159 PFORMAT_STRING pFormat)
7161 NDR_SCONTEXT ContextHandle;
7162 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7163 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7165 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7167 align_pointer(&pStubMsg->Buffer, 4);
7169 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7171 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7172 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7173 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7176 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7177 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7178 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7179 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7180 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7182 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7183 if_id = &sif->InterfaceId;
7186 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7187 pStubMsg->Buffer,
7188 pStubMsg->RpcMsg->DataRepresentation,
7189 if_id, flags);
7190 pStubMsg->Buffer += cbNDRContext;
7192 return ContextHandle;
7195 /***********************************************************************
7196 * NdrCorrelationInitialize [RPCRT4.@]
7198 * Initializes correlation validity checking.
7200 * PARAMS
7201 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7202 * pMemory [I] Pointer to memory to use as a cache.
7203 * CacheSize [I] Size of the memory pointed to by pMemory.
7204 * Flags [I] Reserved. Set to zero.
7206 * RETURNS
7207 * Nothing.
7209 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
7211 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
7212 pStubMsg->fHasNewCorrDesc = TRUE;
7215 /***********************************************************************
7216 * NdrCorrelationPass [RPCRT4.@]
7218 * Performs correlation validity checking.
7220 * PARAMS
7221 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7223 * RETURNS
7224 * Nothing.
7226 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
7228 FIXME("(%p): stub\n", pStubMsg);
7231 /***********************************************************************
7232 * NdrCorrelationFree [RPCRT4.@]
7234 * Frees any resources used while unmarshalling parameters that need
7235 * correlation validity checking.
7237 * PARAMS
7238 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7240 * RETURNS
7241 * Nothing.
7243 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
7245 FIXME("(%p): stub\n", pStubMsg);