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)
4190 unsigned char *saved_buffer;
4191 int pointer_buffer_mark_set = 0;
4192 int saved_ignore_embedded;
4194 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4196 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4198 ERR("invalid format type %x\n", pFormat[0]);
4199 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4203 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4204 /* save buffer pointer */
4205 saved_buffer = pStubMsg->Buffer;
4206 /* get the buffer pointer after complex array data, but before
4208 pStubMsg->IgnoreEmbeddedPointers = 1;
4209 pStubMsg->MemorySize = 0;
4210 NdrComplexArrayMemorySize(pStubMsg, pFormat);
4211 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4213 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - saved_buffer));
4214 if (!pStubMsg->PointerBufferMark)
4216 /* save it for use by embedded pointer code later */
4217 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4218 pointer_buffer_mark_set = 1;
4220 /* restore the original buffer */
4221 pStubMsg->Buffer = saved_buffer;
4223 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
4224 array_read_variance_and_unmarshall(RPC_FC_BOGUS_ARRAY, pStubMsg, ppMemory, pFormat, fMustAlloc,
4225 TRUE /* fUseBufferMemoryServer */, TRUE /* fUnmarshall */);
4227 if (pointer_buffer_mark_set)
4229 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4230 pStubMsg->PointerBufferMark = NULL;
4236 /***********************************************************************
4237 * NdrComplexArrayBufferSize [RPCRT4.@]
4239 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4240 unsigned char *pMemory,
4241 PFORMAT_STRING pFormat)
4243 int pointer_length_set = 0;
4245 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4247 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4249 ERR("invalid format type %x\n", pFormat[0]);
4250 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4254 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
4256 /* save buffer fields that may be changed by buffer sizer functions
4257 * and that may be needed later on */
4258 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4259 ULONG saved_buffer_length = pStubMsg->BufferLength;
4260 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4261 ULONG saved_offset = pStubMsg->Offset;
4262 ULONG saved_actual_count = pStubMsg->ActualCount;
4264 /* get the buffer pointer after complex array data, but before
4266 pStubMsg->IgnoreEmbeddedPointers = 1;
4267 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4268 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4270 /* save it for use by embedded pointer code later */
4271 pStubMsg->PointerLength = pStubMsg->BufferLength;
4272 pointer_length_set = 1;
4274 /* restore fields */
4275 pStubMsg->ActualCount = saved_actual_count;
4276 pStubMsg->Offset = saved_offset;
4277 pStubMsg->MaxCount = saved_max_count;
4278 pStubMsg->BufferLength = saved_buffer_length;
4281 array_compute_and_size_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4282 array_buffer_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat, TRUE /* fHasPointers */);
4284 if(pointer_length_set)
4286 pStubMsg->BufferLength = pStubMsg->PointerLength;
4287 pStubMsg->PointerLength = 0;
4291 /***********************************************************************
4292 * NdrComplexArrayMemorySize [RPCRT4.@]
4294 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4295 PFORMAT_STRING pFormat)
4297 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4299 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4301 ERR("invalid format type %x\n", pFormat[0]);
4302 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4306 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
4307 array_memory_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
4308 return pStubMsg->MemorySize;
4311 /***********************************************************************
4312 * NdrComplexArrayFree [RPCRT4.@]
4314 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4315 unsigned char *pMemory,
4316 PFORMAT_STRING pFormat)
4318 ULONG i, count, def;
4320 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4322 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4324 ERR("invalid format type %x\n", pFormat[0]);
4325 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4329 def = *(const WORD*)&pFormat[2];
4332 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4333 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4335 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4336 TRACE("variance = %d\n", pStubMsg->ActualCount);
4338 count = pStubMsg->ActualCount;
4339 for (i = 0; i < count; i++)
4340 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4343 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4344 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4345 USER_MARSHAL_CB *umcb)
4347 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4348 pStubMsg->RpcMsg->DataRepresentation);
4349 umcb->pStubMsg = pStubMsg;
4350 umcb->pReserve = NULL;
4351 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4352 umcb->CBType = cbtype;
4353 umcb->pFormat = pFormat;
4354 umcb->pTypeFormat = NULL /* FIXME */;
4357 #define USER_MARSHAL_PTR_PREFIX \
4358 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4359 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4361 /***********************************************************************
4362 * NdrUserMarshalMarshall [RPCRT4.@]
4364 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4365 unsigned char *pMemory,
4366 PFORMAT_STRING pFormat)
4368 unsigned flags = pFormat[1];
4369 unsigned index = *(const WORD*)&pFormat[2];
4370 unsigned char *saved_buffer = NULL;
4371 USER_MARSHAL_CB umcb;
4373 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4374 TRACE("index=%d\n", index);
4376 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4378 if (flags & USER_MARSHAL_POINTER)
4380 align_pointer_clear(&pStubMsg->Buffer, 4);
4381 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4382 pStubMsg->Buffer += 4;
4383 if (pStubMsg->PointerBufferMark)
4385 saved_buffer = pStubMsg->Buffer;
4386 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4387 pStubMsg->PointerBufferMark = NULL;
4389 align_pointer_clear(&pStubMsg->Buffer, 8);
4392 align_pointer_clear(&pStubMsg->Buffer, (flags & 0xf) + 1);
4395 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4396 &umcb.Flags, pStubMsg->Buffer, pMemory);
4400 STD_OVERFLOW_CHECK(pStubMsg);
4401 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4402 pStubMsg->Buffer = saved_buffer;
4405 STD_OVERFLOW_CHECK(pStubMsg);
4410 /***********************************************************************
4411 * NdrUserMarshalUnmarshall [RPCRT4.@]
4413 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4414 unsigned char **ppMemory,
4415 PFORMAT_STRING pFormat,
4416 unsigned char fMustAlloc)
4418 unsigned flags = pFormat[1];
4419 unsigned index = *(const WORD*)&pFormat[2];
4420 DWORD memsize = *(const WORD*)&pFormat[4];
4421 unsigned char *saved_buffer = NULL;
4422 USER_MARSHAL_CB umcb;
4424 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4425 TRACE("index=%d\n", index);
4427 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4429 if (flags & USER_MARSHAL_POINTER)
4431 align_pointer(&pStubMsg->Buffer, 4);
4432 /* skip pointer prefix */
4433 pStubMsg->Buffer += 4;
4434 if (pStubMsg->PointerBufferMark)
4436 saved_buffer = pStubMsg->Buffer;
4437 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4438 pStubMsg->PointerBufferMark = NULL;
4440 align_pointer(&pStubMsg->Buffer, 8);
4443 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4445 if (!fMustAlloc && !*ppMemory)
4449 *ppMemory = NdrAllocate(pStubMsg, memsize);
4450 memset(*ppMemory, 0, memsize);
4454 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4455 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4459 STD_OVERFLOW_CHECK(pStubMsg);
4460 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4461 pStubMsg->Buffer = saved_buffer;
4467 /***********************************************************************
4468 * NdrUserMarshalBufferSize [RPCRT4.@]
4470 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4471 unsigned char *pMemory,
4472 PFORMAT_STRING pFormat)
4474 unsigned flags = pFormat[1];
4475 unsigned index = *(const WORD*)&pFormat[2];
4476 DWORD bufsize = *(const WORD*)&pFormat[6];
4477 USER_MARSHAL_CB umcb;
4478 ULONG saved_buffer_length = 0;
4480 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4481 TRACE("index=%d\n", index);
4483 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4485 if (flags & USER_MARSHAL_POINTER)
4487 align_length(&pStubMsg->BufferLength, 4);
4488 /* skip pointer prefix */
4489 safe_buffer_length_increment(pStubMsg, 4);
4490 if (pStubMsg->IgnoreEmbeddedPointers)
4492 if (pStubMsg->PointerLength)
4494 saved_buffer_length = pStubMsg->BufferLength;
4495 pStubMsg->BufferLength = pStubMsg->PointerLength;
4496 pStubMsg->PointerLength = 0;
4498 align_length(&pStubMsg->BufferLength, 8);
4501 align_length(&pStubMsg->BufferLength, (flags & 0xf) + 1);
4504 TRACE("size=%d\n", bufsize);
4505 safe_buffer_length_increment(pStubMsg, bufsize);
4508 pStubMsg->BufferLength =
4509 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4510 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4512 if (saved_buffer_length)
4514 pStubMsg->PointerLength = pStubMsg->BufferLength;
4515 pStubMsg->BufferLength = saved_buffer_length;
4520 /***********************************************************************
4521 * NdrUserMarshalMemorySize [RPCRT4.@]
4523 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4524 PFORMAT_STRING pFormat)
4526 unsigned flags = pFormat[1];
4527 unsigned index = *(const WORD*)&pFormat[2];
4528 DWORD memsize = *(const WORD*)&pFormat[4];
4529 DWORD bufsize = *(const WORD*)&pFormat[6];
4531 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4532 TRACE("index=%d\n", index);
4534 pStubMsg->MemorySize += memsize;
4536 if (flags & USER_MARSHAL_POINTER)
4538 align_pointer(&pStubMsg->Buffer, 4);
4539 /* skip pointer prefix */
4540 pStubMsg->Buffer += 4;
4541 if (pStubMsg->IgnoreEmbeddedPointers)
4542 return pStubMsg->MemorySize;
4543 align_pointer(&pStubMsg->Buffer, 8);
4546 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4549 FIXME("not implemented for varying buffer size\n");
4551 pStubMsg->Buffer += bufsize;
4553 return pStubMsg->MemorySize;
4556 /***********************************************************************
4557 * NdrUserMarshalFree [RPCRT4.@]
4559 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4560 unsigned char *pMemory,
4561 PFORMAT_STRING pFormat)
4563 /* unsigned flags = pFormat[1]; */
4564 unsigned index = *(const WORD*)&pFormat[2];
4565 USER_MARSHAL_CB umcb;
4567 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4568 TRACE("index=%d\n", index);
4570 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4572 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4573 &umcb.Flags, pMemory);
4576 /***********************************************************************
4577 * NdrGetUserMarshalInfo [RPCRT4.@]
4579 RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi)
4581 USER_MARSHAL_CB *umcb = CONTAINING_RECORD(flags, USER_MARSHAL_CB, Flags);
4583 TRACE("(%p,%u,%p)\n", flags, level, umi);
4586 return RPC_S_INVALID_ARG;
4588 memset(&umi->u1.Level1, 0, sizeof(umi->u1.Level1));
4589 umi->InformationLevel = level;
4591 if (umcb->Signature != USER_MARSHAL_CB_SIGNATURE)
4592 return RPC_S_INVALID_ARG;
4594 umi->u1.Level1.pfnAllocate = umcb->pStubMsg->pfnAllocate;
4595 umi->u1.Level1.pfnFree = umcb->pStubMsg->pfnFree;
4596 umi->u1.Level1.pRpcChannelBuffer = umcb->pStubMsg->pRpcChannelBuffer;
4598 switch (umcb->CBType)
4600 case USER_MARSHAL_CB_MARSHALL:
4601 case USER_MARSHAL_CB_UNMARSHALL:
4603 RPC_MESSAGE *msg = umcb->pStubMsg->RpcMsg;
4604 unsigned char *buffer_start = msg->Buffer;
4605 unsigned char *buffer_end =
4606 (unsigned char *)msg->Buffer + msg->BufferLength;
4608 if (umcb->pStubMsg->Buffer < buffer_start ||
4609 umcb->pStubMsg->Buffer > buffer_end)
4610 return ERROR_INVALID_USER_BUFFER;
4612 umi->u1.Level1.Buffer = umcb->pStubMsg->Buffer;
4613 umi->u1.Level1.BufferSize = buffer_end - umcb->pStubMsg->Buffer;
4616 case USER_MARSHAL_CB_BUFFER_SIZE:
4617 case USER_MARSHAL_CB_FREE:
4620 WARN("unrecognised CBType %d\n", umcb->CBType);
4626 /***********************************************************************
4627 * NdrClearOutParameters [RPCRT4.@]
4629 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4630 PFORMAT_STRING pFormat,
4633 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4636 /***********************************************************************
4637 * NdrConvert [RPCRT4.@]
4639 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4641 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4642 /* FIXME: since this stub doesn't do any converting, the proper behavior
4643 is to raise an exception */
4646 /***********************************************************************
4647 * NdrConvert2 [RPCRT4.@]
4649 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4651 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4652 pStubMsg, pFormat, NumberParams);
4653 /* FIXME: since this stub doesn't do any converting, the proper behavior
4654 is to raise an exception */
4657 #include "pshpack1.h"
4658 typedef struct _NDR_CSTRUCT_FORMAT
4661 unsigned char alignment;
4662 unsigned short memory_size;
4663 short offset_to_array_description;
4664 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4665 #include "poppack.h"
4667 /***********************************************************************
4668 * NdrConformantStructMarshall [RPCRT4.@]
4670 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4671 unsigned char *pMemory,
4672 PFORMAT_STRING pFormat)
4674 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4675 PFORMAT_STRING pCArrayFormat;
4676 ULONG esize, bufsize;
4678 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4680 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4681 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4683 ERR("invalid format type %x\n", pCStructFormat->type);
4684 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4688 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4689 pCStructFormat->offset_to_array_description;
4690 if (*pCArrayFormat != RPC_FC_CARRAY)
4692 ERR("invalid array format type %x\n", pCStructFormat->type);
4693 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4696 esize = *(const WORD*)(pCArrayFormat+2);
4698 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4699 pCArrayFormat + 4, 0);
4701 WriteConformance(pStubMsg);
4703 align_pointer_clear(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4705 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4707 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4708 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4710 ERR("integer overflow of memory_size %u with bufsize %u\n",
4711 pCStructFormat->memory_size, bufsize);
4712 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4714 /* copy constant sized part of struct */
4715 pStubMsg->BufferMark = pStubMsg->Buffer;
4716 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4718 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4719 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4724 /***********************************************************************
4725 * NdrConformantStructUnmarshall [RPCRT4.@]
4727 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4728 unsigned char **ppMemory,
4729 PFORMAT_STRING pFormat,
4730 unsigned char fMustAlloc)
4732 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4733 PFORMAT_STRING pCArrayFormat;
4734 ULONG esize, bufsize;
4735 unsigned char *saved_buffer;
4737 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4739 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4740 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4742 ERR("invalid format type %x\n", pCStructFormat->type);
4743 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4746 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4747 pCStructFormat->offset_to_array_description;
4748 if (*pCArrayFormat != RPC_FC_CARRAY)
4750 ERR("invalid array format type %x\n", pCStructFormat->type);
4751 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4754 esize = *(const WORD*)(pCArrayFormat+2);
4756 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4758 align_pointer(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4760 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4762 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4763 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4765 ERR("integer overflow of memory_size %u with bufsize %u\n",
4766 pCStructFormat->memory_size, bufsize);
4767 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4772 SIZE_T size = pCStructFormat->memory_size + bufsize;
4773 *ppMemory = NdrAllocate(pStubMsg, size);
4777 if (!pStubMsg->IsClient && !*ppMemory)
4778 /* for servers, we just point straight into the RPC buffer */
4779 *ppMemory = pStubMsg->Buffer;
4782 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4783 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4784 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4785 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4787 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4788 if (*ppMemory != saved_buffer)
4789 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4794 /***********************************************************************
4795 * NdrConformantStructBufferSize [RPCRT4.@]
4797 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4798 unsigned char *pMemory,
4799 PFORMAT_STRING pFormat)
4801 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4802 PFORMAT_STRING pCArrayFormat;
4805 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4807 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4808 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4810 ERR("invalid format type %x\n", pCStructFormat->type);
4811 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4814 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4815 pCStructFormat->offset_to_array_description;
4816 if (*pCArrayFormat != RPC_FC_CARRAY)
4818 ERR("invalid array format type %x\n", pCStructFormat->type);
4819 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4822 esize = *(const WORD*)(pCArrayFormat+2);
4824 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4825 SizeConformance(pStubMsg);
4827 align_length(&pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4829 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4831 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4832 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4834 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4835 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4838 /***********************************************************************
4839 * NdrConformantStructMemorySize [RPCRT4.@]
4841 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4842 PFORMAT_STRING pFormat)
4848 /***********************************************************************
4849 * NdrConformantStructFree [RPCRT4.@]
4851 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4852 unsigned char *pMemory,
4853 PFORMAT_STRING pFormat)
4855 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4856 PFORMAT_STRING pCArrayFormat;
4858 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4860 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4861 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4863 ERR("invalid format type %x\n", pCStructFormat->type);
4864 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4868 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4869 pCStructFormat->offset_to_array_description;
4870 if (*pCArrayFormat != RPC_FC_CARRAY)
4872 ERR("invalid array format type %x\n", pCStructFormat->type);
4873 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4877 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4878 pCArrayFormat + 4, 0);
4880 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4882 /* copy constant sized part of struct */
4883 pStubMsg->BufferMark = pStubMsg->Buffer;
4885 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4886 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4889 /***********************************************************************
4890 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4892 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4893 unsigned char *pMemory,
4894 PFORMAT_STRING pFormat)
4896 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4897 PFORMAT_STRING pCVArrayFormat;
4899 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4901 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4902 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4904 ERR("invalid format type %x\n", pCVStructFormat->type);
4905 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4909 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4910 pCVStructFormat->offset_to_array_description;
4912 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4913 pMemory + pCVStructFormat->memory_size,
4916 align_pointer_clear(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4918 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4920 /* write constant sized part */
4921 pStubMsg->BufferMark = pStubMsg->Buffer;
4922 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4924 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4925 pMemory + pCVStructFormat->memory_size,
4926 pCVArrayFormat, FALSE /* fHasPointers */);
4928 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4933 /***********************************************************************
4934 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4936 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4937 unsigned char **ppMemory,
4938 PFORMAT_STRING pFormat,
4939 unsigned char fMustAlloc)
4941 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4942 PFORMAT_STRING pCVArrayFormat;
4943 ULONG memsize, bufsize;
4944 unsigned char *saved_buffer, *saved_array_buffer;
4946 unsigned char *array_memory;
4948 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4950 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4951 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4953 ERR("invalid format type %x\n", pCVStructFormat->type);
4954 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4958 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4959 pCVStructFormat->offset_to_array_description;
4961 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4964 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4966 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4968 /* work out how much memory to allocate if we need to do so */
4969 if (!fMustAlloc && !*ppMemory)
4973 SIZE_T size = pCVStructFormat->memory_size + memsize;
4974 *ppMemory = NdrAllocate(pStubMsg, size);
4977 /* mark the start of the constant data */
4978 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4979 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4981 array_memory = *ppMemory + pCVStructFormat->memory_size;
4982 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
4983 &array_memory, pCVArrayFormat,
4984 FALSE /* fMustAlloc */,
4985 FALSE /* fUseServerBufferMemory */,
4986 FALSE /* fUnmarshall */);
4988 /* save offset in case unmarshalling pointers changes it */
4989 offset = pStubMsg->Offset;
4991 /* mark the start of the array data */
4992 saved_array_buffer = pStubMsg->Buffer;
4993 safe_buffer_increment(pStubMsg, bufsize);
4995 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4997 /* copy the constant data */
4998 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
4999 /* copy the array data */
5000 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
5001 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
5002 saved_array_buffer, bufsize);
5004 if (*pCVArrayFormat == RPC_FC_C_CSTRING)
5005 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
5006 else if (*pCVArrayFormat == RPC_FC_C_WSTRING)
5007 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
5012 /***********************************************************************
5013 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
5015 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5016 unsigned char *pMemory,
5017 PFORMAT_STRING pFormat)
5019 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5020 PFORMAT_STRING pCVArrayFormat;
5022 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5024 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5025 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5027 ERR("invalid format type %x\n", pCVStructFormat->type);
5028 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5032 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5033 pCVStructFormat->offset_to_array_description;
5034 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
5035 pMemory + pCVStructFormat->memory_size,
5038 align_length(&pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
5040 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5042 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
5044 array_buffer_size(*pCVArrayFormat, pStubMsg,
5045 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5046 FALSE /* fHasPointers */);
5048 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5051 /***********************************************************************
5052 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
5054 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5055 PFORMAT_STRING pFormat)
5057 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5058 PFORMAT_STRING pCVArrayFormat;
5060 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5062 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5063 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5065 ERR("invalid format type %x\n", pCVStructFormat->type);
5066 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5070 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5071 pCVStructFormat->offset_to_array_description;
5072 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
5074 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
5076 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5078 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
5079 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
5080 FALSE /* fHasPointers */);
5082 pStubMsg->MemorySize += pCVStructFormat->memory_size;
5084 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5086 return pStubMsg->MemorySize;
5089 /***********************************************************************
5090 * NdrConformantVaryingStructFree [RPCRT4.@]
5092 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
5093 unsigned char *pMemory,
5094 PFORMAT_STRING pFormat)
5096 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5097 PFORMAT_STRING pCVArrayFormat;
5099 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5101 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5102 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5104 ERR("invalid format type %x\n", pCVStructFormat->type);
5105 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5109 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5110 pCVStructFormat->offset_to_array_description;
5111 array_free(*pCVArrayFormat, pStubMsg,
5112 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5113 FALSE /* fHasPointers */);
5115 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5117 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5120 #include "pshpack1.h"
5124 unsigned char alignment;
5125 unsigned short total_size;
5126 } NDR_SMFARRAY_FORMAT;
5131 unsigned char alignment;
5133 } NDR_LGFARRAY_FORMAT;
5134 #include "poppack.h"
5136 /***********************************************************************
5137 * NdrFixedArrayMarshall [RPCRT4.@]
5139 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5140 unsigned char *pMemory,
5141 PFORMAT_STRING pFormat)
5143 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5146 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5148 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5149 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5151 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5152 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5156 align_pointer_clear(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5158 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5160 total_size = pSmFArrayFormat->total_size;
5161 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5165 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5166 total_size = pLgFArrayFormat->total_size;
5167 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5170 pStubMsg->BufferMark = pStubMsg->Buffer;
5171 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
5173 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5178 /***********************************************************************
5179 * NdrFixedArrayUnmarshall [RPCRT4.@]
5181 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5182 unsigned char **ppMemory,
5183 PFORMAT_STRING pFormat,
5184 unsigned char fMustAlloc)
5186 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5188 unsigned char *saved_buffer;
5190 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5192 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5193 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5195 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5196 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5200 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5202 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5204 total_size = pSmFArrayFormat->total_size;
5205 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5209 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5210 total_size = pLgFArrayFormat->total_size;
5211 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5215 *ppMemory = NdrAllocate(pStubMsg, total_size);
5218 if (!pStubMsg->IsClient && !*ppMemory)
5219 /* for servers, we just point straight into the RPC buffer */
5220 *ppMemory = pStubMsg->Buffer;
5223 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5224 safe_buffer_increment(pStubMsg, total_size);
5225 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5227 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
5228 if (*ppMemory != saved_buffer)
5229 memcpy(*ppMemory, saved_buffer, total_size);
5234 /***********************************************************************
5235 * NdrFixedArrayBufferSize [RPCRT4.@]
5237 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5238 unsigned char *pMemory,
5239 PFORMAT_STRING pFormat)
5241 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5244 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5246 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5247 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5249 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5250 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5254 align_length(&pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
5256 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5258 total_size = pSmFArrayFormat->total_size;
5259 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5263 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5264 total_size = pLgFArrayFormat->total_size;
5265 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5267 safe_buffer_length_increment(pStubMsg, total_size);
5269 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5272 /***********************************************************************
5273 * NdrFixedArrayMemorySize [RPCRT4.@]
5275 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5276 PFORMAT_STRING pFormat)
5278 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5281 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5283 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5284 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5286 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5287 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5291 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5293 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5295 total_size = pSmFArrayFormat->total_size;
5296 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5300 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5301 total_size = pLgFArrayFormat->total_size;
5302 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5304 pStubMsg->BufferMark = pStubMsg->Buffer;
5305 safe_buffer_increment(pStubMsg, total_size);
5306 pStubMsg->MemorySize += total_size;
5308 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5313 /***********************************************************************
5314 * NdrFixedArrayFree [RPCRT4.@]
5316 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5317 unsigned char *pMemory,
5318 PFORMAT_STRING pFormat)
5320 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5322 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5324 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5325 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5327 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5328 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5332 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5333 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5336 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5337 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5340 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5343 /***********************************************************************
5344 * NdrVaryingArrayMarshall [RPCRT4.@]
5346 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5347 unsigned char *pMemory,
5348 PFORMAT_STRING pFormat)
5350 unsigned char alignment;
5351 DWORD elements, esize;
5354 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5356 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5357 (pFormat[0] != RPC_FC_LGVARRAY))
5359 ERR("invalid format type %x\n", pFormat[0]);
5360 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5364 alignment = pFormat[1] + 1;
5366 if (pFormat[0] == RPC_FC_SMVARRAY)
5369 pFormat += sizeof(WORD);
5370 elements = *(const WORD*)pFormat;
5371 pFormat += sizeof(WORD);
5376 pFormat += sizeof(DWORD);
5377 elements = *(const DWORD*)pFormat;
5378 pFormat += sizeof(DWORD);
5381 esize = *(const WORD*)pFormat;
5382 pFormat += sizeof(WORD);
5384 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5385 if ((pStubMsg->ActualCount > elements) ||
5386 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5388 RpcRaiseException(RPC_S_INVALID_BOUND);
5392 WriteVariance(pStubMsg);
5394 align_pointer_clear(&pStubMsg->Buffer, alignment);
5396 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5397 pStubMsg->BufferMark = pStubMsg->Buffer;
5398 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5400 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5405 /***********************************************************************
5406 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5408 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5409 unsigned char **ppMemory,
5410 PFORMAT_STRING pFormat,
5411 unsigned char fMustAlloc)
5413 unsigned char alignment;
5414 DWORD size, elements, esize;
5416 unsigned char *saved_buffer;
5419 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5421 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5422 (pFormat[0] != RPC_FC_LGVARRAY))
5424 ERR("invalid format type %x\n", pFormat[0]);
5425 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5429 alignment = pFormat[1] + 1;
5431 if (pFormat[0] == RPC_FC_SMVARRAY)
5434 size = *(const WORD*)pFormat;
5435 pFormat += sizeof(WORD);
5436 elements = *(const WORD*)pFormat;
5437 pFormat += sizeof(WORD);
5442 size = *(const DWORD*)pFormat;
5443 pFormat += sizeof(DWORD);
5444 elements = *(const DWORD*)pFormat;
5445 pFormat += sizeof(DWORD);
5448 esize = *(const WORD*)pFormat;
5449 pFormat += sizeof(WORD);
5451 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5453 align_pointer(&pStubMsg->Buffer, alignment);
5455 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5456 offset = pStubMsg->Offset;
5458 if (!fMustAlloc && !*ppMemory)
5461 *ppMemory = NdrAllocate(pStubMsg, size);
5462 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5463 safe_buffer_increment(pStubMsg, bufsize);
5465 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5467 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5472 /***********************************************************************
5473 * NdrVaryingArrayBufferSize [RPCRT4.@]
5475 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5476 unsigned char *pMemory,
5477 PFORMAT_STRING pFormat)
5479 unsigned char alignment;
5480 DWORD elements, esize;
5482 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5484 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5485 (pFormat[0] != RPC_FC_LGVARRAY))
5487 ERR("invalid format type %x\n", pFormat[0]);
5488 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5492 alignment = pFormat[1] + 1;
5494 if (pFormat[0] == RPC_FC_SMVARRAY)
5497 pFormat += sizeof(WORD);
5498 elements = *(const WORD*)pFormat;
5499 pFormat += sizeof(WORD);
5504 pFormat += sizeof(DWORD);
5505 elements = *(const DWORD*)pFormat;
5506 pFormat += sizeof(DWORD);
5509 esize = *(const WORD*)pFormat;
5510 pFormat += sizeof(WORD);
5512 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5513 if ((pStubMsg->ActualCount > elements) ||
5514 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5516 RpcRaiseException(RPC_S_INVALID_BOUND);
5520 SizeVariance(pStubMsg);
5522 align_length(&pStubMsg->BufferLength, alignment);
5524 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5526 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5529 /***********************************************************************
5530 * NdrVaryingArrayMemorySize [RPCRT4.@]
5532 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5533 PFORMAT_STRING pFormat)
5535 unsigned char alignment;
5536 DWORD size, elements, esize;
5538 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5540 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5541 (pFormat[0] != RPC_FC_LGVARRAY))
5543 ERR("invalid format type %x\n", pFormat[0]);
5544 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5548 alignment = pFormat[1] + 1;
5550 if (pFormat[0] == RPC_FC_SMVARRAY)
5553 size = *(const WORD*)pFormat;
5554 pFormat += sizeof(WORD);
5555 elements = *(const WORD*)pFormat;
5556 pFormat += sizeof(WORD);
5561 size = *(const DWORD*)pFormat;
5562 pFormat += sizeof(DWORD);
5563 elements = *(const DWORD*)pFormat;
5564 pFormat += sizeof(DWORD);
5567 esize = *(const WORD*)pFormat;
5568 pFormat += sizeof(WORD);
5570 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5572 align_pointer(&pStubMsg->Buffer, alignment);
5574 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5575 pStubMsg->MemorySize += size;
5577 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5579 return pStubMsg->MemorySize;
5582 /***********************************************************************
5583 * NdrVaryingArrayFree [RPCRT4.@]
5585 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5586 unsigned char *pMemory,
5587 PFORMAT_STRING pFormat)
5591 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5593 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5594 (pFormat[0] != RPC_FC_LGVARRAY))
5596 ERR("invalid format type %x\n", pFormat[0]);
5597 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5601 if (pFormat[0] == RPC_FC_SMVARRAY)
5604 pFormat += sizeof(WORD);
5605 elements = *(const WORD*)pFormat;
5606 pFormat += sizeof(WORD);
5611 pFormat += sizeof(DWORD);
5612 elements = *(const DWORD*)pFormat;
5613 pFormat += sizeof(DWORD);
5616 pFormat += sizeof(WORD);
5618 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5619 if ((pStubMsg->ActualCount > elements) ||
5620 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5622 RpcRaiseException(RPC_S_INVALID_BOUND);
5626 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5629 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5642 return *(const USHORT *)pMemory;
5646 return *(const ULONG *)pMemory;
5647 case RPC_FC_INT3264:
5648 case RPC_FC_UINT3264:
5649 return *(const ULONG_PTR *)pMemory;
5651 FIXME("Unhandled base type: 0x%02x\n", fc);
5656 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5658 PFORMAT_STRING pFormat)
5660 unsigned short num_arms, arm, type;
5662 num_arms = *(const SHORT*)pFormat & 0x0fff;
5664 for(arm = 0; arm < num_arms; arm++)
5666 if(discriminant == *(const ULONG*)pFormat)
5674 type = *(const unsigned short*)pFormat;
5675 TRACE("type %04x\n", type);
5676 if(arm == num_arms) /* default arm extras */
5680 ERR("no arm for 0x%x and no default case\n", discriminant);
5681 RpcRaiseException(RPC_S_INVALID_TAG);
5686 TRACE("falling back to empty default case for 0x%x\n", discriminant);
5693 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5695 unsigned short type;
5699 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5703 type = *(const unsigned short*)pFormat;
5704 if((type & 0xff00) == 0x8000)
5706 unsigned char basetype = LOBYTE(type);
5707 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5711 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5712 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5715 unsigned char *saved_buffer = NULL;
5716 int pointer_buffer_mark_set = 0;
5723 align_pointer_clear(&pStubMsg->Buffer, 4);
5724 saved_buffer = pStubMsg->Buffer;
5725 if (pStubMsg->PointerBufferMark)
5727 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5728 pStubMsg->PointerBufferMark = NULL;
5729 pointer_buffer_mark_set = 1;
5732 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5734 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5735 if (pointer_buffer_mark_set)
5737 STD_OVERFLOW_CHECK(pStubMsg);
5738 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5739 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5741 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5742 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5743 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5745 pStubMsg->Buffer = saved_buffer + 4;
5749 m(pStubMsg, pMemory, desc);
5752 else FIXME("no marshaller for embedded type %02x\n", *desc);
5757 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5758 unsigned char **ppMemory,
5760 PFORMAT_STRING pFormat,
5761 unsigned char fMustAlloc)
5763 unsigned short type;
5767 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5771 type = *(const unsigned short*)pFormat;
5772 if((type & 0xff00) == 0x8000)
5774 unsigned char basetype = LOBYTE(type);
5775 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5779 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5780 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5783 unsigned char *saved_buffer = NULL;
5784 int pointer_buffer_mark_set = 0;
5791 align_pointer(&pStubMsg->Buffer, 4);
5792 saved_buffer = pStubMsg->Buffer;
5793 if (pStubMsg->PointerBufferMark)
5795 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5796 pStubMsg->PointerBufferMark = NULL;
5797 pointer_buffer_mark_set = 1;
5800 pStubMsg->Buffer += 4; /* for pointer ID */
5802 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5804 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5805 saved_buffer, pStubMsg->BufferEnd);
5806 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5809 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5810 if (pointer_buffer_mark_set)
5812 STD_OVERFLOW_CHECK(pStubMsg);
5813 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5814 pStubMsg->Buffer = saved_buffer + 4;
5818 m(pStubMsg, ppMemory, desc, fMustAlloc);
5821 else FIXME("no marshaller for embedded type %02x\n", *desc);
5826 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5827 unsigned char *pMemory,
5829 PFORMAT_STRING pFormat)
5831 unsigned short type;
5835 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5839 type = *(const unsigned short*)pFormat;
5840 if((type & 0xff00) == 0x8000)
5842 unsigned char basetype = LOBYTE(type);
5843 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5847 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5848 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5857 align_length(&pStubMsg->BufferLength, 4);
5858 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5859 if (!pStubMsg->IgnoreEmbeddedPointers)
5861 int saved_buffer_length = pStubMsg->BufferLength;
5862 pStubMsg->BufferLength = pStubMsg->PointerLength;
5863 pStubMsg->PointerLength = 0;
5864 if(!pStubMsg->BufferLength)
5865 ERR("BufferLength == 0??\n");
5866 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5867 pStubMsg->PointerLength = pStubMsg->BufferLength;
5868 pStubMsg->BufferLength = saved_buffer_length;
5872 m(pStubMsg, pMemory, desc);
5875 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5879 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5881 PFORMAT_STRING pFormat)
5883 unsigned short type, size;
5885 size = *(const unsigned short*)pFormat;
5886 pStubMsg->Memory += size;
5889 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5893 type = *(const unsigned short*)pFormat;
5894 if((type & 0xff00) == 0x8000)
5896 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5900 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5901 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5902 unsigned char *saved_buffer;
5911 align_pointer(&pStubMsg->Buffer, 4);
5912 saved_buffer = pStubMsg->Buffer;
5913 safe_buffer_increment(pStubMsg, 4);
5914 align_length(&pStubMsg->MemorySize, sizeof(void *));
5915 pStubMsg->MemorySize += sizeof(void *);
5916 if (!pStubMsg->IgnoreEmbeddedPointers)
5917 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5920 return m(pStubMsg, desc);
5923 else FIXME("no marshaller for embedded type %02x\n", *desc);
5926 TRACE("size %d\n", size);
5930 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5931 unsigned char *pMemory,
5933 PFORMAT_STRING pFormat)
5935 unsigned short type;
5939 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5943 type = *(const unsigned short*)pFormat;
5944 if((type & 0xff00) != 0x8000)
5946 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5947 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5956 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5959 m(pStubMsg, pMemory, desc);
5965 /***********************************************************************
5966 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5968 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5969 unsigned char *pMemory,
5970 PFORMAT_STRING pFormat)
5972 unsigned char switch_type;
5973 unsigned char increment;
5976 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5979 switch_type = *pFormat & 0xf;
5980 increment = (*pFormat & 0xf0) >> 4;
5983 align_pointer_clear(&pStubMsg->Buffer, increment);
5985 switch_value = get_discriminant(switch_type, pMemory);
5986 TRACE("got switch value 0x%x\n", switch_value);
5988 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5989 pMemory += increment;
5991 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5994 /***********************************************************************
5995 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5997 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5998 unsigned char **ppMemory,
5999 PFORMAT_STRING pFormat,
6000 unsigned char fMustAlloc)
6002 unsigned char switch_type;
6003 unsigned char increment;
6005 unsigned short size;
6006 unsigned char *pMemoryArm;
6008 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6011 switch_type = *pFormat & 0xf;
6012 increment = (*pFormat & 0xf0) >> 4;
6015 align_pointer(&pStubMsg->Buffer, increment);
6016 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6017 TRACE("got switch value 0x%x\n", switch_value);
6019 size = *(const unsigned short*)pFormat + increment;
6020 if (!fMustAlloc && !*ppMemory)
6023 *ppMemory = NdrAllocate(pStubMsg, size);
6025 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6026 * since the arm is part of the memory block that is encompassed by
6027 * the whole union. Memory is forced to allocate when pointers
6028 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6029 * clearing the memory we pass in to the unmarshaller */
6031 memset(*ppMemory, 0, size);
6033 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
6034 pMemoryArm = *ppMemory + increment;
6036 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, FALSE);
6039 /***********************************************************************
6040 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
6042 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6043 unsigned char *pMemory,
6044 PFORMAT_STRING pFormat)
6046 unsigned char switch_type;
6047 unsigned char increment;
6050 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6053 switch_type = *pFormat & 0xf;
6054 increment = (*pFormat & 0xf0) >> 4;
6057 align_length(&pStubMsg->BufferLength, increment);
6058 switch_value = get_discriminant(switch_type, pMemory);
6059 TRACE("got switch value 0x%x\n", switch_value);
6061 /* Add discriminant size */
6062 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
6063 pMemory += increment;
6065 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
6068 /***********************************************************************
6069 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
6071 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6072 PFORMAT_STRING pFormat)
6074 unsigned char switch_type;
6075 unsigned char increment;
6078 switch_type = *pFormat & 0xf;
6079 increment = (*pFormat & 0xf0) >> 4;
6082 align_pointer(&pStubMsg->Buffer, increment);
6083 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6084 TRACE("got switch value 0x%x\n", switch_value);
6086 pStubMsg->Memory += increment;
6088 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
6091 /***********************************************************************
6092 * NdrEncapsulatedUnionFree [RPCRT4.@]
6094 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6095 unsigned char *pMemory,
6096 PFORMAT_STRING pFormat)
6098 unsigned char switch_type;
6099 unsigned char increment;
6102 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6105 switch_type = *pFormat & 0xf;
6106 increment = (*pFormat & 0xf0) >> 4;
6109 switch_value = get_discriminant(switch_type, pMemory);
6110 TRACE("got switch value 0x%x\n", switch_value);
6112 pMemory += increment;
6114 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
6117 /***********************************************************************
6118 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
6120 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6121 unsigned char *pMemory,
6122 PFORMAT_STRING pFormat)
6124 unsigned char switch_type;
6126 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6129 switch_type = *pFormat;
6132 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6133 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6134 /* Marshall discriminant */
6135 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6137 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6140 static LONG unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
6141 PFORMAT_STRING *ppFormat)
6143 LONG discriminant = 0;
6153 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6162 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6163 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6171 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6172 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6177 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
6181 if (pStubMsg->fHasNewCorrDesc)
6185 return discriminant;
6188 /**********************************************************************
6189 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6191 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6192 unsigned char **ppMemory,
6193 PFORMAT_STRING pFormat,
6194 unsigned char fMustAlloc)
6197 unsigned short size;
6199 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6202 /* Unmarshall discriminant */
6203 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6204 TRACE("unmarshalled discriminant %x\n", discriminant);
6206 pFormat += *(const SHORT*)pFormat;
6208 size = *(const unsigned short*)pFormat;
6210 if (!fMustAlloc && !*ppMemory)
6213 *ppMemory = NdrAllocate(pStubMsg, size);
6215 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6216 * since the arm is part of the memory block that is encompassed by
6217 * the whole union. Memory is forced to allocate when pointers
6218 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6219 * clearing the memory we pass in to the unmarshaller */
6221 memset(*ppMemory, 0, size);
6223 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, FALSE);
6226 /***********************************************************************
6227 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6229 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6230 unsigned char *pMemory,
6231 PFORMAT_STRING pFormat)
6233 unsigned char switch_type;
6235 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6238 switch_type = *pFormat;
6241 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6242 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6243 /* Add discriminant size */
6244 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6246 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6249 /***********************************************************************
6250 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6252 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6253 PFORMAT_STRING pFormat)
6258 /* Unmarshall discriminant */
6259 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6260 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
6262 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
6265 /***********************************************************************
6266 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6268 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6269 unsigned char *pMemory,
6270 PFORMAT_STRING pFormat)
6272 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6276 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6277 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6279 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6282 /***********************************************************************
6283 * NdrByteCountPointerMarshall [RPCRT4.@]
6285 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6286 unsigned char *pMemory,
6287 PFORMAT_STRING pFormat)
6293 /***********************************************************************
6294 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6296 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6297 unsigned char **ppMemory,
6298 PFORMAT_STRING pFormat,
6299 unsigned char fMustAlloc)
6305 /***********************************************************************
6306 * NdrByteCountPointerBufferSize [RPCRT4.@]
6308 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6309 unsigned char *pMemory,
6310 PFORMAT_STRING pFormat)
6315 /***********************************************************************
6316 * NdrByteCountPointerMemorySize [internal]
6318 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6319 PFORMAT_STRING pFormat)
6325 /***********************************************************************
6326 * NdrByteCountPointerFree [RPCRT4.@]
6328 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6329 unsigned char *pMemory,
6330 PFORMAT_STRING pFormat)
6335 /***********************************************************************
6336 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6338 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6339 unsigned char *pMemory,
6340 PFORMAT_STRING pFormat)
6346 /***********************************************************************
6347 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6349 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6350 unsigned char **ppMemory,
6351 PFORMAT_STRING pFormat,
6352 unsigned char fMustAlloc)
6358 /***********************************************************************
6359 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6361 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6362 unsigned char *pMemory,
6363 PFORMAT_STRING pFormat)
6368 /***********************************************************************
6369 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6371 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6372 PFORMAT_STRING pFormat)
6378 /***********************************************************************
6379 * NdrXmitOrRepAsFree [RPCRT4.@]
6381 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6382 unsigned char *pMemory,
6383 PFORMAT_STRING pFormat)
6388 /***********************************************************************
6389 * NdrRangeMarshall [internal]
6391 static unsigned char *WINAPI NdrRangeMarshall(
6392 PMIDL_STUB_MESSAGE pStubMsg,
6393 unsigned char *pMemory,
6394 PFORMAT_STRING pFormat)
6396 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6397 unsigned char base_type;
6399 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6401 if (pRange->type != RPC_FC_RANGE)
6403 ERR("invalid format type %x\n", pRange->type);
6404 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6408 base_type = pRange->flags_type & 0xf;
6410 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6413 /***********************************************************************
6414 * NdrRangeUnmarshall [RPCRT4.@]
6416 unsigned char *WINAPI NdrRangeUnmarshall(
6417 PMIDL_STUB_MESSAGE pStubMsg,
6418 unsigned char **ppMemory,
6419 PFORMAT_STRING pFormat,
6420 unsigned char fMustAlloc)
6422 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6423 unsigned char base_type;
6425 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6427 if (pRange->type != RPC_FC_RANGE)
6429 ERR("invalid format type %x\n", pRange->type);
6430 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6433 base_type = pRange->flags_type & 0xf;
6435 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6436 base_type, pRange->low_value, pRange->high_value);
6438 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6441 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \
6442 if (!fMustAlloc && !*ppMemory) \
6443 fMustAlloc = TRUE; \
6445 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6446 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6448 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6449 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6450 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6452 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6453 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6455 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6456 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6457 (mem_type)pRange->high_value); \
6458 RpcRaiseException(RPC_S_INVALID_BOUND); \
6461 TRACE("*ppMemory: %p\n", *ppMemory); \
6462 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6463 pStubMsg->Buffer += sizeof(wire_type); \
6470 RANGE_UNMARSHALL(UCHAR, UCHAR, "%d");
6471 TRACE("value: 0x%02x\n", **ppMemory);
6475 RANGE_UNMARSHALL(CHAR, CHAR, "%u");
6476 TRACE("value: 0x%02x\n", **ppMemory);
6478 case RPC_FC_WCHAR: /* FIXME: valid? */
6480 RANGE_UNMARSHALL(USHORT, USHORT, "%u");
6481 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6484 RANGE_UNMARSHALL(SHORT, SHORT, "%d");
6485 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6489 RANGE_UNMARSHALL(LONG, LONG, "%d");
6490 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6493 RANGE_UNMARSHALL(ULONG, ULONG, "%u");
6494 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6497 RANGE_UNMARSHALL(UINT, USHORT, "%u");
6498 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6504 ERR("invalid range base type: 0x%02x\n", base_type);
6505 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6511 /***********************************************************************
6512 * NdrRangeBufferSize [internal]
6514 static void WINAPI NdrRangeBufferSize(
6515 PMIDL_STUB_MESSAGE pStubMsg,
6516 unsigned char *pMemory,
6517 PFORMAT_STRING pFormat)
6519 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6520 unsigned char base_type;
6522 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6524 if (pRange->type != RPC_FC_RANGE)
6526 ERR("invalid format type %x\n", pRange->type);
6527 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6529 base_type = pRange->flags_type & 0xf;
6531 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6534 /***********************************************************************
6535 * NdrRangeMemorySize [internal]
6537 static ULONG WINAPI NdrRangeMemorySize(
6538 PMIDL_STUB_MESSAGE pStubMsg,
6539 PFORMAT_STRING pFormat)
6541 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6542 unsigned char base_type;
6544 if (pRange->type != RPC_FC_RANGE)
6546 ERR("invalid format type %x\n", pRange->type);
6547 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6550 base_type = pRange->flags_type & 0xf;
6552 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6555 /***********************************************************************
6556 * NdrRangeFree [internal]
6558 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6559 unsigned char *pMemory,
6560 PFORMAT_STRING pFormat)
6562 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6567 /***********************************************************************
6568 * NdrBaseTypeMarshall [internal]
6570 static unsigned char *WINAPI NdrBaseTypeMarshall(
6571 PMIDL_STUB_MESSAGE pStubMsg,
6572 unsigned char *pMemory,
6573 PFORMAT_STRING pFormat)
6575 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6583 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6584 TRACE("value: 0x%02x\n", *pMemory);
6589 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6590 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6591 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6595 case RPC_FC_ERROR_STATUS_T:
6597 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONG));
6598 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6599 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6602 align_pointer_clear(&pStubMsg->Buffer, sizeof(float));
6603 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6606 align_pointer_clear(&pStubMsg->Buffer, sizeof(double));
6607 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6610 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONGLONG));
6611 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6612 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6616 USHORT val = *(UINT *)pMemory;
6617 /* only 16-bits on the wire, so do a sanity check */
6618 if (*(UINT *)pMemory > SHRT_MAX)
6619 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6620 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6621 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6622 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6625 case RPC_FC_INT3264:
6626 case RPC_FC_UINT3264:
6628 UINT val = *(UINT_PTR *)pMemory;
6629 align_pointer_clear(&pStubMsg->Buffer, sizeof(UINT));
6630 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6636 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6639 /* FIXME: what is the correct return value? */
6643 /***********************************************************************
6644 * NdrBaseTypeUnmarshall [internal]
6646 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6647 PMIDL_STUB_MESSAGE pStubMsg,
6648 unsigned char **ppMemory,
6649 PFORMAT_STRING pFormat,
6650 unsigned char fMustAlloc)
6652 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6654 #define BASE_TYPE_UNMARSHALL(type) do { \
6655 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
6656 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6658 *ppMemory = pStubMsg->Buffer; \
6659 TRACE("*ppMemory: %p\n", *ppMemory); \
6660 safe_buffer_increment(pStubMsg, sizeof(type)); \
6665 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6666 TRACE("*ppMemory: %p\n", *ppMemory); \
6667 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6677 BASE_TYPE_UNMARSHALL(UCHAR);
6678 TRACE("value: 0x%02x\n", **ppMemory);
6683 BASE_TYPE_UNMARSHALL(USHORT);
6684 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6688 case RPC_FC_ERROR_STATUS_T:
6690 BASE_TYPE_UNMARSHALL(ULONG);
6691 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6694 BASE_TYPE_UNMARSHALL(float);
6695 TRACE("value: %f\n", **(float **)ppMemory);
6698 BASE_TYPE_UNMARSHALL(double);
6699 TRACE("value: %f\n", **(double **)ppMemory);
6702 BASE_TYPE_UNMARSHALL(ULONGLONG);
6703 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6708 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6709 if (!fMustAlloc && !*ppMemory)
6712 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6713 safe_copy_from_buffer(pStubMsg, &val, sizeof(USHORT));
6714 /* 16-bits on the wire, but int in memory */
6715 **(UINT **)ppMemory = val;
6716 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6719 case RPC_FC_INT3264:
6720 if (sizeof(INT_PTR) == sizeof(INT)) BASE_TYPE_UNMARSHALL(INT);
6724 align_pointer(&pStubMsg->Buffer, sizeof(INT));
6725 if (!fMustAlloc && !*ppMemory)
6728 *ppMemory = NdrAllocate(pStubMsg, sizeof(INT_PTR));
6729 safe_copy_from_buffer(pStubMsg, &val, sizeof(INT));
6730 **(INT_PTR **)ppMemory = val;
6731 TRACE("value: 0x%08lx\n", **(INT_PTR **)ppMemory);
6734 case RPC_FC_UINT3264:
6735 if (sizeof(UINT_PTR) == sizeof(UINT)) BASE_TYPE_UNMARSHALL(UINT);
6739 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6740 if (!fMustAlloc && !*ppMemory)
6743 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT_PTR));
6744 safe_copy_from_buffer(pStubMsg, &val, sizeof(UINT));
6745 **(UINT_PTR **)ppMemory = val;
6746 TRACE("value: 0x%08lx\n", **(UINT_PTR **)ppMemory);
6752 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6754 #undef BASE_TYPE_UNMARSHALL
6756 /* FIXME: what is the correct return value? */
6761 /***********************************************************************
6762 * NdrBaseTypeBufferSize [internal]
6764 static void WINAPI NdrBaseTypeBufferSize(
6765 PMIDL_STUB_MESSAGE pStubMsg,
6766 unsigned char *pMemory,
6767 PFORMAT_STRING pFormat)
6769 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6777 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6783 align_length(&pStubMsg->BufferLength, sizeof(USHORT));
6784 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6789 case RPC_FC_INT3264:
6790 case RPC_FC_UINT3264:
6791 align_length(&pStubMsg->BufferLength, sizeof(ULONG));
6792 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6795 align_length(&pStubMsg->BufferLength, sizeof(float));
6796 safe_buffer_length_increment(pStubMsg, sizeof(float));
6799 align_length(&pStubMsg->BufferLength, sizeof(double));
6800 safe_buffer_length_increment(pStubMsg, sizeof(double));
6803 align_length(&pStubMsg->BufferLength, sizeof(ULONGLONG));
6804 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6806 case RPC_FC_ERROR_STATUS_T:
6807 align_length(&pStubMsg->BufferLength, sizeof(error_status_t));
6808 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6813 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6817 /***********************************************************************
6818 * NdrBaseTypeMemorySize [internal]
6820 static ULONG WINAPI NdrBaseTypeMemorySize(
6821 PMIDL_STUB_MESSAGE pStubMsg,
6822 PFORMAT_STRING pFormat)
6824 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6832 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6833 pStubMsg->MemorySize += sizeof(UCHAR);
6834 return sizeof(UCHAR);
6838 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6839 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6840 align_length(&pStubMsg->MemorySize, sizeof(USHORT));
6841 pStubMsg->MemorySize += sizeof(USHORT);
6842 return sizeof(USHORT);
6846 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6847 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6848 align_length(&pStubMsg->MemorySize, sizeof(ULONG));
6849 pStubMsg->MemorySize += sizeof(ULONG);
6850 return sizeof(ULONG);
6852 align_pointer(&pStubMsg->Buffer, sizeof(float));
6853 safe_buffer_increment(pStubMsg, sizeof(float));
6854 align_length(&pStubMsg->MemorySize, sizeof(float));
6855 pStubMsg->MemorySize += sizeof(float);
6856 return sizeof(float);
6858 align_pointer(&pStubMsg->Buffer, sizeof(double));
6859 safe_buffer_increment(pStubMsg, sizeof(double));
6860 align_length(&pStubMsg->MemorySize, sizeof(double));
6861 pStubMsg->MemorySize += sizeof(double);
6862 return sizeof(double);
6864 align_pointer(&pStubMsg->Buffer, sizeof(ULONGLONG));
6865 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6866 align_length(&pStubMsg->MemorySize, sizeof(ULONGLONG));
6867 pStubMsg->MemorySize += sizeof(ULONGLONG);
6868 return sizeof(ULONGLONG);
6869 case RPC_FC_ERROR_STATUS_T:
6870 align_pointer(&pStubMsg->Buffer, sizeof(error_status_t));
6871 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6872 align_length(&pStubMsg->MemorySize, sizeof(error_status_t));
6873 pStubMsg->MemorySize += sizeof(error_status_t);
6874 return sizeof(error_status_t);
6876 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6877 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6878 align_length(&pStubMsg->MemorySize, sizeof(UINT));
6879 pStubMsg->MemorySize += sizeof(UINT);
6880 return sizeof(UINT);
6881 case RPC_FC_INT3264:
6882 case RPC_FC_UINT3264:
6883 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6884 safe_buffer_increment(pStubMsg, sizeof(UINT));
6885 align_length(&pStubMsg->MemorySize, sizeof(UINT_PTR));
6886 pStubMsg->MemorySize += sizeof(UINT_PTR);
6887 return sizeof(UINT_PTR);
6889 align_length(&pStubMsg->MemorySize, sizeof(void *));
6890 pStubMsg->MemorySize += sizeof(void *);
6891 return sizeof(void *);
6893 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6898 /***********************************************************************
6899 * NdrBaseTypeFree [internal]
6901 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6902 unsigned char *pMemory,
6903 PFORMAT_STRING pFormat)
6905 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6910 /***********************************************************************
6911 * NdrContextHandleBufferSize [internal]
6913 static void WINAPI NdrContextHandleBufferSize(
6914 PMIDL_STUB_MESSAGE pStubMsg,
6915 unsigned char *pMemory,
6916 PFORMAT_STRING pFormat)
6918 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6920 if (*pFormat != RPC_FC_BIND_CONTEXT)
6922 ERR("invalid format type %x\n", *pFormat);
6923 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6925 align_length(&pStubMsg->BufferLength, 4);
6926 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6929 /***********************************************************************
6930 * NdrContextHandleMarshall [internal]
6932 static unsigned char *WINAPI NdrContextHandleMarshall(
6933 PMIDL_STUB_MESSAGE pStubMsg,
6934 unsigned char *pMemory,
6935 PFORMAT_STRING pFormat)
6937 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6939 if (*pFormat != RPC_FC_BIND_CONTEXT)
6941 ERR("invalid format type %x\n", *pFormat);
6942 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6944 TRACE("flags: 0x%02x\n", pFormat[1]);
6946 if (pStubMsg->IsClient)
6948 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6949 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6951 NdrClientContextMarshall(pStubMsg, pMemory, FALSE);
6955 NDR_SCONTEXT ctxt = NDRSContextFromValue(pMemory);
6956 NDR_RUNDOWN rundown = pStubMsg->StubDesc->apfnNdrRundownRoutines[pFormat[2]];
6957 NdrServerContextNewMarshall(pStubMsg, ctxt, rundown, pFormat);
6963 /***********************************************************************
6964 * NdrContextHandleUnmarshall [internal]
6966 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6967 PMIDL_STUB_MESSAGE pStubMsg,
6968 unsigned char **ppMemory,
6969 PFORMAT_STRING pFormat,
6970 unsigned char fMustAlloc)
6972 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6973 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6975 if (*pFormat != RPC_FC_BIND_CONTEXT)
6977 ERR("invalid format type %x\n", *pFormat);
6978 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6980 TRACE("flags: 0x%02x\n", pFormat[1]);
6982 if (pStubMsg->IsClient)
6984 /* [out]-only or [ret] param */
6985 if ((pFormat[1] & (HANDLE_PARAM_IS_IN|HANDLE_PARAM_IS_OUT)) == HANDLE_PARAM_IS_OUT)
6986 **(NDR_CCONTEXT **)ppMemory = NULL;
6987 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6992 ctxt = NdrServerContextNewUnmarshall(pStubMsg, pFormat);
6993 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6994 *(void **)ppMemory = NDRSContextValue(ctxt);
6996 *(void **)ppMemory = *NDRSContextValue(ctxt);
7002 /***********************************************************************
7003 * NdrClientContextMarshall [RPCRT4.@]
7005 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7006 NDR_CCONTEXT ContextHandle,
7009 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
7011 align_pointer_clear(&pStubMsg->Buffer, 4);
7013 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7015 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7016 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7017 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7020 /* FIXME: what does fCheck do? */
7021 NDRCContextMarshall(ContextHandle,
7024 pStubMsg->Buffer += cbNDRContext;
7027 /***********************************************************************
7028 * NdrClientContextUnmarshall [RPCRT4.@]
7030 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7031 NDR_CCONTEXT * pContextHandle,
7032 RPC_BINDING_HANDLE BindHandle)
7034 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
7036 align_pointer(&pStubMsg->Buffer, 4);
7038 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
7039 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7041 NDRCContextUnmarshall(pContextHandle,
7044 pStubMsg->RpcMsg->DataRepresentation);
7046 pStubMsg->Buffer += cbNDRContext;
7049 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7050 NDR_SCONTEXT ContextHandle,
7051 NDR_RUNDOWN RundownRoutine )
7053 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
7055 align_pointer(&pStubMsg->Buffer, 4);
7057 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7059 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7060 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7061 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7064 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7065 pStubMsg->Buffer, RundownRoutine, NULL,
7066 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7067 pStubMsg->Buffer += cbNDRContext;
7070 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
7072 NDR_SCONTEXT ContextHandle;
7074 TRACE("(%p)\n", pStubMsg);
7076 align_pointer(&pStubMsg->Buffer, 4);
7078 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7080 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7081 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7082 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7085 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7087 pStubMsg->RpcMsg->DataRepresentation,
7088 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7089 pStubMsg->Buffer += cbNDRContext;
7091 return ContextHandle;
7094 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
7095 unsigned char* pMemory,
7096 PFORMAT_STRING pFormat)
7098 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
7101 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
7102 PFORMAT_STRING pFormat)
7104 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7105 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7107 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7109 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7110 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7111 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7112 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7113 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7115 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7116 if_id = &sif->InterfaceId;
7119 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
7120 pStubMsg->RpcMsg->DataRepresentation, if_id,
7124 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7125 NDR_SCONTEXT ContextHandle,
7126 NDR_RUNDOWN RundownRoutine,
7127 PFORMAT_STRING pFormat)
7129 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7130 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7132 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
7134 align_pointer(&pStubMsg->Buffer, 4);
7136 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7138 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7139 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7140 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7143 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7144 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7145 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7146 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7147 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7149 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7150 if_id = &sif->InterfaceId;
7153 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7154 pStubMsg->Buffer, RundownRoutine, if_id, flags);
7155 pStubMsg->Buffer += cbNDRContext;
7158 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7159 PFORMAT_STRING pFormat)
7161 NDR_SCONTEXT ContextHandle;
7162 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7163 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7165 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7167 align_pointer(&pStubMsg->Buffer, 4);
7169 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7171 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7172 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7173 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7176 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7177 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7178 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7179 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7180 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7182 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7183 if_id = &sif->InterfaceId;
7186 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7188 pStubMsg->RpcMsg->DataRepresentation,
7190 pStubMsg->Buffer += cbNDRContext;
7192 return ContextHandle;
7195 /***********************************************************************
7196 * NdrCorrelationInitialize [RPCRT4.@]
7198 * Initializes correlation validity checking.
7201 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7202 * pMemory [I] Pointer to memory to use as a cache.
7203 * CacheSize [I] Size of the memory pointed to by pMemory.
7204 * Flags [I] Reserved. Set to zero.
7209 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
7211 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
7212 pStubMsg->fHasNewCorrDesc = TRUE;
7215 /***********************************************************************
7216 * NdrCorrelationPass [RPCRT4.@]
7218 * Performs correlation validity checking.
7221 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7226 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
7228 FIXME("(%p): stub\n", pStubMsg);
7231 /***********************************************************************
7232 * NdrCorrelationFree [RPCRT4.@]
7234 * Frees any resources used while unmarshalling parameters that need
7235 * correlation validity checking.
7238 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7243 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
7245 FIXME("(%p): stub\n", pStubMsg);