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
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
36 #define NONAMELESSUNION
45 #include "wine/unicode.h"
46 #include "wine/rpcfc.h"
48 #include "wine/debug.h"
50 WINE_DEFAULT_DEBUG_CHANNEL(ole);
53 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
54 (*((UINT32 *)(pchar)) = (uint32))
56 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
57 (*((UINT32 *)(pchar)))
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) \
68 MAKEWORD(*(pchar), *((pchar)+1)), \
69 MAKEWORD(*((pchar)+2), *((pchar)+3))))
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) \
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)
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)
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))); \
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,
173 NdrPointerMarshall, NdrPointerMarshall,
174 NdrPointerMarshall, NdrPointerMarshall,
176 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
177 NdrConformantStructMarshall, NdrConformantStructMarshall,
178 NdrConformantVaryingStructMarshall,
179 NdrComplexStructMarshall,
181 NdrConformantArrayMarshall,
182 NdrConformantVaryingArrayMarshall,
183 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
184 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
185 NdrComplexArrayMarshall,
187 NdrConformantStringMarshall, 0, 0,
188 NdrConformantStringMarshall,
189 NdrNonConformantStringMarshall, 0, 0, 0,
191 NdrEncapsulatedUnionMarshall,
192 NdrNonEncapsulatedUnionMarshall,
193 NdrByteCountPointerMarshall,
194 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
196 NdrInterfacePointerMarshall,
198 NdrContextHandleMarshall,
201 NdrUserMarshalMarshall,
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,
213 NdrBaseTypeUnmarshall,
215 NdrPointerUnmarshall, NdrPointerUnmarshall,
216 NdrPointerUnmarshall, NdrPointerUnmarshall,
218 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
219 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
220 NdrConformantVaryingStructUnmarshall,
221 NdrComplexStructUnmarshall,
223 NdrConformantArrayUnmarshall,
224 NdrConformantVaryingArrayUnmarshall,
225 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
226 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
227 NdrComplexArrayUnmarshall,
229 NdrConformantStringUnmarshall, 0, 0,
230 NdrConformantStringUnmarshall,
231 NdrNonConformantStringUnmarshall, 0, 0, 0,
233 NdrEncapsulatedUnionUnmarshall,
234 NdrNonEncapsulatedUnionUnmarshall,
235 NdrByteCountPointerUnmarshall,
236 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
238 NdrInterfacePointerUnmarshall,
240 NdrContextHandleUnmarshall,
243 NdrUserMarshalUnmarshall,
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,
255 NdrBaseTypeBufferSize,
257 NdrPointerBufferSize, NdrPointerBufferSize,
258 NdrPointerBufferSize, NdrPointerBufferSize,
260 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
261 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
262 NdrConformantVaryingStructBufferSize,
263 NdrComplexStructBufferSize,
265 NdrConformantArrayBufferSize,
266 NdrConformantVaryingArrayBufferSize,
267 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
268 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
269 NdrComplexArrayBufferSize,
271 NdrConformantStringBufferSize, 0, 0,
272 NdrConformantStringBufferSize,
273 NdrNonConformantStringBufferSize, 0, 0, 0,
275 NdrEncapsulatedUnionBufferSize,
276 NdrNonEncapsulatedUnionBufferSize,
277 NdrByteCountPointerBufferSize,
278 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
280 NdrInterfacePointerBufferSize,
282 NdrContextHandleBufferSize,
285 NdrUserMarshalBufferSize,
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,
297 NdrBaseTypeMemorySize,
299 NdrPointerMemorySize, NdrPointerMemorySize,
300 NdrPointerMemorySize, NdrPointerMemorySize,
302 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
303 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
304 NdrConformantVaryingStructMemorySize,
305 NdrComplexStructMemorySize,
307 NdrConformantArrayMemorySize,
308 NdrConformantVaryingArrayMemorySize,
309 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
310 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
311 NdrComplexArrayMemorySize,
313 NdrConformantStringMemorySize, 0, 0,
314 NdrConformantStringMemorySize,
315 NdrNonConformantStringMemorySize, 0, 0, 0,
317 NdrEncapsulatedUnionMemorySize,
318 NdrNonEncapsulatedUnionMemorySize,
319 NdrByteCountPointerMemorySize,
320 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
322 NdrInterfacePointerMemorySize,
327 NdrUserMarshalMemorySize,
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,
341 NdrPointerFree, NdrPointerFree,
342 NdrPointerFree, NdrPointerFree,
344 NdrSimpleStructFree, NdrSimpleStructFree,
345 NdrConformantStructFree, NdrConformantStructFree,
346 NdrConformantVaryingStructFree,
347 NdrComplexStructFree,
349 NdrConformantArrayFree,
350 NdrConformantVaryingArrayFree,
351 NdrFixedArrayFree, NdrFixedArrayFree,
352 NdrVaryingArrayFree, NdrVaryingArrayFree,
358 NdrEncapsulatedUnionFree,
359 NdrNonEncapsulatedUnionFree,
361 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
363 NdrInterfacePointerFree,
374 typedef struct _NDR_MEMORY_LIST
379 struct _NDR_MEMORY_LIST *next;
382 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
384 /***********************************************************************
385 * NdrAllocate [RPCRT4.@]
387 * Allocates a block of memory using pStubMsg->pfnAllocate.
390 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
391 * len [I] Size of memory block to allocate.
394 * The memory block of size len that was allocated.
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)
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;
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)
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;
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);
486 if (pStubMsg->fHasNewCorrDesc)
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];
541 if (!IsConformanceOrVariancePresent(pFormat)) {
542 /* null descriptor */
547 switch (pFormat[0] & 0xf0) {
548 case RPC_FC_NORMAL_CONFORMANCE:
549 TRACE("normal conformance, ofs=%d\n", ofs);
552 case RPC_FC_POINTER_CONFORMANCE:
553 TRACE("pointer conformance, ofs=%d\n", ofs);
554 ptr = pStubMsg->Memory;
556 case RPC_FC_TOP_LEVEL_CONFORMANCE:
557 TRACE("toplevel conformance, ofs=%d\n", ofs);
558 if (pStubMsg->StackTop) {
559 ptr = pStubMsg->StackTop;
562 /* -Os mode, *pCount is already set */
566 case RPC_FC_CONSTANT_CONFORMANCE:
567 data = ofs | ((DWORD)pFormat[1] << 16);
568 TRACE("constant conformance, val=%ld\n", data);
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;
582 FIXME("unknown conformance type %x, expect crash.\n", pFormat[0] & 0xf0);
586 switch (pFormat[1]) {
587 case RPC_FC_DEREFERENCE:
588 ptr = *(LPVOID*)((char *)ptr + ofs);
590 case RPC_FC_CALLBACK:
592 unsigned char *old_stack_top = pStubMsg->StackTop;
593 ULONG_PTR max_count, old_max_count = pStubMsg->MaxCount;
595 pStubMsg->StackTop = ptr;
597 /* ofs is index into StubDesc->apfnExprEval */
598 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
599 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
601 pStubMsg->StackTop = old_stack_top;
603 /* the callback function always stores the computed value in MaxCount */
604 max_count = pStubMsg->MaxCount;
605 pStubMsg->MaxCount = old_max_count;
610 ptr = (char *)ptr + ofs;
623 data = *(USHORT*)ptr;
634 data = *(ULONGLONG *)ptr;
637 FIXME("unknown conformance data type %x\n", dtype);
640 TRACE("dereferenced data type %x at %p, got %ld\n", dtype, ptr, data);
643 switch (pFormat[1]) {
644 case RPC_FC_DEREFERENCE: /* already handled */
661 FIXME("unknown conformance op %d\n", pFormat[1]);
666 TRACE("resulting conformance is %ld\n", *pCount);
667 if (pStubMsg->fHasNewCorrDesc)
673 static inline PFORMAT_STRING SkipConformance(PMIDL_STUB_MESSAGE pStubMsg,
674 PFORMAT_STRING pFormat)
676 if (pStubMsg->fHasNewCorrDesc)
683 static inline PFORMAT_STRING SkipVariance(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
685 return SkipConformance( pStubMsg, pFormat );
688 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
689 * the result overflows 32-bits */
690 static inline ULONG safe_multiply(ULONG a, ULONG b)
692 ULONGLONG ret = (ULONGLONG)a * b;
693 if (ret > 0xffffffff)
695 RpcRaiseException(RPC_S_INVALID_BOUND);
701 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
703 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
704 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
705 RpcRaiseException(RPC_X_BAD_STUB_DATA);
706 pStubMsg->Buffer += size;
709 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
711 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
713 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
714 pStubMsg->BufferLength, size);
715 RpcRaiseException(RPC_X_BAD_STUB_DATA);
717 pStubMsg->BufferLength += size;
720 /* copies data from the buffer, checking that there is enough data in the buffer
722 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
724 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
725 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
727 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
728 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
729 RpcRaiseException(RPC_X_BAD_STUB_DATA);
731 if (p == pStubMsg->Buffer)
732 ERR("pointer is the same as the buffer\n");
733 memcpy(p, pStubMsg->Buffer, size);
734 pStubMsg->Buffer += size;
737 /* copies data to the buffer, checking that there is enough space to do so */
738 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
740 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
741 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
743 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
744 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
746 RpcRaiseException(RPC_X_BAD_STUB_DATA);
748 memcpy(pStubMsg->Buffer, p, size);
749 pStubMsg->Buffer += size;
752 /* verify that string data sitting in the buffer is valid and safe to
754 static void validate_string_data(MIDL_STUB_MESSAGE *pStubMsg, ULONG bufsize, ULONG esize)
758 /* verify the buffer is safe to access */
759 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
760 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
762 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
763 pStubMsg->BufferEnd, pStubMsg->Buffer);
764 RpcRaiseException(RPC_X_BAD_STUB_DATA);
767 /* strings must always have null terminating bytes */
770 ERR("invalid string length of %d\n", bufsize / esize);
771 RpcRaiseException(RPC_S_INVALID_BOUND);
774 for (i = bufsize - esize; i < bufsize; i++)
775 if (pStubMsg->Buffer[i] != 0)
777 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
778 i, pStubMsg->Buffer[i]);
779 RpcRaiseException(RPC_S_INVALID_BOUND);
783 static inline void dump_pointer_attr(unsigned char attr)
785 if (attr & RPC_FC_P_ALLOCALLNODES)
786 TRACE(" RPC_FC_P_ALLOCALLNODES");
787 if (attr & RPC_FC_P_DONTFREE)
788 TRACE(" RPC_FC_P_DONTFREE");
789 if (attr & RPC_FC_P_ONSTACK)
790 TRACE(" RPC_FC_P_ONSTACK");
791 if (attr & RPC_FC_P_SIMPLEPOINTER)
792 TRACE(" RPC_FC_P_SIMPLEPOINTER");
793 if (attr & RPC_FC_P_DEREF)
794 TRACE(" RPC_FC_P_DEREF");
798 /***********************************************************************
799 * PointerMarshall [internal]
801 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
802 unsigned char *Buffer,
803 unsigned char *Pointer,
804 PFORMAT_STRING pFormat)
806 unsigned type = pFormat[0], attr = pFormat[1];
810 int pointer_needs_marshaling;
812 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
813 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
815 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
816 else desc = pFormat + *(const SHORT*)pFormat;
819 case RPC_FC_RP: /* ref pointer (always non-null) */
822 ERR("NULL ref pointer is not allowed\n");
823 RpcRaiseException(RPC_X_NULL_REF_POINTER);
825 pointer_needs_marshaling = 1;
827 case RPC_FC_UP: /* unique pointer */
828 case RPC_FC_OP: /* object pointer - same as unique here */
830 pointer_needs_marshaling = 1;
832 pointer_needs_marshaling = 0;
833 pointer_id = Pointer ? NDR_POINTER_ID(pStubMsg) : 0;
834 TRACE("writing 0x%08x to buffer\n", pointer_id);
835 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
838 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
839 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
840 TRACE("writing 0x%08x to buffer\n", pointer_id);
841 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
844 FIXME("unhandled ptr type=%02x\n", type);
845 RpcRaiseException(RPC_X_BAD_STUB_DATA);
849 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
851 if (pointer_needs_marshaling) {
852 if (attr & RPC_FC_P_DEREF) {
853 Pointer = *(unsigned char**)Pointer;
854 TRACE("deref => %p\n", Pointer);
856 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
857 if (m) m(pStubMsg, Pointer, desc);
858 else FIXME("no marshaller for data type=%02x\n", *desc);
861 STD_OVERFLOW_CHECK(pStubMsg);
864 /***********************************************************************
865 * PointerUnmarshall [internal]
867 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
868 unsigned char *Buffer,
869 unsigned char **pPointer,
870 unsigned char *pSrcPointer,
871 PFORMAT_STRING pFormat,
872 unsigned char fMustAlloc)
874 unsigned type = pFormat[0], attr = pFormat[1];
877 DWORD pointer_id = 0;
878 int pointer_needs_unmarshaling;
880 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
881 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
883 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
884 else desc = pFormat + *(const SHORT*)pFormat;
887 case RPC_FC_RP: /* ref pointer (always non-null) */
888 pointer_needs_unmarshaling = 1;
890 case RPC_FC_UP: /* unique pointer */
891 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
892 TRACE("pointer_id is 0x%08x\n", pointer_id);
894 pointer_needs_unmarshaling = 1;
897 pointer_needs_unmarshaling = 0;
900 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
901 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
902 TRACE("pointer_id is 0x%08x\n", pointer_id);
903 if (!fMustAlloc && pSrcPointer)
905 FIXME("free object pointer %p\n", pSrcPointer);
909 pointer_needs_unmarshaling = 1;
913 pointer_needs_unmarshaling = 0;
917 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
918 TRACE("pointer_id is 0x%08x\n", pointer_id);
919 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
920 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
923 FIXME("unhandled ptr type=%02x\n", type);
924 RpcRaiseException(RPC_X_BAD_STUB_DATA);
928 if (pointer_needs_unmarshaling) {
929 unsigned char **current_ptr = pPointer;
930 if (pStubMsg->IsClient) {
932 /* if we aren't forcing allocation of memory then try to use the existing
933 * (source) pointer to unmarshall the data into so that [in,out]
934 * parameters behave correctly. it doesn't matter if the parameter is
935 * [out] only since in that case the pointer will be NULL. we force
936 * allocation when the source pointer is NULL here instead of in the type
937 * unmarshalling routine for the benefit of the deref code below */
940 TRACE("setting *pPointer to %p\n", pSrcPointer);
941 *pPointer = pSrcPointer;
947 /* the memory in a stub is never initialised, so we have to work out here
948 * whether we have to initialise it so we can use the optimisation of
949 * setting the pointer to the buffer, if possible, or set fMustAlloc to
951 if (attr & RPC_FC_P_DEREF) {
958 if (attr & RPC_FC_P_ALLOCALLNODES)
959 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
961 if (attr & RPC_FC_P_DEREF) {
963 unsigned char *base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
964 *pPointer = base_ptr_val;
965 current_ptr = (unsigned char **)base_ptr_val;
967 current_ptr = *(unsigned char***)current_ptr;
968 TRACE("deref => %p\n", current_ptr);
969 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
971 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
972 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
973 else FIXME("no unmarshaller for data type=%02x\n", *desc);
975 if (type == RPC_FC_FP)
976 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
980 TRACE("pointer=%p\n", *pPointer);
983 /***********************************************************************
984 * PointerBufferSize [internal]
986 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
987 unsigned char *Pointer,
988 PFORMAT_STRING pFormat)
990 unsigned type = pFormat[0], attr = pFormat[1];
993 int pointer_needs_sizing;
996 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
997 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
999 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1000 else desc = pFormat + *(const SHORT*)pFormat;
1003 case RPC_FC_RP: /* ref pointer (always non-null) */
1006 ERR("NULL ref pointer is not allowed\n");
1007 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1012 /* NULL pointer has no further representation */
1017 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1018 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1019 if (!pointer_needs_sizing)
1023 FIXME("unhandled ptr type=%02x\n", type);
1024 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1028 if (attr & RPC_FC_P_DEREF) {
1029 Pointer = *(unsigned char**)Pointer;
1030 TRACE("deref => %p\n", Pointer);
1033 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1034 if (m) m(pStubMsg, Pointer, desc);
1035 else FIXME("no buffersizer for data type=%02x\n", *desc);
1038 /***********************************************************************
1039 * PointerMemorySize [internal]
1041 static ULONG PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1042 unsigned char *Buffer, PFORMAT_STRING pFormat)
1044 unsigned type = pFormat[0], attr = pFormat[1];
1045 PFORMAT_STRING desc;
1047 DWORD pointer_id = 0;
1048 int pointer_needs_sizing;
1050 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1051 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1053 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1054 else desc = pFormat + *(const SHORT*)pFormat;
1057 case RPC_FC_RP: /* ref pointer (always non-null) */
1058 pointer_needs_sizing = 1;
1060 case RPC_FC_UP: /* unique pointer */
1061 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1062 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1063 TRACE("pointer_id is 0x%08x\n", pointer_id);
1065 pointer_needs_sizing = 1;
1067 pointer_needs_sizing = 0;
1072 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1073 TRACE("pointer_id is 0x%08x\n", pointer_id);
1074 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1075 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1079 FIXME("unhandled ptr type=%02x\n", type);
1080 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1084 if (attr & RPC_FC_P_DEREF) {
1085 align_length(&pStubMsg->MemorySize, sizeof(void*));
1086 pStubMsg->MemorySize += sizeof(void*);
1090 if (pointer_needs_sizing) {
1091 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1092 if (m) m(pStubMsg, desc);
1093 else FIXME("no memorysizer for data type=%02x\n", *desc);
1096 return pStubMsg->MemorySize;
1099 /***********************************************************************
1100 * PointerFree [internal]
1102 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1103 unsigned char *Pointer,
1104 PFORMAT_STRING pFormat)
1106 unsigned type = pFormat[0], attr = pFormat[1];
1107 PFORMAT_STRING desc;
1109 unsigned char *current_pointer = Pointer;
1111 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1112 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1113 if (attr & RPC_FC_P_DONTFREE) return;
1115 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1116 else desc = pFormat + *(const SHORT*)pFormat;
1118 if (!Pointer) return;
1120 if (type == RPC_FC_FP) {
1121 int pointer_needs_freeing = NdrFullPointerFree(
1122 pStubMsg->FullPtrXlatTables, Pointer);
1123 if (!pointer_needs_freeing)
1127 if (attr & RPC_FC_P_DEREF) {
1128 current_pointer = *(unsigned char**)Pointer;
1129 TRACE("deref => %p\n", current_pointer);
1132 m = NdrFreer[*desc & NDR_TABLE_MASK];
1133 if (m) m(pStubMsg, current_pointer, desc);
1135 /* this check stops us from trying to free buffer memory. we don't have to
1136 * worry about clients, since they won't call this function.
1137 * we don't have to check for the buffer being reallocated because
1138 * BufferStart and BufferEnd won't be reset when allocating memory for
1139 * sending the response. we don't have to check for the new buffer here as
1140 * it won't be used a type memory, only for buffer memory */
1141 if (Pointer >= pStubMsg->BufferStart && Pointer < pStubMsg->BufferEnd)
1144 if (attr & RPC_FC_P_ONSTACK) {
1145 TRACE("not freeing stack ptr %p\n", Pointer);
1148 TRACE("freeing %p\n", Pointer);
1149 NdrFree(pStubMsg, Pointer);
1152 TRACE("not freeing %p\n", Pointer);
1155 /***********************************************************************
1156 * EmbeddedPointerMarshall
1158 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1159 unsigned char *pMemory,
1160 PFORMAT_STRING pFormat)
1162 unsigned char *Mark = pStubMsg->BufferMark;
1163 unsigned rep, count, stride;
1165 unsigned char *saved_buffer = NULL;
1167 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1169 if (*pFormat != RPC_FC_PP) return NULL;
1172 if (pStubMsg->PointerBufferMark)
1174 saved_buffer = pStubMsg->Buffer;
1175 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1176 pStubMsg->PointerBufferMark = NULL;
1179 while (pFormat[0] != RPC_FC_END) {
1180 switch (pFormat[0]) {
1182 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1184 case RPC_FC_NO_REPEAT:
1190 case RPC_FC_FIXED_REPEAT:
1191 rep = *(const WORD*)&pFormat[2];
1192 stride = *(const WORD*)&pFormat[4];
1193 count = *(const WORD*)&pFormat[8];
1196 case RPC_FC_VARIABLE_REPEAT:
1197 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1198 stride = *(const WORD*)&pFormat[2];
1199 count = *(const WORD*)&pFormat[6];
1203 for (i = 0; i < rep; i++) {
1204 PFORMAT_STRING info = pFormat;
1205 unsigned char *membase = pMemory + (i * stride);
1206 unsigned char *bufbase = Mark + (i * stride);
1209 for (u=0; u<count; u++,info+=8) {
1210 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1211 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1212 unsigned char *saved_memory = pStubMsg->Memory;
1214 pStubMsg->Memory = pMemory;
1215 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1216 pStubMsg->Memory = saved_memory;
1219 pFormat += 8 * count;
1224 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1225 pStubMsg->Buffer = saved_buffer;
1228 STD_OVERFLOW_CHECK(pStubMsg);
1233 /***********************************************************************
1234 * EmbeddedPointerUnmarshall
1236 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1237 unsigned char *pDstBuffer,
1238 unsigned char *pSrcMemoryPtrs,
1239 PFORMAT_STRING pFormat,
1240 unsigned char fMustAlloc)
1242 unsigned char *Mark = pStubMsg->BufferMark;
1243 unsigned rep, count, stride;
1245 unsigned char *saved_buffer = NULL;
1247 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc);
1249 if (*pFormat != RPC_FC_PP) return NULL;
1252 if (pStubMsg->PointerBufferMark)
1254 saved_buffer = pStubMsg->Buffer;
1255 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1256 pStubMsg->PointerBufferMark = NULL;
1259 while (pFormat[0] != RPC_FC_END) {
1260 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1261 switch (pFormat[0]) {
1263 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1265 case RPC_FC_NO_REPEAT:
1271 case RPC_FC_FIXED_REPEAT:
1272 rep = *(const WORD*)&pFormat[2];
1273 stride = *(const WORD*)&pFormat[4];
1274 count = *(const WORD*)&pFormat[8];
1277 case RPC_FC_VARIABLE_REPEAT:
1278 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1279 stride = *(const WORD*)&pFormat[2];
1280 count = *(const WORD*)&pFormat[6];
1284 for (i = 0; i < rep; i++) {
1285 PFORMAT_STRING info = pFormat;
1286 unsigned char *bufdstbase = pDstBuffer + (i * stride);
1287 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1288 unsigned char *bufbase = Mark + (i * stride);
1291 for (u=0; u<count; u++,info+=8) {
1292 unsigned char **bufdstptr = (unsigned char **)(bufdstbase + *(const SHORT*)&info[2]);
1293 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1294 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1295 PointerUnmarshall(pStubMsg, bufptr, bufdstptr, *memsrcptr, info+4, fMustAlloc);
1298 pFormat += 8 * count;
1303 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1304 pStubMsg->Buffer = saved_buffer;
1310 /***********************************************************************
1311 * EmbeddedPointerBufferSize
1313 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1314 unsigned char *pMemory,
1315 PFORMAT_STRING pFormat)
1317 unsigned rep, count, stride;
1319 ULONG saved_buffer_length = 0;
1321 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1323 if (pStubMsg->IgnoreEmbeddedPointers) return;
1325 if (*pFormat != RPC_FC_PP) return;
1328 if (pStubMsg->PointerLength)
1330 saved_buffer_length = pStubMsg->BufferLength;
1331 pStubMsg->BufferLength = pStubMsg->PointerLength;
1332 pStubMsg->PointerLength = 0;
1335 while (pFormat[0] != RPC_FC_END) {
1336 switch (pFormat[0]) {
1338 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1340 case RPC_FC_NO_REPEAT:
1346 case RPC_FC_FIXED_REPEAT:
1347 rep = *(const WORD*)&pFormat[2];
1348 stride = *(const WORD*)&pFormat[4];
1349 count = *(const WORD*)&pFormat[8];
1352 case RPC_FC_VARIABLE_REPEAT:
1353 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1354 stride = *(const WORD*)&pFormat[2];
1355 count = *(const WORD*)&pFormat[6];
1359 for (i = 0; i < rep; i++) {
1360 PFORMAT_STRING info = pFormat;
1361 unsigned char *membase = pMemory + (i * stride);
1364 for (u=0; u<count; u++,info+=8) {
1365 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1366 unsigned char *saved_memory = pStubMsg->Memory;
1368 pStubMsg->Memory = pMemory;
1369 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1370 pStubMsg->Memory = saved_memory;
1373 pFormat += 8 * count;
1376 if (saved_buffer_length)
1378 pStubMsg->PointerLength = pStubMsg->BufferLength;
1379 pStubMsg->BufferLength = saved_buffer_length;
1383 /***********************************************************************
1384 * EmbeddedPointerMemorySize [internal]
1386 static ULONG EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1387 PFORMAT_STRING pFormat)
1389 unsigned char *Mark = pStubMsg->BufferMark;
1390 unsigned rep, count, stride;
1392 unsigned char *saved_buffer = NULL;
1394 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1396 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1398 if (pStubMsg->PointerBufferMark)
1400 saved_buffer = pStubMsg->Buffer;
1401 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1402 pStubMsg->PointerBufferMark = NULL;
1405 if (*pFormat != RPC_FC_PP) return 0;
1408 while (pFormat[0] != RPC_FC_END) {
1409 switch (pFormat[0]) {
1411 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1413 case RPC_FC_NO_REPEAT:
1419 case RPC_FC_FIXED_REPEAT:
1420 rep = *(const WORD*)&pFormat[2];
1421 stride = *(const WORD*)&pFormat[4];
1422 count = *(const WORD*)&pFormat[8];
1425 case RPC_FC_VARIABLE_REPEAT:
1426 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1427 stride = *(const WORD*)&pFormat[2];
1428 count = *(const WORD*)&pFormat[6];
1432 for (i = 0; i < rep; i++) {
1433 PFORMAT_STRING info = pFormat;
1434 unsigned char *bufbase = Mark + (i * stride);
1436 for (u=0; u<count; u++,info+=8) {
1437 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1438 PointerMemorySize(pStubMsg, bufptr, info+4);
1441 pFormat += 8 * count;
1446 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1447 pStubMsg->Buffer = saved_buffer;
1453 /***********************************************************************
1454 * EmbeddedPointerFree [internal]
1456 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1457 unsigned char *pMemory,
1458 PFORMAT_STRING pFormat)
1460 unsigned rep, count, stride;
1463 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1464 if (*pFormat != RPC_FC_PP) return;
1467 while (pFormat[0] != RPC_FC_END) {
1468 switch (pFormat[0]) {
1470 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1472 case RPC_FC_NO_REPEAT:
1478 case RPC_FC_FIXED_REPEAT:
1479 rep = *(const WORD*)&pFormat[2];
1480 stride = *(const WORD*)&pFormat[4];
1481 count = *(const WORD*)&pFormat[8];
1484 case RPC_FC_VARIABLE_REPEAT:
1485 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1486 stride = *(const WORD*)&pFormat[2];
1487 count = *(const WORD*)&pFormat[6];
1491 for (i = 0; i < rep; i++) {
1492 PFORMAT_STRING info = pFormat;
1493 unsigned char *membase = pMemory + (i * stride);
1496 for (u=0; u<count; u++,info+=8) {
1497 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1498 unsigned char *saved_memory = pStubMsg->Memory;
1500 pStubMsg->Memory = pMemory;
1501 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1502 pStubMsg->Memory = saved_memory;
1505 pFormat += 8 * count;
1509 /***********************************************************************
1510 * NdrPointerMarshall [RPCRT4.@]
1512 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1513 unsigned char *pMemory,
1514 PFORMAT_STRING pFormat)
1516 unsigned char *Buffer;
1518 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1520 /* Increment the buffer here instead of in PointerMarshall,
1521 * as that is used by embedded pointers which already handle the incrementing
1522 * the buffer, and shouldn't write any additional pointer data to the wire */
1523 if (*pFormat != RPC_FC_RP)
1525 align_pointer_clear(&pStubMsg->Buffer, 4);
1526 Buffer = pStubMsg->Buffer;
1527 safe_buffer_increment(pStubMsg, 4);
1530 Buffer = pStubMsg->Buffer;
1532 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1537 /***********************************************************************
1538 * NdrPointerUnmarshall [RPCRT4.@]
1540 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1541 unsigned char **ppMemory,
1542 PFORMAT_STRING pFormat,
1543 unsigned char fMustAlloc)
1545 unsigned char *Buffer;
1547 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1549 if (*pFormat == RPC_FC_RP)
1551 Buffer = pStubMsg->Buffer;
1552 /* Do the NULL ref pointer check here because embedded pointers can be
1553 * NULL if the type the pointer is embedded in was allocated rather than
1554 * being passed in by the client */
1555 if (pStubMsg->IsClient && !*ppMemory)
1557 ERR("NULL ref pointer is not allowed\n");
1558 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1563 /* Increment the buffer here instead of in PointerUnmarshall,
1564 * as that is used by embedded pointers which already handle the incrementing
1565 * the buffer, and shouldn't read any additional pointer data from the
1567 align_pointer(&pStubMsg->Buffer, 4);
1568 Buffer = pStubMsg->Buffer;
1569 safe_buffer_increment(pStubMsg, 4);
1572 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1577 /***********************************************************************
1578 * NdrPointerBufferSize [RPCRT4.@]
1580 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1581 unsigned char *pMemory,
1582 PFORMAT_STRING pFormat)
1584 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1586 /* Increment the buffer length here instead of in PointerBufferSize,
1587 * as that is used by embedded pointers which already handle the buffer
1588 * length, and shouldn't write anything more to the wire */
1589 if (*pFormat != RPC_FC_RP)
1591 align_length(&pStubMsg->BufferLength, 4);
1592 safe_buffer_length_increment(pStubMsg, 4);
1595 PointerBufferSize(pStubMsg, pMemory, pFormat);
1598 /***********************************************************************
1599 * NdrPointerMemorySize [RPCRT4.@]
1601 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1602 PFORMAT_STRING pFormat)
1604 unsigned char *Buffer = pStubMsg->Buffer;
1605 if (*pFormat != RPC_FC_RP)
1607 align_pointer(&pStubMsg->Buffer, 4);
1608 safe_buffer_increment(pStubMsg, 4);
1610 align_length(&pStubMsg->MemorySize, sizeof(void *));
1611 return PointerMemorySize(pStubMsg, Buffer, pFormat);
1614 /***********************************************************************
1615 * NdrPointerFree [RPCRT4.@]
1617 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1618 unsigned char *pMemory,
1619 PFORMAT_STRING pFormat)
1621 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1622 PointerFree(pStubMsg, pMemory, pFormat);
1625 /***********************************************************************
1626 * NdrSimpleTypeMarshall [RPCRT4.@]
1628 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1629 unsigned char FormatChar )
1631 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1634 /***********************************************************************
1635 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1637 * Unmarshall a base type.
1640 * Doesn't check that the buffer is long enough before copying, so the caller
1643 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1644 unsigned char FormatChar )
1646 #define BASE_TYPE_UNMARSHALL(type) \
1647 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
1648 TRACE("pMemory: %p\n", pMemory); \
1649 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1650 pStubMsg->Buffer += sizeof(type);
1658 BASE_TYPE_UNMARSHALL(UCHAR);
1659 TRACE("value: 0x%02x\n", *pMemory);
1664 BASE_TYPE_UNMARSHALL(USHORT);
1665 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
1669 case RPC_FC_ERROR_STATUS_T:
1671 BASE_TYPE_UNMARSHALL(ULONG);
1672 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
1675 BASE_TYPE_UNMARSHALL(float);
1676 TRACE("value: %f\n", *(float *)pMemory);
1679 BASE_TYPE_UNMARSHALL(double);
1680 TRACE("value: %f\n", *(double *)pMemory);
1683 BASE_TYPE_UNMARSHALL(ULONGLONG);
1684 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
1687 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
1688 TRACE("pMemory: %p\n", pMemory);
1689 /* 16-bits on the wire, but int in memory */
1690 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
1691 pStubMsg->Buffer += sizeof(USHORT);
1692 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
1694 case RPC_FC_INT3264:
1695 align_pointer(&pStubMsg->Buffer, sizeof(INT));
1696 /* 32-bits on the wire, but int_ptr in memory */
1697 *(INT_PTR *)pMemory = *(INT *)pStubMsg->Buffer;
1698 pStubMsg->Buffer += sizeof(INT);
1699 TRACE("value: 0x%08lx\n", *(INT_PTR *)pMemory);
1701 case RPC_FC_UINT3264:
1702 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
1703 /* 32-bits on the wire, but int_ptr in memory */
1704 *(UINT_PTR *)pMemory = *(UINT *)pStubMsg->Buffer;
1705 pStubMsg->Buffer += sizeof(UINT);
1706 TRACE("value: 0x%08lx\n", *(UINT_PTR *)pMemory);
1711 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
1713 #undef BASE_TYPE_UNMARSHALL
1716 /***********************************************************************
1717 * NdrSimpleStructMarshall [RPCRT4.@]
1719 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1720 unsigned char *pMemory,
1721 PFORMAT_STRING pFormat)
1723 unsigned size = *(const WORD*)(pFormat+2);
1724 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1726 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1);
1728 pStubMsg->BufferMark = pStubMsg->Buffer;
1729 safe_copy_to_buffer(pStubMsg, pMemory, size);
1731 if (pFormat[0] != RPC_FC_STRUCT)
1732 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1737 /***********************************************************************
1738 * NdrSimpleStructUnmarshall [RPCRT4.@]
1740 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1741 unsigned char **ppMemory,
1742 PFORMAT_STRING pFormat,
1743 unsigned char fMustAlloc)
1745 unsigned size = *(const WORD*)(pFormat+2);
1746 unsigned char *saved_buffer;
1747 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1749 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
1752 *ppMemory = NdrAllocate(pStubMsg, size);
1755 if (!pStubMsg->IsClient && !*ppMemory)
1756 /* for servers, we just point straight into the RPC buffer */
1757 *ppMemory = pStubMsg->Buffer;
1760 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1761 safe_buffer_increment(pStubMsg, size);
1762 if (pFormat[0] == RPC_FC_PSTRUCT)
1763 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1765 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1766 if (*ppMemory != saved_buffer)
1767 memcpy(*ppMemory, saved_buffer, size);
1772 /***********************************************************************
1773 * NdrSimpleStructBufferSize [RPCRT4.@]
1775 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1776 unsigned char *pMemory,
1777 PFORMAT_STRING pFormat)
1779 unsigned size = *(const WORD*)(pFormat+2);
1780 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1782 align_length(&pStubMsg->BufferLength, pFormat[1] + 1);
1784 safe_buffer_length_increment(pStubMsg, size);
1785 if (pFormat[0] != RPC_FC_STRUCT)
1786 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1789 /***********************************************************************
1790 * NdrSimpleStructMemorySize [RPCRT4.@]
1792 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1793 PFORMAT_STRING pFormat)
1795 unsigned short size = *(const WORD *)(pFormat+2);
1797 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1799 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
1800 pStubMsg->MemorySize += size;
1801 safe_buffer_increment(pStubMsg, size);
1803 if (pFormat[0] != RPC_FC_STRUCT)
1804 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1805 return pStubMsg->MemorySize;
1808 /***********************************************************************
1809 * NdrSimpleStructFree [RPCRT4.@]
1811 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1812 unsigned char *pMemory,
1813 PFORMAT_STRING pFormat)
1815 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1816 if (pFormat[0] != RPC_FC_STRUCT)
1817 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1822 static inline void array_compute_and_size_conformance(
1823 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1824 PFORMAT_STRING pFormat)
1831 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1832 SizeConformance(pStubMsg);
1834 case RPC_FC_CVARRAY:
1835 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1836 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1837 SizeConformance(pStubMsg);
1839 case RPC_FC_C_CSTRING:
1840 case RPC_FC_C_WSTRING:
1841 if (fc == RPC_FC_C_CSTRING)
1843 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1844 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1848 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1849 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1852 if (pFormat[1] == RPC_FC_STRING_SIZED)
1853 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1855 pStubMsg->MaxCount = pStubMsg->ActualCount;
1857 SizeConformance(pStubMsg);
1859 case RPC_FC_BOGUS_ARRAY:
1860 count = *(const WORD *)(pFormat + 2);
1862 if (IsConformanceOrVariancePresent(pFormat)) SizeConformance(pStubMsg);
1863 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, count);
1864 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
1867 ERR("unknown array format 0x%x\n", fc);
1868 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1872 static inline void array_buffer_size(
1873 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1874 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1878 unsigned char alignment;
1883 esize = *(const WORD*)(pFormat+2);
1884 alignment = pFormat[1] + 1;
1886 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1888 align_length(&pStubMsg->BufferLength, alignment);
1890 size = safe_multiply(esize, pStubMsg->MaxCount);
1891 /* conformance value plus array */
1892 safe_buffer_length_increment(pStubMsg, size);
1895 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1897 case RPC_FC_CVARRAY:
1898 esize = *(const WORD*)(pFormat+2);
1899 alignment = pFormat[1] + 1;
1901 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1902 pFormat = SkipVariance(pStubMsg, pFormat);
1904 SizeVariance(pStubMsg);
1906 align_length(&pStubMsg->BufferLength, alignment);
1908 size = safe_multiply(esize, pStubMsg->ActualCount);
1909 safe_buffer_length_increment(pStubMsg, size);
1912 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1914 case RPC_FC_C_CSTRING:
1915 case RPC_FC_C_WSTRING:
1916 if (fc == RPC_FC_C_CSTRING)
1921 SizeVariance(pStubMsg);
1923 size = safe_multiply(esize, pStubMsg->ActualCount);
1924 safe_buffer_length_increment(pStubMsg, size);
1926 case RPC_FC_BOGUS_ARRAY:
1927 alignment = pFormat[1] + 1;
1928 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1929 if (IsConformanceOrVariancePresent(pFormat)) SizeVariance(pStubMsg);
1930 pFormat = SkipVariance(pStubMsg, pFormat);
1932 align_length(&pStubMsg->BufferLength, alignment);
1934 size = pStubMsg->ActualCount;
1935 for (i = 0; i < size; i++)
1936 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
1939 ERR("unknown array format 0x%x\n", fc);
1940 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1944 static inline void array_compute_and_write_conformance(
1945 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1946 PFORMAT_STRING pFormat)
1949 BOOL conformance_present;
1954 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1955 WriteConformance(pStubMsg);
1957 case RPC_FC_CVARRAY:
1958 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1959 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1960 WriteConformance(pStubMsg);
1962 case RPC_FC_C_CSTRING:
1963 case RPC_FC_C_WSTRING:
1964 if (fc == RPC_FC_C_CSTRING)
1966 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1967 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1971 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1972 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1974 if (pFormat[1] == RPC_FC_STRING_SIZED)
1975 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1977 pStubMsg->MaxCount = pStubMsg->ActualCount;
1978 pStubMsg->Offset = 0;
1979 WriteConformance(pStubMsg);
1981 case RPC_FC_BOGUS_ARRAY:
1982 def = *(const WORD *)(pFormat + 2);
1984 conformance_present = IsConformanceOrVariancePresent(pFormat);
1985 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
1986 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
1987 if (conformance_present) WriteConformance(pStubMsg);
1990 ERR("unknown array format 0x%x\n", fc);
1991 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1995 static inline void array_write_variance_and_marshall(
1996 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1997 PFORMAT_STRING pFormat, unsigned char fHasPointers)
2001 unsigned char alignment;
2006 esize = *(const WORD*)(pFormat+2);
2007 alignment = pFormat[1] + 1;
2009 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2011 align_pointer_clear(&pStubMsg->Buffer, alignment);
2013 size = safe_multiply(esize, pStubMsg->MaxCount);
2015 pStubMsg->BufferMark = pStubMsg->Buffer;
2016 safe_copy_to_buffer(pStubMsg, pMemory, size);
2019 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2021 case RPC_FC_CVARRAY:
2022 esize = *(const WORD*)(pFormat+2);
2023 alignment = pFormat[1] + 1;
2025 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2026 pFormat = SkipVariance(pStubMsg, pFormat);
2028 WriteVariance(pStubMsg);
2030 align_pointer_clear(&pStubMsg->Buffer, alignment);
2032 size = safe_multiply(esize, pStubMsg->ActualCount);
2035 pStubMsg->BufferMark = pStubMsg->Buffer;
2036 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size);
2039 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2041 case RPC_FC_C_CSTRING:
2042 case RPC_FC_C_WSTRING:
2043 if (fc == RPC_FC_C_CSTRING)
2048 WriteVariance(pStubMsg);
2050 size = safe_multiply(esize, pStubMsg->ActualCount);
2051 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2053 case RPC_FC_BOGUS_ARRAY:
2054 alignment = pFormat[1] + 1;
2055 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2056 if (IsConformanceOrVariancePresent(pFormat)) WriteVariance(pStubMsg);
2057 pFormat = SkipVariance(pStubMsg, pFormat);
2059 align_pointer_clear(&pStubMsg->Buffer, alignment);
2061 size = pStubMsg->ActualCount;
2062 for (i = 0; i < size; i++)
2063 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2066 ERR("unknown array format 0x%x\n", fc);
2067 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2071 static inline ULONG array_read_conformance(
2072 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
2079 esize = *(const WORD*)(pFormat+2);
2080 pFormat = ReadConformance(pStubMsg, pFormat+4);
2081 return safe_multiply(esize, pStubMsg->MaxCount);
2082 case RPC_FC_CVARRAY:
2083 esize = *(const WORD*)(pFormat+2);
2084 pFormat = ReadConformance(pStubMsg, pFormat+4);
2085 return safe_multiply(esize, pStubMsg->MaxCount);
2086 case RPC_FC_C_CSTRING:
2087 case RPC_FC_C_WSTRING:
2088 if (fc == RPC_FC_C_CSTRING)
2093 if (pFormat[1] == RPC_FC_STRING_SIZED)
2094 ReadConformance(pStubMsg, pFormat + 2);
2096 ReadConformance(pStubMsg, NULL);
2097 return safe_multiply(esize, pStubMsg->MaxCount);
2098 case RPC_FC_BOGUS_ARRAY:
2099 def = *(const WORD *)(pFormat + 2);
2101 if (IsConformanceOrVariancePresent(pFormat)) pFormat = ReadConformance(pStubMsg, pFormat);
2104 pStubMsg->MaxCount = def;
2105 pFormat = SkipConformance( pStubMsg, pFormat );
2107 pFormat = SkipVariance( pStubMsg, pFormat );
2109 esize = ComplexStructSize(pStubMsg, pFormat);
2110 return safe_multiply(pStubMsg->MaxCount, esize);
2112 ERR("unknown array format 0x%x\n", fc);
2113 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2117 static inline ULONG array_read_variance_and_unmarshall(
2118 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory,
2119 PFORMAT_STRING pFormat, unsigned char fMustAlloc,
2120 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall)
2122 ULONG bufsize, memsize;
2124 unsigned char alignment;
2125 unsigned char *saved_buffer, *pMemory;
2126 ULONG i, offset, count;
2131 esize = *(const WORD*)(pFormat+2);
2132 alignment = pFormat[1] + 1;
2134 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2136 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2138 align_pointer(&pStubMsg->Buffer, alignment);
2143 *ppMemory = NdrAllocate(pStubMsg, memsize);
2146 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory)
2147 /* for servers, we just point straight into the RPC buffer */
2148 *ppMemory = pStubMsg->Buffer;
2151 saved_buffer = pStubMsg->Buffer;
2152 safe_buffer_increment(pStubMsg, bufsize);
2154 pStubMsg->BufferMark = saved_buffer;
2155 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2157 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2158 if (*ppMemory != saved_buffer)
2159 memcpy(*ppMemory, saved_buffer, bufsize);
2162 case RPC_FC_CVARRAY:
2163 esize = *(const WORD*)(pFormat+2);
2164 alignment = pFormat[1] + 1;
2166 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2168 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2170 align_pointer(&pStubMsg->Buffer, alignment);
2172 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2173 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2177 offset = pStubMsg->Offset;
2179 if (!fMustAlloc && !*ppMemory)
2182 *ppMemory = NdrAllocate(pStubMsg, memsize);
2183 saved_buffer = pStubMsg->Buffer;
2184 safe_buffer_increment(pStubMsg, bufsize);
2186 pStubMsg->BufferMark = saved_buffer;
2187 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat,
2190 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2193 case RPC_FC_C_CSTRING:
2194 case RPC_FC_C_WSTRING:
2195 if (fc == RPC_FC_C_CSTRING)
2200 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2202 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2204 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2205 pStubMsg->ActualCount, pStubMsg->MaxCount);
2206 RpcRaiseException(RPC_S_INVALID_BOUND);
2208 if (pStubMsg->Offset)
2210 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2211 RpcRaiseException(RPC_S_INVALID_BOUND);
2214 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2215 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2217 validate_string_data(pStubMsg, bufsize, esize);
2222 *ppMemory = NdrAllocate(pStubMsg, memsize);
2225 if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
2226 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
2227 /* if the data in the RPC buffer is big enough, we just point
2228 * straight into it */
2229 *ppMemory = pStubMsg->Buffer;
2230 else if (!*ppMemory)
2231 *ppMemory = NdrAllocate(pStubMsg, memsize);
2234 if (*ppMemory == pStubMsg->Buffer)
2235 safe_buffer_increment(pStubMsg, bufsize);
2237 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2239 if (*pFormat == RPC_FC_C_CSTRING)
2240 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
2242 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
2246 case RPC_FC_BOGUS_ARRAY:
2247 alignment = pFormat[1] + 1;
2248 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2249 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2251 esize = ComplexStructSize(pStubMsg, pFormat);
2252 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2254 assert( fUnmarshall );
2256 if (!fMustAlloc && !*ppMemory)
2259 *ppMemory = NdrAllocate(pStubMsg, memsize);
2261 align_pointer(&pStubMsg->Buffer, alignment);
2262 saved_buffer = pStubMsg->Buffer;
2264 pMemory = *ppMemory;
2265 count = pStubMsg->ActualCount;
2266 for (i = 0; i < count; i++)
2267 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
2268 return pStubMsg->Buffer - saved_buffer;
2271 ERR("unknown array format 0x%x\n", fc);
2272 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2276 static inline void array_memory_size(
2277 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
2278 unsigned char fHasPointers)
2280 ULONG i, count, SavedMemorySize;
2281 ULONG bufsize, memsize;
2283 unsigned char alignment;
2288 esize = *(const WORD*)(pFormat+2);
2289 alignment = pFormat[1] + 1;
2291 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2293 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2294 pStubMsg->MemorySize += memsize;
2296 align_pointer(&pStubMsg->Buffer, alignment);
2298 pStubMsg->BufferMark = pStubMsg->Buffer;
2299 safe_buffer_increment(pStubMsg, bufsize);
2302 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2304 case RPC_FC_CVARRAY:
2305 esize = *(const WORD*)(pFormat+2);
2306 alignment = pFormat[1] + 1;
2308 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2310 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2312 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2313 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2314 pStubMsg->MemorySize += memsize;
2316 align_pointer(&pStubMsg->Buffer, alignment);
2318 pStubMsg->BufferMark = pStubMsg->Buffer;
2319 safe_buffer_increment(pStubMsg, bufsize);
2322 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2324 case RPC_FC_C_CSTRING:
2325 case RPC_FC_C_WSTRING:
2326 if (fc == RPC_FC_C_CSTRING)
2331 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2333 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2335 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2336 pStubMsg->ActualCount, pStubMsg->MaxCount);
2337 RpcRaiseException(RPC_S_INVALID_BOUND);
2339 if (pStubMsg->Offset)
2341 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2342 RpcRaiseException(RPC_S_INVALID_BOUND);
2345 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2346 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2348 validate_string_data(pStubMsg, bufsize, esize);
2350 safe_buffer_increment(pStubMsg, bufsize);
2351 pStubMsg->MemorySize += memsize;
2353 case RPC_FC_BOGUS_ARRAY:
2354 alignment = pFormat[1] + 1;
2355 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2356 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2358 align_pointer(&pStubMsg->Buffer, alignment);
2360 SavedMemorySize = pStubMsg->MemorySize;
2362 esize = ComplexStructSize(pStubMsg, pFormat);
2363 memsize = safe_multiply(pStubMsg->MaxCount, esize);
2365 count = pStubMsg->ActualCount;
2366 for (i = 0; i < count; i++)
2367 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
2369 pStubMsg->MemorySize = SavedMemorySize + memsize;
2372 ERR("unknown array format 0x%x\n", fc);
2373 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2377 static inline void array_free(
2378 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
2379 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
2386 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2388 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2390 case RPC_FC_CVARRAY:
2391 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2392 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2394 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2396 case RPC_FC_C_CSTRING:
2397 case RPC_FC_C_WSTRING:
2398 /* No embedded pointers so nothing to do */
2400 case RPC_FC_BOGUS_ARRAY:
2401 count = *(const WORD *)(pFormat + 2);
2402 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, count);
2403 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2405 count = pStubMsg->ActualCount;
2406 for (i = 0; i < count; i++)
2407 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2410 ERR("unknown array format 0x%x\n", fc);
2411 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2416 * NdrConformantString:
2418 * What MS calls a ConformantString is, in DCE terminology,
2419 * a Varying-Conformant String.
2421 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2422 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2423 * into unmarshalled string)
2424 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2426 * data: CHARTYPE[maxlen]
2428 * ], where CHARTYPE is the appropriate character type (specified externally)
2432 /***********************************************************************
2433 * NdrConformantStringMarshall [RPCRT4.@]
2435 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
2436 unsigned char *pszMessage, PFORMAT_STRING pFormat)
2438 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
2440 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2441 ERR("Unhandled string type: %#x\n", pFormat[0]);
2442 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2445 /* allow compiler to optimise inline function by passing constant into
2446 * these functions */
2447 if (pFormat[0] == RPC_FC_C_CSTRING) {
2448 array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2450 array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2451 pFormat, TRUE /* fHasPointers */);
2453 array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2455 array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2456 pFormat, TRUE /* fHasPointers */);
2462 /***********************************************************************
2463 * NdrConformantStringBufferSize [RPCRT4.@]
2465 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2466 unsigned char* pMemory, PFORMAT_STRING pFormat)
2468 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2470 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2471 ERR("Unhandled string type: %#x\n", pFormat[0]);
2472 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2475 /* allow compiler to optimise inline function by passing constant into
2476 * these functions */
2477 if (pFormat[0] == RPC_FC_C_CSTRING) {
2478 array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory,
2480 array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat,
2481 TRUE /* fHasPointers */);
2483 array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory,
2485 array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat,
2486 TRUE /* fHasPointers */);
2490 /************************************************************************
2491 * NdrConformantStringMemorySize [RPCRT4.@]
2493 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2494 PFORMAT_STRING pFormat )
2496 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2498 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2499 ERR("Unhandled string type: %#x\n", pFormat[0]);
2500 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2503 /* allow compiler to optimise inline function by passing constant into
2504 * these functions */
2505 if (pFormat[0] == RPC_FC_C_CSTRING) {
2506 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2507 array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat,
2508 TRUE /* fHasPointers */);
2510 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2511 array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat,
2512 TRUE /* fHasPointers */);
2515 return pStubMsg->MemorySize;
2518 /************************************************************************
2519 * NdrConformantStringUnmarshall [RPCRT4.@]
2521 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2522 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
2524 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2525 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2527 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2528 ERR("Unhandled string type: %#x\n", *pFormat);
2529 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2532 /* allow compiler to optimise inline function by passing constant into
2533 * these functions */
2534 if (pFormat[0] == RPC_FC_C_CSTRING) {
2535 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2536 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory,
2537 pFormat, fMustAlloc,
2538 TRUE /* fUseBufferMemoryServer */,
2539 TRUE /* fUnmarshall */);
2541 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2542 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory,
2543 pFormat, fMustAlloc,
2544 TRUE /* fUseBufferMemoryServer */,
2545 TRUE /* fUnmarshall */);
2551 /***********************************************************************
2552 * NdrNonConformantStringMarshall [RPCRT4.@]
2554 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2555 unsigned char *pMemory,
2556 PFORMAT_STRING pFormat)
2558 ULONG esize, size, maxsize;
2560 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2562 maxsize = *(const USHORT *)&pFormat[2];
2564 if (*pFormat == RPC_FC_CSTRING)
2567 const char *str = (const char *)pMemory;
2568 while (i < maxsize && str[i]) i++;
2569 TRACE("string=%s\n", debugstr_an(str, i));
2570 pStubMsg->ActualCount = i + 1;
2573 else if (*pFormat == RPC_FC_WSTRING)
2576 const WCHAR *str = (const WCHAR *)pMemory;
2577 while (i < maxsize && str[i]) i++;
2578 TRACE("string=%s\n", debugstr_wn(str, i));
2579 pStubMsg->ActualCount = i + 1;
2584 ERR("Unhandled string type: %#x\n", *pFormat);
2585 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2588 pStubMsg->Offset = 0;
2589 WriteVariance(pStubMsg);
2591 size = safe_multiply(esize, pStubMsg->ActualCount);
2592 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2597 /***********************************************************************
2598 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2600 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2601 unsigned char **ppMemory,
2602 PFORMAT_STRING pFormat,
2603 unsigned char fMustAlloc)
2605 ULONG bufsize, memsize, esize, maxsize;
2607 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2608 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2610 maxsize = *(const USHORT *)&pFormat[2];
2612 ReadVariance(pStubMsg, NULL, maxsize);
2613 if (pStubMsg->Offset)
2615 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2616 RpcRaiseException(RPC_S_INVALID_BOUND);
2619 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2620 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2623 ERR("Unhandled string type: %#x\n", *pFormat);
2624 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2627 memsize = esize * maxsize;
2628 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2630 validate_string_data(pStubMsg, bufsize, esize);
2632 if (!fMustAlloc && !*ppMemory)
2635 *ppMemory = NdrAllocate(pStubMsg, memsize);
2637 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2639 if (*pFormat == RPC_FC_CSTRING) {
2640 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
2642 else if (*pFormat == RPC_FC_WSTRING) {
2643 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
2649 /***********************************************************************
2650 * NdrNonConformantStringBufferSize [RPCRT4.@]
2652 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2653 unsigned char *pMemory,
2654 PFORMAT_STRING pFormat)
2656 ULONG esize, maxsize;
2658 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2660 maxsize = *(const USHORT *)&pFormat[2];
2662 SizeVariance(pStubMsg);
2664 if (*pFormat == RPC_FC_CSTRING)
2667 const char *str = (const char *)pMemory;
2668 while (i < maxsize && str[i]) i++;
2669 TRACE("string=%s\n", debugstr_an(str, i));
2670 pStubMsg->ActualCount = i + 1;
2673 else if (*pFormat == RPC_FC_WSTRING)
2676 const WCHAR *str = (const WCHAR *)pMemory;
2677 while (i < maxsize && str[i]) i++;
2678 TRACE("string=%s\n", debugstr_wn(str, i));
2679 pStubMsg->ActualCount = i + 1;
2684 ERR("Unhandled string type: %#x\n", *pFormat);
2685 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2688 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2691 /***********************************************************************
2692 * NdrNonConformantStringMemorySize [RPCRT4.@]
2694 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2695 PFORMAT_STRING pFormat)
2697 ULONG bufsize, memsize, esize, maxsize;
2699 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2701 maxsize = *(const USHORT *)&pFormat[2];
2703 ReadVariance(pStubMsg, NULL, maxsize);
2705 if (pStubMsg->Offset)
2707 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2708 RpcRaiseException(RPC_S_INVALID_BOUND);
2711 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2712 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2715 ERR("Unhandled string type: %#x\n", *pFormat);
2716 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2719 memsize = esize * maxsize;
2720 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2722 validate_string_data(pStubMsg, bufsize, esize);
2724 safe_buffer_increment(pStubMsg, bufsize);
2725 pStubMsg->MemorySize += memsize;
2727 return pStubMsg->MemorySize;
2732 #include "pshpack1.h"
2736 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2740 #include "poppack.h"
2742 static ULONG EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2743 PFORMAT_STRING pFormat)
2747 case RPC_FC_PSTRUCT:
2748 case RPC_FC_CSTRUCT:
2749 case RPC_FC_BOGUS_STRUCT:
2750 case RPC_FC_SMFARRAY:
2751 case RPC_FC_SMVARRAY:
2752 case RPC_FC_CSTRING:
2753 return *(const WORD*)&pFormat[2];
2754 case RPC_FC_USER_MARSHAL:
2755 return *(const WORD*)&pFormat[4];
2756 case RPC_FC_RANGE: {
2757 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2762 return sizeof(UCHAR);
2766 return sizeof(USHORT);
2770 case RPC_FC_INT3264:
2771 case RPC_FC_UINT3264:
2772 return sizeof(ULONG);
2774 return sizeof(float);
2776 return sizeof(double);
2778 return sizeof(ULONGLONG);
2780 return sizeof(UINT);
2782 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2783 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2786 case RPC_FC_NON_ENCAPSULATED_UNION:
2788 if (pStubMsg->fHasNewCorrDesc)
2793 pFormat += *(const SHORT*)pFormat;
2794 return *(const SHORT*)pFormat;
2796 return sizeof(void *);
2797 case RPC_FC_WSTRING:
2798 return *(const WORD*)&pFormat[2] * 2;
2800 FIXME("unhandled embedded type %02x\n", *pFormat);
2806 static ULONG EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2807 PFORMAT_STRING pFormat)
2809 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2813 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2817 return m(pStubMsg, pFormat);
2821 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2822 unsigned char *pMemory,
2823 PFORMAT_STRING pFormat,
2824 PFORMAT_STRING pPointer)
2826 PFORMAT_STRING desc;
2830 while (*pFormat != RPC_FC_END) {
2836 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2837 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2843 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2844 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2849 USHORT val = *(DWORD *)pMemory;
2850 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2851 if (32767 < *(DWORD*)pMemory)
2852 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2853 safe_copy_to_buffer(pStubMsg, &val, 2);
2860 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2861 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2864 case RPC_FC_INT3264:
2865 case RPC_FC_UINT3264:
2867 UINT val = *(UINT_PTR *)pMemory;
2868 TRACE("int3264=%ld <= %p\n", *(UINT_PTR *)pMemory, pMemory);
2869 safe_copy_to_buffer(pStubMsg, &val, sizeof(UINT));
2870 pMemory += sizeof(UINT_PTR);
2874 TRACE("float=%f <= %p\n", *(float*)pMemory, pMemory);
2875 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
2876 pMemory += sizeof(float);
2879 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2880 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2884 TRACE("double=%f <= %p\n", *(double*)pMemory, pMemory);
2885 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
2886 pMemory += sizeof(double);
2892 case RPC_FC_POINTER:
2894 unsigned char *saved_buffer;
2895 int pointer_buffer_mark_set = 0;
2896 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2897 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2898 if (*pFormat != RPC_FC_POINTER)
2900 if (*pPointer != RPC_FC_RP)
2901 align_pointer_clear(&pStubMsg->Buffer, 4);
2902 saved_buffer = pStubMsg->Buffer;
2903 if (pStubMsg->PointerBufferMark)
2905 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2906 pStubMsg->PointerBufferMark = NULL;
2907 pointer_buffer_mark_set = 1;
2909 else if (*pPointer != RPC_FC_RP)
2910 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2911 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2912 if (pointer_buffer_mark_set)
2914 STD_OVERFLOW_CHECK(pStubMsg);
2915 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2916 pStubMsg->Buffer = saved_buffer;
2917 if (*pPointer != RPC_FC_RP)
2918 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2920 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2921 if (*pFormat == RPC_FC_POINTER)
2925 pMemory += sizeof(void *);
2928 case RPC_FC_ALIGNM2:
2929 align_pointer(&pMemory, 2);
2931 case RPC_FC_ALIGNM4:
2932 align_pointer(&pMemory, 4);
2934 case RPC_FC_ALIGNM8:
2935 align_pointer(&pMemory, 8);
2937 case RPC_FC_STRUCTPAD1:
2938 case RPC_FC_STRUCTPAD2:
2939 case RPC_FC_STRUCTPAD3:
2940 case RPC_FC_STRUCTPAD4:
2941 case RPC_FC_STRUCTPAD5:
2942 case RPC_FC_STRUCTPAD6:
2943 case RPC_FC_STRUCTPAD7:
2944 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2946 case RPC_FC_EMBEDDED_COMPLEX:
2947 pMemory += pFormat[1];
2949 desc = pFormat + *(const SHORT*)pFormat;
2950 size = EmbeddedComplexSize(pStubMsg, desc);
2951 TRACE("embedded complex (size=%d) <= %p\n", size, pMemory);
2952 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2955 /* for some reason interface pointers aren't generated as
2956 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2957 * they still need the derefencing treatment that pointers are
2959 if (*desc == RPC_FC_IP)
2960 m(pStubMsg, *(unsigned char **)pMemory, desc);
2962 m(pStubMsg, pMemory, desc);
2964 else FIXME("no marshaller for embedded type %02x\n", *desc);
2971 FIXME("unhandled format 0x%02x\n", *pFormat);
2979 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2980 unsigned char *pMemory,
2981 PFORMAT_STRING pFormat,
2982 PFORMAT_STRING pPointer,
2983 unsigned char fMustAlloc)
2985 PFORMAT_STRING desc;
2989 while (*pFormat != RPC_FC_END) {
2995 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2996 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
3002 safe_copy_from_buffer(pStubMsg, pMemory, 2);
3003 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
3009 safe_copy_from_buffer(pStubMsg, &val, 2);
3010 *(DWORD*)pMemory = val;
3011 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
3012 if (32767 < *(DWORD*)pMemory)
3013 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
3020 safe_copy_from_buffer(pStubMsg, pMemory, 4);
3021 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
3024 case RPC_FC_INT3264:
3027 safe_copy_from_buffer(pStubMsg, &val, 4);
3028 *(INT_PTR *)pMemory = val;
3029 TRACE("int3264=%ld => %p\n", *(INT_PTR*)pMemory, pMemory);
3030 pMemory += sizeof(INT_PTR);
3033 case RPC_FC_UINT3264:
3036 safe_copy_from_buffer(pStubMsg, &val, 4);
3037 *(UINT_PTR *)pMemory = val;
3038 TRACE("uint3264=%ld => %p\n", *(UINT_PTR*)pMemory, pMemory);
3039 pMemory += sizeof(UINT_PTR);
3043 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(float));
3044 TRACE("float=%f => %p\n", *(float*)pMemory, pMemory);
3045 pMemory += sizeof(float);
3048 safe_copy_from_buffer(pStubMsg, pMemory, 8);
3049 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
3053 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(double));
3054 TRACE("double=%f => %p\n", *(double*)pMemory, pMemory);
3055 pMemory += sizeof(double);
3061 case RPC_FC_POINTER:
3063 unsigned char *saved_buffer;
3064 int pointer_buffer_mark_set = 0;
3065 TRACE("pointer => %p\n", pMemory);
3066 if (*pFormat != RPC_FC_POINTER)
3068 if (*pPointer != RPC_FC_RP)
3069 align_pointer(&pStubMsg->Buffer, 4);
3070 saved_buffer = pStubMsg->Buffer;
3071 if (pStubMsg->PointerBufferMark)
3073 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3074 pStubMsg->PointerBufferMark = NULL;
3075 pointer_buffer_mark_set = 1;
3077 else if (*pPointer != RPC_FC_RP)
3078 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3080 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
3081 if (pointer_buffer_mark_set)
3083 STD_OVERFLOW_CHECK(pStubMsg);
3084 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3085 pStubMsg->Buffer = saved_buffer;
3086 if (*pPointer != RPC_FC_RP)
3087 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3089 if (*pFormat == RPC_FC_POINTER)
3093 pMemory += sizeof(void *);
3096 case RPC_FC_ALIGNM2:
3097 align_pointer_clear(&pMemory, 2);
3099 case RPC_FC_ALIGNM4:
3100 align_pointer_clear(&pMemory, 4);
3102 case RPC_FC_ALIGNM8:
3103 align_pointer_clear(&pMemory, 8);
3105 case RPC_FC_STRUCTPAD1:
3106 case RPC_FC_STRUCTPAD2:
3107 case RPC_FC_STRUCTPAD3:
3108 case RPC_FC_STRUCTPAD4:
3109 case RPC_FC_STRUCTPAD5:
3110 case RPC_FC_STRUCTPAD6:
3111 case RPC_FC_STRUCTPAD7:
3112 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
3113 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3115 case RPC_FC_EMBEDDED_COMPLEX:
3116 pMemory += pFormat[1];
3118 desc = pFormat + *(const SHORT*)pFormat;
3119 size = EmbeddedComplexSize(pStubMsg, desc);
3120 TRACE("embedded complex (size=%d) => %p\n", size, pMemory);
3122 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
3123 * since the type is part of the memory block that is encompassed by
3124 * the whole complex type. Memory is forced to allocate when pointers
3125 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
3126 * clearing the memory we pass in to the unmarshaller */
3127 memset(pMemory, 0, size);
3128 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
3131 /* for some reason interface pointers aren't generated as
3132 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3133 * they still need the derefencing treatment that pointers are
3135 if (*desc == RPC_FC_IP)
3136 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
3138 m(pStubMsg, &pMemory, desc, FALSE);
3140 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
3147 FIXME("unhandled format %d\n", *pFormat);
3155 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3156 unsigned char *pMemory,
3157 PFORMAT_STRING pFormat,
3158 PFORMAT_STRING pPointer)
3160 PFORMAT_STRING desc;
3164 while (*pFormat != RPC_FC_END) {
3170 safe_buffer_length_increment(pStubMsg, 1);
3176 safe_buffer_length_increment(pStubMsg, 2);
3180 safe_buffer_length_increment(pStubMsg, 2);
3187 safe_buffer_length_increment(pStubMsg, 4);
3190 case RPC_FC_INT3264:
3191 case RPC_FC_UINT3264:
3192 safe_buffer_length_increment(pStubMsg, 4);
3193 pMemory += sizeof(INT_PTR);
3197 safe_buffer_length_increment(pStubMsg, 8);
3204 case RPC_FC_POINTER:
3205 if (*pFormat != RPC_FC_POINTER)
3207 if (!pStubMsg->IgnoreEmbeddedPointers)
3209 int saved_buffer_length = pStubMsg->BufferLength;
3210 pStubMsg->BufferLength = pStubMsg->PointerLength;
3211 pStubMsg->PointerLength = 0;
3212 if(!pStubMsg->BufferLength)
3213 ERR("BufferLength == 0??\n");
3214 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
3215 pStubMsg->PointerLength = pStubMsg->BufferLength;
3216 pStubMsg->BufferLength = saved_buffer_length;
3218 if (*pPointer != RPC_FC_RP)
3220 align_length(&pStubMsg->BufferLength, 4);
3221 safe_buffer_length_increment(pStubMsg, 4);
3223 if (*pFormat == RPC_FC_POINTER)
3227 pMemory += sizeof(void*);
3229 case RPC_FC_ALIGNM2:
3230 align_pointer(&pMemory, 2);
3232 case RPC_FC_ALIGNM4:
3233 align_pointer(&pMemory, 4);
3235 case RPC_FC_ALIGNM8:
3236 align_pointer(&pMemory, 8);
3238 case RPC_FC_STRUCTPAD1:
3239 case RPC_FC_STRUCTPAD2:
3240 case RPC_FC_STRUCTPAD3:
3241 case RPC_FC_STRUCTPAD4:
3242 case RPC_FC_STRUCTPAD5:
3243 case RPC_FC_STRUCTPAD6:
3244 case RPC_FC_STRUCTPAD7:
3245 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3247 case RPC_FC_EMBEDDED_COMPLEX:
3248 pMemory += pFormat[1];
3250 desc = pFormat + *(const SHORT*)pFormat;
3251 size = EmbeddedComplexSize(pStubMsg, desc);
3252 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
3255 /* for some reason interface pointers aren't generated as
3256 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3257 * they still need the derefencing treatment that pointers are
3259 if (*desc == RPC_FC_IP)
3260 m(pStubMsg, *(unsigned char **)pMemory, desc);
3262 m(pStubMsg, pMemory, desc);
3264 else FIXME("no buffersizer for embedded type %02x\n", *desc);
3271 FIXME("unhandled format 0x%02x\n", *pFormat);
3279 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
3280 unsigned char *pMemory,
3281 PFORMAT_STRING pFormat,
3282 PFORMAT_STRING pPointer)
3284 PFORMAT_STRING desc;
3288 while (*pFormat != RPC_FC_END) {
3308 case RPC_FC_INT3264:
3309 case RPC_FC_UINT3264:
3310 pMemory += sizeof(INT_PTR);
3320 case RPC_FC_POINTER:
3321 if (*pFormat != RPC_FC_POINTER)
3323 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3324 if (*pFormat == RPC_FC_POINTER)
3328 pMemory += sizeof(void *);
3330 case RPC_FC_ALIGNM2:
3331 align_pointer(&pMemory, 2);
3333 case RPC_FC_ALIGNM4:
3334 align_pointer(&pMemory, 4);
3336 case RPC_FC_ALIGNM8:
3337 align_pointer(&pMemory, 8);
3339 case RPC_FC_STRUCTPAD1:
3340 case RPC_FC_STRUCTPAD2:
3341 case RPC_FC_STRUCTPAD3:
3342 case RPC_FC_STRUCTPAD4:
3343 case RPC_FC_STRUCTPAD5:
3344 case RPC_FC_STRUCTPAD6:
3345 case RPC_FC_STRUCTPAD7:
3346 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3348 case RPC_FC_EMBEDDED_COMPLEX:
3349 pMemory += pFormat[1];
3351 desc = pFormat + *(const SHORT*)pFormat;
3352 size = EmbeddedComplexSize(pStubMsg, desc);
3353 m = NdrFreer[*desc & NDR_TABLE_MASK];
3356 /* for some reason interface pointers aren't generated as
3357 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3358 * they still need the derefencing treatment that pointers are
3360 if (*desc == RPC_FC_IP)
3361 m(pStubMsg, *(unsigned char **)pMemory, desc);
3363 m(pStubMsg, pMemory, desc);
3371 FIXME("unhandled format 0x%02x\n", *pFormat);
3379 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3380 PFORMAT_STRING pFormat,
3381 PFORMAT_STRING pPointer)
3383 PFORMAT_STRING desc;
3386 while (*pFormat != RPC_FC_END) {
3393 safe_buffer_increment(pStubMsg, 1);
3399 safe_buffer_increment(pStubMsg, 2);
3403 safe_buffer_increment(pStubMsg, 2);
3410 safe_buffer_increment(pStubMsg, 4);
3412 case RPC_FC_INT3264:
3413 case RPC_FC_UINT3264:
3414 size += sizeof(INT_PTR);
3415 safe_buffer_increment(pStubMsg, 4);
3420 safe_buffer_increment(pStubMsg, 8);
3426 case RPC_FC_POINTER:
3428 unsigned char *saved_buffer;
3429 int pointer_buffer_mark_set = 0;
3430 if (*pFormat != RPC_FC_POINTER)
3432 if (*pPointer != RPC_FC_RP)
3433 align_pointer(&pStubMsg->Buffer, 4);
3434 saved_buffer = pStubMsg->Buffer;
3435 if (pStubMsg->PointerBufferMark)
3437 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3438 pStubMsg->PointerBufferMark = NULL;
3439 pointer_buffer_mark_set = 1;
3441 else if (*pPointer != RPC_FC_RP)
3442 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3444 if (!pStubMsg->IgnoreEmbeddedPointers)
3445 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3446 if (pointer_buffer_mark_set)
3448 STD_OVERFLOW_CHECK(pStubMsg);
3449 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3450 pStubMsg->Buffer = saved_buffer;
3451 if (*pPointer != RPC_FC_RP)
3452 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3454 if (*pFormat == RPC_FC_POINTER)
3458 size += sizeof(void *);
3461 case RPC_FC_ALIGNM2:
3462 align_length(&size, 2);
3464 case RPC_FC_ALIGNM4:
3465 align_length(&size, 4);
3467 case RPC_FC_ALIGNM8:
3468 align_length(&size, 8);
3470 case RPC_FC_STRUCTPAD1:
3471 case RPC_FC_STRUCTPAD2:
3472 case RPC_FC_STRUCTPAD3:
3473 case RPC_FC_STRUCTPAD4:
3474 case RPC_FC_STRUCTPAD5:
3475 case RPC_FC_STRUCTPAD6:
3476 case RPC_FC_STRUCTPAD7:
3477 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3479 case RPC_FC_EMBEDDED_COMPLEX:
3482 desc = pFormat + *(const SHORT*)pFormat;
3483 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3489 FIXME("unhandled format 0x%02x\n", *pFormat);
3497 ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
3499 PFORMAT_STRING desc;
3502 while (*pFormat != RPC_FC_END) {
3522 case RPC_FC_INT3264:
3523 case RPC_FC_UINT3264:
3524 size += sizeof(INT_PTR);
3534 case RPC_FC_POINTER:
3535 size += sizeof(void *);
3536 if (*pFormat != RPC_FC_POINTER)
3539 case RPC_FC_ALIGNM2:
3540 align_length(&size, 2);
3542 case RPC_FC_ALIGNM4:
3543 align_length(&size, 4);
3545 case RPC_FC_ALIGNM8:
3546 align_length(&size, 8);
3548 case RPC_FC_STRUCTPAD1:
3549 case RPC_FC_STRUCTPAD2:
3550 case RPC_FC_STRUCTPAD3:
3551 case RPC_FC_STRUCTPAD4:
3552 case RPC_FC_STRUCTPAD5:
3553 case RPC_FC_STRUCTPAD6:
3554 case RPC_FC_STRUCTPAD7:
3555 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3557 case RPC_FC_EMBEDDED_COMPLEX:
3560 desc = pFormat + *(const SHORT*)pFormat;
3561 size += EmbeddedComplexSize(pStubMsg, desc);
3567 FIXME("unhandled format 0x%02x\n", *pFormat);
3575 /***********************************************************************
3576 * NdrComplexStructMarshall [RPCRT4.@]
3578 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3579 unsigned char *pMemory,
3580 PFORMAT_STRING pFormat)
3582 PFORMAT_STRING conf_array = NULL;
3583 PFORMAT_STRING pointer_desc = NULL;
3584 unsigned char *OldMemory = pStubMsg->Memory;
3585 int pointer_buffer_mark_set = 0;
3587 ULONG max_count = 0;
3590 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3592 if (!pStubMsg->PointerBufferMark)
3594 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3595 /* save buffer length */
3596 ULONG saved_buffer_length = pStubMsg->BufferLength;
3598 /* get the buffer pointer after complex array data, but before
3600 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3601 pStubMsg->IgnoreEmbeddedPointers = 1;
3602 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3603 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3605 /* save it for use by embedded pointer code later */
3606 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3607 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - pStubMsg->Buffer));
3608 pointer_buffer_mark_set = 1;
3610 /* restore the original buffer length */
3611 pStubMsg->BufferLength = saved_buffer_length;
3614 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1);
3617 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3619 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3622 pStubMsg->Memory = pMemory;
3626 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3627 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3628 pMemory + struct_size, conf_array);
3629 /* these could be changed in ComplexMarshall so save them for later */
3630 max_count = pStubMsg->MaxCount;
3631 count = pStubMsg->ActualCount;
3632 offset = pStubMsg->Offset;
3635 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3639 pStubMsg->MaxCount = max_count;
3640 pStubMsg->ActualCount = count;
3641 pStubMsg->Offset = offset;
3642 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3643 conf_array, TRUE /* fHasPointers */);
3646 pStubMsg->Memory = OldMemory;
3648 if (pointer_buffer_mark_set)
3650 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3651 pStubMsg->PointerBufferMark = NULL;
3654 STD_OVERFLOW_CHECK(pStubMsg);
3659 /***********************************************************************
3660 * NdrComplexStructUnmarshall [RPCRT4.@]
3662 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3663 unsigned char **ppMemory,
3664 PFORMAT_STRING pFormat,
3665 unsigned char fMustAlloc)
3667 unsigned size = *(const WORD*)(pFormat+2);
3668 PFORMAT_STRING conf_array = NULL;
3669 PFORMAT_STRING pointer_desc = NULL;
3670 unsigned char *pMemory;
3671 int pointer_buffer_mark_set = 0;
3673 ULONG max_count = 0;
3675 ULONG array_size = 0;
3677 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3679 if (!pStubMsg->PointerBufferMark)
3681 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3682 /* save buffer pointer */
3683 unsigned char *saved_buffer = pStubMsg->Buffer;
3685 /* get the buffer pointer after complex array data, but before
3687 pStubMsg->IgnoreEmbeddedPointers = 1;
3688 NdrComplexStructMemorySize(pStubMsg, pFormat);
3689 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3691 /* save it for use by embedded pointer code later */
3692 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3693 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - saved_buffer));
3694 pointer_buffer_mark_set = 1;
3696 /* restore the original buffer */
3697 pStubMsg->Buffer = saved_buffer;
3700 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3703 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3705 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3710 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3713 /* these could be changed in ComplexMarshall so save them for later */
3714 max_count = pStubMsg->MaxCount;
3715 count = pStubMsg->ActualCount;
3716 offset = pStubMsg->Offset;
3719 if (!fMustAlloc && !*ppMemory)
3722 *ppMemory = NdrAllocate(pStubMsg, size);
3724 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3728 pStubMsg->MaxCount = max_count;
3729 pStubMsg->ActualCount = count;
3730 pStubMsg->Offset = offset;
3732 memset(pMemory, 0, array_size);
3733 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3735 FALSE /* fUseBufferMemoryServer */,
3736 TRUE /* fUnmarshall */);
3739 if (pointer_buffer_mark_set)
3741 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3742 pStubMsg->PointerBufferMark = NULL;
3748 /***********************************************************************
3749 * NdrComplexStructBufferSize [RPCRT4.@]
3751 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3752 unsigned char *pMemory,
3753 PFORMAT_STRING pFormat)
3755 PFORMAT_STRING conf_array = NULL;
3756 PFORMAT_STRING pointer_desc = NULL;
3757 unsigned char *OldMemory = pStubMsg->Memory;
3758 int pointer_length_set = 0;
3760 ULONG max_count = 0;
3763 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3765 align_length(&pStubMsg->BufferLength, pFormat[1] + 1);
3767 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3769 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3770 ULONG saved_buffer_length = pStubMsg->BufferLength;
3772 /* get the buffer length after complex struct data, but before
3774 pStubMsg->IgnoreEmbeddedPointers = 1;
3775 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3776 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3778 /* save it for use by embedded pointer code later */
3779 pStubMsg->PointerLength = pStubMsg->BufferLength;
3780 pointer_length_set = 1;
3781 TRACE("difference = 0x%x\n", pStubMsg->PointerLength - saved_buffer_length);
3783 /* restore the original buffer length */
3784 pStubMsg->BufferLength = saved_buffer_length;
3788 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3790 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3793 pStubMsg->Memory = pMemory;
3797 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3798 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3801 /* these could be changed in ComplexMarshall so save them for later */
3802 max_count = pStubMsg->MaxCount;
3803 count = pStubMsg->ActualCount;
3804 offset = pStubMsg->Offset;
3807 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3811 pStubMsg->MaxCount = max_count;
3812 pStubMsg->ActualCount = count;
3813 pStubMsg->Offset = offset;
3814 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3815 TRUE /* fHasPointers */);
3818 pStubMsg->Memory = OldMemory;
3820 if(pointer_length_set)
3822 pStubMsg->BufferLength = pStubMsg->PointerLength;
3823 pStubMsg->PointerLength = 0;
3828 /***********************************************************************
3829 * NdrComplexStructMemorySize [RPCRT4.@]
3831 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3832 PFORMAT_STRING pFormat)
3834 unsigned size = *(const WORD*)(pFormat+2);
3835 PFORMAT_STRING conf_array = NULL;
3836 PFORMAT_STRING pointer_desc = NULL;
3838 ULONG max_count = 0;
3841 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3843 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3846 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3848 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3853 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3855 /* these could be changed in ComplexStructMemorySize so save them for
3857 max_count = pStubMsg->MaxCount;
3858 count = pStubMsg->ActualCount;
3859 offset = pStubMsg->Offset;
3862 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3866 pStubMsg->MaxCount = max_count;
3867 pStubMsg->ActualCount = count;
3868 pStubMsg->Offset = offset;
3869 array_memory_size(conf_array[0], pStubMsg, conf_array,
3870 TRUE /* fHasPointers */);
3876 /***********************************************************************
3877 * NdrComplexStructFree [RPCRT4.@]
3879 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3880 unsigned char *pMemory,
3881 PFORMAT_STRING pFormat)
3883 PFORMAT_STRING conf_array = NULL;
3884 PFORMAT_STRING pointer_desc = NULL;
3885 unsigned char *OldMemory = pStubMsg->Memory;
3887 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3890 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3892 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3895 pStubMsg->Memory = pMemory;
3897 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3900 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3901 TRUE /* fHasPointers */);
3903 pStubMsg->Memory = OldMemory;
3906 /***********************************************************************
3907 * NdrConformantArrayMarshall [RPCRT4.@]
3909 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3910 unsigned char *pMemory,
3911 PFORMAT_STRING pFormat)
3913 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3914 if (pFormat[0] != RPC_FC_CARRAY)
3916 ERR("invalid format = 0x%x\n", pFormat[0]);
3917 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3920 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory,
3922 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3923 TRUE /* fHasPointers */);
3928 /***********************************************************************
3929 * NdrConformantArrayUnmarshall [RPCRT4.@]
3931 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3932 unsigned char **ppMemory,
3933 PFORMAT_STRING pFormat,
3934 unsigned char fMustAlloc)
3936 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3937 if (pFormat[0] != RPC_FC_CARRAY)
3939 ERR("invalid format = 0x%x\n", pFormat[0]);
3940 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3943 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3944 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat,
3946 TRUE /* fUseBufferMemoryServer */,
3947 TRUE /* fUnmarshall */);
3952 /***********************************************************************
3953 * NdrConformantArrayBufferSize [RPCRT4.@]
3955 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3956 unsigned char *pMemory,
3957 PFORMAT_STRING pFormat)
3959 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3960 if (pFormat[0] != RPC_FC_CARRAY)
3962 ERR("invalid format = 0x%x\n", pFormat[0]);
3963 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3966 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat);
3967 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3968 TRUE /* fHasPointers */);
3971 /***********************************************************************
3972 * NdrConformantArrayMemorySize [RPCRT4.@]
3974 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3975 PFORMAT_STRING pFormat)
3977 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3978 if (pFormat[0] != RPC_FC_CARRAY)
3980 ERR("invalid format = 0x%x\n", pFormat[0]);
3981 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3984 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3985 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
3987 return pStubMsg->MemorySize;
3990 /***********************************************************************
3991 * NdrConformantArrayFree [RPCRT4.@]
3993 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3994 unsigned char *pMemory,
3995 PFORMAT_STRING pFormat)
3997 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3998 if (pFormat[0] != RPC_FC_CARRAY)
4000 ERR("invalid format = 0x%x\n", pFormat[0]);
4001 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4004 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
4005 TRUE /* fHasPointers */);
4009 /***********************************************************************
4010 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
4012 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
4013 unsigned char* pMemory,
4014 PFORMAT_STRING pFormat )
4016 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4018 if (pFormat[0] != RPC_FC_CVARRAY)
4020 ERR("invalid format type %x\n", pFormat[0]);
4021 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4025 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
4027 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory,
4028 pFormat, TRUE /* fHasPointers */);
4034 /***********************************************************************
4035 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
4037 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
4038 unsigned char** ppMemory,
4039 PFORMAT_STRING pFormat,
4040 unsigned char fMustAlloc )
4042 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4044 if (pFormat[0] != RPC_FC_CVARRAY)
4046 ERR("invalid format type %x\n", pFormat[0]);
4047 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4051 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
4052 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory,
4053 pFormat, fMustAlloc,
4054 TRUE /* fUseBufferMemoryServer */,
4055 TRUE /* fUnmarshall */);
4061 /***********************************************************************
4062 * NdrConformantVaryingArrayFree [RPCRT4.@]
4064 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
4065 unsigned char* pMemory,
4066 PFORMAT_STRING pFormat )
4068 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4070 if (pFormat[0] != RPC_FC_CVARRAY)
4072 ERR("invalid format type %x\n", pFormat[0]);
4073 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4077 array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
4078 TRUE /* fHasPointers */);
4082 /***********************************************************************
4083 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
4085 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
4086 unsigned char* pMemory, PFORMAT_STRING pFormat )
4088 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4090 if (pFormat[0] != RPC_FC_CVARRAY)
4092 ERR("invalid format type %x\n", pFormat[0]);
4093 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4097 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
4099 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
4100 TRUE /* fHasPointers */);
4104 /***********************************************************************
4105 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
4107 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
4108 PFORMAT_STRING pFormat )
4110 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4112 if (pFormat[0] != RPC_FC_CVARRAY)
4114 ERR("invalid format type %x\n", pFormat[0]);
4115 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4116 return pStubMsg->MemorySize;
4119 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
4120 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat,
4121 TRUE /* fHasPointers */);
4123 return pStubMsg->MemorySize;
4127 /***********************************************************************
4128 * NdrComplexArrayMarshall [RPCRT4.@]
4130 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4131 unsigned char *pMemory,
4132 PFORMAT_STRING pFormat)
4134 int pointer_buffer_mark_set = 0;
4136 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4138 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4140 ERR("invalid format type %x\n", pFormat[0]);
4141 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4145 if (!pStubMsg->PointerBufferMark)
4147 /* save buffer fields that may be changed by buffer sizer functions
4148 * and that may be needed later on */
4149 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4150 ULONG saved_buffer_length = pStubMsg->BufferLength;
4151 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4152 ULONG saved_offset = pStubMsg->Offset;
4153 ULONG saved_actual_count = pStubMsg->ActualCount;
4155 /* get the buffer pointer after complex array data, but before
4157 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
4158 pStubMsg->IgnoreEmbeddedPointers = 1;
4159 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4160 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4162 /* save it for use by embedded pointer code later */
4163 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
4164 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer));
4165 pointer_buffer_mark_set = 1;
4167 /* restore fields */
4168 pStubMsg->ActualCount = saved_actual_count;
4169 pStubMsg->Offset = saved_offset;
4170 pStubMsg->MaxCount = saved_max_count;
4171 pStubMsg->BufferLength = saved_buffer_length;
4174 array_compute_and_write_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4175 array_write_variance_and_marshall(RPC_FC_BOGUS_ARRAY, pStubMsg,
4176 pMemory, pFormat, TRUE /* fHasPointers */);
4178 STD_OVERFLOW_CHECK(pStubMsg);
4180 if (pointer_buffer_mark_set)
4182 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4183 pStubMsg->PointerBufferMark = NULL;
4189 /***********************************************************************
4190 * NdrComplexArrayUnmarshall [RPCRT4.@]
4192 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4193 unsigned char **ppMemory,
4194 PFORMAT_STRING pFormat,
4195 unsigned char fMustAlloc)
4197 unsigned char *saved_buffer;
4198 int pointer_buffer_mark_set = 0;
4199 int saved_ignore_embedded;
4201 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4203 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4205 ERR("invalid format type %x\n", pFormat[0]);
4206 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4210 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4211 /* save buffer pointer */
4212 saved_buffer = pStubMsg->Buffer;
4213 /* get the buffer pointer after complex array data, but before
4215 pStubMsg->IgnoreEmbeddedPointers = 1;
4216 pStubMsg->MemorySize = 0;
4217 NdrComplexArrayMemorySize(pStubMsg, pFormat);
4218 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4220 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - saved_buffer));
4221 if (!pStubMsg->PointerBufferMark)
4223 /* save it for use by embedded pointer code later */
4224 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4225 pointer_buffer_mark_set = 1;
4227 /* restore the original buffer */
4228 pStubMsg->Buffer = saved_buffer;
4230 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
4231 array_read_variance_and_unmarshall(RPC_FC_BOGUS_ARRAY, pStubMsg, ppMemory, pFormat, fMustAlloc,
4232 TRUE /* fUseBufferMemoryServer */, TRUE /* fUnmarshall */);
4234 if (pointer_buffer_mark_set)
4236 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4237 pStubMsg->PointerBufferMark = NULL;
4243 /***********************************************************************
4244 * NdrComplexArrayBufferSize [RPCRT4.@]
4246 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4247 unsigned char *pMemory,
4248 PFORMAT_STRING pFormat)
4250 int pointer_length_set = 0;
4252 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4254 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4256 ERR("invalid format type %x\n", pFormat[0]);
4257 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4261 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
4263 /* save buffer fields that may be changed by buffer sizer functions
4264 * and that may be needed later on */
4265 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4266 ULONG saved_buffer_length = pStubMsg->BufferLength;
4267 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4268 ULONG saved_offset = pStubMsg->Offset;
4269 ULONG saved_actual_count = pStubMsg->ActualCount;
4271 /* get the buffer pointer after complex array data, but before
4273 pStubMsg->IgnoreEmbeddedPointers = 1;
4274 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4275 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4277 /* save it for use by embedded pointer code later */
4278 pStubMsg->PointerLength = pStubMsg->BufferLength;
4279 pointer_length_set = 1;
4281 /* restore fields */
4282 pStubMsg->ActualCount = saved_actual_count;
4283 pStubMsg->Offset = saved_offset;
4284 pStubMsg->MaxCount = saved_max_count;
4285 pStubMsg->BufferLength = saved_buffer_length;
4288 array_compute_and_size_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4289 array_buffer_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat, TRUE /* fHasPointers */);
4291 if(pointer_length_set)
4293 pStubMsg->BufferLength = pStubMsg->PointerLength;
4294 pStubMsg->PointerLength = 0;
4298 /***********************************************************************
4299 * NdrComplexArrayMemorySize [RPCRT4.@]
4301 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4302 PFORMAT_STRING pFormat)
4304 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4306 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4308 ERR("invalid format type %x\n", pFormat[0]);
4309 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4313 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
4314 array_memory_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
4315 return pStubMsg->MemorySize;
4318 /***********************************************************************
4319 * NdrComplexArrayFree [RPCRT4.@]
4321 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4322 unsigned char *pMemory,
4323 PFORMAT_STRING pFormat)
4325 ULONG i, count, def;
4327 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4329 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4331 ERR("invalid format type %x\n", pFormat[0]);
4332 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4336 def = *(const WORD*)&pFormat[2];
4339 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4340 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4342 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4343 TRACE("variance = %d\n", pStubMsg->ActualCount);
4345 count = pStubMsg->ActualCount;
4346 for (i = 0; i < count; i++)
4347 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4350 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4351 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4352 USER_MARSHAL_CB *umcb)
4354 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4355 pStubMsg->RpcMsg->DataRepresentation);
4356 umcb->pStubMsg = pStubMsg;
4357 umcb->pReserve = NULL;
4358 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4359 umcb->CBType = cbtype;
4360 umcb->pFormat = pFormat;
4361 umcb->pTypeFormat = NULL /* FIXME */;
4364 #define USER_MARSHAL_PTR_PREFIX \
4365 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4366 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4368 /***********************************************************************
4369 * NdrUserMarshalMarshall [RPCRT4.@]
4371 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4372 unsigned char *pMemory,
4373 PFORMAT_STRING pFormat)
4375 unsigned flags = pFormat[1];
4376 unsigned index = *(const WORD*)&pFormat[2];
4377 unsigned char *saved_buffer = NULL;
4378 USER_MARSHAL_CB umcb;
4380 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4381 TRACE("index=%d\n", index);
4383 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4385 if (flags & USER_MARSHAL_POINTER)
4387 align_pointer_clear(&pStubMsg->Buffer, 4);
4388 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4389 pStubMsg->Buffer += 4;
4390 if (pStubMsg->PointerBufferMark)
4392 saved_buffer = pStubMsg->Buffer;
4393 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4394 pStubMsg->PointerBufferMark = NULL;
4396 align_pointer_clear(&pStubMsg->Buffer, 8);
4399 align_pointer_clear(&pStubMsg->Buffer, (flags & 0xf) + 1);
4402 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4403 &umcb.Flags, pStubMsg->Buffer, pMemory);
4407 STD_OVERFLOW_CHECK(pStubMsg);
4408 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4409 pStubMsg->Buffer = saved_buffer;
4412 STD_OVERFLOW_CHECK(pStubMsg);
4417 /***********************************************************************
4418 * NdrUserMarshalUnmarshall [RPCRT4.@]
4420 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4421 unsigned char **ppMemory,
4422 PFORMAT_STRING pFormat,
4423 unsigned char fMustAlloc)
4425 unsigned flags = pFormat[1];
4426 unsigned index = *(const WORD*)&pFormat[2];
4427 DWORD memsize = *(const WORD*)&pFormat[4];
4428 unsigned char *saved_buffer = NULL;
4429 USER_MARSHAL_CB umcb;
4431 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4432 TRACE("index=%d\n", index);
4434 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4436 if (flags & USER_MARSHAL_POINTER)
4438 align_pointer(&pStubMsg->Buffer, 4);
4439 /* skip pointer prefix */
4440 pStubMsg->Buffer += 4;
4441 if (pStubMsg->PointerBufferMark)
4443 saved_buffer = pStubMsg->Buffer;
4444 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4445 pStubMsg->PointerBufferMark = NULL;
4447 align_pointer(&pStubMsg->Buffer, 8);
4450 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4452 if (!fMustAlloc && !*ppMemory)
4456 *ppMemory = NdrAllocate(pStubMsg, memsize);
4457 memset(*ppMemory, 0, memsize);
4461 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4462 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4466 STD_OVERFLOW_CHECK(pStubMsg);
4467 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4468 pStubMsg->Buffer = saved_buffer;
4474 /***********************************************************************
4475 * NdrUserMarshalBufferSize [RPCRT4.@]
4477 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4478 unsigned char *pMemory,
4479 PFORMAT_STRING pFormat)
4481 unsigned flags = pFormat[1];
4482 unsigned index = *(const WORD*)&pFormat[2];
4483 DWORD bufsize = *(const WORD*)&pFormat[6];
4484 USER_MARSHAL_CB umcb;
4485 ULONG saved_buffer_length = 0;
4487 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4488 TRACE("index=%d\n", index);
4490 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4492 if (flags & USER_MARSHAL_POINTER)
4494 align_length(&pStubMsg->BufferLength, 4);
4495 /* skip pointer prefix */
4496 safe_buffer_length_increment(pStubMsg, 4);
4497 if (pStubMsg->IgnoreEmbeddedPointers)
4499 if (pStubMsg->PointerLength)
4501 saved_buffer_length = pStubMsg->BufferLength;
4502 pStubMsg->BufferLength = pStubMsg->PointerLength;
4503 pStubMsg->PointerLength = 0;
4505 align_length(&pStubMsg->BufferLength, 8);
4508 align_length(&pStubMsg->BufferLength, (flags & 0xf) + 1);
4511 TRACE("size=%d\n", bufsize);
4512 safe_buffer_length_increment(pStubMsg, bufsize);
4515 pStubMsg->BufferLength =
4516 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4517 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4519 if (saved_buffer_length)
4521 pStubMsg->PointerLength = pStubMsg->BufferLength;
4522 pStubMsg->BufferLength = saved_buffer_length;
4527 /***********************************************************************
4528 * NdrUserMarshalMemorySize [RPCRT4.@]
4530 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4531 PFORMAT_STRING pFormat)
4533 unsigned flags = pFormat[1];
4534 unsigned index = *(const WORD*)&pFormat[2];
4535 DWORD memsize = *(const WORD*)&pFormat[4];
4536 DWORD bufsize = *(const WORD*)&pFormat[6];
4538 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4539 TRACE("index=%d\n", index);
4541 pStubMsg->MemorySize += memsize;
4543 if (flags & USER_MARSHAL_POINTER)
4545 align_pointer(&pStubMsg->Buffer, 4);
4546 /* skip pointer prefix */
4547 pStubMsg->Buffer += 4;
4548 if (pStubMsg->IgnoreEmbeddedPointers)
4549 return pStubMsg->MemorySize;
4550 align_pointer(&pStubMsg->Buffer, 8);
4553 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4556 FIXME("not implemented for varying buffer size\n");
4558 pStubMsg->Buffer += bufsize;
4560 return pStubMsg->MemorySize;
4563 /***********************************************************************
4564 * NdrUserMarshalFree [RPCRT4.@]
4566 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4567 unsigned char *pMemory,
4568 PFORMAT_STRING pFormat)
4570 /* unsigned flags = pFormat[1]; */
4571 unsigned index = *(const WORD*)&pFormat[2];
4572 USER_MARSHAL_CB umcb;
4574 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4575 TRACE("index=%d\n", index);
4577 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4579 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4580 &umcb.Flags, pMemory);
4583 /***********************************************************************
4584 * NdrGetUserMarshalInfo [RPCRT4.@]
4586 RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi)
4588 USER_MARSHAL_CB *umcb = CONTAINING_RECORD(flags, USER_MARSHAL_CB, Flags);
4590 TRACE("(%p,%u,%p)\n", flags, level, umi);
4593 return RPC_S_INVALID_ARG;
4595 memset(&umi->u1.Level1, 0, sizeof(umi->u1.Level1));
4596 umi->InformationLevel = level;
4598 if (umcb->Signature != USER_MARSHAL_CB_SIGNATURE)
4599 return RPC_S_INVALID_ARG;
4601 umi->u1.Level1.pfnAllocate = umcb->pStubMsg->pfnAllocate;
4602 umi->u1.Level1.pfnFree = umcb->pStubMsg->pfnFree;
4603 umi->u1.Level1.pRpcChannelBuffer = umcb->pStubMsg->pRpcChannelBuffer;
4605 switch (umcb->CBType)
4607 case USER_MARSHAL_CB_MARSHALL:
4608 case USER_MARSHAL_CB_UNMARSHALL:
4610 RPC_MESSAGE *msg = umcb->pStubMsg->RpcMsg;
4611 unsigned char *buffer_start = msg->Buffer;
4612 unsigned char *buffer_end =
4613 (unsigned char *)msg->Buffer + msg->BufferLength;
4615 if (umcb->pStubMsg->Buffer < buffer_start ||
4616 umcb->pStubMsg->Buffer > buffer_end)
4617 return ERROR_INVALID_USER_BUFFER;
4619 umi->u1.Level1.Buffer = umcb->pStubMsg->Buffer;
4620 umi->u1.Level1.BufferSize = buffer_end - umcb->pStubMsg->Buffer;
4623 case USER_MARSHAL_CB_BUFFER_SIZE:
4624 case USER_MARSHAL_CB_FREE:
4627 WARN("unrecognised CBType %d\n", umcb->CBType);
4633 /***********************************************************************
4634 * NdrClearOutParameters [RPCRT4.@]
4636 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4637 PFORMAT_STRING pFormat,
4640 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4643 /***********************************************************************
4644 * NdrConvert [RPCRT4.@]
4646 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4648 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4649 /* FIXME: since this stub doesn't do any converting, the proper behavior
4650 is to raise an exception */
4653 /***********************************************************************
4654 * NdrConvert2 [RPCRT4.@]
4656 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4658 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4659 pStubMsg, pFormat, NumberParams);
4660 /* FIXME: since this stub doesn't do any converting, the proper behavior
4661 is to raise an exception */
4664 #include "pshpack1.h"
4665 typedef struct _NDR_CSTRUCT_FORMAT
4668 unsigned char alignment;
4669 unsigned short memory_size;
4670 short offset_to_array_description;
4671 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4672 #include "poppack.h"
4674 /***********************************************************************
4675 * NdrConformantStructMarshall [RPCRT4.@]
4677 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4678 unsigned char *pMemory,
4679 PFORMAT_STRING pFormat)
4681 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4682 PFORMAT_STRING pCArrayFormat;
4683 ULONG esize, bufsize;
4685 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4687 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4688 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4690 ERR("invalid format type %x\n", pCStructFormat->type);
4691 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4695 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4696 pCStructFormat->offset_to_array_description;
4697 if (*pCArrayFormat != RPC_FC_CARRAY)
4699 ERR("invalid array format type %x\n", pCStructFormat->type);
4700 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4703 esize = *(const WORD*)(pCArrayFormat+2);
4705 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4706 pCArrayFormat + 4, 0);
4708 WriteConformance(pStubMsg);
4710 align_pointer_clear(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4712 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4714 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4715 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4717 ERR("integer overflow of memory_size %u with bufsize %u\n",
4718 pCStructFormat->memory_size, bufsize);
4719 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4721 /* copy constant sized part of struct */
4722 pStubMsg->BufferMark = pStubMsg->Buffer;
4723 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4725 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4726 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4731 /***********************************************************************
4732 * NdrConformantStructUnmarshall [RPCRT4.@]
4734 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4735 unsigned char **ppMemory,
4736 PFORMAT_STRING pFormat,
4737 unsigned char fMustAlloc)
4739 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4740 PFORMAT_STRING pCArrayFormat;
4741 ULONG esize, bufsize;
4742 unsigned char *saved_buffer;
4744 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4746 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4747 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4749 ERR("invalid format type %x\n", pCStructFormat->type);
4750 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4753 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4754 pCStructFormat->offset_to_array_description;
4755 if (*pCArrayFormat != RPC_FC_CARRAY)
4757 ERR("invalid array format type %x\n", pCStructFormat->type);
4758 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4761 esize = *(const WORD*)(pCArrayFormat+2);
4763 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4765 align_pointer(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4767 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4769 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4770 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4772 ERR("integer overflow of memory_size %u with bufsize %u\n",
4773 pCStructFormat->memory_size, bufsize);
4774 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4779 SIZE_T size = pCStructFormat->memory_size + bufsize;
4780 *ppMemory = NdrAllocate(pStubMsg, size);
4784 if (!pStubMsg->IsClient && !*ppMemory)
4785 /* for servers, we just point straight into the RPC buffer */
4786 *ppMemory = pStubMsg->Buffer;
4789 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4790 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4791 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4792 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4794 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4795 if (*ppMemory != saved_buffer)
4796 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4801 /***********************************************************************
4802 * NdrConformantStructBufferSize [RPCRT4.@]
4804 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4805 unsigned char *pMemory,
4806 PFORMAT_STRING pFormat)
4808 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4809 PFORMAT_STRING pCArrayFormat;
4812 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4814 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4815 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4817 ERR("invalid format type %x\n", pCStructFormat->type);
4818 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4821 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4822 pCStructFormat->offset_to_array_description;
4823 if (*pCArrayFormat != RPC_FC_CARRAY)
4825 ERR("invalid array format type %x\n", pCStructFormat->type);
4826 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4829 esize = *(const WORD*)(pCArrayFormat+2);
4831 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4832 SizeConformance(pStubMsg);
4834 align_length(&pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4836 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4838 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4839 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4841 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4842 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4845 /***********************************************************************
4846 * NdrConformantStructMemorySize [RPCRT4.@]
4848 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4849 PFORMAT_STRING pFormat)
4855 /***********************************************************************
4856 * NdrConformantStructFree [RPCRT4.@]
4858 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4859 unsigned char *pMemory,
4860 PFORMAT_STRING pFormat)
4862 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4863 PFORMAT_STRING pCArrayFormat;
4865 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4867 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4868 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4870 ERR("invalid format type %x\n", pCStructFormat->type);
4871 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4875 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4876 pCStructFormat->offset_to_array_description;
4877 if (*pCArrayFormat != RPC_FC_CARRAY)
4879 ERR("invalid array format type %x\n", pCStructFormat->type);
4880 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4884 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4885 pCArrayFormat + 4, 0);
4887 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4889 /* copy constant sized part of struct */
4890 pStubMsg->BufferMark = pStubMsg->Buffer;
4892 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4893 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4896 /***********************************************************************
4897 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4899 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4900 unsigned char *pMemory,
4901 PFORMAT_STRING pFormat)
4903 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4904 PFORMAT_STRING pCVArrayFormat;
4906 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4908 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4909 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4911 ERR("invalid format type %x\n", pCVStructFormat->type);
4912 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4916 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4917 pCVStructFormat->offset_to_array_description;
4919 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4920 pMemory + pCVStructFormat->memory_size,
4923 align_pointer_clear(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4925 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4927 /* write constant sized part */
4928 pStubMsg->BufferMark = pStubMsg->Buffer;
4929 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4931 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4932 pMemory + pCVStructFormat->memory_size,
4933 pCVArrayFormat, FALSE /* fHasPointers */);
4935 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4940 /***********************************************************************
4941 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4943 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4944 unsigned char **ppMemory,
4945 PFORMAT_STRING pFormat,
4946 unsigned char fMustAlloc)
4948 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4949 PFORMAT_STRING pCVArrayFormat;
4950 ULONG memsize, bufsize;
4951 unsigned char *saved_buffer, *saved_array_buffer;
4953 unsigned char *array_memory;
4955 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4957 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4958 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4960 ERR("invalid format type %x\n", pCVStructFormat->type);
4961 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4965 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4966 pCVStructFormat->offset_to_array_description;
4968 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4971 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4973 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4975 /* work out how much memory to allocate if we need to do so */
4976 if (!fMustAlloc && !*ppMemory)
4980 SIZE_T size = pCVStructFormat->memory_size + memsize;
4981 *ppMemory = NdrAllocate(pStubMsg, size);
4984 /* mark the start of the constant data */
4985 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4986 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4988 array_memory = *ppMemory + pCVStructFormat->memory_size;
4989 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
4990 &array_memory, pCVArrayFormat,
4991 FALSE /* fMustAlloc */,
4992 FALSE /* fUseServerBufferMemory */,
4993 FALSE /* fUnmarshall */);
4995 /* save offset in case unmarshalling pointers changes it */
4996 offset = pStubMsg->Offset;
4998 /* mark the start of the array data */
4999 saved_array_buffer = pStubMsg->Buffer;
5000 safe_buffer_increment(pStubMsg, bufsize);
5002 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5004 /* copy the constant data */
5005 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
5006 /* copy the array data */
5007 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
5008 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
5009 saved_array_buffer, bufsize);
5011 if (*pCVArrayFormat == RPC_FC_C_CSTRING)
5012 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
5013 else if (*pCVArrayFormat == RPC_FC_C_WSTRING)
5014 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
5019 /***********************************************************************
5020 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
5022 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5023 unsigned char *pMemory,
5024 PFORMAT_STRING pFormat)
5026 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5027 PFORMAT_STRING pCVArrayFormat;
5029 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5031 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5032 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5034 ERR("invalid format type %x\n", pCVStructFormat->type);
5035 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5039 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5040 pCVStructFormat->offset_to_array_description;
5041 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
5042 pMemory + pCVStructFormat->memory_size,
5045 align_length(&pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
5047 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5049 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
5051 array_buffer_size(*pCVArrayFormat, pStubMsg,
5052 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5053 FALSE /* fHasPointers */);
5055 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5058 /***********************************************************************
5059 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
5061 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5062 PFORMAT_STRING pFormat)
5064 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5065 PFORMAT_STRING pCVArrayFormat;
5067 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5069 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5070 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5072 ERR("invalid format type %x\n", pCVStructFormat->type);
5073 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5077 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5078 pCVStructFormat->offset_to_array_description;
5079 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
5081 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
5083 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5085 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
5086 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
5087 FALSE /* fHasPointers */);
5089 pStubMsg->MemorySize += pCVStructFormat->memory_size;
5091 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5093 return pStubMsg->MemorySize;
5096 /***********************************************************************
5097 * NdrConformantVaryingStructFree [RPCRT4.@]
5099 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
5100 unsigned char *pMemory,
5101 PFORMAT_STRING pFormat)
5103 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5104 PFORMAT_STRING pCVArrayFormat;
5106 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5108 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5109 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5111 ERR("invalid format type %x\n", pCVStructFormat->type);
5112 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5116 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5117 pCVStructFormat->offset_to_array_description;
5118 array_free(*pCVArrayFormat, pStubMsg,
5119 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5120 FALSE /* fHasPointers */);
5122 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5124 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5127 #include "pshpack1.h"
5131 unsigned char alignment;
5132 unsigned short total_size;
5133 } NDR_SMFARRAY_FORMAT;
5138 unsigned char alignment;
5140 } NDR_LGFARRAY_FORMAT;
5141 #include "poppack.h"
5143 /***********************************************************************
5144 * NdrFixedArrayMarshall [RPCRT4.@]
5146 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5147 unsigned char *pMemory,
5148 PFORMAT_STRING pFormat)
5150 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5153 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5155 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5156 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5158 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5159 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5163 align_pointer_clear(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5165 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5167 total_size = pSmFArrayFormat->total_size;
5168 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5172 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5173 total_size = pLgFArrayFormat->total_size;
5174 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5177 pStubMsg->BufferMark = pStubMsg->Buffer;
5178 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
5180 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5185 /***********************************************************************
5186 * NdrFixedArrayUnmarshall [RPCRT4.@]
5188 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5189 unsigned char **ppMemory,
5190 PFORMAT_STRING pFormat,
5191 unsigned char fMustAlloc)
5193 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5195 unsigned char *saved_buffer;
5197 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5199 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5200 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5202 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5203 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5207 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5209 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5211 total_size = pSmFArrayFormat->total_size;
5212 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5216 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5217 total_size = pLgFArrayFormat->total_size;
5218 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5222 *ppMemory = NdrAllocate(pStubMsg, total_size);
5225 if (!pStubMsg->IsClient && !*ppMemory)
5226 /* for servers, we just point straight into the RPC buffer */
5227 *ppMemory = pStubMsg->Buffer;
5230 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5231 safe_buffer_increment(pStubMsg, total_size);
5232 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5234 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
5235 if (*ppMemory != saved_buffer)
5236 memcpy(*ppMemory, saved_buffer, total_size);
5241 /***********************************************************************
5242 * NdrFixedArrayBufferSize [RPCRT4.@]
5244 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5245 unsigned char *pMemory,
5246 PFORMAT_STRING pFormat)
5248 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5251 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5253 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5254 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5256 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5257 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5261 align_length(&pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
5263 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5265 total_size = pSmFArrayFormat->total_size;
5266 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5270 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5271 total_size = pLgFArrayFormat->total_size;
5272 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5274 safe_buffer_length_increment(pStubMsg, total_size);
5276 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5279 /***********************************************************************
5280 * NdrFixedArrayMemorySize [RPCRT4.@]
5282 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5283 PFORMAT_STRING pFormat)
5285 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5288 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5290 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5291 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5293 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5294 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5298 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5300 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5302 total_size = pSmFArrayFormat->total_size;
5303 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5307 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5308 total_size = pLgFArrayFormat->total_size;
5309 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5311 pStubMsg->BufferMark = pStubMsg->Buffer;
5312 safe_buffer_increment(pStubMsg, total_size);
5313 pStubMsg->MemorySize += total_size;
5315 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5320 /***********************************************************************
5321 * NdrFixedArrayFree [RPCRT4.@]
5323 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5324 unsigned char *pMemory,
5325 PFORMAT_STRING pFormat)
5327 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5329 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5331 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5332 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5334 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5335 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5339 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5340 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5343 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5344 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5347 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5350 /***********************************************************************
5351 * NdrVaryingArrayMarshall [RPCRT4.@]
5353 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5354 unsigned char *pMemory,
5355 PFORMAT_STRING pFormat)
5357 unsigned char alignment;
5358 DWORD elements, esize;
5361 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5363 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5364 (pFormat[0] != RPC_FC_LGVARRAY))
5366 ERR("invalid format type %x\n", pFormat[0]);
5367 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5371 alignment = pFormat[1] + 1;
5373 if (pFormat[0] == RPC_FC_SMVARRAY)
5376 pFormat += sizeof(WORD);
5377 elements = *(const WORD*)pFormat;
5378 pFormat += sizeof(WORD);
5383 pFormat += sizeof(DWORD);
5384 elements = *(const DWORD*)pFormat;
5385 pFormat += sizeof(DWORD);
5388 esize = *(const WORD*)pFormat;
5389 pFormat += sizeof(WORD);
5391 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5392 if ((pStubMsg->ActualCount > elements) ||
5393 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5395 RpcRaiseException(RPC_S_INVALID_BOUND);
5399 WriteVariance(pStubMsg);
5401 align_pointer_clear(&pStubMsg->Buffer, alignment);
5403 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5404 pStubMsg->BufferMark = pStubMsg->Buffer;
5405 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5407 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5412 /***********************************************************************
5413 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5415 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5416 unsigned char **ppMemory,
5417 PFORMAT_STRING pFormat,
5418 unsigned char fMustAlloc)
5420 unsigned char alignment;
5421 DWORD size, elements, esize;
5423 unsigned char *saved_buffer;
5426 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5428 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5429 (pFormat[0] != RPC_FC_LGVARRAY))
5431 ERR("invalid format type %x\n", pFormat[0]);
5432 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5436 alignment = pFormat[1] + 1;
5438 if (pFormat[0] == RPC_FC_SMVARRAY)
5441 size = *(const WORD*)pFormat;
5442 pFormat += sizeof(WORD);
5443 elements = *(const WORD*)pFormat;
5444 pFormat += sizeof(WORD);
5449 size = *(const DWORD*)pFormat;
5450 pFormat += sizeof(DWORD);
5451 elements = *(const DWORD*)pFormat;
5452 pFormat += sizeof(DWORD);
5455 esize = *(const WORD*)pFormat;
5456 pFormat += sizeof(WORD);
5458 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5460 align_pointer(&pStubMsg->Buffer, alignment);
5462 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5463 offset = pStubMsg->Offset;
5465 if (!fMustAlloc && !*ppMemory)
5468 *ppMemory = NdrAllocate(pStubMsg, size);
5469 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5470 safe_buffer_increment(pStubMsg, bufsize);
5472 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5474 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5479 /***********************************************************************
5480 * NdrVaryingArrayBufferSize [RPCRT4.@]
5482 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5483 unsigned char *pMemory,
5484 PFORMAT_STRING pFormat)
5486 unsigned char alignment;
5487 DWORD elements, esize;
5489 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5491 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5492 (pFormat[0] != RPC_FC_LGVARRAY))
5494 ERR("invalid format type %x\n", pFormat[0]);
5495 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5499 alignment = pFormat[1] + 1;
5501 if (pFormat[0] == RPC_FC_SMVARRAY)
5504 pFormat += sizeof(WORD);
5505 elements = *(const WORD*)pFormat;
5506 pFormat += sizeof(WORD);
5511 pFormat += sizeof(DWORD);
5512 elements = *(const DWORD*)pFormat;
5513 pFormat += sizeof(DWORD);
5516 esize = *(const WORD*)pFormat;
5517 pFormat += sizeof(WORD);
5519 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5520 if ((pStubMsg->ActualCount > elements) ||
5521 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5523 RpcRaiseException(RPC_S_INVALID_BOUND);
5527 SizeVariance(pStubMsg);
5529 align_length(&pStubMsg->BufferLength, alignment);
5531 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5533 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5536 /***********************************************************************
5537 * NdrVaryingArrayMemorySize [RPCRT4.@]
5539 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5540 PFORMAT_STRING pFormat)
5542 unsigned char alignment;
5543 DWORD size, elements, esize;
5545 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5547 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5548 (pFormat[0] != RPC_FC_LGVARRAY))
5550 ERR("invalid format type %x\n", pFormat[0]);
5551 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5555 alignment = pFormat[1] + 1;
5557 if (pFormat[0] == RPC_FC_SMVARRAY)
5560 size = *(const WORD*)pFormat;
5561 pFormat += sizeof(WORD);
5562 elements = *(const WORD*)pFormat;
5563 pFormat += sizeof(WORD);
5568 size = *(const DWORD*)pFormat;
5569 pFormat += sizeof(DWORD);
5570 elements = *(const DWORD*)pFormat;
5571 pFormat += sizeof(DWORD);
5574 esize = *(const WORD*)pFormat;
5575 pFormat += sizeof(WORD);
5577 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5579 align_pointer(&pStubMsg->Buffer, alignment);
5581 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5582 pStubMsg->MemorySize += size;
5584 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5586 return pStubMsg->MemorySize;
5589 /***********************************************************************
5590 * NdrVaryingArrayFree [RPCRT4.@]
5592 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5593 unsigned char *pMemory,
5594 PFORMAT_STRING pFormat)
5598 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5600 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5601 (pFormat[0] != RPC_FC_LGVARRAY))
5603 ERR("invalid format type %x\n", pFormat[0]);
5604 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5608 if (pFormat[0] == RPC_FC_SMVARRAY)
5611 pFormat += sizeof(WORD);
5612 elements = *(const WORD*)pFormat;
5613 pFormat += sizeof(WORD);
5618 pFormat += sizeof(DWORD);
5619 elements = *(const DWORD*)pFormat;
5620 pFormat += sizeof(DWORD);
5623 pFormat += sizeof(WORD);
5625 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5626 if ((pStubMsg->ActualCount > elements) ||
5627 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5629 RpcRaiseException(RPC_S_INVALID_BOUND);
5633 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5636 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5649 return *(const USHORT *)pMemory;
5653 return *(const ULONG *)pMemory;
5654 case RPC_FC_INT3264:
5655 case RPC_FC_UINT3264:
5656 return *(const ULONG_PTR *)pMemory;
5658 FIXME("Unhandled base type: 0x%02x\n", fc);
5663 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5665 PFORMAT_STRING pFormat)
5667 unsigned short num_arms, arm, type;
5669 num_arms = *(const SHORT*)pFormat & 0x0fff;
5671 for(arm = 0; arm < num_arms; arm++)
5673 if(discriminant == *(const ULONG*)pFormat)
5681 type = *(const unsigned short*)pFormat;
5682 TRACE("type %04x\n", type);
5683 if(arm == num_arms) /* default arm extras */
5687 ERR("no arm for 0x%x and no default case\n", discriminant);
5688 RpcRaiseException(RPC_S_INVALID_TAG);
5693 TRACE("falling back to empty default case for 0x%x\n", discriminant);
5700 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5702 unsigned short type;
5706 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5710 type = *(const unsigned short*)pFormat;
5711 if((type & 0xff00) == 0x8000)
5713 unsigned char basetype = LOBYTE(type);
5714 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5718 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5719 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5722 unsigned char *saved_buffer = NULL;
5723 int pointer_buffer_mark_set = 0;
5730 align_pointer_clear(&pStubMsg->Buffer, 4);
5731 saved_buffer = pStubMsg->Buffer;
5732 if (pStubMsg->PointerBufferMark)
5734 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5735 pStubMsg->PointerBufferMark = NULL;
5736 pointer_buffer_mark_set = 1;
5739 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5741 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5742 if (pointer_buffer_mark_set)
5744 STD_OVERFLOW_CHECK(pStubMsg);
5745 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5746 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5748 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5749 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5750 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5752 pStubMsg->Buffer = saved_buffer + 4;
5756 m(pStubMsg, pMemory, desc);
5759 else FIXME("no marshaller for embedded type %02x\n", *desc);
5764 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5765 unsigned char **ppMemory,
5767 PFORMAT_STRING pFormat,
5768 unsigned char fMustAlloc)
5770 unsigned short type;
5774 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5778 type = *(const unsigned short*)pFormat;
5779 if((type & 0xff00) == 0x8000)
5781 unsigned char basetype = LOBYTE(type);
5782 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5786 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5787 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5790 unsigned char *saved_buffer = NULL;
5791 int pointer_buffer_mark_set = 0;
5798 align_pointer(&pStubMsg->Buffer, 4);
5799 saved_buffer = pStubMsg->Buffer;
5800 if (pStubMsg->PointerBufferMark)
5802 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5803 pStubMsg->PointerBufferMark = NULL;
5804 pointer_buffer_mark_set = 1;
5807 pStubMsg->Buffer += 4; /* for pointer ID */
5809 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5811 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5812 saved_buffer, pStubMsg->BufferEnd);
5813 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5816 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5817 if (pointer_buffer_mark_set)
5819 STD_OVERFLOW_CHECK(pStubMsg);
5820 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5821 pStubMsg->Buffer = saved_buffer + 4;
5825 m(pStubMsg, ppMemory, desc, fMustAlloc);
5828 else FIXME("no marshaller for embedded type %02x\n", *desc);
5833 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5834 unsigned char *pMemory,
5836 PFORMAT_STRING pFormat)
5838 unsigned short type;
5842 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5846 type = *(const unsigned short*)pFormat;
5847 if((type & 0xff00) == 0x8000)
5849 unsigned char basetype = LOBYTE(type);
5850 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5854 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5855 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5864 align_length(&pStubMsg->BufferLength, 4);
5865 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5866 if (!pStubMsg->IgnoreEmbeddedPointers)
5868 int saved_buffer_length = pStubMsg->BufferLength;
5869 pStubMsg->BufferLength = pStubMsg->PointerLength;
5870 pStubMsg->PointerLength = 0;
5871 if(!pStubMsg->BufferLength)
5872 ERR("BufferLength == 0??\n");
5873 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5874 pStubMsg->PointerLength = pStubMsg->BufferLength;
5875 pStubMsg->BufferLength = saved_buffer_length;
5879 m(pStubMsg, pMemory, desc);
5882 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5886 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5888 PFORMAT_STRING pFormat)
5890 unsigned short type, size;
5892 size = *(const unsigned short*)pFormat;
5893 pStubMsg->Memory += size;
5896 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5900 type = *(const unsigned short*)pFormat;
5901 if((type & 0xff00) == 0x8000)
5903 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5907 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5908 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5909 unsigned char *saved_buffer;
5918 align_pointer(&pStubMsg->Buffer, 4);
5919 saved_buffer = pStubMsg->Buffer;
5920 safe_buffer_increment(pStubMsg, 4);
5921 align_length(&pStubMsg->MemorySize, sizeof(void *));
5922 pStubMsg->MemorySize += sizeof(void *);
5923 if (!pStubMsg->IgnoreEmbeddedPointers)
5924 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5927 return m(pStubMsg, desc);
5930 else FIXME("no marshaller for embedded type %02x\n", *desc);
5933 TRACE("size %d\n", size);
5937 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5938 unsigned char *pMemory,
5940 PFORMAT_STRING pFormat)
5942 unsigned short type;
5946 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5950 type = *(const unsigned short*)pFormat;
5951 if((type & 0xff00) != 0x8000)
5953 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5954 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5963 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5966 m(pStubMsg, pMemory, desc);
5972 /***********************************************************************
5973 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5975 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5976 unsigned char *pMemory,
5977 PFORMAT_STRING pFormat)
5979 unsigned char switch_type;
5980 unsigned char increment;
5983 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5986 switch_type = *pFormat & 0xf;
5987 increment = (*pFormat & 0xf0) >> 4;
5990 align_pointer_clear(&pStubMsg->Buffer, increment);
5992 switch_value = get_discriminant(switch_type, pMemory);
5993 TRACE("got switch value 0x%x\n", switch_value);
5995 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5996 pMemory += increment;
5998 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
6001 /***********************************************************************
6002 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
6004 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6005 unsigned char **ppMemory,
6006 PFORMAT_STRING pFormat,
6007 unsigned char fMustAlloc)
6009 unsigned char switch_type;
6010 unsigned char increment;
6012 unsigned short size;
6013 unsigned char *pMemoryArm;
6015 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6018 switch_type = *pFormat & 0xf;
6019 increment = (*pFormat & 0xf0) >> 4;
6022 align_pointer(&pStubMsg->Buffer, increment);
6023 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6024 TRACE("got switch value 0x%x\n", switch_value);
6026 size = *(const unsigned short*)pFormat + increment;
6027 if (!fMustAlloc && !*ppMemory)
6030 *ppMemory = NdrAllocate(pStubMsg, size);
6032 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6033 * since the arm is part of the memory block that is encompassed by
6034 * the whole union. Memory is forced to allocate when pointers
6035 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6036 * clearing the memory we pass in to the unmarshaller */
6038 memset(*ppMemory, 0, size);
6040 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
6041 pMemoryArm = *ppMemory + increment;
6043 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, FALSE);
6046 /***********************************************************************
6047 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
6049 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6050 unsigned char *pMemory,
6051 PFORMAT_STRING pFormat)
6053 unsigned char switch_type;
6054 unsigned char increment;
6057 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6060 switch_type = *pFormat & 0xf;
6061 increment = (*pFormat & 0xf0) >> 4;
6064 align_length(&pStubMsg->BufferLength, increment);
6065 switch_value = get_discriminant(switch_type, pMemory);
6066 TRACE("got switch value 0x%x\n", switch_value);
6068 /* Add discriminant size */
6069 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
6070 pMemory += increment;
6072 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
6075 /***********************************************************************
6076 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
6078 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6079 PFORMAT_STRING pFormat)
6081 unsigned char switch_type;
6082 unsigned char increment;
6085 switch_type = *pFormat & 0xf;
6086 increment = (*pFormat & 0xf0) >> 4;
6089 align_pointer(&pStubMsg->Buffer, increment);
6090 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6091 TRACE("got switch value 0x%x\n", switch_value);
6093 pStubMsg->Memory += increment;
6095 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
6098 /***********************************************************************
6099 * NdrEncapsulatedUnionFree [RPCRT4.@]
6101 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6102 unsigned char *pMemory,
6103 PFORMAT_STRING pFormat)
6105 unsigned char switch_type;
6106 unsigned char increment;
6109 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6112 switch_type = *pFormat & 0xf;
6113 increment = (*pFormat & 0xf0) >> 4;
6116 switch_value = get_discriminant(switch_type, pMemory);
6117 TRACE("got switch value 0x%x\n", switch_value);
6119 pMemory += increment;
6121 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
6124 /***********************************************************************
6125 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
6127 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6128 unsigned char *pMemory,
6129 PFORMAT_STRING pFormat)
6131 unsigned char switch_type;
6133 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6136 switch_type = *pFormat;
6139 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6140 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6141 /* Marshall discriminant */
6142 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6144 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6147 static LONG unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
6148 PFORMAT_STRING *ppFormat)
6150 LONG discriminant = 0;
6160 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6170 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6171 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6179 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6180 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6185 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
6189 if (pStubMsg->fHasNewCorrDesc)
6193 return discriminant;
6196 /**********************************************************************
6197 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6199 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6200 unsigned char **ppMemory,
6201 PFORMAT_STRING pFormat,
6202 unsigned char fMustAlloc)
6205 unsigned short size;
6207 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6210 /* Unmarshall discriminant */
6211 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6212 TRACE("unmarshalled discriminant %x\n", discriminant);
6214 pFormat += *(const SHORT*)pFormat;
6216 size = *(const unsigned short*)pFormat;
6218 if (!fMustAlloc && !*ppMemory)
6221 *ppMemory = NdrAllocate(pStubMsg, size);
6223 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6224 * since the arm is part of the memory block that is encompassed by
6225 * the whole union. Memory is forced to allocate when pointers
6226 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6227 * clearing the memory we pass in to the unmarshaller */
6229 memset(*ppMemory, 0, size);
6231 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, FALSE);
6234 /***********************************************************************
6235 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6237 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6238 unsigned char *pMemory,
6239 PFORMAT_STRING pFormat)
6241 unsigned char switch_type;
6243 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6246 switch_type = *pFormat;
6249 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6250 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6251 /* Add discriminant size */
6252 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6254 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6257 /***********************************************************************
6258 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6260 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6261 PFORMAT_STRING pFormat)
6266 /* Unmarshall discriminant */
6267 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6268 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
6270 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
6273 /***********************************************************************
6274 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6276 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6277 unsigned char *pMemory,
6278 PFORMAT_STRING pFormat)
6280 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6284 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6285 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6287 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6290 /***********************************************************************
6291 * NdrByteCountPointerMarshall [RPCRT4.@]
6293 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6294 unsigned char *pMemory,
6295 PFORMAT_STRING pFormat)
6301 /***********************************************************************
6302 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6304 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6305 unsigned char **ppMemory,
6306 PFORMAT_STRING pFormat,
6307 unsigned char fMustAlloc)
6313 /***********************************************************************
6314 * NdrByteCountPointerBufferSize [RPCRT4.@]
6316 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6317 unsigned char *pMemory,
6318 PFORMAT_STRING pFormat)
6323 /***********************************************************************
6324 * NdrByteCountPointerMemorySize [internal]
6326 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6327 PFORMAT_STRING pFormat)
6333 /***********************************************************************
6334 * NdrByteCountPointerFree [RPCRT4.@]
6336 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6337 unsigned char *pMemory,
6338 PFORMAT_STRING pFormat)
6343 /***********************************************************************
6344 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6346 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6347 unsigned char *pMemory,
6348 PFORMAT_STRING pFormat)
6354 /***********************************************************************
6355 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6357 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6358 unsigned char **ppMemory,
6359 PFORMAT_STRING pFormat,
6360 unsigned char fMustAlloc)
6366 /***********************************************************************
6367 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6369 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6370 unsigned char *pMemory,
6371 PFORMAT_STRING pFormat)
6376 /***********************************************************************
6377 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6379 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6380 PFORMAT_STRING pFormat)
6386 /***********************************************************************
6387 * NdrXmitOrRepAsFree [RPCRT4.@]
6389 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6390 unsigned char *pMemory,
6391 PFORMAT_STRING pFormat)
6396 /***********************************************************************
6397 * NdrRangeMarshall [internal]
6399 static unsigned char *WINAPI NdrRangeMarshall(
6400 PMIDL_STUB_MESSAGE pStubMsg,
6401 unsigned char *pMemory,
6402 PFORMAT_STRING pFormat)
6404 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6405 unsigned char base_type;
6407 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6409 if (pRange->type != RPC_FC_RANGE)
6411 ERR("invalid format type %x\n", pRange->type);
6412 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6416 base_type = pRange->flags_type & 0xf;
6418 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6421 /***********************************************************************
6422 * NdrRangeUnmarshall [RPCRT4.@]
6424 unsigned char *WINAPI NdrRangeUnmarshall(
6425 PMIDL_STUB_MESSAGE pStubMsg,
6426 unsigned char **ppMemory,
6427 PFORMAT_STRING pFormat,
6428 unsigned char fMustAlloc)
6430 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6431 unsigned char base_type;
6433 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6435 if (pRange->type != RPC_FC_RANGE)
6437 ERR("invalid format type %x\n", pRange->type);
6438 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6441 base_type = pRange->flags_type & 0xf;
6443 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6444 base_type, pRange->low_value, pRange->high_value);
6446 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6449 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \
6450 if (!fMustAlloc && !*ppMemory) \
6451 fMustAlloc = TRUE; \
6453 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6454 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6456 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6457 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6458 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6460 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6461 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6463 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6464 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6465 (mem_type)pRange->high_value); \
6466 RpcRaiseException(RPC_S_INVALID_BOUND); \
6469 TRACE("*ppMemory: %p\n", *ppMemory); \
6470 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6471 pStubMsg->Buffer += sizeof(wire_type); \
6478 RANGE_UNMARSHALL(UCHAR, UCHAR, "%d");
6479 TRACE("value: 0x%02x\n", **ppMemory);
6483 RANGE_UNMARSHALL(CHAR, CHAR, "%u");
6484 TRACE("value: 0x%02x\n", **ppMemory);
6486 case RPC_FC_WCHAR: /* FIXME: valid? */
6488 RANGE_UNMARSHALL(USHORT, USHORT, "%u");
6489 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6492 RANGE_UNMARSHALL(SHORT, SHORT, "%d");
6493 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6497 RANGE_UNMARSHALL(LONG, LONG, "%d");
6498 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6501 RANGE_UNMARSHALL(ULONG, ULONG, "%u");
6502 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6505 RANGE_UNMARSHALL(UINT, USHORT, "%u");
6506 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6512 ERR("invalid range base type: 0x%02x\n", base_type);
6513 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6519 /***********************************************************************
6520 * NdrRangeBufferSize [internal]
6522 static void WINAPI NdrRangeBufferSize(
6523 PMIDL_STUB_MESSAGE pStubMsg,
6524 unsigned char *pMemory,
6525 PFORMAT_STRING pFormat)
6527 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6528 unsigned char base_type;
6530 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6532 if (pRange->type != RPC_FC_RANGE)
6534 ERR("invalid format type %x\n", pRange->type);
6535 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6537 base_type = pRange->flags_type & 0xf;
6539 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6542 /***********************************************************************
6543 * NdrRangeMemorySize [internal]
6545 static ULONG WINAPI NdrRangeMemorySize(
6546 PMIDL_STUB_MESSAGE pStubMsg,
6547 PFORMAT_STRING pFormat)
6549 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6550 unsigned char base_type;
6552 if (pRange->type != RPC_FC_RANGE)
6554 ERR("invalid format type %x\n", pRange->type);
6555 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6558 base_type = pRange->flags_type & 0xf;
6560 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6563 /***********************************************************************
6564 * NdrRangeFree [internal]
6566 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6567 unsigned char *pMemory,
6568 PFORMAT_STRING pFormat)
6570 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6575 /***********************************************************************
6576 * NdrBaseTypeMarshall [internal]
6578 static unsigned char *WINAPI NdrBaseTypeMarshall(
6579 PMIDL_STUB_MESSAGE pStubMsg,
6580 unsigned char *pMemory,
6581 PFORMAT_STRING pFormat)
6583 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6591 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6592 TRACE("value: 0x%02x\n", *pMemory);
6597 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6598 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6599 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6603 case RPC_FC_ERROR_STATUS_T:
6605 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONG));
6606 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6607 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6610 align_pointer_clear(&pStubMsg->Buffer, sizeof(float));
6611 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6614 align_pointer_clear(&pStubMsg->Buffer, sizeof(double));
6615 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6618 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONGLONG));
6619 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6620 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6624 USHORT val = *(UINT *)pMemory;
6625 /* only 16-bits on the wire, so do a sanity check */
6626 if (*(UINT *)pMemory > SHRT_MAX)
6627 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6628 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6629 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6630 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6633 case RPC_FC_INT3264:
6634 case RPC_FC_UINT3264:
6636 UINT val = *(UINT_PTR *)pMemory;
6637 align_pointer_clear(&pStubMsg->Buffer, sizeof(UINT));
6638 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6644 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6647 /* FIXME: what is the correct return value? */
6651 /***********************************************************************
6652 * NdrBaseTypeUnmarshall [internal]
6654 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6655 PMIDL_STUB_MESSAGE pStubMsg,
6656 unsigned char **ppMemory,
6657 PFORMAT_STRING pFormat,
6658 unsigned char fMustAlloc)
6660 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6662 #define BASE_TYPE_UNMARSHALL(type) do { \
6663 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
6664 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6666 *ppMemory = pStubMsg->Buffer; \
6667 TRACE("*ppMemory: %p\n", *ppMemory); \
6668 safe_buffer_increment(pStubMsg, sizeof(type)); \
6673 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6674 TRACE("*ppMemory: %p\n", *ppMemory); \
6675 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6685 BASE_TYPE_UNMARSHALL(UCHAR);
6686 TRACE("value: 0x%02x\n", **ppMemory);
6691 BASE_TYPE_UNMARSHALL(USHORT);
6692 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6696 case RPC_FC_ERROR_STATUS_T:
6698 BASE_TYPE_UNMARSHALL(ULONG);
6699 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6702 BASE_TYPE_UNMARSHALL(float);
6703 TRACE("value: %f\n", **(float **)ppMemory);
6706 BASE_TYPE_UNMARSHALL(double);
6707 TRACE("value: %f\n", **(double **)ppMemory);
6710 BASE_TYPE_UNMARSHALL(ULONGLONG);
6711 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6716 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6717 if (!fMustAlloc && !*ppMemory)
6720 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6721 safe_copy_from_buffer(pStubMsg, &val, sizeof(USHORT));
6722 /* 16-bits on the wire, but int in memory */
6723 **(UINT **)ppMemory = val;
6724 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6727 case RPC_FC_INT3264:
6728 if (sizeof(INT_PTR) == sizeof(INT)) BASE_TYPE_UNMARSHALL(INT);
6732 align_pointer(&pStubMsg->Buffer, sizeof(INT));
6733 if (!fMustAlloc && !*ppMemory)
6736 *ppMemory = NdrAllocate(pStubMsg, sizeof(INT_PTR));
6737 safe_copy_from_buffer(pStubMsg, &val, sizeof(INT));
6738 **(INT_PTR **)ppMemory = val;
6739 TRACE("value: 0x%08lx\n", **(INT_PTR **)ppMemory);
6742 case RPC_FC_UINT3264:
6743 if (sizeof(UINT_PTR) == sizeof(UINT)) BASE_TYPE_UNMARSHALL(UINT);
6747 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6748 if (!fMustAlloc && !*ppMemory)
6751 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT_PTR));
6752 safe_copy_from_buffer(pStubMsg, &val, sizeof(UINT));
6753 **(UINT_PTR **)ppMemory = val;
6754 TRACE("value: 0x%08lx\n", **(UINT_PTR **)ppMemory);
6760 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6762 #undef BASE_TYPE_UNMARSHALL
6764 /* FIXME: what is the correct return value? */
6769 /***********************************************************************
6770 * NdrBaseTypeBufferSize [internal]
6772 static void WINAPI NdrBaseTypeBufferSize(
6773 PMIDL_STUB_MESSAGE pStubMsg,
6774 unsigned char *pMemory,
6775 PFORMAT_STRING pFormat)
6777 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6785 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6791 align_length(&pStubMsg->BufferLength, sizeof(USHORT));
6792 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6797 case RPC_FC_INT3264:
6798 case RPC_FC_UINT3264:
6799 align_length(&pStubMsg->BufferLength, sizeof(ULONG));
6800 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6803 align_length(&pStubMsg->BufferLength, sizeof(float));
6804 safe_buffer_length_increment(pStubMsg, sizeof(float));
6807 align_length(&pStubMsg->BufferLength, sizeof(double));
6808 safe_buffer_length_increment(pStubMsg, sizeof(double));
6811 align_length(&pStubMsg->BufferLength, sizeof(ULONGLONG));
6812 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6814 case RPC_FC_ERROR_STATUS_T:
6815 align_length(&pStubMsg->BufferLength, sizeof(error_status_t));
6816 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6821 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6825 /***********************************************************************
6826 * NdrBaseTypeMemorySize [internal]
6828 static ULONG WINAPI NdrBaseTypeMemorySize(
6829 PMIDL_STUB_MESSAGE pStubMsg,
6830 PFORMAT_STRING pFormat)
6832 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6840 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6841 pStubMsg->MemorySize += sizeof(UCHAR);
6842 return sizeof(UCHAR);
6846 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6847 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6848 align_length(&pStubMsg->MemorySize, sizeof(USHORT));
6849 pStubMsg->MemorySize += sizeof(USHORT);
6850 return sizeof(USHORT);
6854 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6855 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6856 align_length(&pStubMsg->MemorySize, sizeof(ULONG));
6857 pStubMsg->MemorySize += sizeof(ULONG);
6858 return sizeof(ULONG);
6860 align_pointer(&pStubMsg->Buffer, sizeof(float));
6861 safe_buffer_increment(pStubMsg, sizeof(float));
6862 align_length(&pStubMsg->MemorySize, sizeof(float));
6863 pStubMsg->MemorySize += sizeof(float);
6864 return sizeof(float);
6866 align_pointer(&pStubMsg->Buffer, sizeof(double));
6867 safe_buffer_increment(pStubMsg, sizeof(double));
6868 align_length(&pStubMsg->MemorySize, sizeof(double));
6869 pStubMsg->MemorySize += sizeof(double);
6870 return sizeof(double);
6872 align_pointer(&pStubMsg->Buffer, sizeof(ULONGLONG));
6873 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6874 align_length(&pStubMsg->MemorySize, sizeof(ULONGLONG));
6875 pStubMsg->MemorySize += sizeof(ULONGLONG);
6876 return sizeof(ULONGLONG);
6877 case RPC_FC_ERROR_STATUS_T:
6878 align_pointer(&pStubMsg->Buffer, sizeof(error_status_t));
6879 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6880 align_length(&pStubMsg->MemorySize, sizeof(error_status_t));
6881 pStubMsg->MemorySize += sizeof(error_status_t);
6882 return sizeof(error_status_t);
6884 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6885 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6886 align_length(&pStubMsg->MemorySize, sizeof(UINT));
6887 pStubMsg->MemorySize += sizeof(UINT);
6888 return sizeof(UINT);
6889 case RPC_FC_INT3264:
6890 case RPC_FC_UINT3264:
6891 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6892 safe_buffer_increment(pStubMsg, sizeof(UINT));
6893 align_length(&pStubMsg->MemorySize, sizeof(UINT_PTR));
6894 pStubMsg->MemorySize += sizeof(UINT_PTR);
6895 return sizeof(UINT_PTR);
6897 align_length(&pStubMsg->MemorySize, sizeof(void *));
6898 pStubMsg->MemorySize += sizeof(void *);
6899 return sizeof(void *);
6901 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6906 /***********************************************************************
6907 * NdrBaseTypeFree [internal]
6909 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6910 unsigned char *pMemory,
6911 PFORMAT_STRING pFormat)
6913 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6918 /***********************************************************************
6919 * NdrContextHandleBufferSize [internal]
6921 static void WINAPI NdrContextHandleBufferSize(
6922 PMIDL_STUB_MESSAGE pStubMsg,
6923 unsigned char *pMemory,
6924 PFORMAT_STRING pFormat)
6926 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6928 if (*pFormat != RPC_FC_BIND_CONTEXT)
6930 ERR("invalid format type %x\n", *pFormat);
6931 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6933 align_length(&pStubMsg->BufferLength, 4);
6934 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6937 /***********************************************************************
6938 * NdrContextHandleMarshall [internal]
6940 static unsigned char *WINAPI NdrContextHandleMarshall(
6941 PMIDL_STUB_MESSAGE pStubMsg,
6942 unsigned char *pMemory,
6943 PFORMAT_STRING pFormat)
6945 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6947 if (*pFormat != RPC_FC_BIND_CONTEXT)
6949 ERR("invalid format type %x\n", *pFormat);
6950 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6952 TRACE("flags: 0x%02x\n", pFormat[1]);
6954 if (pStubMsg->IsClient)
6956 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6957 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6959 NdrClientContextMarshall(pStubMsg, pMemory, FALSE);
6963 NDR_SCONTEXT ctxt = NDRSContextFromValue(pMemory);
6964 NDR_RUNDOWN rundown = pStubMsg->StubDesc->apfnNdrRundownRoutines[pFormat[2]];
6965 NdrServerContextNewMarshall(pStubMsg, ctxt, rundown, pFormat);
6971 /***********************************************************************
6972 * NdrContextHandleUnmarshall [internal]
6974 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6975 PMIDL_STUB_MESSAGE pStubMsg,
6976 unsigned char **ppMemory,
6977 PFORMAT_STRING pFormat,
6978 unsigned char fMustAlloc)
6980 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6981 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6983 if (*pFormat != RPC_FC_BIND_CONTEXT)
6985 ERR("invalid format type %x\n", *pFormat);
6986 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6988 TRACE("flags: 0x%02x\n", pFormat[1]);
6990 if (pStubMsg->IsClient)
6992 /* [out]-only or [ret] param */
6993 if ((pFormat[1] & (HANDLE_PARAM_IS_IN|HANDLE_PARAM_IS_OUT)) == HANDLE_PARAM_IS_OUT)
6994 **(NDR_CCONTEXT **)ppMemory = NULL;
6995 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
7000 ctxt = NdrServerContextNewUnmarshall(pStubMsg, pFormat);
7001 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
7002 *(void **)ppMemory = NDRSContextValue(ctxt);
7004 *(void **)ppMemory = *NDRSContextValue(ctxt);
7010 /***********************************************************************
7011 * NdrClientContextMarshall [RPCRT4.@]
7013 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7014 NDR_CCONTEXT ContextHandle,
7017 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
7019 align_pointer_clear(&pStubMsg->Buffer, 4);
7021 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7023 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7024 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7025 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7028 /* FIXME: what does fCheck do? */
7029 NDRCContextMarshall(ContextHandle,
7032 pStubMsg->Buffer += cbNDRContext;
7035 /***********************************************************************
7036 * NdrClientContextUnmarshall [RPCRT4.@]
7038 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7039 NDR_CCONTEXT * pContextHandle,
7040 RPC_BINDING_HANDLE BindHandle)
7042 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
7044 align_pointer(&pStubMsg->Buffer, 4);
7046 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
7047 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7049 NDRCContextUnmarshall(pContextHandle,
7052 pStubMsg->RpcMsg->DataRepresentation);
7054 pStubMsg->Buffer += cbNDRContext;
7057 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7058 NDR_SCONTEXT ContextHandle,
7059 NDR_RUNDOWN RundownRoutine )
7061 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
7063 align_pointer(&pStubMsg->Buffer, 4);
7065 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7067 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7068 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7069 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7072 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7073 pStubMsg->Buffer, RundownRoutine, NULL,
7074 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7075 pStubMsg->Buffer += cbNDRContext;
7078 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
7080 NDR_SCONTEXT ContextHandle;
7082 TRACE("(%p)\n", pStubMsg);
7084 align_pointer(&pStubMsg->Buffer, 4);
7086 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7088 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7089 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7090 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7093 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7095 pStubMsg->RpcMsg->DataRepresentation,
7096 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7097 pStubMsg->Buffer += cbNDRContext;
7099 return ContextHandle;
7102 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
7103 unsigned char* pMemory,
7104 PFORMAT_STRING pFormat)
7106 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
7109 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
7110 PFORMAT_STRING pFormat)
7112 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7113 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7115 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7117 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7118 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7119 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7120 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7121 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7123 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7124 if_id = &sif->InterfaceId;
7127 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
7128 pStubMsg->RpcMsg->DataRepresentation, if_id,
7132 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7133 NDR_SCONTEXT ContextHandle,
7134 NDR_RUNDOWN RundownRoutine,
7135 PFORMAT_STRING pFormat)
7137 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7138 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7140 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
7142 align_pointer(&pStubMsg->Buffer, 4);
7144 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7146 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7147 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7148 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7151 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7152 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7153 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7154 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7155 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7157 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7158 if_id = &sif->InterfaceId;
7161 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7162 pStubMsg->Buffer, RundownRoutine, if_id, flags);
7163 pStubMsg->Buffer += cbNDRContext;
7166 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7167 PFORMAT_STRING pFormat)
7169 NDR_SCONTEXT ContextHandle;
7170 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7171 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7173 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7175 align_pointer(&pStubMsg->Buffer, 4);
7177 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7179 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7180 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7181 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7184 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7185 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7186 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7187 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7188 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7190 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7191 if_id = &sif->InterfaceId;
7194 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7196 pStubMsg->RpcMsg->DataRepresentation,
7198 pStubMsg->Buffer += cbNDRContext;
7200 return ContextHandle;
7203 /***********************************************************************
7204 * NdrCorrelationInitialize [RPCRT4.@]
7206 * Initializes correlation validity checking.
7209 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7210 * pMemory [I] Pointer to memory to use as a cache.
7211 * CacheSize [I] Size of the memory pointed to by pMemory.
7212 * Flags [I] Reserved. Set to zero.
7217 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
7219 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
7220 pStubMsg->fHasNewCorrDesc = TRUE;
7223 /***********************************************************************
7224 * NdrCorrelationPass [RPCRT4.@]
7226 * Performs correlation validity checking.
7229 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7234 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
7236 FIXME("(%p): stub\n", pStubMsg);
7239 /***********************************************************************
7240 * NdrCorrelationFree [RPCRT4.@]
7242 * Frees any resources used while unmarshalling parameters that need
7243 * correlation validity checking.
7246 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7251 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
7253 FIXME("(%p): stub\n", pStubMsg);