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));
6164 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6165 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6173 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6174 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6179 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
6183 if (pStubMsg->fHasNewCorrDesc)
6187 return discriminant;
6190 /**********************************************************************
6191 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6193 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6194 unsigned char **ppMemory,
6195 PFORMAT_STRING pFormat,
6196 unsigned char fMustAlloc)
6199 unsigned short size;
6201 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6204 /* Unmarshall discriminant */
6205 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6206 TRACE("unmarshalled discriminant %x\n", discriminant);
6208 pFormat += *(const SHORT*)pFormat;
6210 size = *(const unsigned short*)pFormat;
6212 if (!fMustAlloc && !*ppMemory)
6215 *ppMemory = NdrAllocate(pStubMsg, size);
6217 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6218 * since the arm is part of the memory block that is encompassed by
6219 * the whole union. Memory is forced to allocate when pointers
6220 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6221 * clearing the memory we pass in to the unmarshaller */
6223 memset(*ppMemory, 0, size);
6225 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, FALSE);
6228 /***********************************************************************
6229 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6231 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6232 unsigned char *pMemory,
6233 PFORMAT_STRING pFormat)
6235 unsigned char switch_type;
6237 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6240 switch_type = *pFormat;
6243 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6244 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6245 /* Add discriminant size */
6246 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6248 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6251 /***********************************************************************
6252 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6254 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6255 PFORMAT_STRING pFormat)
6260 /* Unmarshall discriminant */
6261 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6262 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
6264 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
6267 /***********************************************************************
6268 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6270 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6271 unsigned char *pMemory,
6272 PFORMAT_STRING pFormat)
6274 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6278 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6279 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6281 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6284 /***********************************************************************
6285 * NdrByteCountPointerMarshall [RPCRT4.@]
6287 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6288 unsigned char *pMemory,
6289 PFORMAT_STRING pFormat)
6295 /***********************************************************************
6296 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6298 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6299 unsigned char **ppMemory,
6300 PFORMAT_STRING pFormat,
6301 unsigned char fMustAlloc)
6307 /***********************************************************************
6308 * NdrByteCountPointerBufferSize [RPCRT4.@]
6310 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6311 unsigned char *pMemory,
6312 PFORMAT_STRING pFormat)
6317 /***********************************************************************
6318 * NdrByteCountPointerMemorySize [internal]
6320 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6321 PFORMAT_STRING pFormat)
6327 /***********************************************************************
6328 * NdrByteCountPointerFree [RPCRT4.@]
6330 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6331 unsigned char *pMemory,
6332 PFORMAT_STRING pFormat)
6337 /***********************************************************************
6338 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6340 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6341 unsigned char *pMemory,
6342 PFORMAT_STRING pFormat)
6348 /***********************************************************************
6349 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6351 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6352 unsigned char **ppMemory,
6353 PFORMAT_STRING pFormat,
6354 unsigned char fMustAlloc)
6360 /***********************************************************************
6361 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6363 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6364 unsigned char *pMemory,
6365 PFORMAT_STRING pFormat)
6370 /***********************************************************************
6371 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6373 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6374 PFORMAT_STRING pFormat)
6380 /***********************************************************************
6381 * NdrXmitOrRepAsFree [RPCRT4.@]
6383 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6384 unsigned char *pMemory,
6385 PFORMAT_STRING pFormat)
6390 /***********************************************************************
6391 * NdrRangeMarshall [internal]
6393 static unsigned char *WINAPI NdrRangeMarshall(
6394 PMIDL_STUB_MESSAGE pStubMsg,
6395 unsigned char *pMemory,
6396 PFORMAT_STRING pFormat)
6398 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6399 unsigned char base_type;
6401 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6403 if (pRange->type != RPC_FC_RANGE)
6405 ERR("invalid format type %x\n", pRange->type);
6406 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6410 base_type = pRange->flags_type & 0xf;
6412 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6415 /***********************************************************************
6416 * NdrRangeUnmarshall [RPCRT4.@]
6418 unsigned char *WINAPI NdrRangeUnmarshall(
6419 PMIDL_STUB_MESSAGE pStubMsg,
6420 unsigned char **ppMemory,
6421 PFORMAT_STRING pFormat,
6422 unsigned char fMustAlloc)
6424 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6425 unsigned char base_type;
6427 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6429 if (pRange->type != RPC_FC_RANGE)
6431 ERR("invalid format type %x\n", pRange->type);
6432 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6435 base_type = pRange->flags_type & 0xf;
6437 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6438 base_type, pRange->low_value, pRange->high_value);
6440 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6443 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \
6444 if (!fMustAlloc && !*ppMemory) \
6445 fMustAlloc = TRUE; \
6447 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6448 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6450 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6451 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6452 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6454 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6455 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6457 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6458 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6459 (mem_type)pRange->high_value); \
6460 RpcRaiseException(RPC_S_INVALID_BOUND); \
6463 TRACE("*ppMemory: %p\n", *ppMemory); \
6464 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6465 pStubMsg->Buffer += sizeof(wire_type); \
6472 RANGE_UNMARSHALL(UCHAR, UCHAR, "%d");
6473 TRACE("value: 0x%02x\n", **ppMemory);
6477 RANGE_UNMARSHALL(CHAR, CHAR, "%u");
6478 TRACE("value: 0x%02x\n", **ppMemory);
6480 case RPC_FC_WCHAR: /* FIXME: valid? */
6482 RANGE_UNMARSHALL(USHORT, USHORT, "%u");
6483 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6486 RANGE_UNMARSHALL(SHORT, SHORT, "%d");
6487 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6491 RANGE_UNMARSHALL(LONG, LONG, "%d");
6492 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6495 RANGE_UNMARSHALL(ULONG, ULONG, "%u");
6496 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6499 RANGE_UNMARSHALL(UINT, USHORT, "%u");
6500 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6506 ERR("invalid range base type: 0x%02x\n", base_type);
6507 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6513 /***********************************************************************
6514 * NdrRangeBufferSize [internal]
6516 static void WINAPI NdrRangeBufferSize(
6517 PMIDL_STUB_MESSAGE pStubMsg,
6518 unsigned char *pMemory,
6519 PFORMAT_STRING pFormat)
6521 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6522 unsigned char base_type;
6524 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6526 if (pRange->type != RPC_FC_RANGE)
6528 ERR("invalid format type %x\n", pRange->type);
6529 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6531 base_type = pRange->flags_type & 0xf;
6533 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6536 /***********************************************************************
6537 * NdrRangeMemorySize [internal]
6539 static ULONG WINAPI NdrRangeMemorySize(
6540 PMIDL_STUB_MESSAGE pStubMsg,
6541 PFORMAT_STRING pFormat)
6543 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6544 unsigned char base_type;
6546 if (pRange->type != RPC_FC_RANGE)
6548 ERR("invalid format type %x\n", pRange->type);
6549 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6552 base_type = pRange->flags_type & 0xf;
6554 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6557 /***********************************************************************
6558 * NdrRangeFree [internal]
6560 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6561 unsigned char *pMemory,
6562 PFORMAT_STRING pFormat)
6564 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6569 /***********************************************************************
6570 * NdrBaseTypeMarshall [internal]
6572 static unsigned char *WINAPI NdrBaseTypeMarshall(
6573 PMIDL_STUB_MESSAGE pStubMsg,
6574 unsigned char *pMemory,
6575 PFORMAT_STRING pFormat)
6577 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6585 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6586 TRACE("value: 0x%02x\n", *pMemory);
6591 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6592 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6593 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6597 case RPC_FC_ERROR_STATUS_T:
6599 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONG));
6600 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6601 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6604 align_pointer_clear(&pStubMsg->Buffer, sizeof(float));
6605 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6608 align_pointer_clear(&pStubMsg->Buffer, sizeof(double));
6609 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6612 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONGLONG));
6613 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6614 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6618 USHORT val = *(UINT *)pMemory;
6619 /* only 16-bits on the wire, so do a sanity check */
6620 if (*(UINT *)pMemory > SHRT_MAX)
6621 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6622 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6623 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6624 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6627 case RPC_FC_INT3264:
6628 case RPC_FC_UINT3264:
6630 UINT val = *(UINT_PTR *)pMemory;
6631 align_pointer_clear(&pStubMsg->Buffer, sizeof(UINT));
6632 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6638 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6641 /* FIXME: what is the correct return value? */
6645 /***********************************************************************
6646 * NdrBaseTypeUnmarshall [internal]
6648 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6649 PMIDL_STUB_MESSAGE pStubMsg,
6650 unsigned char **ppMemory,
6651 PFORMAT_STRING pFormat,
6652 unsigned char fMustAlloc)
6654 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6656 #define BASE_TYPE_UNMARSHALL(type) do { \
6657 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
6658 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6660 *ppMemory = pStubMsg->Buffer; \
6661 TRACE("*ppMemory: %p\n", *ppMemory); \
6662 safe_buffer_increment(pStubMsg, sizeof(type)); \
6667 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6668 TRACE("*ppMemory: %p\n", *ppMemory); \
6669 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6679 BASE_TYPE_UNMARSHALL(UCHAR);
6680 TRACE("value: 0x%02x\n", **ppMemory);
6685 BASE_TYPE_UNMARSHALL(USHORT);
6686 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6690 case RPC_FC_ERROR_STATUS_T:
6692 BASE_TYPE_UNMARSHALL(ULONG);
6693 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6696 BASE_TYPE_UNMARSHALL(float);
6697 TRACE("value: %f\n", **(float **)ppMemory);
6700 BASE_TYPE_UNMARSHALL(double);
6701 TRACE("value: %f\n", **(double **)ppMemory);
6704 BASE_TYPE_UNMARSHALL(ULONGLONG);
6705 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6710 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6711 if (!fMustAlloc && !*ppMemory)
6714 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6715 safe_copy_from_buffer(pStubMsg, &val, sizeof(USHORT));
6716 /* 16-bits on the wire, but int in memory */
6717 **(UINT **)ppMemory = val;
6718 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6721 case RPC_FC_INT3264:
6722 if (sizeof(INT_PTR) == sizeof(INT)) BASE_TYPE_UNMARSHALL(INT);
6726 align_pointer(&pStubMsg->Buffer, sizeof(INT));
6727 if (!fMustAlloc && !*ppMemory)
6730 *ppMemory = NdrAllocate(pStubMsg, sizeof(INT_PTR));
6731 safe_copy_from_buffer(pStubMsg, &val, sizeof(INT));
6732 **(INT_PTR **)ppMemory = val;
6733 TRACE("value: 0x%08lx\n", **(INT_PTR **)ppMemory);
6736 case RPC_FC_UINT3264:
6737 if (sizeof(UINT_PTR) == sizeof(UINT)) BASE_TYPE_UNMARSHALL(UINT);
6741 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6742 if (!fMustAlloc && !*ppMemory)
6745 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT_PTR));
6746 safe_copy_from_buffer(pStubMsg, &val, sizeof(UINT));
6747 **(UINT_PTR **)ppMemory = val;
6748 TRACE("value: 0x%08lx\n", **(UINT_PTR **)ppMemory);
6754 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6756 #undef BASE_TYPE_UNMARSHALL
6758 /* FIXME: what is the correct return value? */
6763 /***********************************************************************
6764 * NdrBaseTypeBufferSize [internal]
6766 static void WINAPI NdrBaseTypeBufferSize(
6767 PMIDL_STUB_MESSAGE pStubMsg,
6768 unsigned char *pMemory,
6769 PFORMAT_STRING pFormat)
6771 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6779 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6785 align_length(&pStubMsg->BufferLength, sizeof(USHORT));
6786 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6791 case RPC_FC_INT3264:
6792 case RPC_FC_UINT3264:
6793 align_length(&pStubMsg->BufferLength, sizeof(ULONG));
6794 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6797 align_length(&pStubMsg->BufferLength, sizeof(float));
6798 safe_buffer_length_increment(pStubMsg, sizeof(float));
6801 align_length(&pStubMsg->BufferLength, sizeof(double));
6802 safe_buffer_length_increment(pStubMsg, sizeof(double));
6805 align_length(&pStubMsg->BufferLength, sizeof(ULONGLONG));
6806 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6808 case RPC_FC_ERROR_STATUS_T:
6809 align_length(&pStubMsg->BufferLength, sizeof(error_status_t));
6810 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6815 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6819 /***********************************************************************
6820 * NdrBaseTypeMemorySize [internal]
6822 static ULONG WINAPI NdrBaseTypeMemorySize(
6823 PMIDL_STUB_MESSAGE pStubMsg,
6824 PFORMAT_STRING pFormat)
6826 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6834 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6835 pStubMsg->MemorySize += sizeof(UCHAR);
6836 return sizeof(UCHAR);
6840 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6841 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6842 align_length(&pStubMsg->MemorySize, sizeof(USHORT));
6843 pStubMsg->MemorySize += sizeof(USHORT);
6844 return sizeof(USHORT);
6848 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6849 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6850 align_length(&pStubMsg->MemorySize, sizeof(ULONG));
6851 pStubMsg->MemorySize += sizeof(ULONG);
6852 return sizeof(ULONG);
6854 align_pointer(&pStubMsg->Buffer, sizeof(float));
6855 safe_buffer_increment(pStubMsg, sizeof(float));
6856 align_length(&pStubMsg->MemorySize, sizeof(float));
6857 pStubMsg->MemorySize += sizeof(float);
6858 return sizeof(float);
6860 align_pointer(&pStubMsg->Buffer, sizeof(double));
6861 safe_buffer_increment(pStubMsg, sizeof(double));
6862 align_length(&pStubMsg->MemorySize, sizeof(double));
6863 pStubMsg->MemorySize += sizeof(double);
6864 return sizeof(double);
6866 align_pointer(&pStubMsg->Buffer, sizeof(ULONGLONG));
6867 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6868 align_length(&pStubMsg->MemorySize, sizeof(ULONGLONG));
6869 pStubMsg->MemorySize += sizeof(ULONGLONG);
6870 return sizeof(ULONGLONG);
6871 case RPC_FC_ERROR_STATUS_T:
6872 align_pointer(&pStubMsg->Buffer, sizeof(error_status_t));
6873 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6874 align_length(&pStubMsg->MemorySize, sizeof(error_status_t));
6875 pStubMsg->MemorySize += sizeof(error_status_t);
6876 return sizeof(error_status_t);
6878 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6879 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6880 align_length(&pStubMsg->MemorySize, sizeof(UINT));
6881 pStubMsg->MemorySize += sizeof(UINT);
6882 return sizeof(UINT);
6883 case RPC_FC_INT3264:
6884 case RPC_FC_UINT3264:
6885 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6886 safe_buffer_increment(pStubMsg, sizeof(UINT));
6887 align_length(&pStubMsg->MemorySize, sizeof(UINT_PTR));
6888 pStubMsg->MemorySize += sizeof(UINT_PTR);
6889 return sizeof(UINT_PTR);
6891 align_length(&pStubMsg->MemorySize, sizeof(void *));
6892 pStubMsg->MemorySize += sizeof(void *);
6893 return sizeof(void *);
6895 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6900 /***********************************************************************
6901 * NdrBaseTypeFree [internal]
6903 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6904 unsigned char *pMemory,
6905 PFORMAT_STRING pFormat)
6907 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6912 /***********************************************************************
6913 * NdrContextHandleBufferSize [internal]
6915 static void WINAPI NdrContextHandleBufferSize(
6916 PMIDL_STUB_MESSAGE pStubMsg,
6917 unsigned char *pMemory,
6918 PFORMAT_STRING pFormat)
6920 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6922 if (*pFormat != RPC_FC_BIND_CONTEXT)
6924 ERR("invalid format type %x\n", *pFormat);
6925 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6927 align_length(&pStubMsg->BufferLength, 4);
6928 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6931 /***********************************************************************
6932 * NdrContextHandleMarshall [internal]
6934 static unsigned char *WINAPI NdrContextHandleMarshall(
6935 PMIDL_STUB_MESSAGE pStubMsg,
6936 unsigned char *pMemory,
6937 PFORMAT_STRING pFormat)
6939 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6941 if (*pFormat != RPC_FC_BIND_CONTEXT)
6943 ERR("invalid format type %x\n", *pFormat);
6944 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6946 TRACE("flags: 0x%02x\n", pFormat[1]);
6948 if (pStubMsg->IsClient)
6950 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6951 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6953 NdrClientContextMarshall(pStubMsg, pMemory, FALSE);
6957 NDR_SCONTEXT ctxt = NDRSContextFromValue(pMemory);
6958 NDR_RUNDOWN rundown = pStubMsg->StubDesc->apfnNdrRundownRoutines[pFormat[2]];
6959 NdrServerContextNewMarshall(pStubMsg, ctxt, rundown, pFormat);
6965 /***********************************************************************
6966 * NdrContextHandleUnmarshall [internal]
6968 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6969 PMIDL_STUB_MESSAGE pStubMsg,
6970 unsigned char **ppMemory,
6971 PFORMAT_STRING pFormat,
6972 unsigned char fMustAlloc)
6974 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6975 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6977 if (*pFormat != RPC_FC_BIND_CONTEXT)
6979 ERR("invalid format type %x\n", *pFormat);
6980 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6982 TRACE("flags: 0x%02x\n", pFormat[1]);
6984 if (pStubMsg->IsClient)
6986 /* [out]-only or [ret] param */
6987 if ((pFormat[1] & (HANDLE_PARAM_IS_IN|HANDLE_PARAM_IS_OUT)) == HANDLE_PARAM_IS_OUT)
6988 **(NDR_CCONTEXT **)ppMemory = NULL;
6989 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6994 ctxt = NdrServerContextNewUnmarshall(pStubMsg, pFormat);
6995 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6996 *(void **)ppMemory = NDRSContextValue(ctxt);
6998 *(void **)ppMemory = *NDRSContextValue(ctxt);
7004 /***********************************************************************
7005 * NdrClientContextMarshall [RPCRT4.@]
7007 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7008 NDR_CCONTEXT ContextHandle,
7011 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
7013 align_pointer_clear(&pStubMsg->Buffer, 4);
7015 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7017 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7018 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7019 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7022 /* FIXME: what does fCheck do? */
7023 NDRCContextMarshall(ContextHandle,
7026 pStubMsg->Buffer += cbNDRContext;
7029 /***********************************************************************
7030 * NdrClientContextUnmarshall [RPCRT4.@]
7032 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7033 NDR_CCONTEXT * pContextHandle,
7034 RPC_BINDING_HANDLE BindHandle)
7036 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
7038 align_pointer(&pStubMsg->Buffer, 4);
7040 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
7041 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7043 NDRCContextUnmarshall(pContextHandle,
7046 pStubMsg->RpcMsg->DataRepresentation);
7048 pStubMsg->Buffer += cbNDRContext;
7051 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7052 NDR_SCONTEXT ContextHandle,
7053 NDR_RUNDOWN RundownRoutine )
7055 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
7057 align_pointer(&pStubMsg->Buffer, 4);
7059 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7061 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7062 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7063 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7066 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7067 pStubMsg->Buffer, RundownRoutine, NULL,
7068 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7069 pStubMsg->Buffer += cbNDRContext;
7072 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
7074 NDR_SCONTEXT ContextHandle;
7076 TRACE("(%p)\n", pStubMsg);
7078 align_pointer(&pStubMsg->Buffer, 4);
7080 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7082 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7083 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7084 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7087 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7089 pStubMsg->RpcMsg->DataRepresentation,
7090 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7091 pStubMsg->Buffer += cbNDRContext;
7093 return ContextHandle;
7096 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
7097 unsigned char* pMemory,
7098 PFORMAT_STRING pFormat)
7100 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
7103 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
7104 PFORMAT_STRING pFormat)
7106 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7107 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7109 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7111 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7112 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7113 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7114 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7115 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7117 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7118 if_id = &sif->InterfaceId;
7121 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
7122 pStubMsg->RpcMsg->DataRepresentation, if_id,
7126 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7127 NDR_SCONTEXT ContextHandle,
7128 NDR_RUNDOWN RundownRoutine,
7129 PFORMAT_STRING pFormat)
7131 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7132 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7134 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
7136 align_pointer(&pStubMsg->Buffer, 4);
7138 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7140 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7141 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7142 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7145 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7146 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7147 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7148 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7149 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7151 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7152 if_id = &sif->InterfaceId;
7155 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7156 pStubMsg->Buffer, RundownRoutine, if_id, flags);
7157 pStubMsg->Buffer += cbNDRContext;
7160 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7161 PFORMAT_STRING pFormat)
7163 NDR_SCONTEXT ContextHandle;
7164 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7165 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7167 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7169 align_pointer(&pStubMsg->Buffer, 4);
7171 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7173 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7174 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7175 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7178 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7179 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7180 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7181 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7182 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7184 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7185 if_id = &sif->InterfaceId;
7188 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7190 pStubMsg->RpcMsg->DataRepresentation,
7192 pStubMsg->Buffer += cbNDRContext;
7194 return ContextHandle;
7197 /***********************************************************************
7198 * NdrCorrelationInitialize [RPCRT4.@]
7200 * Initializes correlation validity checking.
7203 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7204 * pMemory [I] Pointer to memory to use as a cache.
7205 * CacheSize [I] Size of the memory pointed to by pMemory.
7206 * Flags [I] Reserved. Set to zero.
7211 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
7213 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
7214 pStubMsg->fHasNewCorrDesc = TRUE;
7217 /***********************************************************************
7218 * NdrCorrelationPass [RPCRT4.@]
7220 * Performs correlation validity checking.
7223 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7228 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
7230 FIXME("(%p): stub\n", pStubMsg);
7233 /***********************************************************************
7234 * NdrCorrelationFree [RPCRT4.@]
7236 * Frees any resources used while unmarshalling parameters that need
7237 * correlation validity checking.
7240 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7245 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
7247 FIXME("(%p): stub\n", pStubMsg);