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)
2065 unsigned char alignment;
2070 esize = *(const WORD*)(pFormat+2);
2071 pFormat = ReadConformance(pStubMsg, pFormat+4);
2072 return safe_multiply(esize, pStubMsg->MaxCount);
2073 case RPC_FC_CVARRAY:
2074 esize = *(const WORD*)(pFormat+2);
2075 pFormat = ReadConformance(pStubMsg, pFormat+4);
2076 return safe_multiply(esize, pStubMsg->MaxCount);
2077 case RPC_FC_C_CSTRING:
2078 case RPC_FC_C_WSTRING:
2079 if (fc == RPC_FC_C_CSTRING)
2084 if (pFormat[1] == RPC_FC_STRING_SIZED)
2085 ReadConformance(pStubMsg, pFormat + 2);
2087 ReadConformance(pStubMsg, NULL);
2088 return safe_multiply(esize, pStubMsg->MaxCount);
2089 case RPC_FC_BOGUS_ARRAY:
2090 alignment = pFormat[1] + 1;
2091 def = *(const WORD *)(pFormat + 2);
2093 if (IsConformanceOrVariancePresent(pFormat)) pFormat = ReadConformance(pStubMsg, pFormat);
2096 pStubMsg->MaxCount = def;
2097 pFormat = SkipConformance( pStubMsg, pFormat );
2099 pFormat = SkipVariance( pStubMsg, pFormat );
2101 align_pointer(&pStubMsg->Buffer, alignment);
2102 esize = ComplexStructSize(pStubMsg, pFormat);
2103 return safe_multiply(pStubMsg->MaxCount, esize);
2105 ERR("unknown array format 0x%x\n", fc);
2106 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2110 static inline ULONG array_read_variance_and_unmarshall(
2111 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory,
2112 PFORMAT_STRING pFormat, unsigned char fMustAlloc,
2113 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall)
2115 ULONG bufsize, memsize;
2117 unsigned char alignment;
2118 unsigned char *saved_buffer, *pMemory;
2119 ULONG i, offset, count;
2124 esize = *(const WORD*)(pFormat+2);
2125 alignment = pFormat[1] + 1;
2127 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2129 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2131 align_pointer(&pStubMsg->Buffer, alignment);
2136 *ppMemory = NdrAllocate(pStubMsg, memsize);
2139 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory)
2140 /* for servers, we just point straight into the RPC buffer */
2141 *ppMemory = pStubMsg->Buffer;
2144 saved_buffer = pStubMsg->Buffer;
2145 safe_buffer_increment(pStubMsg, bufsize);
2147 pStubMsg->BufferMark = saved_buffer;
2148 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2150 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2151 if (*ppMemory != saved_buffer)
2152 memcpy(*ppMemory, saved_buffer, bufsize);
2155 case RPC_FC_CVARRAY:
2156 esize = *(const WORD*)(pFormat+2);
2157 alignment = pFormat[1] + 1;
2159 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2161 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2163 align_pointer(&pStubMsg->Buffer, alignment);
2165 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2166 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2170 offset = pStubMsg->Offset;
2172 if (!fMustAlloc && !*ppMemory)
2175 *ppMemory = NdrAllocate(pStubMsg, memsize);
2176 saved_buffer = pStubMsg->Buffer;
2177 safe_buffer_increment(pStubMsg, bufsize);
2179 pStubMsg->BufferMark = saved_buffer;
2180 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat,
2183 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2186 case RPC_FC_C_CSTRING:
2187 case RPC_FC_C_WSTRING:
2188 if (fc == RPC_FC_C_CSTRING)
2193 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2195 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2197 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2198 pStubMsg->ActualCount, pStubMsg->MaxCount);
2199 RpcRaiseException(RPC_S_INVALID_BOUND);
2201 if (pStubMsg->Offset)
2203 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2204 RpcRaiseException(RPC_S_INVALID_BOUND);
2207 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2208 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2210 validate_string_data(pStubMsg, bufsize, esize);
2215 *ppMemory = NdrAllocate(pStubMsg, memsize);
2218 if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
2219 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
2220 /* if the data in the RPC buffer is big enough, we just point
2221 * straight into it */
2222 *ppMemory = pStubMsg->Buffer;
2223 else if (!*ppMemory)
2224 *ppMemory = NdrAllocate(pStubMsg, memsize);
2227 if (*ppMemory == pStubMsg->Buffer)
2228 safe_buffer_increment(pStubMsg, bufsize);
2230 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2232 if (*pFormat == RPC_FC_C_CSTRING)
2233 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
2235 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
2239 case RPC_FC_BOGUS_ARRAY:
2240 alignment = pFormat[1] + 1;
2241 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2242 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2244 esize = ComplexStructSize(pStubMsg, pFormat);
2245 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2247 assert( fUnmarshall );
2249 if (!fMustAlloc && !*ppMemory)
2252 *ppMemory = NdrAllocate(pStubMsg, memsize);
2254 align_pointer(&pStubMsg->Buffer, alignment);
2255 saved_buffer = pStubMsg->Buffer;
2257 pMemory = *ppMemory;
2258 count = pStubMsg->ActualCount;
2259 for (i = 0; i < count; i++)
2260 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
2261 return pStubMsg->Buffer - saved_buffer;
2264 ERR("unknown array format 0x%x\n", fc);
2265 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2269 static inline void array_memory_size(
2270 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
2271 unsigned char fHasPointers)
2273 ULONG i, count, SavedMemorySize;
2274 ULONG bufsize, memsize;
2276 unsigned char alignment;
2281 esize = *(const WORD*)(pFormat+2);
2282 alignment = pFormat[1] + 1;
2284 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2286 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2287 pStubMsg->MemorySize += memsize;
2289 align_pointer(&pStubMsg->Buffer, alignment);
2291 pStubMsg->BufferMark = pStubMsg->Buffer;
2292 safe_buffer_increment(pStubMsg, bufsize);
2295 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2297 case RPC_FC_CVARRAY:
2298 esize = *(const WORD*)(pFormat+2);
2299 alignment = pFormat[1] + 1;
2301 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2303 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2305 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2306 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2307 pStubMsg->MemorySize += memsize;
2309 align_pointer(&pStubMsg->Buffer, alignment);
2311 pStubMsg->BufferMark = pStubMsg->Buffer;
2312 safe_buffer_increment(pStubMsg, bufsize);
2315 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2317 case RPC_FC_C_CSTRING:
2318 case RPC_FC_C_WSTRING:
2319 if (fc == RPC_FC_C_CSTRING)
2324 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2326 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2328 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2329 pStubMsg->ActualCount, pStubMsg->MaxCount);
2330 RpcRaiseException(RPC_S_INVALID_BOUND);
2332 if (pStubMsg->Offset)
2334 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2335 RpcRaiseException(RPC_S_INVALID_BOUND);
2338 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2339 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2341 validate_string_data(pStubMsg, bufsize, esize);
2343 safe_buffer_increment(pStubMsg, bufsize);
2344 pStubMsg->MemorySize += memsize;
2346 case RPC_FC_BOGUS_ARRAY:
2347 alignment = pFormat[1] + 1;
2348 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2349 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2351 align_pointer(&pStubMsg->Buffer, alignment);
2353 SavedMemorySize = pStubMsg->MemorySize;
2355 esize = ComplexStructSize(pStubMsg, pFormat);
2356 memsize = safe_multiply(pStubMsg->MaxCount, esize);
2358 count = pStubMsg->ActualCount;
2359 for (i = 0; i < count; i++)
2360 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
2362 pStubMsg->MemorySize = SavedMemorySize + memsize;
2365 ERR("unknown array format 0x%x\n", fc);
2366 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2370 static inline void array_free(
2371 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
2372 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
2379 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2381 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2383 case RPC_FC_CVARRAY:
2384 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2385 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2387 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2389 case RPC_FC_C_CSTRING:
2390 case RPC_FC_C_WSTRING:
2391 /* No embedded pointers so nothing to do */
2393 case RPC_FC_BOGUS_ARRAY:
2394 count = *(const WORD *)(pFormat + 2);
2395 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, count);
2396 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2398 count = pStubMsg->ActualCount;
2399 for (i = 0; i < count; i++)
2400 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2403 ERR("unknown array format 0x%x\n", fc);
2404 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2409 * NdrConformantString:
2411 * What MS calls a ConformantString is, in DCE terminology,
2412 * a Varying-Conformant String.
2414 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2415 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2416 * into unmarshalled string)
2417 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2419 * data: CHARTYPE[maxlen]
2421 * ], where CHARTYPE is the appropriate character type (specified externally)
2425 /***********************************************************************
2426 * NdrConformantStringMarshall [RPCRT4.@]
2428 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
2429 unsigned char *pszMessage, PFORMAT_STRING pFormat)
2431 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
2433 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2434 ERR("Unhandled string type: %#x\n", pFormat[0]);
2435 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2438 /* allow compiler to optimise inline function by passing constant into
2439 * these functions */
2440 if (pFormat[0] == RPC_FC_C_CSTRING) {
2441 array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2443 array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2444 pFormat, TRUE /* fHasPointers */);
2446 array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2448 array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2449 pFormat, TRUE /* fHasPointers */);
2455 /***********************************************************************
2456 * NdrConformantStringBufferSize [RPCRT4.@]
2458 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2459 unsigned char* pMemory, PFORMAT_STRING pFormat)
2461 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2463 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2464 ERR("Unhandled string type: %#x\n", pFormat[0]);
2465 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2468 /* allow compiler to optimise inline function by passing constant into
2469 * these functions */
2470 if (pFormat[0] == RPC_FC_C_CSTRING) {
2471 array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory,
2473 array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat,
2474 TRUE /* fHasPointers */);
2476 array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory,
2478 array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat,
2479 TRUE /* fHasPointers */);
2483 /************************************************************************
2484 * NdrConformantStringMemorySize [RPCRT4.@]
2486 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2487 PFORMAT_STRING pFormat )
2489 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2491 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2492 ERR("Unhandled string type: %#x\n", pFormat[0]);
2493 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2496 /* allow compiler to optimise inline function by passing constant into
2497 * these functions */
2498 if (pFormat[0] == RPC_FC_C_CSTRING) {
2499 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2500 array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat,
2501 TRUE /* fHasPointers */);
2503 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2504 array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat,
2505 TRUE /* fHasPointers */);
2508 return pStubMsg->MemorySize;
2511 /************************************************************************
2512 * NdrConformantStringUnmarshall [RPCRT4.@]
2514 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2515 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
2517 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2518 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2520 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2521 ERR("Unhandled string type: %#x\n", *pFormat);
2522 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2525 /* allow compiler to optimise inline function by passing constant into
2526 * these functions */
2527 if (pFormat[0] == RPC_FC_C_CSTRING) {
2528 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2529 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory,
2530 pFormat, fMustAlloc,
2531 TRUE /* fUseBufferMemoryServer */,
2532 TRUE /* fUnmarshall */);
2534 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2535 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory,
2536 pFormat, fMustAlloc,
2537 TRUE /* fUseBufferMemoryServer */,
2538 TRUE /* fUnmarshall */);
2544 /***********************************************************************
2545 * NdrNonConformantStringMarshall [RPCRT4.@]
2547 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2548 unsigned char *pMemory,
2549 PFORMAT_STRING pFormat)
2551 ULONG esize, size, maxsize;
2553 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2555 maxsize = *(const USHORT *)&pFormat[2];
2557 if (*pFormat == RPC_FC_CSTRING)
2560 const char *str = (const char *)pMemory;
2561 while (i < maxsize && str[i]) i++;
2562 TRACE("string=%s\n", debugstr_an(str, i));
2563 pStubMsg->ActualCount = i + 1;
2566 else if (*pFormat == RPC_FC_WSTRING)
2569 const WCHAR *str = (const WCHAR *)pMemory;
2570 while (i < maxsize && str[i]) i++;
2571 TRACE("string=%s\n", debugstr_wn(str, i));
2572 pStubMsg->ActualCount = i + 1;
2577 ERR("Unhandled string type: %#x\n", *pFormat);
2578 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2581 pStubMsg->Offset = 0;
2582 WriteVariance(pStubMsg);
2584 size = safe_multiply(esize, pStubMsg->ActualCount);
2585 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2590 /***********************************************************************
2591 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2593 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2594 unsigned char **ppMemory,
2595 PFORMAT_STRING pFormat,
2596 unsigned char fMustAlloc)
2598 ULONG bufsize, memsize, esize, maxsize;
2600 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2601 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2603 maxsize = *(const USHORT *)&pFormat[2];
2605 ReadVariance(pStubMsg, NULL, maxsize);
2606 if (pStubMsg->Offset)
2608 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2609 RpcRaiseException(RPC_S_INVALID_BOUND);
2612 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2613 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2616 ERR("Unhandled string type: %#x\n", *pFormat);
2617 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2620 memsize = esize * maxsize;
2621 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2623 validate_string_data(pStubMsg, bufsize, esize);
2625 if (!fMustAlloc && !*ppMemory)
2628 *ppMemory = NdrAllocate(pStubMsg, memsize);
2630 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2632 if (*pFormat == RPC_FC_CSTRING) {
2633 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
2635 else if (*pFormat == RPC_FC_WSTRING) {
2636 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
2642 /***********************************************************************
2643 * NdrNonConformantStringBufferSize [RPCRT4.@]
2645 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2646 unsigned char *pMemory,
2647 PFORMAT_STRING pFormat)
2649 ULONG esize, maxsize;
2651 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2653 maxsize = *(const USHORT *)&pFormat[2];
2655 SizeVariance(pStubMsg);
2657 if (*pFormat == RPC_FC_CSTRING)
2660 const char *str = (const char *)pMemory;
2661 while (i < maxsize && str[i]) i++;
2662 TRACE("string=%s\n", debugstr_an(str, i));
2663 pStubMsg->ActualCount = i + 1;
2666 else if (*pFormat == RPC_FC_WSTRING)
2669 const WCHAR *str = (const WCHAR *)pMemory;
2670 while (i < maxsize && str[i]) i++;
2671 TRACE("string=%s\n", debugstr_wn(str, i));
2672 pStubMsg->ActualCount = i + 1;
2677 ERR("Unhandled string type: %#x\n", *pFormat);
2678 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2681 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2684 /***********************************************************************
2685 * NdrNonConformantStringMemorySize [RPCRT4.@]
2687 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2688 PFORMAT_STRING pFormat)
2690 ULONG bufsize, memsize, esize, maxsize;
2692 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2694 maxsize = *(const USHORT *)&pFormat[2];
2696 ReadVariance(pStubMsg, NULL, maxsize);
2698 if (pStubMsg->Offset)
2700 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2701 RpcRaiseException(RPC_S_INVALID_BOUND);
2704 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2705 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2708 ERR("Unhandled string type: %#x\n", *pFormat);
2709 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2712 memsize = esize * maxsize;
2713 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2715 validate_string_data(pStubMsg, bufsize, esize);
2717 safe_buffer_increment(pStubMsg, bufsize);
2718 pStubMsg->MemorySize += memsize;
2720 return pStubMsg->MemorySize;
2725 #include "pshpack1.h"
2729 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2733 #include "poppack.h"
2735 static ULONG EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2736 PFORMAT_STRING pFormat)
2740 case RPC_FC_PSTRUCT:
2741 case RPC_FC_CSTRUCT:
2742 case RPC_FC_BOGUS_STRUCT:
2743 case RPC_FC_SMFARRAY:
2744 case RPC_FC_SMVARRAY:
2745 case RPC_FC_CSTRING:
2746 return *(const WORD*)&pFormat[2];
2747 case RPC_FC_USER_MARSHAL:
2748 return *(const WORD*)&pFormat[4];
2749 case RPC_FC_RANGE: {
2750 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2755 return sizeof(UCHAR);
2759 return sizeof(USHORT);
2763 case RPC_FC_INT3264:
2764 case RPC_FC_UINT3264:
2765 return sizeof(ULONG);
2767 return sizeof(float);
2769 return sizeof(double);
2771 return sizeof(ULONGLONG);
2773 return sizeof(UINT);
2775 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2776 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2779 case RPC_FC_NON_ENCAPSULATED_UNION:
2781 if (pStubMsg->fHasNewCorrDesc)
2786 pFormat += *(const SHORT*)pFormat;
2787 return *(const SHORT*)pFormat;
2789 return sizeof(void *);
2790 case RPC_FC_WSTRING:
2791 return *(const WORD*)&pFormat[2] * 2;
2793 FIXME("unhandled embedded type %02x\n", *pFormat);
2799 static ULONG EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2800 PFORMAT_STRING pFormat)
2802 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2806 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2810 return m(pStubMsg, pFormat);
2814 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2815 unsigned char *pMemory,
2816 PFORMAT_STRING pFormat,
2817 PFORMAT_STRING pPointer)
2819 PFORMAT_STRING desc;
2823 while (*pFormat != RPC_FC_END) {
2829 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2830 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2836 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2837 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2842 USHORT val = *(DWORD *)pMemory;
2843 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2844 if (32767 < *(DWORD*)pMemory)
2845 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2846 safe_copy_to_buffer(pStubMsg, &val, 2);
2853 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2854 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2857 case RPC_FC_INT3264:
2858 case RPC_FC_UINT3264:
2860 UINT val = *(UINT_PTR *)pMemory;
2861 TRACE("int3264=%ld <= %p\n", *(UINT_PTR *)pMemory, pMemory);
2862 safe_copy_to_buffer(pStubMsg, &val, sizeof(UINT));
2863 pMemory += sizeof(UINT_PTR);
2867 TRACE("float=%f <= %p\n", *(float*)pMemory, pMemory);
2868 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
2869 pMemory += sizeof(float);
2872 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2873 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2877 TRACE("double=%f <= %p\n", *(double*)pMemory, pMemory);
2878 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
2879 pMemory += sizeof(double);
2885 case RPC_FC_POINTER:
2887 unsigned char *saved_buffer;
2888 int pointer_buffer_mark_set = 0;
2889 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2890 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2891 if (*pFormat != RPC_FC_POINTER)
2893 if (*pPointer != RPC_FC_RP)
2894 align_pointer_clear(&pStubMsg->Buffer, 4);
2895 saved_buffer = pStubMsg->Buffer;
2896 if (pStubMsg->PointerBufferMark)
2898 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2899 pStubMsg->PointerBufferMark = NULL;
2900 pointer_buffer_mark_set = 1;
2902 else if (*pPointer != RPC_FC_RP)
2903 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2904 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2905 if (pointer_buffer_mark_set)
2907 STD_OVERFLOW_CHECK(pStubMsg);
2908 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2909 pStubMsg->Buffer = saved_buffer;
2910 if (*pPointer != RPC_FC_RP)
2911 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2913 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2914 if (*pFormat == RPC_FC_POINTER)
2918 pMemory += sizeof(void *);
2921 case RPC_FC_ALIGNM2:
2922 align_pointer(&pMemory, 2);
2924 case RPC_FC_ALIGNM4:
2925 align_pointer(&pMemory, 4);
2927 case RPC_FC_ALIGNM8:
2928 align_pointer(&pMemory, 8);
2930 case RPC_FC_STRUCTPAD1:
2931 case RPC_FC_STRUCTPAD2:
2932 case RPC_FC_STRUCTPAD3:
2933 case RPC_FC_STRUCTPAD4:
2934 case RPC_FC_STRUCTPAD5:
2935 case RPC_FC_STRUCTPAD6:
2936 case RPC_FC_STRUCTPAD7:
2937 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2939 case RPC_FC_EMBEDDED_COMPLEX:
2940 pMemory += pFormat[1];
2942 desc = pFormat + *(const SHORT*)pFormat;
2943 size = EmbeddedComplexSize(pStubMsg, desc);
2944 TRACE("embedded complex (size=%d) <= %p\n", size, pMemory);
2945 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2948 /* for some reason interface pointers aren't generated as
2949 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2950 * they still need the derefencing treatment that pointers are
2952 if (*desc == RPC_FC_IP)
2953 m(pStubMsg, *(unsigned char **)pMemory, desc);
2955 m(pStubMsg, pMemory, desc);
2957 else FIXME("no marshaller for embedded type %02x\n", *desc);
2964 FIXME("unhandled format 0x%02x\n", *pFormat);
2972 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2973 unsigned char *pMemory,
2974 PFORMAT_STRING pFormat,
2975 PFORMAT_STRING pPointer,
2976 unsigned char fMustAlloc)
2978 PFORMAT_STRING desc;
2982 while (*pFormat != RPC_FC_END) {
2988 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2989 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2995 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2996 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
3002 safe_copy_from_buffer(pStubMsg, &val, 2);
3003 *(DWORD*)pMemory = val;
3004 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
3005 if (32767 < *(DWORD*)pMemory)
3006 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
3013 safe_copy_from_buffer(pStubMsg, pMemory, 4);
3014 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
3017 case RPC_FC_INT3264:
3020 safe_copy_from_buffer(pStubMsg, &val, 4);
3021 *(INT_PTR *)pMemory = val;
3022 TRACE("int3264=%ld => %p\n", *(INT_PTR*)pMemory, pMemory);
3023 pMemory += sizeof(INT_PTR);
3026 case RPC_FC_UINT3264:
3029 safe_copy_from_buffer(pStubMsg, &val, 4);
3030 *(UINT_PTR *)pMemory = val;
3031 TRACE("uint3264=%ld => %p\n", *(UINT_PTR*)pMemory, pMemory);
3032 pMemory += sizeof(UINT_PTR);
3036 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(float));
3037 TRACE("float=%f => %p\n", *(float*)pMemory, pMemory);
3038 pMemory += sizeof(float);
3041 safe_copy_from_buffer(pStubMsg, pMemory, 8);
3042 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
3046 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(double));
3047 TRACE("double=%f => %p\n", *(double*)pMemory, pMemory);
3048 pMemory += sizeof(double);
3054 case RPC_FC_POINTER:
3056 unsigned char *saved_buffer;
3057 int pointer_buffer_mark_set = 0;
3058 TRACE("pointer => %p\n", pMemory);
3059 if (*pFormat != RPC_FC_POINTER)
3061 if (*pPointer != RPC_FC_RP)
3062 align_pointer(&pStubMsg->Buffer, 4);
3063 saved_buffer = pStubMsg->Buffer;
3064 if (pStubMsg->PointerBufferMark)
3066 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3067 pStubMsg->PointerBufferMark = NULL;
3068 pointer_buffer_mark_set = 1;
3070 else if (*pPointer != RPC_FC_RP)
3071 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3073 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
3074 if (pointer_buffer_mark_set)
3076 STD_OVERFLOW_CHECK(pStubMsg);
3077 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3078 pStubMsg->Buffer = saved_buffer;
3079 if (*pPointer != RPC_FC_RP)
3080 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3082 if (*pFormat == RPC_FC_POINTER)
3086 pMemory += sizeof(void *);
3089 case RPC_FC_ALIGNM2:
3090 align_pointer_clear(&pMemory, 2);
3092 case RPC_FC_ALIGNM4:
3093 align_pointer_clear(&pMemory, 4);
3095 case RPC_FC_ALIGNM8:
3096 align_pointer_clear(&pMemory, 8);
3098 case RPC_FC_STRUCTPAD1:
3099 case RPC_FC_STRUCTPAD2:
3100 case RPC_FC_STRUCTPAD3:
3101 case RPC_FC_STRUCTPAD4:
3102 case RPC_FC_STRUCTPAD5:
3103 case RPC_FC_STRUCTPAD6:
3104 case RPC_FC_STRUCTPAD7:
3105 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
3106 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3108 case RPC_FC_EMBEDDED_COMPLEX:
3109 pMemory += pFormat[1];
3111 desc = pFormat + *(const SHORT*)pFormat;
3112 size = EmbeddedComplexSize(pStubMsg, desc);
3113 TRACE("embedded complex (size=%d) => %p\n", size, pMemory);
3115 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
3116 * since the type is part of the memory block that is encompassed by
3117 * the whole complex type. Memory is forced to allocate when pointers
3118 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
3119 * clearing the memory we pass in to the unmarshaller */
3120 memset(pMemory, 0, size);
3121 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
3124 /* for some reason interface pointers aren't generated as
3125 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3126 * they still need the derefencing treatment that pointers are
3128 if (*desc == RPC_FC_IP)
3129 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
3131 m(pStubMsg, &pMemory, desc, FALSE);
3133 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
3140 FIXME("unhandled format %d\n", *pFormat);
3148 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3149 unsigned char *pMemory,
3150 PFORMAT_STRING pFormat,
3151 PFORMAT_STRING pPointer)
3153 PFORMAT_STRING desc;
3157 while (*pFormat != RPC_FC_END) {
3163 safe_buffer_length_increment(pStubMsg, 1);
3169 safe_buffer_length_increment(pStubMsg, 2);
3173 safe_buffer_length_increment(pStubMsg, 2);
3180 safe_buffer_length_increment(pStubMsg, 4);
3183 case RPC_FC_INT3264:
3184 case RPC_FC_UINT3264:
3185 safe_buffer_length_increment(pStubMsg, 4);
3186 pMemory += sizeof(INT_PTR);
3190 safe_buffer_length_increment(pStubMsg, 8);
3197 case RPC_FC_POINTER:
3198 if (*pFormat != RPC_FC_POINTER)
3200 if (!pStubMsg->IgnoreEmbeddedPointers)
3202 int saved_buffer_length = pStubMsg->BufferLength;
3203 pStubMsg->BufferLength = pStubMsg->PointerLength;
3204 pStubMsg->PointerLength = 0;
3205 if(!pStubMsg->BufferLength)
3206 ERR("BufferLength == 0??\n");
3207 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
3208 pStubMsg->PointerLength = pStubMsg->BufferLength;
3209 pStubMsg->BufferLength = saved_buffer_length;
3211 if (*pPointer != RPC_FC_RP)
3213 align_length(&pStubMsg->BufferLength, 4);
3214 safe_buffer_length_increment(pStubMsg, 4);
3216 if (*pFormat == RPC_FC_POINTER)
3220 pMemory += sizeof(void*);
3222 case RPC_FC_ALIGNM2:
3223 align_pointer(&pMemory, 2);
3225 case RPC_FC_ALIGNM4:
3226 align_pointer(&pMemory, 4);
3228 case RPC_FC_ALIGNM8:
3229 align_pointer(&pMemory, 8);
3231 case RPC_FC_STRUCTPAD1:
3232 case RPC_FC_STRUCTPAD2:
3233 case RPC_FC_STRUCTPAD3:
3234 case RPC_FC_STRUCTPAD4:
3235 case RPC_FC_STRUCTPAD5:
3236 case RPC_FC_STRUCTPAD6:
3237 case RPC_FC_STRUCTPAD7:
3238 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3240 case RPC_FC_EMBEDDED_COMPLEX:
3241 pMemory += pFormat[1];
3243 desc = pFormat + *(const SHORT*)pFormat;
3244 size = EmbeddedComplexSize(pStubMsg, desc);
3245 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
3248 /* for some reason interface pointers aren't generated as
3249 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3250 * they still need the derefencing treatment that pointers are
3252 if (*desc == RPC_FC_IP)
3253 m(pStubMsg, *(unsigned char **)pMemory, desc);
3255 m(pStubMsg, pMemory, desc);
3257 else FIXME("no buffersizer for embedded type %02x\n", *desc);
3264 FIXME("unhandled format 0x%02x\n", *pFormat);
3272 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
3273 unsigned char *pMemory,
3274 PFORMAT_STRING pFormat,
3275 PFORMAT_STRING pPointer)
3277 PFORMAT_STRING desc;
3281 while (*pFormat != RPC_FC_END) {
3301 case RPC_FC_INT3264:
3302 case RPC_FC_UINT3264:
3303 pMemory += sizeof(INT_PTR);
3313 case RPC_FC_POINTER:
3314 if (*pFormat != RPC_FC_POINTER)
3316 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3317 if (*pFormat == RPC_FC_POINTER)
3321 pMemory += sizeof(void *);
3323 case RPC_FC_ALIGNM2:
3324 align_pointer(&pMemory, 2);
3326 case RPC_FC_ALIGNM4:
3327 align_pointer(&pMemory, 4);
3329 case RPC_FC_ALIGNM8:
3330 align_pointer(&pMemory, 8);
3332 case RPC_FC_STRUCTPAD1:
3333 case RPC_FC_STRUCTPAD2:
3334 case RPC_FC_STRUCTPAD3:
3335 case RPC_FC_STRUCTPAD4:
3336 case RPC_FC_STRUCTPAD5:
3337 case RPC_FC_STRUCTPAD6:
3338 case RPC_FC_STRUCTPAD7:
3339 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3341 case RPC_FC_EMBEDDED_COMPLEX:
3342 pMemory += pFormat[1];
3344 desc = pFormat + *(const SHORT*)pFormat;
3345 size = EmbeddedComplexSize(pStubMsg, desc);
3346 m = NdrFreer[*desc & NDR_TABLE_MASK];
3349 /* for some reason interface pointers aren't generated as
3350 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3351 * they still need the derefencing treatment that pointers are
3353 if (*desc == RPC_FC_IP)
3354 m(pStubMsg, *(unsigned char **)pMemory, desc);
3356 m(pStubMsg, pMemory, desc);
3364 FIXME("unhandled format 0x%02x\n", *pFormat);
3372 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3373 PFORMAT_STRING pFormat,
3374 PFORMAT_STRING pPointer)
3376 PFORMAT_STRING desc;
3379 while (*pFormat != RPC_FC_END) {
3386 safe_buffer_increment(pStubMsg, 1);
3392 safe_buffer_increment(pStubMsg, 2);
3396 safe_buffer_increment(pStubMsg, 2);
3403 safe_buffer_increment(pStubMsg, 4);
3405 case RPC_FC_INT3264:
3406 case RPC_FC_UINT3264:
3407 size += sizeof(INT_PTR);
3408 safe_buffer_increment(pStubMsg, 4);
3413 safe_buffer_increment(pStubMsg, 8);
3419 case RPC_FC_POINTER:
3421 unsigned char *saved_buffer;
3422 int pointer_buffer_mark_set = 0;
3423 if (*pFormat != RPC_FC_POINTER)
3425 if (*pPointer != RPC_FC_RP)
3426 align_pointer(&pStubMsg->Buffer, 4);
3427 saved_buffer = pStubMsg->Buffer;
3428 if (pStubMsg->PointerBufferMark)
3430 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3431 pStubMsg->PointerBufferMark = NULL;
3432 pointer_buffer_mark_set = 1;
3434 else if (*pPointer != RPC_FC_RP)
3435 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3437 if (!pStubMsg->IgnoreEmbeddedPointers)
3438 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3439 if (pointer_buffer_mark_set)
3441 STD_OVERFLOW_CHECK(pStubMsg);
3442 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3443 pStubMsg->Buffer = saved_buffer;
3444 if (*pPointer != RPC_FC_RP)
3445 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3447 if (*pFormat == RPC_FC_POINTER)
3451 size += sizeof(void *);
3454 case RPC_FC_ALIGNM2:
3455 align_length(&size, 2);
3457 case RPC_FC_ALIGNM4:
3458 align_length(&size, 4);
3460 case RPC_FC_ALIGNM8:
3461 align_length(&size, 8);
3463 case RPC_FC_STRUCTPAD1:
3464 case RPC_FC_STRUCTPAD2:
3465 case RPC_FC_STRUCTPAD3:
3466 case RPC_FC_STRUCTPAD4:
3467 case RPC_FC_STRUCTPAD5:
3468 case RPC_FC_STRUCTPAD6:
3469 case RPC_FC_STRUCTPAD7:
3470 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3472 case RPC_FC_EMBEDDED_COMPLEX:
3475 desc = pFormat + *(const SHORT*)pFormat;
3476 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3482 FIXME("unhandled format 0x%02x\n", *pFormat);
3490 ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
3492 PFORMAT_STRING desc;
3495 while (*pFormat != RPC_FC_END) {
3515 case RPC_FC_INT3264:
3516 case RPC_FC_UINT3264:
3517 size += sizeof(INT_PTR);
3527 case RPC_FC_POINTER:
3528 size += sizeof(void *);
3529 if (*pFormat != RPC_FC_POINTER)
3532 case RPC_FC_ALIGNM2:
3533 align_length(&size, 2);
3535 case RPC_FC_ALIGNM4:
3536 align_length(&size, 4);
3538 case RPC_FC_ALIGNM8:
3539 align_length(&size, 8);
3541 case RPC_FC_STRUCTPAD1:
3542 case RPC_FC_STRUCTPAD2:
3543 case RPC_FC_STRUCTPAD3:
3544 case RPC_FC_STRUCTPAD4:
3545 case RPC_FC_STRUCTPAD5:
3546 case RPC_FC_STRUCTPAD6:
3547 case RPC_FC_STRUCTPAD7:
3548 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3550 case RPC_FC_EMBEDDED_COMPLEX:
3553 desc = pFormat + *(const SHORT*)pFormat;
3554 size += EmbeddedComplexSize(pStubMsg, desc);
3560 FIXME("unhandled format 0x%02x\n", *pFormat);
3568 /***********************************************************************
3569 * NdrComplexStructMarshall [RPCRT4.@]
3571 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3572 unsigned char *pMemory,
3573 PFORMAT_STRING pFormat)
3575 PFORMAT_STRING conf_array = NULL;
3576 PFORMAT_STRING pointer_desc = NULL;
3577 unsigned char *OldMemory = pStubMsg->Memory;
3578 int pointer_buffer_mark_set = 0;
3580 ULONG max_count = 0;
3583 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3585 if (!pStubMsg->PointerBufferMark)
3587 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3588 /* save buffer length */
3589 ULONG saved_buffer_length = pStubMsg->BufferLength;
3591 /* get the buffer pointer after complex array data, but before
3593 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3594 pStubMsg->IgnoreEmbeddedPointers = 1;
3595 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3596 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3598 /* save it for use by embedded pointer code later */
3599 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3600 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - pStubMsg->Buffer));
3601 pointer_buffer_mark_set = 1;
3603 /* restore the original buffer length */
3604 pStubMsg->BufferLength = saved_buffer_length;
3607 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1);
3610 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3612 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3615 pStubMsg->Memory = pMemory;
3619 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3620 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3621 pMemory + struct_size, conf_array);
3622 /* these could be changed in ComplexMarshall so save them for later */
3623 max_count = pStubMsg->MaxCount;
3624 count = pStubMsg->ActualCount;
3625 offset = pStubMsg->Offset;
3628 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3632 pStubMsg->MaxCount = max_count;
3633 pStubMsg->ActualCount = count;
3634 pStubMsg->Offset = offset;
3635 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3636 conf_array, TRUE /* fHasPointers */);
3639 pStubMsg->Memory = OldMemory;
3641 if (pointer_buffer_mark_set)
3643 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3644 pStubMsg->PointerBufferMark = NULL;
3647 STD_OVERFLOW_CHECK(pStubMsg);
3652 /***********************************************************************
3653 * NdrComplexStructUnmarshall [RPCRT4.@]
3655 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3656 unsigned char **ppMemory,
3657 PFORMAT_STRING pFormat,
3658 unsigned char fMustAlloc)
3660 unsigned size = *(const WORD*)(pFormat+2);
3661 PFORMAT_STRING conf_array = NULL;
3662 PFORMAT_STRING pointer_desc = NULL;
3663 unsigned char *pMemory;
3664 int pointer_buffer_mark_set = 0;
3666 ULONG max_count = 0;
3668 ULONG array_size = 0;
3670 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3672 if (!pStubMsg->PointerBufferMark)
3674 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3675 /* save buffer pointer */
3676 unsigned char *saved_buffer = pStubMsg->Buffer;
3678 /* get the buffer pointer after complex array data, but before
3680 pStubMsg->IgnoreEmbeddedPointers = 1;
3681 NdrComplexStructMemorySize(pStubMsg, pFormat);
3682 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3684 /* save it for use by embedded pointer code later */
3685 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3686 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - saved_buffer));
3687 pointer_buffer_mark_set = 1;
3689 /* restore the original buffer */
3690 pStubMsg->Buffer = saved_buffer;
3693 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3696 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3698 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3703 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3706 /* these could be changed in ComplexMarshall so save them for later */
3707 max_count = pStubMsg->MaxCount;
3708 count = pStubMsg->ActualCount;
3709 offset = pStubMsg->Offset;
3712 if (!fMustAlloc && !*ppMemory)
3715 *ppMemory = NdrAllocate(pStubMsg, size);
3717 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3721 pStubMsg->MaxCount = max_count;
3722 pStubMsg->ActualCount = count;
3723 pStubMsg->Offset = offset;
3725 memset(pMemory, 0, array_size);
3726 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3728 FALSE /* fUseBufferMemoryServer */,
3729 TRUE /* fUnmarshall */);
3732 if (pointer_buffer_mark_set)
3734 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3735 pStubMsg->PointerBufferMark = NULL;
3741 /***********************************************************************
3742 * NdrComplexStructBufferSize [RPCRT4.@]
3744 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3745 unsigned char *pMemory,
3746 PFORMAT_STRING pFormat)
3748 PFORMAT_STRING conf_array = NULL;
3749 PFORMAT_STRING pointer_desc = NULL;
3750 unsigned char *OldMemory = pStubMsg->Memory;
3751 int pointer_length_set = 0;
3753 ULONG max_count = 0;
3756 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3758 align_length(&pStubMsg->BufferLength, pFormat[1] + 1);
3760 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3762 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3763 ULONG saved_buffer_length = pStubMsg->BufferLength;
3765 /* get the buffer length after complex struct data, but before
3767 pStubMsg->IgnoreEmbeddedPointers = 1;
3768 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3769 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3771 /* save it for use by embedded pointer code later */
3772 pStubMsg->PointerLength = pStubMsg->BufferLength;
3773 pointer_length_set = 1;
3774 TRACE("difference = 0x%x\n", pStubMsg->PointerLength - saved_buffer_length);
3776 /* restore the original buffer length */
3777 pStubMsg->BufferLength = saved_buffer_length;
3781 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3783 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3786 pStubMsg->Memory = pMemory;
3790 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3791 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3794 /* these could be changed in ComplexMarshall so save them for later */
3795 max_count = pStubMsg->MaxCount;
3796 count = pStubMsg->ActualCount;
3797 offset = pStubMsg->Offset;
3800 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3804 pStubMsg->MaxCount = max_count;
3805 pStubMsg->ActualCount = count;
3806 pStubMsg->Offset = offset;
3807 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3808 TRUE /* fHasPointers */);
3811 pStubMsg->Memory = OldMemory;
3813 if(pointer_length_set)
3815 pStubMsg->BufferLength = pStubMsg->PointerLength;
3816 pStubMsg->PointerLength = 0;
3821 /***********************************************************************
3822 * NdrComplexStructMemorySize [RPCRT4.@]
3824 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3825 PFORMAT_STRING pFormat)
3827 unsigned size = *(const WORD*)(pFormat+2);
3828 PFORMAT_STRING conf_array = NULL;
3829 PFORMAT_STRING pointer_desc = NULL;
3831 ULONG max_count = 0;
3834 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3836 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3839 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3841 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3846 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3848 /* these could be changed in ComplexStructMemorySize so save them for
3850 max_count = pStubMsg->MaxCount;
3851 count = pStubMsg->ActualCount;
3852 offset = pStubMsg->Offset;
3855 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3859 pStubMsg->MaxCount = max_count;
3860 pStubMsg->ActualCount = count;
3861 pStubMsg->Offset = offset;
3862 array_memory_size(conf_array[0], pStubMsg, conf_array,
3863 TRUE /* fHasPointers */);
3869 /***********************************************************************
3870 * NdrComplexStructFree [RPCRT4.@]
3872 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3873 unsigned char *pMemory,
3874 PFORMAT_STRING pFormat)
3876 PFORMAT_STRING conf_array = NULL;
3877 PFORMAT_STRING pointer_desc = NULL;
3878 unsigned char *OldMemory = pStubMsg->Memory;
3880 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3883 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3885 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3888 pStubMsg->Memory = pMemory;
3890 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3893 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3894 TRUE /* fHasPointers */);
3896 pStubMsg->Memory = OldMemory;
3899 /***********************************************************************
3900 * NdrConformantArrayMarshall [RPCRT4.@]
3902 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3903 unsigned char *pMemory,
3904 PFORMAT_STRING pFormat)
3906 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3907 if (pFormat[0] != RPC_FC_CARRAY)
3909 ERR("invalid format = 0x%x\n", pFormat[0]);
3910 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3913 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory,
3915 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3916 TRUE /* fHasPointers */);
3921 /***********************************************************************
3922 * NdrConformantArrayUnmarshall [RPCRT4.@]
3924 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3925 unsigned char **ppMemory,
3926 PFORMAT_STRING pFormat,
3927 unsigned char fMustAlloc)
3929 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3930 if (pFormat[0] != RPC_FC_CARRAY)
3932 ERR("invalid format = 0x%x\n", pFormat[0]);
3933 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3936 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3937 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat,
3939 TRUE /* fUseBufferMemoryServer */,
3940 TRUE /* fUnmarshall */);
3945 /***********************************************************************
3946 * NdrConformantArrayBufferSize [RPCRT4.@]
3948 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3949 unsigned char *pMemory,
3950 PFORMAT_STRING pFormat)
3952 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3953 if (pFormat[0] != RPC_FC_CARRAY)
3955 ERR("invalid format = 0x%x\n", pFormat[0]);
3956 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3959 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat);
3960 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3961 TRUE /* fHasPointers */);
3964 /***********************************************************************
3965 * NdrConformantArrayMemorySize [RPCRT4.@]
3967 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3968 PFORMAT_STRING pFormat)
3970 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3971 if (pFormat[0] != RPC_FC_CARRAY)
3973 ERR("invalid format = 0x%x\n", pFormat[0]);
3974 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3977 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3978 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
3980 return pStubMsg->MemorySize;
3983 /***********************************************************************
3984 * NdrConformantArrayFree [RPCRT4.@]
3986 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3987 unsigned char *pMemory,
3988 PFORMAT_STRING pFormat)
3990 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3991 if (pFormat[0] != RPC_FC_CARRAY)
3993 ERR("invalid format = 0x%x\n", pFormat[0]);
3994 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3997 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3998 TRUE /* fHasPointers */);
4002 /***********************************************************************
4003 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
4005 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
4006 unsigned char* pMemory,
4007 PFORMAT_STRING pFormat )
4009 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4011 if (pFormat[0] != RPC_FC_CVARRAY)
4013 ERR("invalid format type %x\n", pFormat[0]);
4014 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4018 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
4020 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory,
4021 pFormat, TRUE /* fHasPointers */);
4027 /***********************************************************************
4028 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
4030 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
4031 unsigned char** ppMemory,
4032 PFORMAT_STRING pFormat,
4033 unsigned char fMustAlloc )
4035 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4037 if (pFormat[0] != RPC_FC_CVARRAY)
4039 ERR("invalid format type %x\n", pFormat[0]);
4040 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4044 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
4045 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory,
4046 pFormat, fMustAlloc,
4047 TRUE /* fUseBufferMemoryServer */,
4048 TRUE /* fUnmarshall */);
4054 /***********************************************************************
4055 * NdrConformantVaryingArrayFree [RPCRT4.@]
4057 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
4058 unsigned char* pMemory,
4059 PFORMAT_STRING pFormat )
4061 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4063 if (pFormat[0] != RPC_FC_CVARRAY)
4065 ERR("invalid format type %x\n", pFormat[0]);
4066 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4070 array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
4071 TRUE /* fHasPointers */);
4075 /***********************************************************************
4076 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
4078 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
4079 unsigned char* pMemory, PFORMAT_STRING pFormat )
4081 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4083 if (pFormat[0] != RPC_FC_CVARRAY)
4085 ERR("invalid format type %x\n", pFormat[0]);
4086 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4090 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
4092 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
4093 TRUE /* fHasPointers */);
4097 /***********************************************************************
4098 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
4100 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
4101 PFORMAT_STRING pFormat )
4103 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4105 if (pFormat[0] != RPC_FC_CVARRAY)
4107 ERR("invalid format type %x\n", pFormat[0]);
4108 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4109 return pStubMsg->MemorySize;
4112 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
4113 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat,
4114 TRUE /* fHasPointers */);
4116 return pStubMsg->MemorySize;
4120 /***********************************************************************
4121 * NdrComplexArrayMarshall [RPCRT4.@]
4123 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4124 unsigned char *pMemory,
4125 PFORMAT_STRING pFormat)
4127 int pointer_buffer_mark_set = 0;
4129 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4131 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4133 ERR("invalid format type %x\n", pFormat[0]);
4134 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4138 if (!pStubMsg->PointerBufferMark)
4140 /* save buffer fields that may be changed by buffer sizer functions
4141 * and that may be needed later on */
4142 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4143 ULONG saved_buffer_length = pStubMsg->BufferLength;
4144 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4145 ULONG saved_offset = pStubMsg->Offset;
4146 ULONG saved_actual_count = pStubMsg->ActualCount;
4148 /* get the buffer pointer after complex array data, but before
4150 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
4151 pStubMsg->IgnoreEmbeddedPointers = 1;
4152 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4153 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4155 /* save it for use by embedded pointer code later */
4156 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
4157 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer));
4158 pointer_buffer_mark_set = 1;
4160 /* restore fields */
4161 pStubMsg->ActualCount = saved_actual_count;
4162 pStubMsg->Offset = saved_offset;
4163 pStubMsg->MaxCount = saved_max_count;
4164 pStubMsg->BufferLength = saved_buffer_length;
4167 array_compute_and_write_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4168 array_write_variance_and_marshall(RPC_FC_BOGUS_ARRAY, pStubMsg,
4169 pMemory, pFormat, TRUE /* fHasPointers */);
4171 STD_OVERFLOW_CHECK(pStubMsg);
4173 if (pointer_buffer_mark_set)
4175 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4176 pStubMsg->PointerBufferMark = NULL;
4182 /***********************************************************************
4183 * NdrComplexArrayUnmarshall [RPCRT4.@]
4185 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4186 unsigned char **ppMemory,
4187 PFORMAT_STRING pFormat,
4188 unsigned char fMustAlloc)
4191 unsigned char *saved_buffer;
4192 int pointer_buffer_mark_set = 0;
4193 int saved_ignore_embedded;
4195 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4197 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4199 ERR("invalid format type %x\n", pFormat[0]);
4200 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4204 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4205 /* save buffer pointer */
4206 saved_buffer = pStubMsg->Buffer;
4207 /* get the buffer pointer after complex array data, but before
4209 pStubMsg->IgnoreEmbeddedPointers = 1;
4210 pStubMsg->MemorySize = 0;
4211 NdrComplexArrayMemorySize(pStubMsg, pFormat);
4212 size = pStubMsg->MemorySize;
4213 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4215 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - saved_buffer));
4216 if (!pStubMsg->PointerBufferMark)
4218 /* save it for use by embedded pointer code later */
4219 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4220 pointer_buffer_mark_set = 1;
4222 /* restore the original buffer */
4223 pStubMsg->Buffer = saved_buffer;
4225 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
4226 array_read_variance_and_unmarshall(RPC_FC_BOGUS_ARRAY, pStubMsg, ppMemory, pFormat, fMustAlloc,
4227 TRUE /* fUseBufferMemoryServer */, TRUE /* fUnmarshall */);
4229 if (pointer_buffer_mark_set)
4231 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4232 pStubMsg->PointerBufferMark = NULL;
4238 /***********************************************************************
4239 * NdrComplexArrayBufferSize [RPCRT4.@]
4241 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4242 unsigned char *pMemory,
4243 PFORMAT_STRING pFormat)
4245 int pointer_length_set = 0;
4247 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4249 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4251 ERR("invalid format type %x\n", pFormat[0]);
4252 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4256 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
4258 /* save buffer fields that may be changed by buffer sizer functions
4259 * and that may be needed later on */
4260 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4261 ULONG saved_buffer_length = pStubMsg->BufferLength;
4262 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4263 ULONG saved_offset = pStubMsg->Offset;
4264 ULONG saved_actual_count = pStubMsg->ActualCount;
4266 /* get the buffer pointer after complex array data, but before
4268 pStubMsg->IgnoreEmbeddedPointers = 1;
4269 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4270 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4272 /* save it for use by embedded pointer code later */
4273 pStubMsg->PointerLength = pStubMsg->BufferLength;
4274 pointer_length_set = 1;
4276 /* restore fields */
4277 pStubMsg->ActualCount = saved_actual_count;
4278 pStubMsg->Offset = saved_offset;
4279 pStubMsg->MaxCount = saved_max_count;
4280 pStubMsg->BufferLength = saved_buffer_length;
4283 array_compute_and_size_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4284 array_buffer_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat, TRUE /* fHasPointers */);
4286 if(pointer_length_set)
4288 pStubMsg->BufferLength = pStubMsg->PointerLength;
4289 pStubMsg->PointerLength = 0;
4293 /***********************************************************************
4294 * NdrComplexArrayMemorySize [RPCRT4.@]
4296 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4297 PFORMAT_STRING pFormat)
4299 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4301 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4303 ERR("invalid format type %x\n", pFormat[0]);
4304 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4308 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
4309 array_memory_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
4310 return pStubMsg->MemorySize;
4313 /***********************************************************************
4314 * NdrComplexArrayFree [RPCRT4.@]
4316 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4317 unsigned char *pMemory,
4318 PFORMAT_STRING pFormat)
4320 ULONG i, count, def;
4322 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4324 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4326 ERR("invalid format type %x\n", pFormat[0]);
4327 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4331 def = *(const WORD*)&pFormat[2];
4334 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4335 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4337 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4338 TRACE("variance = %d\n", pStubMsg->ActualCount);
4340 count = pStubMsg->ActualCount;
4341 for (i = 0; i < count; i++)
4342 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4345 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4346 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4347 USER_MARSHAL_CB *umcb)
4349 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4350 pStubMsg->RpcMsg->DataRepresentation);
4351 umcb->pStubMsg = pStubMsg;
4352 umcb->pReserve = NULL;
4353 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4354 umcb->CBType = cbtype;
4355 umcb->pFormat = pFormat;
4356 umcb->pTypeFormat = NULL /* FIXME */;
4359 #define USER_MARSHAL_PTR_PREFIX \
4360 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4361 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4363 /***********************************************************************
4364 * NdrUserMarshalMarshall [RPCRT4.@]
4366 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4367 unsigned char *pMemory,
4368 PFORMAT_STRING pFormat)
4370 unsigned flags = pFormat[1];
4371 unsigned index = *(const WORD*)&pFormat[2];
4372 unsigned char *saved_buffer = NULL;
4373 USER_MARSHAL_CB umcb;
4375 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4376 TRACE("index=%d\n", index);
4378 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4380 if (flags & USER_MARSHAL_POINTER)
4382 align_pointer_clear(&pStubMsg->Buffer, 4);
4383 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4384 pStubMsg->Buffer += 4;
4385 if (pStubMsg->PointerBufferMark)
4387 saved_buffer = pStubMsg->Buffer;
4388 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4389 pStubMsg->PointerBufferMark = NULL;
4391 align_pointer_clear(&pStubMsg->Buffer, 8);
4394 align_pointer_clear(&pStubMsg->Buffer, (flags & 0xf) + 1);
4397 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4398 &umcb.Flags, pStubMsg->Buffer, pMemory);
4402 STD_OVERFLOW_CHECK(pStubMsg);
4403 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4404 pStubMsg->Buffer = saved_buffer;
4407 STD_OVERFLOW_CHECK(pStubMsg);
4412 /***********************************************************************
4413 * NdrUserMarshalUnmarshall [RPCRT4.@]
4415 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4416 unsigned char **ppMemory,
4417 PFORMAT_STRING pFormat,
4418 unsigned char fMustAlloc)
4420 unsigned flags = pFormat[1];
4421 unsigned index = *(const WORD*)&pFormat[2];
4422 DWORD memsize = *(const WORD*)&pFormat[4];
4423 unsigned char *saved_buffer = NULL;
4424 USER_MARSHAL_CB umcb;
4426 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4427 TRACE("index=%d\n", index);
4429 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4431 if (flags & USER_MARSHAL_POINTER)
4433 align_pointer(&pStubMsg->Buffer, 4);
4434 /* skip pointer prefix */
4435 pStubMsg->Buffer += 4;
4436 if (pStubMsg->PointerBufferMark)
4438 saved_buffer = pStubMsg->Buffer;
4439 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4440 pStubMsg->PointerBufferMark = NULL;
4442 align_pointer(&pStubMsg->Buffer, 8);
4445 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4447 if (!fMustAlloc && !*ppMemory)
4451 *ppMemory = NdrAllocate(pStubMsg, memsize);
4452 memset(*ppMemory, 0, memsize);
4456 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4457 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4461 STD_OVERFLOW_CHECK(pStubMsg);
4462 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4463 pStubMsg->Buffer = saved_buffer;
4469 /***********************************************************************
4470 * NdrUserMarshalBufferSize [RPCRT4.@]
4472 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4473 unsigned char *pMemory,
4474 PFORMAT_STRING pFormat)
4476 unsigned flags = pFormat[1];
4477 unsigned index = *(const WORD*)&pFormat[2];
4478 DWORD bufsize = *(const WORD*)&pFormat[6];
4479 USER_MARSHAL_CB umcb;
4480 ULONG saved_buffer_length = 0;
4482 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4483 TRACE("index=%d\n", index);
4485 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4487 if (flags & USER_MARSHAL_POINTER)
4489 align_length(&pStubMsg->BufferLength, 4);
4490 /* skip pointer prefix */
4491 safe_buffer_length_increment(pStubMsg, 4);
4492 if (pStubMsg->IgnoreEmbeddedPointers)
4494 if (pStubMsg->PointerLength)
4496 saved_buffer_length = pStubMsg->BufferLength;
4497 pStubMsg->BufferLength = pStubMsg->PointerLength;
4498 pStubMsg->PointerLength = 0;
4500 align_length(&pStubMsg->BufferLength, 8);
4503 align_length(&pStubMsg->BufferLength, (flags & 0xf) + 1);
4506 TRACE("size=%d\n", bufsize);
4507 safe_buffer_length_increment(pStubMsg, bufsize);
4510 pStubMsg->BufferLength =
4511 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4512 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4514 if (saved_buffer_length)
4516 pStubMsg->PointerLength = pStubMsg->BufferLength;
4517 pStubMsg->BufferLength = saved_buffer_length;
4522 /***********************************************************************
4523 * NdrUserMarshalMemorySize [RPCRT4.@]
4525 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4526 PFORMAT_STRING pFormat)
4528 unsigned flags = pFormat[1];
4529 unsigned index = *(const WORD*)&pFormat[2];
4530 DWORD memsize = *(const WORD*)&pFormat[4];
4531 DWORD bufsize = *(const WORD*)&pFormat[6];
4533 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4534 TRACE("index=%d\n", index);
4536 pStubMsg->MemorySize += memsize;
4538 if (flags & USER_MARSHAL_POINTER)
4540 align_pointer(&pStubMsg->Buffer, 4);
4541 /* skip pointer prefix */
4542 pStubMsg->Buffer += 4;
4543 if (pStubMsg->IgnoreEmbeddedPointers)
4544 return pStubMsg->MemorySize;
4545 align_pointer(&pStubMsg->Buffer, 8);
4548 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4551 FIXME("not implemented for varying buffer size\n");
4553 pStubMsg->Buffer += bufsize;
4555 return pStubMsg->MemorySize;
4558 /***********************************************************************
4559 * NdrUserMarshalFree [RPCRT4.@]
4561 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4562 unsigned char *pMemory,
4563 PFORMAT_STRING pFormat)
4565 /* unsigned flags = pFormat[1]; */
4566 unsigned index = *(const WORD*)&pFormat[2];
4567 USER_MARSHAL_CB umcb;
4569 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4570 TRACE("index=%d\n", index);
4572 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4574 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4575 &umcb.Flags, pMemory);
4578 /***********************************************************************
4579 * NdrGetUserMarshalInfo [RPCRT4.@]
4581 RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi)
4583 USER_MARSHAL_CB *umcb = CONTAINING_RECORD(flags, USER_MARSHAL_CB, Flags);
4585 TRACE("(%p,%u,%p)\n", flags, level, umi);
4588 return RPC_S_INVALID_ARG;
4590 memset(&umi->u1.Level1, 0, sizeof(umi->u1.Level1));
4591 umi->InformationLevel = level;
4593 if (umcb->Signature != USER_MARSHAL_CB_SIGNATURE)
4594 return RPC_S_INVALID_ARG;
4596 umi->u1.Level1.pfnAllocate = umcb->pStubMsg->pfnAllocate;
4597 umi->u1.Level1.pfnFree = umcb->pStubMsg->pfnFree;
4598 umi->u1.Level1.pRpcChannelBuffer = umcb->pStubMsg->pRpcChannelBuffer;
4600 switch (umcb->CBType)
4602 case USER_MARSHAL_CB_MARSHALL:
4603 case USER_MARSHAL_CB_UNMARSHALL:
4605 RPC_MESSAGE *msg = umcb->pStubMsg->RpcMsg;
4606 unsigned char *buffer_start = msg->Buffer;
4607 unsigned char *buffer_end =
4608 (unsigned char *)msg->Buffer + msg->BufferLength;
4610 if (umcb->pStubMsg->Buffer < buffer_start ||
4611 umcb->pStubMsg->Buffer > buffer_end)
4612 return ERROR_INVALID_USER_BUFFER;
4614 umi->u1.Level1.Buffer = umcb->pStubMsg->Buffer;
4615 umi->u1.Level1.BufferSize = buffer_end - umcb->pStubMsg->Buffer;
4618 case USER_MARSHAL_CB_BUFFER_SIZE:
4619 case USER_MARSHAL_CB_FREE:
4622 WARN("unrecognised CBType %d\n", umcb->CBType);
4628 /***********************************************************************
4629 * NdrClearOutParameters [RPCRT4.@]
4631 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4632 PFORMAT_STRING pFormat,
4635 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4638 /***********************************************************************
4639 * NdrConvert [RPCRT4.@]
4641 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4643 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4644 /* FIXME: since this stub doesn't do any converting, the proper behavior
4645 is to raise an exception */
4648 /***********************************************************************
4649 * NdrConvert2 [RPCRT4.@]
4651 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4653 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4654 pStubMsg, pFormat, NumberParams);
4655 /* FIXME: since this stub doesn't do any converting, the proper behavior
4656 is to raise an exception */
4659 #include "pshpack1.h"
4660 typedef struct _NDR_CSTRUCT_FORMAT
4663 unsigned char alignment;
4664 unsigned short memory_size;
4665 short offset_to_array_description;
4666 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4667 #include "poppack.h"
4669 /***********************************************************************
4670 * NdrConformantStructMarshall [RPCRT4.@]
4672 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4673 unsigned char *pMemory,
4674 PFORMAT_STRING pFormat)
4676 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4677 PFORMAT_STRING pCArrayFormat;
4678 ULONG esize, bufsize;
4680 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4682 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4683 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4685 ERR("invalid format type %x\n", pCStructFormat->type);
4686 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4690 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4691 pCStructFormat->offset_to_array_description;
4692 if (*pCArrayFormat != RPC_FC_CARRAY)
4694 ERR("invalid array format type %x\n", pCStructFormat->type);
4695 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4698 esize = *(const WORD*)(pCArrayFormat+2);
4700 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4701 pCArrayFormat + 4, 0);
4703 WriteConformance(pStubMsg);
4705 align_pointer_clear(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4707 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4709 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4710 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4712 ERR("integer overflow of memory_size %u with bufsize %u\n",
4713 pCStructFormat->memory_size, bufsize);
4714 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4716 /* copy constant sized part of struct */
4717 pStubMsg->BufferMark = pStubMsg->Buffer;
4718 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4720 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4721 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4726 /***********************************************************************
4727 * NdrConformantStructUnmarshall [RPCRT4.@]
4729 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4730 unsigned char **ppMemory,
4731 PFORMAT_STRING pFormat,
4732 unsigned char fMustAlloc)
4734 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4735 PFORMAT_STRING pCArrayFormat;
4736 ULONG esize, bufsize;
4737 unsigned char *saved_buffer;
4739 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4741 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4742 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4744 ERR("invalid format type %x\n", pCStructFormat->type);
4745 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4748 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4749 pCStructFormat->offset_to_array_description;
4750 if (*pCArrayFormat != RPC_FC_CARRAY)
4752 ERR("invalid array format type %x\n", pCStructFormat->type);
4753 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4756 esize = *(const WORD*)(pCArrayFormat+2);
4758 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4760 align_pointer(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4762 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4764 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4765 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4767 ERR("integer overflow of memory_size %u with bufsize %u\n",
4768 pCStructFormat->memory_size, bufsize);
4769 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4774 SIZE_T size = pCStructFormat->memory_size + bufsize;
4775 *ppMemory = NdrAllocate(pStubMsg, size);
4779 if (!pStubMsg->IsClient && !*ppMemory)
4780 /* for servers, we just point straight into the RPC buffer */
4781 *ppMemory = pStubMsg->Buffer;
4784 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4785 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4786 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4787 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4789 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4790 if (*ppMemory != saved_buffer)
4791 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4796 /***********************************************************************
4797 * NdrConformantStructBufferSize [RPCRT4.@]
4799 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4800 unsigned char *pMemory,
4801 PFORMAT_STRING pFormat)
4803 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4804 PFORMAT_STRING pCArrayFormat;
4807 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4809 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4810 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4812 ERR("invalid format type %x\n", pCStructFormat->type);
4813 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4816 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4817 pCStructFormat->offset_to_array_description;
4818 if (*pCArrayFormat != RPC_FC_CARRAY)
4820 ERR("invalid array format type %x\n", pCStructFormat->type);
4821 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4824 esize = *(const WORD*)(pCArrayFormat+2);
4826 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4827 SizeConformance(pStubMsg);
4829 align_length(&pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4831 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4833 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4834 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4836 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4837 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4840 /***********************************************************************
4841 * NdrConformantStructMemorySize [RPCRT4.@]
4843 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4844 PFORMAT_STRING pFormat)
4850 /***********************************************************************
4851 * NdrConformantStructFree [RPCRT4.@]
4853 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4854 unsigned char *pMemory,
4855 PFORMAT_STRING pFormat)
4857 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4858 PFORMAT_STRING pCArrayFormat;
4860 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4862 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4863 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4865 ERR("invalid format type %x\n", pCStructFormat->type);
4866 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4870 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4871 pCStructFormat->offset_to_array_description;
4872 if (*pCArrayFormat != RPC_FC_CARRAY)
4874 ERR("invalid array format type %x\n", pCStructFormat->type);
4875 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4879 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4880 pCArrayFormat + 4, 0);
4882 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4884 /* copy constant sized part of struct */
4885 pStubMsg->BufferMark = pStubMsg->Buffer;
4887 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4888 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4891 /***********************************************************************
4892 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4894 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4895 unsigned char *pMemory,
4896 PFORMAT_STRING pFormat)
4898 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4899 PFORMAT_STRING pCVArrayFormat;
4901 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4903 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4904 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4906 ERR("invalid format type %x\n", pCVStructFormat->type);
4907 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4911 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4912 pCVStructFormat->offset_to_array_description;
4914 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4915 pMemory + pCVStructFormat->memory_size,
4918 align_pointer_clear(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4920 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4922 /* write constant sized part */
4923 pStubMsg->BufferMark = pStubMsg->Buffer;
4924 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4926 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4927 pMemory + pCVStructFormat->memory_size,
4928 pCVArrayFormat, FALSE /* fHasPointers */);
4930 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4935 /***********************************************************************
4936 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4938 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4939 unsigned char **ppMemory,
4940 PFORMAT_STRING pFormat,
4941 unsigned char fMustAlloc)
4943 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4944 PFORMAT_STRING pCVArrayFormat;
4945 ULONG memsize, bufsize;
4946 unsigned char *saved_buffer, *saved_array_buffer;
4948 unsigned char *array_memory;
4950 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4952 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4953 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4955 ERR("invalid format type %x\n", pCVStructFormat->type);
4956 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4960 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4961 pCVStructFormat->offset_to_array_description;
4963 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4966 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4968 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4970 /* work out how much memory to allocate if we need to do so */
4971 if (!fMustAlloc && !*ppMemory)
4975 SIZE_T size = pCVStructFormat->memory_size + memsize;
4976 *ppMemory = NdrAllocate(pStubMsg, size);
4979 /* mark the start of the constant data */
4980 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4981 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4983 array_memory = *ppMemory + pCVStructFormat->memory_size;
4984 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
4985 &array_memory, pCVArrayFormat,
4986 FALSE /* fMustAlloc */,
4987 FALSE /* fUseServerBufferMemory */,
4988 FALSE /* fUnmarshall */);
4990 /* save offset in case unmarshalling pointers changes it */
4991 offset = pStubMsg->Offset;
4993 /* mark the start of the array data */
4994 saved_array_buffer = pStubMsg->Buffer;
4995 safe_buffer_increment(pStubMsg, bufsize);
4997 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4999 /* copy the constant data */
5000 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
5001 /* copy the array data */
5002 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
5003 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
5004 saved_array_buffer, bufsize);
5006 if (*pCVArrayFormat == RPC_FC_C_CSTRING)
5007 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
5008 else if (*pCVArrayFormat == RPC_FC_C_WSTRING)
5009 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
5014 /***********************************************************************
5015 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
5017 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5018 unsigned char *pMemory,
5019 PFORMAT_STRING pFormat)
5021 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5022 PFORMAT_STRING pCVArrayFormat;
5024 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5026 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5027 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5029 ERR("invalid format type %x\n", pCVStructFormat->type);
5030 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5034 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5035 pCVStructFormat->offset_to_array_description;
5036 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
5037 pMemory + pCVStructFormat->memory_size,
5040 align_length(&pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
5042 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5044 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
5046 array_buffer_size(*pCVArrayFormat, pStubMsg,
5047 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5048 FALSE /* fHasPointers */);
5050 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5053 /***********************************************************************
5054 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
5056 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5057 PFORMAT_STRING pFormat)
5059 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5060 PFORMAT_STRING pCVArrayFormat;
5062 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5064 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5065 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5067 ERR("invalid format type %x\n", pCVStructFormat->type);
5068 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5072 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5073 pCVStructFormat->offset_to_array_description;
5074 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
5076 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
5078 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5080 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
5081 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
5082 FALSE /* fHasPointers */);
5084 pStubMsg->MemorySize += pCVStructFormat->memory_size;
5086 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5088 return pStubMsg->MemorySize;
5091 /***********************************************************************
5092 * NdrConformantVaryingStructFree [RPCRT4.@]
5094 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
5095 unsigned char *pMemory,
5096 PFORMAT_STRING pFormat)
5098 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5099 PFORMAT_STRING pCVArrayFormat;
5101 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5103 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5104 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5106 ERR("invalid format type %x\n", pCVStructFormat->type);
5107 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5111 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5112 pCVStructFormat->offset_to_array_description;
5113 array_free(*pCVArrayFormat, pStubMsg,
5114 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5115 FALSE /* fHasPointers */);
5117 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5119 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5122 #include "pshpack1.h"
5126 unsigned char alignment;
5127 unsigned short total_size;
5128 } NDR_SMFARRAY_FORMAT;
5133 unsigned char alignment;
5135 } NDR_LGFARRAY_FORMAT;
5136 #include "poppack.h"
5138 /***********************************************************************
5139 * NdrFixedArrayMarshall [RPCRT4.@]
5141 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5142 unsigned char *pMemory,
5143 PFORMAT_STRING pFormat)
5145 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5148 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5150 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5151 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5153 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5154 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5158 align_pointer_clear(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5160 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5162 total_size = pSmFArrayFormat->total_size;
5163 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5167 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5168 total_size = pLgFArrayFormat->total_size;
5169 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5172 pStubMsg->BufferMark = pStubMsg->Buffer;
5173 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
5175 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5180 /***********************************************************************
5181 * NdrFixedArrayUnmarshall [RPCRT4.@]
5183 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5184 unsigned char **ppMemory,
5185 PFORMAT_STRING pFormat,
5186 unsigned char fMustAlloc)
5188 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5190 unsigned char *saved_buffer;
5192 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5194 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5195 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5197 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5198 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5202 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5204 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5206 total_size = pSmFArrayFormat->total_size;
5207 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5211 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5212 total_size = pLgFArrayFormat->total_size;
5213 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5217 *ppMemory = NdrAllocate(pStubMsg, total_size);
5220 if (!pStubMsg->IsClient && !*ppMemory)
5221 /* for servers, we just point straight into the RPC buffer */
5222 *ppMemory = pStubMsg->Buffer;
5225 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5226 safe_buffer_increment(pStubMsg, total_size);
5227 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5229 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
5230 if (*ppMemory != saved_buffer)
5231 memcpy(*ppMemory, saved_buffer, total_size);
5236 /***********************************************************************
5237 * NdrFixedArrayBufferSize [RPCRT4.@]
5239 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5240 unsigned char *pMemory,
5241 PFORMAT_STRING pFormat)
5243 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5246 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5248 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5249 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5251 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5252 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5256 align_length(&pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
5258 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5260 total_size = pSmFArrayFormat->total_size;
5261 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5265 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5266 total_size = pLgFArrayFormat->total_size;
5267 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5269 safe_buffer_length_increment(pStubMsg, total_size);
5271 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5274 /***********************************************************************
5275 * NdrFixedArrayMemorySize [RPCRT4.@]
5277 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5278 PFORMAT_STRING pFormat)
5280 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5283 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5285 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5286 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5288 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5289 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5293 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5295 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5297 total_size = pSmFArrayFormat->total_size;
5298 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5302 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5303 total_size = pLgFArrayFormat->total_size;
5304 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5306 pStubMsg->BufferMark = pStubMsg->Buffer;
5307 safe_buffer_increment(pStubMsg, total_size);
5308 pStubMsg->MemorySize += total_size;
5310 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5315 /***********************************************************************
5316 * NdrFixedArrayFree [RPCRT4.@]
5318 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5319 unsigned char *pMemory,
5320 PFORMAT_STRING pFormat)
5322 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5324 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5326 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5327 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5329 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5330 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5334 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5335 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5338 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5339 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5342 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5345 /***********************************************************************
5346 * NdrVaryingArrayMarshall [RPCRT4.@]
5348 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5349 unsigned char *pMemory,
5350 PFORMAT_STRING pFormat)
5352 unsigned char alignment;
5353 DWORD elements, esize;
5356 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5358 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5359 (pFormat[0] != RPC_FC_LGVARRAY))
5361 ERR("invalid format type %x\n", pFormat[0]);
5362 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5366 alignment = pFormat[1] + 1;
5368 if (pFormat[0] == RPC_FC_SMVARRAY)
5371 pFormat += sizeof(WORD);
5372 elements = *(const WORD*)pFormat;
5373 pFormat += sizeof(WORD);
5378 pFormat += sizeof(DWORD);
5379 elements = *(const DWORD*)pFormat;
5380 pFormat += sizeof(DWORD);
5383 esize = *(const WORD*)pFormat;
5384 pFormat += sizeof(WORD);
5386 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5387 if ((pStubMsg->ActualCount > elements) ||
5388 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5390 RpcRaiseException(RPC_S_INVALID_BOUND);
5394 WriteVariance(pStubMsg);
5396 align_pointer_clear(&pStubMsg->Buffer, alignment);
5398 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5399 pStubMsg->BufferMark = pStubMsg->Buffer;
5400 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5402 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5407 /***********************************************************************
5408 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5410 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5411 unsigned char **ppMemory,
5412 PFORMAT_STRING pFormat,
5413 unsigned char fMustAlloc)
5415 unsigned char alignment;
5416 DWORD size, elements, esize;
5418 unsigned char *saved_buffer;
5421 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5423 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5424 (pFormat[0] != RPC_FC_LGVARRAY))
5426 ERR("invalid format type %x\n", pFormat[0]);
5427 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5431 alignment = pFormat[1] + 1;
5433 if (pFormat[0] == RPC_FC_SMVARRAY)
5436 size = *(const WORD*)pFormat;
5437 pFormat += sizeof(WORD);
5438 elements = *(const WORD*)pFormat;
5439 pFormat += sizeof(WORD);
5444 size = *(const DWORD*)pFormat;
5445 pFormat += sizeof(DWORD);
5446 elements = *(const DWORD*)pFormat;
5447 pFormat += sizeof(DWORD);
5450 esize = *(const WORD*)pFormat;
5451 pFormat += sizeof(WORD);
5453 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5455 align_pointer(&pStubMsg->Buffer, alignment);
5457 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5458 offset = pStubMsg->Offset;
5460 if (!fMustAlloc && !*ppMemory)
5463 *ppMemory = NdrAllocate(pStubMsg, size);
5464 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5465 safe_buffer_increment(pStubMsg, bufsize);
5467 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5469 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5474 /***********************************************************************
5475 * NdrVaryingArrayBufferSize [RPCRT4.@]
5477 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5478 unsigned char *pMemory,
5479 PFORMAT_STRING pFormat)
5481 unsigned char alignment;
5482 DWORD elements, esize;
5484 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5486 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5487 (pFormat[0] != RPC_FC_LGVARRAY))
5489 ERR("invalid format type %x\n", pFormat[0]);
5490 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5494 alignment = pFormat[1] + 1;
5496 if (pFormat[0] == RPC_FC_SMVARRAY)
5499 pFormat += sizeof(WORD);
5500 elements = *(const WORD*)pFormat;
5501 pFormat += sizeof(WORD);
5506 pFormat += sizeof(DWORD);
5507 elements = *(const DWORD*)pFormat;
5508 pFormat += sizeof(DWORD);
5511 esize = *(const WORD*)pFormat;
5512 pFormat += sizeof(WORD);
5514 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5515 if ((pStubMsg->ActualCount > elements) ||
5516 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5518 RpcRaiseException(RPC_S_INVALID_BOUND);
5522 SizeVariance(pStubMsg);
5524 align_length(&pStubMsg->BufferLength, alignment);
5526 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5528 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5531 /***********************************************************************
5532 * NdrVaryingArrayMemorySize [RPCRT4.@]
5534 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5535 PFORMAT_STRING pFormat)
5537 unsigned char alignment;
5538 DWORD size, elements, esize;
5540 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5542 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5543 (pFormat[0] != RPC_FC_LGVARRAY))
5545 ERR("invalid format type %x\n", pFormat[0]);
5546 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5550 alignment = pFormat[1] + 1;
5552 if (pFormat[0] == RPC_FC_SMVARRAY)
5555 size = *(const WORD*)pFormat;
5556 pFormat += sizeof(WORD);
5557 elements = *(const WORD*)pFormat;
5558 pFormat += sizeof(WORD);
5563 size = *(const DWORD*)pFormat;
5564 pFormat += sizeof(DWORD);
5565 elements = *(const DWORD*)pFormat;
5566 pFormat += sizeof(DWORD);
5569 esize = *(const WORD*)pFormat;
5570 pFormat += sizeof(WORD);
5572 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5574 align_pointer(&pStubMsg->Buffer, alignment);
5576 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5577 pStubMsg->MemorySize += size;
5579 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5581 return pStubMsg->MemorySize;
5584 /***********************************************************************
5585 * NdrVaryingArrayFree [RPCRT4.@]
5587 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5588 unsigned char *pMemory,
5589 PFORMAT_STRING pFormat)
5593 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5595 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5596 (pFormat[0] != RPC_FC_LGVARRAY))
5598 ERR("invalid format type %x\n", pFormat[0]);
5599 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5603 if (pFormat[0] == RPC_FC_SMVARRAY)
5606 pFormat += sizeof(WORD);
5607 elements = *(const WORD*)pFormat;
5608 pFormat += sizeof(WORD);
5613 pFormat += sizeof(DWORD);
5614 elements = *(const DWORD*)pFormat;
5615 pFormat += sizeof(DWORD);
5618 pFormat += sizeof(WORD);
5620 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5621 if ((pStubMsg->ActualCount > elements) ||
5622 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5624 RpcRaiseException(RPC_S_INVALID_BOUND);
5628 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5631 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5644 return *(const USHORT *)pMemory;
5648 return *(const ULONG *)pMemory;
5649 case RPC_FC_INT3264:
5650 case RPC_FC_UINT3264:
5651 return *(const ULONG_PTR *)pMemory;
5653 FIXME("Unhandled base type: 0x%02x\n", fc);
5658 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5660 PFORMAT_STRING pFormat)
5662 unsigned short num_arms, arm, type;
5664 num_arms = *(const SHORT*)pFormat & 0x0fff;
5666 for(arm = 0; arm < num_arms; arm++)
5668 if(discriminant == *(const ULONG*)pFormat)
5676 type = *(const unsigned short*)pFormat;
5677 TRACE("type %04x\n", type);
5678 if(arm == num_arms) /* default arm extras */
5682 ERR("no arm for 0x%x and no default case\n", discriminant);
5683 RpcRaiseException(RPC_S_INVALID_TAG);
5688 TRACE("falling back to empty default case for 0x%x\n", discriminant);
5695 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5697 unsigned short type;
5701 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5705 type = *(const unsigned short*)pFormat;
5706 if((type & 0xff00) == 0x8000)
5708 unsigned char basetype = LOBYTE(type);
5709 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5713 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5714 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5717 unsigned char *saved_buffer = NULL;
5718 int pointer_buffer_mark_set = 0;
5725 align_pointer_clear(&pStubMsg->Buffer, 4);
5726 saved_buffer = pStubMsg->Buffer;
5727 if (pStubMsg->PointerBufferMark)
5729 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5730 pStubMsg->PointerBufferMark = NULL;
5731 pointer_buffer_mark_set = 1;
5734 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5736 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5737 if (pointer_buffer_mark_set)
5739 STD_OVERFLOW_CHECK(pStubMsg);
5740 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5741 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5743 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5744 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5745 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5747 pStubMsg->Buffer = saved_buffer + 4;
5751 m(pStubMsg, pMemory, desc);
5754 else FIXME("no marshaller for embedded type %02x\n", *desc);
5759 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5760 unsigned char **ppMemory,
5762 PFORMAT_STRING pFormat,
5763 unsigned char fMustAlloc)
5765 unsigned short type;
5769 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5773 type = *(const unsigned short*)pFormat;
5774 if((type & 0xff00) == 0x8000)
5776 unsigned char basetype = LOBYTE(type);
5777 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5781 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5782 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5785 unsigned char *saved_buffer = NULL;
5786 int pointer_buffer_mark_set = 0;
5793 align_pointer(&pStubMsg->Buffer, 4);
5794 saved_buffer = pStubMsg->Buffer;
5795 if (pStubMsg->PointerBufferMark)
5797 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5798 pStubMsg->PointerBufferMark = NULL;
5799 pointer_buffer_mark_set = 1;
5802 pStubMsg->Buffer += 4; /* for pointer ID */
5804 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5806 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5807 saved_buffer, pStubMsg->BufferEnd);
5808 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5811 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5812 if (pointer_buffer_mark_set)
5814 STD_OVERFLOW_CHECK(pStubMsg);
5815 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5816 pStubMsg->Buffer = saved_buffer + 4;
5820 m(pStubMsg, ppMemory, desc, fMustAlloc);
5823 else FIXME("no marshaller for embedded type %02x\n", *desc);
5828 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5829 unsigned char *pMemory,
5831 PFORMAT_STRING pFormat)
5833 unsigned short type;
5837 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5841 type = *(const unsigned short*)pFormat;
5842 if((type & 0xff00) == 0x8000)
5844 unsigned char basetype = LOBYTE(type);
5845 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5849 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5850 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5859 align_length(&pStubMsg->BufferLength, 4);
5860 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5861 if (!pStubMsg->IgnoreEmbeddedPointers)
5863 int saved_buffer_length = pStubMsg->BufferLength;
5864 pStubMsg->BufferLength = pStubMsg->PointerLength;
5865 pStubMsg->PointerLength = 0;
5866 if(!pStubMsg->BufferLength)
5867 ERR("BufferLength == 0??\n");
5868 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5869 pStubMsg->PointerLength = pStubMsg->BufferLength;
5870 pStubMsg->BufferLength = saved_buffer_length;
5874 m(pStubMsg, pMemory, desc);
5877 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5881 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5883 PFORMAT_STRING pFormat)
5885 unsigned short type, size;
5887 size = *(const unsigned short*)pFormat;
5888 pStubMsg->Memory += size;
5891 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5895 type = *(const unsigned short*)pFormat;
5896 if((type & 0xff00) == 0x8000)
5898 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5902 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5903 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5904 unsigned char *saved_buffer;
5913 align_pointer(&pStubMsg->Buffer, 4);
5914 saved_buffer = pStubMsg->Buffer;
5915 safe_buffer_increment(pStubMsg, 4);
5916 align_length(&pStubMsg->MemorySize, sizeof(void *));
5917 pStubMsg->MemorySize += sizeof(void *);
5918 if (!pStubMsg->IgnoreEmbeddedPointers)
5919 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5922 return m(pStubMsg, desc);
5925 else FIXME("no marshaller for embedded type %02x\n", *desc);
5928 TRACE("size %d\n", size);
5932 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5933 unsigned char *pMemory,
5935 PFORMAT_STRING pFormat)
5937 unsigned short type;
5941 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5945 type = *(const unsigned short*)pFormat;
5946 if((type & 0xff00) != 0x8000)
5948 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5949 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5958 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5961 m(pStubMsg, pMemory, desc);
5967 /***********************************************************************
5968 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5970 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5971 unsigned char *pMemory,
5972 PFORMAT_STRING pFormat)
5974 unsigned char switch_type;
5975 unsigned char increment;
5978 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5981 switch_type = *pFormat & 0xf;
5982 increment = (*pFormat & 0xf0) >> 4;
5985 align_pointer_clear(&pStubMsg->Buffer, increment);
5987 switch_value = get_discriminant(switch_type, pMemory);
5988 TRACE("got switch value 0x%x\n", switch_value);
5990 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5991 pMemory += increment;
5993 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5996 /***********************************************************************
5997 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5999 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6000 unsigned char **ppMemory,
6001 PFORMAT_STRING pFormat,
6002 unsigned char fMustAlloc)
6004 unsigned char switch_type;
6005 unsigned char increment;
6007 unsigned short size;
6008 unsigned char *pMemoryArm;
6010 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6013 switch_type = *pFormat & 0xf;
6014 increment = (*pFormat & 0xf0) >> 4;
6017 align_pointer(&pStubMsg->Buffer, increment);
6018 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6019 TRACE("got switch value 0x%x\n", switch_value);
6021 size = *(const unsigned short*)pFormat + increment;
6022 if (!fMustAlloc && !*ppMemory)
6025 *ppMemory = NdrAllocate(pStubMsg, size);
6027 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6028 * since the arm is part of the memory block that is encompassed by
6029 * the whole union. Memory is forced to allocate when pointers
6030 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6031 * clearing the memory we pass in to the unmarshaller */
6033 memset(*ppMemory, 0, size);
6035 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
6036 pMemoryArm = *ppMemory + increment;
6038 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, FALSE);
6041 /***********************************************************************
6042 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
6044 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6045 unsigned char *pMemory,
6046 PFORMAT_STRING pFormat)
6048 unsigned char switch_type;
6049 unsigned char increment;
6052 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6055 switch_type = *pFormat & 0xf;
6056 increment = (*pFormat & 0xf0) >> 4;
6059 align_length(&pStubMsg->BufferLength, increment);
6060 switch_value = get_discriminant(switch_type, pMemory);
6061 TRACE("got switch value 0x%x\n", switch_value);
6063 /* Add discriminant size */
6064 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
6065 pMemory += increment;
6067 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
6070 /***********************************************************************
6071 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
6073 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6074 PFORMAT_STRING pFormat)
6076 unsigned char switch_type;
6077 unsigned char increment;
6080 switch_type = *pFormat & 0xf;
6081 increment = (*pFormat & 0xf0) >> 4;
6084 align_pointer(&pStubMsg->Buffer, increment);
6085 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6086 TRACE("got switch value 0x%x\n", switch_value);
6088 pStubMsg->Memory += increment;
6090 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
6093 /***********************************************************************
6094 * NdrEncapsulatedUnionFree [RPCRT4.@]
6096 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6097 unsigned char *pMemory,
6098 PFORMAT_STRING pFormat)
6100 unsigned char switch_type;
6101 unsigned char increment;
6104 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6107 switch_type = *pFormat & 0xf;
6108 increment = (*pFormat & 0xf0) >> 4;
6111 switch_value = get_discriminant(switch_type, pMemory);
6112 TRACE("got switch value 0x%x\n", switch_value);
6114 pMemory += increment;
6116 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
6119 /***********************************************************************
6120 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
6122 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6123 unsigned char *pMemory,
6124 PFORMAT_STRING pFormat)
6126 unsigned char switch_type;
6128 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6131 switch_type = *pFormat;
6134 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6135 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6136 /* Marshall discriminant */
6137 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6139 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6142 static LONG unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
6143 PFORMAT_STRING *ppFormat)
6145 LONG discriminant = 0;
6155 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6164 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6165 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6173 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6174 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6179 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
6183 if (pStubMsg->fHasNewCorrDesc)
6187 return discriminant;
6190 /**********************************************************************
6191 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6193 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6194 unsigned char **ppMemory,
6195 PFORMAT_STRING pFormat,
6196 unsigned char fMustAlloc)
6199 unsigned short size;
6201 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6204 /* Unmarshall discriminant */
6205 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6206 TRACE("unmarshalled discriminant %x\n", discriminant);
6208 pFormat += *(const SHORT*)pFormat;
6210 size = *(const unsigned short*)pFormat;
6212 if (!fMustAlloc && !*ppMemory)
6215 *ppMemory = NdrAllocate(pStubMsg, size);
6217 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6218 * since the arm is part of the memory block that is encompassed by
6219 * the whole union. Memory is forced to allocate when pointers
6220 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6221 * clearing the memory we pass in to the unmarshaller */
6223 memset(*ppMemory, 0, size);
6225 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, FALSE);
6228 /***********************************************************************
6229 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6231 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6232 unsigned char *pMemory,
6233 PFORMAT_STRING pFormat)
6235 unsigned char switch_type;
6237 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6240 switch_type = *pFormat;
6243 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6244 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6245 /* Add discriminant size */
6246 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6248 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6251 /***********************************************************************
6252 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6254 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6255 PFORMAT_STRING pFormat)
6260 /* Unmarshall discriminant */
6261 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6262 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
6264 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
6267 /***********************************************************************
6268 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6270 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6271 unsigned char *pMemory,
6272 PFORMAT_STRING pFormat)
6274 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6278 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6279 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6281 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6284 /***********************************************************************
6285 * NdrByteCountPointerMarshall [RPCRT4.@]
6287 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6288 unsigned char *pMemory,
6289 PFORMAT_STRING pFormat)
6295 /***********************************************************************
6296 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6298 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6299 unsigned char **ppMemory,
6300 PFORMAT_STRING pFormat,
6301 unsigned char fMustAlloc)
6307 /***********************************************************************
6308 * NdrByteCountPointerBufferSize [RPCRT4.@]
6310 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6311 unsigned char *pMemory,
6312 PFORMAT_STRING pFormat)
6317 /***********************************************************************
6318 * NdrByteCountPointerMemorySize [internal]
6320 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6321 PFORMAT_STRING pFormat)
6327 /***********************************************************************
6328 * NdrByteCountPointerFree [RPCRT4.@]
6330 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6331 unsigned char *pMemory,
6332 PFORMAT_STRING pFormat)
6337 /***********************************************************************
6338 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6340 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6341 unsigned char *pMemory,
6342 PFORMAT_STRING pFormat)
6348 /***********************************************************************
6349 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6351 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6352 unsigned char **ppMemory,
6353 PFORMAT_STRING pFormat,
6354 unsigned char fMustAlloc)
6360 /***********************************************************************
6361 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6363 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6364 unsigned char *pMemory,
6365 PFORMAT_STRING pFormat)
6370 /***********************************************************************
6371 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6373 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6374 PFORMAT_STRING pFormat)
6380 /***********************************************************************
6381 * NdrXmitOrRepAsFree [RPCRT4.@]
6383 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6384 unsigned char *pMemory,
6385 PFORMAT_STRING pFormat)
6390 /***********************************************************************
6391 * NdrRangeMarshall [internal]
6393 static unsigned char *WINAPI NdrRangeMarshall(
6394 PMIDL_STUB_MESSAGE pStubMsg,
6395 unsigned char *pMemory,
6396 PFORMAT_STRING pFormat)
6398 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6399 unsigned char base_type;
6401 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6403 if (pRange->type != RPC_FC_RANGE)
6405 ERR("invalid format type %x\n", pRange->type);
6406 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6410 base_type = pRange->flags_type & 0xf;
6412 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6415 /***********************************************************************
6416 * NdrRangeUnmarshall [RPCRT4.@]
6418 unsigned char *WINAPI NdrRangeUnmarshall(
6419 PMIDL_STUB_MESSAGE pStubMsg,
6420 unsigned char **ppMemory,
6421 PFORMAT_STRING pFormat,
6422 unsigned char fMustAlloc)
6424 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6425 unsigned char base_type;
6427 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6429 if (pRange->type != RPC_FC_RANGE)
6431 ERR("invalid format type %x\n", pRange->type);
6432 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6435 base_type = pRange->flags_type & 0xf;
6437 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6438 base_type, pRange->low_value, pRange->high_value);
6440 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6443 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \
6444 if (!fMustAlloc && !*ppMemory) \
6445 fMustAlloc = TRUE; \
6447 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6448 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6450 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6451 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6452 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6454 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6455 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6457 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6458 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6459 (mem_type)pRange->high_value); \
6460 RpcRaiseException(RPC_S_INVALID_BOUND); \
6463 TRACE("*ppMemory: %p\n", *ppMemory); \
6464 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6465 pStubMsg->Buffer += sizeof(wire_type); \
6472 RANGE_UNMARSHALL(UCHAR, UCHAR, "%d");
6473 TRACE("value: 0x%02x\n", **ppMemory);
6477 RANGE_UNMARSHALL(CHAR, CHAR, "%u");
6478 TRACE("value: 0x%02x\n", **ppMemory);
6480 case RPC_FC_WCHAR: /* FIXME: valid? */
6482 RANGE_UNMARSHALL(USHORT, USHORT, "%u");
6483 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6486 RANGE_UNMARSHALL(SHORT, SHORT, "%d");
6487 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6491 RANGE_UNMARSHALL(LONG, LONG, "%d");
6492 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6495 RANGE_UNMARSHALL(ULONG, ULONG, "%u");
6496 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6499 RANGE_UNMARSHALL(UINT, USHORT, "%u");
6500 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6506 ERR("invalid range base type: 0x%02x\n", base_type);
6507 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6513 /***********************************************************************
6514 * NdrRangeBufferSize [internal]
6516 static void WINAPI NdrRangeBufferSize(
6517 PMIDL_STUB_MESSAGE pStubMsg,
6518 unsigned char *pMemory,
6519 PFORMAT_STRING pFormat)
6521 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6522 unsigned char base_type;
6524 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6526 if (pRange->type != RPC_FC_RANGE)
6528 ERR("invalid format type %x\n", pRange->type);
6529 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6531 base_type = pRange->flags_type & 0xf;
6533 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6536 /***********************************************************************
6537 * NdrRangeMemorySize [internal]
6539 static ULONG WINAPI NdrRangeMemorySize(
6540 PMIDL_STUB_MESSAGE pStubMsg,
6541 PFORMAT_STRING pFormat)
6543 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6544 unsigned char base_type;
6546 if (pRange->type != RPC_FC_RANGE)
6548 ERR("invalid format type %x\n", pRange->type);
6549 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6552 base_type = pRange->flags_type & 0xf;
6554 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6557 /***********************************************************************
6558 * NdrRangeFree [internal]
6560 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6561 unsigned char *pMemory,
6562 PFORMAT_STRING pFormat)
6564 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6569 /***********************************************************************
6570 * NdrBaseTypeMarshall [internal]
6572 static unsigned char *WINAPI NdrBaseTypeMarshall(
6573 PMIDL_STUB_MESSAGE pStubMsg,
6574 unsigned char *pMemory,
6575 PFORMAT_STRING pFormat)
6577 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6585 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6586 TRACE("value: 0x%02x\n", *pMemory);
6591 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6592 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6593 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6597 case RPC_FC_ERROR_STATUS_T:
6599 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONG));
6600 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6601 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6604 align_pointer_clear(&pStubMsg->Buffer, sizeof(float));
6605 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6608 align_pointer_clear(&pStubMsg->Buffer, sizeof(double));
6609 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6612 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONGLONG));
6613 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6614 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6618 USHORT val = *(UINT *)pMemory;
6619 /* only 16-bits on the wire, so do a sanity check */
6620 if (*(UINT *)pMemory > SHRT_MAX)
6621 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6622 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6623 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6624 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6627 case RPC_FC_INT3264:
6628 case RPC_FC_UINT3264:
6630 UINT val = *(UINT_PTR *)pMemory;
6631 align_pointer_clear(&pStubMsg->Buffer, sizeof(UINT));
6632 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6638 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6641 /* FIXME: what is the correct return value? */
6645 /***********************************************************************
6646 * NdrBaseTypeUnmarshall [internal]
6648 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6649 PMIDL_STUB_MESSAGE pStubMsg,
6650 unsigned char **ppMemory,
6651 PFORMAT_STRING pFormat,
6652 unsigned char fMustAlloc)
6654 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6656 #define BASE_TYPE_UNMARSHALL(type) do { \
6657 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
6658 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6660 *ppMemory = pStubMsg->Buffer; \
6661 TRACE("*ppMemory: %p\n", *ppMemory); \
6662 safe_buffer_increment(pStubMsg, sizeof(type)); \
6667 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6668 TRACE("*ppMemory: %p\n", *ppMemory); \
6669 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6679 BASE_TYPE_UNMARSHALL(UCHAR);
6680 TRACE("value: 0x%02x\n", **ppMemory);
6685 BASE_TYPE_UNMARSHALL(USHORT);
6686 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6690 case RPC_FC_ERROR_STATUS_T:
6692 BASE_TYPE_UNMARSHALL(ULONG);
6693 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6696 BASE_TYPE_UNMARSHALL(float);
6697 TRACE("value: %f\n", **(float **)ppMemory);
6700 BASE_TYPE_UNMARSHALL(double);
6701 TRACE("value: %f\n", **(double **)ppMemory);
6704 BASE_TYPE_UNMARSHALL(ULONGLONG);
6705 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6710 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6711 if (!fMustAlloc && !*ppMemory)
6714 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6715 safe_copy_from_buffer(pStubMsg, &val, sizeof(USHORT));
6716 /* 16-bits on the wire, but int in memory */
6717 **(UINT **)ppMemory = val;
6718 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6721 case RPC_FC_INT3264:
6722 if (sizeof(INT_PTR) == sizeof(INT)) BASE_TYPE_UNMARSHALL(INT);
6726 align_pointer(&pStubMsg->Buffer, sizeof(INT));
6727 if (!fMustAlloc && !*ppMemory)
6730 *ppMemory = NdrAllocate(pStubMsg, sizeof(INT_PTR));
6731 safe_copy_from_buffer(pStubMsg, &val, sizeof(INT));
6732 **(INT_PTR **)ppMemory = val;
6733 TRACE("value: 0x%08lx\n", **(INT_PTR **)ppMemory);
6736 case RPC_FC_UINT3264:
6737 if (sizeof(UINT_PTR) == sizeof(UINT)) BASE_TYPE_UNMARSHALL(UINT);
6741 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6742 if (!fMustAlloc && !*ppMemory)
6745 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT_PTR));
6746 safe_copy_from_buffer(pStubMsg, &val, sizeof(UINT));
6747 **(UINT_PTR **)ppMemory = val;
6748 TRACE("value: 0x%08lx\n", **(UINT_PTR **)ppMemory);
6754 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6756 #undef BASE_TYPE_UNMARSHALL
6758 /* FIXME: what is the correct return value? */
6763 /***********************************************************************
6764 * NdrBaseTypeBufferSize [internal]
6766 static void WINAPI NdrBaseTypeBufferSize(
6767 PMIDL_STUB_MESSAGE pStubMsg,
6768 unsigned char *pMemory,
6769 PFORMAT_STRING pFormat)
6771 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6779 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6785 align_length(&pStubMsg->BufferLength, sizeof(USHORT));
6786 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6791 case RPC_FC_INT3264:
6792 case RPC_FC_UINT3264:
6793 align_length(&pStubMsg->BufferLength, sizeof(ULONG));
6794 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6797 align_length(&pStubMsg->BufferLength, sizeof(float));
6798 safe_buffer_length_increment(pStubMsg, sizeof(float));
6801 align_length(&pStubMsg->BufferLength, sizeof(double));
6802 safe_buffer_length_increment(pStubMsg, sizeof(double));
6805 align_length(&pStubMsg->BufferLength, sizeof(ULONGLONG));
6806 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6808 case RPC_FC_ERROR_STATUS_T:
6809 align_length(&pStubMsg->BufferLength, sizeof(error_status_t));
6810 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6815 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6819 /***********************************************************************
6820 * NdrBaseTypeMemorySize [internal]
6822 static ULONG WINAPI NdrBaseTypeMemorySize(
6823 PMIDL_STUB_MESSAGE pStubMsg,
6824 PFORMAT_STRING pFormat)
6826 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6834 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6835 pStubMsg->MemorySize += sizeof(UCHAR);
6836 return sizeof(UCHAR);
6840 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6841 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6842 align_length(&pStubMsg->MemorySize, sizeof(USHORT));
6843 pStubMsg->MemorySize += sizeof(USHORT);
6844 return sizeof(USHORT);
6848 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6849 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6850 align_length(&pStubMsg->MemorySize, sizeof(ULONG));
6851 pStubMsg->MemorySize += sizeof(ULONG);
6852 return sizeof(ULONG);
6854 align_pointer(&pStubMsg->Buffer, sizeof(float));
6855 safe_buffer_increment(pStubMsg, sizeof(float));
6856 align_length(&pStubMsg->MemorySize, sizeof(float));
6857 pStubMsg->MemorySize += sizeof(float);
6858 return sizeof(float);
6860 align_pointer(&pStubMsg->Buffer, sizeof(double));
6861 safe_buffer_increment(pStubMsg, sizeof(double));
6862 align_length(&pStubMsg->MemorySize, sizeof(double));
6863 pStubMsg->MemorySize += sizeof(double);
6864 return sizeof(double);
6866 align_pointer(&pStubMsg->Buffer, sizeof(ULONGLONG));
6867 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6868 align_length(&pStubMsg->MemorySize, sizeof(ULONGLONG));
6869 pStubMsg->MemorySize += sizeof(ULONGLONG);
6870 return sizeof(ULONGLONG);
6871 case RPC_FC_ERROR_STATUS_T:
6872 align_pointer(&pStubMsg->Buffer, sizeof(error_status_t));
6873 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6874 align_length(&pStubMsg->MemorySize, sizeof(error_status_t));
6875 pStubMsg->MemorySize += sizeof(error_status_t);
6876 return sizeof(error_status_t);
6878 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6879 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6880 align_length(&pStubMsg->MemorySize, sizeof(UINT));
6881 pStubMsg->MemorySize += sizeof(UINT);
6882 return sizeof(UINT);
6883 case RPC_FC_INT3264:
6884 case RPC_FC_UINT3264:
6885 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6886 safe_buffer_increment(pStubMsg, sizeof(UINT));
6887 align_length(&pStubMsg->MemorySize, sizeof(UINT_PTR));
6888 pStubMsg->MemorySize += sizeof(UINT_PTR);
6889 return sizeof(UINT_PTR);
6891 align_length(&pStubMsg->MemorySize, sizeof(void *));
6892 pStubMsg->MemorySize += sizeof(void *);
6893 return sizeof(void *);
6895 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6900 /***********************************************************************
6901 * NdrBaseTypeFree [internal]
6903 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6904 unsigned char *pMemory,
6905 PFORMAT_STRING pFormat)
6907 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6912 /***********************************************************************
6913 * NdrContextHandleBufferSize [internal]
6915 static void WINAPI NdrContextHandleBufferSize(
6916 PMIDL_STUB_MESSAGE pStubMsg,
6917 unsigned char *pMemory,
6918 PFORMAT_STRING pFormat)
6920 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6922 if (*pFormat != RPC_FC_BIND_CONTEXT)
6924 ERR("invalid format type %x\n", *pFormat);
6925 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6927 align_length(&pStubMsg->BufferLength, 4);
6928 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6931 /***********************************************************************
6932 * NdrContextHandleMarshall [internal]
6934 static unsigned char *WINAPI NdrContextHandleMarshall(
6935 PMIDL_STUB_MESSAGE pStubMsg,
6936 unsigned char *pMemory,
6937 PFORMAT_STRING pFormat)
6939 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6941 if (*pFormat != RPC_FC_BIND_CONTEXT)
6943 ERR("invalid format type %x\n", *pFormat);
6944 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6946 TRACE("flags: 0x%02x\n", pFormat[1]);
6948 if (pStubMsg->IsClient)
6950 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6951 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6953 NdrClientContextMarshall(pStubMsg, pMemory, FALSE);
6957 NDR_SCONTEXT ctxt = NDRSContextFromValue(pMemory);
6958 NDR_RUNDOWN rundown = pStubMsg->StubDesc->apfnNdrRundownRoutines[pFormat[2]];
6959 NdrServerContextNewMarshall(pStubMsg, ctxt, rundown, pFormat);
6965 /***********************************************************************
6966 * NdrContextHandleUnmarshall [internal]
6968 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6969 PMIDL_STUB_MESSAGE pStubMsg,
6970 unsigned char **ppMemory,
6971 PFORMAT_STRING pFormat,
6972 unsigned char fMustAlloc)
6974 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6975 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6977 if (*pFormat != RPC_FC_BIND_CONTEXT)
6979 ERR("invalid format type %x\n", *pFormat);
6980 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6982 TRACE("flags: 0x%02x\n", pFormat[1]);
6984 if (pStubMsg->IsClient)
6986 /* [out]-only or [ret] param */
6987 if ((pFormat[1] & (HANDLE_PARAM_IS_IN|HANDLE_PARAM_IS_OUT)) == HANDLE_PARAM_IS_OUT)
6988 **(NDR_CCONTEXT **)ppMemory = NULL;
6989 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6994 ctxt = NdrServerContextNewUnmarshall(pStubMsg, pFormat);
6995 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6996 *(void **)ppMemory = NDRSContextValue(ctxt);
6998 *(void **)ppMemory = *NDRSContextValue(ctxt);
7004 /***********************************************************************
7005 * NdrClientContextMarshall [RPCRT4.@]
7007 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7008 NDR_CCONTEXT ContextHandle,
7011 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
7013 align_pointer_clear(&pStubMsg->Buffer, 4);
7015 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7017 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7018 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7019 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7022 /* FIXME: what does fCheck do? */
7023 NDRCContextMarshall(ContextHandle,
7026 pStubMsg->Buffer += cbNDRContext;
7029 /***********************************************************************
7030 * NdrClientContextUnmarshall [RPCRT4.@]
7032 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7033 NDR_CCONTEXT * pContextHandle,
7034 RPC_BINDING_HANDLE BindHandle)
7036 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
7038 align_pointer(&pStubMsg->Buffer, 4);
7040 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
7041 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7043 NDRCContextUnmarshall(pContextHandle,
7046 pStubMsg->RpcMsg->DataRepresentation);
7048 pStubMsg->Buffer += cbNDRContext;
7051 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7052 NDR_SCONTEXT ContextHandle,
7053 NDR_RUNDOWN RundownRoutine )
7055 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
7057 align_pointer(&pStubMsg->Buffer, 4);
7059 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7061 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7062 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7063 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7066 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7067 pStubMsg->Buffer, RundownRoutine, NULL,
7068 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7069 pStubMsg->Buffer += cbNDRContext;
7072 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
7074 NDR_SCONTEXT ContextHandle;
7076 TRACE("(%p)\n", pStubMsg);
7078 align_pointer(&pStubMsg->Buffer, 4);
7080 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7082 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7083 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7084 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7087 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7089 pStubMsg->RpcMsg->DataRepresentation,
7090 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7091 pStubMsg->Buffer += cbNDRContext;
7093 return ContextHandle;
7096 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
7097 unsigned char* pMemory,
7098 PFORMAT_STRING pFormat)
7100 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
7103 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
7104 PFORMAT_STRING pFormat)
7106 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7107 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7109 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7111 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7112 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7113 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7114 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7115 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7117 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7118 if_id = &sif->InterfaceId;
7121 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
7122 pStubMsg->RpcMsg->DataRepresentation, if_id,
7126 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7127 NDR_SCONTEXT ContextHandle,
7128 NDR_RUNDOWN RundownRoutine,
7129 PFORMAT_STRING pFormat)
7131 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7132 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7134 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
7136 align_pointer(&pStubMsg->Buffer, 4);
7138 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7140 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7141 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7142 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7145 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7146 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7147 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7148 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7149 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7151 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7152 if_id = &sif->InterfaceId;
7155 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7156 pStubMsg->Buffer, RundownRoutine, if_id, flags);
7157 pStubMsg->Buffer += cbNDRContext;
7160 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7161 PFORMAT_STRING pFormat)
7163 NDR_SCONTEXT ContextHandle;
7164 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7165 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7167 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7169 align_pointer(&pStubMsg->Buffer, 4);
7171 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7173 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7174 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7175 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7178 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7179 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7180 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7181 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7182 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7184 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7185 if_id = &sif->InterfaceId;
7188 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7190 pStubMsg->RpcMsg->DataRepresentation,
7192 pStubMsg->Buffer += cbNDRContext;
7194 return ContextHandle;
7197 /***********************************************************************
7198 * NdrCorrelationInitialize [RPCRT4.@]
7200 * Initializes correlation validity checking.
7203 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7204 * pMemory [I] Pointer to memory to use as a cache.
7205 * CacheSize [I] Size of the memory pointed to by pMemory.
7206 * Flags [I] Reserved. Set to zero.
7211 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
7213 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
7214 pStubMsg->fHasNewCorrDesc = TRUE;
7217 /***********************************************************************
7218 * NdrCorrelationPass [RPCRT4.@]
7220 * Performs correlation validity checking.
7223 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7228 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
7230 FIXME("(%p): stub\n", pStubMsg);
7233 /***********************************************************************
7234 * NdrCorrelationFree [RPCRT4.@]
7236 * Frees any resources used while unmarshalling parameters that need
7237 * correlation validity checking.
7240 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7245 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
7247 FIXME("(%p): stub\n", pStubMsg);