4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * - Byte count pointers
24 * - transmit_as/represent as
25 * - Multi-dimensional arrays
26 * - Conversion functions (NdrConvert)
27 * - Checks for integer addition overflow in user marshall functions
36 #define NONAMELESSUNION
45 #include "wine/unicode.h"
46 #include "wine/rpcfc.h"
48 #include "wine/debug.h"
50 WINE_DEFAULT_DEBUG_CHANNEL(ole);
53 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
54 (*((UINT32 *)(pchar)) = (uint32))
56 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
57 (*((UINT32 *)(pchar)))
59 /* these would work for i386 too, but less efficient */
60 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
61 (*(pchar) = LOBYTE(LOWORD(uint32)), \
62 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
63 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
64 *((pchar)+3) = HIBYTE(HIWORD(uint32)))
66 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
68 MAKEWORD(*(pchar), *((pchar)+1)), \
69 MAKEWORD(*((pchar)+2), *((pchar)+3))))
72 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
73 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
74 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
75 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
76 *(pchar) = HIBYTE(HIWORD(uint32)))
78 #define BIG_ENDIAN_UINT32_READ(pchar) \
80 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
81 MAKEWORD(*((pchar)+1), *(pchar))))
83 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
84 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
85 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
86 # define NDR_LOCAL_UINT32_READ(pchar) \
87 BIG_ENDIAN_UINT32_READ(pchar)
89 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
90 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
91 # define NDR_LOCAL_UINT32_READ(pchar) \
92 LITTLE_ENDIAN_UINT32_READ(pchar)
95 static inline void align_length( ULONG *len, unsigned int align )
97 *len = (*len + align - 1) & ~(align - 1);
100 static inline void align_pointer( unsigned char **ptr, unsigned int align )
102 ULONG_PTR mask = align - 1;
103 *ptr = (unsigned char *)(((ULONG_PTR)*ptr + mask) & ~mask);
106 static inline void align_pointer_clear( unsigned char **ptr, unsigned int align )
108 ULONG_PTR mask = align - 1;
109 memset( *ptr, 0, (align - (ULONG_PTR)*ptr) & mask );
110 *ptr = (unsigned char *)(((ULONG_PTR)*ptr + mask) & ~mask);
113 #define STD_OVERFLOW_CHECK(_Msg) do { \
114 TRACE("buffer=%d/%d\n", (ULONG)(_Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer), _Msg->BufferLength); \
115 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
116 ERR("buffer overflow %d bytes\n", (ULONG)(_Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength))); \
119 #define NDR_POINTER_ID_BASE 0x20000
120 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
121 #define NDR_TABLE_SIZE 128
122 #define NDR_TABLE_MASK 127
124 #define NDRSContextFromValue(user_context) (NDR_SCONTEXT)((char *)(user_context) - (char *)NDRSContextValue((NDR_SCONTEXT)NULL))
126 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
127 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
128 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
129 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
130 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
132 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
133 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
134 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
136 static unsigned char *WINAPI NdrRangeMarshall(PMIDL_STUB_MESSAGE,unsigned char *, PFORMAT_STRING);
137 static void WINAPI NdrRangeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
138 static ULONG WINAPI NdrRangeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
139 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
141 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
143 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
144 unsigned char *pMemory,
145 PFORMAT_STRING pFormat,
146 PFORMAT_STRING pPointer);
147 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
148 unsigned char *pMemory,
149 PFORMAT_STRING pFormat,
150 PFORMAT_STRING pPointer);
151 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
152 unsigned char *pMemory,
153 PFORMAT_STRING pFormat,
154 PFORMAT_STRING pPointer,
155 unsigned char fMustAlloc);
156 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
157 PFORMAT_STRING pFormat,
158 PFORMAT_STRING pPointer);
159 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
160 unsigned char *pMemory,
161 PFORMAT_STRING pFormat,
162 PFORMAT_STRING pPointer);
164 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
166 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
167 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
168 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
169 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
173 NdrPointerMarshall, NdrPointerMarshall,
174 NdrPointerMarshall, NdrPointerMarshall,
176 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
177 NdrConformantStructMarshall, NdrConformantStructMarshall,
178 NdrConformantVaryingStructMarshall,
179 NdrComplexStructMarshall,
181 NdrConformantArrayMarshall,
182 NdrConformantVaryingArrayMarshall,
183 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
184 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
185 NdrComplexArrayMarshall,
187 NdrConformantStringMarshall, 0, 0,
188 NdrConformantStringMarshall,
189 NdrNonConformantStringMarshall, 0, 0, 0,
191 NdrEncapsulatedUnionMarshall,
192 NdrNonEncapsulatedUnionMarshall,
193 NdrByteCountPointerMarshall,
194 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
196 NdrInterfacePointerMarshall,
198 NdrContextHandleMarshall,
201 NdrUserMarshalMarshall,
206 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
208 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
209 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
210 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
211 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
213 NdrBaseTypeUnmarshall,
215 NdrPointerUnmarshall, NdrPointerUnmarshall,
216 NdrPointerUnmarshall, NdrPointerUnmarshall,
218 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
219 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
220 NdrConformantVaryingStructUnmarshall,
221 NdrComplexStructUnmarshall,
223 NdrConformantArrayUnmarshall,
224 NdrConformantVaryingArrayUnmarshall,
225 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
226 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
227 NdrComplexArrayUnmarshall,
229 NdrConformantStringUnmarshall, 0, 0,
230 NdrConformantStringUnmarshall,
231 NdrNonConformantStringUnmarshall, 0, 0, 0,
233 NdrEncapsulatedUnionUnmarshall,
234 NdrNonEncapsulatedUnionUnmarshall,
235 NdrByteCountPointerUnmarshall,
236 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
238 NdrInterfacePointerUnmarshall,
240 NdrContextHandleUnmarshall,
243 NdrUserMarshalUnmarshall,
248 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
250 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
251 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
252 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
253 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
255 NdrBaseTypeBufferSize,
257 NdrPointerBufferSize, NdrPointerBufferSize,
258 NdrPointerBufferSize, NdrPointerBufferSize,
260 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
261 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
262 NdrConformantVaryingStructBufferSize,
263 NdrComplexStructBufferSize,
265 NdrConformantArrayBufferSize,
266 NdrConformantVaryingArrayBufferSize,
267 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
268 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
269 NdrComplexArrayBufferSize,
271 NdrConformantStringBufferSize, 0, 0,
272 NdrConformantStringBufferSize,
273 NdrNonConformantStringBufferSize, 0, 0, 0,
275 NdrEncapsulatedUnionBufferSize,
276 NdrNonEncapsulatedUnionBufferSize,
277 NdrByteCountPointerBufferSize,
278 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
280 NdrInterfacePointerBufferSize,
282 NdrContextHandleBufferSize,
285 NdrUserMarshalBufferSize,
290 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
292 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
293 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
294 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
295 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
297 NdrBaseTypeMemorySize,
299 NdrPointerMemorySize, NdrPointerMemorySize,
300 NdrPointerMemorySize, NdrPointerMemorySize,
302 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
303 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
304 NdrConformantVaryingStructMemorySize,
305 NdrComplexStructMemorySize,
307 NdrConformantArrayMemorySize,
308 NdrConformantVaryingArrayMemorySize,
309 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
310 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
311 NdrComplexArrayMemorySize,
313 NdrConformantStringMemorySize, 0, 0,
314 NdrConformantStringMemorySize,
315 NdrNonConformantStringMemorySize, 0, 0, 0,
317 NdrEncapsulatedUnionMemorySize,
318 NdrNonEncapsulatedUnionMemorySize,
319 NdrByteCountPointerMemorySize,
320 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
322 NdrInterfacePointerMemorySize,
327 NdrUserMarshalMemorySize,
332 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
334 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
335 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
336 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
337 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
341 NdrPointerFree, NdrPointerFree,
342 NdrPointerFree, NdrPointerFree,
344 NdrSimpleStructFree, NdrSimpleStructFree,
345 NdrConformantStructFree, NdrConformantStructFree,
346 NdrConformantVaryingStructFree,
347 NdrComplexStructFree,
349 NdrConformantArrayFree,
350 NdrConformantVaryingArrayFree,
351 NdrFixedArrayFree, NdrFixedArrayFree,
352 NdrVaryingArrayFree, NdrVaryingArrayFree,
358 NdrEncapsulatedUnionFree,
359 NdrNonEncapsulatedUnionFree,
361 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
363 NdrInterfacePointerFree,
374 typedef struct _NDR_MEMORY_LIST
379 struct _NDR_MEMORY_LIST *next;
382 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
384 /***********************************************************************
385 * NdrAllocate [RPCRT4.@]
387 * Allocates a block of memory using pStubMsg->pfnAllocate.
390 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
391 * len [I] Size of memory block to allocate.
394 * The memory block of size len that was allocated.
397 * The memory block is always 8-byte aligned.
398 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
399 * exception is raised.
401 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, SIZE_T len)
406 NDR_MEMORY_LIST *mem_list;
408 aligned_len = (len + 7) & ~7;
409 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
410 /* check for overflow */
411 if (adjusted_len < len)
413 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len, len);
414 RpcRaiseException(RPC_X_BAD_STUB_DATA);
417 p = pStubMsg->pfnAllocate(adjusted_len);
418 if (!p) RpcRaiseException(ERROR_OUTOFMEMORY);
420 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
421 mem_list->magic = MEML_MAGIC;
422 mem_list->size = aligned_len;
423 mem_list->reserved = 0;
424 mem_list->next = pStubMsg->pMemoryList;
425 pStubMsg->pMemoryList = mem_list;
431 static void NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
433 TRACE("(%p, %p)\n", pStubMsg, Pointer);
435 pStubMsg->pfnFree(Pointer);
438 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
440 return (*(const ULONG *)pFormat != -1);
443 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
445 align_pointer(&pStubMsg->Buffer, 4);
446 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
447 RpcRaiseException(RPC_X_BAD_STUB_DATA);
448 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
449 pStubMsg->Buffer += 4;
450 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
451 if (pStubMsg->fHasNewCorrDesc)
457 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
459 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
461 pStubMsg->Offset = 0;
462 pStubMsg->ActualCount = pStubMsg->MaxCount;
466 align_pointer(&pStubMsg->Buffer, 4);
467 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
468 RpcRaiseException(RPC_X_BAD_STUB_DATA);
469 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
470 pStubMsg->Buffer += 4;
471 TRACE("offset is %d\n", pStubMsg->Offset);
472 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
473 pStubMsg->Buffer += 4;
474 TRACE("variance is %d\n", pStubMsg->ActualCount);
476 if ((pStubMsg->ActualCount > MaxValue) ||
477 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
479 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
480 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
481 RpcRaiseException(RPC_S_INVALID_BOUND);
486 if (pStubMsg->fHasNewCorrDesc)
492 /* writes the conformance value to the buffer */
493 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
495 align_pointer_clear(&pStubMsg->Buffer, 4);
496 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
497 RpcRaiseException(RPC_X_BAD_STUB_DATA);
498 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
499 pStubMsg->Buffer += 4;
502 /* writes the variance values to the buffer */
503 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
505 align_pointer_clear(&pStubMsg->Buffer, 4);
506 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
507 RpcRaiseException(RPC_X_BAD_STUB_DATA);
508 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
509 pStubMsg->Buffer += 4;
510 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
511 pStubMsg->Buffer += 4;
514 /* requests buffer space for the conformance value */
515 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
517 align_length(&pStubMsg->BufferLength, 4);
518 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
519 RpcRaiseException(RPC_X_BAD_STUB_DATA);
520 pStubMsg->BufferLength += 4;
523 /* requests buffer space for the variance values */
524 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
526 align_length(&pStubMsg->BufferLength, 4);
527 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
528 RpcRaiseException(RPC_X_BAD_STUB_DATA);
529 pStubMsg->BufferLength += 8;
532 PFORMAT_STRING ComputeConformanceOrVariance(
533 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
534 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
536 BYTE dtype = pFormat[0] & 0xf;
537 short ofs = *(const short *)&pFormat[2];
541 if (!IsConformanceOrVariancePresent(pFormat)) {
542 /* null descriptor */
547 switch (pFormat[0] & 0xf0) {
548 case RPC_FC_NORMAL_CONFORMANCE:
549 TRACE("normal conformance, ofs=%d\n", ofs);
552 case RPC_FC_POINTER_CONFORMANCE:
553 TRACE("pointer conformance, ofs=%d\n", ofs);
554 ptr = pStubMsg->Memory;
556 case RPC_FC_TOP_LEVEL_CONFORMANCE:
557 TRACE("toplevel conformance, ofs=%d\n", ofs);
558 if (pStubMsg->StackTop) {
559 ptr = pStubMsg->StackTop;
562 /* -Os mode, *pCount is already set */
566 case RPC_FC_CONSTANT_CONFORMANCE:
567 data = ofs | ((DWORD)pFormat[1] << 16);
568 TRACE("constant conformance, val=%d\n", data);
571 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
572 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
573 if (pStubMsg->StackTop) {
574 ptr = pStubMsg->StackTop;
582 FIXME("unknown conformance type %x, expect crash.\n", pFormat[0] & 0xf0);
586 switch (pFormat[1]) {
587 case RPC_FC_DEREFERENCE:
588 ptr = *(LPVOID*)((char *)ptr + ofs);
590 case RPC_FC_CALLBACK:
592 unsigned char *old_stack_top = pStubMsg->StackTop;
593 pStubMsg->StackTop = ptr;
595 /* ofs is index into StubDesc->apfnExprEval */
596 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
597 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
599 pStubMsg->StackTop = old_stack_top;
601 /* the callback function always stores the computed value in MaxCount */
602 *pCount = pStubMsg->MaxCount;
606 ptr = (char *)ptr + ofs;
619 data = *(USHORT*)ptr;
630 FIXME("unknown conformance data type %x\n", dtype);
633 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
636 switch (pFormat[1]) {
637 case RPC_FC_DEREFERENCE: /* already handled */
654 FIXME("unknown conformance op %d\n", pFormat[1]);
659 TRACE("resulting conformance is %ld\n", *pCount);
660 if (pStubMsg->fHasNewCorrDesc)
666 static inline PFORMAT_STRING SkipConformance(PMIDL_STUB_MESSAGE pStubMsg,
667 PFORMAT_STRING pFormat)
669 if (pStubMsg->fHasNewCorrDesc)
676 static inline PFORMAT_STRING SkipVariance(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
678 return SkipConformance( pStubMsg, pFormat );
681 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
682 * the result overflows 32-bits */
683 static inline ULONG safe_multiply(ULONG a, ULONG b)
685 ULONGLONG ret = (ULONGLONG)a * b;
686 if (ret > 0xffffffff)
688 RpcRaiseException(RPC_S_INVALID_BOUND);
694 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
696 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
697 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
698 RpcRaiseException(RPC_X_BAD_STUB_DATA);
699 pStubMsg->Buffer += size;
702 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
704 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
706 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
707 pStubMsg->BufferLength, size);
708 RpcRaiseException(RPC_X_BAD_STUB_DATA);
710 pStubMsg->BufferLength += size;
713 /* copies data from the buffer, checking that there is enough data in the buffer
715 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
717 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
718 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
720 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
721 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
722 RpcRaiseException(RPC_X_BAD_STUB_DATA);
724 if (p == pStubMsg->Buffer)
725 ERR("pointer is the same as the buffer\n");
726 memcpy(p, pStubMsg->Buffer, size);
727 pStubMsg->Buffer += size;
730 /* copies data to the buffer, checking that there is enough space to do so */
731 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
733 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
734 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
736 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
737 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
739 RpcRaiseException(RPC_X_BAD_STUB_DATA);
741 memcpy(pStubMsg->Buffer, p, size);
742 pStubMsg->Buffer += size;
745 /* verify that string data sitting in the buffer is valid and safe to
747 static void validate_string_data(MIDL_STUB_MESSAGE *pStubMsg, ULONG bufsize, ULONG esize)
751 /* verify the buffer is safe to access */
752 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
753 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
755 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
756 pStubMsg->BufferEnd, pStubMsg->Buffer);
757 RpcRaiseException(RPC_X_BAD_STUB_DATA);
760 /* strings must always have null terminating bytes */
763 ERR("invalid string length of %d\n", bufsize / esize);
764 RpcRaiseException(RPC_S_INVALID_BOUND);
767 for (i = bufsize - esize; i < bufsize; i++)
768 if (pStubMsg->Buffer[i] != 0)
770 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
771 i, pStubMsg->Buffer[i]);
772 RpcRaiseException(RPC_S_INVALID_BOUND);
776 static inline void dump_pointer_attr(unsigned char attr)
778 if (attr & RPC_FC_P_ALLOCALLNODES)
779 TRACE(" RPC_FC_P_ALLOCALLNODES");
780 if (attr & RPC_FC_P_DONTFREE)
781 TRACE(" RPC_FC_P_DONTFREE");
782 if (attr & RPC_FC_P_ONSTACK)
783 TRACE(" RPC_FC_P_ONSTACK");
784 if (attr & RPC_FC_P_SIMPLEPOINTER)
785 TRACE(" RPC_FC_P_SIMPLEPOINTER");
786 if (attr & RPC_FC_P_DEREF)
787 TRACE(" RPC_FC_P_DEREF");
791 /***********************************************************************
792 * PointerMarshall [internal]
794 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
795 unsigned char *Buffer,
796 unsigned char *Pointer,
797 PFORMAT_STRING pFormat)
799 unsigned type = pFormat[0], attr = pFormat[1];
803 int pointer_needs_marshaling;
805 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
806 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
808 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
809 else desc = pFormat + *(const SHORT*)pFormat;
812 case RPC_FC_RP: /* ref pointer (always non-null) */
815 ERR("NULL ref pointer is not allowed\n");
816 RpcRaiseException(RPC_X_NULL_REF_POINTER);
818 pointer_needs_marshaling = 1;
820 case RPC_FC_UP: /* unique pointer */
821 case RPC_FC_OP: /* object pointer - same as unique here */
823 pointer_needs_marshaling = 1;
825 pointer_needs_marshaling = 0;
826 pointer_id = Pointer ? NDR_POINTER_ID(pStubMsg) : 0;
827 TRACE("writing 0x%08x to buffer\n", pointer_id);
828 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
831 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
832 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
833 TRACE("writing 0x%08x to buffer\n", pointer_id);
834 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
837 FIXME("unhandled ptr type=%02x\n", type);
838 RpcRaiseException(RPC_X_BAD_STUB_DATA);
842 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
844 if (pointer_needs_marshaling) {
845 if (attr & RPC_FC_P_DEREF) {
846 Pointer = *(unsigned char**)Pointer;
847 TRACE("deref => %p\n", Pointer);
849 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
850 if (m) m(pStubMsg, Pointer, desc);
851 else FIXME("no marshaller for data type=%02x\n", *desc);
854 STD_OVERFLOW_CHECK(pStubMsg);
857 /***********************************************************************
858 * PointerUnmarshall [internal]
860 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
861 unsigned char *Buffer,
862 unsigned char **pPointer,
863 unsigned char *pSrcPointer,
864 PFORMAT_STRING pFormat,
865 unsigned char fMustAlloc)
867 unsigned type = pFormat[0], attr = pFormat[1];
870 DWORD pointer_id = 0;
871 int pointer_needs_unmarshaling;
873 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
874 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
876 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
877 else desc = pFormat + *(const SHORT*)pFormat;
880 case RPC_FC_RP: /* ref pointer (always non-null) */
881 pointer_needs_unmarshaling = 1;
883 case RPC_FC_UP: /* unique pointer */
884 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
885 TRACE("pointer_id is 0x%08x\n", pointer_id);
887 pointer_needs_unmarshaling = 1;
890 pointer_needs_unmarshaling = 0;
893 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
894 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
895 TRACE("pointer_id is 0x%08x\n", pointer_id);
896 if (!fMustAlloc && pSrcPointer)
898 FIXME("free object pointer %p\n", pSrcPointer);
902 pointer_needs_unmarshaling = 1;
906 pointer_needs_unmarshaling = 0;
910 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
911 TRACE("pointer_id is 0x%08x\n", pointer_id);
912 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
913 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
916 FIXME("unhandled ptr type=%02x\n", type);
917 RpcRaiseException(RPC_X_BAD_STUB_DATA);
921 if (pointer_needs_unmarshaling) {
922 unsigned char **current_ptr = pPointer;
923 if (pStubMsg->IsClient) {
925 /* if we aren't forcing allocation of memory then try to use the existing
926 * (source) pointer to unmarshall the data into so that [in,out]
927 * parameters behave correctly. it doesn't matter if the parameter is
928 * [out] only since in that case the pointer will be NULL. we force
929 * allocation when the source pointer is NULL here instead of in the type
930 * unmarshalling routine for the benefit of the deref code below */
933 TRACE("setting *pPointer to %p\n", pSrcPointer);
934 *pPointer = pSrcPointer;
940 /* the memory in a stub is never initialised, so we have to work out here
941 * whether we have to initialise it so we can use the optimisation of
942 * setting the pointer to the buffer, if possible, or set fMustAlloc to
944 if (attr & RPC_FC_P_DEREF) {
951 if (attr & RPC_FC_P_ALLOCALLNODES)
952 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
954 if (attr & RPC_FC_P_DEREF) {
956 unsigned char *base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
957 *pPointer = base_ptr_val;
958 current_ptr = (unsigned char **)base_ptr_val;
960 current_ptr = *(unsigned char***)current_ptr;
961 TRACE("deref => %p\n", current_ptr);
962 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
964 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
965 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
966 else FIXME("no unmarshaller for data type=%02x\n", *desc);
968 if (type == RPC_FC_FP)
969 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
973 TRACE("pointer=%p\n", *pPointer);
976 /***********************************************************************
977 * PointerBufferSize [internal]
979 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
980 unsigned char *Pointer,
981 PFORMAT_STRING pFormat)
983 unsigned type = pFormat[0], attr = pFormat[1];
986 int pointer_needs_sizing;
989 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
990 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
992 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
993 else desc = pFormat + *(const SHORT*)pFormat;
996 case RPC_FC_RP: /* ref pointer (always non-null) */
999 ERR("NULL ref pointer is not allowed\n");
1000 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1005 /* NULL pointer has no further representation */
1010 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1011 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1012 if (!pointer_needs_sizing)
1016 FIXME("unhandled ptr type=%02x\n", type);
1017 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1021 if (attr & RPC_FC_P_DEREF) {
1022 Pointer = *(unsigned char**)Pointer;
1023 TRACE("deref => %p\n", Pointer);
1026 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1027 if (m) m(pStubMsg, Pointer, desc);
1028 else FIXME("no buffersizer for data type=%02x\n", *desc);
1031 /***********************************************************************
1032 * PointerMemorySize [internal]
1034 static ULONG PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1035 unsigned char *Buffer, PFORMAT_STRING pFormat)
1037 unsigned type = pFormat[0], attr = pFormat[1];
1038 PFORMAT_STRING desc;
1040 DWORD pointer_id = 0;
1041 int pointer_needs_sizing;
1043 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1044 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1046 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1047 else desc = pFormat + *(const SHORT*)pFormat;
1050 case RPC_FC_RP: /* ref pointer (always non-null) */
1051 pointer_needs_sizing = 1;
1053 case RPC_FC_UP: /* unique pointer */
1054 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1055 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1056 TRACE("pointer_id is 0x%08x\n", pointer_id);
1058 pointer_needs_sizing = 1;
1060 pointer_needs_sizing = 0;
1065 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1066 TRACE("pointer_id is 0x%08x\n", pointer_id);
1067 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1068 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1072 FIXME("unhandled ptr type=%02x\n", type);
1073 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1077 if (attr & RPC_FC_P_DEREF) {
1078 align_length(&pStubMsg->MemorySize, sizeof(void*));
1079 pStubMsg->MemorySize += sizeof(void*);
1083 if (pointer_needs_sizing) {
1084 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1085 if (m) m(pStubMsg, desc);
1086 else FIXME("no memorysizer for data type=%02x\n", *desc);
1089 return pStubMsg->MemorySize;
1092 /***********************************************************************
1093 * PointerFree [internal]
1095 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1096 unsigned char *Pointer,
1097 PFORMAT_STRING pFormat)
1099 unsigned type = pFormat[0], attr = pFormat[1];
1100 PFORMAT_STRING desc;
1102 unsigned char *current_pointer = Pointer;
1104 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1105 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1106 if (attr & RPC_FC_P_DONTFREE) return;
1108 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1109 else desc = pFormat + *(const SHORT*)pFormat;
1111 if (!Pointer) return;
1113 if (type == RPC_FC_FP) {
1114 int pointer_needs_freeing = NdrFullPointerFree(
1115 pStubMsg->FullPtrXlatTables, Pointer);
1116 if (!pointer_needs_freeing)
1120 if (attr & RPC_FC_P_DEREF) {
1121 current_pointer = *(unsigned char**)Pointer;
1122 TRACE("deref => %p\n", current_pointer);
1125 m = NdrFreer[*desc & NDR_TABLE_MASK];
1126 if (m) m(pStubMsg, current_pointer, desc);
1128 /* this check stops us from trying to free buffer memory. we don't have to
1129 * worry about clients, since they won't call this function.
1130 * we don't have to check for the buffer being reallocated because
1131 * BufferStart and BufferEnd won't be reset when allocating memory for
1132 * sending the response. we don't have to check for the new buffer here as
1133 * it won't be used a type memory, only for buffer memory */
1134 if (Pointer >= pStubMsg->BufferStart && Pointer < pStubMsg->BufferEnd)
1137 if (attr & RPC_FC_P_ONSTACK) {
1138 TRACE("not freeing stack ptr %p\n", Pointer);
1141 TRACE("freeing %p\n", Pointer);
1142 NdrFree(pStubMsg, Pointer);
1145 TRACE("not freeing %p\n", Pointer);
1148 /***********************************************************************
1149 * EmbeddedPointerMarshall
1151 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1152 unsigned char *pMemory,
1153 PFORMAT_STRING pFormat)
1155 unsigned char *Mark = pStubMsg->BufferMark;
1156 unsigned rep, count, stride;
1158 unsigned char *saved_buffer = NULL;
1160 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1162 if (*pFormat != RPC_FC_PP) return NULL;
1165 if (pStubMsg->PointerBufferMark)
1167 saved_buffer = pStubMsg->Buffer;
1168 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1169 pStubMsg->PointerBufferMark = NULL;
1172 while (pFormat[0] != RPC_FC_END) {
1173 switch (pFormat[0]) {
1175 FIXME("unknown repeat type %d\n", pFormat[0]);
1176 case RPC_FC_NO_REPEAT:
1182 case RPC_FC_FIXED_REPEAT:
1183 rep = *(const WORD*)&pFormat[2];
1184 stride = *(const WORD*)&pFormat[4];
1185 count = *(const WORD*)&pFormat[8];
1188 case RPC_FC_VARIABLE_REPEAT:
1189 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1190 stride = *(const WORD*)&pFormat[2];
1191 count = *(const WORD*)&pFormat[6];
1195 for (i = 0; i < rep; i++) {
1196 PFORMAT_STRING info = pFormat;
1197 unsigned char *membase = pMemory + (i * stride);
1198 unsigned char *bufbase = Mark + (i * stride);
1201 for (u=0; u<count; u++,info+=8) {
1202 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1203 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1204 unsigned char *saved_memory = pStubMsg->Memory;
1206 pStubMsg->Memory = pMemory;
1207 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1208 pStubMsg->Memory = saved_memory;
1211 pFormat += 8 * count;
1216 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1217 pStubMsg->Buffer = saved_buffer;
1220 STD_OVERFLOW_CHECK(pStubMsg);
1225 /***********************************************************************
1226 * EmbeddedPointerUnmarshall
1228 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1229 unsigned char *pDstBuffer,
1230 unsigned char *pSrcMemoryPtrs,
1231 PFORMAT_STRING pFormat,
1232 unsigned char fMustAlloc)
1234 unsigned char *Mark = pStubMsg->BufferMark;
1235 unsigned rep, count, stride;
1237 unsigned char *saved_buffer = NULL;
1239 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc);
1241 if (*pFormat != RPC_FC_PP) return NULL;
1244 if (pStubMsg->PointerBufferMark)
1246 saved_buffer = pStubMsg->Buffer;
1247 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1248 pStubMsg->PointerBufferMark = NULL;
1251 while (pFormat[0] != RPC_FC_END) {
1252 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1253 switch (pFormat[0]) {
1255 FIXME("unknown repeat type %d\n", pFormat[0]);
1256 case RPC_FC_NO_REPEAT:
1262 case RPC_FC_FIXED_REPEAT:
1263 rep = *(const WORD*)&pFormat[2];
1264 stride = *(const WORD*)&pFormat[4];
1265 count = *(const WORD*)&pFormat[8];
1268 case RPC_FC_VARIABLE_REPEAT:
1269 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1270 stride = *(const WORD*)&pFormat[2];
1271 count = *(const WORD*)&pFormat[6];
1275 for (i = 0; i < rep; i++) {
1276 PFORMAT_STRING info = pFormat;
1277 unsigned char *bufdstbase = pDstBuffer + (i * stride);
1278 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1279 unsigned char *bufbase = Mark + (i * stride);
1282 for (u=0; u<count; u++,info+=8) {
1283 unsigned char **bufdstptr = (unsigned char **)(bufdstbase + *(const SHORT*)&info[2]);
1284 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1285 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1286 PointerUnmarshall(pStubMsg, bufptr, bufdstptr, *memsrcptr, info+4, fMustAlloc);
1289 pFormat += 8 * count;
1294 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1295 pStubMsg->Buffer = saved_buffer;
1301 /***********************************************************************
1302 * EmbeddedPointerBufferSize
1304 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1305 unsigned char *pMemory,
1306 PFORMAT_STRING pFormat)
1308 unsigned rep, count, stride;
1310 ULONG saved_buffer_length = 0;
1312 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1314 if (pStubMsg->IgnoreEmbeddedPointers) return;
1316 if (*pFormat != RPC_FC_PP) return;
1319 if (pStubMsg->PointerLength)
1321 saved_buffer_length = pStubMsg->BufferLength;
1322 pStubMsg->BufferLength = pStubMsg->PointerLength;
1323 pStubMsg->PointerLength = 0;
1326 while (pFormat[0] != RPC_FC_END) {
1327 switch (pFormat[0]) {
1329 FIXME("unknown repeat type %d\n", pFormat[0]);
1330 case RPC_FC_NO_REPEAT:
1336 case RPC_FC_FIXED_REPEAT:
1337 rep = *(const WORD*)&pFormat[2];
1338 stride = *(const WORD*)&pFormat[4];
1339 count = *(const WORD*)&pFormat[8];
1342 case RPC_FC_VARIABLE_REPEAT:
1343 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1344 stride = *(const WORD*)&pFormat[2];
1345 count = *(const WORD*)&pFormat[6];
1349 for (i = 0; i < rep; i++) {
1350 PFORMAT_STRING info = pFormat;
1351 unsigned char *membase = pMemory + (i * stride);
1354 for (u=0; u<count; u++,info+=8) {
1355 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1356 unsigned char *saved_memory = pStubMsg->Memory;
1358 pStubMsg->Memory = pMemory;
1359 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1360 pStubMsg->Memory = saved_memory;
1363 pFormat += 8 * count;
1366 if (saved_buffer_length)
1368 pStubMsg->PointerLength = pStubMsg->BufferLength;
1369 pStubMsg->BufferLength = saved_buffer_length;
1373 /***********************************************************************
1374 * EmbeddedPointerMemorySize [internal]
1376 static ULONG EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1377 PFORMAT_STRING pFormat)
1379 unsigned char *Mark = pStubMsg->BufferMark;
1380 unsigned rep, count, stride;
1382 unsigned char *saved_buffer = NULL;
1384 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1386 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1388 if (pStubMsg->PointerBufferMark)
1390 saved_buffer = pStubMsg->Buffer;
1391 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1392 pStubMsg->PointerBufferMark = NULL;
1395 if (*pFormat != RPC_FC_PP) return 0;
1398 while (pFormat[0] != RPC_FC_END) {
1399 switch (pFormat[0]) {
1401 FIXME("unknown repeat type %d\n", pFormat[0]);
1402 case RPC_FC_NO_REPEAT:
1408 case RPC_FC_FIXED_REPEAT:
1409 rep = *(const WORD*)&pFormat[2];
1410 stride = *(const WORD*)&pFormat[4];
1411 count = *(const WORD*)&pFormat[8];
1414 case RPC_FC_VARIABLE_REPEAT:
1415 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1416 stride = *(const WORD*)&pFormat[2];
1417 count = *(const WORD*)&pFormat[6];
1421 for (i = 0; i < rep; i++) {
1422 PFORMAT_STRING info = pFormat;
1423 unsigned char *bufbase = Mark + (i * stride);
1425 for (u=0; u<count; u++,info+=8) {
1426 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1427 PointerMemorySize(pStubMsg, bufptr, info+4);
1430 pFormat += 8 * count;
1435 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1436 pStubMsg->Buffer = saved_buffer;
1442 /***********************************************************************
1443 * EmbeddedPointerFree [internal]
1445 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1446 unsigned char *pMemory,
1447 PFORMAT_STRING pFormat)
1449 unsigned rep, count, stride;
1452 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1453 if (*pFormat != RPC_FC_PP) return;
1456 while (pFormat[0] != RPC_FC_END) {
1457 switch (pFormat[0]) {
1459 FIXME("unknown repeat type %d\n", pFormat[0]);
1460 case RPC_FC_NO_REPEAT:
1466 case RPC_FC_FIXED_REPEAT:
1467 rep = *(const WORD*)&pFormat[2];
1468 stride = *(const WORD*)&pFormat[4];
1469 count = *(const WORD*)&pFormat[8];
1472 case RPC_FC_VARIABLE_REPEAT:
1473 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1474 stride = *(const WORD*)&pFormat[2];
1475 count = *(const WORD*)&pFormat[6];
1479 for (i = 0; i < rep; i++) {
1480 PFORMAT_STRING info = pFormat;
1481 unsigned char *membase = pMemory + (i * stride);
1484 for (u=0; u<count; u++,info+=8) {
1485 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1486 unsigned char *saved_memory = pStubMsg->Memory;
1488 pStubMsg->Memory = pMemory;
1489 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1490 pStubMsg->Memory = saved_memory;
1493 pFormat += 8 * count;
1497 /***********************************************************************
1498 * NdrPointerMarshall [RPCRT4.@]
1500 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1501 unsigned char *pMemory,
1502 PFORMAT_STRING pFormat)
1504 unsigned char *Buffer;
1506 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1508 /* Increment the buffer here instead of in PointerMarshall,
1509 * as that is used by embedded pointers which already handle the incrementing
1510 * the buffer, and shouldn't write any additional pointer data to the wire */
1511 if (*pFormat != RPC_FC_RP)
1513 align_pointer_clear(&pStubMsg->Buffer, 4);
1514 Buffer = pStubMsg->Buffer;
1515 safe_buffer_increment(pStubMsg, 4);
1518 Buffer = pStubMsg->Buffer;
1520 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1525 /***********************************************************************
1526 * NdrPointerUnmarshall [RPCRT4.@]
1528 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1529 unsigned char **ppMemory,
1530 PFORMAT_STRING pFormat,
1531 unsigned char fMustAlloc)
1533 unsigned char *Buffer;
1535 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1537 if (*pFormat == RPC_FC_RP)
1539 Buffer = pStubMsg->Buffer;
1540 /* Do the NULL ref pointer check here because embedded pointers can be
1541 * NULL if the type the pointer is embedded in was allocated rather than
1542 * being passed in by the client */
1543 if (pStubMsg->IsClient && !*ppMemory)
1545 ERR("NULL ref pointer is not allowed\n");
1546 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1551 /* Increment the buffer here instead of in PointerUnmarshall,
1552 * as that is used by embedded pointers which already handle the incrementing
1553 * the buffer, and shouldn't read any additional pointer data from the
1555 align_pointer(&pStubMsg->Buffer, 4);
1556 Buffer = pStubMsg->Buffer;
1557 safe_buffer_increment(pStubMsg, 4);
1560 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1565 /***********************************************************************
1566 * NdrPointerBufferSize [RPCRT4.@]
1568 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1569 unsigned char *pMemory,
1570 PFORMAT_STRING pFormat)
1572 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1574 /* Increment the buffer length here instead of in PointerBufferSize,
1575 * as that is used by embedded pointers which already handle the buffer
1576 * length, and shouldn't write anything more to the wire */
1577 if (*pFormat != RPC_FC_RP)
1579 align_length(&pStubMsg->BufferLength, 4);
1580 safe_buffer_length_increment(pStubMsg, 4);
1583 PointerBufferSize(pStubMsg, pMemory, pFormat);
1586 /***********************************************************************
1587 * NdrPointerMemorySize [RPCRT4.@]
1589 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1590 PFORMAT_STRING pFormat)
1592 unsigned char *Buffer = pStubMsg->Buffer;
1593 if (*pFormat != RPC_FC_RP)
1595 align_pointer(&pStubMsg->Buffer, 4);
1596 safe_buffer_increment(pStubMsg, 4);
1598 align_length(&pStubMsg->MemorySize, sizeof(void *));
1599 return PointerMemorySize(pStubMsg, Buffer, pFormat);
1602 /***********************************************************************
1603 * NdrPointerFree [RPCRT4.@]
1605 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1606 unsigned char *pMemory,
1607 PFORMAT_STRING pFormat)
1609 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1610 PointerFree(pStubMsg, pMemory, pFormat);
1613 /***********************************************************************
1614 * NdrSimpleTypeMarshall [RPCRT4.@]
1616 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1617 unsigned char FormatChar )
1619 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1622 /***********************************************************************
1623 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1625 * Unmarshall a base type.
1628 * Doesn't check that the buffer is long enough before copying, so the caller
1631 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1632 unsigned char FormatChar )
1634 #define BASE_TYPE_UNMARSHALL(type) \
1635 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
1636 TRACE("pMemory: %p\n", pMemory); \
1637 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1638 pStubMsg->Buffer += sizeof(type);
1646 BASE_TYPE_UNMARSHALL(UCHAR);
1647 TRACE("value: 0x%02x\n", *pMemory);
1652 BASE_TYPE_UNMARSHALL(USHORT);
1653 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
1657 case RPC_FC_ERROR_STATUS_T:
1659 BASE_TYPE_UNMARSHALL(ULONG);
1660 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
1663 BASE_TYPE_UNMARSHALL(float);
1664 TRACE("value: %f\n", *(float *)pMemory);
1667 BASE_TYPE_UNMARSHALL(double);
1668 TRACE("value: %f\n", *(double *)pMemory);
1671 BASE_TYPE_UNMARSHALL(ULONGLONG);
1672 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
1675 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
1676 TRACE("pMemory: %p\n", pMemory);
1677 /* 16-bits on the wire, but int in memory */
1678 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
1679 pStubMsg->Buffer += sizeof(USHORT);
1680 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
1682 case RPC_FC_INT3264:
1683 align_pointer(&pStubMsg->Buffer, sizeof(INT));
1684 /* 32-bits on the wire, but int_ptr in memory */
1685 *(INT_PTR *)pMemory = *(INT *)pStubMsg->Buffer;
1686 pStubMsg->Buffer += sizeof(INT);
1687 TRACE("value: 0x%08lx\n", *(INT_PTR *)pMemory);
1689 case RPC_FC_UINT3264:
1690 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
1691 /* 32-bits on the wire, but int_ptr in memory */
1692 *(UINT_PTR *)pMemory = *(UINT *)pStubMsg->Buffer;
1693 pStubMsg->Buffer += sizeof(UINT);
1694 TRACE("value: 0x%08lx\n", *(UINT_PTR *)pMemory);
1699 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
1701 #undef BASE_TYPE_UNMARSHALL
1704 /***********************************************************************
1705 * NdrSimpleStructMarshall [RPCRT4.@]
1707 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1708 unsigned char *pMemory,
1709 PFORMAT_STRING pFormat)
1711 unsigned size = *(const WORD*)(pFormat+2);
1712 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1714 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1);
1716 pStubMsg->BufferMark = pStubMsg->Buffer;
1717 safe_copy_to_buffer(pStubMsg, pMemory, size);
1719 if (pFormat[0] != RPC_FC_STRUCT)
1720 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1725 /***********************************************************************
1726 * NdrSimpleStructUnmarshall [RPCRT4.@]
1728 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1729 unsigned char **ppMemory,
1730 PFORMAT_STRING pFormat,
1731 unsigned char fMustAlloc)
1733 unsigned size = *(const WORD*)(pFormat+2);
1734 unsigned char *saved_buffer;
1735 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1737 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
1740 *ppMemory = NdrAllocate(pStubMsg, size);
1743 if (!pStubMsg->IsClient && !*ppMemory)
1744 /* for servers, we just point straight into the RPC buffer */
1745 *ppMemory = pStubMsg->Buffer;
1748 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1749 safe_buffer_increment(pStubMsg, size);
1750 if (pFormat[0] == RPC_FC_PSTRUCT)
1751 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1753 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1754 if (*ppMemory != saved_buffer)
1755 memcpy(*ppMemory, saved_buffer, size);
1760 /***********************************************************************
1761 * NdrSimpleStructBufferSize [RPCRT4.@]
1763 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1764 unsigned char *pMemory,
1765 PFORMAT_STRING pFormat)
1767 unsigned size = *(const WORD*)(pFormat+2);
1768 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1770 align_length(&pStubMsg->BufferLength, pFormat[1] + 1);
1772 safe_buffer_length_increment(pStubMsg, size);
1773 if (pFormat[0] != RPC_FC_STRUCT)
1774 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1777 /***********************************************************************
1778 * NdrSimpleStructMemorySize [RPCRT4.@]
1780 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1781 PFORMAT_STRING pFormat)
1783 unsigned short size = *(const WORD *)(pFormat+2);
1785 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1787 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
1788 pStubMsg->MemorySize += size;
1789 safe_buffer_increment(pStubMsg, size);
1791 if (pFormat[0] != RPC_FC_STRUCT)
1792 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1793 return pStubMsg->MemorySize;
1796 /***********************************************************************
1797 * NdrSimpleStructFree [RPCRT4.@]
1799 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1800 unsigned char *pMemory,
1801 PFORMAT_STRING pFormat)
1803 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1804 if (pFormat[0] != RPC_FC_STRUCT)
1805 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1810 static inline void array_compute_and_size_conformance(
1811 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1812 PFORMAT_STRING pFormat)
1819 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1820 SizeConformance(pStubMsg);
1822 case RPC_FC_CVARRAY:
1823 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1824 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1825 SizeConformance(pStubMsg);
1827 case RPC_FC_C_CSTRING:
1828 case RPC_FC_C_WSTRING:
1829 if (fc == RPC_FC_C_CSTRING)
1831 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1832 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1836 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1837 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1840 if (pFormat[1] == RPC_FC_STRING_SIZED)
1841 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1843 pStubMsg->MaxCount = pStubMsg->ActualCount;
1845 SizeConformance(pStubMsg);
1847 case RPC_FC_BOGUS_ARRAY:
1848 count = *(const WORD *)(pFormat + 2);
1850 if (IsConformanceOrVariancePresent(pFormat)) SizeConformance(pStubMsg);
1851 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, count);
1852 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
1855 ERR("unknown array format 0x%x\n", fc);
1856 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1860 static inline void array_buffer_size(
1861 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1862 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1866 unsigned char alignment;
1871 esize = *(const WORD*)(pFormat+2);
1872 alignment = pFormat[1] + 1;
1874 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1876 align_length(&pStubMsg->BufferLength, alignment);
1878 size = safe_multiply(esize, pStubMsg->MaxCount);
1879 /* conformance value plus array */
1880 safe_buffer_length_increment(pStubMsg, size);
1883 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1885 case RPC_FC_CVARRAY:
1886 esize = *(const WORD*)(pFormat+2);
1887 alignment = pFormat[1] + 1;
1889 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1890 pFormat = SkipVariance(pStubMsg, pFormat);
1892 SizeVariance(pStubMsg);
1894 align_length(&pStubMsg->BufferLength, alignment);
1896 size = safe_multiply(esize, pStubMsg->ActualCount);
1897 safe_buffer_length_increment(pStubMsg, size);
1900 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1902 case RPC_FC_C_CSTRING:
1903 case RPC_FC_C_WSTRING:
1904 if (fc == RPC_FC_C_CSTRING)
1909 SizeVariance(pStubMsg);
1911 size = safe_multiply(esize, pStubMsg->ActualCount);
1912 safe_buffer_length_increment(pStubMsg, size);
1914 case RPC_FC_BOGUS_ARRAY:
1915 alignment = pFormat[1] + 1;
1916 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1917 if (IsConformanceOrVariancePresent(pFormat)) SizeVariance(pStubMsg);
1918 pFormat = SkipVariance(pStubMsg, pFormat);
1920 align_length(&pStubMsg->BufferLength, alignment);
1922 size = pStubMsg->ActualCount;
1923 for (i = 0; i < size; i++)
1924 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
1927 ERR("unknown array format 0x%x\n", fc);
1928 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1932 static inline void array_compute_and_write_conformance(
1933 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1934 PFORMAT_STRING pFormat)
1937 BOOL conformance_present;
1942 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1943 WriteConformance(pStubMsg);
1945 case RPC_FC_CVARRAY:
1946 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1947 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1948 WriteConformance(pStubMsg);
1950 case RPC_FC_C_CSTRING:
1951 case RPC_FC_C_WSTRING:
1952 if (fc == RPC_FC_C_CSTRING)
1954 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1955 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1959 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1960 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1962 if (pFormat[1] == RPC_FC_STRING_SIZED)
1963 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1965 pStubMsg->MaxCount = pStubMsg->ActualCount;
1966 pStubMsg->Offset = 0;
1967 WriteConformance(pStubMsg);
1969 case RPC_FC_BOGUS_ARRAY:
1970 def = *(const WORD *)(pFormat + 2);
1972 conformance_present = IsConformanceOrVariancePresent(pFormat);
1973 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
1974 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
1975 if (conformance_present) WriteConformance(pStubMsg);
1978 ERR("unknown array format 0x%x\n", fc);
1979 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1983 static inline void array_write_variance_and_marshall(
1984 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1985 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1989 unsigned char alignment;
1994 esize = *(const WORD*)(pFormat+2);
1995 alignment = pFormat[1] + 1;
1997 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1999 align_pointer_clear(&pStubMsg->Buffer, alignment);
2001 size = safe_multiply(esize, pStubMsg->MaxCount);
2003 pStubMsg->BufferMark = pStubMsg->Buffer;
2004 safe_copy_to_buffer(pStubMsg, pMemory, size);
2007 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2009 case RPC_FC_CVARRAY:
2010 esize = *(const WORD*)(pFormat+2);
2011 alignment = pFormat[1] + 1;
2013 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2014 pFormat = SkipVariance(pStubMsg, pFormat);
2016 WriteVariance(pStubMsg);
2018 align_pointer_clear(&pStubMsg->Buffer, alignment);
2020 size = safe_multiply(esize, pStubMsg->ActualCount);
2023 pStubMsg->BufferMark = pStubMsg->Buffer;
2024 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size);
2027 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2029 case RPC_FC_C_CSTRING:
2030 case RPC_FC_C_WSTRING:
2031 if (fc == RPC_FC_C_CSTRING)
2036 WriteVariance(pStubMsg);
2038 size = safe_multiply(esize, pStubMsg->ActualCount);
2039 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2041 case RPC_FC_BOGUS_ARRAY:
2042 alignment = pFormat[1] + 1;
2043 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2044 if (IsConformanceOrVariancePresent(pFormat)) WriteVariance(pStubMsg);
2045 pFormat = SkipVariance(pStubMsg, pFormat);
2047 align_pointer_clear(&pStubMsg->Buffer, alignment);
2049 size = pStubMsg->ActualCount;
2050 for (i = 0; i < size; i++)
2051 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2054 ERR("unknown array format 0x%x\n", fc);
2055 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2059 static inline ULONG array_read_conformance(
2060 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
2067 esize = *(const WORD*)(pFormat+2);
2068 pFormat = ReadConformance(pStubMsg, pFormat+4);
2069 return safe_multiply(esize, pStubMsg->MaxCount);
2070 case RPC_FC_CVARRAY:
2071 esize = *(const WORD*)(pFormat+2);
2072 pFormat = ReadConformance(pStubMsg, pFormat+4);
2073 return safe_multiply(esize, pStubMsg->MaxCount);
2074 case RPC_FC_C_CSTRING:
2075 case RPC_FC_C_WSTRING:
2076 if (fc == RPC_FC_C_CSTRING)
2081 if (pFormat[1] == RPC_FC_STRING_SIZED)
2082 ReadConformance(pStubMsg, pFormat + 2);
2084 ReadConformance(pStubMsg, NULL);
2085 return safe_multiply(esize, pStubMsg->MaxCount);
2086 case RPC_FC_BOGUS_ARRAY:
2087 def = *(const WORD *)(pFormat + 2);
2089 if (IsConformanceOrVariancePresent(pFormat)) pFormat = ReadConformance(pStubMsg, pFormat);
2092 pStubMsg->MaxCount = def;
2093 pFormat = SkipConformance( pStubMsg, pFormat );
2095 pFormat = SkipVariance( pStubMsg, pFormat );
2097 esize = ComplexStructSize(pStubMsg, pFormat);
2098 return safe_multiply(pStubMsg->MaxCount, esize);
2100 ERR("unknown array format 0x%x\n", fc);
2101 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2105 static inline ULONG array_read_variance_and_unmarshall(
2106 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory,
2107 PFORMAT_STRING pFormat, unsigned char fMustAlloc,
2108 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall)
2110 ULONG bufsize, memsize;
2112 unsigned char alignment;
2113 unsigned char *saved_buffer, *pMemory;
2114 ULONG i, offset, count;
2119 esize = *(const WORD*)(pFormat+2);
2120 alignment = pFormat[1] + 1;
2122 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2124 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2126 align_pointer(&pStubMsg->Buffer, alignment);
2131 *ppMemory = NdrAllocate(pStubMsg, memsize);
2134 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory)
2135 /* for servers, we just point straight into the RPC buffer */
2136 *ppMemory = pStubMsg->Buffer;
2139 saved_buffer = pStubMsg->Buffer;
2140 safe_buffer_increment(pStubMsg, bufsize);
2142 pStubMsg->BufferMark = saved_buffer;
2143 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2145 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2146 if (*ppMemory != saved_buffer)
2147 memcpy(*ppMemory, saved_buffer, bufsize);
2150 case RPC_FC_CVARRAY:
2151 esize = *(const WORD*)(pFormat+2);
2152 alignment = pFormat[1] + 1;
2154 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2156 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2158 align_pointer(&pStubMsg->Buffer, alignment);
2160 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2161 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2165 offset = pStubMsg->Offset;
2167 if (!fMustAlloc && !*ppMemory)
2170 *ppMemory = NdrAllocate(pStubMsg, memsize);
2171 saved_buffer = pStubMsg->Buffer;
2172 safe_buffer_increment(pStubMsg, bufsize);
2174 pStubMsg->BufferMark = saved_buffer;
2175 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat,
2178 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2181 case RPC_FC_C_CSTRING:
2182 case RPC_FC_C_WSTRING:
2183 if (fc == RPC_FC_C_CSTRING)
2188 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2190 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2192 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2193 pStubMsg->ActualCount, pStubMsg->MaxCount);
2194 RpcRaiseException(RPC_S_INVALID_BOUND);
2196 if (pStubMsg->Offset)
2198 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2199 RpcRaiseException(RPC_S_INVALID_BOUND);
2202 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2203 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2205 validate_string_data(pStubMsg, bufsize, esize);
2210 *ppMemory = NdrAllocate(pStubMsg, memsize);
2213 if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
2214 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
2215 /* if the data in the RPC buffer is big enough, we just point
2216 * straight into it */
2217 *ppMemory = pStubMsg->Buffer;
2218 else if (!*ppMemory)
2219 *ppMemory = NdrAllocate(pStubMsg, memsize);
2222 if (*ppMemory == pStubMsg->Buffer)
2223 safe_buffer_increment(pStubMsg, bufsize);
2225 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2227 if (*pFormat == RPC_FC_C_CSTRING)
2228 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
2230 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
2234 case RPC_FC_BOGUS_ARRAY:
2235 alignment = pFormat[1] + 1;
2236 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2237 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2239 esize = ComplexStructSize(pStubMsg, pFormat);
2240 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2242 assert( fUnmarshall );
2244 if (!fMustAlloc && !*ppMemory)
2247 *ppMemory = NdrAllocate(pStubMsg, memsize);
2249 align_pointer(&pStubMsg->Buffer, alignment);
2250 saved_buffer = pStubMsg->Buffer;
2252 pMemory = *ppMemory;
2253 count = pStubMsg->ActualCount;
2254 for (i = 0; i < count; i++)
2255 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
2256 return pStubMsg->Buffer - saved_buffer;
2259 ERR("unknown array format 0x%x\n", fc);
2260 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2264 static inline void array_memory_size(
2265 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
2266 unsigned char fHasPointers)
2268 ULONG i, count, SavedMemorySize;
2269 ULONG bufsize, memsize;
2271 unsigned char alignment;
2276 esize = *(const WORD*)(pFormat+2);
2277 alignment = pFormat[1] + 1;
2279 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2281 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2282 pStubMsg->MemorySize += memsize;
2284 align_pointer(&pStubMsg->Buffer, alignment);
2286 pStubMsg->BufferMark = pStubMsg->Buffer;
2287 safe_buffer_increment(pStubMsg, bufsize);
2290 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2292 case RPC_FC_CVARRAY:
2293 esize = *(const WORD*)(pFormat+2);
2294 alignment = pFormat[1] + 1;
2296 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2298 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2300 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2301 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2302 pStubMsg->MemorySize += memsize;
2304 align_pointer(&pStubMsg->Buffer, alignment);
2306 pStubMsg->BufferMark = pStubMsg->Buffer;
2307 safe_buffer_increment(pStubMsg, bufsize);
2310 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2312 case RPC_FC_C_CSTRING:
2313 case RPC_FC_C_WSTRING:
2314 if (fc == RPC_FC_C_CSTRING)
2319 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2321 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2323 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2324 pStubMsg->ActualCount, pStubMsg->MaxCount);
2325 RpcRaiseException(RPC_S_INVALID_BOUND);
2327 if (pStubMsg->Offset)
2329 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2330 RpcRaiseException(RPC_S_INVALID_BOUND);
2333 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2334 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2336 validate_string_data(pStubMsg, bufsize, esize);
2338 safe_buffer_increment(pStubMsg, bufsize);
2339 pStubMsg->MemorySize += memsize;
2341 case RPC_FC_BOGUS_ARRAY:
2342 alignment = pFormat[1] + 1;
2343 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2344 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2346 align_pointer(&pStubMsg->Buffer, alignment);
2348 SavedMemorySize = pStubMsg->MemorySize;
2350 esize = ComplexStructSize(pStubMsg, pFormat);
2351 memsize = safe_multiply(pStubMsg->MaxCount, esize);
2353 count = pStubMsg->ActualCount;
2354 for (i = 0; i < count; i++)
2355 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
2357 pStubMsg->MemorySize = SavedMemorySize + memsize;
2360 ERR("unknown array format 0x%x\n", fc);
2361 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2365 static inline void array_free(
2366 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
2367 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
2374 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2376 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2378 case RPC_FC_CVARRAY:
2379 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2380 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2382 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2384 case RPC_FC_C_CSTRING:
2385 case RPC_FC_C_WSTRING:
2386 /* No embedded pointers so nothing to do */
2388 case RPC_FC_BOGUS_ARRAY:
2389 count = *(const WORD *)(pFormat + 2);
2390 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, count);
2391 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2393 count = pStubMsg->ActualCount;
2394 for (i = 0; i < count; i++)
2395 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2398 ERR("unknown array format 0x%x\n", fc);
2399 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2404 * NdrConformantString:
2406 * What MS calls a ConformantString is, in DCE terminology,
2407 * a Varying-Conformant String.
2409 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2410 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2411 * into unmarshalled string)
2412 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2414 * data: CHARTYPE[maxlen]
2416 * ], where CHARTYPE is the appropriate character type (specified externally)
2420 /***********************************************************************
2421 * NdrConformantStringMarshall [RPCRT4.@]
2423 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
2424 unsigned char *pszMessage, PFORMAT_STRING pFormat)
2426 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
2428 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2429 ERR("Unhandled string type: %#x\n", pFormat[0]);
2430 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2433 /* allow compiler to optimise inline function by passing constant into
2434 * these functions */
2435 if (pFormat[0] == RPC_FC_C_CSTRING) {
2436 array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2438 array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2439 pFormat, TRUE /* fHasPointers */);
2441 array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2443 array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2444 pFormat, TRUE /* fHasPointers */);
2450 /***********************************************************************
2451 * NdrConformantStringBufferSize [RPCRT4.@]
2453 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2454 unsigned char* pMemory, PFORMAT_STRING pFormat)
2456 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2458 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2459 ERR("Unhandled string type: %#x\n", pFormat[0]);
2460 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2463 /* allow compiler to optimise inline function by passing constant into
2464 * these functions */
2465 if (pFormat[0] == RPC_FC_C_CSTRING) {
2466 array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory,
2468 array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat,
2469 TRUE /* fHasPointers */);
2471 array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory,
2473 array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat,
2474 TRUE /* fHasPointers */);
2478 /************************************************************************
2479 * NdrConformantStringMemorySize [RPCRT4.@]
2481 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2482 PFORMAT_STRING pFormat )
2484 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2486 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2487 ERR("Unhandled string type: %#x\n", pFormat[0]);
2488 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2491 /* allow compiler to optimise inline function by passing constant into
2492 * these functions */
2493 if (pFormat[0] == RPC_FC_C_CSTRING) {
2494 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2495 array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat,
2496 TRUE /* fHasPointers */);
2498 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2499 array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat,
2500 TRUE /* fHasPointers */);
2503 return pStubMsg->MemorySize;
2506 /************************************************************************
2507 * NdrConformantStringUnmarshall [RPCRT4.@]
2509 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2510 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
2512 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2513 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2515 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2516 ERR("Unhandled string type: %#x\n", *pFormat);
2517 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2520 /* allow compiler to optimise inline function by passing constant into
2521 * these functions */
2522 if (pFormat[0] == RPC_FC_C_CSTRING) {
2523 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2524 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory,
2525 pFormat, fMustAlloc,
2526 TRUE /* fUseBufferMemoryServer */,
2527 TRUE /* fUnmarshall */);
2529 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2530 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory,
2531 pFormat, fMustAlloc,
2532 TRUE /* fUseBufferMemoryServer */,
2533 TRUE /* fUnmarshall */);
2539 /***********************************************************************
2540 * NdrNonConformantStringMarshall [RPCRT4.@]
2542 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2543 unsigned char *pMemory,
2544 PFORMAT_STRING pFormat)
2546 ULONG esize, size, maxsize;
2548 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2550 maxsize = *(const USHORT *)&pFormat[2];
2552 if (*pFormat == RPC_FC_CSTRING)
2555 const char *str = (const char *)pMemory;
2556 while (i < maxsize && str[i]) i++;
2557 TRACE("string=%s\n", debugstr_an(str, i));
2558 pStubMsg->ActualCount = i + 1;
2561 else if (*pFormat == RPC_FC_WSTRING)
2564 const WCHAR *str = (const WCHAR *)pMemory;
2565 while (i < maxsize && str[i]) i++;
2566 TRACE("string=%s\n", debugstr_wn(str, i));
2567 pStubMsg->ActualCount = i + 1;
2572 ERR("Unhandled string type: %#x\n", *pFormat);
2573 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2576 pStubMsg->Offset = 0;
2577 WriteVariance(pStubMsg);
2579 size = safe_multiply(esize, pStubMsg->ActualCount);
2580 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2585 /***********************************************************************
2586 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2588 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2589 unsigned char **ppMemory,
2590 PFORMAT_STRING pFormat,
2591 unsigned char fMustAlloc)
2593 ULONG bufsize, memsize, esize, maxsize;
2595 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2596 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2598 maxsize = *(const USHORT *)&pFormat[2];
2600 ReadVariance(pStubMsg, NULL, maxsize);
2601 if (pStubMsg->Offset)
2603 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2604 RpcRaiseException(RPC_S_INVALID_BOUND);
2607 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2608 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2611 ERR("Unhandled string type: %#x\n", *pFormat);
2612 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2615 memsize = esize * maxsize;
2616 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2618 validate_string_data(pStubMsg, bufsize, esize);
2620 if (!fMustAlloc && !*ppMemory)
2623 *ppMemory = NdrAllocate(pStubMsg, memsize);
2625 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2627 if (*pFormat == RPC_FC_CSTRING) {
2628 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
2630 else if (*pFormat == RPC_FC_WSTRING) {
2631 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
2637 /***********************************************************************
2638 * NdrNonConformantStringBufferSize [RPCRT4.@]
2640 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2641 unsigned char *pMemory,
2642 PFORMAT_STRING pFormat)
2644 ULONG esize, maxsize;
2646 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2648 maxsize = *(const USHORT *)&pFormat[2];
2650 SizeVariance(pStubMsg);
2652 if (*pFormat == RPC_FC_CSTRING)
2655 const char *str = (const char *)pMemory;
2656 while (i < maxsize && str[i]) i++;
2657 TRACE("string=%s\n", debugstr_an(str, i));
2658 pStubMsg->ActualCount = i + 1;
2661 else if (*pFormat == RPC_FC_WSTRING)
2664 const WCHAR *str = (const WCHAR *)pMemory;
2665 while (i < maxsize && str[i]) i++;
2666 TRACE("string=%s\n", debugstr_wn(str, i));
2667 pStubMsg->ActualCount = i + 1;
2672 ERR("Unhandled string type: %#x\n", *pFormat);
2673 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2676 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2679 /***********************************************************************
2680 * NdrNonConformantStringMemorySize [RPCRT4.@]
2682 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2683 PFORMAT_STRING pFormat)
2685 ULONG bufsize, memsize, esize, maxsize;
2687 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2689 maxsize = *(const USHORT *)&pFormat[2];
2691 ReadVariance(pStubMsg, NULL, maxsize);
2693 if (pStubMsg->Offset)
2695 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2696 RpcRaiseException(RPC_S_INVALID_BOUND);
2699 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2700 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2703 ERR("Unhandled string type: %#x\n", *pFormat);
2704 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2707 memsize = esize * maxsize;
2708 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2710 validate_string_data(pStubMsg, bufsize, esize);
2712 safe_buffer_increment(pStubMsg, bufsize);
2713 pStubMsg->MemorySize += memsize;
2715 return pStubMsg->MemorySize;
2720 #include "pshpack1.h"
2724 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2728 #include "poppack.h"
2730 static ULONG EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2731 PFORMAT_STRING pFormat)
2735 case RPC_FC_PSTRUCT:
2736 case RPC_FC_CSTRUCT:
2737 case RPC_FC_BOGUS_STRUCT:
2738 case RPC_FC_SMFARRAY:
2739 case RPC_FC_SMVARRAY:
2740 case RPC_FC_CSTRING:
2741 return *(const WORD*)&pFormat[2];
2742 case RPC_FC_USER_MARSHAL:
2743 return *(const WORD*)&pFormat[4];
2744 case RPC_FC_RANGE: {
2745 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2750 return sizeof(UCHAR);
2754 return sizeof(USHORT);
2758 case RPC_FC_INT3264:
2759 case RPC_FC_UINT3264:
2760 return sizeof(ULONG);
2762 return sizeof(float);
2764 return sizeof(double);
2766 return sizeof(ULONGLONG);
2768 return sizeof(UINT);
2770 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2771 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2774 case RPC_FC_NON_ENCAPSULATED_UNION:
2776 if (pStubMsg->fHasNewCorrDesc)
2781 pFormat += *(const SHORT*)pFormat;
2782 return *(const SHORT*)pFormat;
2784 return sizeof(void *);
2785 case RPC_FC_WSTRING:
2786 return *(const WORD*)&pFormat[2] * 2;
2788 FIXME("unhandled embedded type %02x\n", *pFormat);
2794 static ULONG EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2795 PFORMAT_STRING pFormat)
2797 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2801 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2805 return m(pStubMsg, pFormat);
2809 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2810 unsigned char *pMemory,
2811 PFORMAT_STRING pFormat,
2812 PFORMAT_STRING pPointer)
2814 PFORMAT_STRING desc;
2818 while (*pFormat != RPC_FC_END) {
2824 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2825 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2831 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2832 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2837 USHORT val = *(DWORD *)pMemory;
2838 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2839 if (32767 < *(DWORD*)pMemory)
2840 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2841 safe_copy_to_buffer(pStubMsg, &val, 2);
2848 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2849 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2852 case RPC_FC_INT3264:
2853 case RPC_FC_UINT3264:
2855 UINT val = *(UINT_PTR *)pMemory;
2856 TRACE("int3264=%ld <= %p\n", *(UINT_PTR *)pMemory, pMemory);
2857 safe_copy_to_buffer(pStubMsg, &val, sizeof(UINT));
2858 pMemory += sizeof(UINT_PTR);
2862 TRACE("float=%f <= %p\n", *(float*)pMemory, pMemory);
2863 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
2864 pMemory += sizeof(float);
2867 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2868 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2872 TRACE("double=%f <= %p\n", *(double*)pMemory, pMemory);
2873 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
2874 pMemory += sizeof(double);
2880 case RPC_FC_POINTER:
2882 unsigned char *saved_buffer;
2883 int pointer_buffer_mark_set = 0;
2884 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2885 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2886 if (*pFormat != RPC_FC_POINTER)
2888 if (*pPointer != RPC_FC_RP)
2889 align_pointer_clear(&pStubMsg->Buffer, 4);
2890 saved_buffer = pStubMsg->Buffer;
2891 if (pStubMsg->PointerBufferMark)
2893 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2894 pStubMsg->PointerBufferMark = NULL;
2895 pointer_buffer_mark_set = 1;
2897 else if (*pPointer != RPC_FC_RP)
2898 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2899 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2900 if (pointer_buffer_mark_set)
2902 STD_OVERFLOW_CHECK(pStubMsg);
2903 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2904 pStubMsg->Buffer = saved_buffer;
2905 if (*pPointer != RPC_FC_RP)
2906 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2908 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2909 if (*pFormat == RPC_FC_POINTER)
2913 pMemory += sizeof(void *);
2916 case RPC_FC_ALIGNM2:
2917 align_pointer(&pMemory, 2);
2919 case RPC_FC_ALIGNM4:
2920 align_pointer(&pMemory, 4);
2922 case RPC_FC_ALIGNM8:
2923 align_pointer(&pMemory, 8);
2925 case RPC_FC_STRUCTPAD1:
2926 case RPC_FC_STRUCTPAD2:
2927 case RPC_FC_STRUCTPAD3:
2928 case RPC_FC_STRUCTPAD4:
2929 case RPC_FC_STRUCTPAD5:
2930 case RPC_FC_STRUCTPAD6:
2931 case RPC_FC_STRUCTPAD7:
2932 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2934 case RPC_FC_EMBEDDED_COMPLEX:
2935 pMemory += pFormat[1];
2937 desc = pFormat + *(const SHORT*)pFormat;
2938 size = EmbeddedComplexSize(pStubMsg, desc);
2939 TRACE("embedded complex (size=%d) <= %p\n", size, pMemory);
2940 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2943 /* for some reason interface pointers aren't generated as
2944 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2945 * they still need the derefencing treatment that pointers are
2947 if (*desc == RPC_FC_IP)
2948 m(pStubMsg, *(unsigned char **)pMemory, desc);
2950 m(pStubMsg, pMemory, desc);
2952 else FIXME("no marshaller for embedded type %02x\n", *desc);
2959 FIXME("unhandled format 0x%02x\n", *pFormat);
2967 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2968 unsigned char *pMemory,
2969 PFORMAT_STRING pFormat,
2970 PFORMAT_STRING pPointer,
2971 unsigned char fMustAlloc)
2973 PFORMAT_STRING desc;
2977 while (*pFormat != RPC_FC_END) {
2983 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2984 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2990 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2991 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2997 safe_copy_from_buffer(pStubMsg, &val, 2);
2998 *(DWORD*)pMemory = val;
2999 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
3000 if (32767 < *(DWORD*)pMemory)
3001 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
3008 safe_copy_from_buffer(pStubMsg, pMemory, 4);
3009 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
3012 case RPC_FC_INT3264:
3015 safe_copy_from_buffer(pStubMsg, &val, 4);
3016 *(INT_PTR *)pMemory = val;
3017 TRACE("int3264=%ld => %p\n", *(INT_PTR*)pMemory, pMemory);
3018 pMemory += sizeof(INT_PTR);
3021 case RPC_FC_UINT3264:
3024 safe_copy_from_buffer(pStubMsg, &val, 4);
3025 *(UINT_PTR *)pMemory = val;
3026 TRACE("uint3264=%ld => %p\n", *(UINT_PTR*)pMemory, pMemory);
3027 pMemory += sizeof(UINT_PTR);
3031 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(float));
3032 TRACE("float=%f => %p\n", *(float*)pMemory, pMemory);
3033 pMemory += sizeof(float);
3036 safe_copy_from_buffer(pStubMsg, pMemory, 8);
3037 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
3041 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(double));
3042 TRACE("double=%f => %p\n", *(double*)pMemory, pMemory);
3043 pMemory += sizeof(double);
3049 case RPC_FC_POINTER:
3051 unsigned char *saved_buffer;
3052 int pointer_buffer_mark_set = 0;
3053 TRACE("pointer => %p\n", pMemory);
3054 if (*pFormat != RPC_FC_POINTER)
3056 if (*pPointer != RPC_FC_RP)
3057 align_pointer(&pStubMsg->Buffer, 4);
3058 saved_buffer = pStubMsg->Buffer;
3059 if (pStubMsg->PointerBufferMark)
3061 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3062 pStubMsg->PointerBufferMark = NULL;
3063 pointer_buffer_mark_set = 1;
3065 else if (*pPointer != RPC_FC_RP)
3066 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3068 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
3069 if (pointer_buffer_mark_set)
3071 STD_OVERFLOW_CHECK(pStubMsg);
3072 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3073 pStubMsg->Buffer = saved_buffer;
3074 if (*pPointer != RPC_FC_RP)
3075 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3077 if (*pFormat == RPC_FC_POINTER)
3081 pMemory += sizeof(void *);
3084 case RPC_FC_ALIGNM2:
3085 align_pointer_clear(&pMemory, 2);
3087 case RPC_FC_ALIGNM4:
3088 align_pointer_clear(&pMemory, 4);
3090 case RPC_FC_ALIGNM8:
3091 align_pointer_clear(&pMemory, 8);
3093 case RPC_FC_STRUCTPAD1:
3094 case RPC_FC_STRUCTPAD2:
3095 case RPC_FC_STRUCTPAD3:
3096 case RPC_FC_STRUCTPAD4:
3097 case RPC_FC_STRUCTPAD5:
3098 case RPC_FC_STRUCTPAD6:
3099 case RPC_FC_STRUCTPAD7:
3100 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
3101 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3103 case RPC_FC_EMBEDDED_COMPLEX:
3104 pMemory += pFormat[1];
3106 desc = pFormat + *(const SHORT*)pFormat;
3107 size = EmbeddedComplexSize(pStubMsg, desc);
3108 TRACE("embedded complex (size=%d) => %p\n", size, pMemory);
3110 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
3111 * since the type is part of the memory block that is encompassed by
3112 * the whole complex type. Memory is forced to allocate when pointers
3113 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
3114 * clearing the memory we pass in to the unmarshaller */
3115 memset(pMemory, 0, size);
3116 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
3119 /* for some reason interface pointers aren't generated as
3120 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3121 * they still need the derefencing treatment that pointers are
3123 if (*desc == RPC_FC_IP)
3124 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
3126 m(pStubMsg, &pMemory, desc, FALSE);
3128 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
3135 FIXME("unhandled format %d\n", *pFormat);
3143 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3144 unsigned char *pMemory,
3145 PFORMAT_STRING pFormat,
3146 PFORMAT_STRING pPointer)
3148 PFORMAT_STRING desc;
3152 while (*pFormat != RPC_FC_END) {
3158 safe_buffer_length_increment(pStubMsg, 1);
3164 safe_buffer_length_increment(pStubMsg, 2);
3168 safe_buffer_length_increment(pStubMsg, 2);
3175 safe_buffer_length_increment(pStubMsg, 4);
3178 case RPC_FC_INT3264:
3179 case RPC_FC_UINT3264:
3180 safe_buffer_length_increment(pStubMsg, 4);
3181 pMemory += sizeof(INT_PTR);
3185 safe_buffer_length_increment(pStubMsg, 8);
3192 case RPC_FC_POINTER:
3193 if (*pFormat != RPC_FC_POINTER)
3195 if (!pStubMsg->IgnoreEmbeddedPointers)
3197 int saved_buffer_length = pStubMsg->BufferLength;
3198 pStubMsg->BufferLength = pStubMsg->PointerLength;
3199 pStubMsg->PointerLength = 0;
3200 if(!pStubMsg->BufferLength)
3201 ERR("BufferLength == 0??\n");
3202 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
3203 pStubMsg->PointerLength = pStubMsg->BufferLength;
3204 pStubMsg->BufferLength = saved_buffer_length;
3206 if (*pPointer != RPC_FC_RP)
3208 align_length(&pStubMsg->BufferLength, 4);
3209 safe_buffer_length_increment(pStubMsg, 4);
3211 if (*pFormat == RPC_FC_POINTER)
3215 pMemory += sizeof(void*);
3217 case RPC_FC_ALIGNM2:
3218 align_pointer(&pMemory, 2);
3220 case RPC_FC_ALIGNM4:
3221 align_pointer(&pMemory, 4);
3223 case RPC_FC_ALIGNM8:
3224 align_pointer(&pMemory, 8);
3226 case RPC_FC_STRUCTPAD1:
3227 case RPC_FC_STRUCTPAD2:
3228 case RPC_FC_STRUCTPAD3:
3229 case RPC_FC_STRUCTPAD4:
3230 case RPC_FC_STRUCTPAD5:
3231 case RPC_FC_STRUCTPAD6:
3232 case RPC_FC_STRUCTPAD7:
3233 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3235 case RPC_FC_EMBEDDED_COMPLEX:
3236 pMemory += pFormat[1];
3238 desc = pFormat + *(const SHORT*)pFormat;
3239 size = EmbeddedComplexSize(pStubMsg, desc);
3240 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
3243 /* for some reason interface pointers aren't generated as
3244 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3245 * they still need the derefencing treatment that pointers are
3247 if (*desc == RPC_FC_IP)
3248 m(pStubMsg, *(unsigned char **)pMemory, desc);
3250 m(pStubMsg, pMemory, desc);
3252 else FIXME("no buffersizer for embedded type %02x\n", *desc);
3259 FIXME("unhandled format 0x%02x\n", *pFormat);
3267 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
3268 unsigned char *pMemory,
3269 PFORMAT_STRING pFormat,
3270 PFORMAT_STRING pPointer)
3272 PFORMAT_STRING desc;
3276 while (*pFormat != RPC_FC_END) {
3296 case RPC_FC_INT3264:
3297 case RPC_FC_UINT3264:
3298 pMemory += sizeof(INT_PTR);
3308 case RPC_FC_POINTER:
3309 if (*pFormat != RPC_FC_POINTER)
3311 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3312 if (*pFormat == RPC_FC_POINTER)
3316 pMemory += sizeof(void *);
3318 case RPC_FC_ALIGNM2:
3319 align_pointer(&pMemory, 2);
3321 case RPC_FC_ALIGNM4:
3322 align_pointer(&pMemory, 4);
3324 case RPC_FC_ALIGNM8:
3325 align_pointer(&pMemory, 8);
3327 case RPC_FC_STRUCTPAD1:
3328 case RPC_FC_STRUCTPAD2:
3329 case RPC_FC_STRUCTPAD3:
3330 case RPC_FC_STRUCTPAD4:
3331 case RPC_FC_STRUCTPAD5:
3332 case RPC_FC_STRUCTPAD6:
3333 case RPC_FC_STRUCTPAD7:
3334 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3336 case RPC_FC_EMBEDDED_COMPLEX:
3337 pMemory += pFormat[1];
3339 desc = pFormat + *(const SHORT*)pFormat;
3340 size = EmbeddedComplexSize(pStubMsg, desc);
3341 m = NdrFreer[*desc & NDR_TABLE_MASK];
3344 /* for some reason interface pointers aren't generated as
3345 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3346 * they still need the derefencing treatment that pointers are
3348 if (*desc == RPC_FC_IP)
3349 m(pStubMsg, *(unsigned char **)pMemory, desc);
3351 m(pStubMsg, pMemory, desc);
3359 FIXME("unhandled format 0x%02x\n", *pFormat);
3367 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3368 PFORMAT_STRING pFormat,
3369 PFORMAT_STRING pPointer)
3371 PFORMAT_STRING desc;
3374 while (*pFormat != RPC_FC_END) {
3381 safe_buffer_increment(pStubMsg, 1);
3387 safe_buffer_increment(pStubMsg, 2);
3391 safe_buffer_increment(pStubMsg, 2);
3398 safe_buffer_increment(pStubMsg, 4);
3400 case RPC_FC_INT3264:
3401 case RPC_FC_UINT3264:
3402 size += sizeof(INT_PTR);
3403 safe_buffer_increment(pStubMsg, 4);
3408 safe_buffer_increment(pStubMsg, 8);
3414 case RPC_FC_POINTER:
3416 unsigned char *saved_buffer;
3417 int pointer_buffer_mark_set = 0;
3418 if (*pFormat != RPC_FC_POINTER)
3420 if (*pPointer != RPC_FC_RP)
3421 align_pointer(&pStubMsg->Buffer, 4);
3422 saved_buffer = pStubMsg->Buffer;
3423 if (pStubMsg->PointerBufferMark)
3425 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3426 pStubMsg->PointerBufferMark = NULL;
3427 pointer_buffer_mark_set = 1;
3429 else if (*pPointer != RPC_FC_RP)
3430 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3432 if (!pStubMsg->IgnoreEmbeddedPointers)
3433 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3434 if (pointer_buffer_mark_set)
3436 STD_OVERFLOW_CHECK(pStubMsg);
3437 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3438 pStubMsg->Buffer = saved_buffer;
3439 if (*pPointer != RPC_FC_RP)
3440 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3442 if (*pFormat == RPC_FC_POINTER)
3446 size += sizeof(void *);
3449 case RPC_FC_ALIGNM2:
3450 align_length(&size, 2);
3452 case RPC_FC_ALIGNM4:
3453 align_length(&size, 4);
3455 case RPC_FC_ALIGNM8:
3456 align_length(&size, 8);
3458 case RPC_FC_STRUCTPAD1:
3459 case RPC_FC_STRUCTPAD2:
3460 case RPC_FC_STRUCTPAD3:
3461 case RPC_FC_STRUCTPAD4:
3462 case RPC_FC_STRUCTPAD5:
3463 case RPC_FC_STRUCTPAD6:
3464 case RPC_FC_STRUCTPAD7:
3465 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3467 case RPC_FC_EMBEDDED_COMPLEX:
3470 desc = pFormat + *(const SHORT*)pFormat;
3471 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3477 FIXME("unhandled format 0x%02x\n", *pFormat);
3485 ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
3487 PFORMAT_STRING desc;
3490 while (*pFormat != RPC_FC_END) {
3510 case RPC_FC_INT3264:
3511 case RPC_FC_UINT3264:
3512 size += sizeof(INT_PTR);
3522 case RPC_FC_POINTER:
3523 size += sizeof(void *);
3524 if (*pFormat != RPC_FC_POINTER)
3527 case RPC_FC_ALIGNM2:
3528 align_length(&size, 2);
3530 case RPC_FC_ALIGNM4:
3531 align_length(&size, 4);
3533 case RPC_FC_ALIGNM8:
3534 align_length(&size, 8);
3536 case RPC_FC_STRUCTPAD1:
3537 case RPC_FC_STRUCTPAD2:
3538 case RPC_FC_STRUCTPAD3:
3539 case RPC_FC_STRUCTPAD4:
3540 case RPC_FC_STRUCTPAD5:
3541 case RPC_FC_STRUCTPAD6:
3542 case RPC_FC_STRUCTPAD7:
3543 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3545 case RPC_FC_EMBEDDED_COMPLEX:
3548 desc = pFormat + *(const SHORT*)pFormat;
3549 size += EmbeddedComplexSize(pStubMsg, desc);
3555 FIXME("unhandled format 0x%02x\n", *pFormat);
3563 /***********************************************************************
3564 * NdrComplexStructMarshall [RPCRT4.@]
3566 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3567 unsigned char *pMemory,
3568 PFORMAT_STRING pFormat)
3570 PFORMAT_STRING conf_array = NULL;
3571 PFORMAT_STRING pointer_desc = NULL;
3572 unsigned char *OldMemory = pStubMsg->Memory;
3573 int pointer_buffer_mark_set = 0;
3575 ULONG max_count = 0;
3578 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3580 if (!pStubMsg->PointerBufferMark)
3582 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3583 /* save buffer length */
3584 ULONG saved_buffer_length = pStubMsg->BufferLength;
3586 /* get the buffer pointer after complex array data, but before
3588 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3589 pStubMsg->IgnoreEmbeddedPointers = 1;
3590 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3591 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3593 /* save it for use by embedded pointer code later */
3594 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3595 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - pStubMsg->Buffer));
3596 pointer_buffer_mark_set = 1;
3598 /* restore the original buffer length */
3599 pStubMsg->BufferLength = saved_buffer_length;
3602 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1);
3605 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3607 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3610 pStubMsg->Memory = pMemory;
3614 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3615 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3616 pMemory + struct_size, conf_array);
3617 /* these could be changed in ComplexMarshall so save them for later */
3618 max_count = pStubMsg->MaxCount;
3619 count = pStubMsg->ActualCount;
3620 offset = pStubMsg->Offset;
3623 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3627 pStubMsg->MaxCount = max_count;
3628 pStubMsg->ActualCount = count;
3629 pStubMsg->Offset = offset;
3630 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3631 conf_array, TRUE /* fHasPointers */);
3634 pStubMsg->Memory = OldMemory;
3636 if (pointer_buffer_mark_set)
3638 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3639 pStubMsg->PointerBufferMark = NULL;
3642 STD_OVERFLOW_CHECK(pStubMsg);
3647 /***********************************************************************
3648 * NdrComplexStructUnmarshall [RPCRT4.@]
3650 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3651 unsigned char **ppMemory,
3652 PFORMAT_STRING pFormat,
3653 unsigned char fMustAlloc)
3655 unsigned size = *(const WORD*)(pFormat+2);
3656 PFORMAT_STRING conf_array = NULL;
3657 PFORMAT_STRING pointer_desc = NULL;
3658 unsigned char *pMemory;
3659 int pointer_buffer_mark_set = 0;
3661 ULONG max_count = 0;
3663 ULONG array_size = 0;
3665 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3667 if (!pStubMsg->PointerBufferMark)
3669 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3670 /* save buffer pointer */
3671 unsigned char *saved_buffer = pStubMsg->Buffer;
3673 /* get the buffer pointer after complex array data, but before
3675 pStubMsg->IgnoreEmbeddedPointers = 1;
3676 NdrComplexStructMemorySize(pStubMsg, pFormat);
3677 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3679 /* save it for use by embedded pointer code later */
3680 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3681 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - saved_buffer));
3682 pointer_buffer_mark_set = 1;
3684 /* restore the original buffer */
3685 pStubMsg->Buffer = saved_buffer;
3688 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3691 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3693 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3698 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3701 /* these could be changed in ComplexMarshall so save them for later */
3702 max_count = pStubMsg->MaxCount;
3703 count = pStubMsg->ActualCount;
3704 offset = pStubMsg->Offset;
3707 if (!fMustAlloc && !*ppMemory)
3710 *ppMemory = NdrAllocate(pStubMsg, size);
3712 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3716 pStubMsg->MaxCount = max_count;
3717 pStubMsg->ActualCount = count;
3718 pStubMsg->Offset = offset;
3720 memset(pMemory, 0, array_size);
3721 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3723 FALSE /* fUseBufferMemoryServer */,
3724 TRUE /* fUnmarshall */);
3727 if (pointer_buffer_mark_set)
3729 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3730 pStubMsg->PointerBufferMark = NULL;
3736 /***********************************************************************
3737 * NdrComplexStructBufferSize [RPCRT4.@]
3739 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3740 unsigned char *pMemory,
3741 PFORMAT_STRING pFormat)
3743 PFORMAT_STRING conf_array = NULL;
3744 PFORMAT_STRING pointer_desc = NULL;
3745 unsigned char *OldMemory = pStubMsg->Memory;
3746 int pointer_length_set = 0;
3748 ULONG max_count = 0;
3751 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3753 align_length(&pStubMsg->BufferLength, pFormat[1] + 1);
3755 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3757 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3758 ULONG saved_buffer_length = pStubMsg->BufferLength;
3760 /* get the buffer length after complex struct data, but before
3762 pStubMsg->IgnoreEmbeddedPointers = 1;
3763 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3764 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3766 /* save it for use by embedded pointer code later */
3767 pStubMsg->PointerLength = pStubMsg->BufferLength;
3768 pointer_length_set = 1;
3769 TRACE("difference = 0x%x\n", pStubMsg->PointerLength - saved_buffer_length);
3771 /* restore the original buffer length */
3772 pStubMsg->BufferLength = saved_buffer_length;
3776 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3778 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3781 pStubMsg->Memory = pMemory;
3785 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3786 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3789 /* these could be changed in ComplexMarshall so save them for later */
3790 max_count = pStubMsg->MaxCount;
3791 count = pStubMsg->ActualCount;
3792 offset = pStubMsg->Offset;
3795 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3799 pStubMsg->MaxCount = max_count;
3800 pStubMsg->ActualCount = count;
3801 pStubMsg->Offset = offset;
3802 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3803 TRUE /* fHasPointers */);
3806 pStubMsg->Memory = OldMemory;
3808 if(pointer_length_set)
3810 pStubMsg->BufferLength = pStubMsg->PointerLength;
3811 pStubMsg->PointerLength = 0;
3816 /***********************************************************************
3817 * NdrComplexStructMemorySize [RPCRT4.@]
3819 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3820 PFORMAT_STRING pFormat)
3822 unsigned size = *(const WORD*)(pFormat+2);
3823 PFORMAT_STRING conf_array = NULL;
3824 PFORMAT_STRING pointer_desc = NULL;
3826 ULONG max_count = 0;
3829 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3831 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3834 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3836 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3841 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3843 /* these could be changed in ComplexStructMemorySize so save them for
3845 max_count = pStubMsg->MaxCount;
3846 count = pStubMsg->ActualCount;
3847 offset = pStubMsg->Offset;
3850 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3854 pStubMsg->MaxCount = max_count;
3855 pStubMsg->ActualCount = count;
3856 pStubMsg->Offset = offset;
3857 array_memory_size(conf_array[0], pStubMsg, conf_array,
3858 TRUE /* fHasPointers */);
3864 /***********************************************************************
3865 * NdrComplexStructFree [RPCRT4.@]
3867 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3868 unsigned char *pMemory,
3869 PFORMAT_STRING pFormat)
3871 PFORMAT_STRING conf_array = NULL;
3872 PFORMAT_STRING pointer_desc = NULL;
3873 unsigned char *OldMemory = pStubMsg->Memory;
3875 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3878 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3880 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3883 pStubMsg->Memory = pMemory;
3885 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3888 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3889 TRUE /* fHasPointers */);
3891 pStubMsg->Memory = OldMemory;
3894 /***********************************************************************
3895 * NdrConformantArrayMarshall [RPCRT4.@]
3897 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3898 unsigned char *pMemory,
3899 PFORMAT_STRING pFormat)
3901 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3902 if (pFormat[0] != RPC_FC_CARRAY)
3904 ERR("invalid format = 0x%x\n", pFormat[0]);
3905 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3908 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory,
3910 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3911 TRUE /* fHasPointers */);
3916 /***********************************************************************
3917 * NdrConformantArrayUnmarshall [RPCRT4.@]
3919 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3920 unsigned char **ppMemory,
3921 PFORMAT_STRING pFormat,
3922 unsigned char fMustAlloc)
3924 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3925 if (pFormat[0] != RPC_FC_CARRAY)
3927 ERR("invalid format = 0x%x\n", pFormat[0]);
3928 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3931 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3932 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat,
3934 TRUE /* fUseBufferMemoryServer */,
3935 TRUE /* fUnmarshall */);
3940 /***********************************************************************
3941 * NdrConformantArrayBufferSize [RPCRT4.@]
3943 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3944 unsigned char *pMemory,
3945 PFORMAT_STRING pFormat)
3947 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3948 if (pFormat[0] != RPC_FC_CARRAY)
3950 ERR("invalid format = 0x%x\n", pFormat[0]);
3951 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3954 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat);
3955 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3956 TRUE /* fHasPointers */);
3959 /***********************************************************************
3960 * NdrConformantArrayMemorySize [RPCRT4.@]
3962 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3963 PFORMAT_STRING pFormat)
3965 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3966 if (pFormat[0] != RPC_FC_CARRAY)
3968 ERR("invalid format = 0x%x\n", pFormat[0]);
3969 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3972 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3973 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
3975 return pStubMsg->MemorySize;
3978 /***********************************************************************
3979 * NdrConformantArrayFree [RPCRT4.@]
3981 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3982 unsigned char *pMemory,
3983 PFORMAT_STRING pFormat)
3985 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3986 if (pFormat[0] != RPC_FC_CARRAY)
3988 ERR("invalid format = 0x%x\n", pFormat[0]);
3989 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3992 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3993 TRUE /* fHasPointers */);
3997 /***********************************************************************
3998 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
4000 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
4001 unsigned char* pMemory,
4002 PFORMAT_STRING pFormat )
4004 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4006 if (pFormat[0] != RPC_FC_CVARRAY)
4008 ERR("invalid format type %x\n", pFormat[0]);
4009 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4013 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
4015 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory,
4016 pFormat, TRUE /* fHasPointers */);
4022 /***********************************************************************
4023 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
4025 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
4026 unsigned char** ppMemory,
4027 PFORMAT_STRING pFormat,
4028 unsigned char fMustAlloc )
4030 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4032 if (pFormat[0] != RPC_FC_CVARRAY)
4034 ERR("invalid format type %x\n", pFormat[0]);
4035 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4039 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
4040 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory,
4041 pFormat, fMustAlloc,
4042 TRUE /* fUseBufferMemoryServer */,
4043 TRUE /* fUnmarshall */);
4049 /***********************************************************************
4050 * NdrConformantVaryingArrayFree [RPCRT4.@]
4052 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
4053 unsigned char* pMemory,
4054 PFORMAT_STRING pFormat )
4056 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4058 if (pFormat[0] != RPC_FC_CVARRAY)
4060 ERR("invalid format type %x\n", pFormat[0]);
4061 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4065 array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
4066 TRUE /* fHasPointers */);
4070 /***********************************************************************
4071 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
4073 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
4074 unsigned char* pMemory, PFORMAT_STRING pFormat )
4076 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4078 if (pFormat[0] != RPC_FC_CVARRAY)
4080 ERR("invalid format type %x\n", pFormat[0]);
4081 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4085 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
4087 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
4088 TRUE /* fHasPointers */);
4092 /***********************************************************************
4093 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
4095 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
4096 PFORMAT_STRING pFormat )
4098 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4100 if (pFormat[0] != RPC_FC_CVARRAY)
4102 ERR("invalid format type %x\n", pFormat[0]);
4103 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4104 return pStubMsg->MemorySize;
4107 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
4108 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat,
4109 TRUE /* fHasPointers */);
4111 return pStubMsg->MemorySize;
4115 /***********************************************************************
4116 * NdrComplexArrayMarshall [RPCRT4.@]
4118 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4119 unsigned char *pMemory,
4120 PFORMAT_STRING pFormat)
4122 int pointer_buffer_mark_set = 0;
4124 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4126 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4128 ERR("invalid format type %x\n", pFormat[0]);
4129 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4133 if (!pStubMsg->PointerBufferMark)
4135 /* save buffer fields that may be changed by buffer sizer functions
4136 * and that may be needed later on */
4137 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4138 ULONG saved_buffer_length = pStubMsg->BufferLength;
4139 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4140 ULONG saved_offset = pStubMsg->Offset;
4141 ULONG saved_actual_count = pStubMsg->ActualCount;
4143 /* get the buffer pointer after complex array data, but before
4145 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
4146 pStubMsg->IgnoreEmbeddedPointers = 1;
4147 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4148 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4150 /* save it for use by embedded pointer code later */
4151 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
4152 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer));
4153 pointer_buffer_mark_set = 1;
4155 /* restore fields */
4156 pStubMsg->ActualCount = saved_actual_count;
4157 pStubMsg->Offset = saved_offset;
4158 pStubMsg->MaxCount = saved_max_count;
4159 pStubMsg->BufferLength = saved_buffer_length;
4162 array_compute_and_write_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4163 array_write_variance_and_marshall(RPC_FC_BOGUS_ARRAY, pStubMsg,
4164 pMemory, pFormat, TRUE /* fHasPointers */);
4166 STD_OVERFLOW_CHECK(pStubMsg);
4168 if (pointer_buffer_mark_set)
4170 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4171 pStubMsg->PointerBufferMark = NULL;
4177 /***********************************************************************
4178 * NdrComplexArrayUnmarshall [RPCRT4.@]
4180 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4181 unsigned char **ppMemory,
4182 PFORMAT_STRING pFormat,
4183 unsigned char fMustAlloc)
4185 unsigned char *saved_buffer;
4186 int pointer_buffer_mark_set = 0;
4187 int saved_ignore_embedded;
4189 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4191 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4193 ERR("invalid format type %x\n", pFormat[0]);
4194 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4198 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4199 /* save buffer pointer */
4200 saved_buffer = pStubMsg->Buffer;
4201 /* get the buffer pointer after complex array data, but before
4203 pStubMsg->IgnoreEmbeddedPointers = 1;
4204 pStubMsg->MemorySize = 0;
4205 NdrComplexArrayMemorySize(pStubMsg, pFormat);
4206 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4208 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - saved_buffer));
4209 if (!pStubMsg->PointerBufferMark)
4211 /* save it for use by embedded pointer code later */
4212 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4213 pointer_buffer_mark_set = 1;
4215 /* restore the original buffer */
4216 pStubMsg->Buffer = saved_buffer;
4218 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
4219 array_read_variance_and_unmarshall(RPC_FC_BOGUS_ARRAY, pStubMsg, ppMemory, pFormat, fMustAlloc,
4220 TRUE /* fUseBufferMemoryServer */, TRUE /* fUnmarshall */);
4222 if (pointer_buffer_mark_set)
4224 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4225 pStubMsg->PointerBufferMark = NULL;
4231 /***********************************************************************
4232 * NdrComplexArrayBufferSize [RPCRT4.@]
4234 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4235 unsigned char *pMemory,
4236 PFORMAT_STRING pFormat)
4238 int pointer_length_set = 0;
4240 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4242 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4244 ERR("invalid format type %x\n", pFormat[0]);
4245 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4249 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
4251 /* save buffer fields that may be changed by buffer sizer functions
4252 * and that may be needed later on */
4253 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4254 ULONG saved_buffer_length = pStubMsg->BufferLength;
4255 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4256 ULONG saved_offset = pStubMsg->Offset;
4257 ULONG saved_actual_count = pStubMsg->ActualCount;
4259 /* get the buffer pointer after complex array data, but before
4261 pStubMsg->IgnoreEmbeddedPointers = 1;
4262 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4263 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4265 /* save it for use by embedded pointer code later */
4266 pStubMsg->PointerLength = pStubMsg->BufferLength;
4267 pointer_length_set = 1;
4269 /* restore fields */
4270 pStubMsg->ActualCount = saved_actual_count;
4271 pStubMsg->Offset = saved_offset;
4272 pStubMsg->MaxCount = saved_max_count;
4273 pStubMsg->BufferLength = saved_buffer_length;
4276 array_compute_and_size_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4277 array_buffer_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat, TRUE /* fHasPointers */);
4279 if(pointer_length_set)
4281 pStubMsg->BufferLength = pStubMsg->PointerLength;
4282 pStubMsg->PointerLength = 0;
4286 /***********************************************************************
4287 * NdrComplexArrayMemorySize [RPCRT4.@]
4289 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4290 PFORMAT_STRING pFormat)
4292 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4294 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4296 ERR("invalid format type %x\n", pFormat[0]);
4297 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4301 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
4302 array_memory_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
4303 return pStubMsg->MemorySize;
4306 /***********************************************************************
4307 * NdrComplexArrayFree [RPCRT4.@]
4309 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4310 unsigned char *pMemory,
4311 PFORMAT_STRING pFormat)
4313 ULONG i, count, def;
4315 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4317 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4319 ERR("invalid format type %x\n", pFormat[0]);
4320 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4324 def = *(const WORD*)&pFormat[2];
4327 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4328 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4330 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4331 TRACE("variance = %d\n", pStubMsg->ActualCount);
4333 count = pStubMsg->ActualCount;
4334 for (i = 0; i < count; i++)
4335 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4338 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4339 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4340 USER_MARSHAL_CB *umcb)
4342 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4343 pStubMsg->RpcMsg->DataRepresentation);
4344 umcb->pStubMsg = pStubMsg;
4345 umcb->pReserve = NULL;
4346 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4347 umcb->CBType = cbtype;
4348 umcb->pFormat = pFormat;
4349 umcb->pTypeFormat = NULL /* FIXME */;
4352 #define USER_MARSHAL_PTR_PREFIX \
4353 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4354 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4356 /***********************************************************************
4357 * NdrUserMarshalMarshall [RPCRT4.@]
4359 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4360 unsigned char *pMemory,
4361 PFORMAT_STRING pFormat)
4363 unsigned flags = pFormat[1];
4364 unsigned index = *(const WORD*)&pFormat[2];
4365 unsigned char *saved_buffer = NULL;
4366 USER_MARSHAL_CB umcb;
4368 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4369 TRACE("index=%d\n", index);
4371 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4373 if (flags & USER_MARSHAL_POINTER)
4375 align_pointer_clear(&pStubMsg->Buffer, 4);
4376 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4377 pStubMsg->Buffer += 4;
4378 if (pStubMsg->PointerBufferMark)
4380 saved_buffer = pStubMsg->Buffer;
4381 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4382 pStubMsg->PointerBufferMark = NULL;
4384 align_pointer_clear(&pStubMsg->Buffer, 8);
4387 align_pointer_clear(&pStubMsg->Buffer, (flags & 0xf) + 1);
4390 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4391 &umcb.Flags, pStubMsg->Buffer, pMemory);
4395 STD_OVERFLOW_CHECK(pStubMsg);
4396 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4397 pStubMsg->Buffer = saved_buffer;
4400 STD_OVERFLOW_CHECK(pStubMsg);
4405 /***********************************************************************
4406 * NdrUserMarshalUnmarshall [RPCRT4.@]
4408 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4409 unsigned char **ppMemory,
4410 PFORMAT_STRING pFormat,
4411 unsigned char fMustAlloc)
4413 unsigned flags = pFormat[1];
4414 unsigned index = *(const WORD*)&pFormat[2];
4415 DWORD memsize = *(const WORD*)&pFormat[4];
4416 unsigned char *saved_buffer = NULL;
4417 USER_MARSHAL_CB umcb;
4419 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4420 TRACE("index=%d\n", index);
4422 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4424 if (flags & USER_MARSHAL_POINTER)
4426 align_pointer(&pStubMsg->Buffer, 4);
4427 /* skip pointer prefix */
4428 pStubMsg->Buffer += 4;
4429 if (pStubMsg->PointerBufferMark)
4431 saved_buffer = pStubMsg->Buffer;
4432 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4433 pStubMsg->PointerBufferMark = NULL;
4435 align_pointer(&pStubMsg->Buffer, 8);
4438 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4440 if (!fMustAlloc && !*ppMemory)
4444 *ppMemory = NdrAllocate(pStubMsg, memsize);
4445 memset(*ppMemory, 0, memsize);
4449 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4450 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4454 STD_OVERFLOW_CHECK(pStubMsg);
4455 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4456 pStubMsg->Buffer = saved_buffer;
4462 /***********************************************************************
4463 * NdrUserMarshalBufferSize [RPCRT4.@]
4465 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4466 unsigned char *pMemory,
4467 PFORMAT_STRING pFormat)
4469 unsigned flags = pFormat[1];
4470 unsigned index = *(const WORD*)&pFormat[2];
4471 DWORD bufsize = *(const WORD*)&pFormat[6];
4472 USER_MARSHAL_CB umcb;
4473 ULONG saved_buffer_length = 0;
4475 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4476 TRACE("index=%d\n", index);
4478 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4480 if (flags & USER_MARSHAL_POINTER)
4482 align_length(&pStubMsg->BufferLength, 4);
4483 /* skip pointer prefix */
4484 safe_buffer_length_increment(pStubMsg, 4);
4485 if (pStubMsg->IgnoreEmbeddedPointers)
4487 if (pStubMsg->PointerLength)
4489 saved_buffer_length = pStubMsg->BufferLength;
4490 pStubMsg->BufferLength = pStubMsg->PointerLength;
4491 pStubMsg->PointerLength = 0;
4493 align_length(&pStubMsg->BufferLength, 8);
4496 align_length(&pStubMsg->BufferLength, (flags & 0xf) + 1);
4499 TRACE("size=%d\n", bufsize);
4500 safe_buffer_length_increment(pStubMsg, bufsize);
4503 pStubMsg->BufferLength =
4504 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4505 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4507 if (saved_buffer_length)
4509 pStubMsg->PointerLength = pStubMsg->BufferLength;
4510 pStubMsg->BufferLength = saved_buffer_length;
4515 /***********************************************************************
4516 * NdrUserMarshalMemorySize [RPCRT4.@]
4518 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4519 PFORMAT_STRING pFormat)
4521 unsigned flags = pFormat[1];
4522 unsigned index = *(const WORD*)&pFormat[2];
4523 DWORD memsize = *(const WORD*)&pFormat[4];
4524 DWORD bufsize = *(const WORD*)&pFormat[6];
4526 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4527 TRACE("index=%d\n", index);
4529 pStubMsg->MemorySize += memsize;
4531 if (flags & USER_MARSHAL_POINTER)
4533 align_pointer(&pStubMsg->Buffer, 4);
4534 /* skip pointer prefix */
4535 pStubMsg->Buffer += 4;
4536 if (pStubMsg->IgnoreEmbeddedPointers)
4537 return pStubMsg->MemorySize;
4538 align_pointer(&pStubMsg->Buffer, 8);
4541 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4544 FIXME("not implemented for varying buffer size\n");
4546 pStubMsg->Buffer += bufsize;
4548 return pStubMsg->MemorySize;
4551 /***********************************************************************
4552 * NdrUserMarshalFree [RPCRT4.@]
4554 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4555 unsigned char *pMemory,
4556 PFORMAT_STRING pFormat)
4558 /* unsigned flags = pFormat[1]; */
4559 unsigned index = *(const WORD*)&pFormat[2];
4560 USER_MARSHAL_CB umcb;
4562 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4563 TRACE("index=%d\n", index);
4565 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4567 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4568 &umcb.Flags, pMemory);
4571 /***********************************************************************
4572 * NdrGetUserMarshalInfo [RPCRT4.@]
4574 RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi)
4576 USER_MARSHAL_CB *umcb = CONTAINING_RECORD(flags, USER_MARSHAL_CB, Flags);
4578 TRACE("(%p,%u,%p)\n", flags, level, umi);
4581 return RPC_S_INVALID_ARG;
4583 memset(&umi->u1.Level1, 0, sizeof(umi->u1.Level1));
4584 umi->InformationLevel = level;
4586 if (umcb->Signature != USER_MARSHAL_CB_SIGNATURE)
4587 return RPC_S_INVALID_ARG;
4589 umi->u1.Level1.pfnAllocate = umcb->pStubMsg->pfnAllocate;
4590 umi->u1.Level1.pfnFree = umcb->pStubMsg->pfnFree;
4591 umi->u1.Level1.pRpcChannelBuffer = umcb->pStubMsg->pRpcChannelBuffer;
4593 switch (umcb->CBType)
4595 case USER_MARSHAL_CB_MARSHALL:
4596 case USER_MARSHAL_CB_UNMARSHALL:
4598 RPC_MESSAGE *msg = umcb->pStubMsg->RpcMsg;
4599 unsigned char *buffer_start = msg->Buffer;
4600 unsigned char *buffer_end =
4601 (unsigned char *)msg->Buffer + msg->BufferLength;
4603 if (umcb->pStubMsg->Buffer < buffer_start ||
4604 umcb->pStubMsg->Buffer > buffer_end)
4605 return ERROR_INVALID_USER_BUFFER;
4607 umi->u1.Level1.Buffer = umcb->pStubMsg->Buffer;
4608 umi->u1.Level1.BufferSize = buffer_end - umcb->pStubMsg->Buffer;
4611 case USER_MARSHAL_CB_BUFFER_SIZE:
4612 case USER_MARSHAL_CB_FREE:
4615 WARN("unrecognised CBType %d\n", umcb->CBType);
4621 /***********************************************************************
4622 * NdrClearOutParameters [RPCRT4.@]
4624 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4625 PFORMAT_STRING pFormat,
4628 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4631 /***********************************************************************
4632 * NdrConvert [RPCRT4.@]
4634 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4636 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4637 /* FIXME: since this stub doesn't do any converting, the proper behavior
4638 is to raise an exception */
4641 /***********************************************************************
4642 * NdrConvert2 [RPCRT4.@]
4644 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4646 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4647 pStubMsg, pFormat, NumberParams);
4648 /* FIXME: since this stub doesn't do any converting, the proper behavior
4649 is to raise an exception */
4652 #include "pshpack1.h"
4653 typedef struct _NDR_CSTRUCT_FORMAT
4656 unsigned char alignment;
4657 unsigned short memory_size;
4658 short offset_to_array_description;
4659 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4660 #include "poppack.h"
4662 /***********************************************************************
4663 * NdrConformantStructMarshall [RPCRT4.@]
4665 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4666 unsigned char *pMemory,
4667 PFORMAT_STRING pFormat)
4669 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4670 PFORMAT_STRING pCArrayFormat;
4671 ULONG esize, bufsize;
4673 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4675 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4676 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4678 ERR("invalid format type %x\n", pCStructFormat->type);
4679 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4683 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4684 pCStructFormat->offset_to_array_description;
4685 if (*pCArrayFormat != RPC_FC_CARRAY)
4687 ERR("invalid array format type %x\n", pCStructFormat->type);
4688 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4691 esize = *(const WORD*)(pCArrayFormat+2);
4693 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4694 pCArrayFormat + 4, 0);
4696 WriteConformance(pStubMsg);
4698 align_pointer_clear(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4700 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4702 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4703 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4705 ERR("integer overflow of memory_size %u with bufsize %u\n",
4706 pCStructFormat->memory_size, bufsize);
4707 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4709 /* copy constant sized part of struct */
4710 pStubMsg->BufferMark = pStubMsg->Buffer;
4711 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4713 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4714 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4719 /***********************************************************************
4720 * NdrConformantStructUnmarshall [RPCRT4.@]
4722 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4723 unsigned char **ppMemory,
4724 PFORMAT_STRING pFormat,
4725 unsigned char fMustAlloc)
4727 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4728 PFORMAT_STRING pCArrayFormat;
4729 ULONG esize, bufsize;
4730 unsigned char *saved_buffer;
4732 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4734 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4735 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4737 ERR("invalid format type %x\n", pCStructFormat->type);
4738 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4741 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4742 pCStructFormat->offset_to_array_description;
4743 if (*pCArrayFormat != RPC_FC_CARRAY)
4745 ERR("invalid array format type %x\n", pCStructFormat->type);
4746 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4749 esize = *(const WORD*)(pCArrayFormat+2);
4751 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4753 align_pointer(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4755 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4757 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4758 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4760 ERR("integer overflow of memory_size %u with bufsize %u\n",
4761 pCStructFormat->memory_size, bufsize);
4762 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4767 SIZE_T size = pCStructFormat->memory_size + bufsize;
4768 *ppMemory = NdrAllocate(pStubMsg, size);
4772 if (!pStubMsg->IsClient && !*ppMemory)
4773 /* for servers, we just point straight into the RPC buffer */
4774 *ppMemory = pStubMsg->Buffer;
4777 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4778 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4779 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4780 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4782 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4783 if (*ppMemory != saved_buffer)
4784 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4789 /***********************************************************************
4790 * NdrConformantStructBufferSize [RPCRT4.@]
4792 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4793 unsigned char *pMemory,
4794 PFORMAT_STRING pFormat)
4796 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4797 PFORMAT_STRING pCArrayFormat;
4800 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4802 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4803 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4805 ERR("invalid format type %x\n", pCStructFormat->type);
4806 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4809 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4810 pCStructFormat->offset_to_array_description;
4811 if (*pCArrayFormat != RPC_FC_CARRAY)
4813 ERR("invalid array format type %x\n", pCStructFormat->type);
4814 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4817 esize = *(const WORD*)(pCArrayFormat+2);
4819 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4820 SizeConformance(pStubMsg);
4822 align_length(&pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4824 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4826 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4827 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4829 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4830 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4833 /***********************************************************************
4834 * NdrConformantStructMemorySize [RPCRT4.@]
4836 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4837 PFORMAT_STRING pFormat)
4843 /***********************************************************************
4844 * NdrConformantStructFree [RPCRT4.@]
4846 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4847 unsigned char *pMemory,
4848 PFORMAT_STRING pFormat)
4850 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4851 PFORMAT_STRING pCArrayFormat;
4853 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4855 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4856 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4858 ERR("invalid format type %x\n", pCStructFormat->type);
4859 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4863 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4864 pCStructFormat->offset_to_array_description;
4865 if (*pCArrayFormat != RPC_FC_CARRAY)
4867 ERR("invalid array format type %x\n", pCStructFormat->type);
4868 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4872 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4873 pCArrayFormat + 4, 0);
4875 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4877 /* copy constant sized part of struct */
4878 pStubMsg->BufferMark = pStubMsg->Buffer;
4880 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4881 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4884 /***********************************************************************
4885 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4887 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4888 unsigned char *pMemory,
4889 PFORMAT_STRING pFormat)
4891 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4892 PFORMAT_STRING pCVArrayFormat;
4894 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4896 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4897 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4899 ERR("invalid format type %x\n", pCVStructFormat->type);
4900 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4904 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4905 pCVStructFormat->offset_to_array_description;
4907 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4908 pMemory + pCVStructFormat->memory_size,
4911 align_pointer_clear(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4913 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4915 /* write constant sized part */
4916 pStubMsg->BufferMark = pStubMsg->Buffer;
4917 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4919 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4920 pMemory + pCVStructFormat->memory_size,
4921 pCVArrayFormat, FALSE /* fHasPointers */);
4923 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4928 /***********************************************************************
4929 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4931 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4932 unsigned char **ppMemory,
4933 PFORMAT_STRING pFormat,
4934 unsigned char fMustAlloc)
4936 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4937 PFORMAT_STRING pCVArrayFormat;
4938 ULONG memsize, bufsize;
4939 unsigned char *saved_buffer, *saved_array_buffer;
4941 unsigned char *array_memory;
4943 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4945 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4946 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4948 ERR("invalid format type %x\n", pCVStructFormat->type);
4949 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4953 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4954 pCVStructFormat->offset_to_array_description;
4956 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4959 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4961 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4963 /* work out how much memory to allocate if we need to do so */
4964 if (!fMustAlloc && !*ppMemory)
4968 SIZE_T size = pCVStructFormat->memory_size + memsize;
4969 *ppMemory = NdrAllocate(pStubMsg, size);
4972 /* mark the start of the constant data */
4973 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4974 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4976 array_memory = *ppMemory + pCVStructFormat->memory_size;
4977 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
4978 &array_memory, pCVArrayFormat,
4979 FALSE /* fMustAlloc */,
4980 FALSE /* fUseServerBufferMemory */,
4981 FALSE /* fUnmarshall */);
4983 /* save offset in case unmarshalling pointers changes it */
4984 offset = pStubMsg->Offset;
4986 /* mark the start of the array data */
4987 saved_array_buffer = pStubMsg->Buffer;
4988 safe_buffer_increment(pStubMsg, bufsize);
4990 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4992 /* copy the constant data */
4993 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
4994 /* copy the array data */
4995 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
4996 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
4997 saved_array_buffer, bufsize);
4999 if (*pCVArrayFormat == RPC_FC_C_CSTRING)
5000 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
5001 else if (*pCVArrayFormat == RPC_FC_C_WSTRING)
5002 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
5007 /***********************************************************************
5008 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
5010 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5011 unsigned char *pMemory,
5012 PFORMAT_STRING pFormat)
5014 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5015 PFORMAT_STRING pCVArrayFormat;
5017 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5019 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5020 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5022 ERR("invalid format type %x\n", pCVStructFormat->type);
5023 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5027 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5028 pCVStructFormat->offset_to_array_description;
5029 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
5030 pMemory + pCVStructFormat->memory_size,
5033 align_length(&pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
5035 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5037 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
5039 array_buffer_size(*pCVArrayFormat, pStubMsg,
5040 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5041 FALSE /* fHasPointers */);
5043 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5046 /***********************************************************************
5047 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
5049 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5050 PFORMAT_STRING pFormat)
5052 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5053 PFORMAT_STRING pCVArrayFormat;
5055 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5057 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5058 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5060 ERR("invalid format type %x\n", pCVStructFormat->type);
5061 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5065 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5066 pCVStructFormat->offset_to_array_description;
5067 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
5069 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
5071 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5073 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
5074 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
5075 FALSE /* fHasPointers */);
5077 pStubMsg->MemorySize += pCVStructFormat->memory_size;
5079 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5081 return pStubMsg->MemorySize;
5084 /***********************************************************************
5085 * NdrConformantVaryingStructFree [RPCRT4.@]
5087 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
5088 unsigned char *pMemory,
5089 PFORMAT_STRING pFormat)
5091 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5092 PFORMAT_STRING pCVArrayFormat;
5094 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5096 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5097 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5099 ERR("invalid format type %x\n", pCVStructFormat->type);
5100 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5104 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5105 pCVStructFormat->offset_to_array_description;
5106 array_free(*pCVArrayFormat, pStubMsg,
5107 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5108 FALSE /* fHasPointers */);
5110 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5112 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5115 #include "pshpack1.h"
5119 unsigned char alignment;
5120 unsigned short total_size;
5121 } NDR_SMFARRAY_FORMAT;
5126 unsigned char alignment;
5128 } NDR_LGFARRAY_FORMAT;
5129 #include "poppack.h"
5131 /***********************************************************************
5132 * NdrFixedArrayMarshall [RPCRT4.@]
5134 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5135 unsigned char *pMemory,
5136 PFORMAT_STRING pFormat)
5138 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5141 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5143 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5144 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5146 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5147 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5151 align_pointer_clear(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5153 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5155 total_size = pSmFArrayFormat->total_size;
5156 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5160 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5161 total_size = pLgFArrayFormat->total_size;
5162 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5165 pStubMsg->BufferMark = pStubMsg->Buffer;
5166 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
5168 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5173 /***********************************************************************
5174 * NdrFixedArrayUnmarshall [RPCRT4.@]
5176 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5177 unsigned char **ppMemory,
5178 PFORMAT_STRING pFormat,
5179 unsigned char fMustAlloc)
5181 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5183 unsigned char *saved_buffer;
5185 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5187 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5188 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5190 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5191 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5195 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5197 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5199 total_size = pSmFArrayFormat->total_size;
5200 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5204 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5205 total_size = pLgFArrayFormat->total_size;
5206 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5210 *ppMemory = NdrAllocate(pStubMsg, total_size);
5213 if (!pStubMsg->IsClient && !*ppMemory)
5214 /* for servers, we just point straight into the RPC buffer */
5215 *ppMemory = pStubMsg->Buffer;
5218 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5219 safe_buffer_increment(pStubMsg, total_size);
5220 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5222 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
5223 if (*ppMemory != saved_buffer)
5224 memcpy(*ppMemory, saved_buffer, total_size);
5229 /***********************************************************************
5230 * NdrFixedArrayBufferSize [RPCRT4.@]
5232 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5233 unsigned char *pMemory,
5234 PFORMAT_STRING pFormat)
5236 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5239 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5241 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5242 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5244 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5245 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5249 align_length(&pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
5251 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5253 total_size = pSmFArrayFormat->total_size;
5254 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5258 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5259 total_size = pLgFArrayFormat->total_size;
5260 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5262 safe_buffer_length_increment(pStubMsg, total_size);
5264 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5267 /***********************************************************************
5268 * NdrFixedArrayMemorySize [RPCRT4.@]
5270 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5271 PFORMAT_STRING pFormat)
5273 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5276 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5278 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5279 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5281 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5282 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5286 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5288 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5290 total_size = pSmFArrayFormat->total_size;
5291 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5295 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5296 total_size = pLgFArrayFormat->total_size;
5297 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5299 pStubMsg->BufferMark = pStubMsg->Buffer;
5300 safe_buffer_increment(pStubMsg, total_size);
5301 pStubMsg->MemorySize += total_size;
5303 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5308 /***********************************************************************
5309 * NdrFixedArrayFree [RPCRT4.@]
5311 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5312 unsigned char *pMemory,
5313 PFORMAT_STRING pFormat)
5315 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5317 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5319 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5320 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5322 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5323 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5327 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5328 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5331 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5332 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5335 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5338 /***********************************************************************
5339 * NdrVaryingArrayMarshall [RPCRT4.@]
5341 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5342 unsigned char *pMemory,
5343 PFORMAT_STRING pFormat)
5345 unsigned char alignment;
5346 DWORD elements, esize;
5349 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5351 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5352 (pFormat[0] != RPC_FC_LGVARRAY))
5354 ERR("invalid format type %x\n", pFormat[0]);
5355 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5359 alignment = pFormat[1] + 1;
5361 if (pFormat[0] == RPC_FC_SMVARRAY)
5364 pFormat += sizeof(WORD);
5365 elements = *(const WORD*)pFormat;
5366 pFormat += sizeof(WORD);
5371 pFormat += sizeof(DWORD);
5372 elements = *(const DWORD*)pFormat;
5373 pFormat += sizeof(DWORD);
5376 esize = *(const WORD*)pFormat;
5377 pFormat += sizeof(WORD);
5379 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5380 if ((pStubMsg->ActualCount > elements) ||
5381 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5383 RpcRaiseException(RPC_S_INVALID_BOUND);
5387 WriteVariance(pStubMsg);
5389 align_pointer_clear(&pStubMsg->Buffer, alignment);
5391 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5392 pStubMsg->BufferMark = pStubMsg->Buffer;
5393 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5395 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5400 /***********************************************************************
5401 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5403 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5404 unsigned char **ppMemory,
5405 PFORMAT_STRING pFormat,
5406 unsigned char fMustAlloc)
5408 unsigned char alignment;
5409 DWORD size, elements, esize;
5411 unsigned char *saved_buffer;
5414 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5416 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5417 (pFormat[0] != RPC_FC_LGVARRAY))
5419 ERR("invalid format type %x\n", pFormat[0]);
5420 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5424 alignment = pFormat[1] + 1;
5426 if (pFormat[0] == RPC_FC_SMVARRAY)
5429 size = *(const WORD*)pFormat;
5430 pFormat += sizeof(WORD);
5431 elements = *(const WORD*)pFormat;
5432 pFormat += sizeof(WORD);
5437 size = *(const DWORD*)pFormat;
5438 pFormat += sizeof(DWORD);
5439 elements = *(const DWORD*)pFormat;
5440 pFormat += sizeof(DWORD);
5443 esize = *(const WORD*)pFormat;
5444 pFormat += sizeof(WORD);
5446 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5448 align_pointer(&pStubMsg->Buffer, alignment);
5450 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5451 offset = pStubMsg->Offset;
5453 if (!fMustAlloc && !*ppMemory)
5456 *ppMemory = NdrAllocate(pStubMsg, size);
5457 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5458 safe_buffer_increment(pStubMsg, bufsize);
5460 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5462 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5467 /***********************************************************************
5468 * NdrVaryingArrayBufferSize [RPCRT4.@]
5470 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5471 unsigned char *pMemory,
5472 PFORMAT_STRING pFormat)
5474 unsigned char alignment;
5475 DWORD elements, esize;
5477 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5479 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5480 (pFormat[0] != RPC_FC_LGVARRAY))
5482 ERR("invalid format type %x\n", pFormat[0]);
5483 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5487 alignment = pFormat[1] + 1;
5489 if (pFormat[0] == RPC_FC_SMVARRAY)
5492 pFormat += sizeof(WORD);
5493 elements = *(const WORD*)pFormat;
5494 pFormat += sizeof(WORD);
5499 pFormat += sizeof(DWORD);
5500 elements = *(const DWORD*)pFormat;
5501 pFormat += sizeof(DWORD);
5504 esize = *(const WORD*)pFormat;
5505 pFormat += sizeof(WORD);
5507 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5508 if ((pStubMsg->ActualCount > elements) ||
5509 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5511 RpcRaiseException(RPC_S_INVALID_BOUND);
5515 SizeVariance(pStubMsg);
5517 align_length(&pStubMsg->BufferLength, alignment);
5519 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5521 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5524 /***********************************************************************
5525 * NdrVaryingArrayMemorySize [RPCRT4.@]
5527 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5528 PFORMAT_STRING pFormat)
5530 unsigned char alignment;
5531 DWORD size, elements, esize;
5533 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5535 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5536 (pFormat[0] != RPC_FC_LGVARRAY))
5538 ERR("invalid format type %x\n", pFormat[0]);
5539 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5543 alignment = pFormat[1] + 1;
5545 if (pFormat[0] == RPC_FC_SMVARRAY)
5548 size = *(const WORD*)pFormat;
5549 pFormat += sizeof(WORD);
5550 elements = *(const WORD*)pFormat;
5551 pFormat += sizeof(WORD);
5556 size = *(const DWORD*)pFormat;
5557 pFormat += sizeof(DWORD);
5558 elements = *(const DWORD*)pFormat;
5559 pFormat += sizeof(DWORD);
5562 esize = *(const WORD*)pFormat;
5563 pFormat += sizeof(WORD);
5565 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5567 align_pointer(&pStubMsg->Buffer, alignment);
5569 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5570 pStubMsg->MemorySize += size;
5572 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5574 return pStubMsg->MemorySize;
5577 /***********************************************************************
5578 * NdrVaryingArrayFree [RPCRT4.@]
5580 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5581 unsigned char *pMemory,
5582 PFORMAT_STRING pFormat)
5586 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5588 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5589 (pFormat[0] != RPC_FC_LGVARRAY))
5591 ERR("invalid format type %x\n", pFormat[0]);
5592 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5596 if (pFormat[0] == RPC_FC_SMVARRAY)
5599 pFormat += sizeof(WORD);
5600 elements = *(const WORD*)pFormat;
5601 pFormat += sizeof(WORD);
5606 pFormat += sizeof(DWORD);
5607 elements = *(const DWORD*)pFormat;
5608 pFormat += sizeof(DWORD);
5611 pFormat += sizeof(WORD);
5613 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5614 if ((pStubMsg->ActualCount > elements) ||
5615 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5617 RpcRaiseException(RPC_S_INVALID_BOUND);
5621 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5624 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5637 return *(const USHORT *)pMemory;
5641 return *(const ULONG *)pMemory;
5642 case RPC_FC_INT3264:
5643 case RPC_FC_UINT3264:
5644 return *(const ULONG_PTR *)pMemory;
5646 FIXME("Unhandled base type: 0x%02x\n", fc);
5651 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5653 PFORMAT_STRING pFormat)
5655 unsigned short num_arms, arm, type;
5657 num_arms = *(const SHORT*)pFormat & 0x0fff;
5659 for(arm = 0; arm < num_arms; arm++)
5661 if(discriminant == *(const ULONG*)pFormat)
5669 type = *(const unsigned short*)pFormat;
5670 TRACE("type %04x\n", type);
5671 if(arm == num_arms) /* default arm extras */
5675 ERR("no arm for 0x%x and no default case\n", discriminant);
5676 RpcRaiseException(RPC_S_INVALID_TAG);
5681 TRACE("falling back to empty default case for 0x%x\n", discriminant);
5688 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5690 unsigned short type;
5694 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5698 type = *(const unsigned short*)pFormat;
5699 if((type & 0xff00) == 0x8000)
5701 unsigned char basetype = LOBYTE(type);
5702 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5706 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5707 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5710 unsigned char *saved_buffer = NULL;
5711 int pointer_buffer_mark_set = 0;
5718 align_pointer_clear(&pStubMsg->Buffer, 4);
5719 saved_buffer = pStubMsg->Buffer;
5720 if (pStubMsg->PointerBufferMark)
5722 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5723 pStubMsg->PointerBufferMark = NULL;
5724 pointer_buffer_mark_set = 1;
5727 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5729 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5730 if (pointer_buffer_mark_set)
5732 STD_OVERFLOW_CHECK(pStubMsg);
5733 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5734 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5736 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5737 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5738 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5740 pStubMsg->Buffer = saved_buffer + 4;
5744 m(pStubMsg, pMemory, desc);
5747 else FIXME("no marshaller for embedded type %02x\n", *desc);
5752 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5753 unsigned char **ppMemory,
5755 PFORMAT_STRING pFormat,
5756 unsigned char fMustAlloc)
5758 unsigned short type;
5762 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5766 type = *(const unsigned short*)pFormat;
5767 if((type & 0xff00) == 0x8000)
5769 unsigned char basetype = LOBYTE(type);
5770 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5774 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5775 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5778 unsigned char *saved_buffer = NULL;
5779 int pointer_buffer_mark_set = 0;
5786 align_pointer(&pStubMsg->Buffer, 4);
5787 saved_buffer = pStubMsg->Buffer;
5788 if (pStubMsg->PointerBufferMark)
5790 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5791 pStubMsg->PointerBufferMark = NULL;
5792 pointer_buffer_mark_set = 1;
5795 pStubMsg->Buffer += 4; /* for pointer ID */
5797 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5799 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5800 saved_buffer, pStubMsg->BufferEnd);
5801 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5804 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5805 if (pointer_buffer_mark_set)
5807 STD_OVERFLOW_CHECK(pStubMsg);
5808 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5809 pStubMsg->Buffer = saved_buffer + 4;
5813 m(pStubMsg, ppMemory, desc, fMustAlloc);
5816 else FIXME("no marshaller for embedded type %02x\n", *desc);
5821 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5822 unsigned char *pMemory,
5824 PFORMAT_STRING pFormat)
5826 unsigned short type;
5830 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5834 type = *(const unsigned short*)pFormat;
5835 if((type & 0xff00) == 0x8000)
5837 unsigned char basetype = LOBYTE(type);
5838 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5842 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5843 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5852 align_length(&pStubMsg->BufferLength, 4);
5853 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5854 if (!pStubMsg->IgnoreEmbeddedPointers)
5856 int saved_buffer_length = pStubMsg->BufferLength;
5857 pStubMsg->BufferLength = pStubMsg->PointerLength;
5858 pStubMsg->PointerLength = 0;
5859 if(!pStubMsg->BufferLength)
5860 ERR("BufferLength == 0??\n");
5861 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5862 pStubMsg->PointerLength = pStubMsg->BufferLength;
5863 pStubMsg->BufferLength = saved_buffer_length;
5867 m(pStubMsg, pMemory, desc);
5870 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5874 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5876 PFORMAT_STRING pFormat)
5878 unsigned short type, size;
5880 size = *(const unsigned short*)pFormat;
5881 pStubMsg->Memory += size;
5884 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5888 type = *(const unsigned short*)pFormat;
5889 if((type & 0xff00) == 0x8000)
5891 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5895 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5896 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5897 unsigned char *saved_buffer;
5906 align_pointer(&pStubMsg->Buffer, 4);
5907 saved_buffer = pStubMsg->Buffer;
5908 safe_buffer_increment(pStubMsg, 4);
5909 align_length(&pStubMsg->MemorySize, sizeof(void *));
5910 pStubMsg->MemorySize += sizeof(void *);
5911 if (!pStubMsg->IgnoreEmbeddedPointers)
5912 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5915 return m(pStubMsg, desc);
5918 else FIXME("no marshaller for embedded type %02x\n", *desc);
5921 TRACE("size %d\n", size);
5925 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5926 unsigned char *pMemory,
5928 PFORMAT_STRING pFormat)
5930 unsigned short type;
5934 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5938 type = *(const unsigned short*)pFormat;
5939 if((type & 0xff00) != 0x8000)
5941 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5942 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5951 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5954 m(pStubMsg, pMemory, desc);
5960 /***********************************************************************
5961 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5963 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5964 unsigned char *pMemory,
5965 PFORMAT_STRING pFormat)
5967 unsigned char switch_type;
5968 unsigned char increment;
5971 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5974 switch_type = *pFormat & 0xf;
5975 increment = (*pFormat & 0xf0) >> 4;
5978 align_pointer_clear(&pStubMsg->Buffer, increment);
5980 switch_value = get_discriminant(switch_type, pMemory);
5981 TRACE("got switch value 0x%x\n", switch_value);
5983 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5984 pMemory += increment;
5986 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5989 /***********************************************************************
5990 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5992 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5993 unsigned char **ppMemory,
5994 PFORMAT_STRING pFormat,
5995 unsigned char fMustAlloc)
5997 unsigned char switch_type;
5998 unsigned char increment;
6000 unsigned short size;
6001 unsigned char *pMemoryArm;
6003 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6006 switch_type = *pFormat & 0xf;
6007 increment = (*pFormat & 0xf0) >> 4;
6010 align_pointer(&pStubMsg->Buffer, increment);
6011 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6012 TRACE("got switch value 0x%x\n", switch_value);
6014 size = *(const unsigned short*)pFormat + increment;
6015 if (!fMustAlloc && !*ppMemory)
6018 *ppMemory = NdrAllocate(pStubMsg, size);
6020 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6021 * since the arm is part of the memory block that is encompassed by
6022 * the whole union. Memory is forced to allocate when pointers
6023 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6024 * clearing the memory we pass in to the unmarshaller */
6026 memset(*ppMemory, 0, size);
6028 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
6029 pMemoryArm = *ppMemory + increment;
6031 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, FALSE);
6034 /***********************************************************************
6035 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
6037 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6038 unsigned char *pMemory,
6039 PFORMAT_STRING pFormat)
6041 unsigned char switch_type;
6042 unsigned char increment;
6045 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6048 switch_type = *pFormat & 0xf;
6049 increment = (*pFormat & 0xf0) >> 4;
6052 align_length(&pStubMsg->BufferLength, increment);
6053 switch_value = get_discriminant(switch_type, pMemory);
6054 TRACE("got switch value 0x%x\n", switch_value);
6056 /* Add discriminant size */
6057 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
6058 pMemory += increment;
6060 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
6063 /***********************************************************************
6064 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
6066 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6067 PFORMAT_STRING pFormat)
6069 unsigned char switch_type;
6070 unsigned char increment;
6073 switch_type = *pFormat & 0xf;
6074 increment = (*pFormat & 0xf0) >> 4;
6077 align_pointer(&pStubMsg->Buffer, increment);
6078 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6079 TRACE("got switch value 0x%x\n", switch_value);
6081 pStubMsg->Memory += increment;
6083 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
6086 /***********************************************************************
6087 * NdrEncapsulatedUnionFree [RPCRT4.@]
6089 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6090 unsigned char *pMemory,
6091 PFORMAT_STRING pFormat)
6093 unsigned char switch_type;
6094 unsigned char increment;
6097 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6100 switch_type = *pFormat & 0xf;
6101 increment = (*pFormat & 0xf0) >> 4;
6104 switch_value = get_discriminant(switch_type, pMemory);
6105 TRACE("got switch value 0x%x\n", switch_value);
6107 pMemory += increment;
6109 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
6112 /***********************************************************************
6113 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
6115 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6116 unsigned char *pMemory,
6117 PFORMAT_STRING pFormat)
6119 unsigned char switch_type;
6121 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6124 switch_type = *pFormat;
6127 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6128 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6129 /* Marshall discriminant */
6130 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6132 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6135 static LONG unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
6136 PFORMAT_STRING *ppFormat)
6138 LONG discriminant = 0;
6148 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6157 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6158 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6166 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6167 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6172 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
6176 if (pStubMsg->fHasNewCorrDesc)
6180 return discriminant;
6183 /**********************************************************************
6184 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6186 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6187 unsigned char **ppMemory,
6188 PFORMAT_STRING pFormat,
6189 unsigned char fMustAlloc)
6192 unsigned short size;
6194 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6197 /* Unmarshall discriminant */
6198 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6199 TRACE("unmarshalled discriminant %x\n", discriminant);
6201 pFormat += *(const SHORT*)pFormat;
6203 size = *(const unsigned short*)pFormat;
6205 if (!fMustAlloc && !*ppMemory)
6208 *ppMemory = NdrAllocate(pStubMsg, size);
6210 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6211 * since the arm is part of the memory block that is encompassed by
6212 * the whole union. Memory is forced to allocate when pointers
6213 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6214 * clearing the memory we pass in to the unmarshaller */
6216 memset(*ppMemory, 0, size);
6218 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, FALSE);
6221 /***********************************************************************
6222 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6224 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6225 unsigned char *pMemory,
6226 PFORMAT_STRING pFormat)
6228 unsigned char switch_type;
6230 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6233 switch_type = *pFormat;
6236 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6237 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6238 /* Add discriminant size */
6239 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6241 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6244 /***********************************************************************
6245 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6247 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6248 PFORMAT_STRING pFormat)
6253 /* Unmarshall discriminant */
6254 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6255 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
6257 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
6260 /***********************************************************************
6261 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6263 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6264 unsigned char *pMemory,
6265 PFORMAT_STRING pFormat)
6267 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6271 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6272 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6274 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6277 /***********************************************************************
6278 * NdrByteCountPointerMarshall [RPCRT4.@]
6280 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6281 unsigned char *pMemory,
6282 PFORMAT_STRING pFormat)
6288 /***********************************************************************
6289 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6291 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6292 unsigned char **ppMemory,
6293 PFORMAT_STRING pFormat,
6294 unsigned char fMustAlloc)
6300 /***********************************************************************
6301 * NdrByteCountPointerBufferSize [RPCRT4.@]
6303 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6304 unsigned char *pMemory,
6305 PFORMAT_STRING pFormat)
6310 /***********************************************************************
6311 * NdrByteCountPointerMemorySize [internal]
6313 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6314 PFORMAT_STRING pFormat)
6320 /***********************************************************************
6321 * NdrByteCountPointerFree [RPCRT4.@]
6323 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6324 unsigned char *pMemory,
6325 PFORMAT_STRING pFormat)
6330 /***********************************************************************
6331 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6333 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6334 unsigned char *pMemory,
6335 PFORMAT_STRING pFormat)
6341 /***********************************************************************
6342 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6344 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6345 unsigned char **ppMemory,
6346 PFORMAT_STRING pFormat,
6347 unsigned char fMustAlloc)
6353 /***********************************************************************
6354 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6356 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6357 unsigned char *pMemory,
6358 PFORMAT_STRING pFormat)
6363 /***********************************************************************
6364 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6366 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6367 PFORMAT_STRING pFormat)
6373 /***********************************************************************
6374 * NdrXmitOrRepAsFree [RPCRT4.@]
6376 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6377 unsigned char *pMemory,
6378 PFORMAT_STRING pFormat)
6383 /***********************************************************************
6384 * NdrRangeMarshall [internal]
6386 static unsigned char *WINAPI NdrRangeMarshall(
6387 PMIDL_STUB_MESSAGE pStubMsg,
6388 unsigned char *pMemory,
6389 PFORMAT_STRING pFormat)
6391 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6392 unsigned char base_type;
6394 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6396 if (pRange->type != RPC_FC_RANGE)
6398 ERR("invalid format type %x\n", pRange->type);
6399 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6403 base_type = pRange->flags_type & 0xf;
6405 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6408 /***********************************************************************
6409 * NdrRangeUnmarshall [RPCRT4.@]
6411 unsigned char *WINAPI NdrRangeUnmarshall(
6412 PMIDL_STUB_MESSAGE pStubMsg,
6413 unsigned char **ppMemory,
6414 PFORMAT_STRING pFormat,
6415 unsigned char fMustAlloc)
6417 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6418 unsigned char base_type;
6420 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6422 if (pRange->type != RPC_FC_RANGE)
6424 ERR("invalid format type %x\n", pRange->type);
6425 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6428 base_type = pRange->flags_type & 0xf;
6430 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6431 base_type, pRange->low_value, pRange->high_value);
6433 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6436 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \
6437 if (!fMustAlloc && !*ppMemory) \
6438 fMustAlloc = TRUE; \
6440 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6441 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6443 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6444 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6445 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6447 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6448 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6450 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6451 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6452 (mem_type)pRange->high_value); \
6453 RpcRaiseException(RPC_S_INVALID_BOUND); \
6456 TRACE("*ppMemory: %p\n", *ppMemory); \
6457 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6458 pStubMsg->Buffer += sizeof(wire_type); \
6465 RANGE_UNMARSHALL(UCHAR, UCHAR, "%d");
6466 TRACE("value: 0x%02x\n", **ppMemory);
6470 RANGE_UNMARSHALL(CHAR, CHAR, "%u");
6471 TRACE("value: 0x%02x\n", **ppMemory);
6473 case RPC_FC_WCHAR: /* FIXME: valid? */
6475 RANGE_UNMARSHALL(USHORT, USHORT, "%u");
6476 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6479 RANGE_UNMARSHALL(SHORT, SHORT, "%d");
6480 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6484 RANGE_UNMARSHALL(LONG, LONG, "%d");
6485 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6488 RANGE_UNMARSHALL(ULONG, ULONG, "%u");
6489 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6492 RANGE_UNMARSHALL(UINT, USHORT, "%u");
6493 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6499 ERR("invalid range base type: 0x%02x\n", base_type);
6500 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6506 /***********************************************************************
6507 * NdrRangeBufferSize [internal]
6509 static void WINAPI NdrRangeBufferSize(
6510 PMIDL_STUB_MESSAGE pStubMsg,
6511 unsigned char *pMemory,
6512 PFORMAT_STRING pFormat)
6514 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6515 unsigned char base_type;
6517 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6519 if (pRange->type != RPC_FC_RANGE)
6521 ERR("invalid format type %x\n", pRange->type);
6522 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6524 base_type = pRange->flags_type & 0xf;
6526 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6529 /***********************************************************************
6530 * NdrRangeMemorySize [internal]
6532 static ULONG WINAPI NdrRangeMemorySize(
6533 PMIDL_STUB_MESSAGE pStubMsg,
6534 PFORMAT_STRING pFormat)
6536 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6537 unsigned char base_type;
6539 if (pRange->type != RPC_FC_RANGE)
6541 ERR("invalid format type %x\n", pRange->type);
6542 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6545 base_type = pRange->flags_type & 0xf;
6547 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6550 /***********************************************************************
6551 * NdrRangeFree [internal]
6553 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6554 unsigned char *pMemory,
6555 PFORMAT_STRING pFormat)
6557 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6562 /***********************************************************************
6563 * NdrBaseTypeMarshall [internal]
6565 static unsigned char *WINAPI NdrBaseTypeMarshall(
6566 PMIDL_STUB_MESSAGE pStubMsg,
6567 unsigned char *pMemory,
6568 PFORMAT_STRING pFormat)
6570 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6578 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6579 TRACE("value: 0x%02x\n", *pMemory);
6584 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6585 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6586 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6590 case RPC_FC_ERROR_STATUS_T:
6592 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONG));
6593 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6594 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6597 align_pointer_clear(&pStubMsg->Buffer, sizeof(float));
6598 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6601 align_pointer_clear(&pStubMsg->Buffer, sizeof(double));
6602 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6605 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONGLONG));
6606 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6607 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6611 USHORT val = *(UINT *)pMemory;
6612 /* only 16-bits on the wire, so do a sanity check */
6613 if (*(UINT *)pMemory > SHRT_MAX)
6614 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6615 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6616 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6617 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6620 case RPC_FC_INT3264:
6621 case RPC_FC_UINT3264:
6623 UINT val = *(UINT_PTR *)pMemory;
6624 align_pointer_clear(&pStubMsg->Buffer, sizeof(UINT));
6625 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6631 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6634 /* FIXME: what is the correct return value? */
6638 /***********************************************************************
6639 * NdrBaseTypeUnmarshall [internal]
6641 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6642 PMIDL_STUB_MESSAGE pStubMsg,
6643 unsigned char **ppMemory,
6644 PFORMAT_STRING pFormat,
6645 unsigned char fMustAlloc)
6647 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6649 #define BASE_TYPE_UNMARSHALL(type) do { \
6650 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
6651 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6653 *ppMemory = pStubMsg->Buffer; \
6654 TRACE("*ppMemory: %p\n", *ppMemory); \
6655 safe_buffer_increment(pStubMsg, sizeof(type)); \
6660 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6661 TRACE("*ppMemory: %p\n", *ppMemory); \
6662 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6672 BASE_TYPE_UNMARSHALL(UCHAR);
6673 TRACE("value: 0x%02x\n", **ppMemory);
6678 BASE_TYPE_UNMARSHALL(USHORT);
6679 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6683 case RPC_FC_ERROR_STATUS_T:
6685 BASE_TYPE_UNMARSHALL(ULONG);
6686 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6689 BASE_TYPE_UNMARSHALL(float);
6690 TRACE("value: %f\n", **(float **)ppMemory);
6693 BASE_TYPE_UNMARSHALL(double);
6694 TRACE("value: %f\n", **(double **)ppMemory);
6697 BASE_TYPE_UNMARSHALL(ULONGLONG);
6698 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6703 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6704 if (!fMustAlloc && !*ppMemory)
6707 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6708 safe_copy_from_buffer(pStubMsg, &val, sizeof(USHORT));
6709 /* 16-bits on the wire, but int in memory */
6710 **(UINT **)ppMemory = val;
6711 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6714 case RPC_FC_INT3264:
6715 if (sizeof(INT_PTR) == sizeof(INT)) BASE_TYPE_UNMARSHALL(INT);
6719 align_pointer(&pStubMsg->Buffer, sizeof(INT));
6720 if (!fMustAlloc && !*ppMemory)
6723 *ppMemory = NdrAllocate(pStubMsg, sizeof(INT_PTR));
6724 safe_copy_from_buffer(pStubMsg, &val, sizeof(INT));
6725 **(INT_PTR **)ppMemory = val;
6726 TRACE("value: 0x%08lx\n", **(INT_PTR **)ppMemory);
6729 case RPC_FC_UINT3264:
6730 if (sizeof(UINT_PTR) == sizeof(UINT)) BASE_TYPE_UNMARSHALL(UINT);
6734 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6735 if (!fMustAlloc && !*ppMemory)
6738 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT_PTR));
6739 safe_copy_from_buffer(pStubMsg, &val, sizeof(UINT));
6740 **(UINT_PTR **)ppMemory = val;
6741 TRACE("value: 0x%08lx\n", **(UINT_PTR **)ppMemory);
6747 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6749 #undef BASE_TYPE_UNMARSHALL
6751 /* FIXME: what is the correct return value? */
6756 /***********************************************************************
6757 * NdrBaseTypeBufferSize [internal]
6759 static void WINAPI NdrBaseTypeBufferSize(
6760 PMIDL_STUB_MESSAGE pStubMsg,
6761 unsigned char *pMemory,
6762 PFORMAT_STRING pFormat)
6764 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6772 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6778 align_length(&pStubMsg->BufferLength, sizeof(USHORT));
6779 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6784 case RPC_FC_INT3264:
6785 case RPC_FC_UINT3264:
6786 align_length(&pStubMsg->BufferLength, sizeof(ULONG));
6787 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6790 align_length(&pStubMsg->BufferLength, sizeof(float));
6791 safe_buffer_length_increment(pStubMsg, sizeof(float));
6794 align_length(&pStubMsg->BufferLength, sizeof(double));
6795 safe_buffer_length_increment(pStubMsg, sizeof(double));
6798 align_length(&pStubMsg->BufferLength, sizeof(ULONGLONG));
6799 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6801 case RPC_FC_ERROR_STATUS_T:
6802 align_length(&pStubMsg->BufferLength, sizeof(error_status_t));
6803 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6808 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6812 /***********************************************************************
6813 * NdrBaseTypeMemorySize [internal]
6815 static ULONG WINAPI NdrBaseTypeMemorySize(
6816 PMIDL_STUB_MESSAGE pStubMsg,
6817 PFORMAT_STRING pFormat)
6819 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6827 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6828 pStubMsg->MemorySize += sizeof(UCHAR);
6829 return sizeof(UCHAR);
6833 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6834 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6835 align_length(&pStubMsg->MemorySize, sizeof(USHORT));
6836 pStubMsg->MemorySize += sizeof(USHORT);
6837 return sizeof(USHORT);
6841 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6842 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6843 align_length(&pStubMsg->MemorySize, sizeof(ULONG));
6844 pStubMsg->MemorySize += sizeof(ULONG);
6845 return sizeof(ULONG);
6847 align_pointer(&pStubMsg->Buffer, sizeof(float));
6848 safe_buffer_increment(pStubMsg, sizeof(float));
6849 align_length(&pStubMsg->MemorySize, sizeof(float));
6850 pStubMsg->MemorySize += sizeof(float);
6851 return sizeof(float);
6853 align_pointer(&pStubMsg->Buffer, sizeof(double));
6854 safe_buffer_increment(pStubMsg, sizeof(double));
6855 align_length(&pStubMsg->MemorySize, sizeof(double));
6856 pStubMsg->MemorySize += sizeof(double);
6857 return sizeof(double);
6859 align_pointer(&pStubMsg->Buffer, sizeof(ULONGLONG));
6860 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6861 align_length(&pStubMsg->MemorySize, sizeof(ULONGLONG));
6862 pStubMsg->MemorySize += sizeof(ULONGLONG);
6863 return sizeof(ULONGLONG);
6864 case RPC_FC_ERROR_STATUS_T:
6865 align_pointer(&pStubMsg->Buffer, sizeof(error_status_t));
6866 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6867 align_length(&pStubMsg->MemorySize, sizeof(error_status_t));
6868 pStubMsg->MemorySize += sizeof(error_status_t);
6869 return sizeof(error_status_t);
6871 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6872 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6873 align_length(&pStubMsg->MemorySize, sizeof(UINT));
6874 pStubMsg->MemorySize += sizeof(UINT);
6875 return sizeof(UINT);
6876 case RPC_FC_INT3264:
6877 case RPC_FC_UINT3264:
6878 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6879 safe_buffer_increment(pStubMsg, sizeof(UINT));
6880 align_length(&pStubMsg->MemorySize, sizeof(UINT_PTR));
6881 pStubMsg->MemorySize += sizeof(UINT_PTR);
6882 return sizeof(UINT_PTR);
6884 align_length(&pStubMsg->MemorySize, sizeof(void *));
6885 pStubMsg->MemorySize += sizeof(void *);
6886 return sizeof(void *);
6888 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6893 /***********************************************************************
6894 * NdrBaseTypeFree [internal]
6896 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6897 unsigned char *pMemory,
6898 PFORMAT_STRING pFormat)
6900 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6905 /***********************************************************************
6906 * NdrContextHandleBufferSize [internal]
6908 static void WINAPI NdrContextHandleBufferSize(
6909 PMIDL_STUB_MESSAGE pStubMsg,
6910 unsigned char *pMemory,
6911 PFORMAT_STRING pFormat)
6913 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6915 if (*pFormat != RPC_FC_BIND_CONTEXT)
6917 ERR("invalid format type %x\n", *pFormat);
6918 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6920 align_length(&pStubMsg->BufferLength, 4);
6921 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6924 /***********************************************************************
6925 * NdrContextHandleMarshall [internal]
6927 static unsigned char *WINAPI NdrContextHandleMarshall(
6928 PMIDL_STUB_MESSAGE pStubMsg,
6929 unsigned char *pMemory,
6930 PFORMAT_STRING pFormat)
6932 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6934 if (*pFormat != RPC_FC_BIND_CONTEXT)
6936 ERR("invalid format type %x\n", *pFormat);
6937 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6939 TRACE("flags: 0x%02x\n", pFormat[1]);
6941 if (pStubMsg->IsClient)
6943 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6944 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6946 NdrClientContextMarshall(pStubMsg, pMemory, FALSE);
6950 NDR_SCONTEXT ctxt = NDRSContextFromValue(pMemory);
6951 NDR_RUNDOWN rundown = pStubMsg->StubDesc->apfnNdrRundownRoutines[pFormat[2]];
6952 NdrServerContextNewMarshall(pStubMsg, ctxt, rundown, pFormat);
6958 /***********************************************************************
6959 * NdrContextHandleUnmarshall [internal]
6961 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6962 PMIDL_STUB_MESSAGE pStubMsg,
6963 unsigned char **ppMemory,
6964 PFORMAT_STRING pFormat,
6965 unsigned char fMustAlloc)
6967 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6968 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6970 if (*pFormat != RPC_FC_BIND_CONTEXT)
6972 ERR("invalid format type %x\n", *pFormat);
6973 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6975 TRACE("flags: 0x%02x\n", pFormat[1]);
6977 if (pStubMsg->IsClient)
6979 /* [out]-only or [ret] param */
6980 if ((pFormat[1] & (HANDLE_PARAM_IS_IN|HANDLE_PARAM_IS_OUT)) == HANDLE_PARAM_IS_OUT)
6981 **(NDR_CCONTEXT **)ppMemory = NULL;
6982 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6987 ctxt = NdrServerContextNewUnmarshall(pStubMsg, pFormat);
6988 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6989 *(void **)ppMemory = NDRSContextValue(ctxt);
6991 *(void **)ppMemory = *NDRSContextValue(ctxt);
6997 /***********************************************************************
6998 * NdrClientContextMarshall [RPCRT4.@]
7000 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7001 NDR_CCONTEXT ContextHandle,
7004 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
7006 align_pointer_clear(&pStubMsg->Buffer, 4);
7008 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7010 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7011 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7012 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7015 /* FIXME: what does fCheck do? */
7016 NDRCContextMarshall(ContextHandle,
7019 pStubMsg->Buffer += cbNDRContext;
7022 /***********************************************************************
7023 * NdrClientContextUnmarshall [RPCRT4.@]
7025 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7026 NDR_CCONTEXT * pContextHandle,
7027 RPC_BINDING_HANDLE BindHandle)
7029 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
7031 align_pointer(&pStubMsg->Buffer, 4);
7033 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
7034 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7036 NDRCContextUnmarshall(pContextHandle,
7039 pStubMsg->RpcMsg->DataRepresentation);
7041 pStubMsg->Buffer += cbNDRContext;
7044 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7045 NDR_SCONTEXT ContextHandle,
7046 NDR_RUNDOWN RundownRoutine )
7048 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
7050 align_pointer(&pStubMsg->Buffer, 4);
7052 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7054 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7055 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7056 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7059 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7060 pStubMsg->Buffer, RundownRoutine, NULL,
7061 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7062 pStubMsg->Buffer += cbNDRContext;
7065 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
7067 NDR_SCONTEXT ContextHandle;
7069 TRACE("(%p)\n", pStubMsg);
7071 align_pointer(&pStubMsg->Buffer, 4);
7073 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7075 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7076 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7077 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7080 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7082 pStubMsg->RpcMsg->DataRepresentation,
7083 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7084 pStubMsg->Buffer += cbNDRContext;
7086 return ContextHandle;
7089 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
7090 unsigned char* pMemory,
7091 PFORMAT_STRING pFormat)
7093 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
7096 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
7097 PFORMAT_STRING pFormat)
7099 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7100 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7102 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7104 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7105 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7106 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7107 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7108 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7110 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7111 if_id = &sif->InterfaceId;
7114 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
7115 pStubMsg->RpcMsg->DataRepresentation, if_id,
7119 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7120 NDR_SCONTEXT ContextHandle,
7121 NDR_RUNDOWN RundownRoutine,
7122 PFORMAT_STRING pFormat)
7124 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7125 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7127 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
7129 align_pointer(&pStubMsg->Buffer, 4);
7131 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7133 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7134 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7135 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7138 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7139 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7140 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7141 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7142 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7144 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7145 if_id = &sif->InterfaceId;
7148 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7149 pStubMsg->Buffer, RundownRoutine, if_id, flags);
7150 pStubMsg->Buffer += cbNDRContext;
7153 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7154 PFORMAT_STRING pFormat)
7156 NDR_SCONTEXT ContextHandle;
7157 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7158 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7160 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7162 align_pointer(&pStubMsg->Buffer, 4);
7164 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7166 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7167 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7168 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7171 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7172 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7173 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7174 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7175 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7177 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7178 if_id = &sif->InterfaceId;
7181 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7183 pStubMsg->RpcMsg->DataRepresentation,
7185 pStubMsg->Buffer += cbNDRContext;
7187 return ContextHandle;
7190 /***********************************************************************
7191 * NdrCorrelationInitialize [RPCRT4.@]
7193 * Initializes correlation validity checking.
7196 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7197 * pMemory [I] Pointer to memory to use as a cache.
7198 * CacheSize [I] Size of the memory pointed to by pMemory.
7199 * Flags [I] Reserved. Set to zero.
7204 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
7206 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
7207 pStubMsg->fHasNewCorrDesc = TRUE;
7210 /***********************************************************************
7211 * NdrCorrelationPass [RPCRT4.@]
7213 * Performs correlation validity checking.
7216 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7221 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
7223 FIXME("(%p): stub\n", pStubMsg);
7226 /***********************************************************************
7227 * NdrCorrelationFree [RPCRT4.@]
7229 * Frees any resources used while unmarshalling parameters that need
7230 * correlation validity checking.
7233 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7238 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
7240 FIXME("(%p): stub\n", pStubMsg);