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=%d\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 pStubMsg->StackTop = ptr;
595 /* ofs is index into StubDesc->apfnExprEval */
596 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
597 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
599 pStubMsg->StackTop = old_stack_top;
601 /* the callback function always stores the computed value in MaxCount */
602 *pCount = pStubMsg->MaxCount;
606 ptr = (char *)ptr + ofs;
619 data = *(USHORT*)ptr;
630 FIXME("unknown conformance data type %x\n", dtype);
633 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
636 switch (pFormat[1]) {
637 case RPC_FC_DEREFERENCE: /* already handled */
654 FIXME("unknown conformance op %d\n", pFormat[1]);
659 TRACE("resulting conformance is %ld\n", *pCount);
660 if (pStubMsg->fHasNewCorrDesc)
666 static inline PFORMAT_STRING SkipConformance(PMIDL_STUB_MESSAGE pStubMsg,
667 PFORMAT_STRING pFormat)
669 if (pStubMsg->fHasNewCorrDesc)
676 static inline PFORMAT_STRING SkipVariance(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
678 return SkipConformance( pStubMsg, pFormat );
681 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
682 * the result overflows 32-bits */
683 static inline ULONG safe_multiply(ULONG a, ULONG b)
685 ULONGLONG ret = (ULONGLONG)a * b;
686 if (ret > 0xffffffff)
688 RpcRaiseException(RPC_S_INVALID_BOUND);
694 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
696 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
697 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
698 RpcRaiseException(RPC_X_BAD_STUB_DATA);
699 pStubMsg->Buffer += size;
702 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
704 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
706 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
707 pStubMsg->BufferLength, size);
708 RpcRaiseException(RPC_X_BAD_STUB_DATA);
710 pStubMsg->BufferLength += size;
713 /* copies data from the buffer, checking that there is enough data in the buffer
715 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
717 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
718 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
720 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
721 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
722 RpcRaiseException(RPC_X_BAD_STUB_DATA);
724 if (p == pStubMsg->Buffer)
725 ERR("pointer is the same as the buffer\n");
726 memcpy(p, pStubMsg->Buffer, size);
727 pStubMsg->Buffer += size;
730 /* copies data to the buffer, checking that there is enough space to do so */
731 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
733 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
734 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
736 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
737 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
739 RpcRaiseException(RPC_X_BAD_STUB_DATA);
741 memcpy(pStubMsg->Buffer, p, size);
742 pStubMsg->Buffer += size;
745 /* verify that string data sitting in the buffer is valid and safe to
747 static void validate_string_data(MIDL_STUB_MESSAGE *pStubMsg, ULONG bufsize, ULONG esize)
751 /* verify the buffer is safe to access */
752 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
753 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
755 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
756 pStubMsg->BufferEnd, pStubMsg->Buffer);
757 RpcRaiseException(RPC_X_BAD_STUB_DATA);
760 /* strings must always have null terminating bytes */
763 ERR("invalid string length of %d\n", bufsize / esize);
764 RpcRaiseException(RPC_S_INVALID_BOUND);
767 for (i = bufsize - esize; i < bufsize; i++)
768 if (pStubMsg->Buffer[i] != 0)
770 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
771 i, pStubMsg->Buffer[i]);
772 RpcRaiseException(RPC_S_INVALID_BOUND);
776 static inline void dump_pointer_attr(unsigned char attr)
778 if (attr & RPC_FC_P_ALLOCALLNODES)
779 TRACE(" RPC_FC_P_ALLOCALLNODES");
780 if (attr & RPC_FC_P_DONTFREE)
781 TRACE(" RPC_FC_P_DONTFREE");
782 if (attr & RPC_FC_P_ONSTACK)
783 TRACE(" RPC_FC_P_ONSTACK");
784 if (attr & RPC_FC_P_SIMPLEPOINTER)
785 TRACE(" RPC_FC_P_SIMPLEPOINTER");
786 if (attr & RPC_FC_P_DEREF)
787 TRACE(" RPC_FC_P_DEREF");
791 /***********************************************************************
792 * PointerMarshall [internal]
794 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
795 unsigned char *Buffer,
796 unsigned char *Pointer,
797 PFORMAT_STRING pFormat)
799 unsigned type = pFormat[0], attr = pFormat[1];
803 int pointer_needs_marshaling;
805 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
806 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
808 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
809 else desc = pFormat + *(const SHORT*)pFormat;
812 case RPC_FC_RP: /* ref pointer (always non-null) */
815 ERR("NULL ref pointer is not allowed\n");
816 RpcRaiseException(RPC_X_NULL_REF_POINTER);
818 pointer_needs_marshaling = 1;
820 case RPC_FC_UP: /* unique pointer */
821 case RPC_FC_OP: /* object pointer - same as unique here */
823 pointer_needs_marshaling = 1;
825 pointer_needs_marshaling = 0;
826 pointer_id = Pointer ? NDR_POINTER_ID(pStubMsg) : 0;
827 TRACE("writing 0x%08x to buffer\n", pointer_id);
828 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
831 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
832 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
833 TRACE("writing 0x%08x to buffer\n", pointer_id);
834 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
837 FIXME("unhandled ptr type=%02x\n", type);
838 RpcRaiseException(RPC_X_BAD_STUB_DATA);
842 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
844 if (pointer_needs_marshaling) {
845 if (attr & RPC_FC_P_DEREF) {
846 Pointer = *(unsigned char**)Pointer;
847 TRACE("deref => %p\n", Pointer);
849 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
850 if (m) m(pStubMsg, Pointer, desc);
851 else FIXME("no marshaller for data type=%02x\n", *desc);
854 STD_OVERFLOW_CHECK(pStubMsg);
857 /***********************************************************************
858 * PointerUnmarshall [internal]
860 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
861 unsigned char *Buffer,
862 unsigned char **pPointer,
863 unsigned char *pSrcPointer,
864 PFORMAT_STRING pFormat,
865 unsigned char fMustAlloc)
867 unsigned type = pFormat[0], attr = pFormat[1];
870 DWORD pointer_id = 0;
871 int pointer_needs_unmarshaling;
873 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
874 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
876 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
877 else desc = pFormat + *(const SHORT*)pFormat;
880 case RPC_FC_RP: /* ref pointer (always non-null) */
881 pointer_needs_unmarshaling = 1;
883 case RPC_FC_UP: /* unique pointer */
884 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
885 TRACE("pointer_id is 0x%08x\n", pointer_id);
887 pointer_needs_unmarshaling = 1;
890 pointer_needs_unmarshaling = 0;
893 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
894 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
895 TRACE("pointer_id is 0x%08x\n", pointer_id);
896 if (!fMustAlloc && pSrcPointer)
898 FIXME("free object pointer %p\n", pSrcPointer);
902 pointer_needs_unmarshaling = 1;
906 pointer_needs_unmarshaling = 0;
910 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
911 TRACE("pointer_id is 0x%08x\n", pointer_id);
912 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
913 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
916 FIXME("unhandled ptr type=%02x\n", type);
917 RpcRaiseException(RPC_X_BAD_STUB_DATA);
921 if (pointer_needs_unmarshaling) {
922 unsigned char *base_ptr_val = *pPointer;
923 unsigned char **current_ptr = pPointer;
924 if (pStubMsg->IsClient) {
926 /* if we aren't forcing allocation of memory then try to use the existing
927 * (source) pointer to unmarshall the data into so that [in,out]
928 * parameters behave correctly. it doesn't matter if the parameter is
929 * [out] only since in that case the pointer will be NULL. we force
930 * allocation when the source pointer is NULL here instead of in the type
931 * unmarshalling routine for the benefit of the deref code below */
934 TRACE("setting *pPointer to %p\n", pSrcPointer);
935 *pPointer = base_ptr_val = pSrcPointer;
941 /* the memory in a stub is never initialised, so we have to work out here
942 * whether we have to initialise it so we can use the optimisation of
943 * setting the pointer to the buffer, if possible, or set fMustAlloc to
945 if (attr & RPC_FC_P_DEREF) {
953 if (attr & RPC_FC_P_ALLOCALLNODES)
954 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
956 if (attr & RPC_FC_P_DEREF) {
958 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
959 *pPointer = base_ptr_val;
960 current_ptr = (unsigned char **)base_ptr_val;
962 current_ptr = *(unsigned char***)current_ptr;
963 TRACE("deref => %p\n", current_ptr);
964 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
966 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
967 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
968 else FIXME("no unmarshaller for data type=%02x\n", *desc);
970 if (type == RPC_FC_FP)
971 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
975 TRACE("pointer=%p\n", *pPointer);
978 /***********************************************************************
979 * PointerBufferSize [internal]
981 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
982 unsigned char *Pointer,
983 PFORMAT_STRING pFormat)
985 unsigned type = pFormat[0], attr = pFormat[1];
988 int pointer_needs_sizing;
991 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
992 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
994 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
995 else desc = pFormat + *(const SHORT*)pFormat;
998 case RPC_FC_RP: /* ref pointer (always non-null) */
1001 ERR("NULL ref pointer is not allowed\n");
1002 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1007 /* NULL pointer has no further representation */
1012 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1013 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1014 if (!pointer_needs_sizing)
1018 FIXME("unhandled ptr type=%02x\n", type);
1019 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1023 if (attr & RPC_FC_P_DEREF) {
1024 Pointer = *(unsigned char**)Pointer;
1025 TRACE("deref => %p\n", Pointer);
1028 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1029 if (m) m(pStubMsg, Pointer, desc);
1030 else FIXME("no buffersizer for data type=%02x\n", *desc);
1033 /***********************************************************************
1034 * PointerMemorySize [internal]
1036 static ULONG PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1037 unsigned char *Buffer, PFORMAT_STRING pFormat)
1039 unsigned type = pFormat[0], attr = pFormat[1];
1040 PFORMAT_STRING desc;
1042 DWORD pointer_id = 0;
1043 int pointer_needs_sizing;
1045 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1046 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1048 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1049 else desc = pFormat + *(const SHORT*)pFormat;
1052 case RPC_FC_RP: /* ref pointer (always non-null) */
1053 pointer_needs_sizing = 1;
1055 case RPC_FC_UP: /* unique pointer */
1056 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1057 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1058 TRACE("pointer_id is 0x%08x\n", pointer_id);
1060 pointer_needs_sizing = 1;
1062 pointer_needs_sizing = 0;
1067 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1068 TRACE("pointer_id is 0x%08x\n", pointer_id);
1069 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1070 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1074 FIXME("unhandled ptr type=%02x\n", type);
1075 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1079 if (attr & RPC_FC_P_DEREF) {
1080 align_length(&pStubMsg->MemorySize, sizeof(void*));
1081 pStubMsg->MemorySize += sizeof(void*);
1085 if (pointer_needs_sizing) {
1086 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1087 if (m) m(pStubMsg, desc);
1088 else FIXME("no memorysizer for data type=%02x\n", *desc);
1091 return pStubMsg->MemorySize;
1094 /***********************************************************************
1095 * PointerFree [internal]
1097 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1098 unsigned char *Pointer,
1099 PFORMAT_STRING pFormat)
1101 unsigned type = pFormat[0], attr = pFormat[1];
1102 PFORMAT_STRING desc;
1104 unsigned char *current_pointer = Pointer;
1106 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1107 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1108 if (attr & RPC_FC_P_DONTFREE) return;
1110 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1111 else desc = pFormat + *(const SHORT*)pFormat;
1113 if (!Pointer) return;
1115 if (type == RPC_FC_FP) {
1116 int pointer_needs_freeing = NdrFullPointerFree(
1117 pStubMsg->FullPtrXlatTables, Pointer);
1118 if (!pointer_needs_freeing)
1122 if (attr & RPC_FC_P_DEREF) {
1123 current_pointer = *(unsigned char**)Pointer;
1124 TRACE("deref => %p\n", current_pointer);
1127 m = NdrFreer[*desc & NDR_TABLE_MASK];
1128 if (m) m(pStubMsg, current_pointer, desc);
1130 /* this check stops us from trying to free buffer memory. we don't have to
1131 * worry about clients, since they won't call this function.
1132 * we don't have to check for the buffer being reallocated because
1133 * BufferStart and BufferEnd won't be reset when allocating memory for
1134 * sending the response. we don't have to check for the new buffer here as
1135 * it won't be used a type memory, only for buffer memory */
1136 if (Pointer >= pStubMsg->BufferStart && Pointer < pStubMsg->BufferEnd)
1139 if (attr & RPC_FC_P_ONSTACK) {
1140 TRACE("not freeing stack ptr %p\n", Pointer);
1143 TRACE("freeing %p\n", Pointer);
1144 NdrFree(pStubMsg, Pointer);
1147 TRACE("not freeing %p\n", Pointer);
1150 /***********************************************************************
1151 * EmbeddedPointerMarshall
1153 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1154 unsigned char *pMemory,
1155 PFORMAT_STRING pFormat)
1157 unsigned char *Mark = pStubMsg->BufferMark;
1158 unsigned rep, count, stride;
1160 unsigned char *saved_buffer = NULL;
1162 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1164 if (*pFormat != RPC_FC_PP) return NULL;
1167 if (pStubMsg->PointerBufferMark)
1169 saved_buffer = pStubMsg->Buffer;
1170 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1171 pStubMsg->PointerBufferMark = NULL;
1174 while (pFormat[0] != RPC_FC_END) {
1175 switch (pFormat[0]) {
1177 FIXME("unknown repeat type %d\n", pFormat[0]);
1178 case RPC_FC_NO_REPEAT:
1184 case RPC_FC_FIXED_REPEAT:
1185 rep = *(const WORD*)&pFormat[2];
1186 stride = *(const WORD*)&pFormat[4];
1187 count = *(const WORD*)&pFormat[8];
1190 case RPC_FC_VARIABLE_REPEAT:
1191 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1192 stride = *(const WORD*)&pFormat[2];
1193 count = *(const WORD*)&pFormat[6];
1197 for (i = 0; i < rep; i++) {
1198 PFORMAT_STRING info = pFormat;
1199 unsigned char *membase = pMemory + (i * stride);
1200 unsigned char *bufbase = Mark + (i * stride);
1203 for (u=0; u<count; u++,info+=8) {
1204 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1205 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1206 unsigned char *saved_memory = pStubMsg->Memory;
1208 pStubMsg->Memory = pMemory;
1209 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1210 pStubMsg->Memory = saved_memory;
1213 pFormat += 8 * count;
1218 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1219 pStubMsg->Buffer = saved_buffer;
1222 STD_OVERFLOW_CHECK(pStubMsg);
1227 /***********************************************************************
1228 * EmbeddedPointerUnmarshall
1230 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1231 unsigned char *pDstBuffer,
1232 unsigned char *pSrcMemoryPtrs,
1233 PFORMAT_STRING pFormat,
1234 unsigned char fMustAlloc)
1236 unsigned char *Mark = pStubMsg->BufferMark;
1237 unsigned rep, count, stride;
1239 unsigned char *saved_buffer = NULL;
1241 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc);
1243 if (*pFormat != RPC_FC_PP) return NULL;
1246 if (pStubMsg->PointerBufferMark)
1248 saved_buffer = pStubMsg->Buffer;
1249 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1250 pStubMsg->PointerBufferMark = NULL;
1253 while (pFormat[0] != RPC_FC_END) {
1254 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1255 switch (pFormat[0]) {
1257 FIXME("unknown repeat type %d\n", pFormat[0]);
1258 case RPC_FC_NO_REPEAT:
1264 case RPC_FC_FIXED_REPEAT:
1265 rep = *(const WORD*)&pFormat[2];
1266 stride = *(const WORD*)&pFormat[4];
1267 count = *(const WORD*)&pFormat[8];
1270 case RPC_FC_VARIABLE_REPEAT:
1271 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1272 stride = *(const WORD*)&pFormat[2];
1273 count = *(const WORD*)&pFormat[6];
1277 for (i = 0; i < rep; i++) {
1278 PFORMAT_STRING info = pFormat;
1279 unsigned char *bufdstbase = pDstBuffer + (i * stride);
1280 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1281 unsigned char *bufbase = Mark + (i * stride);
1284 for (u=0; u<count; u++,info+=8) {
1285 unsigned char **bufdstptr = (unsigned char **)(bufdstbase + *(const SHORT*)&info[2]);
1286 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1287 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1288 PointerUnmarshall(pStubMsg, bufptr, bufdstptr, *memsrcptr, info+4, fMustAlloc);
1291 pFormat += 8 * count;
1296 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1297 pStubMsg->Buffer = saved_buffer;
1303 /***********************************************************************
1304 * EmbeddedPointerBufferSize
1306 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1307 unsigned char *pMemory,
1308 PFORMAT_STRING pFormat)
1310 unsigned rep, count, stride;
1312 ULONG saved_buffer_length = 0;
1314 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1316 if (pStubMsg->IgnoreEmbeddedPointers) return;
1318 if (*pFormat != RPC_FC_PP) return;
1321 if (pStubMsg->PointerLength)
1323 saved_buffer_length = pStubMsg->BufferLength;
1324 pStubMsg->BufferLength = pStubMsg->PointerLength;
1325 pStubMsg->PointerLength = 0;
1328 while (pFormat[0] != RPC_FC_END) {
1329 switch (pFormat[0]) {
1331 FIXME("unknown repeat type %d\n", pFormat[0]);
1332 case RPC_FC_NO_REPEAT:
1338 case RPC_FC_FIXED_REPEAT:
1339 rep = *(const WORD*)&pFormat[2];
1340 stride = *(const WORD*)&pFormat[4];
1341 count = *(const WORD*)&pFormat[8];
1344 case RPC_FC_VARIABLE_REPEAT:
1345 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1346 stride = *(const WORD*)&pFormat[2];
1347 count = *(const WORD*)&pFormat[6];
1351 for (i = 0; i < rep; i++) {
1352 PFORMAT_STRING info = pFormat;
1353 unsigned char *membase = pMemory + (i * stride);
1356 for (u=0; u<count; u++,info+=8) {
1357 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1358 unsigned char *saved_memory = pStubMsg->Memory;
1360 pStubMsg->Memory = pMemory;
1361 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1362 pStubMsg->Memory = saved_memory;
1365 pFormat += 8 * count;
1368 if (saved_buffer_length)
1370 pStubMsg->PointerLength = pStubMsg->BufferLength;
1371 pStubMsg->BufferLength = saved_buffer_length;
1375 /***********************************************************************
1376 * EmbeddedPointerMemorySize [internal]
1378 static ULONG EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1379 PFORMAT_STRING pFormat)
1381 unsigned char *Mark = pStubMsg->BufferMark;
1382 unsigned rep, count, stride;
1384 unsigned char *saved_buffer = NULL;
1386 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1388 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1390 if (pStubMsg->PointerBufferMark)
1392 saved_buffer = pStubMsg->Buffer;
1393 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1394 pStubMsg->PointerBufferMark = NULL;
1397 if (*pFormat != RPC_FC_PP) return 0;
1400 while (pFormat[0] != RPC_FC_END) {
1401 switch (pFormat[0]) {
1403 FIXME("unknown repeat type %d\n", pFormat[0]);
1404 case RPC_FC_NO_REPEAT:
1410 case RPC_FC_FIXED_REPEAT:
1411 rep = *(const WORD*)&pFormat[2];
1412 stride = *(const WORD*)&pFormat[4];
1413 count = *(const WORD*)&pFormat[8];
1416 case RPC_FC_VARIABLE_REPEAT:
1417 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1418 stride = *(const WORD*)&pFormat[2];
1419 count = *(const WORD*)&pFormat[6];
1423 for (i = 0; i < rep; i++) {
1424 PFORMAT_STRING info = pFormat;
1425 unsigned char *bufbase = Mark + (i * stride);
1427 for (u=0; u<count; u++,info+=8) {
1428 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1429 PointerMemorySize(pStubMsg, bufptr, info+4);
1432 pFormat += 8 * count;
1437 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1438 pStubMsg->Buffer = saved_buffer;
1444 /***********************************************************************
1445 * EmbeddedPointerFree [internal]
1447 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1448 unsigned char *pMemory,
1449 PFORMAT_STRING pFormat)
1451 unsigned rep, count, stride;
1454 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1455 if (*pFormat != RPC_FC_PP) return;
1458 while (pFormat[0] != RPC_FC_END) {
1459 switch (pFormat[0]) {
1461 FIXME("unknown repeat type %d\n", pFormat[0]);
1462 case RPC_FC_NO_REPEAT:
1468 case RPC_FC_FIXED_REPEAT:
1469 rep = *(const WORD*)&pFormat[2];
1470 stride = *(const WORD*)&pFormat[4];
1471 count = *(const WORD*)&pFormat[8];
1474 case RPC_FC_VARIABLE_REPEAT:
1475 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1476 stride = *(const WORD*)&pFormat[2];
1477 count = *(const WORD*)&pFormat[6];
1481 for (i = 0; i < rep; i++) {
1482 PFORMAT_STRING info = pFormat;
1483 unsigned char *membase = pMemory + (i * stride);
1486 for (u=0; u<count; u++,info+=8) {
1487 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1488 unsigned char *saved_memory = pStubMsg->Memory;
1490 pStubMsg->Memory = pMemory;
1491 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1492 pStubMsg->Memory = saved_memory;
1495 pFormat += 8 * count;
1499 /***********************************************************************
1500 * NdrPointerMarshall [RPCRT4.@]
1502 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1503 unsigned char *pMemory,
1504 PFORMAT_STRING pFormat)
1506 unsigned char *Buffer;
1508 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1510 /* Increment the buffer here instead of in PointerMarshall,
1511 * as that is used by embedded pointers which already handle the incrementing
1512 * the buffer, and shouldn't write any additional pointer data to the wire */
1513 if (*pFormat != RPC_FC_RP)
1515 align_pointer_clear(&pStubMsg->Buffer, 4);
1516 Buffer = pStubMsg->Buffer;
1517 safe_buffer_increment(pStubMsg, 4);
1520 Buffer = pStubMsg->Buffer;
1522 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1527 /***********************************************************************
1528 * NdrPointerUnmarshall [RPCRT4.@]
1530 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1531 unsigned char **ppMemory,
1532 PFORMAT_STRING pFormat,
1533 unsigned char fMustAlloc)
1535 unsigned char *Buffer;
1537 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1539 if (*pFormat == RPC_FC_RP)
1541 Buffer = pStubMsg->Buffer;
1542 /* Do the NULL ref pointer check here because embedded pointers can be
1543 * NULL if the type the pointer is embedded in was allocated rather than
1544 * being passed in by the client */
1545 if (pStubMsg->IsClient && !*ppMemory)
1547 ERR("NULL ref pointer is not allowed\n");
1548 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1553 /* Increment the buffer here instead of in PointerUnmarshall,
1554 * as that is used by embedded pointers which already handle the incrementing
1555 * the buffer, and shouldn't read any additional pointer data from the
1557 align_pointer(&pStubMsg->Buffer, 4);
1558 Buffer = pStubMsg->Buffer;
1559 safe_buffer_increment(pStubMsg, 4);
1562 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1567 /***********************************************************************
1568 * NdrPointerBufferSize [RPCRT4.@]
1570 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1571 unsigned char *pMemory,
1572 PFORMAT_STRING pFormat)
1574 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1576 /* Increment the buffer length here instead of in PointerBufferSize,
1577 * as that is used by embedded pointers which already handle the buffer
1578 * length, and shouldn't write anything more to the wire */
1579 if (*pFormat != RPC_FC_RP)
1581 align_length(&pStubMsg->BufferLength, 4);
1582 safe_buffer_length_increment(pStubMsg, 4);
1585 PointerBufferSize(pStubMsg, pMemory, pFormat);
1588 /***********************************************************************
1589 * NdrPointerMemorySize [RPCRT4.@]
1591 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1592 PFORMAT_STRING pFormat)
1594 unsigned char *Buffer = pStubMsg->Buffer;
1595 if (*pFormat != RPC_FC_RP)
1597 align_pointer(&pStubMsg->Buffer, 4);
1598 safe_buffer_increment(pStubMsg, 4);
1600 align_length(&pStubMsg->MemorySize, sizeof(void *));
1601 return PointerMemorySize(pStubMsg, Buffer, pFormat);
1604 /***********************************************************************
1605 * NdrPointerFree [RPCRT4.@]
1607 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1608 unsigned char *pMemory,
1609 PFORMAT_STRING pFormat)
1611 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1612 PointerFree(pStubMsg, pMemory, pFormat);
1615 /***********************************************************************
1616 * NdrSimpleTypeMarshall [RPCRT4.@]
1618 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1619 unsigned char FormatChar )
1621 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1624 /***********************************************************************
1625 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1627 * Unmarshall a base type.
1630 * Doesn't check that the buffer is long enough before copying, so the caller
1633 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1634 unsigned char FormatChar )
1636 #define BASE_TYPE_UNMARSHALL(type) \
1637 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
1638 TRACE("pMemory: %p\n", pMemory); \
1639 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1640 pStubMsg->Buffer += sizeof(type);
1648 BASE_TYPE_UNMARSHALL(UCHAR);
1649 TRACE("value: 0x%02x\n", *pMemory);
1654 BASE_TYPE_UNMARSHALL(USHORT);
1655 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
1659 case RPC_FC_ERROR_STATUS_T:
1661 BASE_TYPE_UNMARSHALL(ULONG);
1662 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
1665 BASE_TYPE_UNMARSHALL(float);
1666 TRACE("value: %f\n", *(float *)pMemory);
1669 BASE_TYPE_UNMARSHALL(double);
1670 TRACE("value: %f\n", *(double *)pMemory);
1673 BASE_TYPE_UNMARSHALL(ULONGLONG);
1674 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
1677 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
1678 TRACE("pMemory: %p\n", pMemory);
1679 /* 16-bits on the wire, but int in memory */
1680 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
1681 pStubMsg->Buffer += sizeof(USHORT);
1682 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
1684 case RPC_FC_INT3264:
1685 align_pointer(&pStubMsg->Buffer, sizeof(INT));
1686 /* 32-bits on the wire, but int_ptr in memory */
1687 *(INT_PTR *)pMemory = *(INT *)pStubMsg->Buffer;
1688 pStubMsg->Buffer += sizeof(INT);
1689 TRACE("value: 0x%08lx\n", *(INT_PTR *)pMemory);
1691 case RPC_FC_UINT3264:
1692 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
1693 /* 32-bits on the wire, but int_ptr in memory */
1694 *(UINT_PTR *)pMemory = *(UINT *)pStubMsg->Buffer;
1695 pStubMsg->Buffer += sizeof(UINT);
1696 TRACE("value: 0x%08lx\n", *(UINT_PTR *)pMemory);
1701 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
1703 #undef BASE_TYPE_UNMARSHALL
1706 /***********************************************************************
1707 * NdrSimpleStructMarshall [RPCRT4.@]
1709 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1710 unsigned char *pMemory,
1711 PFORMAT_STRING pFormat)
1713 unsigned size = *(const WORD*)(pFormat+2);
1714 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1716 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1);
1718 pStubMsg->BufferMark = pStubMsg->Buffer;
1719 safe_copy_to_buffer(pStubMsg, pMemory, size);
1721 if (pFormat[0] != RPC_FC_STRUCT)
1722 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1727 /***********************************************************************
1728 * NdrSimpleStructUnmarshall [RPCRT4.@]
1730 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1731 unsigned char **ppMemory,
1732 PFORMAT_STRING pFormat,
1733 unsigned char fMustAlloc)
1735 unsigned size = *(const WORD*)(pFormat+2);
1736 unsigned char *saved_buffer;
1737 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1739 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
1742 *ppMemory = NdrAllocate(pStubMsg, size);
1745 if (!pStubMsg->IsClient && !*ppMemory)
1746 /* for servers, we just point straight into the RPC buffer */
1747 *ppMemory = pStubMsg->Buffer;
1750 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1751 safe_buffer_increment(pStubMsg, size);
1752 if (pFormat[0] == RPC_FC_PSTRUCT)
1753 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1755 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1756 if (*ppMemory != saved_buffer)
1757 memcpy(*ppMemory, saved_buffer, size);
1762 /***********************************************************************
1763 * NdrSimpleStructBufferSize [RPCRT4.@]
1765 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1766 unsigned char *pMemory,
1767 PFORMAT_STRING pFormat)
1769 unsigned size = *(const WORD*)(pFormat+2);
1770 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1772 align_length(&pStubMsg->BufferLength, pFormat[1] + 1);
1774 safe_buffer_length_increment(pStubMsg, size);
1775 if (pFormat[0] != RPC_FC_STRUCT)
1776 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1779 /***********************************************************************
1780 * NdrSimpleStructMemorySize [RPCRT4.@]
1782 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1783 PFORMAT_STRING pFormat)
1785 unsigned short size = *(const WORD *)(pFormat+2);
1787 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1789 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
1790 pStubMsg->MemorySize += size;
1791 safe_buffer_increment(pStubMsg, size);
1793 if (pFormat[0] != RPC_FC_STRUCT)
1794 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1795 return pStubMsg->MemorySize;
1798 /***********************************************************************
1799 * NdrSimpleStructFree [RPCRT4.@]
1801 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1802 unsigned char *pMemory,
1803 PFORMAT_STRING pFormat)
1805 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1806 if (pFormat[0] != RPC_FC_STRUCT)
1807 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1812 static inline void array_compute_and_size_conformance(
1813 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1814 PFORMAT_STRING pFormat)
1821 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1822 SizeConformance(pStubMsg);
1824 case RPC_FC_CVARRAY:
1825 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1826 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1827 SizeConformance(pStubMsg);
1829 case RPC_FC_C_CSTRING:
1830 case RPC_FC_C_WSTRING:
1831 if (fc == RPC_FC_C_CSTRING)
1833 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1834 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1838 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1839 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1842 if (pFormat[1] == RPC_FC_STRING_SIZED)
1843 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1845 pStubMsg->MaxCount = pStubMsg->ActualCount;
1847 SizeConformance(pStubMsg);
1849 case RPC_FC_BOGUS_ARRAY:
1850 count = *(const WORD *)(pFormat + 2);
1852 if (IsConformanceOrVariancePresent(pFormat)) SizeConformance(pStubMsg);
1853 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, count);
1854 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
1857 ERR("unknown array format 0x%x\n", fc);
1858 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1862 static inline void array_buffer_size(
1863 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1864 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1868 unsigned char alignment;
1873 esize = *(const WORD*)(pFormat+2);
1874 alignment = pFormat[1] + 1;
1876 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1878 align_length(&pStubMsg->BufferLength, alignment);
1880 size = safe_multiply(esize, pStubMsg->MaxCount);
1881 /* conformance value plus array */
1882 safe_buffer_length_increment(pStubMsg, size);
1885 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1887 case RPC_FC_CVARRAY:
1888 esize = *(const WORD*)(pFormat+2);
1889 alignment = pFormat[1] + 1;
1891 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1892 pFormat = SkipVariance(pStubMsg, pFormat);
1894 SizeVariance(pStubMsg);
1896 align_length(&pStubMsg->BufferLength, alignment);
1898 size = safe_multiply(esize, pStubMsg->ActualCount);
1899 safe_buffer_length_increment(pStubMsg, size);
1902 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1904 case RPC_FC_C_CSTRING:
1905 case RPC_FC_C_WSTRING:
1906 if (fc == RPC_FC_C_CSTRING)
1911 SizeVariance(pStubMsg);
1913 size = safe_multiply(esize, pStubMsg->ActualCount);
1914 safe_buffer_length_increment(pStubMsg, size);
1916 case RPC_FC_BOGUS_ARRAY:
1917 alignment = pFormat[1] + 1;
1918 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1919 if (IsConformanceOrVariancePresent(pFormat)) SizeVariance(pStubMsg);
1920 pFormat = SkipVariance(pStubMsg, pFormat);
1922 align_length(&pStubMsg->BufferLength, alignment);
1924 size = pStubMsg->ActualCount;
1925 for (i = 0; i < size; i++)
1926 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
1929 ERR("unknown array format 0x%x\n", fc);
1930 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1934 static inline void array_compute_and_write_conformance(
1935 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1936 PFORMAT_STRING pFormat)
1939 BOOL conformance_present;
1944 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1945 WriteConformance(pStubMsg);
1947 case RPC_FC_CVARRAY:
1948 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1949 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1950 WriteConformance(pStubMsg);
1952 case RPC_FC_C_CSTRING:
1953 case RPC_FC_C_WSTRING:
1954 if (fc == RPC_FC_C_CSTRING)
1956 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1957 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1961 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1962 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1964 if (pFormat[1] == RPC_FC_STRING_SIZED)
1965 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1967 pStubMsg->MaxCount = pStubMsg->ActualCount;
1968 pStubMsg->Offset = 0;
1969 WriteConformance(pStubMsg);
1971 case RPC_FC_BOGUS_ARRAY:
1972 def = *(const WORD *)(pFormat + 2);
1974 conformance_present = IsConformanceOrVariancePresent(pFormat);
1975 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
1976 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
1977 if (conformance_present) WriteConformance(pStubMsg);
1980 ERR("unknown array format 0x%x\n", fc);
1981 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1985 static inline void array_write_variance_and_marshall(
1986 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1987 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1991 unsigned char alignment;
1996 esize = *(const WORD*)(pFormat+2);
1997 alignment = pFormat[1] + 1;
1999 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2001 align_pointer_clear(&pStubMsg->Buffer, alignment);
2003 size = safe_multiply(esize, pStubMsg->MaxCount);
2005 pStubMsg->BufferMark = pStubMsg->Buffer;
2006 safe_copy_to_buffer(pStubMsg, pMemory, size);
2009 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2011 case RPC_FC_CVARRAY:
2012 esize = *(const WORD*)(pFormat+2);
2013 alignment = pFormat[1] + 1;
2015 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2016 pFormat = SkipVariance(pStubMsg, pFormat);
2018 WriteVariance(pStubMsg);
2020 align_pointer_clear(&pStubMsg->Buffer, alignment);
2022 size = safe_multiply(esize, pStubMsg->ActualCount);
2025 pStubMsg->BufferMark = pStubMsg->Buffer;
2026 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size);
2029 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2031 case RPC_FC_C_CSTRING:
2032 case RPC_FC_C_WSTRING:
2033 if (fc == RPC_FC_C_CSTRING)
2038 WriteVariance(pStubMsg);
2040 size = safe_multiply(esize, pStubMsg->ActualCount);
2041 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2043 case RPC_FC_BOGUS_ARRAY:
2044 alignment = pFormat[1] + 1;
2045 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2046 if (IsConformanceOrVariancePresent(pFormat)) WriteVariance(pStubMsg);
2047 pFormat = SkipVariance(pStubMsg, pFormat);
2049 align_pointer_clear(&pStubMsg->Buffer, alignment);
2051 size = pStubMsg->ActualCount;
2052 for (i = 0; i < size; i++)
2053 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2056 ERR("unknown array format 0x%x\n", fc);
2057 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2061 static inline ULONG array_read_conformance(
2062 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
2069 esize = *(const WORD*)(pFormat+2);
2070 pFormat = ReadConformance(pStubMsg, pFormat+4);
2071 return safe_multiply(esize, pStubMsg->MaxCount);
2072 case RPC_FC_CVARRAY:
2073 esize = *(const WORD*)(pFormat+2);
2074 pFormat = ReadConformance(pStubMsg, pFormat+4);
2075 return safe_multiply(esize, pStubMsg->MaxCount);
2076 case RPC_FC_C_CSTRING:
2077 case RPC_FC_C_WSTRING:
2078 if (fc == RPC_FC_C_CSTRING)
2083 if (pFormat[1] == RPC_FC_STRING_SIZED)
2084 ReadConformance(pStubMsg, pFormat + 2);
2086 ReadConformance(pStubMsg, NULL);
2087 return safe_multiply(esize, pStubMsg->MaxCount);
2088 case RPC_FC_BOGUS_ARRAY:
2089 def = *(const WORD *)(pFormat + 2);
2091 if (IsConformanceOrVariancePresent(pFormat)) pFormat = ReadConformance(pStubMsg, pFormat);
2094 pStubMsg->MaxCount = def;
2095 pFormat = SkipConformance( pStubMsg, pFormat );
2097 pFormat = SkipVariance( pStubMsg, pFormat );
2099 esize = ComplexStructSize(pStubMsg, pFormat);
2100 return safe_multiply(pStubMsg->MaxCount, esize);
2102 ERR("unknown array format 0x%x\n", fc);
2103 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2107 static inline ULONG array_read_variance_and_unmarshall(
2108 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory,
2109 PFORMAT_STRING pFormat, unsigned char fMustAlloc,
2110 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall)
2112 ULONG bufsize, memsize;
2114 unsigned char alignment;
2115 unsigned char *saved_buffer, *pMemory;
2116 ULONG i, offset, count;
2121 esize = *(const WORD*)(pFormat+2);
2122 alignment = pFormat[1] + 1;
2124 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2126 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2128 align_pointer(&pStubMsg->Buffer, alignment);
2133 *ppMemory = NdrAllocate(pStubMsg, memsize);
2136 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory)
2137 /* for servers, we just point straight into the RPC buffer */
2138 *ppMemory = pStubMsg->Buffer;
2141 saved_buffer = pStubMsg->Buffer;
2142 safe_buffer_increment(pStubMsg, bufsize);
2144 pStubMsg->BufferMark = saved_buffer;
2145 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2147 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2148 if (*ppMemory != saved_buffer)
2149 memcpy(*ppMemory, saved_buffer, bufsize);
2152 case RPC_FC_CVARRAY:
2153 esize = *(const WORD*)(pFormat+2);
2154 alignment = pFormat[1] + 1;
2156 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2158 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2160 align_pointer(&pStubMsg->Buffer, alignment);
2162 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2163 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2167 offset = pStubMsg->Offset;
2169 if (!fMustAlloc && !*ppMemory)
2172 *ppMemory = NdrAllocate(pStubMsg, memsize);
2173 saved_buffer = pStubMsg->Buffer;
2174 safe_buffer_increment(pStubMsg, bufsize);
2176 pStubMsg->BufferMark = saved_buffer;
2177 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat,
2180 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2183 case RPC_FC_C_CSTRING:
2184 case RPC_FC_C_WSTRING:
2185 if (fc == RPC_FC_C_CSTRING)
2190 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2192 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2194 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2195 pStubMsg->ActualCount, pStubMsg->MaxCount);
2196 RpcRaiseException(RPC_S_INVALID_BOUND);
2198 if (pStubMsg->Offset)
2200 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2201 RpcRaiseException(RPC_S_INVALID_BOUND);
2204 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2205 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2207 validate_string_data(pStubMsg, bufsize, esize);
2212 *ppMemory = NdrAllocate(pStubMsg, memsize);
2215 if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
2216 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
2217 /* if the data in the RPC buffer is big enough, we just point
2218 * straight into it */
2219 *ppMemory = pStubMsg->Buffer;
2220 else if (!*ppMemory)
2221 *ppMemory = NdrAllocate(pStubMsg, memsize);
2224 if (*ppMemory == pStubMsg->Buffer)
2225 safe_buffer_increment(pStubMsg, bufsize);
2227 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2229 if (*pFormat == RPC_FC_C_CSTRING)
2230 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
2232 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
2236 case RPC_FC_BOGUS_ARRAY:
2237 alignment = pFormat[1] + 1;
2238 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2239 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2241 esize = ComplexStructSize(pStubMsg, pFormat);
2242 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2244 assert( fUnmarshall );
2246 if (!fMustAlloc && !*ppMemory)
2249 *ppMemory = NdrAllocate(pStubMsg, memsize);
2251 align_pointer(&pStubMsg->Buffer, alignment);
2252 saved_buffer = pStubMsg->Buffer;
2254 pMemory = *ppMemory;
2255 count = pStubMsg->ActualCount;
2256 for (i = 0; i < count; i++)
2257 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
2258 return pStubMsg->Buffer - saved_buffer;
2261 ERR("unknown array format 0x%x\n", fc);
2262 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2266 static inline void array_memory_size(
2267 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
2268 unsigned char fHasPointers)
2270 ULONG i, count, SavedMemorySize;
2271 ULONG bufsize, memsize;
2273 unsigned char alignment;
2278 esize = *(const WORD*)(pFormat+2);
2279 alignment = pFormat[1] + 1;
2281 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2283 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2284 pStubMsg->MemorySize += memsize;
2286 align_pointer(&pStubMsg->Buffer, alignment);
2288 pStubMsg->BufferMark = pStubMsg->Buffer;
2289 safe_buffer_increment(pStubMsg, bufsize);
2292 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2294 case RPC_FC_CVARRAY:
2295 esize = *(const WORD*)(pFormat+2);
2296 alignment = pFormat[1] + 1;
2298 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2300 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2302 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2303 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2304 pStubMsg->MemorySize += memsize;
2306 align_pointer(&pStubMsg->Buffer, alignment);
2308 pStubMsg->BufferMark = pStubMsg->Buffer;
2309 safe_buffer_increment(pStubMsg, bufsize);
2312 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2314 case RPC_FC_C_CSTRING:
2315 case RPC_FC_C_WSTRING:
2316 if (fc == RPC_FC_C_CSTRING)
2321 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2323 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2325 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2326 pStubMsg->ActualCount, pStubMsg->MaxCount);
2327 RpcRaiseException(RPC_S_INVALID_BOUND);
2329 if (pStubMsg->Offset)
2331 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2332 RpcRaiseException(RPC_S_INVALID_BOUND);
2335 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2336 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2338 validate_string_data(pStubMsg, bufsize, esize);
2340 safe_buffer_increment(pStubMsg, bufsize);
2341 pStubMsg->MemorySize += memsize;
2343 case RPC_FC_BOGUS_ARRAY:
2344 alignment = pFormat[1] + 1;
2345 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2346 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2348 align_pointer(&pStubMsg->Buffer, alignment);
2350 SavedMemorySize = pStubMsg->MemorySize;
2352 esize = ComplexStructSize(pStubMsg, pFormat);
2353 memsize = safe_multiply(pStubMsg->MaxCount, esize);
2355 count = pStubMsg->ActualCount;
2356 for (i = 0; i < count; i++)
2357 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
2359 pStubMsg->MemorySize = SavedMemorySize + memsize;
2362 ERR("unknown array format 0x%x\n", fc);
2363 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2367 static inline void array_free(
2368 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
2369 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
2376 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2378 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2380 case RPC_FC_CVARRAY:
2381 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2382 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2384 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2386 case RPC_FC_C_CSTRING:
2387 case RPC_FC_C_WSTRING:
2388 /* No embedded pointers so nothing to do */
2390 case RPC_FC_BOGUS_ARRAY:
2391 count = *(const WORD *)(pFormat + 2);
2392 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, count);
2393 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2395 count = pStubMsg->ActualCount;
2396 for (i = 0; i < count; i++)
2397 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2400 ERR("unknown array format 0x%x\n", fc);
2401 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2406 * NdrConformantString:
2408 * What MS calls a ConformantString is, in DCE terminology,
2409 * a Varying-Conformant String.
2411 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2412 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2413 * into unmarshalled string)
2414 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2416 * data: CHARTYPE[maxlen]
2418 * ], where CHARTYPE is the appropriate character type (specified externally)
2422 /***********************************************************************
2423 * NdrConformantStringMarshall [RPCRT4.@]
2425 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
2426 unsigned char *pszMessage, PFORMAT_STRING pFormat)
2428 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
2430 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2431 ERR("Unhandled string type: %#x\n", pFormat[0]);
2432 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2435 /* allow compiler to optimise inline function by passing constant into
2436 * these functions */
2437 if (pFormat[0] == RPC_FC_C_CSTRING) {
2438 array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2440 array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2441 pFormat, TRUE /* fHasPointers */);
2443 array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2445 array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2446 pFormat, TRUE /* fHasPointers */);
2452 /***********************************************************************
2453 * NdrConformantStringBufferSize [RPCRT4.@]
2455 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2456 unsigned char* pMemory, PFORMAT_STRING pFormat)
2458 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2460 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2461 ERR("Unhandled string type: %#x\n", pFormat[0]);
2462 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2465 /* allow compiler to optimise inline function by passing constant into
2466 * these functions */
2467 if (pFormat[0] == RPC_FC_C_CSTRING) {
2468 array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory,
2470 array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat,
2471 TRUE /* fHasPointers */);
2473 array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory,
2475 array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat,
2476 TRUE /* fHasPointers */);
2480 /************************************************************************
2481 * NdrConformantStringMemorySize [RPCRT4.@]
2483 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2484 PFORMAT_STRING pFormat )
2486 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2488 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2489 ERR("Unhandled string type: %#x\n", pFormat[0]);
2490 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2493 /* allow compiler to optimise inline function by passing constant into
2494 * these functions */
2495 if (pFormat[0] == RPC_FC_C_CSTRING) {
2496 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2497 array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat,
2498 TRUE /* fHasPointers */);
2500 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2501 array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat,
2502 TRUE /* fHasPointers */);
2505 return pStubMsg->MemorySize;
2508 /************************************************************************
2509 * NdrConformantStringUnmarshall [RPCRT4.@]
2511 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2512 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
2514 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2515 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2517 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2518 ERR("Unhandled string type: %#x\n", *pFormat);
2519 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2522 /* allow compiler to optimise inline function by passing constant into
2523 * these functions */
2524 if (pFormat[0] == RPC_FC_C_CSTRING) {
2525 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2526 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory,
2527 pFormat, fMustAlloc,
2528 TRUE /* fUseBufferMemoryServer */,
2529 TRUE /* fUnmarshall */);
2531 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2532 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory,
2533 pFormat, fMustAlloc,
2534 TRUE /* fUseBufferMemoryServer */,
2535 TRUE /* fUnmarshall */);
2541 /***********************************************************************
2542 * NdrNonConformantStringMarshall [RPCRT4.@]
2544 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2545 unsigned char *pMemory,
2546 PFORMAT_STRING pFormat)
2548 ULONG esize, size, maxsize;
2550 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2552 maxsize = *(const USHORT *)&pFormat[2];
2554 if (*pFormat == RPC_FC_CSTRING)
2557 const char *str = (const char *)pMemory;
2558 while (i < maxsize && str[i]) i++;
2559 TRACE("string=%s\n", debugstr_an(str, i));
2560 pStubMsg->ActualCount = i + 1;
2563 else if (*pFormat == RPC_FC_WSTRING)
2566 const WCHAR *str = (const WCHAR *)pMemory;
2567 while (i < maxsize && str[i]) i++;
2568 TRACE("string=%s\n", debugstr_wn(str, i));
2569 pStubMsg->ActualCount = i + 1;
2574 ERR("Unhandled string type: %#x\n", *pFormat);
2575 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2578 pStubMsg->Offset = 0;
2579 WriteVariance(pStubMsg);
2581 size = safe_multiply(esize, pStubMsg->ActualCount);
2582 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2587 /***********************************************************************
2588 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2590 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2591 unsigned char **ppMemory,
2592 PFORMAT_STRING pFormat,
2593 unsigned char fMustAlloc)
2595 ULONG bufsize, memsize, esize, maxsize;
2597 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2598 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2600 maxsize = *(const USHORT *)&pFormat[2];
2602 ReadVariance(pStubMsg, NULL, maxsize);
2603 if (pStubMsg->Offset)
2605 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2606 RpcRaiseException(RPC_S_INVALID_BOUND);
2609 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2610 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2613 ERR("Unhandled string type: %#x\n", *pFormat);
2614 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2617 memsize = esize * maxsize;
2618 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2620 validate_string_data(pStubMsg, bufsize, esize);
2622 if (!fMustAlloc && !*ppMemory)
2625 *ppMemory = NdrAllocate(pStubMsg, memsize);
2627 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2629 if (*pFormat == RPC_FC_CSTRING) {
2630 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
2632 else if (*pFormat == RPC_FC_WSTRING) {
2633 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
2639 /***********************************************************************
2640 * NdrNonConformantStringBufferSize [RPCRT4.@]
2642 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2643 unsigned char *pMemory,
2644 PFORMAT_STRING pFormat)
2646 ULONG esize, maxsize;
2648 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2650 maxsize = *(const USHORT *)&pFormat[2];
2652 SizeVariance(pStubMsg);
2654 if (*pFormat == RPC_FC_CSTRING)
2657 const char *str = (const char *)pMemory;
2658 while (i < maxsize && str[i]) i++;
2659 TRACE("string=%s\n", debugstr_an(str, i));
2660 pStubMsg->ActualCount = i + 1;
2663 else if (*pFormat == RPC_FC_WSTRING)
2666 const WCHAR *str = (const WCHAR *)pMemory;
2667 while (i < maxsize && str[i]) i++;
2668 TRACE("string=%s\n", debugstr_wn(str, i));
2669 pStubMsg->ActualCount = i + 1;
2674 ERR("Unhandled string type: %#x\n", *pFormat);
2675 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2678 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2681 /***********************************************************************
2682 * NdrNonConformantStringMemorySize [RPCRT4.@]
2684 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2685 PFORMAT_STRING pFormat)
2687 ULONG bufsize, memsize, esize, maxsize;
2689 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2691 maxsize = *(const USHORT *)&pFormat[2];
2693 ReadVariance(pStubMsg, NULL, maxsize);
2695 if (pStubMsg->Offset)
2697 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2698 RpcRaiseException(RPC_S_INVALID_BOUND);
2701 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2702 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2705 ERR("Unhandled string type: %#x\n", *pFormat);
2706 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2709 memsize = esize * maxsize;
2710 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2712 validate_string_data(pStubMsg, bufsize, esize);
2714 safe_buffer_increment(pStubMsg, bufsize);
2715 pStubMsg->MemorySize += memsize;
2717 return pStubMsg->MemorySize;
2722 #include "pshpack1.h"
2726 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2730 #include "poppack.h"
2732 static ULONG EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2733 PFORMAT_STRING pFormat)
2737 case RPC_FC_PSTRUCT:
2738 case RPC_FC_CSTRUCT:
2739 case RPC_FC_BOGUS_STRUCT:
2740 case RPC_FC_SMFARRAY:
2741 case RPC_FC_SMVARRAY:
2742 case RPC_FC_CSTRING:
2743 return *(const WORD*)&pFormat[2];
2744 case RPC_FC_USER_MARSHAL:
2745 return *(const WORD*)&pFormat[4];
2746 case RPC_FC_RANGE: {
2747 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2752 return sizeof(UCHAR);
2756 return sizeof(USHORT);
2760 case RPC_FC_INT3264:
2761 case RPC_FC_UINT3264:
2762 return sizeof(ULONG);
2764 return sizeof(float);
2766 return sizeof(double);
2768 return sizeof(ULONGLONG);
2770 return sizeof(UINT);
2772 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2773 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2776 case RPC_FC_NON_ENCAPSULATED_UNION:
2778 if (pStubMsg->fHasNewCorrDesc)
2783 pFormat += *(const SHORT*)pFormat;
2784 return *(const SHORT*)pFormat;
2786 return sizeof(void *);
2787 case RPC_FC_WSTRING:
2788 return *(const WORD*)&pFormat[2] * 2;
2790 FIXME("unhandled embedded type %02x\n", *pFormat);
2796 static ULONG EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2797 PFORMAT_STRING pFormat)
2799 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2803 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2807 return m(pStubMsg, pFormat);
2811 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2812 unsigned char *pMemory,
2813 PFORMAT_STRING pFormat,
2814 PFORMAT_STRING pPointer)
2816 PFORMAT_STRING desc;
2820 while (*pFormat != RPC_FC_END) {
2826 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2827 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2833 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2834 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2839 USHORT val = *(DWORD *)pMemory;
2840 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2841 if (32767 < *(DWORD*)pMemory)
2842 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2843 safe_copy_to_buffer(pStubMsg, &val, 2);
2850 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2851 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2854 case RPC_FC_INT3264:
2855 case RPC_FC_UINT3264:
2857 UINT val = *(UINT_PTR *)pMemory;
2858 TRACE("int3264=%ld <= %p\n", *(UINT_PTR *)pMemory, pMemory);
2859 safe_copy_to_buffer(pStubMsg, &val, sizeof(UINT));
2860 pMemory += sizeof(UINT_PTR);
2864 TRACE("float=%f <= %p\n", *(float*)pMemory, pMemory);
2865 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
2866 pMemory += sizeof(float);
2869 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2870 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2874 TRACE("double=%f <= %p\n", *(double*)pMemory, pMemory);
2875 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
2876 pMemory += sizeof(double);
2882 case RPC_FC_POINTER:
2884 unsigned char *saved_buffer;
2885 int pointer_buffer_mark_set = 0;
2886 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2887 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2888 if (*pFormat != RPC_FC_POINTER)
2890 if (*pPointer != RPC_FC_RP)
2891 align_pointer_clear(&pStubMsg->Buffer, 4);
2892 saved_buffer = pStubMsg->Buffer;
2893 if (pStubMsg->PointerBufferMark)
2895 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2896 pStubMsg->PointerBufferMark = NULL;
2897 pointer_buffer_mark_set = 1;
2899 else if (*pPointer != RPC_FC_RP)
2900 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2901 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2902 if (pointer_buffer_mark_set)
2904 STD_OVERFLOW_CHECK(pStubMsg);
2905 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2906 pStubMsg->Buffer = saved_buffer;
2907 if (*pPointer != RPC_FC_RP)
2908 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2910 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2911 if (*pFormat == RPC_FC_POINTER)
2915 pMemory += sizeof(void *);
2918 case RPC_FC_ALIGNM2:
2919 align_pointer(&pMemory, 2);
2921 case RPC_FC_ALIGNM4:
2922 align_pointer(&pMemory, 4);
2924 case RPC_FC_ALIGNM8:
2925 align_pointer(&pMemory, 8);
2927 case RPC_FC_STRUCTPAD1:
2928 case RPC_FC_STRUCTPAD2:
2929 case RPC_FC_STRUCTPAD3:
2930 case RPC_FC_STRUCTPAD4:
2931 case RPC_FC_STRUCTPAD5:
2932 case RPC_FC_STRUCTPAD6:
2933 case RPC_FC_STRUCTPAD7:
2934 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2936 case RPC_FC_EMBEDDED_COMPLEX:
2937 pMemory += pFormat[1];
2939 desc = pFormat + *(const SHORT*)pFormat;
2940 size = EmbeddedComplexSize(pStubMsg, desc);
2941 TRACE("embedded complex (size=%d) <= %p\n", size, pMemory);
2942 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2945 /* for some reason interface pointers aren't generated as
2946 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2947 * they still need the derefencing treatment that pointers are
2949 if (*desc == RPC_FC_IP)
2950 m(pStubMsg, *(unsigned char **)pMemory, desc);
2952 m(pStubMsg, pMemory, desc);
2954 else FIXME("no marshaller for embedded type %02x\n", *desc);
2961 FIXME("unhandled format 0x%02x\n", *pFormat);
2969 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2970 unsigned char *pMemory,
2971 PFORMAT_STRING pFormat,
2972 PFORMAT_STRING pPointer,
2973 unsigned char fMustAlloc)
2975 PFORMAT_STRING desc;
2979 while (*pFormat != RPC_FC_END) {
2985 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2986 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2992 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2993 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2999 safe_copy_from_buffer(pStubMsg, &val, 2);
3000 *(DWORD*)pMemory = val;
3001 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
3002 if (32767 < *(DWORD*)pMemory)
3003 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
3010 safe_copy_from_buffer(pStubMsg, pMemory, 4);
3011 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
3014 case RPC_FC_INT3264:
3017 safe_copy_from_buffer(pStubMsg, &val, 4);
3018 *(INT_PTR *)pMemory = val;
3019 TRACE("int3264=%ld => %p\n", *(INT_PTR*)pMemory, pMemory);
3020 pMemory += sizeof(INT_PTR);
3023 case RPC_FC_UINT3264:
3026 safe_copy_from_buffer(pStubMsg, &val, 4);
3027 *(UINT_PTR *)pMemory = val;
3028 TRACE("uint3264=%ld => %p\n", *(UINT_PTR*)pMemory, pMemory);
3029 pMemory += sizeof(UINT_PTR);
3033 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(float));
3034 TRACE("float=%f => %p\n", *(float*)pMemory, pMemory);
3035 pMemory += sizeof(float);
3038 safe_copy_from_buffer(pStubMsg, pMemory, 8);
3039 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
3043 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(double));
3044 TRACE("double=%f => %p\n", *(double*)pMemory, pMemory);
3045 pMemory += sizeof(double);
3051 case RPC_FC_POINTER:
3053 unsigned char *saved_buffer;
3054 int pointer_buffer_mark_set = 0;
3055 TRACE("pointer => %p\n", pMemory);
3056 if (*pFormat != RPC_FC_POINTER)
3058 if (*pPointer != RPC_FC_RP)
3059 align_pointer(&pStubMsg->Buffer, 4);
3060 saved_buffer = pStubMsg->Buffer;
3061 if (pStubMsg->PointerBufferMark)
3063 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3064 pStubMsg->PointerBufferMark = NULL;
3065 pointer_buffer_mark_set = 1;
3067 else if (*pPointer != RPC_FC_RP)
3068 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3070 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
3071 if (pointer_buffer_mark_set)
3073 STD_OVERFLOW_CHECK(pStubMsg);
3074 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3075 pStubMsg->Buffer = saved_buffer;
3076 if (*pPointer != RPC_FC_RP)
3077 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3079 if (*pFormat == RPC_FC_POINTER)
3083 pMemory += sizeof(void *);
3086 case RPC_FC_ALIGNM2:
3087 align_pointer_clear(&pMemory, 2);
3089 case RPC_FC_ALIGNM4:
3090 align_pointer_clear(&pMemory, 4);
3092 case RPC_FC_ALIGNM8:
3093 align_pointer_clear(&pMemory, 8);
3095 case RPC_FC_STRUCTPAD1:
3096 case RPC_FC_STRUCTPAD2:
3097 case RPC_FC_STRUCTPAD3:
3098 case RPC_FC_STRUCTPAD4:
3099 case RPC_FC_STRUCTPAD5:
3100 case RPC_FC_STRUCTPAD6:
3101 case RPC_FC_STRUCTPAD7:
3102 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
3103 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3105 case RPC_FC_EMBEDDED_COMPLEX:
3106 pMemory += pFormat[1];
3108 desc = pFormat + *(const SHORT*)pFormat;
3109 size = EmbeddedComplexSize(pStubMsg, desc);
3110 TRACE("embedded complex (size=%d) => %p\n", size, pMemory);
3112 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
3113 * since the type is part of the memory block that is encompassed by
3114 * the whole complex type. Memory is forced to allocate when pointers
3115 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
3116 * clearing the memory we pass in to the unmarshaller */
3117 memset(pMemory, 0, size);
3118 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
3121 /* for some reason interface pointers aren't generated as
3122 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3123 * they still need the derefencing treatment that pointers are
3125 if (*desc == RPC_FC_IP)
3126 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
3128 m(pStubMsg, &pMemory, desc, FALSE);
3130 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
3137 FIXME("unhandled format %d\n", *pFormat);
3145 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3146 unsigned char *pMemory,
3147 PFORMAT_STRING pFormat,
3148 PFORMAT_STRING pPointer)
3150 PFORMAT_STRING desc;
3154 while (*pFormat != RPC_FC_END) {
3160 safe_buffer_length_increment(pStubMsg, 1);
3166 safe_buffer_length_increment(pStubMsg, 2);
3170 safe_buffer_length_increment(pStubMsg, 2);
3177 safe_buffer_length_increment(pStubMsg, 4);
3180 case RPC_FC_INT3264:
3181 case RPC_FC_UINT3264:
3182 safe_buffer_length_increment(pStubMsg, 4);
3183 pMemory += sizeof(INT_PTR);
3187 safe_buffer_length_increment(pStubMsg, 8);
3194 case RPC_FC_POINTER:
3195 if (*pFormat != RPC_FC_POINTER)
3197 if (!pStubMsg->IgnoreEmbeddedPointers)
3199 int saved_buffer_length = pStubMsg->BufferLength;
3200 pStubMsg->BufferLength = pStubMsg->PointerLength;
3201 pStubMsg->PointerLength = 0;
3202 if(!pStubMsg->BufferLength)
3203 ERR("BufferLength == 0??\n");
3204 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
3205 pStubMsg->PointerLength = pStubMsg->BufferLength;
3206 pStubMsg->BufferLength = saved_buffer_length;
3208 if (*pPointer != RPC_FC_RP)
3210 align_length(&pStubMsg->BufferLength, 4);
3211 safe_buffer_length_increment(pStubMsg, 4);
3213 if (*pFormat == RPC_FC_POINTER)
3217 pMemory += sizeof(void*);
3219 case RPC_FC_ALIGNM2:
3220 align_pointer(&pMemory, 2);
3222 case RPC_FC_ALIGNM4:
3223 align_pointer(&pMemory, 4);
3225 case RPC_FC_ALIGNM8:
3226 align_pointer(&pMemory, 8);
3228 case RPC_FC_STRUCTPAD1:
3229 case RPC_FC_STRUCTPAD2:
3230 case RPC_FC_STRUCTPAD3:
3231 case RPC_FC_STRUCTPAD4:
3232 case RPC_FC_STRUCTPAD5:
3233 case RPC_FC_STRUCTPAD6:
3234 case RPC_FC_STRUCTPAD7:
3235 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3237 case RPC_FC_EMBEDDED_COMPLEX:
3238 pMemory += pFormat[1];
3240 desc = pFormat + *(const SHORT*)pFormat;
3241 size = EmbeddedComplexSize(pStubMsg, desc);
3242 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
3245 /* for some reason interface pointers aren't generated as
3246 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3247 * they still need the derefencing treatment that pointers are
3249 if (*desc == RPC_FC_IP)
3250 m(pStubMsg, *(unsigned char **)pMemory, desc);
3252 m(pStubMsg, pMemory, desc);
3254 else FIXME("no buffersizer for embedded type %02x\n", *desc);
3261 FIXME("unhandled format 0x%02x\n", *pFormat);
3269 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
3270 unsigned char *pMemory,
3271 PFORMAT_STRING pFormat,
3272 PFORMAT_STRING pPointer)
3274 PFORMAT_STRING desc;
3278 while (*pFormat != RPC_FC_END) {
3298 case RPC_FC_INT3264:
3299 case RPC_FC_UINT3264:
3300 pMemory += sizeof(INT_PTR);
3310 case RPC_FC_POINTER:
3311 if (*pFormat != RPC_FC_POINTER)
3313 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3314 if (*pFormat == RPC_FC_POINTER)
3318 pMemory += sizeof(void *);
3320 case RPC_FC_ALIGNM2:
3321 align_pointer(&pMemory, 2);
3323 case RPC_FC_ALIGNM4:
3324 align_pointer(&pMemory, 4);
3326 case RPC_FC_ALIGNM8:
3327 align_pointer(&pMemory, 8);
3329 case RPC_FC_STRUCTPAD1:
3330 case RPC_FC_STRUCTPAD2:
3331 case RPC_FC_STRUCTPAD3:
3332 case RPC_FC_STRUCTPAD4:
3333 case RPC_FC_STRUCTPAD5:
3334 case RPC_FC_STRUCTPAD6:
3335 case RPC_FC_STRUCTPAD7:
3336 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3338 case RPC_FC_EMBEDDED_COMPLEX:
3339 pMemory += pFormat[1];
3341 desc = pFormat + *(const SHORT*)pFormat;
3342 size = EmbeddedComplexSize(pStubMsg, desc);
3343 m = NdrFreer[*desc & NDR_TABLE_MASK];
3346 /* for some reason interface pointers aren't generated as
3347 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3348 * they still need the derefencing treatment that pointers are
3350 if (*desc == RPC_FC_IP)
3351 m(pStubMsg, *(unsigned char **)pMemory, desc);
3353 m(pStubMsg, pMemory, desc);
3361 FIXME("unhandled format 0x%02x\n", *pFormat);
3369 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3370 PFORMAT_STRING pFormat,
3371 PFORMAT_STRING pPointer)
3373 PFORMAT_STRING desc;
3376 while (*pFormat != RPC_FC_END) {
3383 safe_buffer_increment(pStubMsg, 1);
3389 safe_buffer_increment(pStubMsg, 2);
3393 safe_buffer_increment(pStubMsg, 2);
3400 safe_buffer_increment(pStubMsg, 4);
3402 case RPC_FC_INT3264:
3403 case RPC_FC_UINT3264:
3404 size += sizeof(INT_PTR);
3405 safe_buffer_increment(pStubMsg, 4);
3410 safe_buffer_increment(pStubMsg, 8);
3416 case RPC_FC_POINTER:
3418 unsigned char *saved_buffer;
3419 int pointer_buffer_mark_set = 0;
3420 if (*pFormat != RPC_FC_POINTER)
3422 if (*pPointer != RPC_FC_RP)
3423 align_pointer(&pStubMsg->Buffer, 4);
3424 saved_buffer = pStubMsg->Buffer;
3425 if (pStubMsg->PointerBufferMark)
3427 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3428 pStubMsg->PointerBufferMark = NULL;
3429 pointer_buffer_mark_set = 1;
3431 else if (*pPointer != RPC_FC_RP)
3432 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3434 if (!pStubMsg->IgnoreEmbeddedPointers)
3435 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3436 if (pointer_buffer_mark_set)
3438 STD_OVERFLOW_CHECK(pStubMsg);
3439 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3440 pStubMsg->Buffer = saved_buffer;
3441 if (*pPointer != RPC_FC_RP)
3442 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3444 if (*pFormat == RPC_FC_POINTER)
3448 size += sizeof(void *);
3451 case RPC_FC_ALIGNM2:
3452 align_length(&size, 2);
3454 case RPC_FC_ALIGNM4:
3455 align_length(&size, 4);
3457 case RPC_FC_ALIGNM8:
3458 align_length(&size, 8);
3460 case RPC_FC_STRUCTPAD1:
3461 case RPC_FC_STRUCTPAD2:
3462 case RPC_FC_STRUCTPAD3:
3463 case RPC_FC_STRUCTPAD4:
3464 case RPC_FC_STRUCTPAD5:
3465 case RPC_FC_STRUCTPAD6:
3466 case RPC_FC_STRUCTPAD7:
3467 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3469 case RPC_FC_EMBEDDED_COMPLEX:
3472 desc = pFormat + *(const SHORT*)pFormat;
3473 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3479 FIXME("unhandled format 0x%02x\n", *pFormat);
3487 ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
3489 PFORMAT_STRING desc;
3492 while (*pFormat != RPC_FC_END) {
3512 case RPC_FC_INT3264:
3513 case RPC_FC_UINT3264:
3514 size += sizeof(INT_PTR);
3524 case RPC_FC_POINTER:
3525 size += sizeof(void *);
3526 if (*pFormat != RPC_FC_POINTER)
3529 case RPC_FC_ALIGNM2:
3530 align_length(&size, 2);
3532 case RPC_FC_ALIGNM4:
3533 align_length(&size, 4);
3535 case RPC_FC_ALIGNM8:
3536 align_length(&size, 8);
3538 case RPC_FC_STRUCTPAD1:
3539 case RPC_FC_STRUCTPAD2:
3540 case RPC_FC_STRUCTPAD3:
3541 case RPC_FC_STRUCTPAD4:
3542 case RPC_FC_STRUCTPAD5:
3543 case RPC_FC_STRUCTPAD6:
3544 case RPC_FC_STRUCTPAD7:
3545 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3547 case RPC_FC_EMBEDDED_COMPLEX:
3550 desc = pFormat + *(const SHORT*)pFormat;
3551 size += EmbeddedComplexSize(pStubMsg, desc);
3557 FIXME("unhandled format 0x%02x\n", *pFormat);
3565 /***********************************************************************
3566 * NdrComplexStructMarshall [RPCRT4.@]
3568 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3569 unsigned char *pMemory,
3570 PFORMAT_STRING pFormat)
3572 PFORMAT_STRING conf_array = NULL;
3573 PFORMAT_STRING pointer_desc = NULL;
3574 unsigned char *OldMemory = pStubMsg->Memory;
3575 int pointer_buffer_mark_set = 0;
3577 ULONG max_count = 0;
3580 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3582 if (!pStubMsg->PointerBufferMark)
3584 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3585 /* save buffer length */
3586 ULONG saved_buffer_length = pStubMsg->BufferLength;
3588 /* get the buffer pointer after complex array data, but before
3590 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3591 pStubMsg->IgnoreEmbeddedPointers = 1;
3592 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3593 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3595 /* save it for use by embedded pointer code later */
3596 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3597 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - pStubMsg->Buffer));
3598 pointer_buffer_mark_set = 1;
3600 /* restore the original buffer length */
3601 pStubMsg->BufferLength = saved_buffer_length;
3604 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1);
3607 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3609 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3612 pStubMsg->Memory = pMemory;
3616 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3617 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3618 pMemory + struct_size, conf_array);
3619 /* these could be changed in ComplexMarshall so save them for later */
3620 max_count = pStubMsg->MaxCount;
3621 count = pStubMsg->ActualCount;
3622 offset = pStubMsg->Offset;
3625 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3629 pStubMsg->MaxCount = max_count;
3630 pStubMsg->ActualCount = count;
3631 pStubMsg->Offset = offset;
3632 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3633 conf_array, TRUE /* fHasPointers */);
3636 pStubMsg->Memory = OldMemory;
3638 if (pointer_buffer_mark_set)
3640 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3641 pStubMsg->PointerBufferMark = NULL;
3644 STD_OVERFLOW_CHECK(pStubMsg);
3649 /***********************************************************************
3650 * NdrComplexStructUnmarshall [RPCRT4.@]
3652 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3653 unsigned char **ppMemory,
3654 PFORMAT_STRING pFormat,
3655 unsigned char fMustAlloc)
3657 unsigned size = *(const WORD*)(pFormat+2);
3658 PFORMAT_STRING conf_array = NULL;
3659 PFORMAT_STRING pointer_desc = NULL;
3660 unsigned char *pMemory;
3661 int pointer_buffer_mark_set = 0;
3663 ULONG max_count = 0;
3665 ULONG array_size = 0;
3667 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3669 if (!pStubMsg->PointerBufferMark)
3671 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3672 /* save buffer pointer */
3673 unsigned char *saved_buffer = pStubMsg->Buffer;
3675 /* get the buffer pointer after complex array data, but before
3677 pStubMsg->IgnoreEmbeddedPointers = 1;
3678 NdrComplexStructMemorySize(pStubMsg, pFormat);
3679 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3681 /* save it for use by embedded pointer code later */
3682 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3683 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - saved_buffer));
3684 pointer_buffer_mark_set = 1;
3686 /* restore the original buffer */
3687 pStubMsg->Buffer = saved_buffer;
3690 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3693 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3695 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3700 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3703 /* these could be changed in ComplexMarshall so save them for later */
3704 max_count = pStubMsg->MaxCount;
3705 count = pStubMsg->ActualCount;
3706 offset = pStubMsg->Offset;
3709 if (!fMustAlloc && !*ppMemory)
3712 *ppMemory = NdrAllocate(pStubMsg, size);
3714 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3718 pStubMsg->MaxCount = max_count;
3719 pStubMsg->ActualCount = count;
3720 pStubMsg->Offset = offset;
3722 memset(pMemory, 0, array_size);
3723 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3725 FALSE /* fUseBufferMemoryServer */,
3726 TRUE /* fUnmarshall */);
3729 if (pointer_buffer_mark_set)
3731 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3732 pStubMsg->PointerBufferMark = NULL;
3738 /***********************************************************************
3739 * NdrComplexStructBufferSize [RPCRT4.@]
3741 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3742 unsigned char *pMemory,
3743 PFORMAT_STRING pFormat)
3745 PFORMAT_STRING conf_array = NULL;
3746 PFORMAT_STRING pointer_desc = NULL;
3747 unsigned char *OldMemory = pStubMsg->Memory;
3748 int pointer_length_set = 0;
3750 ULONG max_count = 0;
3753 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3755 align_length(&pStubMsg->BufferLength, pFormat[1] + 1);
3757 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3759 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3760 ULONG saved_buffer_length = pStubMsg->BufferLength;
3762 /* get the buffer length after complex struct data, but before
3764 pStubMsg->IgnoreEmbeddedPointers = 1;
3765 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3766 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3768 /* save it for use by embedded pointer code later */
3769 pStubMsg->PointerLength = pStubMsg->BufferLength;
3770 pointer_length_set = 1;
3771 TRACE("difference = 0x%x\n", pStubMsg->PointerLength - saved_buffer_length);
3773 /* restore the original buffer length */
3774 pStubMsg->BufferLength = saved_buffer_length;
3778 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3780 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3783 pStubMsg->Memory = pMemory;
3787 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3788 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3791 /* these could be changed in ComplexMarshall so save them for later */
3792 max_count = pStubMsg->MaxCount;
3793 count = pStubMsg->ActualCount;
3794 offset = pStubMsg->Offset;
3797 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3801 pStubMsg->MaxCount = max_count;
3802 pStubMsg->ActualCount = count;
3803 pStubMsg->Offset = offset;
3804 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3805 TRUE /* fHasPointers */);
3808 pStubMsg->Memory = OldMemory;
3810 if(pointer_length_set)
3812 pStubMsg->BufferLength = pStubMsg->PointerLength;
3813 pStubMsg->PointerLength = 0;
3818 /***********************************************************************
3819 * NdrComplexStructMemorySize [RPCRT4.@]
3821 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3822 PFORMAT_STRING pFormat)
3824 unsigned size = *(const WORD*)(pFormat+2);
3825 PFORMAT_STRING conf_array = NULL;
3826 PFORMAT_STRING pointer_desc = NULL;
3828 ULONG max_count = 0;
3831 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3833 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3836 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3838 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3843 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3845 /* these could be changed in ComplexStructMemorySize so save them for
3847 max_count = pStubMsg->MaxCount;
3848 count = pStubMsg->ActualCount;
3849 offset = pStubMsg->Offset;
3852 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3856 pStubMsg->MaxCount = max_count;
3857 pStubMsg->ActualCount = count;
3858 pStubMsg->Offset = offset;
3859 array_memory_size(conf_array[0], pStubMsg, conf_array,
3860 TRUE /* fHasPointers */);
3866 /***********************************************************************
3867 * NdrComplexStructFree [RPCRT4.@]
3869 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3870 unsigned char *pMemory,
3871 PFORMAT_STRING pFormat)
3873 PFORMAT_STRING conf_array = NULL;
3874 PFORMAT_STRING pointer_desc = NULL;
3875 unsigned char *OldMemory = pStubMsg->Memory;
3877 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3880 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3882 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3885 pStubMsg->Memory = pMemory;
3887 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3890 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3891 TRUE /* fHasPointers */);
3893 pStubMsg->Memory = OldMemory;
3896 /***********************************************************************
3897 * NdrConformantArrayMarshall [RPCRT4.@]
3899 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3900 unsigned char *pMemory,
3901 PFORMAT_STRING pFormat)
3903 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3904 if (pFormat[0] != RPC_FC_CARRAY)
3906 ERR("invalid format = 0x%x\n", pFormat[0]);
3907 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3910 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory,
3912 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3913 TRUE /* fHasPointers */);
3918 /***********************************************************************
3919 * NdrConformantArrayUnmarshall [RPCRT4.@]
3921 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3922 unsigned char **ppMemory,
3923 PFORMAT_STRING pFormat,
3924 unsigned char fMustAlloc)
3926 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3927 if (pFormat[0] != RPC_FC_CARRAY)
3929 ERR("invalid format = 0x%x\n", pFormat[0]);
3930 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3933 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3934 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat,
3936 TRUE /* fUseBufferMemoryServer */,
3937 TRUE /* fUnmarshall */);
3942 /***********************************************************************
3943 * NdrConformantArrayBufferSize [RPCRT4.@]
3945 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3946 unsigned char *pMemory,
3947 PFORMAT_STRING pFormat)
3949 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3950 if (pFormat[0] != RPC_FC_CARRAY)
3952 ERR("invalid format = 0x%x\n", pFormat[0]);
3953 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3956 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat);
3957 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3958 TRUE /* fHasPointers */);
3961 /***********************************************************************
3962 * NdrConformantArrayMemorySize [RPCRT4.@]
3964 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3965 PFORMAT_STRING pFormat)
3967 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3968 if (pFormat[0] != RPC_FC_CARRAY)
3970 ERR("invalid format = 0x%x\n", pFormat[0]);
3971 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3974 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3975 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
3977 return pStubMsg->MemorySize;
3980 /***********************************************************************
3981 * NdrConformantArrayFree [RPCRT4.@]
3983 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3984 unsigned char *pMemory,
3985 PFORMAT_STRING pFormat)
3987 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3988 if (pFormat[0] != RPC_FC_CARRAY)
3990 ERR("invalid format = 0x%x\n", pFormat[0]);
3991 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3994 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3995 TRUE /* fHasPointers */);
3999 /***********************************************************************
4000 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
4002 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
4003 unsigned char* pMemory,
4004 PFORMAT_STRING pFormat )
4006 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4008 if (pFormat[0] != RPC_FC_CVARRAY)
4010 ERR("invalid format type %x\n", pFormat[0]);
4011 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4015 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
4017 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory,
4018 pFormat, TRUE /* fHasPointers */);
4024 /***********************************************************************
4025 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
4027 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
4028 unsigned char** ppMemory,
4029 PFORMAT_STRING pFormat,
4030 unsigned char fMustAlloc )
4032 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4034 if (pFormat[0] != RPC_FC_CVARRAY)
4036 ERR("invalid format type %x\n", pFormat[0]);
4037 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4041 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
4042 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory,
4043 pFormat, fMustAlloc,
4044 TRUE /* fUseBufferMemoryServer */,
4045 TRUE /* fUnmarshall */);
4051 /***********************************************************************
4052 * NdrConformantVaryingArrayFree [RPCRT4.@]
4054 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
4055 unsigned char* pMemory,
4056 PFORMAT_STRING pFormat )
4058 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4060 if (pFormat[0] != RPC_FC_CVARRAY)
4062 ERR("invalid format type %x\n", pFormat[0]);
4063 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4067 array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
4068 TRUE /* fHasPointers */);
4072 /***********************************************************************
4073 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
4075 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
4076 unsigned char* pMemory, PFORMAT_STRING pFormat )
4078 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4080 if (pFormat[0] != RPC_FC_CVARRAY)
4082 ERR("invalid format type %x\n", pFormat[0]);
4083 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4087 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
4089 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
4090 TRUE /* fHasPointers */);
4094 /***********************************************************************
4095 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
4097 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
4098 PFORMAT_STRING pFormat )
4100 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4102 if (pFormat[0] != RPC_FC_CVARRAY)
4104 ERR("invalid format type %x\n", pFormat[0]);
4105 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4106 return pStubMsg->MemorySize;
4109 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
4110 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat,
4111 TRUE /* fHasPointers */);
4113 return pStubMsg->MemorySize;
4117 /***********************************************************************
4118 * NdrComplexArrayMarshall [RPCRT4.@]
4120 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4121 unsigned char *pMemory,
4122 PFORMAT_STRING pFormat)
4124 int pointer_buffer_mark_set = 0;
4126 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4128 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4130 ERR("invalid format type %x\n", pFormat[0]);
4131 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4135 if (!pStubMsg->PointerBufferMark)
4137 /* save buffer fields that may be changed by buffer sizer functions
4138 * and that may be needed later on */
4139 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4140 ULONG saved_buffer_length = pStubMsg->BufferLength;
4141 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4142 ULONG saved_offset = pStubMsg->Offset;
4143 ULONG saved_actual_count = pStubMsg->ActualCount;
4145 /* get the buffer pointer after complex array data, but before
4147 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
4148 pStubMsg->IgnoreEmbeddedPointers = 1;
4149 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4150 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4152 /* save it for use by embedded pointer code later */
4153 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
4154 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer));
4155 pointer_buffer_mark_set = 1;
4157 /* restore fields */
4158 pStubMsg->ActualCount = saved_actual_count;
4159 pStubMsg->Offset = saved_offset;
4160 pStubMsg->MaxCount = saved_max_count;
4161 pStubMsg->BufferLength = saved_buffer_length;
4164 array_compute_and_write_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4165 array_write_variance_and_marshall(RPC_FC_BOGUS_ARRAY, pStubMsg,
4166 pMemory, pFormat, TRUE /* fHasPointers */);
4168 STD_OVERFLOW_CHECK(pStubMsg);
4170 if (pointer_buffer_mark_set)
4172 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4173 pStubMsg->PointerBufferMark = NULL;
4179 /***********************************************************************
4180 * NdrComplexArrayUnmarshall [RPCRT4.@]
4182 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4183 unsigned char **ppMemory,
4184 PFORMAT_STRING pFormat,
4185 unsigned char fMustAlloc)
4187 unsigned char *saved_buffer;
4188 int pointer_buffer_mark_set = 0;
4189 int saved_ignore_embedded;
4191 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4193 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4195 ERR("invalid format type %x\n", pFormat[0]);
4196 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4200 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4201 /* save buffer pointer */
4202 saved_buffer = pStubMsg->Buffer;
4203 /* get the buffer pointer after complex array data, but before
4205 pStubMsg->IgnoreEmbeddedPointers = 1;
4206 pStubMsg->MemorySize = 0;
4207 NdrComplexArrayMemorySize(pStubMsg, pFormat);
4208 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4210 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - saved_buffer));
4211 if (!pStubMsg->PointerBufferMark)
4213 /* save it for use by embedded pointer code later */
4214 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4215 pointer_buffer_mark_set = 1;
4217 /* restore the original buffer */
4218 pStubMsg->Buffer = saved_buffer;
4220 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
4221 array_read_variance_and_unmarshall(RPC_FC_BOGUS_ARRAY, pStubMsg, ppMemory, pFormat, fMustAlloc,
4222 TRUE /* fUseBufferMemoryServer */, TRUE /* fUnmarshall */);
4224 if (pointer_buffer_mark_set)
4226 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4227 pStubMsg->PointerBufferMark = NULL;
4233 /***********************************************************************
4234 * NdrComplexArrayBufferSize [RPCRT4.@]
4236 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4237 unsigned char *pMemory,
4238 PFORMAT_STRING pFormat)
4240 int pointer_length_set = 0;
4242 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4244 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4246 ERR("invalid format type %x\n", pFormat[0]);
4247 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4251 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
4253 /* save buffer fields that may be changed by buffer sizer functions
4254 * and that may be needed later on */
4255 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4256 ULONG saved_buffer_length = pStubMsg->BufferLength;
4257 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4258 ULONG saved_offset = pStubMsg->Offset;
4259 ULONG saved_actual_count = pStubMsg->ActualCount;
4261 /* get the buffer pointer after complex array data, but before
4263 pStubMsg->IgnoreEmbeddedPointers = 1;
4264 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4265 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4267 /* save it for use by embedded pointer code later */
4268 pStubMsg->PointerLength = pStubMsg->BufferLength;
4269 pointer_length_set = 1;
4271 /* restore fields */
4272 pStubMsg->ActualCount = saved_actual_count;
4273 pStubMsg->Offset = saved_offset;
4274 pStubMsg->MaxCount = saved_max_count;
4275 pStubMsg->BufferLength = saved_buffer_length;
4278 array_compute_and_size_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4279 array_buffer_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat, TRUE /* fHasPointers */);
4281 if(pointer_length_set)
4283 pStubMsg->BufferLength = pStubMsg->PointerLength;
4284 pStubMsg->PointerLength = 0;
4288 /***********************************************************************
4289 * NdrComplexArrayMemorySize [RPCRT4.@]
4291 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4292 PFORMAT_STRING pFormat)
4294 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4296 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4298 ERR("invalid format type %x\n", pFormat[0]);
4299 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4303 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
4304 array_memory_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
4305 return pStubMsg->MemorySize;
4308 /***********************************************************************
4309 * NdrComplexArrayFree [RPCRT4.@]
4311 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4312 unsigned char *pMemory,
4313 PFORMAT_STRING pFormat)
4315 ULONG i, count, def;
4317 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4319 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4321 ERR("invalid format type %x\n", pFormat[0]);
4322 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4326 def = *(const WORD*)&pFormat[2];
4329 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4330 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4332 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4333 TRACE("variance = %d\n", pStubMsg->ActualCount);
4335 count = pStubMsg->ActualCount;
4336 for (i = 0; i < count; i++)
4337 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4340 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4341 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4342 USER_MARSHAL_CB *umcb)
4344 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4345 pStubMsg->RpcMsg->DataRepresentation);
4346 umcb->pStubMsg = pStubMsg;
4347 umcb->pReserve = NULL;
4348 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4349 umcb->CBType = cbtype;
4350 umcb->pFormat = pFormat;
4351 umcb->pTypeFormat = NULL /* FIXME */;
4354 #define USER_MARSHAL_PTR_PREFIX \
4355 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4356 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4358 /***********************************************************************
4359 * NdrUserMarshalMarshall [RPCRT4.@]
4361 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4362 unsigned char *pMemory,
4363 PFORMAT_STRING pFormat)
4365 unsigned flags = pFormat[1];
4366 unsigned index = *(const WORD*)&pFormat[2];
4367 unsigned char *saved_buffer = NULL;
4368 USER_MARSHAL_CB umcb;
4370 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4371 TRACE("index=%d\n", index);
4373 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4375 if (flags & USER_MARSHAL_POINTER)
4377 align_pointer_clear(&pStubMsg->Buffer, 4);
4378 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4379 pStubMsg->Buffer += 4;
4380 if (pStubMsg->PointerBufferMark)
4382 saved_buffer = pStubMsg->Buffer;
4383 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4384 pStubMsg->PointerBufferMark = NULL;
4386 align_pointer_clear(&pStubMsg->Buffer, 8);
4389 align_pointer_clear(&pStubMsg->Buffer, (flags & 0xf) + 1);
4392 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4393 &umcb.Flags, pStubMsg->Buffer, pMemory);
4397 STD_OVERFLOW_CHECK(pStubMsg);
4398 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4399 pStubMsg->Buffer = saved_buffer;
4402 STD_OVERFLOW_CHECK(pStubMsg);
4407 /***********************************************************************
4408 * NdrUserMarshalUnmarshall [RPCRT4.@]
4410 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4411 unsigned char **ppMemory,
4412 PFORMAT_STRING pFormat,
4413 unsigned char fMustAlloc)
4415 unsigned flags = pFormat[1];
4416 unsigned index = *(const WORD*)&pFormat[2];
4417 DWORD memsize = *(const WORD*)&pFormat[4];
4418 unsigned char *saved_buffer = NULL;
4419 USER_MARSHAL_CB umcb;
4421 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4422 TRACE("index=%d\n", index);
4424 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4426 if (flags & USER_MARSHAL_POINTER)
4428 align_pointer(&pStubMsg->Buffer, 4);
4429 /* skip pointer prefix */
4430 pStubMsg->Buffer += 4;
4431 if (pStubMsg->PointerBufferMark)
4433 saved_buffer = pStubMsg->Buffer;
4434 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4435 pStubMsg->PointerBufferMark = NULL;
4437 align_pointer(&pStubMsg->Buffer, 8);
4440 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4442 if (!fMustAlloc && !*ppMemory)
4446 *ppMemory = NdrAllocate(pStubMsg, memsize);
4447 memset(*ppMemory, 0, memsize);
4451 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4452 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4456 STD_OVERFLOW_CHECK(pStubMsg);
4457 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4458 pStubMsg->Buffer = saved_buffer;
4464 /***********************************************************************
4465 * NdrUserMarshalBufferSize [RPCRT4.@]
4467 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4468 unsigned char *pMemory,
4469 PFORMAT_STRING pFormat)
4471 unsigned flags = pFormat[1];
4472 unsigned index = *(const WORD*)&pFormat[2];
4473 DWORD bufsize = *(const WORD*)&pFormat[6];
4474 USER_MARSHAL_CB umcb;
4475 ULONG saved_buffer_length = 0;
4477 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4478 TRACE("index=%d\n", index);
4480 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4482 if (flags & USER_MARSHAL_POINTER)
4484 align_length(&pStubMsg->BufferLength, 4);
4485 /* skip pointer prefix */
4486 safe_buffer_length_increment(pStubMsg, 4);
4487 if (pStubMsg->IgnoreEmbeddedPointers)
4489 if (pStubMsg->PointerLength)
4491 saved_buffer_length = pStubMsg->BufferLength;
4492 pStubMsg->BufferLength = pStubMsg->PointerLength;
4493 pStubMsg->PointerLength = 0;
4495 align_length(&pStubMsg->BufferLength, 8);
4498 align_length(&pStubMsg->BufferLength, (flags & 0xf) + 1);
4501 TRACE("size=%d\n", bufsize);
4502 safe_buffer_length_increment(pStubMsg, bufsize);
4505 pStubMsg->BufferLength =
4506 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4507 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4509 if (saved_buffer_length)
4511 pStubMsg->PointerLength = pStubMsg->BufferLength;
4512 pStubMsg->BufferLength = saved_buffer_length;
4517 /***********************************************************************
4518 * NdrUserMarshalMemorySize [RPCRT4.@]
4520 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4521 PFORMAT_STRING pFormat)
4523 unsigned flags = pFormat[1];
4524 unsigned index = *(const WORD*)&pFormat[2];
4525 DWORD memsize = *(const WORD*)&pFormat[4];
4526 DWORD bufsize = *(const WORD*)&pFormat[6];
4528 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4529 TRACE("index=%d\n", index);
4531 pStubMsg->MemorySize += memsize;
4533 if (flags & USER_MARSHAL_POINTER)
4535 align_pointer(&pStubMsg->Buffer, 4);
4536 /* skip pointer prefix */
4537 pStubMsg->Buffer += 4;
4538 if (pStubMsg->IgnoreEmbeddedPointers)
4539 return pStubMsg->MemorySize;
4540 align_pointer(&pStubMsg->Buffer, 8);
4543 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4546 FIXME("not implemented for varying buffer size\n");
4548 pStubMsg->Buffer += bufsize;
4550 return pStubMsg->MemorySize;
4553 /***********************************************************************
4554 * NdrUserMarshalFree [RPCRT4.@]
4556 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4557 unsigned char *pMemory,
4558 PFORMAT_STRING pFormat)
4560 /* unsigned flags = pFormat[1]; */
4561 unsigned index = *(const WORD*)&pFormat[2];
4562 USER_MARSHAL_CB umcb;
4564 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4565 TRACE("index=%d\n", index);
4567 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4569 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4570 &umcb.Flags, pMemory);
4573 /***********************************************************************
4574 * NdrGetUserMarshalInfo [RPCRT4.@]
4576 RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi)
4578 USER_MARSHAL_CB *umcb = CONTAINING_RECORD(flags, USER_MARSHAL_CB, Flags);
4580 TRACE("(%p,%u,%p)\n", flags, level, umi);
4583 return RPC_S_INVALID_ARG;
4585 memset(&umi->u1.Level1, 0, sizeof(umi->u1.Level1));
4586 umi->InformationLevel = level;
4588 if (umcb->Signature != USER_MARSHAL_CB_SIGNATURE)
4589 return RPC_S_INVALID_ARG;
4591 umi->u1.Level1.pfnAllocate = umcb->pStubMsg->pfnAllocate;
4592 umi->u1.Level1.pfnFree = umcb->pStubMsg->pfnFree;
4593 umi->u1.Level1.pRpcChannelBuffer = umcb->pStubMsg->pRpcChannelBuffer;
4595 switch (umcb->CBType)
4597 case USER_MARSHAL_CB_MARSHALL:
4598 case USER_MARSHAL_CB_UNMARSHALL:
4600 RPC_MESSAGE *msg = umcb->pStubMsg->RpcMsg;
4601 unsigned char *buffer_start = msg->Buffer;
4602 unsigned char *buffer_end =
4603 (unsigned char *)msg->Buffer + msg->BufferLength;
4605 if (umcb->pStubMsg->Buffer < buffer_start ||
4606 umcb->pStubMsg->Buffer > buffer_end)
4607 return ERROR_INVALID_USER_BUFFER;
4609 umi->u1.Level1.Buffer = umcb->pStubMsg->Buffer;
4610 umi->u1.Level1.BufferSize = buffer_end - umcb->pStubMsg->Buffer;
4613 case USER_MARSHAL_CB_BUFFER_SIZE:
4614 case USER_MARSHAL_CB_FREE:
4617 WARN("unrecognised CBType %d\n", umcb->CBType);
4623 /***********************************************************************
4624 * NdrClearOutParameters [RPCRT4.@]
4626 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4627 PFORMAT_STRING pFormat,
4630 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4633 /***********************************************************************
4634 * NdrConvert [RPCRT4.@]
4636 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4638 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4639 /* FIXME: since this stub doesn't do any converting, the proper behavior
4640 is to raise an exception */
4643 /***********************************************************************
4644 * NdrConvert2 [RPCRT4.@]
4646 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4648 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4649 pStubMsg, pFormat, NumberParams);
4650 /* FIXME: since this stub doesn't do any converting, the proper behavior
4651 is to raise an exception */
4654 #include "pshpack1.h"
4655 typedef struct _NDR_CSTRUCT_FORMAT
4658 unsigned char alignment;
4659 unsigned short memory_size;
4660 short offset_to_array_description;
4661 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4662 #include "poppack.h"
4664 /***********************************************************************
4665 * NdrConformantStructMarshall [RPCRT4.@]
4667 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4668 unsigned char *pMemory,
4669 PFORMAT_STRING pFormat)
4671 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4672 PFORMAT_STRING pCArrayFormat;
4673 ULONG esize, bufsize;
4675 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4677 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4678 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4680 ERR("invalid format type %x\n", pCStructFormat->type);
4681 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4685 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4686 pCStructFormat->offset_to_array_description;
4687 if (*pCArrayFormat != RPC_FC_CARRAY)
4689 ERR("invalid array format type %x\n", pCStructFormat->type);
4690 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4693 esize = *(const WORD*)(pCArrayFormat+2);
4695 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4696 pCArrayFormat + 4, 0);
4698 WriteConformance(pStubMsg);
4700 align_pointer_clear(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4702 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4704 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4705 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4707 ERR("integer overflow of memory_size %u with bufsize %u\n",
4708 pCStructFormat->memory_size, bufsize);
4709 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4711 /* copy constant sized part of struct */
4712 pStubMsg->BufferMark = pStubMsg->Buffer;
4713 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4715 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4716 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4721 /***********************************************************************
4722 * NdrConformantStructUnmarshall [RPCRT4.@]
4724 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4725 unsigned char **ppMemory,
4726 PFORMAT_STRING pFormat,
4727 unsigned char fMustAlloc)
4729 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4730 PFORMAT_STRING pCArrayFormat;
4731 ULONG esize, bufsize;
4732 unsigned char *saved_buffer;
4734 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4736 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4737 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4739 ERR("invalid format type %x\n", pCStructFormat->type);
4740 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4743 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4744 pCStructFormat->offset_to_array_description;
4745 if (*pCArrayFormat != RPC_FC_CARRAY)
4747 ERR("invalid array format type %x\n", pCStructFormat->type);
4748 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4751 esize = *(const WORD*)(pCArrayFormat+2);
4753 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4755 align_pointer(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4757 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4759 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4760 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4762 ERR("integer overflow of memory_size %u with bufsize %u\n",
4763 pCStructFormat->memory_size, bufsize);
4764 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4769 SIZE_T size = pCStructFormat->memory_size + bufsize;
4770 *ppMemory = NdrAllocate(pStubMsg, size);
4774 if (!pStubMsg->IsClient && !*ppMemory)
4775 /* for servers, we just point straight into the RPC buffer */
4776 *ppMemory = pStubMsg->Buffer;
4779 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4780 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4781 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4782 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4784 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4785 if (*ppMemory != saved_buffer)
4786 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4791 /***********************************************************************
4792 * NdrConformantStructBufferSize [RPCRT4.@]
4794 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4795 unsigned char *pMemory,
4796 PFORMAT_STRING pFormat)
4798 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4799 PFORMAT_STRING pCArrayFormat;
4802 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4804 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4805 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4807 ERR("invalid format type %x\n", pCStructFormat->type);
4808 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4811 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4812 pCStructFormat->offset_to_array_description;
4813 if (*pCArrayFormat != RPC_FC_CARRAY)
4815 ERR("invalid array format type %x\n", pCStructFormat->type);
4816 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4819 esize = *(const WORD*)(pCArrayFormat+2);
4821 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4822 SizeConformance(pStubMsg);
4824 align_length(&pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4826 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4828 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4829 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4831 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4832 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4835 /***********************************************************************
4836 * NdrConformantStructMemorySize [RPCRT4.@]
4838 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4839 PFORMAT_STRING pFormat)
4845 /***********************************************************************
4846 * NdrConformantStructFree [RPCRT4.@]
4848 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4849 unsigned char *pMemory,
4850 PFORMAT_STRING pFormat)
4852 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4853 PFORMAT_STRING pCArrayFormat;
4855 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4857 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4858 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4860 ERR("invalid format type %x\n", pCStructFormat->type);
4861 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4865 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4866 pCStructFormat->offset_to_array_description;
4867 if (*pCArrayFormat != RPC_FC_CARRAY)
4869 ERR("invalid array format type %x\n", pCStructFormat->type);
4870 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4874 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4875 pCArrayFormat + 4, 0);
4877 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4879 /* copy constant sized part of struct */
4880 pStubMsg->BufferMark = pStubMsg->Buffer;
4882 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4883 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4886 /***********************************************************************
4887 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4889 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4890 unsigned char *pMemory,
4891 PFORMAT_STRING pFormat)
4893 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4894 PFORMAT_STRING pCVArrayFormat;
4896 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4898 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4899 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4901 ERR("invalid format type %x\n", pCVStructFormat->type);
4902 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4906 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4907 pCVStructFormat->offset_to_array_description;
4909 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4910 pMemory + pCVStructFormat->memory_size,
4913 align_pointer_clear(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4915 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4917 /* write constant sized part */
4918 pStubMsg->BufferMark = pStubMsg->Buffer;
4919 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4921 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4922 pMemory + pCVStructFormat->memory_size,
4923 pCVArrayFormat, FALSE /* fHasPointers */);
4925 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4930 /***********************************************************************
4931 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4933 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4934 unsigned char **ppMemory,
4935 PFORMAT_STRING pFormat,
4936 unsigned char fMustAlloc)
4938 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4939 PFORMAT_STRING pCVArrayFormat;
4940 ULONG memsize, bufsize;
4941 unsigned char *saved_buffer, *saved_array_buffer;
4943 unsigned char *array_memory;
4945 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4947 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4948 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4950 ERR("invalid format type %x\n", pCVStructFormat->type);
4951 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4955 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4956 pCVStructFormat->offset_to_array_description;
4958 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4961 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4963 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4965 /* work out how much memory to allocate if we need to do so */
4966 if (!fMustAlloc && !*ppMemory)
4970 SIZE_T size = pCVStructFormat->memory_size + memsize;
4971 *ppMemory = NdrAllocate(pStubMsg, size);
4974 /* mark the start of the constant data */
4975 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4976 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4978 array_memory = *ppMemory + pCVStructFormat->memory_size;
4979 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
4980 &array_memory, pCVArrayFormat,
4981 FALSE /* fMustAlloc */,
4982 FALSE /* fUseServerBufferMemory */,
4983 FALSE /* fUnmarshall */);
4985 /* save offset in case unmarshalling pointers changes it */
4986 offset = pStubMsg->Offset;
4988 /* mark the start of the array data */
4989 saved_array_buffer = pStubMsg->Buffer;
4990 safe_buffer_increment(pStubMsg, bufsize);
4992 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4994 /* copy the constant data */
4995 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
4996 /* copy the array data */
4997 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
4998 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
4999 saved_array_buffer, bufsize);
5001 if (*pCVArrayFormat == RPC_FC_C_CSTRING)
5002 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
5003 else if (*pCVArrayFormat == RPC_FC_C_WSTRING)
5004 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
5009 /***********************************************************************
5010 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
5012 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5013 unsigned char *pMemory,
5014 PFORMAT_STRING pFormat)
5016 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5017 PFORMAT_STRING pCVArrayFormat;
5019 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5021 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5022 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5024 ERR("invalid format type %x\n", pCVStructFormat->type);
5025 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5029 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5030 pCVStructFormat->offset_to_array_description;
5031 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
5032 pMemory + pCVStructFormat->memory_size,
5035 align_length(&pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
5037 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5039 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
5041 array_buffer_size(*pCVArrayFormat, pStubMsg,
5042 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5043 FALSE /* fHasPointers */);
5045 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5048 /***********************************************************************
5049 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
5051 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5052 PFORMAT_STRING pFormat)
5054 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5055 PFORMAT_STRING pCVArrayFormat;
5057 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5059 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5060 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5062 ERR("invalid format type %x\n", pCVStructFormat->type);
5063 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5067 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5068 pCVStructFormat->offset_to_array_description;
5069 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
5071 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
5073 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5075 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
5076 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
5077 FALSE /* fHasPointers */);
5079 pStubMsg->MemorySize += pCVStructFormat->memory_size;
5081 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5083 return pStubMsg->MemorySize;
5086 /***********************************************************************
5087 * NdrConformantVaryingStructFree [RPCRT4.@]
5089 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
5090 unsigned char *pMemory,
5091 PFORMAT_STRING pFormat)
5093 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5094 PFORMAT_STRING pCVArrayFormat;
5096 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5098 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5099 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5101 ERR("invalid format type %x\n", pCVStructFormat->type);
5102 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5106 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5107 pCVStructFormat->offset_to_array_description;
5108 array_free(*pCVArrayFormat, pStubMsg,
5109 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5110 FALSE /* fHasPointers */);
5112 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5114 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5117 #include "pshpack1.h"
5121 unsigned char alignment;
5122 unsigned short total_size;
5123 } NDR_SMFARRAY_FORMAT;
5128 unsigned char alignment;
5130 } NDR_LGFARRAY_FORMAT;
5131 #include "poppack.h"
5133 /***********************************************************************
5134 * NdrFixedArrayMarshall [RPCRT4.@]
5136 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5137 unsigned char *pMemory,
5138 PFORMAT_STRING pFormat)
5140 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5143 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5145 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5146 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5148 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5149 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5153 align_pointer_clear(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5155 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5157 total_size = pSmFArrayFormat->total_size;
5158 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5162 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5163 total_size = pLgFArrayFormat->total_size;
5164 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5167 pStubMsg->BufferMark = pStubMsg->Buffer;
5168 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
5170 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5175 /***********************************************************************
5176 * NdrFixedArrayUnmarshall [RPCRT4.@]
5178 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5179 unsigned char **ppMemory,
5180 PFORMAT_STRING pFormat,
5181 unsigned char fMustAlloc)
5183 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5185 unsigned char *saved_buffer;
5187 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5189 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5190 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5192 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5193 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5197 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5199 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5201 total_size = pSmFArrayFormat->total_size;
5202 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5206 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5207 total_size = pLgFArrayFormat->total_size;
5208 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5212 *ppMemory = NdrAllocate(pStubMsg, total_size);
5215 if (!pStubMsg->IsClient && !*ppMemory)
5216 /* for servers, we just point straight into the RPC buffer */
5217 *ppMemory = pStubMsg->Buffer;
5220 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5221 safe_buffer_increment(pStubMsg, total_size);
5222 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5224 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
5225 if (*ppMemory != saved_buffer)
5226 memcpy(*ppMemory, saved_buffer, total_size);
5231 /***********************************************************************
5232 * NdrFixedArrayBufferSize [RPCRT4.@]
5234 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5235 unsigned char *pMemory,
5236 PFORMAT_STRING pFormat)
5238 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5241 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5243 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5244 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5246 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5247 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5251 align_length(&pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
5253 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5255 total_size = pSmFArrayFormat->total_size;
5256 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5260 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5261 total_size = pLgFArrayFormat->total_size;
5262 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5264 safe_buffer_length_increment(pStubMsg, total_size);
5266 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5269 /***********************************************************************
5270 * NdrFixedArrayMemorySize [RPCRT4.@]
5272 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5273 PFORMAT_STRING pFormat)
5275 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5278 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5280 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5281 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5283 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5284 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5288 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5290 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5292 total_size = pSmFArrayFormat->total_size;
5293 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5297 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5298 total_size = pLgFArrayFormat->total_size;
5299 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5301 pStubMsg->BufferMark = pStubMsg->Buffer;
5302 safe_buffer_increment(pStubMsg, total_size);
5303 pStubMsg->MemorySize += total_size;
5305 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5310 /***********************************************************************
5311 * NdrFixedArrayFree [RPCRT4.@]
5313 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5314 unsigned char *pMemory,
5315 PFORMAT_STRING pFormat)
5317 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5319 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5321 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5322 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5324 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5325 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5329 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5330 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5333 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5334 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5337 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5340 /***********************************************************************
5341 * NdrVaryingArrayMarshall [RPCRT4.@]
5343 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5344 unsigned char *pMemory,
5345 PFORMAT_STRING pFormat)
5347 unsigned char alignment;
5348 DWORD elements, esize;
5351 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5353 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5354 (pFormat[0] != RPC_FC_LGVARRAY))
5356 ERR("invalid format type %x\n", pFormat[0]);
5357 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5361 alignment = pFormat[1] + 1;
5363 if (pFormat[0] == RPC_FC_SMVARRAY)
5366 pFormat += sizeof(WORD);
5367 elements = *(const WORD*)pFormat;
5368 pFormat += sizeof(WORD);
5373 pFormat += sizeof(DWORD);
5374 elements = *(const DWORD*)pFormat;
5375 pFormat += sizeof(DWORD);
5378 esize = *(const WORD*)pFormat;
5379 pFormat += sizeof(WORD);
5381 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5382 if ((pStubMsg->ActualCount > elements) ||
5383 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5385 RpcRaiseException(RPC_S_INVALID_BOUND);
5389 WriteVariance(pStubMsg);
5391 align_pointer_clear(&pStubMsg->Buffer, alignment);
5393 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5394 pStubMsg->BufferMark = pStubMsg->Buffer;
5395 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5397 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5402 /***********************************************************************
5403 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5405 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5406 unsigned char **ppMemory,
5407 PFORMAT_STRING pFormat,
5408 unsigned char fMustAlloc)
5410 unsigned char alignment;
5411 DWORD size, elements, esize;
5413 unsigned char *saved_buffer;
5416 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5418 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5419 (pFormat[0] != RPC_FC_LGVARRAY))
5421 ERR("invalid format type %x\n", pFormat[0]);
5422 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5426 alignment = pFormat[1] + 1;
5428 if (pFormat[0] == RPC_FC_SMVARRAY)
5431 size = *(const WORD*)pFormat;
5432 pFormat += sizeof(WORD);
5433 elements = *(const WORD*)pFormat;
5434 pFormat += sizeof(WORD);
5439 size = *(const DWORD*)pFormat;
5440 pFormat += sizeof(DWORD);
5441 elements = *(const DWORD*)pFormat;
5442 pFormat += sizeof(DWORD);
5445 esize = *(const WORD*)pFormat;
5446 pFormat += sizeof(WORD);
5448 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5450 align_pointer(&pStubMsg->Buffer, alignment);
5452 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5453 offset = pStubMsg->Offset;
5455 if (!fMustAlloc && !*ppMemory)
5458 *ppMemory = NdrAllocate(pStubMsg, size);
5459 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5460 safe_buffer_increment(pStubMsg, bufsize);
5462 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5464 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5469 /***********************************************************************
5470 * NdrVaryingArrayBufferSize [RPCRT4.@]
5472 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5473 unsigned char *pMemory,
5474 PFORMAT_STRING pFormat)
5476 unsigned char alignment;
5477 DWORD elements, esize;
5479 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5481 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5482 (pFormat[0] != RPC_FC_LGVARRAY))
5484 ERR("invalid format type %x\n", pFormat[0]);
5485 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5489 alignment = pFormat[1] + 1;
5491 if (pFormat[0] == RPC_FC_SMVARRAY)
5494 pFormat += sizeof(WORD);
5495 elements = *(const WORD*)pFormat;
5496 pFormat += sizeof(WORD);
5501 pFormat += sizeof(DWORD);
5502 elements = *(const DWORD*)pFormat;
5503 pFormat += sizeof(DWORD);
5506 esize = *(const WORD*)pFormat;
5507 pFormat += sizeof(WORD);
5509 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5510 if ((pStubMsg->ActualCount > elements) ||
5511 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5513 RpcRaiseException(RPC_S_INVALID_BOUND);
5517 SizeVariance(pStubMsg);
5519 align_length(&pStubMsg->BufferLength, alignment);
5521 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5523 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5526 /***********************************************************************
5527 * NdrVaryingArrayMemorySize [RPCRT4.@]
5529 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5530 PFORMAT_STRING pFormat)
5532 unsigned char alignment;
5533 DWORD size, elements, esize;
5535 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5537 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5538 (pFormat[0] != RPC_FC_LGVARRAY))
5540 ERR("invalid format type %x\n", pFormat[0]);
5541 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5545 alignment = pFormat[1] + 1;
5547 if (pFormat[0] == RPC_FC_SMVARRAY)
5550 size = *(const WORD*)pFormat;
5551 pFormat += sizeof(WORD);
5552 elements = *(const WORD*)pFormat;
5553 pFormat += sizeof(WORD);
5558 size = *(const DWORD*)pFormat;
5559 pFormat += sizeof(DWORD);
5560 elements = *(const DWORD*)pFormat;
5561 pFormat += sizeof(DWORD);
5564 esize = *(const WORD*)pFormat;
5565 pFormat += sizeof(WORD);
5567 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5569 align_pointer(&pStubMsg->Buffer, alignment);
5571 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5572 pStubMsg->MemorySize += size;
5574 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5576 return pStubMsg->MemorySize;
5579 /***********************************************************************
5580 * NdrVaryingArrayFree [RPCRT4.@]
5582 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5583 unsigned char *pMemory,
5584 PFORMAT_STRING pFormat)
5588 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5590 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5591 (pFormat[0] != RPC_FC_LGVARRAY))
5593 ERR("invalid format type %x\n", pFormat[0]);
5594 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5598 if (pFormat[0] == RPC_FC_SMVARRAY)
5601 pFormat += sizeof(WORD);
5602 elements = *(const WORD*)pFormat;
5603 pFormat += sizeof(WORD);
5608 pFormat += sizeof(DWORD);
5609 elements = *(const DWORD*)pFormat;
5610 pFormat += sizeof(DWORD);
5613 pFormat += sizeof(WORD);
5615 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5616 if ((pStubMsg->ActualCount > elements) ||
5617 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5619 RpcRaiseException(RPC_S_INVALID_BOUND);
5623 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5626 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5639 return *(const USHORT *)pMemory;
5643 return *(const ULONG *)pMemory;
5644 case RPC_FC_INT3264:
5645 case RPC_FC_UINT3264:
5646 return *(const ULONG_PTR *)pMemory;
5648 FIXME("Unhandled base type: 0x%02x\n", fc);
5653 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5655 PFORMAT_STRING pFormat)
5657 unsigned short num_arms, arm, type;
5659 num_arms = *(const SHORT*)pFormat & 0x0fff;
5661 for(arm = 0; arm < num_arms; arm++)
5663 if(discriminant == *(const ULONG*)pFormat)
5671 type = *(const unsigned short*)pFormat;
5672 TRACE("type %04x\n", type);
5673 if(arm == num_arms) /* default arm extras */
5677 ERR("no arm for 0x%x and no default case\n", discriminant);
5678 RpcRaiseException(RPC_S_INVALID_TAG);
5683 TRACE("falling back to empty default case for 0x%x\n", discriminant);
5690 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5692 unsigned short type;
5696 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5700 type = *(const unsigned short*)pFormat;
5701 if((type & 0xff00) == 0x8000)
5703 unsigned char basetype = LOBYTE(type);
5704 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5708 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5709 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5712 unsigned char *saved_buffer = NULL;
5713 int pointer_buffer_mark_set = 0;
5720 align_pointer_clear(&pStubMsg->Buffer, 4);
5721 saved_buffer = pStubMsg->Buffer;
5722 if (pStubMsg->PointerBufferMark)
5724 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5725 pStubMsg->PointerBufferMark = NULL;
5726 pointer_buffer_mark_set = 1;
5729 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5731 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5732 if (pointer_buffer_mark_set)
5734 STD_OVERFLOW_CHECK(pStubMsg);
5735 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5736 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5738 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5739 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5740 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5742 pStubMsg->Buffer = saved_buffer + 4;
5746 m(pStubMsg, pMemory, desc);
5749 else FIXME("no marshaller for embedded type %02x\n", *desc);
5754 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5755 unsigned char **ppMemory,
5757 PFORMAT_STRING pFormat,
5758 unsigned char fMustAlloc)
5760 unsigned short type;
5764 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5768 type = *(const unsigned short*)pFormat;
5769 if((type & 0xff00) == 0x8000)
5771 unsigned char basetype = LOBYTE(type);
5772 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5776 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5777 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5780 unsigned char *saved_buffer = NULL;
5781 int pointer_buffer_mark_set = 0;
5788 align_pointer(&pStubMsg->Buffer, 4);
5789 saved_buffer = pStubMsg->Buffer;
5790 if (pStubMsg->PointerBufferMark)
5792 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5793 pStubMsg->PointerBufferMark = NULL;
5794 pointer_buffer_mark_set = 1;
5797 pStubMsg->Buffer += 4; /* for pointer ID */
5799 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5801 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5802 saved_buffer, pStubMsg->BufferEnd);
5803 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5806 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5807 if (pointer_buffer_mark_set)
5809 STD_OVERFLOW_CHECK(pStubMsg);
5810 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5811 pStubMsg->Buffer = saved_buffer + 4;
5815 m(pStubMsg, ppMemory, desc, fMustAlloc);
5818 else FIXME("no marshaller for embedded type %02x\n", *desc);
5823 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5824 unsigned char *pMemory,
5826 PFORMAT_STRING pFormat)
5828 unsigned short type;
5832 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5836 type = *(const unsigned short*)pFormat;
5837 if((type & 0xff00) == 0x8000)
5839 unsigned char basetype = LOBYTE(type);
5840 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5844 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5845 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5854 align_length(&pStubMsg->BufferLength, 4);
5855 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5856 if (!pStubMsg->IgnoreEmbeddedPointers)
5858 int saved_buffer_length = pStubMsg->BufferLength;
5859 pStubMsg->BufferLength = pStubMsg->PointerLength;
5860 pStubMsg->PointerLength = 0;
5861 if(!pStubMsg->BufferLength)
5862 ERR("BufferLength == 0??\n");
5863 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5864 pStubMsg->PointerLength = pStubMsg->BufferLength;
5865 pStubMsg->BufferLength = saved_buffer_length;
5869 m(pStubMsg, pMemory, desc);
5872 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5876 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5878 PFORMAT_STRING pFormat)
5880 unsigned short type, size;
5882 size = *(const unsigned short*)pFormat;
5883 pStubMsg->Memory += size;
5886 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5890 type = *(const unsigned short*)pFormat;
5891 if((type & 0xff00) == 0x8000)
5893 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5897 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5898 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5899 unsigned char *saved_buffer;
5908 align_pointer(&pStubMsg->Buffer, 4);
5909 saved_buffer = pStubMsg->Buffer;
5910 safe_buffer_increment(pStubMsg, 4);
5911 align_length(&pStubMsg->MemorySize, sizeof(void *));
5912 pStubMsg->MemorySize += sizeof(void *);
5913 if (!pStubMsg->IgnoreEmbeddedPointers)
5914 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5917 return m(pStubMsg, desc);
5920 else FIXME("no marshaller for embedded type %02x\n", *desc);
5923 TRACE("size %d\n", size);
5927 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5928 unsigned char *pMemory,
5930 PFORMAT_STRING pFormat)
5932 unsigned short type;
5936 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5940 type = *(const unsigned short*)pFormat;
5941 if((type & 0xff00) != 0x8000)
5943 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5944 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5953 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5956 m(pStubMsg, pMemory, desc);
5962 /***********************************************************************
5963 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5965 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5966 unsigned char *pMemory,
5967 PFORMAT_STRING pFormat)
5969 unsigned char switch_type;
5970 unsigned char increment;
5973 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5976 switch_type = *pFormat & 0xf;
5977 increment = (*pFormat & 0xf0) >> 4;
5980 align_pointer_clear(&pStubMsg->Buffer, increment);
5982 switch_value = get_discriminant(switch_type, pMemory);
5983 TRACE("got switch value 0x%x\n", switch_value);
5985 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5986 pMemory += increment;
5988 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5991 /***********************************************************************
5992 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5994 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5995 unsigned char **ppMemory,
5996 PFORMAT_STRING pFormat,
5997 unsigned char fMustAlloc)
5999 unsigned char switch_type;
6000 unsigned char increment;
6002 unsigned short size;
6003 unsigned char *pMemoryArm;
6005 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6008 switch_type = *pFormat & 0xf;
6009 increment = (*pFormat & 0xf0) >> 4;
6012 align_pointer(&pStubMsg->Buffer, increment);
6013 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6014 TRACE("got switch value 0x%x\n", switch_value);
6016 size = *(const unsigned short*)pFormat + increment;
6017 if (!fMustAlloc && !*ppMemory)
6020 *ppMemory = NdrAllocate(pStubMsg, size);
6022 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6023 * since the arm is part of the memory block that is encompassed by
6024 * the whole union. Memory is forced to allocate when pointers
6025 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6026 * clearing the memory we pass in to the unmarshaller */
6028 memset(*ppMemory, 0, size);
6030 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
6031 pMemoryArm = *ppMemory + increment;
6033 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, FALSE);
6036 /***********************************************************************
6037 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
6039 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6040 unsigned char *pMemory,
6041 PFORMAT_STRING pFormat)
6043 unsigned char switch_type;
6044 unsigned char increment;
6047 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6050 switch_type = *pFormat & 0xf;
6051 increment = (*pFormat & 0xf0) >> 4;
6054 align_length(&pStubMsg->BufferLength, increment);
6055 switch_value = get_discriminant(switch_type, pMemory);
6056 TRACE("got switch value 0x%x\n", switch_value);
6058 /* Add discriminant size */
6059 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
6060 pMemory += increment;
6062 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
6065 /***********************************************************************
6066 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
6068 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6069 PFORMAT_STRING pFormat)
6071 unsigned char switch_type;
6072 unsigned char increment;
6075 switch_type = *pFormat & 0xf;
6076 increment = (*pFormat & 0xf0) >> 4;
6079 align_pointer(&pStubMsg->Buffer, increment);
6080 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6081 TRACE("got switch value 0x%x\n", switch_value);
6083 pStubMsg->Memory += increment;
6085 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
6088 /***********************************************************************
6089 * NdrEncapsulatedUnionFree [RPCRT4.@]
6091 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6092 unsigned char *pMemory,
6093 PFORMAT_STRING pFormat)
6095 unsigned char switch_type;
6096 unsigned char increment;
6099 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6102 switch_type = *pFormat & 0xf;
6103 increment = (*pFormat & 0xf0) >> 4;
6106 switch_value = get_discriminant(switch_type, pMemory);
6107 TRACE("got switch value 0x%x\n", switch_value);
6109 pMemory += increment;
6111 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
6114 /***********************************************************************
6115 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
6117 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6118 unsigned char *pMemory,
6119 PFORMAT_STRING pFormat)
6121 unsigned char switch_type;
6123 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6126 switch_type = *pFormat;
6129 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6130 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6131 /* Marshall discriminant */
6132 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6134 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6137 static LONG unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
6138 PFORMAT_STRING *ppFormat)
6140 LONG discriminant = 0;
6150 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6159 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6160 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6168 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6169 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6174 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
6178 if (pStubMsg->fHasNewCorrDesc)
6182 return discriminant;
6185 /**********************************************************************
6186 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6188 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6189 unsigned char **ppMemory,
6190 PFORMAT_STRING pFormat,
6191 unsigned char fMustAlloc)
6194 unsigned short size;
6196 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6199 /* Unmarshall discriminant */
6200 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6201 TRACE("unmarshalled discriminant %x\n", discriminant);
6203 pFormat += *(const SHORT*)pFormat;
6205 size = *(const unsigned short*)pFormat;
6207 if (!fMustAlloc && !*ppMemory)
6210 *ppMemory = NdrAllocate(pStubMsg, size);
6212 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6213 * since the arm is part of the memory block that is encompassed by
6214 * the whole union. Memory is forced to allocate when pointers
6215 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6216 * clearing the memory we pass in to the unmarshaller */
6218 memset(*ppMemory, 0, size);
6220 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, FALSE);
6223 /***********************************************************************
6224 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6226 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6227 unsigned char *pMemory,
6228 PFORMAT_STRING pFormat)
6230 unsigned char switch_type;
6232 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6235 switch_type = *pFormat;
6238 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6239 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6240 /* Add discriminant size */
6241 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6243 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6246 /***********************************************************************
6247 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6249 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6250 PFORMAT_STRING pFormat)
6255 /* Unmarshall discriminant */
6256 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6257 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
6259 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
6262 /***********************************************************************
6263 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6265 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6266 unsigned char *pMemory,
6267 PFORMAT_STRING pFormat)
6269 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6273 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6274 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6276 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6279 /***********************************************************************
6280 * NdrByteCountPointerMarshall [RPCRT4.@]
6282 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6283 unsigned char *pMemory,
6284 PFORMAT_STRING pFormat)
6290 /***********************************************************************
6291 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6293 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6294 unsigned char **ppMemory,
6295 PFORMAT_STRING pFormat,
6296 unsigned char fMustAlloc)
6302 /***********************************************************************
6303 * NdrByteCountPointerBufferSize [RPCRT4.@]
6305 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6306 unsigned char *pMemory,
6307 PFORMAT_STRING pFormat)
6312 /***********************************************************************
6313 * NdrByteCountPointerMemorySize [internal]
6315 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6316 PFORMAT_STRING pFormat)
6322 /***********************************************************************
6323 * NdrByteCountPointerFree [RPCRT4.@]
6325 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6326 unsigned char *pMemory,
6327 PFORMAT_STRING pFormat)
6332 /***********************************************************************
6333 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6335 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6336 unsigned char *pMemory,
6337 PFORMAT_STRING pFormat)
6343 /***********************************************************************
6344 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6346 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6347 unsigned char **ppMemory,
6348 PFORMAT_STRING pFormat,
6349 unsigned char fMustAlloc)
6355 /***********************************************************************
6356 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6358 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6359 unsigned char *pMemory,
6360 PFORMAT_STRING pFormat)
6365 /***********************************************************************
6366 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6368 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6369 PFORMAT_STRING pFormat)
6375 /***********************************************************************
6376 * NdrXmitOrRepAsFree [RPCRT4.@]
6378 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6379 unsigned char *pMemory,
6380 PFORMAT_STRING pFormat)
6385 /***********************************************************************
6386 * NdrRangeMarshall [internal]
6388 static unsigned char *WINAPI NdrRangeMarshall(
6389 PMIDL_STUB_MESSAGE pStubMsg,
6390 unsigned char *pMemory,
6391 PFORMAT_STRING pFormat)
6393 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6394 unsigned char base_type;
6396 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6398 if (pRange->type != RPC_FC_RANGE)
6400 ERR("invalid format type %x\n", pRange->type);
6401 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6405 base_type = pRange->flags_type & 0xf;
6407 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6410 /***********************************************************************
6411 * NdrRangeUnmarshall [RPCRT4.@]
6413 unsigned char *WINAPI NdrRangeUnmarshall(
6414 PMIDL_STUB_MESSAGE pStubMsg,
6415 unsigned char **ppMemory,
6416 PFORMAT_STRING pFormat,
6417 unsigned char fMustAlloc)
6419 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6420 unsigned char base_type;
6422 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6424 if (pRange->type != RPC_FC_RANGE)
6426 ERR("invalid format type %x\n", pRange->type);
6427 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6430 base_type = pRange->flags_type & 0xf;
6432 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6433 base_type, pRange->low_value, pRange->high_value);
6435 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6438 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \
6439 if (!fMustAlloc && !*ppMemory) \
6440 fMustAlloc = TRUE; \
6442 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6443 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6445 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6446 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6447 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6449 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6450 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6452 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6453 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6454 (mem_type)pRange->high_value); \
6455 RpcRaiseException(RPC_S_INVALID_BOUND); \
6458 TRACE("*ppMemory: %p\n", *ppMemory); \
6459 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6460 pStubMsg->Buffer += sizeof(wire_type); \
6467 RANGE_UNMARSHALL(UCHAR, UCHAR, "%d");
6468 TRACE("value: 0x%02x\n", **ppMemory);
6472 RANGE_UNMARSHALL(CHAR, CHAR, "%u");
6473 TRACE("value: 0x%02x\n", **ppMemory);
6475 case RPC_FC_WCHAR: /* FIXME: valid? */
6477 RANGE_UNMARSHALL(USHORT, USHORT, "%u");
6478 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6481 RANGE_UNMARSHALL(SHORT, SHORT, "%d");
6482 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6486 RANGE_UNMARSHALL(LONG, LONG, "%d");
6487 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6490 RANGE_UNMARSHALL(ULONG, ULONG, "%u");
6491 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6494 RANGE_UNMARSHALL(UINT, USHORT, "%u");
6495 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6501 ERR("invalid range base type: 0x%02x\n", base_type);
6502 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6508 /***********************************************************************
6509 * NdrRangeBufferSize [internal]
6511 static void WINAPI NdrRangeBufferSize(
6512 PMIDL_STUB_MESSAGE pStubMsg,
6513 unsigned char *pMemory,
6514 PFORMAT_STRING pFormat)
6516 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6517 unsigned char base_type;
6519 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6521 if (pRange->type != RPC_FC_RANGE)
6523 ERR("invalid format type %x\n", pRange->type);
6524 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6526 base_type = pRange->flags_type & 0xf;
6528 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6531 /***********************************************************************
6532 * NdrRangeMemorySize [internal]
6534 static ULONG WINAPI NdrRangeMemorySize(
6535 PMIDL_STUB_MESSAGE pStubMsg,
6536 PFORMAT_STRING pFormat)
6538 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6539 unsigned char base_type;
6541 if (pRange->type != RPC_FC_RANGE)
6543 ERR("invalid format type %x\n", pRange->type);
6544 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6547 base_type = pRange->flags_type & 0xf;
6549 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6552 /***********************************************************************
6553 * NdrRangeFree [internal]
6555 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6556 unsigned char *pMemory,
6557 PFORMAT_STRING pFormat)
6559 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6564 /***********************************************************************
6565 * NdrBaseTypeMarshall [internal]
6567 static unsigned char *WINAPI NdrBaseTypeMarshall(
6568 PMIDL_STUB_MESSAGE pStubMsg,
6569 unsigned char *pMemory,
6570 PFORMAT_STRING pFormat)
6572 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6580 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6581 TRACE("value: 0x%02x\n", *pMemory);
6586 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6587 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6588 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6592 case RPC_FC_ERROR_STATUS_T:
6594 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONG));
6595 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6596 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6599 align_pointer_clear(&pStubMsg->Buffer, sizeof(float));
6600 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6603 align_pointer_clear(&pStubMsg->Buffer, sizeof(double));
6604 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6607 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONGLONG));
6608 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6609 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6613 USHORT val = *(UINT *)pMemory;
6614 /* only 16-bits on the wire, so do a sanity check */
6615 if (*(UINT *)pMemory > SHRT_MAX)
6616 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6617 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6618 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6619 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6622 case RPC_FC_INT3264:
6623 case RPC_FC_UINT3264:
6625 UINT val = *(UINT_PTR *)pMemory;
6626 align_pointer_clear(&pStubMsg->Buffer, sizeof(UINT));
6627 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6633 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6636 /* FIXME: what is the correct return value? */
6640 /***********************************************************************
6641 * NdrBaseTypeUnmarshall [internal]
6643 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6644 PMIDL_STUB_MESSAGE pStubMsg,
6645 unsigned char **ppMemory,
6646 PFORMAT_STRING pFormat,
6647 unsigned char fMustAlloc)
6649 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6651 #define BASE_TYPE_UNMARSHALL(type) do { \
6652 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
6653 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6655 *ppMemory = pStubMsg->Buffer; \
6656 TRACE("*ppMemory: %p\n", *ppMemory); \
6657 safe_buffer_increment(pStubMsg, sizeof(type)); \
6662 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6663 TRACE("*ppMemory: %p\n", *ppMemory); \
6664 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6674 BASE_TYPE_UNMARSHALL(UCHAR);
6675 TRACE("value: 0x%02x\n", **ppMemory);
6680 BASE_TYPE_UNMARSHALL(USHORT);
6681 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6685 case RPC_FC_ERROR_STATUS_T:
6687 BASE_TYPE_UNMARSHALL(ULONG);
6688 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6691 BASE_TYPE_UNMARSHALL(float);
6692 TRACE("value: %f\n", **(float **)ppMemory);
6695 BASE_TYPE_UNMARSHALL(double);
6696 TRACE("value: %f\n", **(double **)ppMemory);
6699 BASE_TYPE_UNMARSHALL(ULONGLONG);
6700 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6705 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6706 if (!fMustAlloc && !*ppMemory)
6709 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6710 safe_copy_from_buffer(pStubMsg, &val, sizeof(USHORT));
6711 /* 16-bits on the wire, but int in memory */
6712 **(UINT **)ppMemory = val;
6713 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6716 case RPC_FC_INT3264:
6717 if (sizeof(INT_PTR) == sizeof(INT)) BASE_TYPE_UNMARSHALL(INT);
6721 align_pointer(&pStubMsg->Buffer, sizeof(INT));
6722 if (!fMustAlloc && !*ppMemory)
6725 *ppMemory = NdrAllocate(pStubMsg, sizeof(INT_PTR));
6726 safe_copy_from_buffer(pStubMsg, &val, sizeof(INT));
6727 **(INT_PTR **)ppMemory = val;
6728 TRACE("value: 0x%08lx\n", **(INT_PTR **)ppMemory);
6731 case RPC_FC_UINT3264:
6732 if (sizeof(UINT_PTR) == sizeof(UINT)) BASE_TYPE_UNMARSHALL(UINT);
6736 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6737 if (!fMustAlloc && !*ppMemory)
6740 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT_PTR));
6741 safe_copy_from_buffer(pStubMsg, &val, sizeof(UINT));
6742 **(UINT_PTR **)ppMemory = val;
6743 TRACE("value: 0x%08lx\n", **(UINT_PTR **)ppMemory);
6749 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6751 #undef BASE_TYPE_UNMARSHALL
6753 /* FIXME: what is the correct return value? */
6758 /***********************************************************************
6759 * NdrBaseTypeBufferSize [internal]
6761 static void WINAPI NdrBaseTypeBufferSize(
6762 PMIDL_STUB_MESSAGE pStubMsg,
6763 unsigned char *pMemory,
6764 PFORMAT_STRING pFormat)
6766 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6774 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6780 align_length(&pStubMsg->BufferLength, sizeof(USHORT));
6781 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6786 case RPC_FC_INT3264:
6787 case RPC_FC_UINT3264:
6788 align_length(&pStubMsg->BufferLength, sizeof(ULONG));
6789 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6792 align_length(&pStubMsg->BufferLength, sizeof(float));
6793 safe_buffer_length_increment(pStubMsg, sizeof(float));
6796 align_length(&pStubMsg->BufferLength, sizeof(double));
6797 safe_buffer_length_increment(pStubMsg, sizeof(double));
6800 align_length(&pStubMsg->BufferLength, sizeof(ULONGLONG));
6801 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6803 case RPC_FC_ERROR_STATUS_T:
6804 align_length(&pStubMsg->BufferLength, sizeof(error_status_t));
6805 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6810 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6814 /***********************************************************************
6815 * NdrBaseTypeMemorySize [internal]
6817 static ULONG WINAPI NdrBaseTypeMemorySize(
6818 PMIDL_STUB_MESSAGE pStubMsg,
6819 PFORMAT_STRING pFormat)
6821 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6829 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6830 pStubMsg->MemorySize += sizeof(UCHAR);
6831 return sizeof(UCHAR);
6835 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6836 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6837 align_length(&pStubMsg->MemorySize, sizeof(USHORT));
6838 pStubMsg->MemorySize += sizeof(USHORT);
6839 return sizeof(USHORT);
6843 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6844 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6845 align_length(&pStubMsg->MemorySize, sizeof(ULONG));
6846 pStubMsg->MemorySize += sizeof(ULONG);
6847 return sizeof(ULONG);
6849 align_pointer(&pStubMsg->Buffer, sizeof(float));
6850 safe_buffer_increment(pStubMsg, sizeof(float));
6851 align_length(&pStubMsg->MemorySize, sizeof(float));
6852 pStubMsg->MemorySize += sizeof(float);
6853 return sizeof(float);
6855 align_pointer(&pStubMsg->Buffer, sizeof(double));
6856 safe_buffer_increment(pStubMsg, sizeof(double));
6857 align_length(&pStubMsg->MemorySize, sizeof(double));
6858 pStubMsg->MemorySize += sizeof(double);
6859 return sizeof(double);
6861 align_pointer(&pStubMsg->Buffer, sizeof(ULONGLONG));
6862 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6863 align_length(&pStubMsg->MemorySize, sizeof(ULONGLONG));
6864 pStubMsg->MemorySize += sizeof(ULONGLONG);
6865 return sizeof(ULONGLONG);
6866 case RPC_FC_ERROR_STATUS_T:
6867 align_pointer(&pStubMsg->Buffer, sizeof(error_status_t));
6868 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6869 align_length(&pStubMsg->MemorySize, sizeof(error_status_t));
6870 pStubMsg->MemorySize += sizeof(error_status_t);
6871 return sizeof(error_status_t);
6873 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6874 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6875 align_length(&pStubMsg->MemorySize, sizeof(UINT));
6876 pStubMsg->MemorySize += sizeof(UINT);
6877 return sizeof(UINT);
6878 case RPC_FC_INT3264:
6879 case RPC_FC_UINT3264:
6880 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6881 safe_buffer_increment(pStubMsg, sizeof(UINT));
6882 align_length(&pStubMsg->MemorySize, sizeof(UINT_PTR));
6883 pStubMsg->MemorySize += sizeof(UINT_PTR);
6884 return sizeof(UINT_PTR);
6886 align_length(&pStubMsg->MemorySize, sizeof(void *));
6887 pStubMsg->MemorySize += sizeof(void *);
6888 return sizeof(void *);
6890 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6895 /***********************************************************************
6896 * NdrBaseTypeFree [internal]
6898 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6899 unsigned char *pMemory,
6900 PFORMAT_STRING pFormat)
6902 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6907 /***********************************************************************
6908 * NdrContextHandleBufferSize [internal]
6910 static void WINAPI NdrContextHandleBufferSize(
6911 PMIDL_STUB_MESSAGE pStubMsg,
6912 unsigned char *pMemory,
6913 PFORMAT_STRING pFormat)
6915 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6917 if (*pFormat != RPC_FC_BIND_CONTEXT)
6919 ERR("invalid format type %x\n", *pFormat);
6920 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6922 align_length(&pStubMsg->BufferLength, 4);
6923 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6926 /***********************************************************************
6927 * NdrContextHandleMarshall [internal]
6929 static unsigned char *WINAPI NdrContextHandleMarshall(
6930 PMIDL_STUB_MESSAGE pStubMsg,
6931 unsigned char *pMemory,
6932 PFORMAT_STRING pFormat)
6934 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6936 if (*pFormat != RPC_FC_BIND_CONTEXT)
6938 ERR("invalid format type %x\n", *pFormat);
6939 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6941 TRACE("flags: 0x%02x\n", pFormat[1]);
6943 if (pStubMsg->IsClient)
6945 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6946 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6948 NdrClientContextMarshall(pStubMsg, pMemory, FALSE);
6952 NDR_SCONTEXT ctxt = NDRSContextFromValue(pMemory);
6953 NDR_RUNDOWN rundown = pStubMsg->StubDesc->apfnNdrRundownRoutines[pFormat[2]];
6954 NdrServerContextNewMarshall(pStubMsg, ctxt, rundown, pFormat);
6960 /***********************************************************************
6961 * NdrContextHandleUnmarshall [internal]
6963 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6964 PMIDL_STUB_MESSAGE pStubMsg,
6965 unsigned char **ppMemory,
6966 PFORMAT_STRING pFormat,
6967 unsigned char fMustAlloc)
6969 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6970 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6972 if (*pFormat != RPC_FC_BIND_CONTEXT)
6974 ERR("invalid format type %x\n", *pFormat);
6975 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6977 TRACE("flags: 0x%02x\n", pFormat[1]);
6979 if (pStubMsg->IsClient)
6981 /* [out]-only or [ret] param */
6982 if ((pFormat[1] & (HANDLE_PARAM_IS_IN|HANDLE_PARAM_IS_OUT)) == HANDLE_PARAM_IS_OUT)
6983 **(NDR_CCONTEXT **)ppMemory = NULL;
6984 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6989 ctxt = NdrServerContextNewUnmarshall(pStubMsg, pFormat);
6990 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6991 *(void **)ppMemory = NDRSContextValue(ctxt);
6993 *(void **)ppMemory = *NDRSContextValue(ctxt);
6999 /***********************************************************************
7000 * NdrClientContextMarshall [RPCRT4.@]
7002 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7003 NDR_CCONTEXT ContextHandle,
7006 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
7008 align_pointer_clear(&pStubMsg->Buffer, 4);
7010 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7012 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7013 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7014 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7017 /* FIXME: what does fCheck do? */
7018 NDRCContextMarshall(ContextHandle,
7021 pStubMsg->Buffer += cbNDRContext;
7024 /***********************************************************************
7025 * NdrClientContextUnmarshall [RPCRT4.@]
7027 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7028 NDR_CCONTEXT * pContextHandle,
7029 RPC_BINDING_HANDLE BindHandle)
7031 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
7033 align_pointer(&pStubMsg->Buffer, 4);
7035 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
7036 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7038 NDRCContextUnmarshall(pContextHandle,
7041 pStubMsg->RpcMsg->DataRepresentation);
7043 pStubMsg->Buffer += cbNDRContext;
7046 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7047 NDR_SCONTEXT ContextHandle,
7048 NDR_RUNDOWN RundownRoutine )
7050 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
7052 align_pointer(&pStubMsg->Buffer, 4);
7054 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7056 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7057 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7058 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7061 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7062 pStubMsg->Buffer, RundownRoutine, NULL,
7063 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7064 pStubMsg->Buffer += cbNDRContext;
7067 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
7069 NDR_SCONTEXT ContextHandle;
7071 TRACE("(%p)\n", pStubMsg);
7073 align_pointer(&pStubMsg->Buffer, 4);
7075 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7077 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7078 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7079 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7082 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7084 pStubMsg->RpcMsg->DataRepresentation,
7085 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7086 pStubMsg->Buffer += cbNDRContext;
7088 return ContextHandle;
7091 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
7092 unsigned char* pMemory,
7093 PFORMAT_STRING pFormat)
7095 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
7098 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
7099 PFORMAT_STRING pFormat)
7101 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7102 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7104 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7106 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7107 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7108 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7109 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7110 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7112 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7113 if_id = &sif->InterfaceId;
7116 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
7117 pStubMsg->RpcMsg->DataRepresentation, if_id,
7121 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7122 NDR_SCONTEXT ContextHandle,
7123 NDR_RUNDOWN RundownRoutine,
7124 PFORMAT_STRING pFormat)
7126 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7127 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7129 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
7131 align_pointer(&pStubMsg->Buffer, 4);
7133 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7135 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7136 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7137 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7140 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7141 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7142 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7143 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7144 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7146 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7147 if_id = &sif->InterfaceId;
7150 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7151 pStubMsg->Buffer, RundownRoutine, if_id, flags);
7152 pStubMsg->Buffer += cbNDRContext;
7155 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7156 PFORMAT_STRING pFormat)
7158 NDR_SCONTEXT ContextHandle;
7159 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7160 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7162 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7164 align_pointer(&pStubMsg->Buffer, 4);
7166 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7168 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7169 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7170 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7173 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7174 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7175 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7176 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7177 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7179 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7180 if_id = &sif->InterfaceId;
7183 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7185 pStubMsg->RpcMsg->DataRepresentation,
7187 pStubMsg->Buffer += cbNDRContext;
7189 return ContextHandle;
7192 /***********************************************************************
7193 * NdrCorrelationInitialize [RPCRT4.@]
7195 * Initializes correlation validity checking.
7198 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7199 * pMemory [I] Pointer to memory to use as a cache.
7200 * CacheSize [I] Size of the memory pointed to by pMemory.
7201 * Flags [I] Reserved. Set to zero.
7206 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
7208 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
7209 pStubMsg->fHasNewCorrDesc = TRUE;
7212 /***********************************************************************
7213 * NdrCorrelationPass [RPCRT4.@]
7215 * Performs correlation validity checking.
7218 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7223 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
7225 FIXME("(%p): stub\n", pStubMsg);
7228 /***********************************************************************
7229 * NdrCorrelationFree [RPCRT4.@]
7231 * Frees any resources used while unmarshalling parameters that need
7232 * correlation validity checking.
7235 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7240 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
7242 FIXME("(%p): stub\n", pStubMsg);