4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * - Byte count pointers
24 * - transmit_as/represent as
25 * - Multi-dimensional arrays
26 * - Conversion functions (NdrConvert)
27 * - Checks for integer addition overflow in user marshall functions
36 #define NONAMELESSUNION
45 #include "wine/unicode.h"
46 #include "wine/rpcfc.h"
48 #include "wine/debug.h"
50 WINE_DEFAULT_DEBUG_CHANNEL(ole);
53 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
54 (*((UINT32 *)(pchar)) = (uint32))
56 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
57 (*((UINT32 *)(pchar)))
59 /* these would work for i386 too, but less efficient */
60 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
61 (*(pchar) = LOBYTE(LOWORD(uint32)), \
62 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
63 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
64 *((pchar)+3) = HIBYTE(HIWORD(uint32)))
66 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
68 MAKEWORD(*(pchar), *((pchar)+1)), \
69 MAKEWORD(*((pchar)+2), *((pchar)+3))))
72 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
73 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
74 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
75 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
76 *(pchar) = HIBYTE(HIWORD(uint32)))
78 #define BIG_ENDIAN_UINT32_READ(pchar) \
80 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
81 MAKEWORD(*((pchar)+1), *(pchar))))
83 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
84 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
85 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
86 # define NDR_LOCAL_UINT32_READ(pchar) \
87 BIG_ENDIAN_UINT32_READ(pchar)
89 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
90 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
91 # define NDR_LOCAL_UINT32_READ(pchar) \
92 LITTLE_ENDIAN_UINT32_READ(pchar)
95 static inline void align_length( ULONG *len, unsigned int align )
97 *len = (*len + align - 1) & ~(align - 1);
100 static inline void align_pointer( unsigned char **ptr, unsigned int align )
102 ULONG_PTR mask = align - 1;
103 *ptr = (unsigned char *)(((ULONG_PTR)*ptr + mask) & ~mask);
106 static inline void align_pointer_clear( unsigned char **ptr, unsigned int align )
108 ULONG_PTR mask = align - 1;
109 memset( *ptr, 0, (align - (ULONG_PTR)*ptr) & mask );
110 *ptr = (unsigned char *)(((ULONG_PTR)*ptr + mask) & ~mask);
113 #define STD_OVERFLOW_CHECK(_Msg) do { \
114 TRACE("buffer=%d/%d\n", (ULONG)(_Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer), _Msg->BufferLength); \
115 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
116 ERR("buffer overflow %d bytes\n", (ULONG)(_Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength))); \
119 #define NDR_POINTER_ID_BASE 0x20000
120 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
121 #define NDR_TABLE_SIZE 128
122 #define NDR_TABLE_MASK 127
124 #define NDRSContextFromValue(user_context) (NDR_SCONTEXT)((char *)(user_context) - (char *)NDRSContextValue((NDR_SCONTEXT)NULL))
126 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
127 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
128 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
129 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
130 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
132 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
133 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
134 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
136 static unsigned char *WINAPI NdrRangeMarshall(PMIDL_STUB_MESSAGE,unsigned char *, PFORMAT_STRING);
137 static void WINAPI NdrRangeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
138 static ULONG WINAPI NdrRangeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
139 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
141 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
143 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
144 unsigned char *pMemory,
145 PFORMAT_STRING pFormat,
146 PFORMAT_STRING pPointer);
147 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
148 unsigned char *pMemory,
149 PFORMAT_STRING pFormat,
150 PFORMAT_STRING pPointer);
151 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
152 unsigned char *pMemory,
153 PFORMAT_STRING pFormat,
154 PFORMAT_STRING pPointer,
155 unsigned char fMustAlloc);
156 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
157 PFORMAT_STRING pFormat,
158 PFORMAT_STRING pPointer);
159 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
160 unsigned char *pMemory,
161 PFORMAT_STRING pFormat,
162 PFORMAT_STRING pPointer);
164 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
166 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
167 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
168 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
169 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
173 NdrPointerMarshall, NdrPointerMarshall,
174 NdrPointerMarshall, NdrPointerMarshall,
176 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
177 NdrConformantStructMarshall, NdrConformantStructMarshall,
178 NdrConformantVaryingStructMarshall,
179 NdrComplexStructMarshall,
181 NdrConformantArrayMarshall,
182 NdrConformantVaryingArrayMarshall,
183 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
184 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
185 NdrComplexArrayMarshall,
187 NdrConformantStringMarshall, 0, 0,
188 NdrConformantStringMarshall,
189 NdrNonConformantStringMarshall, 0, 0, 0,
191 NdrEncapsulatedUnionMarshall,
192 NdrNonEncapsulatedUnionMarshall,
193 NdrByteCountPointerMarshall,
194 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
196 NdrInterfacePointerMarshall,
198 NdrContextHandleMarshall,
201 NdrUserMarshalMarshall,
206 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
208 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
209 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
210 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
211 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
213 NdrBaseTypeUnmarshall,
215 NdrPointerUnmarshall, NdrPointerUnmarshall,
216 NdrPointerUnmarshall, NdrPointerUnmarshall,
218 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
219 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
220 NdrConformantVaryingStructUnmarshall,
221 NdrComplexStructUnmarshall,
223 NdrConformantArrayUnmarshall,
224 NdrConformantVaryingArrayUnmarshall,
225 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
226 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
227 NdrComplexArrayUnmarshall,
229 NdrConformantStringUnmarshall, 0, 0,
230 NdrConformantStringUnmarshall,
231 NdrNonConformantStringUnmarshall, 0, 0, 0,
233 NdrEncapsulatedUnionUnmarshall,
234 NdrNonEncapsulatedUnionUnmarshall,
235 NdrByteCountPointerUnmarshall,
236 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
238 NdrInterfacePointerUnmarshall,
240 NdrContextHandleUnmarshall,
243 NdrUserMarshalUnmarshall,
248 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
250 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
251 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
252 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
253 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
255 NdrBaseTypeBufferSize,
257 NdrPointerBufferSize, NdrPointerBufferSize,
258 NdrPointerBufferSize, NdrPointerBufferSize,
260 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
261 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
262 NdrConformantVaryingStructBufferSize,
263 NdrComplexStructBufferSize,
265 NdrConformantArrayBufferSize,
266 NdrConformantVaryingArrayBufferSize,
267 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
268 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
269 NdrComplexArrayBufferSize,
271 NdrConformantStringBufferSize, 0, 0,
272 NdrConformantStringBufferSize,
273 NdrNonConformantStringBufferSize, 0, 0, 0,
275 NdrEncapsulatedUnionBufferSize,
276 NdrNonEncapsulatedUnionBufferSize,
277 NdrByteCountPointerBufferSize,
278 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
280 NdrInterfacePointerBufferSize,
282 NdrContextHandleBufferSize,
285 NdrUserMarshalBufferSize,
290 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
292 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
293 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
294 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
295 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
297 NdrBaseTypeMemorySize,
299 NdrPointerMemorySize, NdrPointerMemorySize,
300 NdrPointerMemorySize, NdrPointerMemorySize,
302 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
303 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
304 NdrConformantVaryingStructMemorySize,
305 NdrComplexStructMemorySize,
307 NdrConformantArrayMemorySize,
308 NdrConformantVaryingArrayMemorySize,
309 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
310 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
311 NdrComplexArrayMemorySize,
313 NdrConformantStringMemorySize, 0, 0,
314 NdrConformantStringMemorySize,
315 NdrNonConformantStringMemorySize, 0, 0, 0,
317 NdrEncapsulatedUnionMemorySize,
318 NdrNonEncapsulatedUnionMemorySize,
319 NdrByteCountPointerMemorySize,
320 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
322 NdrInterfacePointerMemorySize,
327 NdrUserMarshalMemorySize,
332 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
334 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
335 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
336 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
337 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
341 NdrPointerFree, NdrPointerFree,
342 NdrPointerFree, NdrPointerFree,
344 NdrSimpleStructFree, NdrSimpleStructFree,
345 NdrConformantStructFree, NdrConformantStructFree,
346 NdrConformantVaryingStructFree,
347 NdrComplexStructFree,
349 NdrConformantArrayFree,
350 NdrConformantVaryingArrayFree,
351 NdrFixedArrayFree, NdrFixedArrayFree,
352 NdrVaryingArrayFree, NdrVaryingArrayFree,
358 NdrEncapsulatedUnionFree,
359 NdrNonEncapsulatedUnionFree,
361 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
363 NdrInterfacePointerFree,
374 typedef struct _NDR_MEMORY_LIST
379 struct _NDR_MEMORY_LIST *next;
382 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
384 /***********************************************************************
385 * NdrAllocate [RPCRT4.@]
387 * Allocates a block of memory using pStubMsg->pfnAllocate.
390 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
391 * len [I] Size of memory block to allocate.
394 * The memory block of size len that was allocated.
397 * The memory block is always 8-byte aligned.
398 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
399 * exception is raised.
401 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, SIZE_T len)
406 NDR_MEMORY_LIST *mem_list;
408 aligned_len = (len + 7) & ~7;
409 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
410 /* check for overflow */
411 if (adjusted_len < len)
413 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len, len);
414 RpcRaiseException(RPC_X_BAD_STUB_DATA);
417 p = pStubMsg->pfnAllocate(adjusted_len);
418 if (!p) RpcRaiseException(ERROR_OUTOFMEMORY);
420 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
421 mem_list->magic = MEML_MAGIC;
422 mem_list->size = aligned_len;
423 mem_list->reserved = 0;
424 mem_list->next = pStubMsg->pMemoryList;
425 pStubMsg->pMemoryList = mem_list;
431 static void NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
433 TRACE("(%p, %p)\n", pStubMsg, Pointer);
435 pStubMsg->pfnFree(Pointer);
438 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
440 return (*(const ULONG *)pFormat != -1);
443 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
445 align_pointer(&pStubMsg->Buffer, 4);
446 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
447 RpcRaiseException(RPC_X_BAD_STUB_DATA);
448 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
449 pStubMsg->Buffer += 4;
450 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
451 if (pStubMsg->fHasNewCorrDesc)
457 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
459 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
461 pStubMsg->Offset = 0;
462 pStubMsg->ActualCount = pStubMsg->MaxCount;
466 align_pointer(&pStubMsg->Buffer, 4);
467 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
468 RpcRaiseException(RPC_X_BAD_STUB_DATA);
469 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
470 pStubMsg->Buffer += 4;
471 TRACE("offset is %d\n", pStubMsg->Offset);
472 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
473 pStubMsg->Buffer += 4;
474 TRACE("variance is %d\n", pStubMsg->ActualCount);
476 if ((pStubMsg->ActualCount > MaxValue) ||
477 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
479 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
480 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
481 RpcRaiseException(RPC_S_INVALID_BOUND);
486 if (pStubMsg->fHasNewCorrDesc)
492 /* writes the conformance value to the buffer */
493 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
495 align_pointer_clear(&pStubMsg->Buffer, 4);
496 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
497 RpcRaiseException(RPC_X_BAD_STUB_DATA);
498 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
499 pStubMsg->Buffer += 4;
502 /* writes the variance values to the buffer */
503 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
505 align_pointer_clear(&pStubMsg->Buffer, 4);
506 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
507 RpcRaiseException(RPC_X_BAD_STUB_DATA);
508 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
509 pStubMsg->Buffer += 4;
510 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
511 pStubMsg->Buffer += 4;
514 /* requests buffer space for the conformance value */
515 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
517 align_length(&pStubMsg->BufferLength, 4);
518 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
519 RpcRaiseException(RPC_X_BAD_STUB_DATA);
520 pStubMsg->BufferLength += 4;
523 /* requests buffer space for the variance values */
524 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
526 align_length(&pStubMsg->BufferLength, 4);
527 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
528 RpcRaiseException(RPC_X_BAD_STUB_DATA);
529 pStubMsg->BufferLength += 8;
532 PFORMAT_STRING ComputeConformanceOrVariance(
533 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
534 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
536 BYTE dtype = pFormat[0] & 0xf;
537 short ofs = *(const short *)&pFormat[2];
541 if (!IsConformanceOrVariancePresent(pFormat)) {
542 /* null descriptor */
547 switch (pFormat[0] & 0xf0) {
548 case RPC_FC_NORMAL_CONFORMANCE:
549 TRACE("normal conformance, ofs=%d\n", ofs);
552 case RPC_FC_POINTER_CONFORMANCE:
553 TRACE("pointer conformance, ofs=%d\n", ofs);
554 ptr = pStubMsg->Memory;
556 case RPC_FC_TOP_LEVEL_CONFORMANCE:
557 TRACE("toplevel conformance, ofs=%d\n", ofs);
558 if (pStubMsg->StackTop) {
559 ptr = pStubMsg->StackTop;
562 /* -Os mode, *pCount is already set */
566 case RPC_FC_CONSTANT_CONFORMANCE:
567 data = ofs | ((DWORD)pFormat[1] << 16);
568 TRACE("constant conformance, val=%ld\n", data);
571 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
572 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
573 if (pStubMsg->StackTop) {
574 ptr = pStubMsg->StackTop;
582 FIXME("unknown conformance type %x, expect crash.\n", pFormat[0] & 0xf0);
586 switch (pFormat[1]) {
587 case RPC_FC_DEREFERENCE:
588 ptr = *(LPVOID*)((char *)ptr + ofs);
590 case RPC_FC_CALLBACK:
592 unsigned char *old_stack_top = pStubMsg->StackTop;
593 ULONG_PTR max_count, old_max_count = pStubMsg->MaxCount;
595 pStubMsg->StackTop = ptr;
597 /* ofs is index into StubDesc->apfnExprEval */
598 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
599 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
601 pStubMsg->StackTop = old_stack_top;
603 /* the callback function always stores the computed value in MaxCount */
604 max_count = pStubMsg->MaxCount;
605 pStubMsg->MaxCount = old_max_count;
610 ptr = (char *)ptr + ofs;
623 data = *(USHORT*)ptr;
634 data = *(ULONGLONG *)ptr;
637 FIXME("unknown conformance data type %x\n", dtype);
640 TRACE("dereferenced data type %x at %p, got %ld\n", dtype, ptr, data);
643 switch (pFormat[1]) {
644 case RPC_FC_DEREFERENCE: /* already handled */
661 FIXME("unknown conformance op %d\n", pFormat[1]);
666 TRACE("resulting conformance is %ld\n", *pCount);
667 if (pStubMsg->fHasNewCorrDesc)
673 static inline PFORMAT_STRING SkipConformance(PMIDL_STUB_MESSAGE pStubMsg,
674 PFORMAT_STRING pFormat)
676 if (pStubMsg->fHasNewCorrDesc)
683 static inline PFORMAT_STRING SkipVariance(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
685 return SkipConformance( pStubMsg, pFormat );
688 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
689 * the result overflows 32-bits */
690 static inline ULONG safe_multiply(ULONG a, ULONG b)
692 ULONGLONG ret = (ULONGLONG)a * b;
693 if (ret > 0xffffffff)
695 RpcRaiseException(RPC_S_INVALID_BOUND);
701 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
703 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
704 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
705 RpcRaiseException(RPC_X_BAD_STUB_DATA);
706 pStubMsg->Buffer += size;
709 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
711 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
713 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
714 pStubMsg->BufferLength, size);
715 RpcRaiseException(RPC_X_BAD_STUB_DATA);
717 pStubMsg->BufferLength += size;
720 /* copies data from the buffer, checking that there is enough data in the buffer
722 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
724 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
725 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
727 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
728 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
729 RpcRaiseException(RPC_X_BAD_STUB_DATA);
731 if (p == pStubMsg->Buffer)
732 ERR("pointer is the same as the buffer\n");
733 memcpy(p, pStubMsg->Buffer, size);
734 pStubMsg->Buffer += size;
737 /* copies data to the buffer, checking that there is enough space to do so */
738 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
740 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
741 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
743 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
744 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
746 RpcRaiseException(RPC_X_BAD_STUB_DATA);
748 memcpy(pStubMsg->Buffer, p, size);
749 pStubMsg->Buffer += size;
752 /* verify that string data sitting in the buffer is valid and safe to
754 static void validate_string_data(MIDL_STUB_MESSAGE *pStubMsg, ULONG bufsize, ULONG esize)
758 /* verify the buffer is safe to access */
759 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
760 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
762 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
763 pStubMsg->BufferEnd, pStubMsg->Buffer);
764 RpcRaiseException(RPC_X_BAD_STUB_DATA);
767 /* strings must always have null terminating bytes */
770 ERR("invalid string length of %d\n", bufsize / esize);
771 RpcRaiseException(RPC_S_INVALID_BOUND);
774 for (i = bufsize - esize; i < bufsize; i++)
775 if (pStubMsg->Buffer[i] != 0)
777 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
778 i, pStubMsg->Buffer[i]);
779 RpcRaiseException(RPC_S_INVALID_BOUND);
783 static inline void dump_pointer_attr(unsigned char attr)
785 if (attr & RPC_FC_P_ALLOCALLNODES)
786 TRACE(" RPC_FC_P_ALLOCALLNODES");
787 if (attr & RPC_FC_P_DONTFREE)
788 TRACE(" RPC_FC_P_DONTFREE");
789 if (attr & RPC_FC_P_ONSTACK)
790 TRACE(" RPC_FC_P_ONSTACK");
791 if (attr & RPC_FC_P_SIMPLEPOINTER)
792 TRACE(" RPC_FC_P_SIMPLEPOINTER");
793 if (attr & RPC_FC_P_DEREF)
794 TRACE(" RPC_FC_P_DEREF");
798 /***********************************************************************
799 * PointerMarshall [internal]
801 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
802 unsigned char *Buffer,
803 unsigned char *Pointer,
804 PFORMAT_STRING pFormat)
806 unsigned type = pFormat[0], attr = pFormat[1];
810 int pointer_needs_marshaling;
812 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
813 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
815 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
816 else desc = pFormat + *(const SHORT*)pFormat;
819 case RPC_FC_RP: /* ref pointer (always non-null) */
822 ERR("NULL ref pointer is not allowed\n");
823 RpcRaiseException(RPC_X_NULL_REF_POINTER);
825 pointer_needs_marshaling = 1;
827 case RPC_FC_UP: /* unique pointer */
828 case RPC_FC_OP: /* object pointer - same as unique here */
830 pointer_needs_marshaling = 1;
832 pointer_needs_marshaling = 0;
833 pointer_id = Pointer ? NDR_POINTER_ID(pStubMsg) : 0;
834 TRACE("writing 0x%08x to buffer\n", pointer_id);
835 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
838 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
839 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
840 TRACE("writing 0x%08x to buffer\n", pointer_id);
841 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
844 FIXME("unhandled ptr type=%02x\n", type);
845 RpcRaiseException(RPC_X_BAD_STUB_DATA);
849 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
851 if (pointer_needs_marshaling) {
852 if (attr & RPC_FC_P_DEREF) {
853 Pointer = *(unsigned char**)Pointer;
854 TRACE("deref => %p\n", Pointer);
856 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
857 if (m) m(pStubMsg, Pointer, desc);
858 else FIXME("no marshaller for data type=%02x\n", *desc);
861 STD_OVERFLOW_CHECK(pStubMsg);
864 /***********************************************************************
865 * PointerUnmarshall [internal]
867 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
868 unsigned char *Buffer,
869 unsigned char **pPointer,
870 unsigned char *pSrcPointer,
871 PFORMAT_STRING pFormat,
872 unsigned char fMustAlloc)
874 unsigned type = pFormat[0], attr = pFormat[1];
877 DWORD pointer_id = 0;
878 int pointer_needs_unmarshaling;
880 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
881 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
883 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
884 else desc = pFormat + *(const SHORT*)pFormat;
887 case RPC_FC_RP: /* ref pointer (always non-null) */
888 pointer_needs_unmarshaling = 1;
890 case RPC_FC_UP: /* unique pointer */
891 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
892 TRACE("pointer_id is 0x%08x\n", pointer_id);
894 pointer_needs_unmarshaling = 1;
897 pointer_needs_unmarshaling = 0;
900 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
901 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
902 TRACE("pointer_id is 0x%08x\n", pointer_id);
903 if (!fMustAlloc && pSrcPointer)
905 FIXME("free object pointer %p\n", pSrcPointer);
909 pointer_needs_unmarshaling = 1;
913 pointer_needs_unmarshaling = 0;
917 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
918 TRACE("pointer_id is 0x%08x\n", pointer_id);
919 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
920 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
923 FIXME("unhandled ptr type=%02x\n", type);
924 RpcRaiseException(RPC_X_BAD_STUB_DATA);
928 if (pointer_needs_unmarshaling) {
929 unsigned char **current_ptr = pPointer;
930 if (pStubMsg->IsClient) {
932 /* if we aren't forcing allocation of memory then try to use the existing
933 * (source) pointer to unmarshall the data into so that [in,out]
934 * parameters behave correctly. it doesn't matter if the parameter is
935 * [out] only since in that case the pointer will be NULL. we force
936 * allocation when the source pointer is NULL here instead of in the type
937 * unmarshalling routine for the benefit of the deref code below */
940 TRACE("setting *pPointer to %p\n", pSrcPointer);
941 *pPointer = pSrcPointer;
947 /* the memory in a stub is never initialised, so we have to work out here
948 * whether we have to initialise it so we can use the optimisation of
949 * setting the pointer to the buffer, if possible, or set fMustAlloc to
951 if (attr & RPC_FC_P_DEREF) {
958 if (attr & RPC_FC_P_ALLOCALLNODES)
959 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
961 if (attr & RPC_FC_P_DEREF) {
963 unsigned char *base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
964 *pPointer = base_ptr_val;
965 current_ptr = (unsigned char **)base_ptr_val;
967 current_ptr = *(unsigned char***)current_ptr;
968 TRACE("deref => %p\n", current_ptr);
969 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
971 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
972 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
973 else FIXME("no unmarshaller for data type=%02x\n", *desc);
975 if (type == RPC_FC_FP)
976 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
980 TRACE("pointer=%p\n", *pPointer);
983 /***********************************************************************
984 * PointerBufferSize [internal]
986 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
987 unsigned char *Pointer,
988 PFORMAT_STRING pFormat)
990 unsigned type = pFormat[0], attr = pFormat[1];
993 int pointer_needs_sizing;
996 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
997 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
999 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1000 else desc = pFormat + *(const SHORT*)pFormat;
1003 case RPC_FC_RP: /* ref pointer (always non-null) */
1006 ERR("NULL ref pointer is not allowed\n");
1007 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1012 /* NULL pointer has no further representation */
1017 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1018 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1019 if (!pointer_needs_sizing)
1023 FIXME("unhandled ptr type=%02x\n", type);
1024 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1028 if (attr & RPC_FC_P_DEREF) {
1029 Pointer = *(unsigned char**)Pointer;
1030 TRACE("deref => %p\n", Pointer);
1033 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1034 if (m) m(pStubMsg, Pointer, desc);
1035 else FIXME("no buffersizer for data type=%02x\n", *desc);
1038 /***********************************************************************
1039 * PointerMemorySize [internal]
1041 static ULONG PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1042 unsigned char *Buffer, PFORMAT_STRING pFormat)
1044 unsigned type = pFormat[0], attr = pFormat[1];
1045 PFORMAT_STRING desc;
1047 DWORD pointer_id = 0;
1048 int pointer_needs_sizing;
1050 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1051 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1053 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1054 else desc = pFormat + *(const SHORT*)pFormat;
1057 case RPC_FC_RP: /* ref pointer (always non-null) */
1058 pointer_needs_sizing = 1;
1060 case RPC_FC_UP: /* unique pointer */
1061 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1062 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1063 TRACE("pointer_id is 0x%08x\n", pointer_id);
1065 pointer_needs_sizing = 1;
1067 pointer_needs_sizing = 0;
1072 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1073 TRACE("pointer_id is 0x%08x\n", pointer_id);
1074 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1075 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1079 FIXME("unhandled ptr type=%02x\n", type);
1080 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1084 if (attr & RPC_FC_P_DEREF) {
1085 align_length(&pStubMsg->MemorySize, sizeof(void*));
1086 pStubMsg->MemorySize += sizeof(void*);
1090 if (pointer_needs_sizing) {
1091 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1092 if (m) m(pStubMsg, desc);
1093 else FIXME("no memorysizer for data type=%02x\n", *desc);
1096 return pStubMsg->MemorySize;
1099 /***********************************************************************
1100 * PointerFree [internal]
1102 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1103 unsigned char *Pointer,
1104 PFORMAT_STRING pFormat)
1106 unsigned type = pFormat[0], attr = pFormat[1];
1107 PFORMAT_STRING desc;
1109 unsigned char *current_pointer = Pointer;
1111 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1112 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1113 if (attr & RPC_FC_P_DONTFREE) return;
1115 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1116 else desc = pFormat + *(const SHORT*)pFormat;
1118 if (!Pointer) return;
1120 if (type == RPC_FC_FP) {
1121 int pointer_needs_freeing = NdrFullPointerFree(
1122 pStubMsg->FullPtrXlatTables, Pointer);
1123 if (!pointer_needs_freeing)
1127 if (attr & RPC_FC_P_DEREF) {
1128 current_pointer = *(unsigned char**)Pointer;
1129 TRACE("deref => %p\n", current_pointer);
1132 m = NdrFreer[*desc & NDR_TABLE_MASK];
1133 if (m) m(pStubMsg, current_pointer, desc);
1135 /* this check stops us from trying to free buffer memory. we don't have to
1136 * worry about clients, since they won't call this function.
1137 * we don't have to check for the buffer being reallocated because
1138 * BufferStart and BufferEnd won't be reset when allocating memory for
1139 * sending the response. we don't have to check for the new buffer here as
1140 * it won't be used a type memory, only for buffer memory */
1141 if (Pointer >= pStubMsg->BufferStart && Pointer < pStubMsg->BufferEnd)
1144 if (attr & RPC_FC_P_ONSTACK) {
1145 TRACE("not freeing stack ptr %p\n", Pointer);
1148 TRACE("freeing %p\n", Pointer);
1149 NdrFree(pStubMsg, Pointer);
1152 TRACE("not freeing %p\n", Pointer);
1155 /***********************************************************************
1156 * EmbeddedPointerMarshall
1158 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1159 unsigned char *pMemory,
1160 PFORMAT_STRING pFormat)
1162 unsigned char *Mark = pStubMsg->BufferMark;
1163 unsigned rep, count, stride;
1165 unsigned char *saved_buffer = NULL;
1167 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1169 if (*pFormat != RPC_FC_PP) return NULL;
1172 if (pStubMsg->PointerBufferMark)
1174 saved_buffer = pStubMsg->Buffer;
1175 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1176 pStubMsg->PointerBufferMark = NULL;
1179 while (pFormat[0] != RPC_FC_END) {
1180 switch (pFormat[0]) {
1182 FIXME("unknown repeat type %d\n", pFormat[0]);
1183 case RPC_FC_NO_REPEAT:
1189 case RPC_FC_FIXED_REPEAT:
1190 rep = *(const WORD*)&pFormat[2];
1191 stride = *(const WORD*)&pFormat[4];
1192 count = *(const WORD*)&pFormat[8];
1195 case RPC_FC_VARIABLE_REPEAT:
1196 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1197 stride = *(const WORD*)&pFormat[2];
1198 count = *(const WORD*)&pFormat[6];
1202 for (i = 0; i < rep; i++) {
1203 PFORMAT_STRING info = pFormat;
1204 unsigned char *membase = pMemory + (i * stride);
1205 unsigned char *bufbase = Mark + (i * stride);
1208 for (u=0; u<count; u++,info+=8) {
1209 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1210 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1211 unsigned char *saved_memory = pStubMsg->Memory;
1213 pStubMsg->Memory = pMemory;
1214 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1215 pStubMsg->Memory = saved_memory;
1218 pFormat += 8 * count;
1223 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1224 pStubMsg->Buffer = saved_buffer;
1227 STD_OVERFLOW_CHECK(pStubMsg);
1232 /***********************************************************************
1233 * EmbeddedPointerUnmarshall
1235 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1236 unsigned char *pDstBuffer,
1237 unsigned char *pSrcMemoryPtrs,
1238 PFORMAT_STRING pFormat,
1239 unsigned char fMustAlloc)
1241 unsigned char *Mark = pStubMsg->BufferMark;
1242 unsigned rep, count, stride;
1244 unsigned char *saved_buffer = NULL;
1246 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc);
1248 if (*pFormat != RPC_FC_PP) return NULL;
1251 if (pStubMsg->PointerBufferMark)
1253 saved_buffer = pStubMsg->Buffer;
1254 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1255 pStubMsg->PointerBufferMark = NULL;
1258 while (pFormat[0] != RPC_FC_END) {
1259 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1260 switch (pFormat[0]) {
1262 FIXME("unknown repeat type %d\n", pFormat[0]);
1263 case RPC_FC_NO_REPEAT:
1269 case RPC_FC_FIXED_REPEAT:
1270 rep = *(const WORD*)&pFormat[2];
1271 stride = *(const WORD*)&pFormat[4];
1272 count = *(const WORD*)&pFormat[8];
1275 case RPC_FC_VARIABLE_REPEAT:
1276 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1277 stride = *(const WORD*)&pFormat[2];
1278 count = *(const WORD*)&pFormat[6];
1282 for (i = 0; i < rep; i++) {
1283 PFORMAT_STRING info = pFormat;
1284 unsigned char *bufdstbase = pDstBuffer + (i * stride);
1285 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1286 unsigned char *bufbase = Mark + (i * stride);
1289 for (u=0; u<count; u++,info+=8) {
1290 unsigned char **bufdstptr = (unsigned char **)(bufdstbase + *(const SHORT*)&info[2]);
1291 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1292 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1293 PointerUnmarshall(pStubMsg, bufptr, bufdstptr, *memsrcptr, info+4, fMustAlloc);
1296 pFormat += 8 * count;
1301 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1302 pStubMsg->Buffer = saved_buffer;
1308 /***********************************************************************
1309 * EmbeddedPointerBufferSize
1311 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1312 unsigned char *pMemory,
1313 PFORMAT_STRING pFormat)
1315 unsigned rep, count, stride;
1317 ULONG saved_buffer_length = 0;
1319 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1321 if (pStubMsg->IgnoreEmbeddedPointers) return;
1323 if (*pFormat != RPC_FC_PP) return;
1326 if (pStubMsg->PointerLength)
1328 saved_buffer_length = pStubMsg->BufferLength;
1329 pStubMsg->BufferLength = pStubMsg->PointerLength;
1330 pStubMsg->PointerLength = 0;
1333 while (pFormat[0] != RPC_FC_END) {
1334 switch (pFormat[0]) {
1336 FIXME("unknown repeat type %d\n", pFormat[0]);
1337 case RPC_FC_NO_REPEAT:
1343 case RPC_FC_FIXED_REPEAT:
1344 rep = *(const WORD*)&pFormat[2];
1345 stride = *(const WORD*)&pFormat[4];
1346 count = *(const WORD*)&pFormat[8];
1349 case RPC_FC_VARIABLE_REPEAT:
1350 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1351 stride = *(const WORD*)&pFormat[2];
1352 count = *(const WORD*)&pFormat[6];
1356 for (i = 0; i < rep; i++) {
1357 PFORMAT_STRING info = pFormat;
1358 unsigned char *membase = pMemory + (i * stride);
1361 for (u=0; u<count; u++,info+=8) {
1362 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1363 unsigned char *saved_memory = pStubMsg->Memory;
1365 pStubMsg->Memory = pMemory;
1366 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1367 pStubMsg->Memory = saved_memory;
1370 pFormat += 8 * count;
1373 if (saved_buffer_length)
1375 pStubMsg->PointerLength = pStubMsg->BufferLength;
1376 pStubMsg->BufferLength = saved_buffer_length;
1380 /***********************************************************************
1381 * EmbeddedPointerMemorySize [internal]
1383 static ULONG EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1384 PFORMAT_STRING pFormat)
1386 unsigned char *Mark = pStubMsg->BufferMark;
1387 unsigned rep, count, stride;
1389 unsigned char *saved_buffer = NULL;
1391 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1393 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1395 if (pStubMsg->PointerBufferMark)
1397 saved_buffer = pStubMsg->Buffer;
1398 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1399 pStubMsg->PointerBufferMark = NULL;
1402 if (*pFormat != RPC_FC_PP) return 0;
1405 while (pFormat[0] != RPC_FC_END) {
1406 switch (pFormat[0]) {
1408 FIXME("unknown repeat type %d\n", pFormat[0]);
1409 case RPC_FC_NO_REPEAT:
1415 case RPC_FC_FIXED_REPEAT:
1416 rep = *(const WORD*)&pFormat[2];
1417 stride = *(const WORD*)&pFormat[4];
1418 count = *(const WORD*)&pFormat[8];
1421 case RPC_FC_VARIABLE_REPEAT:
1422 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1423 stride = *(const WORD*)&pFormat[2];
1424 count = *(const WORD*)&pFormat[6];
1428 for (i = 0; i < rep; i++) {
1429 PFORMAT_STRING info = pFormat;
1430 unsigned char *bufbase = Mark + (i * stride);
1432 for (u=0; u<count; u++,info+=8) {
1433 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1434 PointerMemorySize(pStubMsg, bufptr, info+4);
1437 pFormat += 8 * count;
1442 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1443 pStubMsg->Buffer = saved_buffer;
1449 /***********************************************************************
1450 * EmbeddedPointerFree [internal]
1452 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1453 unsigned char *pMemory,
1454 PFORMAT_STRING pFormat)
1456 unsigned rep, count, stride;
1459 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1460 if (*pFormat != RPC_FC_PP) return;
1463 while (pFormat[0] != RPC_FC_END) {
1464 switch (pFormat[0]) {
1466 FIXME("unknown repeat type %d\n", pFormat[0]);
1467 case RPC_FC_NO_REPEAT:
1473 case RPC_FC_FIXED_REPEAT:
1474 rep = *(const WORD*)&pFormat[2];
1475 stride = *(const WORD*)&pFormat[4];
1476 count = *(const WORD*)&pFormat[8];
1479 case RPC_FC_VARIABLE_REPEAT:
1480 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1481 stride = *(const WORD*)&pFormat[2];
1482 count = *(const WORD*)&pFormat[6];
1486 for (i = 0; i < rep; i++) {
1487 PFORMAT_STRING info = pFormat;
1488 unsigned char *membase = pMemory + (i * stride);
1491 for (u=0; u<count; u++,info+=8) {
1492 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1493 unsigned char *saved_memory = pStubMsg->Memory;
1495 pStubMsg->Memory = pMemory;
1496 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1497 pStubMsg->Memory = saved_memory;
1500 pFormat += 8 * count;
1504 /***********************************************************************
1505 * NdrPointerMarshall [RPCRT4.@]
1507 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1508 unsigned char *pMemory,
1509 PFORMAT_STRING pFormat)
1511 unsigned char *Buffer;
1513 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1515 /* Increment the buffer here instead of in PointerMarshall,
1516 * as that is used by embedded pointers which already handle the incrementing
1517 * the buffer, and shouldn't write any additional pointer data to the wire */
1518 if (*pFormat != RPC_FC_RP)
1520 align_pointer_clear(&pStubMsg->Buffer, 4);
1521 Buffer = pStubMsg->Buffer;
1522 safe_buffer_increment(pStubMsg, 4);
1525 Buffer = pStubMsg->Buffer;
1527 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1532 /***********************************************************************
1533 * NdrPointerUnmarshall [RPCRT4.@]
1535 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1536 unsigned char **ppMemory,
1537 PFORMAT_STRING pFormat,
1538 unsigned char fMustAlloc)
1540 unsigned char *Buffer;
1542 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1544 if (*pFormat == RPC_FC_RP)
1546 Buffer = pStubMsg->Buffer;
1547 /* Do the NULL ref pointer check here because embedded pointers can be
1548 * NULL if the type the pointer is embedded in was allocated rather than
1549 * being passed in by the client */
1550 if (pStubMsg->IsClient && !*ppMemory)
1552 ERR("NULL ref pointer is not allowed\n");
1553 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1558 /* Increment the buffer here instead of in PointerUnmarshall,
1559 * as that is used by embedded pointers which already handle the incrementing
1560 * the buffer, and shouldn't read any additional pointer data from the
1562 align_pointer(&pStubMsg->Buffer, 4);
1563 Buffer = pStubMsg->Buffer;
1564 safe_buffer_increment(pStubMsg, 4);
1567 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1572 /***********************************************************************
1573 * NdrPointerBufferSize [RPCRT4.@]
1575 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1576 unsigned char *pMemory,
1577 PFORMAT_STRING pFormat)
1579 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1581 /* Increment the buffer length here instead of in PointerBufferSize,
1582 * as that is used by embedded pointers which already handle the buffer
1583 * length, and shouldn't write anything more to the wire */
1584 if (*pFormat != RPC_FC_RP)
1586 align_length(&pStubMsg->BufferLength, 4);
1587 safe_buffer_length_increment(pStubMsg, 4);
1590 PointerBufferSize(pStubMsg, pMemory, pFormat);
1593 /***********************************************************************
1594 * NdrPointerMemorySize [RPCRT4.@]
1596 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1597 PFORMAT_STRING pFormat)
1599 unsigned char *Buffer = pStubMsg->Buffer;
1600 if (*pFormat != RPC_FC_RP)
1602 align_pointer(&pStubMsg->Buffer, 4);
1603 safe_buffer_increment(pStubMsg, 4);
1605 align_length(&pStubMsg->MemorySize, sizeof(void *));
1606 return PointerMemorySize(pStubMsg, Buffer, pFormat);
1609 /***********************************************************************
1610 * NdrPointerFree [RPCRT4.@]
1612 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1613 unsigned char *pMemory,
1614 PFORMAT_STRING pFormat)
1616 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1617 PointerFree(pStubMsg, pMemory, pFormat);
1620 /***********************************************************************
1621 * NdrSimpleTypeMarshall [RPCRT4.@]
1623 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1624 unsigned char FormatChar )
1626 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1629 /***********************************************************************
1630 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1632 * Unmarshall a base type.
1635 * Doesn't check that the buffer is long enough before copying, so the caller
1638 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1639 unsigned char FormatChar )
1641 #define BASE_TYPE_UNMARSHALL(type) \
1642 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
1643 TRACE("pMemory: %p\n", pMemory); \
1644 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1645 pStubMsg->Buffer += sizeof(type);
1653 BASE_TYPE_UNMARSHALL(UCHAR);
1654 TRACE("value: 0x%02x\n", *pMemory);
1659 BASE_TYPE_UNMARSHALL(USHORT);
1660 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
1664 case RPC_FC_ERROR_STATUS_T:
1666 BASE_TYPE_UNMARSHALL(ULONG);
1667 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
1670 BASE_TYPE_UNMARSHALL(float);
1671 TRACE("value: %f\n", *(float *)pMemory);
1674 BASE_TYPE_UNMARSHALL(double);
1675 TRACE("value: %f\n", *(double *)pMemory);
1678 BASE_TYPE_UNMARSHALL(ULONGLONG);
1679 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
1682 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
1683 TRACE("pMemory: %p\n", pMemory);
1684 /* 16-bits on the wire, but int in memory */
1685 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
1686 pStubMsg->Buffer += sizeof(USHORT);
1687 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
1689 case RPC_FC_INT3264:
1690 align_pointer(&pStubMsg->Buffer, sizeof(INT));
1691 /* 32-bits on the wire, but int_ptr in memory */
1692 *(INT_PTR *)pMemory = *(INT *)pStubMsg->Buffer;
1693 pStubMsg->Buffer += sizeof(INT);
1694 TRACE("value: 0x%08lx\n", *(INT_PTR *)pMemory);
1696 case RPC_FC_UINT3264:
1697 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
1698 /* 32-bits on the wire, but int_ptr in memory */
1699 *(UINT_PTR *)pMemory = *(UINT *)pStubMsg->Buffer;
1700 pStubMsg->Buffer += sizeof(UINT);
1701 TRACE("value: 0x%08lx\n", *(UINT_PTR *)pMemory);
1706 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
1708 #undef BASE_TYPE_UNMARSHALL
1711 /***********************************************************************
1712 * NdrSimpleStructMarshall [RPCRT4.@]
1714 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1715 unsigned char *pMemory,
1716 PFORMAT_STRING pFormat)
1718 unsigned size = *(const WORD*)(pFormat+2);
1719 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1721 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1);
1723 pStubMsg->BufferMark = pStubMsg->Buffer;
1724 safe_copy_to_buffer(pStubMsg, pMemory, size);
1726 if (pFormat[0] != RPC_FC_STRUCT)
1727 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1732 /***********************************************************************
1733 * NdrSimpleStructUnmarshall [RPCRT4.@]
1735 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1736 unsigned char **ppMemory,
1737 PFORMAT_STRING pFormat,
1738 unsigned char fMustAlloc)
1740 unsigned size = *(const WORD*)(pFormat+2);
1741 unsigned char *saved_buffer;
1742 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1744 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
1747 *ppMemory = NdrAllocate(pStubMsg, size);
1750 if (!pStubMsg->IsClient && !*ppMemory)
1751 /* for servers, we just point straight into the RPC buffer */
1752 *ppMemory = pStubMsg->Buffer;
1755 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1756 safe_buffer_increment(pStubMsg, size);
1757 if (pFormat[0] == RPC_FC_PSTRUCT)
1758 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1760 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1761 if (*ppMemory != saved_buffer)
1762 memcpy(*ppMemory, saved_buffer, size);
1767 /***********************************************************************
1768 * NdrSimpleStructBufferSize [RPCRT4.@]
1770 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1771 unsigned char *pMemory,
1772 PFORMAT_STRING pFormat)
1774 unsigned size = *(const WORD*)(pFormat+2);
1775 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1777 align_length(&pStubMsg->BufferLength, pFormat[1] + 1);
1779 safe_buffer_length_increment(pStubMsg, size);
1780 if (pFormat[0] != RPC_FC_STRUCT)
1781 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1784 /***********************************************************************
1785 * NdrSimpleStructMemorySize [RPCRT4.@]
1787 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1788 PFORMAT_STRING pFormat)
1790 unsigned short size = *(const WORD *)(pFormat+2);
1792 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1794 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
1795 pStubMsg->MemorySize += size;
1796 safe_buffer_increment(pStubMsg, size);
1798 if (pFormat[0] != RPC_FC_STRUCT)
1799 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1800 return pStubMsg->MemorySize;
1803 /***********************************************************************
1804 * NdrSimpleStructFree [RPCRT4.@]
1806 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1807 unsigned char *pMemory,
1808 PFORMAT_STRING pFormat)
1810 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1811 if (pFormat[0] != RPC_FC_STRUCT)
1812 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1817 static inline void array_compute_and_size_conformance(
1818 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1819 PFORMAT_STRING pFormat)
1826 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1827 SizeConformance(pStubMsg);
1829 case RPC_FC_CVARRAY:
1830 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1831 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1832 SizeConformance(pStubMsg);
1834 case RPC_FC_C_CSTRING:
1835 case RPC_FC_C_WSTRING:
1836 if (fc == RPC_FC_C_CSTRING)
1838 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1839 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1843 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1844 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1847 if (pFormat[1] == RPC_FC_STRING_SIZED)
1848 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1850 pStubMsg->MaxCount = pStubMsg->ActualCount;
1852 SizeConformance(pStubMsg);
1854 case RPC_FC_BOGUS_ARRAY:
1855 count = *(const WORD *)(pFormat + 2);
1857 if (IsConformanceOrVariancePresent(pFormat)) SizeConformance(pStubMsg);
1858 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, count);
1859 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
1862 ERR("unknown array format 0x%x\n", fc);
1863 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1867 static inline void array_buffer_size(
1868 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1869 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1873 unsigned char alignment;
1878 esize = *(const WORD*)(pFormat+2);
1879 alignment = pFormat[1] + 1;
1881 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1883 align_length(&pStubMsg->BufferLength, alignment);
1885 size = safe_multiply(esize, pStubMsg->MaxCount);
1886 /* conformance value plus array */
1887 safe_buffer_length_increment(pStubMsg, size);
1890 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1892 case RPC_FC_CVARRAY:
1893 esize = *(const WORD*)(pFormat+2);
1894 alignment = pFormat[1] + 1;
1896 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1897 pFormat = SkipVariance(pStubMsg, pFormat);
1899 SizeVariance(pStubMsg);
1901 align_length(&pStubMsg->BufferLength, alignment);
1903 size = safe_multiply(esize, pStubMsg->ActualCount);
1904 safe_buffer_length_increment(pStubMsg, size);
1907 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1909 case RPC_FC_C_CSTRING:
1910 case RPC_FC_C_WSTRING:
1911 if (fc == RPC_FC_C_CSTRING)
1916 SizeVariance(pStubMsg);
1918 size = safe_multiply(esize, pStubMsg->ActualCount);
1919 safe_buffer_length_increment(pStubMsg, size);
1921 case RPC_FC_BOGUS_ARRAY:
1922 alignment = pFormat[1] + 1;
1923 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1924 if (IsConformanceOrVariancePresent(pFormat)) SizeVariance(pStubMsg);
1925 pFormat = SkipVariance(pStubMsg, pFormat);
1927 align_length(&pStubMsg->BufferLength, alignment);
1929 size = pStubMsg->ActualCount;
1930 for (i = 0; i < size; i++)
1931 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
1934 ERR("unknown array format 0x%x\n", fc);
1935 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1939 static inline void array_compute_and_write_conformance(
1940 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1941 PFORMAT_STRING pFormat)
1944 BOOL conformance_present;
1949 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1950 WriteConformance(pStubMsg);
1952 case RPC_FC_CVARRAY:
1953 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1954 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1955 WriteConformance(pStubMsg);
1957 case RPC_FC_C_CSTRING:
1958 case RPC_FC_C_WSTRING:
1959 if (fc == RPC_FC_C_CSTRING)
1961 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1962 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1966 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1967 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1969 if (pFormat[1] == RPC_FC_STRING_SIZED)
1970 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1972 pStubMsg->MaxCount = pStubMsg->ActualCount;
1973 pStubMsg->Offset = 0;
1974 WriteConformance(pStubMsg);
1976 case RPC_FC_BOGUS_ARRAY:
1977 def = *(const WORD *)(pFormat + 2);
1979 conformance_present = IsConformanceOrVariancePresent(pFormat);
1980 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
1981 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
1982 if (conformance_present) WriteConformance(pStubMsg);
1985 ERR("unknown array format 0x%x\n", fc);
1986 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1990 static inline void array_write_variance_and_marshall(
1991 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1992 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1996 unsigned char alignment;
2001 esize = *(const WORD*)(pFormat+2);
2002 alignment = pFormat[1] + 1;
2004 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2006 align_pointer_clear(&pStubMsg->Buffer, alignment);
2008 size = safe_multiply(esize, pStubMsg->MaxCount);
2010 pStubMsg->BufferMark = pStubMsg->Buffer;
2011 safe_copy_to_buffer(pStubMsg, pMemory, size);
2014 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2016 case RPC_FC_CVARRAY:
2017 esize = *(const WORD*)(pFormat+2);
2018 alignment = pFormat[1] + 1;
2020 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2021 pFormat = SkipVariance(pStubMsg, pFormat);
2023 WriteVariance(pStubMsg);
2025 align_pointer_clear(&pStubMsg->Buffer, alignment);
2027 size = safe_multiply(esize, pStubMsg->ActualCount);
2030 pStubMsg->BufferMark = pStubMsg->Buffer;
2031 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size);
2034 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2036 case RPC_FC_C_CSTRING:
2037 case RPC_FC_C_WSTRING:
2038 if (fc == RPC_FC_C_CSTRING)
2043 WriteVariance(pStubMsg);
2045 size = safe_multiply(esize, pStubMsg->ActualCount);
2046 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2048 case RPC_FC_BOGUS_ARRAY:
2049 alignment = pFormat[1] + 1;
2050 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2051 if (IsConformanceOrVariancePresent(pFormat)) WriteVariance(pStubMsg);
2052 pFormat = SkipVariance(pStubMsg, pFormat);
2054 align_pointer_clear(&pStubMsg->Buffer, alignment);
2056 size = pStubMsg->ActualCount;
2057 for (i = 0; i < size; i++)
2058 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2061 ERR("unknown array format 0x%x\n", fc);
2062 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2066 static inline ULONG array_read_conformance(
2067 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
2074 esize = *(const WORD*)(pFormat+2);
2075 pFormat = ReadConformance(pStubMsg, pFormat+4);
2076 return safe_multiply(esize, pStubMsg->MaxCount);
2077 case RPC_FC_CVARRAY:
2078 esize = *(const WORD*)(pFormat+2);
2079 pFormat = ReadConformance(pStubMsg, pFormat+4);
2080 return safe_multiply(esize, pStubMsg->MaxCount);
2081 case RPC_FC_C_CSTRING:
2082 case RPC_FC_C_WSTRING:
2083 if (fc == RPC_FC_C_CSTRING)
2088 if (pFormat[1] == RPC_FC_STRING_SIZED)
2089 ReadConformance(pStubMsg, pFormat + 2);
2091 ReadConformance(pStubMsg, NULL);
2092 return safe_multiply(esize, pStubMsg->MaxCount);
2093 case RPC_FC_BOGUS_ARRAY:
2094 def = *(const WORD *)(pFormat + 2);
2096 if (IsConformanceOrVariancePresent(pFormat)) pFormat = ReadConformance(pStubMsg, pFormat);
2099 pStubMsg->MaxCount = def;
2100 pFormat = SkipConformance( pStubMsg, pFormat );
2102 pFormat = SkipVariance( pStubMsg, pFormat );
2104 esize = ComplexStructSize(pStubMsg, pFormat);
2105 return safe_multiply(pStubMsg->MaxCount, esize);
2107 ERR("unknown array format 0x%x\n", fc);
2108 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2112 static inline ULONG array_read_variance_and_unmarshall(
2113 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory,
2114 PFORMAT_STRING pFormat, unsigned char fMustAlloc,
2115 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall)
2117 ULONG bufsize, memsize;
2119 unsigned char alignment;
2120 unsigned char *saved_buffer, *pMemory;
2121 ULONG i, offset, count;
2126 esize = *(const WORD*)(pFormat+2);
2127 alignment = pFormat[1] + 1;
2129 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2131 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2133 align_pointer(&pStubMsg->Buffer, alignment);
2138 *ppMemory = NdrAllocate(pStubMsg, memsize);
2141 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory)
2142 /* for servers, we just point straight into the RPC buffer */
2143 *ppMemory = pStubMsg->Buffer;
2146 saved_buffer = pStubMsg->Buffer;
2147 safe_buffer_increment(pStubMsg, bufsize);
2149 pStubMsg->BufferMark = saved_buffer;
2150 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2152 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2153 if (*ppMemory != saved_buffer)
2154 memcpy(*ppMemory, saved_buffer, bufsize);
2157 case RPC_FC_CVARRAY:
2158 esize = *(const WORD*)(pFormat+2);
2159 alignment = pFormat[1] + 1;
2161 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2163 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2165 align_pointer(&pStubMsg->Buffer, alignment);
2167 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2168 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2172 offset = pStubMsg->Offset;
2174 if (!fMustAlloc && !*ppMemory)
2177 *ppMemory = NdrAllocate(pStubMsg, memsize);
2178 saved_buffer = pStubMsg->Buffer;
2179 safe_buffer_increment(pStubMsg, bufsize);
2181 pStubMsg->BufferMark = saved_buffer;
2182 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat,
2185 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2188 case RPC_FC_C_CSTRING:
2189 case RPC_FC_C_WSTRING:
2190 if (fc == RPC_FC_C_CSTRING)
2195 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2197 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2199 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2200 pStubMsg->ActualCount, pStubMsg->MaxCount);
2201 RpcRaiseException(RPC_S_INVALID_BOUND);
2203 if (pStubMsg->Offset)
2205 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2206 RpcRaiseException(RPC_S_INVALID_BOUND);
2209 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2210 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2212 validate_string_data(pStubMsg, bufsize, esize);
2217 *ppMemory = NdrAllocate(pStubMsg, memsize);
2220 if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
2221 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
2222 /* if the data in the RPC buffer is big enough, we just point
2223 * straight into it */
2224 *ppMemory = pStubMsg->Buffer;
2225 else if (!*ppMemory)
2226 *ppMemory = NdrAllocate(pStubMsg, memsize);
2229 if (*ppMemory == pStubMsg->Buffer)
2230 safe_buffer_increment(pStubMsg, bufsize);
2232 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2234 if (*pFormat == RPC_FC_C_CSTRING)
2235 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
2237 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
2241 case RPC_FC_BOGUS_ARRAY:
2242 alignment = pFormat[1] + 1;
2243 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2244 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2246 esize = ComplexStructSize(pStubMsg, pFormat);
2247 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2249 assert( fUnmarshall );
2251 if (!fMustAlloc && !*ppMemory)
2254 *ppMemory = NdrAllocate(pStubMsg, memsize);
2256 align_pointer(&pStubMsg->Buffer, alignment);
2257 saved_buffer = pStubMsg->Buffer;
2259 pMemory = *ppMemory;
2260 count = pStubMsg->ActualCount;
2261 for (i = 0; i < count; i++)
2262 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
2263 return pStubMsg->Buffer - saved_buffer;
2266 ERR("unknown array format 0x%x\n", fc);
2267 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2271 static inline void array_memory_size(
2272 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
2273 unsigned char fHasPointers)
2275 ULONG i, count, SavedMemorySize;
2276 ULONG bufsize, memsize;
2278 unsigned char alignment;
2283 esize = *(const WORD*)(pFormat+2);
2284 alignment = pFormat[1] + 1;
2286 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2288 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2289 pStubMsg->MemorySize += memsize;
2291 align_pointer(&pStubMsg->Buffer, alignment);
2293 pStubMsg->BufferMark = pStubMsg->Buffer;
2294 safe_buffer_increment(pStubMsg, bufsize);
2297 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2299 case RPC_FC_CVARRAY:
2300 esize = *(const WORD*)(pFormat+2);
2301 alignment = pFormat[1] + 1;
2303 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2305 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2307 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2308 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2309 pStubMsg->MemorySize += memsize;
2311 align_pointer(&pStubMsg->Buffer, alignment);
2313 pStubMsg->BufferMark = pStubMsg->Buffer;
2314 safe_buffer_increment(pStubMsg, bufsize);
2317 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2319 case RPC_FC_C_CSTRING:
2320 case RPC_FC_C_WSTRING:
2321 if (fc == RPC_FC_C_CSTRING)
2326 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2328 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2330 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2331 pStubMsg->ActualCount, pStubMsg->MaxCount);
2332 RpcRaiseException(RPC_S_INVALID_BOUND);
2334 if (pStubMsg->Offset)
2336 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2337 RpcRaiseException(RPC_S_INVALID_BOUND);
2340 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2341 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2343 validate_string_data(pStubMsg, bufsize, esize);
2345 safe_buffer_increment(pStubMsg, bufsize);
2346 pStubMsg->MemorySize += memsize;
2348 case RPC_FC_BOGUS_ARRAY:
2349 alignment = pFormat[1] + 1;
2350 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2351 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2353 align_pointer(&pStubMsg->Buffer, alignment);
2355 SavedMemorySize = pStubMsg->MemorySize;
2357 esize = ComplexStructSize(pStubMsg, pFormat);
2358 memsize = safe_multiply(pStubMsg->MaxCount, esize);
2360 count = pStubMsg->ActualCount;
2361 for (i = 0; i < count; i++)
2362 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
2364 pStubMsg->MemorySize = SavedMemorySize + memsize;
2367 ERR("unknown array format 0x%x\n", fc);
2368 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2372 static inline void array_free(
2373 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
2374 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
2381 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2383 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2385 case RPC_FC_CVARRAY:
2386 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2387 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2389 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2391 case RPC_FC_C_CSTRING:
2392 case RPC_FC_C_WSTRING:
2393 /* No embedded pointers so nothing to do */
2395 case RPC_FC_BOGUS_ARRAY:
2396 count = *(const WORD *)(pFormat + 2);
2397 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, count);
2398 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2400 count = pStubMsg->ActualCount;
2401 for (i = 0; i < count; i++)
2402 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2405 ERR("unknown array format 0x%x\n", fc);
2406 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2411 * NdrConformantString:
2413 * What MS calls a ConformantString is, in DCE terminology,
2414 * a Varying-Conformant String.
2416 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2417 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2418 * into unmarshalled string)
2419 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2421 * data: CHARTYPE[maxlen]
2423 * ], where CHARTYPE is the appropriate character type (specified externally)
2427 /***********************************************************************
2428 * NdrConformantStringMarshall [RPCRT4.@]
2430 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
2431 unsigned char *pszMessage, PFORMAT_STRING pFormat)
2433 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
2435 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2436 ERR("Unhandled string type: %#x\n", pFormat[0]);
2437 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2440 /* allow compiler to optimise inline function by passing constant into
2441 * these functions */
2442 if (pFormat[0] == RPC_FC_C_CSTRING) {
2443 array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2445 array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2446 pFormat, TRUE /* fHasPointers */);
2448 array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2450 array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2451 pFormat, TRUE /* fHasPointers */);
2457 /***********************************************************************
2458 * NdrConformantStringBufferSize [RPCRT4.@]
2460 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2461 unsigned char* pMemory, PFORMAT_STRING pFormat)
2463 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2465 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2466 ERR("Unhandled string type: %#x\n", pFormat[0]);
2467 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2470 /* allow compiler to optimise inline function by passing constant into
2471 * these functions */
2472 if (pFormat[0] == RPC_FC_C_CSTRING) {
2473 array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory,
2475 array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat,
2476 TRUE /* fHasPointers */);
2478 array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory,
2480 array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat,
2481 TRUE /* fHasPointers */);
2485 /************************************************************************
2486 * NdrConformantStringMemorySize [RPCRT4.@]
2488 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2489 PFORMAT_STRING pFormat )
2491 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2493 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2494 ERR("Unhandled string type: %#x\n", pFormat[0]);
2495 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2498 /* allow compiler to optimise inline function by passing constant into
2499 * these functions */
2500 if (pFormat[0] == RPC_FC_C_CSTRING) {
2501 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2502 array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat,
2503 TRUE /* fHasPointers */);
2505 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2506 array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat,
2507 TRUE /* fHasPointers */);
2510 return pStubMsg->MemorySize;
2513 /************************************************************************
2514 * NdrConformantStringUnmarshall [RPCRT4.@]
2516 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2517 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
2519 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2520 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2522 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2523 ERR("Unhandled string type: %#x\n", *pFormat);
2524 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2527 /* allow compiler to optimise inline function by passing constant into
2528 * these functions */
2529 if (pFormat[0] == RPC_FC_C_CSTRING) {
2530 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2531 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory,
2532 pFormat, fMustAlloc,
2533 TRUE /* fUseBufferMemoryServer */,
2534 TRUE /* fUnmarshall */);
2536 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2537 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory,
2538 pFormat, fMustAlloc,
2539 TRUE /* fUseBufferMemoryServer */,
2540 TRUE /* fUnmarshall */);
2546 /***********************************************************************
2547 * NdrNonConformantStringMarshall [RPCRT4.@]
2549 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2550 unsigned char *pMemory,
2551 PFORMAT_STRING pFormat)
2553 ULONG esize, size, maxsize;
2555 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2557 maxsize = *(const USHORT *)&pFormat[2];
2559 if (*pFormat == RPC_FC_CSTRING)
2562 const char *str = (const char *)pMemory;
2563 while (i < maxsize && str[i]) i++;
2564 TRACE("string=%s\n", debugstr_an(str, i));
2565 pStubMsg->ActualCount = i + 1;
2568 else if (*pFormat == RPC_FC_WSTRING)
2571 const WCHAR *str = (const WCHAR *)pMemory;
2572 while (i < maxsize && str[i]) i++;
2573 TRACE("string=%s\n", debugstr_wn(str, i));
2574 pStubMsg->ActualCount = i + 1;
2579 ERR("Unhandled string type: %#x\n", *pFormat);
2580 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2583 pStubMsg->Offset = 0;
2584 WriteVariance(pStubMsg);
2586 size = safe_multiply(esize, pStubMsg->ActualCount);
2587 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2592 /***********************************************************************
2593 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2595 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2596 unsigned char **ppMemory,
2597 PFORMAT_STRING pFormat,
2598 unsigned char fMustAlloc)
2600 ULONG bufsize, memsize, esize, maxsize;
2602 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2603 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2605 maxsize = *(const USHORT *)&pFormat[2];
2607 ReadVariance(pStubMsg, NULL, maxsize);
2608 if (pStubMsg->Offset)
2610 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2611 RpcRaiseException(RPC_S_INVALID_BOUND);
2614 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2615 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2618 ERR("Unhandled string type: %#x\n", *pFormat);
2619 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2622 memsize = esize * maxsize;
2623 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2625 validate_string_data(pStubMsg, bufsize, esize);
2627 if (!fMustAlloc && !*ppMemory)
2630 *ppMemory = NdrAllocate(pStubMsg, memsize);
2632 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2634 if (*pFormat == RPC_FC_CSTRING) {
2635 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
2637 else if (*pFormat == RPC_FC_WSTRING) {
2638 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
2644 /***********************************************************************
2645 * NdrNonConformantStringBufferSize [RPCRT4.@]
2647 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2648 unsigned char *pMemory,
2649 PFORMAT_STRING pFormat)
2651 ULONG esize, maxsize;
2653 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2655 maxsize = *(const USHORT *)&pFormat[2];
2657 SizeVariance(pStubMsg);
2659 if (*pFormat == RPC_FC_CSTRING)
2662 const char *str = (const char *)pMemory;
2663 while (i < maxsize && str[i]) i++;
2664 TRACE("string=%s\n", debugstr_an(str, i));
2665 pStubMsg->ActualCount = i + 1;
2668 else if (*pFormat == RPC_FC_WSTRING)
2671 const WCHAR *str = (const WCHAR *)pMemory;
2672 while (i < maxsize && str[i]) i++;
2673 TRACE("string=%s\n", debugstr_wn(str, i));
2674 pStubMsg->ActualCount = i + 1;
2679 ERR("Unhandled string type: %#x\n", *pFormat);
2680 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2683 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2686 /***********************************************************************
2687 * NdrNonConformantStringMemorySize [RPCRT4.@]
2689 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2690 PFORMAT_STRING pFormat)
2692 ULONG bufsize, memsize, esize, maxsize;
2694 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2696 maxsize = *(const USHORT *)&pFormat[2];
2698 ReadVariance(pStubMsg, NULL, maxsize);
2700 if (pStubMsg->Offset)
2702 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2703 RpcRaiseException(RPC_S_INVALID_BOUND);
2706 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2707 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2710 ERR("Unhandled string type: %#x\n", *pFormat);
2711 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2714 memsize = esize * maxsize;
2715 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2717 validate_string_data(pStubMsg, bufsize, esize);
2719 safe_buffer_increment(pStubMsg, bufsize);
2720 pStubMsg->MemorySize += memsize;
2722 return pStubMsg->MemorySize;
2727 #include "pshpack1.h"
2731 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2735 #include "poppack.h"
2737 static ULONG EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2738 PFORMAT_STRING pFormat)
2742 case RPC_FC_PSTRUCT:
2743 case RPC_FC_CSTRUCT:
2744 case RPC_FC_BOGUS_STRUCT:
2745 case RPC_FC_SMFARRAY:
2746 case RPC_FC_SMVARRAY:
2747 case RPC_FC_CSTRING:
2748 return *(const WORD*)&pFormat[2];
2749 case RPC_FC_USER_MARSHAL:
2750 return *(const WORD*)&pFormat[4];
2751 case RPC_FC_RANGE: {
2752 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2757 return sizeof(UCHAR);
2761 return sizeof(USHORT);
2765 case RPC_FC_INT3264:
2766 case RPC_FC_UINT3264:
2767 return sizeof(ULONG);
2769 return sizeof(float);
2771 return sizeof(double);
2773 return sizeof(ULONGLONG);
2775 return sizeof(UINT);
2777 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2778 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2781 case RPC_FC_NON_ENCAPSULATED_UNION:
2783 if (pStubMsg->fHasNewCorrDesc)
2788 pFormat += *(const SHORT*)pFormat;
2789 return *(const SHORT*)pFormat;
2791 return sizeof(void *);
2792 case RPC_FC_WSTRING:
2793 return *(const WORD*)&pFormat[2] * 2;
2795 FIXME("unhandled embedded type %02x\n", *pFormat);
2801 static ULONG EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2802 PFORMAT_STRING pFormat)
2804 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2808 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2812 return m(pStubMsg, pFormat);
2816 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2817 unsigned char *pMemory,
2818 PFORMAT_STRING pFormat,
2819 PFORMAT_STRING pPointer)
2821 PFORMAT_STRING desc;
2825 while (*pFormat != RPC_FC_END) {
2831 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2832 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2838 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2839 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2844 USHORT val = *(DWORD *)pMemory;
2845 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2846 if (32767 < *(DWORD*)pMemory)
2847 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2848 safe_copy_to_buffer(pStubMsg, &val, 2);
2855 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2856 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2859 case RPC_FC_INT3264:
2860 case RPC_FC_UINT3264:
2862 UINT val = *(UINT_PTR *)pMemory;
2863 TRACE("int3264=%ld <= %p\n", *(UINT_PTR *)pMemory, pMemory);
2864 safe_copy_to_buffer(pStubMsg, &val, sizeof(UINT));
2865 pMemory += sizeof(UINT_PTR);
2869 TRACE("float=%f <= %p\n", *(float*)pMemory, pMemory);
2870 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
2871 pMemory += sizeof(float);
2874 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2875 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2879 TRACE("double=%f <= %p\n", *(double*)pMemory, pMemory);
2880 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
2881 pMemory += sizeof(double);
2887 case RPC_FC_POINTER:
2889 unsigned char *saved_buffer;
2890 int pointer_buffer_mark_set = 0;
2891 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2892 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2893 if (*pFormat != RPC_FC_POINTER)
2895 if (*pPointer != RPC_FC_RP)
2896 align_pointer_clear(&pStubMsg->Buffer, 4);
2897 saved_buffer = pStubMsg->Buffer;
2898 if (pStubMsg->PointerBufferMark)
2900 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2901 pStubMsg->PointerBufferMark = NULL;
2902 pointer_buffer_mark_set = 1;
2904 else if (*pPointer != RPC_FC_RP)
2905 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2906 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2907 if (pointer_buffer_mark_set)
2909 STD_OVERFLOW_CHECK(pStubMsg);
2910 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2911 pStubMsg->Buffer = saved_buffer;
2912 if (*pPointer != RPC_FC_RP)
2913 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2915 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2916 if (*pFormat == RPC_FC_POINTER)
2920 pMemory += sizeof(void *);
2923 case RPC_FC_ALIGNM2:
2924 align_pointer(&pMemory, 2);
2926 case RPC_FC_ALIGNM4:
2927 align_pointer(&pMemory, 4);
2929 case RPC_FC_ALIGNM8:
2930 align_pointer(&pMemory, 8);
2932 case RPC_FC_STRUCTPAD1:
2933 case RPC_FC_STRUCTPAD2:
2934 case RPC_FC_STRUCTPAD3:
2935 case RPC_FC_STRUCTPAD4:
2936 case RPC_FC_STRUCTPAD5:
2937 case RPC_FC_STRUCTPAD6:
2938 case RPC_FC_STRUCTPAD7:
2939 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2941 case RPC_FC_EMBEDDED_COMPLEX:
2942 pMemory += pFormat[1];
2944 desc = pFormat + *(const SHORT*)pFormat;
2945 size = EmbeddedComplexSize(pStubMsg, desc);
2946 TRACE("embedded complex (size=%d) <= %p\n", size, pMemory);
2947 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2950 /* for some reason interface pointers aren't generated as
2951 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2952 * they still need the derefencing treatment that pointers are
2954 if (*desc == RPC_FC_IP)
2955 m(pStubMsg, *(unsigned char **)pMemory, desc);
2957 m(pStubMsg, pMemory, desc);
2959 else FIXME("no marshaller for embedded type %02x\n", *desc);
2966 FIXME("unhandled format 0x%02x\n", *pFormat);
2974 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2975 unsigned char *pMemory,
2976 PFORMAT_STRING pFormat,
2977 PFORMAT_STRING pPointer,
2978 unsigned char fMustAlloc)
2980 PFORMAT_STRING desc;
2984 while (*pFormat != RPC_FC_END) {
2990 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2991 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2997 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2998 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
3004 safe_copy_from_buffer(pStubMsg, &val, 2);
3005 *(DWORD*)pMemory = val;
3006 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
3007 if (32767 < *(DWORD*)pMemory)
3008 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
3015 safe_copy_from_buffer(pStubMsg, pMemory, 4);
3016 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
3019 case RPC_FC_INT3264:
3022 safe_copy_from_buffer(pStubMsg, &val, 4);
3023 *(INT_PTR *)pMemory = val;
3024 TRACE("int3264=%ld => %p\n", *(INT_PTR*)pMemory, pMemory);
3025 pMemory += sizeof(INT_PTR);
3028 case RPC_FC_UINT3264:
3031 safe_copy_from_buffer(pStubMsg, &val, 4);
3032 *(UINT_PTR *)pMemory = val;
3033 TRACE("uint3264=%ld => %p\n", *(UINT_PTR*)pMemory, pMemory);
3034 pMemory += sizeof(UINT_PTR);
3038 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(float));
3039 TRACE("float=%f => %p\n", *(float*)pMemory, pMemory);
3040 pMemory += sizeof(float);
3043 safe_copy_from_buffer(pStubMsg, pMemory, 8);
3044 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
3048 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(double));
3049 TRACE("double=%f => %p\n", *(double*)pMemory, pMemory);
3050 pMemory += sizeof(double);
3056 case RPC_FC_POINTER:
3058 unsigned char *saved_buffer;
3059 int pointer_buffer_mark_set = 0;
3060 TRACE("pointer => %p\n", pMemory);
3061 if (*pFormat != RPC_FC_POINTER)
3063 if (*pPointer != RPC_FC_RP)
3064 align_pointer(&pStubMsg->Buffer, 4);
3065 saved_buffer = pStubMsg->Buffer;
3066 if (pStubMsg->PointerBufferMark)
3068 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3069 pStubMsg->PointerBufferMark = NULL;
3070 pointer_buffer_mark_set = 1;
3072 else if (*pPointer != RPC_FC_RP)
3073 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3075 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
3076 if (pointer_buffer_mark_set)
3078 STD_OVERFLOW_CHECK(pStubMsg);
3079 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3080 pStubMsg->Buffer = saved_buffer;
3081 if (*pPointer != RPC_FC_RP)
3082 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3084 if (*pFormat == RPC_FC_POINTER)
3088 pMemory += sizeof(void *);
3091 case RPC_FC_ALIGNM2:
3092 align_pointer_clear(&pMemory, 2);
3094 case RPC_FC_ALIGNM4:
3095 align_pointer_clear(&pMemory, 4);
3097 case RPC_FC_ALIGNM8:
3098 align_pointer_clear(&pMemory, 8);
3100 case RPC_FC_STRUCTPAD1:
3101 case RPC_FC_STRUCTPAD2:
3102 case RPC_FC_STRUCTPAD3:
3103 case RPC_FC_STRUCTPAD4:
3104 case RPC_FC_STRUCTPAD5:
3105 case RPC_FC_STRUCTPAD6:
3106 case RPC_FC_STRUCTPAD7:
3107 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
3108 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3110 case RPC_FC_EMBEDDED_COMPLEX:
3111 pMemory += pFormat[1];
3113 desc = pFormat + *(const SHORT*)pFormat;
3114 size = EmbeddedComplexSize(pStubMsg, desc);
3115 TRACE("embedded complex (size=%d) => %p\n", size, pMemory);
3117 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
3118 * since the type is part of the memory block that is encompassed by
3119 * the whole complex type. Memory is forced to allocate when pointers
3120 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
3121 * clearing the memory we pass in to the unmarshaller */
3122 memset(pMemory, 0, size);
3123 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
3126 /* for some reason interface pointers aren't generated as
3127 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3128 * they still need the derefencing treatment that pointers are
3130 if (*desc == RPC_FC_IP)
3131 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
3133 m(pStubMsg, &pMemory, desc, FALSE);
3135 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
3142 FIXME("unhandled format %d\n", *pFormat);
3150 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3151 unsigned char *pMemory,
3152 PFORMAT_STRING pFormat,
3153 PFORMAT_STRING pPointer)
3155 PFORMAT_STRING desc;
3159 while (*pFormat != RPC_FC_END) {
3165 safe_buffer_length_increment(pStubMsg, 1);
3171 safe_buffer_length_increment(pStubMsg, 2);
3175 safe_buffer_length_increment(pStubMsg, 2);
3182 safe_buffer_length_increment(pStubMsg, 4);
3185 case RPC_FC_INT3264:
3186 case RPC_FC_UINT3264:
3187 safe_buffer_length_increment(pStubMsg, 4);
3188 pMemory += sizeof(INT_PTR);
3192 safe_buffer_length_increment(pStubMsg, 8);
3199 case RPC_FC_POINTER:
3200 if (*pFormat != RPC_FC_POINTER)
3202 if (!pStubMsg->IgnoreEmbeddedPointers)
3204 int saved_buffer_length = pStubMsg->BufferLength;
3205 pStubMsg->BufferLength = pStubMsg->PointerLength;
3206 pStubMsg->PointerLength = 0;
3207 if(!pStubMsg->BufferLength)
3208 ERR("BufferLength == 0??\n");
3209 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
3210 pStubMsg->PointerLength = pStubMsg->BufferLength;
3211 pStubMsg->BufferLength = saved_buffer_length;
3213 if (*pPointer != RPC_FC_RP)
3215 align_length(&pStubMsg->BufferLength, 4);
3216 safe_buffer_length_increment(pStubMsg, 4);
3218 if (*pFormat == RPC_FC_POINTER)
3222 pMemory += sizeof(void*);
3224 case RPC_FC_ALIGNM2:
3225 align_pointer(&pMemory, 2);
3227 case RPC_FC_ALIGNM4:
3228 align_pointer(&pMemory, 4);
3230 case RPC_FC_ALIGNM8:
3231 align_pointer(&pMemory, 8);
3233 case RPC_FC_STRUCTPAD1:
3234 case RPC_FC_STRUCTPAD2:
3235 case RPC_FC_STRUCTPAD3:
3236 case RPC_FC_STRUCTPAD4:
3237 case RPC_FC_STRUCTPAD5:
3238 case RPC_FC_STRUCTPAD6:
3239 case RPC_FC_STRUCTPAD7:
3240 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3242 case RPC_FC_EMBEDDED_COMPLEX:
3243 pMemory += pFormat[1];
3245 desc = pFormat + *(const SHORT*)pFormat;
3246 size = EmbeddedComplexSize(pStubMsg, desc);
3247 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
3250 /* for some reason interface pointers aren't generated as
3251 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3252 * they still need the derefencing treatment that pointers are
3254 if (*desc == RPC_FC_IP)
3255 m(pStubMsg, *(unsigned char **)pMemory, desc);
3257 m(pStubMsg, pMemory, desc);
3259 else FIXME("no buffersizer for embedded type %02x\n", *desc);
3266 FIXME("unhandled format 0x%02x\n", *pFormat);
3274 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
3275 unsigned char *pMemory,
3276 PFORMAT_STRING pFormat,
3277 PFORMAT_STRING pPointer)
3279 PFORMAT_STRING desc;
3283 while (*pFormat != RPC_FC_END) {
3303 case RPC_FC_INT3264:
3304 case RPC_FC_UINT3264:
3305 pMemory += sizeof(INT_PTR);
3315 case RPC_FC_POINTER:
3316 if (*pFormat != RPC_FC_POINTER)
3318 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3319 if (*pFormat == RPC_FC_POINTER)
3323 pMemory += sizeof(void *);
3325 case RPC_FC_ALIGNM2:
3326 align_pointer(&pMemory, 2);
3328 case RPC_FC_ALIGNM4:
3329 align_pointer(&pMemory, 4);
3331 case RPC_FC_ALIGNM8:
3332 align_pointer(&pMemory, 8);
3334 case RPC_FC_STRUCTPAD1:
3335 case RPC_FC_STRUCTPAD2:
3336 case RPC_FC_STRUCTPAD3:
3337 case RPC_FC_STRUCTPAD4:
3338 case RPC_FC_STRUCTPAD5:
3339 case RPC_FC_STRUCTPAD6:
3340 case RPC_FC_STRUCTPAD7:
3341 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3343 case RPC_FC_EMBEDDED_COMPLEX:
3344 pMemory += pFormat[1];
3346 desc = pFormat + *(const SHORT*)pFormat;
3347 size = EmbeddedComplexSize(pStubMsg, desc);
3348 m = NdrFreer[*desc & NDR_TABLE_MASK];
3351 /* for some reason interface pointers aren't generated as
3352 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3353 * they still need the derefencing treatment that pointers are
3355 if (*desc == RPC_FC_IP)
3356 m(pStubMsg, *(unsigned char **)pMemory, desc);
3358 m(pStubMsg, pMemory, desc);
3366 FIXME("unhandled format 0x%02x\n", *pFormat);
3374 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3375 PFORMAT_STRING pFormat,
3376 PFORMAT_STRING pPointer)
3378 PFORMAT_STRING desc;
3381 while (*pFormat != RPC_FC_END) {
3388 safe_buffer_increment(pStubMsg, 1);
3394 safe_buffer_increment(pStubMsg, 2);
3398 safe_buffer_increment(pStubMsg, 2);
3405 safe_buffer_increment(pStubMsg, 4);
3407 case RPC_FC_INT3264:
3408 case RPC_FC_UINT3264:
3409 size += sizeof(INT_PTR);
3410 safe_buffer_increment(pStubMsg, 4);
3415 safe_buffer_increment(pStubMsg, 8);
3421 case RPC_FC_POINTER:
3423 unsigned char *saved_buffer;
3424 int pointer_buffer_mark_set = 0;
3425 if (*pFormat != RPC_FC_POINTER)
3427 if (*pPointer != RPC_FC_RP)
3428 align_pointer(&pStubMsg->Buffer, 4);
3429 saved_buffer = pStubMsg->Buffer;
3430 if (pStubMsg->PointerBufferMark)
3432 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3433 pStubMsg->PointerBufferMark = NULL;
3434 pointer_buffer_mark_set = 1;
3436 else if (*pPointer != RPC_FC_RP)
3437 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3439 if (!pStubMsg->IgnoreEmbeddedPointers)
3440 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3441 if (pointer_buffer_mark_set)
3443 STD_OVERFLOW_CHECK(pStubMsg);
3444 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3445 pStubMsg->Buffer = saved_buffer;
3446 if (*pPointer != RPC_FC_RP)
3447 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3449 if (*pFormat == RPC_FC_POINTER)
3453 size += sizeof(void *);
3456 case RPC_FC_ALIGNM2:
3457 align_length(&size, 2);
3459 case RPC_FC_ALIGNM4:
3460 align_length(&size, 4);
3462 case RPC_FC_ALIGNM8:
3463 align_length(&size, 8);
3465 case RPC_FC_STRUCTPAD1:
3466 case RPC_FC_STRUCTPAD2:
3467 case RPC_FC_STRUCTPAD3:
3468 case RPC_FC_STRUCTPAD4:
3469 case RPC_FC_STRUCTPAD5:
3470 case RPC_FC_STRUCTPAD6:
3471 case RPC_FC_STRUCTPAD7:
3472 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3474 case RPC_FC_EMBEDDED_COMPLEX:
3477 desc = pFormat + *(const SHORT*)pFormat;
3478 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3484 FIXME("unhandled format 0x%02x\n", *pFormat);
3492 ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
3494 PFORMAT_STRING desc;
3497 while (*pFormat != RPC_FC_END) {
3517 case RPC_FC_INT3264:
3518 case RPC_FC_UINT3264:
3519 size += sizeof(INT_PTR);
3529 case RPC_FC_POINTER:
3530 size += sizeof(void *);
3531 if (*pFormat != RPC_FC_POINTER)
3534 case RPC_FC_ALIGNM2:
3535 align_length(&size, 2);
3537 case RPC_FC_ALIGNM4:
3538 align_length(&size, 4);
3540 case RPC_FC_ALIGNM8:
3541 align_length(&size, 8);
3543 case RPC_FC_STRUCTPAD1:
3544 case RPC_FC_STRUCTPAD2:
3545 case RPC_FC_STRUCTPAD3:
3546 case RPC_FC_STRUCTPAD4:
3547 case RPC_FC_STRUCTPAD5:
3548 case RPC_FC_STRUCTPAD6:
3549 case RPC_FC_STRUCTPAD7:
3550 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3552 case RPC_FC_EMBEDDED_COMPLEX:
3555 desc = pFormat + *(const SHORT*)pFormat;
3556 size += EmbeddedComplexSize(pStubMsg, desc);
3562 FIXME("unhandled format 0x%02x\n", *pFormat);
3570 /***********************************************************************
3571 * NdrComplexStructMarshall [RPCRT4.@]
3573 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3574 unsigned char *pMemory,
3575 PFORMAT_STRING pFormat)
3577 PFORMAT_STRING conf_array = NULL;
3578 PFORMAT_STRING pointer_desc = NULL;
3579 unsigned char *OldMemory = pStubMsg->Memory;
3580 int pointer_buffer_mark_set = 0;
3582 ULONG max_count = 0;
3585 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3587 if (!pStubMsg->PointerBufferMark)
3589 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3590 /* save buffer length */
3591 ULONG saved_buffer_length = pStubMsg->BufferLength;
3593 /* get the buffer pointer after complex array data, but before
3595 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3596 pStubMsg->IgnoreEmbeddedPointers = 1;
3597 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3598 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3600 /* save it for use by embedded pointer code later */
3601 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3602 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - pStubMsg->Buffer));
3603 pointer_buffer_mark_set = 1;
3605 /* restore the original buffer length */
3606 pStubMsg->BufferLength = saved_buffer_length;
3609 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1);
3612 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3614 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3617 pStubMsg->Memory = pMemory;
3621 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3622 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3623 pMemory + struct_size, conf_array);
3624 /* these could be changed in ComplexMarshall so save them for later */
3625 max_count = pStubMsg->MaxCount;
3626 count = pStubMsg->ActualCount;
3627 offset = pStubMsg->Offset;
3630 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3634 pStubMsg->MaxCount = max_count;
3635 pStubMsg->ActualCount = count;
3636 pStubMsg->Offset = offset;
3637 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3638 conf_array, TRUE /* fHasPointers */);
3641 pStubMsg->Memory = OldMemory;
3643 if (pointer_buffer_mark_set)
3645 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3646 pStubMsg->PointerBufferMark = NULL;
3649 STD_OVERFLOW_CHECK(pStubMsg);
3654 /***********************************************************************
3655 * NdrComplexStructUnmarshall [RPCRT4.@]
3657 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3658 unsigned char **ppMemory,
3659 PFORMAT_STRING pFormat,
3660 unsigned char fMustAlloc)
3662 unsigned size = *(const WORD*)(pFormat+2);
3663 PFORMAT_STRING conf_array = NULL;
3664 PFORMAT_STRING pointer_desc = NULL;
3665 unsigned char *pMemory;
3666 int pointer_buffer_mark_set = 0;
3668 ULONG max_count = 0;
3670 ULONG array_size = 0;
3672 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3674 if (!pStubMsg->PointerBufferMark)
3676 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3677 /* save buffer pointer */
3678 unsigned char *saved_buffer = pStubMsg->Buffer;
3680 /* get the buffer pointer after complex array data, but before
3682 pStubMsg->IgnoreEmbeddedPointers = 1;
3683 NdrComplexStructMemorySize(pStubMsg, pFormat);
3684 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3686 /* save it for use by embedded pointer code later */
3687 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3688 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - saved_buffer));
3689 pointer_buffer_mark_set = 1;
3691 /* restore the original buffer */
3692 pStubMsg->Buffer = saved_buffer;
3695 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3698 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3700 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3705 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3708 /* these could be changed in ComplexMarshall so save them for later */
3709 max_count = pStubMsg->MaxCount;
3710 count = pStubMsg->ActualCount;
3711 offset = pStubMsg->Offset;
3714 if (!fMustAlloc && !*ppMemory)
3717 *ppMemory = NdrAllocate(pStubMsg, size);
3719 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3723 pStubMsg->MaxCount = max_count;
3724 pStubMsg->ActualCount = count;
3725 pStubMsg->Offset = offset;
3727 memset(pMemory, 0, array_size);
3728 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3730 FALSE /* fUseBufferMemoryServer */,
3731 TRUE /* fUnmarshall */);
3734 if (pointer_buffer_mark_set)
3736 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3737 pStubMsg->PointerBufferMark = NULL;
3743 /***********************************************************************
3744 * NdrComplexStructBufferSize [RPCRT4.@]
3746 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3747 unsigned char *pMemory,
3748 PFORMAT_STRING pFormat)
3750 PFORMAT_STRING conf_array = NULL;
3751 PFORMAT_STRING pointer_desc = NULL;
3752 unsigned char *OldMemory = pStubMsg->Memory;
3753 int pointer_length_set = 0;
3755 ULONG max_count = 0;
3758 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3760 align_length(&pStubMsg->BufferLength, pFormat[1] + 1);
3762 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3764 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3765 ULONG saved_buffer_length = pStubMsg->BufferLength;
3767 /* get the buffer length after complex struct data, but before
3769 pStubMsg->IgnoreEmbeddedPointers = 1;
3770 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3771 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3773 /* save it for use by embedded pointer code later */
3774 pStubMsg->PointerLength = pStubMsg->BufferLength;
3775 pointer_length_set = 1;
3776 TRACE("difference = 0x%x\n", pStubMsg->PointerLength - saved_buffer_length);
3778 /* restore the original buffer length */
3779 pStubMsg->BufferLength = saved_buffer_length;
3783 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3785 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3788 pStubMsg->Memory = pMemory;
3792 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3793 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3796 /* these could be changed in ComplexMarshall so save them for later */
3797 max_count = pStubMsg->MaxCount;
3798 count = pStubMsg->ActualCount;
3799 offset = pStubMsg->Offset;
3802 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3806 pStubMsg->MaxCount = max_count;
3807 pStubMsg->ActualCount = count;
3808 pStubMsg->Offset = offset;
3809 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3810 TRUE /* fHasPointers */);
3813 pStubMsg->Memory = OldMemory;
3815 if(pointer_length_set)
3817 pStubMsg->BufferLength = pStubMsg->PointerLength;
3818 pStubMsg->PointerLength = 0;
3823 /***********************************************************************
3824 * NdrComplexStructMemorySize [RPCRT4.@]
3826 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3827 PFORMAT_STRING pFormat)
3829 unsigned size = *(const WORD*)(pFormat+2);
3830 PFORMAT_STRING conf_array = NULL;
3831 PFORMAT_STRING pointer_desc = NULL;
3833 ULONG max_count = 0;
3836 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3838 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3841 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3843 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3848 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3850 /* these could be changed in ComplexStructMemorySize so save them for
3852 max_count = pStubMsg->MaxCount;
3853 count = pStubMsg->ActualCount;
3854 offset = pStubMsg->Offset;
3857 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3861 pStubMsg->MaxCount = max_count;
3862 pStubMsg->ActualCount = count;
3863 pStubMsg->Offset = offset;
3864 array_memory_size(conf_array[0], pStubMsg, conf_array,
3865 TRUE /* fHasPointers */);
3871 /***********************************************************************
3872 * NdrComplexStructFree [RPCRT4.@]
3874 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3875 unsigned char *pMemory,
3876 PFORMAT_STRING pFormat)
3878 PFORMAT_STRING conf_array = NULL;
3879 PFORMAT_STRING pointer_desc = NULL;
3880 unsigned char *OldMemory = pStubMsg->Memory;
3882 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3885 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3887 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3890 pStubMsg->Memory = pMemory;
3892 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3895 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3896 TRUE /* fHasPointers */);
3898 pStubMsg->Memory = OldMemory;
3901 /***********************************************************************
3902 * NdrConformantArrayMarshall [RPCRT4.@]
3904 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3905 unsigned char *pMemory,
3906 PFORMAT_STRING pFormat)
3908 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3909 if (pFormat[0] != RPC_FC_CARRAY)
3911 ERR("invalid format = 0x%x\n", pFormat[0]);
3912 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3915 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory,
3917 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3918 TRUE /* fHasPointers */);
3923 /***********************************************************************
3924 * NdrConformantArrayUnmarshall [RPCRT4.@]
3926 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3927 unsigned char **ppMemory,
3928 PFORMAT_STRING pFormat,
3929 unsigned char fMustAlloc)
3931 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3932 if (pFormat[0] != RPC_FC_CARRAY)
3934 ERR("invalid format = 0x%x\n", pFormat[0]);
3935 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3938 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3939 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat,
3941 TRUE /* fUseBufferMemoryServer */,
3942 TRUE /* fUnmarshall */);
3947 /***********************************************************************
3948 * NdrConformantArrayBufferSize [RPCRT4.@]
3950 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3951 unsigned char *pMemory,
3952 PFORMAT_STRING pFormat)
3954 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3955 if (pFormat[0] != RPC_FC_CARRAY)
3957 ERR("invalid format = 0x%x\n", pFormat[0]);
3958 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3961 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat);
3962 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3963 TRUE /* fHasPointers */);
3966 /***********************************************************************
3967 * NdrConformantArrayMemorySize [RPCRT4.@]
3969 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3970 PFORMAT_STRING pFormat)
3972 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3973 if (pFormat[0] != RPC_FC_CARRAY)
3975 ERR("invalid format = 0x%x\n", pFormat[0]);
3976 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3979 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3980 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
3982 return pStubMsg->MemorySize;
3985 /***********************************************************************
3986 * NdrConformantArrayFree [RPCRT4.@]
3988 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3989 unsigned char *pMemory,
3990 PFORMAT_STRING pFormat)
3992 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3993 if (pFormat[0] != RPC_FC_CARRAY)
3995 ERR("invalid format = 0x%x\n", pFormat[0]);
3996 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3999 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
4000 TRUE /* fHasPointers */);
4004 /***********************************************************************
4005 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
4007 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
4008 unsigned char* pMemory,
4009 PFORMAT_STRING pFormat )
4011 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4013 if (pFormat[0] != RPC_FC_CVARRAY)
4015 ERR("invalid format type %x\n", pFormat[0]);
4016 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4020 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
4022 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory,
4023 pFormat, TRUE /* fHasPointers */);
4029 /***********************************************************************
4030 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
4032 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
4033 unsigned char** ppMemory,
4034 PFORMAT_STRING pFormat,
4035 unsigned char fMustAlloc )
4037 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4039 if (pFormat[0] != RPC_FC_CVARRAY)
4041 ERR("invalid format type %x\n", pFormat[0]);
4042 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4046 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
4047 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory,
4048 pFormat, fMustAlloc,
4049 TRUE /* fUseBufferMemoryServer */,
4050 TRUE /* fUnmarshall */);
4056 /***********************************************************************
4057 * NdrConformantVaryingArrayFree [RPCRT4.@]
4059 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
4060 unsigned char* pMemory,
4061 PFORMAT_STRING pFormat )
4063 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4065 if (pFormat[0] != RPC_FC_CVARRAY)
4067 ERR("invalid format type %x\n", pFormat[0]);
4068 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4072 array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
4073 TRUE /* fHasPointers */);
4077 /***********************************************************************
4078 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
4080 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
4081 unsigned char* pMemory, PFORMAT_STRING pFormat )
4083 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4085 if (pFormat[0] != RPC_FC_CVARRAY)
4087 ERR("invalid format type %x\n", pFormat[0]);
4088 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4092 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
4094 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
4095 TRUE /* fHasPointers */);
4099 /***********************************************************************
4100 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
4102 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
4103 PFORMAT_STRING pFormat )
4105 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4107 if (pFormat[0] != RPC_FC_CVARRAY)
4109 ERR("invalid format type %x\n", pFormat[0]);
4110 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4111 return pStubMsg->MemorySize;
4114 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
4115 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat,
4116 TRUE /* fHasPointers */);
4118 return pStubMsg->MemorySize;
4122 /***********************************************************************
4123 * NdrComplexArrayMarshall [RPCRT4.@]
4125 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4126 unsigned char *pMemory,
4127 PFORMAT_STRING pFormat)
4129 int pointer_buffer_mark_set = 0;
4131 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4133 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4135 ERR("invalid format type %x\n", pFormat[0]);
4136 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4140 if (!pStubMsg->PointerBufferMark)
4142 /* save buffer fields that may be changed by buffer sizer functions
4143 * and that may be needed later on */
4144 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4145 ULONG saved_buffer_length = pStubMsg->BufferLength;
4146 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4147 ULONG saved_offset = pStubMsg->Offset;
4148 ULONG saved_actual_count = pStubMsg->ActualCount;
4150 /* get the buffer pointer after complex array data, but before
4152 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
4153 pStubMsg->IgnoreEmbeddedPointers = 1;
4154 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4155 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4157 /* save it for use by embedded pointer code later */
4158 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
4159 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer));
4160 pointer_buffer_mark_set = 1;
4162 /* restore fields */
4163 pStubMsg->ActualCount = saved_actual_count;
4164 pStubMsg->Offset = saved_offset;
4165 pStubMsg->MaxCount = saved_max_count;
4166 pStubMsg->BufferLength = saved_buffer_length;
4169 array_compute_and_write_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4170 array_write_variance_and_marshall(RPC_FC_BOGUS_ARRAY, pStubMsg,
4171 pMemory, pFormat, TRUE /* fHasPointers */);
4173 STD_OVERFLOW_CHECK(pStubMsg);
4175 if (pointer_buffer_mark_set)
4177 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4178 pStubMsg->PointerBufferMark = NULL;
4184 /***********************************************************************
4185 * NdrComplexArrayUnmarshall [RPCRT4.@]
4187 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4188 unsigned char **ppMemory,
4189 PFORMAT_STRING pFormat,
4190 unsigned char fMustAlloc)
4192 unsigned char *saved_buffer;
4193 int pointer_buffer_mark_set = 0;
4194 int saved_ignore_embedded;
4196 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4198 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4200 ERR("invalid format type %x\n", pFormat[0]);
4201 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4205 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4206 /* save buffer pointer */
4207 saved_buffer = pStubMsg->Buffer;
4208 /* get the buffer pointer after complex array data, but before
4210 pStubMsg->IgnoreEmbeddedPointers = 1;
4211 pStubMsg->MemorySize = 0;
4212 NdrComplexArrayMemorySize(pStubMsg, pFormat);
4213 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4215 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - saved_buffer));
4216 if (!pStubMsg->PointerBufferMark)
4218 /* save it for use by embedded pointer code later */
4219 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4220 pointer_buffer_mark_set = 1;
4222 /* restore the original buffer */
4223 pStubMsg->Buffer = saved_buffer;
4225 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
4226 array_read_variance_and_unmarshall(RPC_FC_BOGUS_ARRAY, pStubMsg, ppMemory, pFormat, fMustAlloc,
4227 TRUE /* fUseBufferMemoryServer */, TRUE /* fUnmarshall */);
4229 if (pointer_buffer_mark_set)
4231 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4232 pStubMsg->PointerBufferMark = NULL;
4238 /***********************************************************************
4239 * NdrComplexArrayBufferSize [RPCRT4.@]
4241 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4242 unsigned char *pMemory,
4243 PFORMAT_STRING pFormat)
4245 int pointer_length_set = 0;
4247 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4249 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4251 ERR("invalid format type %x\n", pFormat[0]);
4252 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4256 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
4258 /* save buffer fields that may be changed by buffer sizer functions
4259 * and that may be needed later on */
4260 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4261 ULONG saved_buffer_length = pStubMsg->BufferLength;
4262 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4263 ULONG saved_offset = pStubMsg->Offset;
4264 ULONG saved_actual_count = pStubMsg->ActualCount;
4266 /* get the buffer pointer after complex array data, but before
4268 pStubMsg->IgnoreEmbeddedPointers = 1;
4269 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4270 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4272 /* save it for use by embedded pointer code later */
4273 pStubMsg->PointerLength = pStubMsg->BufferLength;
4274 pointer_length_set = 1;
4276 /* restore fields */
4277 pStubMsg->ActualCount = saved_actual_count;
4278 pStubMsg->Offset = saved_offset;
4279 pStubMsg->MaxCount = saved_max_count;
4280 pStubMsg->BufferLength = saved_buffer_length;
4283 array_compute_and_size_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4284 array_buffer_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat, TRUE /* fHasPointers */);
4286 if(pointer_length_set)
4288 pStubMsg->BufferLength = pStubMsg->PointerLength;
4289 pStubMsg->PointerLength = 0;
4293 /***********************************************************************
4294 * NdrComplexArrayMemorySize [RPCRT4.@]
4296 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4297 PFORMAT_STRING pFormat)
4299 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4301 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4303 ERR("invalid format type %x\n", pFormat[0]);
4304 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4308 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
4309 array_memory_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
4310 return pStubMsg->MemorySize;
4313 /***********************************************************************
4314 * NdrComplexArrayFree [RPCRT4.@]
4316 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4317 unsigned char *pMemory,
4318 PFORMAT_STRING pFormat)
4320 ULONG i, count, def;
4322 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4324 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4326 ERR("invalid format type %x\n", pFormat[0]);
4327 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4331 def = *(const WORD*)&pFormat[2];
4334 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4335 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4337 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4338 TRACE("variance = %d\n", pStubMsg->ActualCount);
4340 count = pStubMsg->ActualCount;
4341 for (i = 0; i < count; i++)
4342 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4345 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4346 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4347 USER_MARSHAL_CB *umcb)
4349 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4350 pStubMsg->RpcMsg->DataRepresentation);
4351 umcb->pStubMsg = pStubMsg;
4352 umcb->pReserve = NULL;
4353 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4354 umcb->CBType = cbtype;
4355 umcb->pFormat = pFormat;
4356 umcb->pTypeFormat = NULL /* FIXME */;
4359 #define USER_MARSHAL_PTR_PREFIX \
4360 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4361 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4363 /***********************************************************************
4364 * NdrUserMarshalMarshall [RPCRT4.@]
4366 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4367 unsigned char *pMemory,
4368 PFORMAT_STRING pFormat)
4370 unsigned flags = pFormat[1];
4371 unsigned index = *(const WORD*)&pFormat[2];
4372 unsigned char *saved_buffer = NULL;
4373 USER_MARSHAL_CB umcb;
4375 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4376 TRACE("index=%d\n", index);
4378 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4380 if (flags & USER_MARSHAL_POINTER)
4382 align_pointer_clear(&pStubMsg->Buffer, 4);
4383 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4384 pStubMsg->Buffer += 4;
4385 if (pStubMsg->PointerBufferMark)
4387 saved_buffer = pStubMsg->Buffer;
4388 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4389 pStubMsg->PointerBufferMark = NULL;
4391 align_pointer_clear(&pStubMsg->Buffer, 8);
4394 align_pointer_clear(&pStubMsg->Buffer, (flags & 0xf) + 1);
4397 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4398 &umcb.Flags, pStubMsg->Buffer, pMemory);
4402 STD_OVERFLOW_CHECK(pStubMsg);
4403 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4404 pStubMsg->Buffer = saved_buffer;
4407 STD_OVERFLOW_CHECK(pStubMsg);
4412 /***********************************************************************
4413 * NdrUserMarshalUnmarshall [RPCRT4.@]
4415 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4416 unsigned char **ppMemory,
4417 PFORMAT_STRING pFormat,
4418 unsigned char fMustAlloc)
4420 unsigned flags = pFormat[1];
4421 unsigned index = *(const WORD*)&pFormat[2];
4422 DWORD memsize = *(const WORD*)&pFormat[4];
4423 unsigned char *saved_buffer = NULL;
4424 USER_MARSHAL_CB umcb;
4426 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4427 TRACE("index=%d\n", index);
4429 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4431 if (flags & USER_MARSHAL_POINTER)
4433 align_pointer(&pStubMsg->Buffer, 4);
4434 /* skip pointer prefix */
4435 pStubMsg->Buffer += 4;
4436 if (pStubMsg->PointerBufferMark)
4438 saved_buffer = pStubMsg->Buffer;
4439 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4440 pStubMsg->PointerBufferMark = NULL;
4442 align_pointer(&pStubMsg->Buffer, 8);
4445 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4447 if (!fMustAlloc && !*ppMemory)
4451 *ppMemory = NdrAllocate(pStubMsg, memsize);
4452 memset(*ppMemory, 0, memsize);
4456 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4457 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4461 STD_OVERFLOW_CHECK(pStubMsg);
4462 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4463 pStubMsg->Buffer = saved_buffer;
4469 /***********************************************************************
4470 * NdrUserMarshalBufferSize [RPCRT4.@]
4472 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4473 unsigned char *pMemory,
4474 PFORMAT_STRING pFormat)
4476 unsigned flags = pFormat[1];
4477 unsigned index = *(const WORD*)&pFormat[2];
4478 DWORD bufsize = *(const WORD*)&pFormat[6];
4479 USER_MARSHAL_CB umcb;
4480 ULONG saved_buffer_length = 0;
4482 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4483 TRACE("index=%d\n", index);
4485 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4487 if (flags & USER_MARSHAL_POINTER)
4489 align_length(&pStubMsg->BufferLength, 4);
4490 /* skip pointer prefix */
4491 safe_buffer_length_increment(pStubMsg, 4);
4492 if (pStubMsg->IgnoreEmbeddedPointers)
4494 if (pStubMsg->PointerLength)
4496 saved_buffer_length = pStubMsg->BufferLength;
4497 pStubMsg->BufferLength = pStubMsg->PointerLength;
4498 pStubMsg->PointerLength = 0;
4500 align_length(&pStubMsg->BufferLength, 8);
4503 align_length(&pStubMsg->BufferLength, (flags & 0xf) + 1);
4506 TRACE("size=%d\n", bufsize);
4507 safe_buffer_length_increment(pStubMsg, bufsize);
4510 pStubMsg->BufferLength =
4511 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4512 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4514 if (saved_buffer_length)
4516 pStubMsg->PointerLength = pStubMsg->BufferLength;
4517 pStubMsg->BufferLength = saved_buffer_length;
4522 /***********************************************************************
4523 * NdrUserMarshalMemorySize [RPCRT4.@]
4525 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4526 PFORMAT_STRING pFormat)
4528 unsigned flags = pFormat[1];
4529 unsigned index = *(const WORD*)&pFormat[2];
4530 DWORD memsize = *(const WORD*)&pFormat[4];
4531 DWORD bufsize = *(const WORD*)&pFormat[6];
4533 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4534 TRACE("index=%d\n", index);
4536 pStubMsg->MemorySize += memsize;
4538 if (flags & USER_MARSHAL_POINTER)
4540 align_pointer(&pStubMsg->Buffer, 4);
4541 /* skip pointer prefix */
4542 pStubMsg->Buffer += 4;
4543 if (pStubMsg->IgnoreEmbeddedPointers)
4544 return pStubMsg->MemorySize;
4545 align_pointer(&pStubMsg->Buffer, 8);
4548 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4551 FIXME("not implemented for varying buffer size\n");
4553 pStubMsg->Buffer += bufsize;
4555 return pStubMsg->MemorySize;
4558 /***********************************************************************
4559 * NdrUserMarshalFree [RPCRT4.@]
4561 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4562 unsigned char *pMemory,
4563 PFORMAT_STRING pFormat)
4565 /* unsigned flags = pFormat[1]; */
4566 unsigned index = *(const WORD*)&pFormat[2];
4567 USER_MARSHAL_CB umcb;
4569 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4570 TRACE("index=%d\n", index);
4572 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4574 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4575 &umcb.Flags, pMemory);
4578 /***********************************************************************
4579 * NdrGetUserMarshalInfo [RPCRT4.@]
4581 RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi)
4583 USER_MARSHAL_CB *umcb = CONTAINING_RECORD(flags, USER_MARSHAL_CB, Flags);
4585 TRACE("(%p,%u,%p)\n", flags, level, umi);
4588 return RPC_S_INVALID_ARG;
4590 memset(&umi->u1.Level1, 0, sizeof(umi->u1.Level1));
4591 umi->InformationLevel = level;
4593 if (umcb->Signature != USER_MARSHAL_CB_SIGNATURE)
4594 return RPC_S_INVALID_ARG;
4596 umi->u1.Level1.pfnAllocate = umcb->pStubMsg->pfnAllocate;
4597 umi->u1.Level1.pfnFree = umcb->pStubMsg->pfnFree;
4598 umi->u1.Level1.pRpcChannelBuffer = umcb->pStubMsg->pRpcChannelBuffer;
4600 switch (umcb->CBType)
4602 case USER_MARSHAL_CB_MARSHALL:
4603 case USER_MARSHAL_CB_UNMARSHALL:
4605 RPC_MESSAGE *msg = umcb->pStubMsg->RpcMsg;
4606 unsigned char *buffer_start = msg->Buffer;
4607 unsigned char *buffer_end =
4608 (unsigned char *)msg->Buffer + msg->BufferLength;
4610 if (umcb->pStubMsg->Buffer < buffer_start ||
4611 umcb->pStubMsg->Buffer > buffer_end)
4612 return ERROR_INVALID_USER_BUFFER;
4614 umi->u1.Level1.Buffer = umcb->pStubMsg->Buffer;
4615 umi->u1.Level1.BufferSize = buffer_end - umcb->pStubMsg->Buffer;
4618 case USER_MARSHAL_CB_BUFFER_SIZE:
4619 case USER_MARSHAL_CB_FREE:
4622 WARN("unrecognised CBType %d\n", umcb->CBType);
4628 /***********************************************************************
4629 * NdrClearOutParameters [RPCRT4.@]
4631 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4632 PFORMAT_STRING pFormat,
4635 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4638 /***********************************************************************
4639 * NdrConvert [RPCRT4.@]
4641 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4643 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4644 /* FIXME: since this stub doesn't do any converting, the proper behavior
4645 is to raise an exception */
4648 /***********************************************************************
4649 * NdrConvert2 [RPCRT4.@]
4651 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4653 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4654 pStubMsg, pFormat, NumberParams);
4655 /* FIXME: since this stub doesn't do any converting, the proper behavior
4656 is to raise an exception */
4659 #include "pshpack1.h"
4660 typedef struct _NDR_CSTRUCT_FORMAT
4663 unsigned char alignment;
4664 unsigned short memory_size;
4665 short offset_to_array_description;
4666 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4667 #include "poppack.h"
4669 /***********************************************************************
4670 * NdrConformantStructMarshall [RPCRT4.@]
4672 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4673 unsigned char *pMemory,
4674 PFORMAT_STRING pFormat)
4676 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4677 PFORMAT_STRING pCArrayFormat;
4678 ULONG esize, bufsize;
4680 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4682 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4683 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4685 ERR("invalid format type %x\n", pCStructFormat->type);
4686 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4690 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4691 pCStructFormat->offset_to_array_description;
4692 if (*pCArrayFormat != RPC_FC_CARRAY)
4694 ERR("invalid array format type %x\n", pCStructFormat->type);
4695 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4698 esize = *(const WORD*)(pCArrayFormat+2);
4700 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4701 pCArrayFormat + 4, 0);
4703 WriteConformance(pStubMsg);
4705 align_pointer_clear(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4707 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4709 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4710 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4712 ERR("integer overflow of memory_size %u with bufsize %u\n",
4713 pCStructFormat->memory_size, bufsize);
4714 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4716 /* copy constant sized part of struct */
4717 pStubMsg->BufferMark = pStubMsg->Buffer;
4718 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4720 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4721 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4726 /***********************************************************************
4727 * NdrConformantStructUnmarshall [RPCRT4.@]
4729 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4730 unsigned char **ppMemory,
4731 PFORMAT_STRING pFormat,
4732 unsigned char fMustAlloc)
4734 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4735 PFORMAT_STRING pCArrayFormat;
4736 ULONG esize, bufsize;
4737 unsigned char *saved_buffer;
4739 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4741 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4742 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4744 ERR("invalid format type %x\n", pCStructFormat->type);
4745 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4748 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4749 pCStructFormat->offset_to_array_description;
4750 if (*pCArrayFormat != RPC_FC_CARRAY)
4752 ERR("invalid array format type %x\n", pCStructFormat->type);
4753 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4756 esize = *(const WORD*)(pCArrayFormat+2);
4758 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4760 align_pointer(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4762 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4764 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4765 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4767 ERR("integer overflow of memory_size %u with bufsize %u\n",
4768 pCStructFormat->memory_size, bufsize);
4769 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4774 SIZE_T size = pCStructFormat->memory_size + bufsize;
4775 *ppMemory = NdrAllocate(pStubMsg, size);
4779 if (!pStubMsg->IsClient && !*ppMemory)
4780 /* for servers, we just point straight into the RPC buffer */
4781 *ppMemory = pStubMsg->Buffer;
4784 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4785 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4786 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4787 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4789 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4790 if (*ppMemory != saved_buffer)
4791 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4796 /***********************************************************************
4797 * NdrConformantStructBufferSize [RPCRT4.@]
4799 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4800 unsigned char *pMemory,
4801 PFORMAT_STRING pFormat)
4803 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4804 PFORMAT_STRING pCArrayFormat;
4807 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4809 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4810 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4812 ERR("invalid format type %x\n", pCStructFormat->type);
4813 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4816 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4817 pCStructFormat->offset_to_array_description;
4818 if (*pCArrayFormat != RPC_FC_CARRAY)
4820 ERR("invalid array format type %x\n", pCStructFormat->type);
4821 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4824 esize = *(const WORD*)(pCArrayFormat+2);
4826 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4827 SizeConformance(pStubMsg);
4829 align_length(&pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4831 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4833 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4834 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4836 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4837 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4840 /***********************************************************************
4841 * NdrConformantStructMemorySize [RPCRT4.@]
4843 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4844 PFORMAT_STRING pFormat)
4850 /***********************************************************************
4851 * NdrConformantStructFree [RPCRT4.@]
4853 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4854 unsigned char *pMemory,
4855 PFORMAT_STRING pFormat)
4857 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4858 PFORMAT_STRING pCArrayFormat;
4860 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4862 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4863 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4865 ERR("invalid format type %x\n", pCStructFormat->type);
4866 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4870 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4871 pCStructFormat->offset_to_array_description;
4872 if (*pCArrayFormat != RPC_FC_CARRAY)
4874 ERR("invalid array format type %x\n", pCStructFormat->type);
4875 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4879 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4880 pCArrayFormat + 4, 0);
4882 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4884 /* copy constant sized part of struct */
4885 pStubMsg->BufferMark = pStubMsg->Buffer;
4887 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4888 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4891 /***********************************************************************
4892 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4894 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4895 unsigned char *pMemory,
4896 PFORMAT_STRING pFormat)
4898 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4899 PFORMAT_STRING pCVArrayFormat;
4901 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4903 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4904 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4906 ERR("invalid format type %x\n", pCVStructFormat->type);
4907 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4911 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4912 pCVStructFormat->offset_to_array_description;
4914 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4915 pMemory + pCVStructFormat->memory_size,
4918 align_pointer_clear(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4920 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4922 /* write constant sized part */
4923 pStubMsg->BufferMark = pStubMsg->Buffer;
4924 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4926 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4927 pMemory + pCVStructFormat->memory_size,
4928 pCVArrayFormat, FALSE /* fHasPointers */);
4930 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4935 /***********************************************************************
4936 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4938 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4939 unsigned char **ppMemory,
4940 PFORMAT_STRING pFormat,
4941 unsigned char fMustAlloc)
4943 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4944 PFORMAT_STRING pCVArrayFormat;
4945 ULONG memsize, bufsize;
4946 unsigned char *saved_buffer, *saved_array_buffer;
4948 unsigned char *array_memory;
4950 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4952 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4953 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4955 ERR("invalid format type %x\n", pCVStructFormat->type);
4956 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4960 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4961 pCVStructFormat->offset_to_array_description;
4963 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4966 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4968 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4970 /* work out how much memory to allocate if we need to do so */
4971 if (!fMustAlloc && !*ppMemory)
4975 SIZE_T size = pCVStructFormat->memory_size + memsize;
4976 *ppMemory = NdrAllocate(pStubMsg, size);
4979 /* mark the start of the constant data */
4980 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4981 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4983 array_memory = *ppMemory + pCVStructFormat->memory_size;
4984 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
4985 &array_memory, pCVArrayFormat,
4986 FALSE /* fMustAlloc */,
4987 FALSE /* fUseServerBufferMemory */,
4988 FALSE /* fUnmarshall */);
4990 /* save offset in case unmarshalling pointers changes it */
4991 offset = pStubMsg->Offset;
4993 /* mark the start of the array data */
4994 saved_array_buffer = pStubMsg->Buffer;
4995 safe_buffer_increment(pStubMsg, bufsize);
4997 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4999 /* copy the constant data */
5000 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
5001 /* copy the array data */
5002 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
5003 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
5004 saved_array_buffer, bufsize);
5006 if (*pCVArrayFormat == RPC_FC_C_CSTRING)
5007 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
5008 else if (*pCVArrayFormat == RPC_FC_C_WSTRING)
5009 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
5014 /***********************************************************************
5015 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
5017 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5018 unsigned char *pMemory,
5019 PFORMAT_STRING pFormat)
5021 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5022 PFORMAT_STRING pCVArrayFormat;
5024 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5026 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5027 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5029 ERR("invalid format type %x\n", pCVStructFormat->type);
5030 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5034 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5035 pCVStructFormat->offset_to_array_description;
5036 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
5037 pMemory + pCVStructFormat->memory_size,
5040 align_length(&pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
5042 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5044 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
5046 array_buffer_size(*pCVArrayFormat, pStubMsg,
5047 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5048 FALSE /* fHasPointers */);
5050 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5053 /***********************************************************************
5054 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
5056 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5057 PFORMAT_STRING pFormat)
5059 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5060 PFORMAT_STRING pCVArrayFormat;
5062 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5064 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5065 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5067 ERR("invalid format type %x\n", pCVStructFormat->type);
5068 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5072 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5073 pCVStructFormat->offset_to_array_description;
5074 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
5076 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
5078 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5080 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
5081 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
5082 FALSE /* fHasPointers */);
5084 pStubMsg->MemorySize += pCVStructFormat->memory_size;
5086 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5088 return pStubMsg->MemorySize;
5091 /***********************************************************************
5092 * NdrConformantVaryingStructFree [RPCRT4.@]
5094 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
5095 unsigned char *pMemory,
5096 PFORMAT_STRING pFormat)
5098 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5099 PFORMAT_STRING pCVArrayFormat;
5101 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5103 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5104 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5106 ERR("invalid format type %x\n", pCVStructFormat->type);
5107 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5111 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5112 pCVStructFormat->offset_to_array_description;
5113 array_free(*pCVArrayFormat, pStubMsg,
5114 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5115 FALSE /* fHasPointers */);
5117 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5119 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5122 #include "pshpack1.h"
5126 unsigned char alignment;
5127 unsigned short total_size;
5128 } NDR_SMFARRAY_FORMAT;
5133 unsigned char alignment;
5135 } NDR_LGFARRAY_FORMAT;
5136 #include "poppack.h"
5138 /***********************************************************************
5139 * NdrFixedArrayMarshall [RPCRT4.@]
5141 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5142 unsigned char *pMemory,
5143 PFORMAT_STRING pFormat)
5145 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5148 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5150 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5151 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5153 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5154 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5158 align_pointer_clear(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5160 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5162 total_size = pSmFArrayFormat->total_size;
5163 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5167 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5168 total_size = pLgFArrayFormat->total_size;
5169 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5172 pStubMsg->BufferMark = pStubMsg->Buffer;
5173 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
5175 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5180 /***********************************************************************
5181 * NdrFixedArrayUnmarshall [RPCRT4.@]
5183 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5184 unsigned char **ppMemory,
5185 PFORMAT_STRING pFormat,
5186 unsigned char fMustAlloc)
5188 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5190 unsigned char *saved_buffer;
5192 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5194 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5195 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5197 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5198 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5202 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5204 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5206 total_size = pSmFArrayFormat->total_size;
5207 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5211 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5212 total_size = pLgFArrayFormat->total_size;
5213 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5217 *ppMemory = NdrAllocate(pStubMsg, total_size);
5220 if (!pStubMsg->IsClient && !*ppMemory)
5221 /* for servers, we just point straight into the RPC buffer */
5222 *ppMemory = pStubMsg->Buffer;
5225 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5226 safe_buffer_increment(pStubMsg, total_size);
5227 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5229 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
5230 if (*ppMemory != saved_buffer)
5231 memcpy(*ppMemory, saved_buffer, total_size);
5236 /***********************************************************************
5237 * NdrFixedArrayBufferSize [RPCRT4.@]
5239 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5240 unsigned char *pMemory,
5241 PFORMAT_STRING pFormat)
5243 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5246 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5248 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5249 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5251 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5252 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5256 align_length(&pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
5258 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5260 total_size = pSmFArrayFormat->total_size;
5261 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5265 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5266 total_size = pLgFArrayFormat->total_size;
5267 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5269 safe_buffer_length_increment(pStubMsg, total_size);
5271 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5274 /***********************************************************************
5275 * NdrFixedArrayMemorySize [RPCRT4.@]
5277 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5278 PFORMAT_STRING pFormat)
5280 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5283 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5285 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5286 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5288 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5289 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5293 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5295 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5297 total_size = pSmFArrayFormat->total_size;
5298 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5302 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5303 total_size = pLgFArrayFormat->total_size;
5304 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5306 pStubMsg->BufferMark = pStubMsg->Buffer;
5307 safe_buffer_increment(pStubMsg, total_size);
5308 pStubMsg->MemorySize += total_size;
5310 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5315 /***********************************************************************
5316 * NdrFixedArrayFree [RPCRT4.@]
5318 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5319 unsigned char *pMemory,
5320 PFORMAT_STRING pFormat)
5322 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5324 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5326 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5327 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5329 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5330 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5334 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5335 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5338 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5339 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5342 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5345 /***********************************************************************
5346 * NdrVaryingArrayMarshall [RPCRT4.@]
5348 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5349 unsigned char *pMemory,
5350 PFORMAT_STRING pFormat)
5352 unsigned char alignment;
5353 DWORD elements, esize;
5356 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5358 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5359 (pFormat[0] != RPC_FC_LGVARRAY))
5361 ERR("invalid format type %x\n", pFormat[0]);
5362 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5366 alignment = pFormat[1] + 1;
5368 if (pFormat[0] == RPC_FC_SMVARRAY)
5371 pFormat += sizeof(WORD);
5372 elements = *(const WORD*)pFormat;
5373 pFormat += sizeof(WORD);
5378 pFormat += sizeof(DWORD);
5379 elements = *(const DWORD*)pFormat;
5380 pFormat += sizeof(DWORD);
5383 esize = *(const WORD*)pFormat;
5384 pFormat += sizeof(WORD);
5386 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5387 if ((pStubMsg->ActualCount > elements) ||
5388 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5390 RpcRaiseException(RPC_S_INVALID_BOUND);
5394 WriteVariance(pStubMsg);
5396 align_pointer_clear(&pStubMsg->Buffer, alignment);
5398 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5399 pStubMsg->BufferMark = pStubMsg->Buffer;
5400 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5402 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5407 /***********************************************************************
5408 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5410 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5411 unsigned char **ppMemory,
5412 PFORMAT_STRING pFormat,
5413 unsigned char fMustAlloc)
5415 unsigned char alignment;
5416 DWORD size, elements, esize;
5418 unsigned char *saved_buffer;
5421 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5423 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5424 (pFormat[0] != RPC_FC_LGVARRAY))
5426 ERR("invalid format type %x\n", pFormat[0]);
5427 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5431 alignment = pFormat[1] + 1;
5433 if (pFormat[0] == RPC_FC_SMVARRAY)
5436 size = *(const WORD*)pFormat;
5437 pFormat += sizeof(WORD);
5438 elements = *(const WORD*)pFormat;
5439 pFormat += sizeof(WORD);
5444 size = *(const DWORD*)pFormat;
5445 pFormat += sizeof(DWORD);
5446 elements = *(const DWORD*)pFormat;
5447 pFormat += sizeof(DWORD);
5450 esize = *(const WORD*)pFormat;
5451 pFormat += sizeof(WORD);
5453 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5455 align_pointer(&pStubMsg->Buffer, alignment);
5457 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5458 offset = pStubMsg->Offset;
5460 if (!fMustAlloc && !*ppMemory)
5463 *ppMemory = NdrAllocate(pStubMsg, size);
5464 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5465 safe_buffer_increment(pStubMsg, bufsize);
5467 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5469 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5474 /***********************************************************************
5475 * NdrVaryingArrayBufferSize [RPCRT4.@]
5477 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5478 unsigned char *pMemory,
5479 PFORMAT_STRING pFormat)
5481 unsigned char alignment;
5482 DWORD elements, esize;
5484 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5486 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5487 (pFormat[0] != RPC_FC_LGVARRAY))
5489 ERR("invalid format type %x\n", pFormat[0]);
5490 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5494 alignment = pFormat[1] + 1;
5496 if (pFormat[0] == RPC_FC_SMVARRAY)
5499 pFormat += sizeof(WORD);
5500 elements = *(const WORD*)pFormat;
5501 pFormat += sizeof(WORD);
5506 pFormat += sizeof(DWORD);
5507 elements = *(const DWORD*)pFormat;
5508 pFormat += sizeof(DWORD);
5511 esize = *(const WORD*)pFormat;
5512 pFormat += sizeof(WORD);
5514 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5515 if ((pStubMsg->ActualCount > elements) ||
5516 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5518 RpcRaiseException(RPC_S_INVALID_BOUND);
5522 SizeVariance(pStubMsg);
5524 align_length(&pStubMsg->BufferLength, alignment);
5526 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5528 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5531 /***********************************************************************
5532 * NdrVaryingArrayMemorySize [RPCRT4.@]
5534 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5535 PFORMAT_STRING pFormat)
5537 unsigned char alignment;
5538 DWORD size, elements, esize;
5540 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5542 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5543 (pFormat[0] != RPC_FC_LGVARRAY))
5545 ERR("invalid format type %x\n", pFormat[0]);
5546 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5550 alignment = pFormat[1] + 1;
5552 if (pFormat[0] == RPC_FC_SMVARRAY)
5555 size = *(const WORD*)pFormat;
5556 pFormat += sizeof(WORD);
5557 elements = *(const WORD*)pFormat;
5558 pFormat += sizeof(WORD);
5563 size = *(const DWORD*)pFormat;
5564 pFormat += sizeof(DWORD);
5565 elements = *(const DWORD*)pFormat;
5566 pFormat += sizeof(DWORD);
5569 esize = *(const WORD*)pFormat;
5570 pFormat += sizeof(WORD);
5572 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5574 align_pointer(&pStubMsg->Buffer, alignment);
5576 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5577 pStubMsg->MemorySize += size;
5579 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5581 return pStubMsg->MemorySize;
5584 /***********************************************************************
5585 * NdrVaryingArrayFree [RPCRT4.@]
5587 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5588 unsigned char *pMemory,
5589 PFORMAT_STRING pFormat)
5593 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5595 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5596 (pFormat[0] != RPC_FC_LGVARRAY))
5598 ERR("invalid format type %x\n", pFormat[0]);
5599 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5603 if (pFormat[0] == RPC_FC_SMVARRAY)
5606 pFormat += sizeof(WORD);
5607 elements = *(const WORD*)pFormat;
5608 pFormat += sizeof(WORD);
5613 pFormat += sizeof(DWORD);
5614 elements = *(const DWORD*)pFormat;
5615 pFormat += sizeof(DWORD);
5618 pFormat += sizeof(WORD);
5620 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5621 if ((pStubMsg->ActualCount > elements) ||
5622 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5624 RpcRaiseException(RPC_S_INVALID_BOUND);
5628 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5631 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5644 return *(const USHORT *)pMemory;
5648 return *(const ULONG *)pMemory;
5649 case RPC_FC_INT3264:
5650 case RPC_FC_UINT3264:
5651 return *(const ULONG_PTR *)pMemory;
5653 FIXME("Unhandled base type: 0x%02x\n", fc);
5658 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5660 PFORMAT_STRING pFormat)
5662 unsigned short num_arms, arm, type;
5664 num_arms = *(const SHORT*)pFormat & 0x0fff;
5666 for(arm = 0; arm < num_arms; arm++)
5668 if(discriminant == *(const ULONG*)pFormat)
5676 type = *(const unsigned short*)pFormat;
5677 TRACE("type %04x\n", type);
5678 if(arm == num_arms) /* default arm extras */
5682 ERR("no arm for 0x%x and no default case\n", discriminant);
5683 RpcRaiseException(RPC_S_INVALID_TAG);
5688 TRACE("falling back to empty default case for 0x%x\n", discriminant);
5695 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5697 unsigned short type;
5701 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5705 type = *(const unsigned short*)pFormat;
5706 if((type & 0xff00) == 0x8000)
5708 unsigned char basetype = LOBYTE(type);
5709 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5713 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5714 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5717 unsigned char *saved_buffer = NULL;
5718 int pointer_buffer_mark_set = 0;
5725 align_pointer_clear(&pStubMsg->Buffer, 4);
5726 saved_buffer = pStubMsg->Buffer;
5727 if (pStubMsg->PointerBufferMark)
5729 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5730 pStubMsg->PointerBufferMark = NULL;
5731 pointer_buffer_mark_set = 1;
5734 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5736 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5737 if (pointer_buffer_mark_set)
5739 STD_OVERFLOW_CHECK(pStubMsg);
5740 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5741 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5743 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5744 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5745 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5747 pStubMsg->Buffer = saved_buffer + 4;
5751 m(pStubMsg, pMemory, desc);
5754 else FIXME("no marshaller for embedded type %02x\n", *desc);
5759 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5760 unsigned char **ppMemory,
5762 PFORMAT_STRING pFormat,
5763 unsigned char fMustAlloc)
5765 unsigned short type;
5769 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5773 type = *(const unsigned short*)pFormat;
5774 if((type & 0xff00) == 0x8000)
5776 unsigned char basetype = LOBYTE(type);
5777 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5781 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5782 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5785 unsigned char *saved_buffer = NULL;
5786 int pointer_buffer_mark_set = 0;
5793 align_pointer(&pStubMsg->Buffer, 4);
5794 saved_buffer = pStubMsg->Buffer;
5795 if (pStubMsg->PointerBufferMark)
5797 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5798 pStubMsg->PointerBufferMark = NULL;
5799 pointer_buffer_mark_set = 1;
5802 pStubMsg->Buffer += 4; /* for pointer ID */
5804 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5806 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5807 saved_buffer, pStubMsg->BufferEnd);
5808 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5811 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5812 if (pointer_buffer_mark_set)
5814 STD_OVERFLOW_CHECK(pStubMsg);
5815 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5816 pStubMsg->Buffer = saved_buffer + 4;
5820 m(pStubMsg, ppMemory, desc, fMustAlloc);
5823 else FIXME("no marshaller for embedded type %02x\n", *desc);
5828 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5829 unsigned char *pMemory,
5831 PFORMAT_STRING pFormat)
5833 unsigned short type;
5837 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5841 type = *(const unsigned short*)pFormat;
5842 if((type & 0xff00) == 0x8000)
5844 unsigned char basetype = LOBYTE(type);
5845 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5849 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5850 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5859 align_length(&pStubMsg->BufferLength, 4);
5860 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5861 if (!pStubMsg->IgnoreEmbeddedPointers)
5863 int saved_buffer_length = pStubMsg->BufferLength;
5864 pStubMsg->BufferLength = pStubMsg->PointerLength;
5865 pStubMsg->PointerLength = 0;
5866 if(!pStubMsg->BufferLength)
5867 ERR("BufferLength == 0??\n");
5868 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5869 pStubMsg->PointerLength = pStubMsg->BufferLength;
5870 pStubMsg->BufferLength = saved_buffer_length;
5874 m(pStubMsg, pMemory, desc);
5877 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5881 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5883 PFORMAT_STRING pFormat)
5885 unsigned short type, size;
5887 size = *(const unsigned short*)pFormat;
5888 pStubMsg->Memory += size;
5891 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5895 type = *(const unsigned short*)pFormat;
5896 if((type & 0xff00) == 0x8000)
5898 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5902 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5903 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5904 unsigned char *saved_buffer;
5913 align_pointer(&pStubMsg->Buffer, 4);
5914 saved_buffer = pStubMsg->Buffer;
5915 safe_buffer_increment(pStubMsg, 4);
5916 align_length(&pStubMsg->MemorySize, sizeof(void *));
5917 pStubMsg->MemorySize += sizeof(void *);
5918 if (!pStubMsg->IgnoreEmbeddedPointers)
5919 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5922 return m(pStubMsg, desc);
5925 else FIXME("no marshaller for embedded type %02x\n", *desc);
5928 TRACE("size %d\n", size);
5932 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5933 unsigned char *pMemory,
5935 PFORMAT_STRING pFormat)
5937 unsigned short type;
5941 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5945 type = *(const unsigned short*)pFormat;
5946 if((type & 0xff00) != 0x8000)
5948 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5949 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5958 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5961 m(pStubMsg, pMemory, desc);
5967 /***********************************************************************
5968 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5970 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5971 unsigned char *pMemory,
5972 PFORMAT_STRING pFormat)
5974 unsigned char switch_type;
5975 unsigned char increment;
5978 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5981 switch_type = *pFormat & 0xf;
5982 increment = (*pFormat & 0xf0) >> 4;
5985 align_pointer_clear(&pStubMsg->Buffer, increment);
5987 switch_value = get_discriminant(switch_type, pMemory);
5988 TRACE("got switch value 0x%x\n", switch_value);
5990 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5991 pMemory += increment;
5993 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5996 /***********************************************************************
5997 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5999 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6000 unsigned char **ppMemory,
6001 PFORMAT_STRING pFormat,
6002 unsigned char fMustAlloc)
6004 unsigned char switch_type;
6005 unsigned char increment;
6007 unsigned short size;
6008 unsigned char *pMemoryArm;
6010 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6013 switch_type = *pFormat & 0xf;
6014 increment = (*pFormat & 0xf0) >> 4;
6017 align_pointer(&pStubMsg->Buffer, increment);
6018 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6019 TRACE("got switch value 0x%x\n", switch_value);
6021 size = *(const unsigned short*)pFormat + increment;
6022 if (!fMustAlloc && !*ppMemory)
6025 *ppMemory = NdrAllocate(pStubMsg, size);
6027 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6028 * since the arm is part of the memory block that is encompassed by
6029 * the whole union. Memory is forced to allocate when pointers
6030 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6031 * clearing the memory we pass in to the unmarshaller */
6033 memset(*ppMemory, 0, size);
6035 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
6036 pMemoryArm = *ppMemory + increment;
6038 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, FALSE);
6041 /***********************************************************************
6042 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
6044 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6045 unsigned char *pMemory,
6046 PFORMAT_STRING pFormat)
6048 unsigned char switch_type;
6049 unsigned char increment;
6052 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6055 switch_type = *pFormat & 0xf;
6056 increment = (*pFormat & 0xf0) >> 4;
6059 align_length(&pStubMsg->BufferLength, increment);
6060 switch_value = get_discriminant(switch_type, pMemory);
6061 TRACE("got switch value 0x%x\n", switch_value);
6063 /* Add discriminant size */
6064 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
6065 pMemory += increment;
6067 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
6070 /***********************************************************************
6071 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
6073 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6074 PFORMAT_STRING pFormat)
6076 unsigned char switch_type;
6077 unsigned char increment;
6080 switch_type = *pFormat & 0xf;
6081 increment = (*pFormat & 0xf0) >> 4;
6084 align_pointer(&pStubMsg->Buffer, increment);
6085 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6086 TRACE("got switch value 0x%x\n", switch_value);
6088 pStubMsg->Memory += increment;
6090 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
6093 /***********************************************************************
6094 * NdrEncapsulatedUnionFree [RPCRT4.@]
6096 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6097 unsigned char *pMemory,
6098 PFORMAT_STRING pFormat)
6100 unsigned char switch_type;
6101 unsigned char increment;
6104 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6107 switch_type = *pFormat & 0xf;
6108 increment = (*pFormat & 0xf0) >> 4;
6111 switch_value = get_discriminant(switch_type, pMemory);
6112 TRACE("got switch value 0x%x\n", switch_value);
6114 pMemory += increment;
6116 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
6119 /***********************************************************************
6120 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
6122 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6123 unsigned char *pMemory,
6124 PFORMAT_STRING pFormat)
6126 unsigned char switch_type;
6128 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6131 switch_type = *pFormat;
6134 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6135 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6136 /* Marshall discriminant */
6137 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6139 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6142 static LONG unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
6143 PFORMAT_STRING *ppFormat)
6145 LONG discriminant = 0;
6155 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6165 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6166 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6174 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6175 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6180 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
6184 if (pStubMsg->fHasNewCorrDesc)
6188 return discriminant;
6191 /**********************************************************************
6192 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6194 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6195 unsigned char **ppMemory,
6196 PFORMAT_STRING pFormat,
6197 unsigned char fMustAlloc)
6200 unsigned short size;
6202 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6205 /* Unmarshall discriminant */
6206 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6207 TRACE("unmarshalled discriminant %x\n", discriminant);
6209 pFormat += *(const SHORT*)pFormat;
6211 size = *(const unsigned short*)pFormat;
6213 if (!fMustAlloc && !*ppMemory)
6216 *ppMemory = NdrAllocate(pStubMsg, size);
6218 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6219 * since the arm is part of the memory block that is encompassed by
6220 * the whole union. Memory is forced to allocate when pointers
6221 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6222 * clearing the memory we pass in to the unmarshaller */
6224 memset(*ppMemory, 0, size);
6226 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, FALSE);
6229 /***********************************************************************
6230 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6232 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6233 unsigned char *pMemory,
6234 PFORMAT_STRING pFormat)
6236 unsigned char switch_type;
6238 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6241 switch_type = *pFormat;
6244 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6245 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6246 /* Add discriminant size */
6247 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6249 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6252 /***********************************************************************
6253 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6255 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6256 PFORMAT_STRING pFormat)
6261 /* Unmarshall discriminant */
6262 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6263 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
6265 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
6268 /***********************************************************************
6269 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6271 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6272 unsigned char *pMemory,
6273 PFORMAT_STRING pFormat)
6275 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6279 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6280 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6282 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6285 /***********************************************************************
6286 * NdrByteCountPointerMarshall [RPCRT4.@]
6288 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6289 unsigned char *pMemory,
6290 PFORMAT_STRING pFormat)
6296 /***********************************************************************
6297 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6299 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6300 unsigned char **ppMemory,
6301 PFORMAT_STRING pFormat,
6302 unsigned char fMustAlloc)
6308 /***********************************************************************
6309 * NdrByteCountPointerBufferSize [RPCRT4.@]
6311 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6312 unsigned char *pMemory,
6313 PFORMAT_STRING pFormat)
6318 /***********************************************************************
6319 * NdrByteCountPointerMemorySize [internal]
6321 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6322 PFORMAT_STRING pFormat)
6328 /***********************************************************************
6329 * NdrByteCountPointerFree [RPCRT4.@]
6331 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6332 unsigned char *pMemory,
6333 PFORMAT_STRING pFormat)
6338 /***********************************************************************
6339 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6341 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6342 unsigned char *pMemory,
6343 PFORMAT_STRING pFormat)
6349 /***********************************************************************
6350 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6352 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6353 unsigned char **ppMemory,
6354 PFORMAT_STRING pFormat,
6355 unsigned char fMustAlloc)
6361 /***********************************************************************
6362 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6364 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6365 unsigned char *pMemory,
6366 PFORMAT_STRING pFormat)
6371 /***********************************************************************
6372 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6374 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6375 PFORMAT_STRING pFormat)
6381 /***********************************************************************
6382 * NdrXmitOrRepAsFree [RPCRT4.@]
6384 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6385 unsigned char *pMemory,
6386 PFORMAT_STRING pFormat)
6391 /***********************************************************************
6392 * NdrRangeMarshall [internal]
6394 static unsigned char *WINAPI NdrRangeMarshall(
6395 PMIDL_STUB_MESSAGE pStubMsg,
6396 unsigned char *pMemory,
6397 PFORMAT_STRING pFormat)
6399 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6400 unsigned char base_type;
6402 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6404 if (pRange->type != RPC_FC_RANGE)
6406 ERR("invalid format type %x\n", pRange->type);
6407 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6411 base_type = pRange->flags_type & 0xf;
6413 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6416 /***********************************************************************
6417 * NdrRangeUnmarshall [RPCRT4.@]
6419 unsigned char *WINAPI NdrRangeUnmarshall(
6420 PMIDL_STUB_MESSAGE pStubMsg,
6421 unsigned char **ppMemory,
6422 PFORMAT_STRING pFormat,
6423 unsigned char fMustAlloc)
6425 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6426 unsigned char base_type;
6428 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6430 if (pRange->type != RPC_FC_RANGE)
6432 ERR("invalid format type %x\n", pRange->type);
6433 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6436 base_type = pRange->flags_type & 0xf;
6438 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6439 base_type, pRange->low_value, pRange->high_value);
6441 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6444 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \
6445 if (!fMustAlloc && !*ppMemory) \
6446 fMustAlloc = TRUE; \
6448 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6449 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6451 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6452 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6453 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6455 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6456 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6458 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6459 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6460 (mem_type)pRange->high_value); \
6461 RpcRaiseException(RPC_S_INVALID_BOUND); \
6464 TRACE("*ppMemory: %p\n", *ppMemory); \
6465 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6466 pStubMsg->Buffer += sizeof(wire_type); \
6473 RANGE_UNMARSHALL(UCHAR, UCHAR, "%d");
6474 TRACE("value: 0x%02x\n", **ppMemory);
6478 RANGE_UNMARSHALL(CHAR, CHAR, "%u");
6479 TRACE("value: 0x%02x\n", **ppMemory);
6481 case RPC_FC_WCHAR: /* FIXME: valid? */
6483 RANGE_UNMARSHALL(USHORT, USHORT, "%u");
6484 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6487 RANGE_UNMARSHALL(SHORT, SHORT, "%d");
6488 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6492 RANGE_UNMARSHALL(LONG, LONG, "%d");
6493 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6496 RANGE_UNMARSHALL(ULONG, ULONG, "%u");
6497 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6500 RANGE_UNMARSHALL(UINT, USHORT, "%u");
6501 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6507 ERR("invalid range base type: 0x%02x\n", base_type);
6508 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6514 /***********************************************************************
6515 * NdrRangeBufferSize [internal]
6517 static void WINAPI NdrRangeBufferSize(
6518 PMIDL_STUB_MESSAGE pStubMsg,
6519 unsigned char *pMemory,
6520 PFORMAT_STRING pFormat)
6522 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6523 unsigned char base_type;
6525 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6527 if (pRange->type != RPC_FC_RANGE)
6529 ERR("invalid format type %x\n", pRange->type);
6530 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6532 base_type = pRange->flags_type & 0xf;
6534 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6537 /***********************************************************************
6538 * NdrRangeMemorySize [internal]
6540 static ULONG WINAPI NdrRangeMemorySize(
6541 PMIDL_STUB_MESSAGE pStubMsg,
6542 PFORMAT_STRING pFormat)
6544 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6545 unsigned char base_type;
6547 if (pRange->type != RPC_FC_RANGE)
6549 ERR("invalid format type %x\n", pRange->type);
6550 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6553 base_type = pRange->flags_type & 0xf;
6555 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6558 /***********************************************************************
6559 * NdrRangeFree [internal]
6561 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6562 unsigned char *pMemory,
6563 PFORMAT_STRING pFormat)
6565 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6570 /***********************************************************************
6571 * NdrBaseTypeMarshall [internal]
6573 static unsigned char *WINAPI NdrBaseTypeMarshall(
6574 PMIDL_STUB_MESSAGE pStubMsg,
6575 unsigned char *pMemory,
6576 PFORMAT_STRING pFormat)
6578 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6586 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6587 TRACE("value: 0x%02x\n", *pMemory);
6592 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6593 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6594 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6598 case RPC_FC_ERROR_STATUS_T:
6600 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONG));
6601 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6602 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6605 align_pointer_clear(&pStubMsg->Buffer, sizeof(float));
6606 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6609 align_pointer_clear(&pStubMsg->Buffer, sizeof(double));
6610 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6613 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONGLONG));
6614 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6615 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6619 USHORT val = *(UINT *)pMemory;
6620 /* only 16-bits on the wire, so do a sanity check */
6621 if (*(UINT *)pMemory > SHRT_MAX)
6622 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6623 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6624 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6625 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6628 case RPC_FC_INT3264:
6629 case RPC_FC_UINT3264:
6631 UINT val = *(UINT_PTR *)pMemory;
6632 align_pointer_clear(&pStubMsg->Buffer, sizeof(UINT));
6633 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6639 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6642 /* FIXME: what is the correct return value? */
6646 /***********************************************************************
6647 * NdrBaseTypeUnmarshall [internal]
6649 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6650 PMIDL_STUB_MESSAGE pStubMsg,
6651 unsigned char **ppMemory,
6652 PFORMAT_STRING pFormat,
6653 unsigned char fMustAlloc)
6655 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6657 #define BASE_TYPE_UNMARSHALL(type) do { \
6658 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
6659 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6661 *ppMemory = pStubMsg->Buffer; \
6662 TRACE("*ppMemory: %p\n", *ppMemory); \
6663 safe_buffer_increment(pStubMsg, sizeof(type)); \
6668 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6669 TRACE("*ppMemory: %p\n", *ppMemory); \
6670 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6680 BASE_TYPE_UNMARSHALL(UCHAR);
6681 TRACE("value: 0x%02x\n", **ppMemory);
6686 BASE_TYPE_UNMARSHALL(USHORT);
6687 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6691 case RPC_FC_ERROR_STATUS_T:
6693 BASE_TYPE_UNMARSHALL(ULONG);
6694 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6697 BASE_TYPE_UNMARSHALL(float);
6698 TRACE("value: %f\n", **(float **)ppMemory);
6701 BASE_TYPE_UNMARSHALL(double);
6702 TRACE("value: %f\n", **(double **)ppMemory);
6705 BASE_TYPE_UNMARSHALL(ULONGLONG);
6706 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6711 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6712 if (!fMustAlloc && !*ppMemory)
6715 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6716 safe_copy_from_buffer(pStubMsg, &val, sizeof(USHORT));
6717 /* 16-bits on the wire, but int in memory */
6718 **(UINT **)ppMemory = val;
6719 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6722 case RPC_FC_INT3264:
6723 if (sizeof(INT_PTR) == sizeof(INT)) BASE_TYPE_UNMARSHALL(INT);
6727 align_pointer(&pStubMsg->Buffer, sizeof(INT));
6728 if (!fMustAlloc && !*ppMemory)
6731 *ppMemory = NdrAllocate(pStubMsg, sizeof(INT_PTR));
6732 safe_copy_from_buffer(pStubMsg, &val, sizeof(INT));
6733 **(INT_PTR **)ppMemory = val;
6734 TRACE("value: 0x%08lx\n", **(INT_PTR **)ppMemory);
6737 case RPC_FC_UINT3264:
6738 if (sizeof(UINT_PTR) == sizeof(UINT)) BASE_TYPE_UNMARSHALL(UINT);
6742 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6743 if (!fMustAlloc && !*ppMemory)
6746 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT_PTR));
6747 safe_copy_from_buffer(pStubMsg, &val, sizeof(UINT));
6748 **(UINT_PTR **)ppMemory = val;
6749 TRACE("value: 0x%08lx\n", **(UINT_PTR **)ppMemory);
6755 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6757 #undef BASE_TYPE_UNMARSHALL
6759 /* FIXME: what is the correct return value? */
6764 /***********************************************************************
6765 * NdrBaseTypeBufferSize [internal]
6767 static void WINAPI NdrBaseTypeBufferSize(
6768 PMIDL_STUB_MESSAGE pStubMsg,
6769 unsigned char *pMemory,
6770 PFORMAT_STRING pFormat)
6772 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6780 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6786 align_length(&pStubMsg->BufferLength, sizeof(USHORT));
6787 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6792 case RPC_FC_INT3264:
6793 case RPC_FC_UINT3264:
6794 align_length(&pStubMsg->BufferLength, sizeof(ULONG));
6795 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6798 align_length(&pStubMsg->BufferLength, sizeof(float));
6799 safe_buffer_length_increment(pStubMsg, sizeof(float));
6802 align_length(&pStubMsg->BufferLength, sizeof(double));
6803 safe_buffer_length_increment(pStubMsg, sizeof(double));
6806 align_length(&pStubMsg->BufferLength, sizeof(ULONGLONG));
6807 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6809 case RPC_FC_ERROR_STATUS_T:
6810 align_length(&pStubMsg->BufferLength, sizeof(error_status_t));
6811 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6816 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6820 /***********************************************************************
6821 * NdrBaseTypeMemorySize [internal]
6823 static ULONG WINAPI NdrBaseTypeMemorySize(
6824 PMIDL_STUB_MESSAGE pStubMsg,
6825 PFORMAT_STRING pFormat)
6827 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6835 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6836 pStubMsg->MemorySize += sizeof(UCHAR);
6837 return sizeof(UCHAR);
6841 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6842 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6843 align_length(&pStubMsg->MemorySize, sizeof(USHORT));
6844 pStubMsg->MemorySize += sizeof(USHORT);
6845 return sizeof(USHORT);
6849 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6850 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6851 align_length(&pStubMsg->MemorySize, sizeof(ULONG));
6852 pStubMsg->MemorySize += sizeof(ULONG);
6853 return sizeof(ULONG);
6855 align_pointer(&pStubMsg->Buffer, sizeof(float));
6856 safe_buffer_increment(pStubMsg, sizeof(float));
6857 align_length(&pStubMsg->MemorySize, sizeof(float));
6858 pStubMsg->MemorySize += sizeof(float);
6859 return sizeof(float);
6861 align_pointer(&pStubMsg->Buffer, sizeof(double));
6862 safe_buffer_increment(pStubMsg, sizeof(double));
6863 align_length(&pStubMsg->MemorySize, sizeof(double));
6864 pStubMsg->MemorySize += sizeof(double);
6865 return sizeof(double);
6867 align_pointer(&pStubMsg->Buffer, sizeof(ULONGLONG));
6868 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6869 align_length(&pStubMsg->MemorySize, sizeof(ULONGLONG));
6870 pStubMsg->MemorySize += sizeof(ULONGLONG);
6871 return sizeof(ULONGLONG);
6872 case RPC_FC_ERROR_STATUS_T:
6873 align_pointer(&pStubMsg->Buffer, sizeof(error_status_t));
6874 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6875 align_length(&pStubMsg->MemorySize, sizeof(error_status_t));
6876 pStubMsg->MemorySize += sizeof(error_status_t);
6877 return sizeof(error_status_t);
6879 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6880 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6881 align_length(&pStubMsg->MemorySize, sizeof(UINT));
6882 pStubMsg->MemorySize += sizeof(UINT);
6883 return sizeof(UINT);
6884 case RPC_FC_INT3264:
6885 case RPC_FC_UINT3264:
6886 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6887 safe_buffer_increment(pStubMsg, sizeof(UINT));
6888 align_length(&pStubMsg->MemorySize, sizeof(UINT_PTR));
6889 pStubMsg->MemorySize += sizeof(UINT_PTR);
6890 return sizeof(UINT_PTR);
6892 align_length(&pStubMsg->MemorySize, sizeof(void *));
6893 pStubMsg->MemorySize += sizeof(void *);
6894 return sizeof(void *);
6896 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6901 /***********************************************************************
6902 * NdrBaseTypeFree [internal]
6904 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6905 unsigned char *pMemory,
6906 PFORMAT_STRING pFormat)
6908 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6913 /***********************************************************************
6914 * NdrContextHandleBufferSize [internal]
6916 static void WINAPI NdrContextHandleBufferSize(
6917 PMIDL_STUB_MESSAGE pStubMsg,
6918 unsigned char *pMemory,
6919 PFORMAT_STRING pFormat)
6921 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6923 if (*pFormat != RPC_FC_BIND_CONTEXT)
6925 ERR("invalid format type %x\n", *pFormat);
6926 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6928 align_length(&pStubMsg->BufferLength, 4);
6929 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6932 /***********************************************************************
6933 * NdrContextHandleMarshall [internal]
6935 static unsigned char *WINAPI NdrContextHandleMarshall(
6936 PMIDL_STUB_MESSAGE pStubMsg,
6937 unsigned char *pMemory,
6938 PFORMAT_STRING pFormat)
6940 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6942 if (*pFormat != RPC_FC_BIND_CONTEXT)
6944 ERR("invalid format type %x\n", *pFormat);
6945 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6947 TRACE("flags: 0x%02x\n", pFormat[1]);
6949 if (pStubMsg->IsClient)
6951 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6952 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6954 NdrClientContextMarshall(pStubMsg, pMemory, FALSE);
6958 NDR_SCONTEXT ctxt = NDRSContextFromValue(pMemory);
6959 NDR_RUNDOWN rundown = pStubMsg->StubDesc->apfnNdrRundownRoutines[pFormat[2]];
6960 NdrServerContextNewMarshall(pStubMsg, ctxt, rundown, pFormat);
6966 /***********************************************************************
6967 * NdrContextHandleUnmarshall [internal]
6969 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6970 PMIDL_STUB_MESSAGE pStubMsg,
6971 unsigned char **ppMemory,
6972 PFORMAT_STRING pFormat,
6973 unsigned char fMustAlloc)
6975 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6976 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6978 if (*pFormat != RPC_FC_BIND_CONTEXT)
6980 ERR("invalid format type %x\n", *pFormat);
6981 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6983 TRACE("flags: 0x%02x\n", pFormat[1]);
6985 if (pStubMsg->IsClient)
6987 /* [out]-only or [ret] param */
6988 if ((pFormat[1] & (HANDLE_PARAM_IS_IN|HANDLE_PARAM_IS_OUT)) == HANDLE_PARAM_IS_OUT)
6989 **(NDR_CCONTEXT **)ppMemory = NULL;
6990 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6995 ctxt = NdrServerContextNewUnmarshall(pStubMsg, pFormat);
6996 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6997 *(void **)ppMemory = NDRSContextValue(ctxt);
6999 *(void **)ppMemory = *NDRSContextValue(ctxt);
7005 /***********************************************************************
7006 * NdrClientContextMarshall [RPCRT4.@]
7008 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7009 NDR_CCONTEXT ContextHandle,
7012 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
7014 align_pointer_clear(&pStubMsg->Buffer, 4);
7016 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7018 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7019 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7020 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7023 /* FIXME: what does fCheck do? */
7024 NDRCContextMarshall(ContextHandle,
7027 pStubMsg->Buffer += cbNDRContext;
7030 /***********************************************************************
7031 * NdrClientContextUnmarshall [RPCRT4.@]
7033 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7034 NDR_CCONTEXT * pContextHandle,
7035 RPC_BINDING_HANDLE BindHandle)
7037 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
7039 align_pointer(&pStubMsg->Buffer, 4);
7041 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
7042 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7044 NDRCContextUnmarshall(pContextHandle,
7047 pStubMsg->RpcMsg->DataRepresentation);
7049 pStubMsg->Buffer += cbNDRContext;
7052 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7053 NDR_SCONTEXT ContextHandle,
7054 NDR_RUNDOWN RundownRoutine )
7056 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
7058 align_pointer(&pStubMsg->Buffer, 4);
7060 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7062 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7063 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7064 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7067 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7068 pStubMsg->Buffer, RundownRoutine, NULL,
7069 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7070 pStubMsg->Buffer += cbNDRContext;
7073 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
7075 NDR_SCONTEXT ContextHandle;
7077 TRACE("(%p)\n", pStubMsg);
7079 align_pointer(&pStubMsg->Buffer, 4);
7081 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7083 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7084 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7085 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7088 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7090 pStubMsg->RpcMsg->DataRepresentation,
7091 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7092 pStubMsg->Buffer += cbNDRContext;
7094 return ContextHandle;
7097 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
7098 unsigned char* pMemory,
7099 PFORMAT_STRING pFormat)
7101 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
7104 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
7105 PFORMAT_STRING pFormat)
7107 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7108 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7110 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7112 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7113 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7114 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7115 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7116 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7118 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7119 if_id = &sif->InterfaceId;
7122 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
7123 pStubMsg->RpcMsg->DataRepresentation, if_id,
7127 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7128 NDR_SCONTEXT ContextHandle,
7129 NDR_RUNDOWN RundownRoutine,
7130 PFORMAT_STRING pFormat)
7132 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7133 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7135 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
7137 align_pointer(&pStubMsg->Buffer, 4);
7139 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7141 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7142 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7143 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7146 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7147 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7148 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7149 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7150 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7152 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7153 if_id = &sif->InterfaceId;
7156 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7157 pStubMsg->Buffer, RundownRoutine, if_id, flags);
7158 pStubMsg->Buffer += cbNDRContext;
7161 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7162 PFORMAT_STRING pFormat)
7164 NDR_SCONTEXT ContextHandle;
7165 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7166 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7168 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7170 align_pointer(&pStubMsg->Buffer, 4);
7172 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7174 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7175 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7176 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7179 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7180 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7181 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7182 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7183 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7185 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7186 if_id = &sif->InterfaceId;
7189 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7191 pStubMsg->RpcMsg->DataRepresentation,
7193 pStubMsg->Buffer += cbNDRContext;
7195 return ContextHandle;
7198 /***********************************************************************
7199 * NdrCorrelationInitialize [RPCRT4.@]
7201 * Initializes correlation validity checking.
7204 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7205 * pMemory [I] Pointer to memory to use as a cache.
7206 * CacheSize [I] Size of the memory pointed to by pMemory.
7207 * Flags [I] Reserved. Set to zero.
7212 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
7214 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
7215 pStubMsg->fHasNewCorrDesc = TRUE;
7218 /***********************************************************************
7219 * NdrCorrelationPass [RPCRT4.@]
7221 * Performs correlation validity checking.
7224 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7229 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
7231 FIXME("(%p): stub\n", pStubMsg);
7234 /***********************************************************************
7235 * NdrCorrelationFree [RPCRT4.@]
7237 * Frees any resources used while unmarshalling parameters that need
7238 * correlation validity checking.
7241 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7246 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
7248 FIXME("(%p): stub\n", pStubMsg);