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
22 * - Non-conformant strings
24 * - Byte count pointers
25 * - transmit_as/represent as
26 * - Multi-dimensional arrays
27 * - Conversion functions (NdrConvert)
28 * - Checks for integer addition overflow in base type and user marshall functions
44 #include "wine/unicode.h"
45 #include "wine/rpcfc.h"
47 #include "wine/debug.h"
49 WINE_DEFAULT_DEBUG_CHANNEL(ole);
52 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
53 (*((UINT32 *)(pchar)) = (uint32))
55 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
56 (*((UINT32 *)(pchar)))
58 /* these would work for i386 too, but less efficient */
59 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
60 (*(pchar) = LOBYTE(LOWORD(uint32)), \
61 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
62 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
63 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
64 (uint32)) /* allow as r-value */
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)), \
77 (uint32)) /* allow as r-value */
79 #define BIG_ENDIAN_UINT32_READ(pchar) \
81 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
82 MAKEWORD(*((pchar)+1), *(pchar))))
84 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
85 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
86 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
87 # define NDR_LOCAL_UINT32_READ(pchar) \
88 BIG_ENDIAN_UINT32_READ(pchar)
90 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
91 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
92 # define NDR_LOCAL_UINT32_READ(pchar) \
93 LITTLE_ENDIAN_UINT32_READ(pchar)
96 /* _Align must be the desired alignment,
97 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
98 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
99 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
100 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
101 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
102 #define ALIGN_POINTER_CLEAR(_Ptr, _Align) \
104 memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \
105 ALIGN_POINTER(_Ptr, _Align); \
108 #define STD_OVERFLOW_CHECK(_Msg) do { \
109 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
110 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
111 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
114 #define NDR_TABLE_SIZE 128
115 #define NDR_TABLE_MASK 127
117 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
118 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
119 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
120 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
121 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
123 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
124 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
125 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
127 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
129 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
130 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
131 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
132 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
136 NdrPointerMarshall, NdrPointerMarshall,
137 NdrPointerMarshall, NdrPointerMarshall,
139 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
140 NdrConformantStructMarshall, NdrConformantStructMarshall,
141 NdrConformantVaryingStructMarshall,
142 NdrComplexStructMarshall,
144 NdrConformantArrayMarshall,
145 NdrConformantVaryingArrayMarshall,
146 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
147 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
148 NdrComplexArrayMarshall,
150 NdrConformantStringMarshall, 0, 0,
151 NdrConformantStringMarshall,
152 NdrNonConformantStringMarshall, 0, 0, 0,
154 NdrEncapsulatedUnionMarshall,
155 NdrNonEncapsulatedUnionMarshall,
156 NdrByteCountPointerMarshall,
157 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
159 NdrInterfacePointerMarshall,
161 NdrContextHandleMarshall,
164 NdrUserMarshalMarshall,
169 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
171 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
172 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
173 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
174 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
176 NdrBaseTypeUnmarshall,
178 NdrPointerUnmarshall, NdrPointerUnmarshall,
179 NdrPointerUnmarshall, NdrPointerUnmarshall,
181 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
182 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
183 NdrConformantVaryingStructUnmarshall,
184 NdrComplexStructUnmarshall,
186 NdrConformantArrayUnmarshall,
187 NdrConformantVaryingArrayUnmarshall,
188 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
189 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
190 NdrComplexArrayUnmarshall,
192 NdrConformantStringUnmarshall, 0, 0,
193 NdrConformantStringUnmarshall,
194 NdrNonConformantStringUnmarshall, 0, 0, 0,
196 NdrEncapsulatedUnionUnmarshall,
197 NdrNonEncapsulatedUnionUnmarshall,
198 NdrByteCountPointerUnmarshall,
199 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
201 NdrInterfacePointerUnmarshall,
203 NdrContextHandleUnmarshall,
206 NdrUserMarshalUnmarshall,
211 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
213 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
214 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
215 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
216 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
218 NdrBaseTypeBufferSize,
220 NdrPointerBufferSize, NdrPointerBufferSize,
221 NdrPointerBufferSize, NdrPointerBufferSize,
223 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
224 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
225 NdrConformantVaryingStructBufferSize,
226 NdrComplexStructBufferSize,
228 NdrConformantArrayBufferSize,
229 NdrConformantVaryingArrayBufferSize,
230 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
231 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
232 NdrComplexArrayBufferSize,
234 NdrConformantStringBufferSize, 0, 0,
235 NdrConformantStringBufferSize,
236 NdrNonConformantStringBufferSize, 0, 0, 0,
238 NdrEncapsulatedUnionBufferSize,
239 NdrNonEncapsulatedUnionBufferSize,
240 NdrByteCountPointerBufferSize,
241 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
243 NdrInterfacePointerBufferSize,
245 NdrContextHandleBufferSize,
248 NdrUserMarshalBufferSize,
253 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
255 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
256 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
257 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
258 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
260 NdrBaseTypeMemorySize,
262 NdrPointerMemorySize, NdrPointerMemorySize,
263 NdrPointerMemorySize, NdrPointerMemorySize,
265 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
266 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
267 NdrConformantVaryingStructMemorySize,
268 NdrComplexStructMemorySize,
270 NdrConformantArrayMemorySize,
271 NdrConformantVaryingArrayMemorySize,
272 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
273 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
274 NdrComplexArrayMemorySize,
276 NdrConformantStringMemorySize, 0, 0,
277 NdrConformantStringMemorySize,
278 NdrNonConformantStringMemorySize, 0, 0, 0,
280 NdrEncapsulatedUnionMemorySize,
281 NdrNonEncapsulatedUnionMemorySize,
282 NdrByteCountPointerMemorySize,
283 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
285 NdrInterfacePointerMemorySize,
290 NdrUserMarshalMemorySize,
295 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
297 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
298 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
299 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
300 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
304 NdrPointerFree, NdrPointerFree,
305 NdrPointerFree, NdrPointerFree,
307 NdrSimpleStructFree, NdrSimpleStructFree,
308 NdrConformantStructFree, NdrConformantStructFree,
309 NdrConformantVaryingStructFree,
310 NdrComplexStructFree,
312 NdrConformantArrayFree,
313 NdrConformantVaryingArrayFree,
314 NdrFixedArrayFree, NdrFixedArrayFree,
315 NdrVaryingArrayFree, NdrVaryingArrayFree,
321 NdrEncapsulatedUnionFree,
322 NdrNonEncapsulatedUnionFree,
324 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
326 NdrInterfacePointerFree,
337 typedef struct _NDR_MEMORY_LIST
342 struct _NDR_MEMORY_LIST *next;
345 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
347 /***********************************************************************
348 * NdrAllocate [RPCRT4.@]
350 * Allocates a block of memory using pStubMsg->pfnAllocate.
353 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
354 * len [I] Size of memory block to allocate.
357 * The memory block of size len that was allocated.
360 * The memory block is always 8-byte aligned.
361 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
362 * exception is raised.
364 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
369 NDR_MEMORY_LIST *mem_list;
371 aligned_len = ALIGNED_LENGTH(len, 8);
372 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
373 /* check for overflow */
374 if (adjusted_len < len)
376 ERR("overflow of adjusted_len %d, len %d\n", adjusted_len, len);
377 RpcRaiseException(RPC_X_BAD_STUB_DATA);
380 p = pStubMsg->pfnAllocate(adjusted_len);
381 if (!p) RpcRaiseException(ERROR_OUTOFMEMORY);
383 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
384 mem_list->magic = MEML_MAGIC;
385 mem_list->size = aligned_len;
386 mem_list->reserved = 0;
387 mem_list->next = pStubMsg->pMemoryList;
388 pStubMsg->pMemoryList = mem_list;
394 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
396 TRACE("(%p, %p)\n", pStubMsg, Pointer);
398 pStubMsg->pfnFree(Pointer);
401 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
403 return (*(const ULONG *)pFormat != -1);
406 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
408 ALIGN_POINTER(pStubMsg->Buffer, 4);
409 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
410 RpcRaiseException(RPC_X_BAD_STUB_DATA);
411 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
412 pStubMsg->Buffer += 4;
413 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
414 if (pStubMsg->fHasNewCorrDesc)
420 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
422 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
424 pStubMsg->Offset = 0;
425 pStubMsg->ActualCount = pStubMsg->MaxCount;
429 ALIGN_POINTER(pStubMsg->Buffer, 4);
430 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
431 RpcRaiseException(RPC_X_BAD_STUB_DATA);
432 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
433 pStubMsg->Buffer += 4;
434 TRACE("offset is %d\n", pStubMsg->Offset);
435 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
436 pStubMsg->Buffer += 4;
437 TRACE("variance is %d\n", pStubMsg->ActualCount);
439 if ((pStubMsg->ActualCount > MaxValue) ||
440 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
442 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
443 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
444 RpcRaiseException(RPC_S_INVALID_BOUND);
449 if (pStubMsg->fHasNewCorrDesc)
455 /* writes the conformance value to the buffer */
456 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
458 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
459 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
460 RpcRaiseException(RPC_X_BAD_STUB_DATA);
461 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
462 pStubMsg->Buffer += 4;
465 /* writes the variance values to the buffer */
466 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
468 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
469 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
470 RpcRaiseException(RPC_X_BAD_STUB_DATA);
471 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
472 pStubMsg->Buffer += 4;
473 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
474 pStubMsg->Buffer += 4;
477 /* requests buffer space for the conformance value */
478 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
480 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
481 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
482 RpcRaiseException(RPC_X_BAD_STUB_DATA);
483 pStubMsg->BufferLength += 4;
486 /* requests buffer space for the variance values */
487 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
489 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
490 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
491 RpcRaiseException(RPC_X_BAD_STUB_DATA);
492 pStubMsg->BufferLength += 8;
495 PFORMAT_STRING ComputeConformanceOrVariance(
496 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
497 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
499 BYTE dtype = pFormat[0] & 0xf;
500 short ofs = *(const short *)&pFormat[2];
504 if (!IsConformanceOrVariancePresent(pFormat)) {
505 /* null descriptor */
510 switch (pFormat[0] & 0xf0) {
511 case RPC_FC_NORMAL_CONFORMANCE:
512 TRACE("normal conformance, ofs=%d\n", ofs);
515 case RPC_FC_POINTER_CONFORMANCE:
516 TRACE("pointer conformance, ofs=%d\n", ofs);
517 ptr = pStubMsg->Memory;
519 case RPC_FC_TOP_LEVEL_CONFORMANCE:
520 TRACE("toplevel conformance, ofs=%d\n", ofs);
521 if (pStubMsg->StackTop) {
522 ptr = pStubMsg->StackTop;
525 /* -Os mode, *pCount is already set */
529 case RPC_FC_CONSTANT_CONFORMANCE:
530 data = ofs | ((DWORD)pFormat[1] << 16);
531 TRACE("constant conformance, val=%d\n", data);
534 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
535 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
536 if (pStubMsg->StackTop) {
537 ptr = pStubMsg->StackTop;
545 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
548 switch (pFormat[1]) {
549 case RPC_FC_DEREFERENCE:
550 ptr = *(LPVOID*)((char *)ptr + ofs);
552 case RPC_FC_CALLBACK:
554 unsigned char *old_stack_top = pStubMsg->StackTop;
555 pStubMsg->StackTop = ptr;
557 /* ofs is index into StubDesc->apfnExprEval */
558 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
559 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
561 pStubMsg->StackTop = old_stack_top;
563 /* the callback function always stores the computed value in MaxCount */
564 *pCount = pStubMsg->MaxCount;
568 ptr = (char *)ptr + ofs;
581 data = *(USHORT*)ptr;
592 FIXME("unknown conformance data type %x\n", dtype);
595 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
598 switch (pFormat[1]) {
599 case RPC_FC_DEREFERENCE: /* already handled */
616 FIXME("unknown conformance op %d\n", pFormat[1]);
621 TRACE("resulting conformance is %ld\n", *pCount);
622 if (pStubMsg->fHasNewCorrDesc)
628 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
629 * the result overflows 32-bits */
630 static inline ULONG safe_multiply(ULONG a, ULONG b)
632 ULONGLONG ret = (ULONGLONG)a * b;
633 if (ret > 0xffffffff)
635 RpcRaiseException(RPC_S_INVALID_BOUND);
641 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
643 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
644 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
645 RpcRaiseException(RPC_X_BAD_STUB_DATA);
646 pStubMsg->Buffer += size;
649 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
651 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
653 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
654 pStubMsg->BufferLength, size);
655 RpcRaiseException(RPC_X_BAD_STUB_DATA);
657 pStubMsg->BufferLength += size;
660 /* copies data from the buffer, checking that there is enough data in the buffer
662 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
664 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
665 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
667 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
668 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
669 RpcRaiseException(RPC_X_BAD_STUB_DATA);
671 if (p == pStubMsg->Buffer)
672 ERR("pointer is the same as the buffer\n");
673 memcpy(p, pStubMsg->Buffer, size);
674 pStubMsg->Buffer += size;
677 /* copies data to the buffer, checking that there is enough space to do so */
678 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
680 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
681 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
683 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
684 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
686 RpcRaiseException(RPC_X_BAD_STUB_DATA);
688 memcpy(pStubMsg->Buffer, p, size);
689 pStubMsg->Buffer += size;
693 * NdrConformantString:
695 * What MS calls a ConformantString is, in DCE terminology,
696 * a Varying-Conformant String.
698 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
699 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
700 * into unmarshalled string)
701 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
703 * data: CHARTYPE[maxlen]
705 * ], where CHARTYPE is the appropriate character type (specified externally)
709 /***********************************************************************
710 * NdrConformantStringMarshall [RPCRT4.@]
712 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
713 unsigned char *pszMessage, PFORMAT_STRING pFormat)
717 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
719 if (*pFormat == RPC_FC_C_CSTRING) {
720 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
721 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
724 else if (*pFormat == RPC_FC_C_WSTRING) {
725 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
726 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
730 ERR("Unhandled string type: %#x\n", *pFormat);
731 /* FIXME: raise an exception. */
735 if (pFormat[1] == RPC_FC_STRING_SIZED)
736 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
738 pStubMsg->MaxCount = pStubMsg->ActualCount;
739 pStubMsg->Offset = 0;
740 WriteConformance(pStubMsg);
741 WriteVariance(pStubMsg);
743 size = safe_multiply(esize, pStubMsg->ActualCount);
744 safe_copy_to_buffer(pStubMsg, pszMessage, size); /* the string itself */
747 return NULL; /* is this always right? */
750 /***********************************************************************
751 * NdrConformantStringBufferSize [RPCRT4.@]
753 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
754 unsigned char* pMemory, PFORMAT_STRING pFormat)
758 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
760 SizeConformance(pStubMsg);
761 SizeVariance(pStubMsg);
763 if (*pFormat == RPC_FC_C_CSTRING) {
764 TRACE("string=%s\n", debugstr_a((char*)pMemory));
765 pStubMsg->ActualCount = strlen((char*)pMemory)+1;
768 else if (*pFormat == RPC_FC_C_WSTRING) {
769 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
770 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;
774 ERR("Unhandled string type: %#x\n", *pFormat);
775 /* FIXME: raise an exception */
779 if (pFormat[1] == RPC_FC_STRING_SIZED)
780 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
782 pStubMsg->MaxCount = pStubMsg->ActualCount;
784 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
787 /************************************************************************
788 * NdrConformantStringMemorySize [RPCRT4.@]
790 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
791 PFORMAT_STRING pFormat )
795 FIXME("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
797 assert(pStubMsg && pFormat);
799 if (*pFormat == RPC_FC_C_CSTRING) {
800 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
802 else if (*pFormat == RPC_FC_C_WSTRING) {
803 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
806 ERR("Unhandled string type: %#x\n", *pFormat);
807 /* FIXME: raise an exception */
810 if (pFormat[1] != RPC_FC_PAD) {
811 FIXME("sized string format=%d\n", pFormat[1]);
814 TRACE(" --> %u\n", rslt);
818 /************************************************************************
819 * NdrConformantStringUnmarshall [RPCRT4.@]
821 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
822 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
824 ULONG bufsize, memsize, esize, i;
826 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
827 pStubMsg, *ppMemory, pFormat, fMustAlloc);
829 assert(pFormat && ppMemory && pStubMsg);
831 ReadConformance(pStubMsg, NULL);
832 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
834 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
836 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
837 pStubMsg->ActualCount, pStubMsg->MaxCount);
838 RpcRaiseException(RPC_S_INVALID_BOUND);
841 if (pStubMsg->Offset)
843 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
844 RpcRaiseException(RPC_S_INVALID_BOUND);
848 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
849 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
851 ERR("Unhandled string type: %#x\n", *pFormat);
852 /* FIXME: raise an exception */
856 memsize = safe_multiply(esize, pStubMsg->MaxCount);
857 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
859 /* strings must always have null terminating bytes */
862 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
863 RpcRaiseException(RPC_S_INVALID_BOUND);
867 /* verify the buffer is safe to access */
868 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
869 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
871 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
872 pStubMsg->BufferEnd, pStubMsg->Buffer);
873 RpcRaiseException(RPC_X_BAD_STUB_DATA);
877 for (i = bufsize - esize; i < bufsize; i++)
878 if (pStubMsg->Buffer[i] != 0)
880 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
881 i, pStubMsg->Buffer[i]);
882 RpcRaiseException(RPC_S_INVALID_BOUND);
887 *ppMemory = NdrAllocate(pStubMsg, memsize);
890 if (!pStubMsg->IsClient && !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
891 /* if the data in the RPC buffer is big enough, we just point straight
893 *ppMemory = pStubMsg->Buffer;
895 *ppMemory = NdrAllocate(pStubMsg, memsize);
898 if (*ppMemory == pStubMsg->Buffer)
899 safe_buffer_increment(pStubMsg, bufsize);
901 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
903 if (*pFormat == RPC_FC_C_CSTRING) {
904 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
906 else if (*pFormat == RPC_FC_C_WSTRING) {
907 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
910 return NULL; /* FIXME: is this always right? */
913 /***********************************************************************
914 * NdrNonConformantStringMarshall [RPCRT4.@]
916 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
917 unsigned char *pMemory,
918 PFORMAT_STRING pFormat)
924 /***********************************************************************
925 * NdrNonConformantStringUnmarshall [RPCRT4.@]
927 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
928 unsigned char **ppMemory,
929 PFORMAT_STRING pFormat,
930 unsigned char fMustAlloc)
936 /***********************************************************************
937 * NdrNonConformantStringBufferSize [RPCRT4.@]
939 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
940 unsigned char *pMemory,
941 PFORMAT_STRING pFormat)
946 /***********************************************************************
947 * NdrNonConformantStringMemorySize [RPCRT4.@]
949 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
950 PFORMAT_STRING pFormat)
956 static inline void dump_pointer_attr(unsigned char attr)
958 if (attr & RPC_FC_P_ALLOCALLNODES)
959 TRACE(" RPC_FC_P_ALLOCALLNODES");
960 if (attr & RPC_FC_P_DONTFREE)
961 TRACE(" RPC_FC_P_DONTFREE");
962 if (attr & RPC_FC_P_ONSTACK)
963 TRACE(" RPC_FC_P_ONSTACK");
964 if (attr & RPC_FC_P_SIMPLEPOINTER)
965 TRACE(" RPC_FC_P_SIMPLEPOINTER");
966 if (attr & RPC_FC_P_DEREF)
967 TRACE(" RPC_FC_P_DEREF");
971 /***********************************************************************
972 * PointerMarshall [internal]
974 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
975 unsigned char *Buffer,
976 unsigned char *Pointer,
977 PFORMAT_STRING pFormat)
979 unsigned type = pFormat[0], attr = pFormat[1];
983 int pointer_needs_marshaling;
985 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
986 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
988 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
989 else desc = pFormat + *(const SHORT*)pFormat;
992 case RPC_FC_RP: /* ref pointer (always non-null) */
995 ERR("NULL ref pointer is not allowed\n");
996 RpcRaiseException(RPC_X_NULL_REF_POINTER);
998 pointer_needs_marshaling = 1;
1000 case RPC_FC_UP: /* unique pointer */
1001 case RPC_FC_OP: /* object pointer - same as unique here */
1003 pointer_needs_marshaling = 1;
1005 pointer_needs_marshaling = 0;
1006 pointer_id = (ULONG)Pointer;
1007 TRACE("writing 0x%08x to buffer\n", pointer_id);
1008 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
1011 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
1012 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
1013 TRACE("writing 0x%08x to buffer\n", pointer_id);
1014 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
1017 FIXME("unhandled ptr type=%02x\n", type);
1018 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1022 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
1024 if (pointer_needs_marshaling) {
1025 if (attr & RPC_FC_P_DEREF) {
1026 Pointer = *(unsigned char**)Pointer;
1027 TRACE("deref => %p\n", Pointer);
1029 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1030 if (m) m(pStubMsg, Pointer, desc);
1031 else FIXME("no marshaller for data type=%02x\n", *desc);
1034 STD_OVERFLOW_CHECK(pStubMsg);
1037 /***********************************************************************
1038 * PointerUnmarshall [internal]
1040 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1041 unsigned char *Buffer,
1042 unsigned char **pPointer,
1043 unsigned char *pSrcPointer,
1044 PFORMAT_STRING pFormat,
1045 unsigned char fMustAlloc)
1047 unsigned type = pFormat[0], attr = pFormat[1];
1048 PFORMAT_STRING desc;
1050 DWORD pointer_id = 0;
1051 int pointer_needs_unmarshaling;
1053 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
1054 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1056 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1057 else desc = pFormat + *(const SHORT*)pFormat;
1060 case RPC_FC_RP: /* ref pointer (always non-null) */
1061 pointer_needs_unmarshaling = 1;
1063 case RPC_FC_UP: /* unique pointer */
1064 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1065 TRACE("pointer_id is 0x%08x\n", pointer_id);
1067 pointer_needs_unmarshaling = 1;
1070 pointer_needs_unmarshaling = 0;
1073 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1074 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1075 TRACE("pointer_id is 0x%08x\n", pointer_id);
1076 if (!fMustAlloc && pSrcPointer)
1078 FIXME("free object pointer %p\n", pSrcPointer);
1082 pointer_needs_unmarshaling = 1;
1084 pointer_needs_unmarshaling = 0;
1087 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1088 TRACE("pointer_id is 0x%08x\n", pointer_id);
1089 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
1090 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
1093 FIXME("unhandled ptr type=%02x\n", type);
1094 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1098 if (pointer_needs_unmarshaling) {
1099 unsigned char *base_ptr_val = *pPointer;
1100 unsigned char **current_ptr = pPointer;
1101 if (pStubMsg->IsClient) {
1103 /* if we aren't forcing allocation of memory then try to use the existing
1104 * (source) pointer to unmarshall the data into so that [in,out]
1105 * parameters behave correctly. it doesn't matter if the parameter is
1106 * [out] only since in that case the pointer will be NULL. we force
1107 * allocation when the source pointer is NULL here instead of in the type
1108 * unmarshalling routine for the benefit of the deref code below */
1111 TRACE("setting *pPointer to %p\n", pSrcPointer);
1112 *pPointer = base_ptr_val = pSrcPointer;
1118 /* the memory in a stub is never initialised, so we have to work out here
1119 * whether we have to initialise it so we can use the optimisation of
1120 * setting the pointer to the buffer, if possible, or set fMustAlloc to
1122 if (attr & RPC_FC_P_DEREF) {
1125 base_ptr_val = NULL;
1126 *current_ptr = NULL;
1130 if (attr & RPC_FC_P_ALLOCALLNODES)
1131 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
1133 if (attr & RPC_FC_P_DEREF) {
1135 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
1136 *pPointer = base_ptr_val;
1137 current_ptr = (unsigned char **)base_ptr_val;
1139 current_ptr = *(unsigned char***)current_ptr;
1140 TRACE("deref => %p\n", current_ptr);
1141 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
1143 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1144 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
1145 else FIXME("no unmarshaller for data type=%02x\n", *desc);
1147 if (type == RPC_FC_FP)
1148 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
1152 TRACE("pointer=%p\n", *pPointer);
1155 /***********************************************************************
1156 * PointerBufferSize [internal]
1158 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1159 unsigned char *Pointer,
1160 PFORMAT_STRING pFormat)
1162 unsigned type = pFormat[0], attr = pFormat[1];
1163 PFORMAT_STRING desc;
1165 int pointer_needs_sizing;
1168 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1169 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1171 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1172 else desc = pFormat + *(const SHORT*)pFormat;
1175 case RPC_FC_RP: /* ref pointer (always non-null) */
1178 ERR("NULL ref pointer is not allowed\n");
1179 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1184 /* NULL pointer has no further representation */
1189 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1190 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1191 if (!pointer_needs_sizing)
1195 FIXME("unhandled ptr type=%02x\n", type);
1196 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1200 if (attr & RPC_FC_P_DEREF) {
1201 Pointer = *(unsigned char**)Pointer;
1202 TRACE("deref => %p\n", Pointer);
1205 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1206 if (m) m(pStubMsg, Pointer, desc);
1207 else FIXME("no buffersizer for data type=%02x\n", *desc);
1210 /***********************************************************************
1211 * PointerMemorySize [internal]
1213 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1214 unsigned char *Buffer,
1215 PFORMAT_STRING pFormat)
1217 unsigned type = pFormat[0], attr = pFormat[1];
1218 PFORMAT_STRING desc;
1220 DWORD pointer_id = 0;
1221 int pointer_needs_sizing;
1223 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1224 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1226 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1227 else desc = pFormat + *(const SHORT*)pFormat;
1230 case RPC_FC_RP: /* ref pointer (always non-null) */
1231 pointer_needs_sizing = 1;
1233 case RPC_FC_UP: /* unique pointer */
1234 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1235 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1236 TRACE("pointer_id is 0x%08x\n", pointer_id);
1238 pointer_needs_sizing = 1;
1240 pointer_needs_sizing = 0;
1245 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1246 TRACE("pointer_id is 0x%08x\n", pointer_id);
1247 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1248 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1252 FIXME("unhandled ptr type=%02x\n", type);
1253 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1257 if (attr & RPC_FC_P_DEREF) {
1261 if (pointer_needs_sizing) {
1262 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1263 if (m) m(pStubMsg, desc);
1264 else FIXME("no memorysizer for data type=%02x\n", *desc);
1267 return pStubMsg->MemorySize;
1270 /***********************************************************************
1271 * PointerFree [internal]
1273 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1274 unsigned char *Pointer,
1275 PFORMAT_STRING pFormat)
1277 unsigned type = pFormat[0], attr = pFormat[1];
1278 PFORMAT_STRING desc;
1280 unsigned char *current_pointer = Pointer;
1282 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1283 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1284 if (attr & RPC_FC_P_DONTFREE) return;
1286 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1287 else desc = pFormat + *(const SHORT*)pFormat;
1289 if (!Pointer) return;
1291 if (type == RPC_FC_FP) {
1292 int pointer_needs_freeing = NdrFullPointerFree(
1293 pStubMsg->FullPtrXlatTables, Pointer);
1294 if (!pointer_needs_freeing)
1298 if (attr & RPC_FC_P_DEREF) {
1299 current_pointer = *(unsigned char**)Pointer;
1300 TRACE("deref => %p\n", current_pointer);
1303 m = NdrFreer[*desc & NDR_TABLE_MASK];
1304 if (m) m(pStubMsg, current_pointer, desc);
1306 /* this check stops us from trying to free buffer memory. we don't have to
1307 * worry about clients, since they won't call this function.
1308 * we don't have to check for the buffer being reallocated because
1309 * BufferStart and BufferEnd won't be reset when allocating memory for
1310 * sending the response. we don't have to check for the new buffer here as
1311 * it won't be used a type memory, only for buffer memory */
1312 if (Pointer >= (unsigned char *)pStubMsg->BufferStart &&
1313 Pointer < (unsigned char *)pStubMsg->BufferEnd)
1316 if (attr & RPC_FC_P_ONSTACK) {
1317 TRACE("not freeing stack ptr %p\n", Pointer);
1320 TRACE("freeing %p\n", Pointer);
1321 NdrFree(pStubMsg, Pointer);
1324 TRACE("not freeing %p\n", Pointer);
1327 /***********************************************************************
1328 * EmbeddedPointerMarshall
1330 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1331 unsigned char *pMemory,
1332 PFORMAT_STRING pFormat)
1334 unsigned char *Mark = pStubMsg->BufferMark;
1335 unsigned rep, count, stride;
1337 unsigned char *saved_buffer = NULL;
1339 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1341 if (*pFormat != RPC_FC_PP) return NULL;
1344 if (pStubMsg->PointerBufferMark)
1346 saved_buffer = pStubMsg->Buffer;
1347 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1348 pStubMsg->PointerBufferMark = NULL;
1351 while (pFormat[0] != RPC_FC_END) {
1352 switch (pFormat[0]) {
1354 FIXME("unknown repeat type %d\n", pFormat[0]);
1355 case RPC_FC_NO_REPEAT:
1361 case RPC_FC_FIXED_REPEAT:
1362 rep = *(const WORD*)&pFormat[2];
1363 stride = *(const WORD*)&pFormat[4];
1364 count = *(const WORD*)&pFormat[8];
1367 case RPC_FC_VARIABLE_REPEAT:
1368 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1369 stride = *(const WORD*)&pFormat[2];
1370 count = *(const WORD*)&pFormat[6];
1374 for (i = 0; i < rep; i++) {
1375 PFORMAT_STRING info = pFormat;
1376 unsigned char *membase = pMemory + (i * stride);
1377 unsigned char *bufbase = Mark + (i * stride);
1380 for (u=0; u<count; u++,info+=8) {
1381 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1382 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1383 unsigned char *saved_memory = pStubMsg->Memory;
1385 pStubMsg->Memory = pMemory;
1386 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1387 pStubMsg->Memory = saved_memory;
1390 pFormat += 8 * count;
1395 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1396 pStubMsg->Buffer = saved_buffer;
1399 STD_OVERFLOW_CHECK(pStubMsg);
1404 /***********************************************************************
1405 * EmbeddedPointerUnmarshall
1407 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1408 unsigned char *pDstMemoryPtrs,
1409 unsigned char *pSrcMemoryPtrs,
1410 PFORMAT_STRING pFormat,
1411 unsigned char fMustAlloc)
1413 unsigned char *Mark = pStubMsg->BufferMark;
1414 unsigned rep, count, stride;
1416 unsigned char *saved_buffer = NULL;
1418 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstMemoryPtrs, pSrcMemoryPtrs, pFormat, fMustAlloc);
1420 if (*pFormat != RPC_FC_PP) return NULL;
1423 if (pStubMsg->PointerBufferMark)
1425 saved_buffer = pStubMsg->Buffer;
1426 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1427 pStubMsg->PointerBufferMark = NULL;
1430 while (pFormat[0] != RPC_FC_END) {
1431 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1432 switch (pFormat[0]) {
1434 FIXME("unknown repeat type %d\n", pFormat[0]);
1435 case RPC_FC_NO_REPEAT:
1441 case RPC_FC_FIXED_REPEAT:
1442 rep = *(const WORD*)&pFormat[2];
1443 stride = *(const WORD*)&pFormat[4];
1444 count = *(const WORD*)&pFormat[8];
1447 case RPC_FC_VARIABLE_REPEAT:
1448 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1449 stride = *(const WORD*)&pFormat[2];
1450 count = *(const WORD*)&pFormat[6];
1454 for (i = 0; i < rep; i++) {
1455 PFORMAT_STRING info = pFormat;
1456 unsigned char *memdstbase = pDstMemoryPtrs + (i * stride);
1457 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1458 unsigned char *bufbase = Mark + (i * stride);
1461 for (u=0; u<count; u++,info+=8) {
1462 unsigned char **memdstptr = (unsigned char **)(memdstbase + *(const SHORT*)&info[0]);
1463 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1464 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1465 PointerUnmarshall(pStubMsg, bufptr, memdstptr, *memsrcptr, info+4, fMustAlloc);
1468 pFormat += 8 * count;
1473 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1474 pStubMsg->Buffer = saved_buffer;
1480 /***********************************************************************
1481 * EmbeddedPointerBufferSize
1483 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1484 unsigned char *pMemory,
1485 PFORMAT_STRING pFormat)
1487 unsigned rep, count, stride;
1489 ULONG saved_buffer_length = 0;
1491 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1493 if (pStubMsg->IgnoreEmbeddedPointers) return;
1495 if (*pFormat != RPC_FC_PP) return;
1498 if (pStubMsg->PointerLength)
1500 saved_buffer_length = pStubMsg->BufferLength;
1501 pStubMsg->BufferLength = pStubMsg->PointerLength;
1502 pStubMsg->PointerLength = 0;
1505 while (pFormat[0] != RPC_FC_END) {
1506 switch (pFormat[0]) {
1508 FIXME("unknown repeat type %d\n", pFormat[0]);
1509 case RPC_FC_NO_REPEAT:
1515 case RPC_FC_FIXED_REPEAT:
1516 rep = *(const WORD*)&pFormat[2];
1517 stride = *(const WORD*)&pFormat[4];
1518 count = *(const WORD*)&pFormat[8];
1521 case RPC_FC_VARIABLE_REPEAT:
1522 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1523 stride = *(const WORD*)&pFormat[2];
1524 count = *(const WORD*)&pFormat[6];
1528 for (i = 0; i < rep; i++) {
1529 PFORMAT_STRING info = pFormat;
1530 unsigned char *membase = pMemory + (i * stride);
1533 for (u=0; u<count; u++,info+=8) {
1534 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1535 unsigned char *saved_memory = pStubMsg->Memory;
1537 pStubMsg->Memory = pMemory;
1538 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1539 pStubMsg->Memory = saved_memory;
1542 pFormat += 8 * count;
1545 if (saved_buffer_length)
1547 pStubMsg->PointerLength = pStubMsg->BufferLength;
1548 pStubMsg->BufferLength = saved_buffer_length;
1552 /***********************************************************************
1553 * EmbeddedPointerMemorySize [internal]
1555 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1556 PFORMAT_STRING pFormat)
1558 unsigned char *Mark = pStubMsg->BufferMark;
1559 unsigned rep, count, stride;
1561 unsigned char *saved_buffer = NULL;
1563 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1565 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1567 if (pStubMsg->PointerBufferMark)
1569 saved_buffer = pStubMsg->Buffer;
1570 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1571 pStubMsg->PointerBufferMark = NULL;
1574 if (*pFormat != RPC_FC_PP) return 0;
1577 while (pFormat[0] != RPC_FC_END) {
1578 switch (pFormat[0]) {
1580 FIXME("unknown repeat type %d\n", pFormat[0]);
1581 case RPC_FC_NO_REPEAT:
1587 case RPC_FC_FIXED_REPEAT:
1588 rep = *(const WORD*)&pFormat[2];
1589 stride = *(const WORD*)&pFormat[4];
1590 count = *(const WORD*)&pFormat[8];
1593 case RPC_FC_VARIABLE_REPEAT:
1594 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1595 stride = *(const WORD*)&pFormat[2];
1596 count = *(const WORD*)&pFormat[6];
1600 for (i = 0; i < rep; i++) {
1601 PFORMAT_STRING info = pFormat;
1602 unsigned char *bufbase = Mark + (i * stride);
1604 for (u=0; u<count; u++,info+=8) {
1605 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1606 PointerMemorySize(pStubMsg, bufptr, info+4);
1609 pFormat += 8 * count;
1614 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1615 pStubMsg->Buffer = saved_buffer;
1621 /***********************************************************************
1622 * EmbeddedPointerFree [internal]
1624 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1625 unsigned char *pMemory,
1626 PFORMAT_STRING pFormat)
1628 unsigned rep, count, stride;
1631 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1632 if (*pFormat != RPC_FC_PP) return;
1635 while (pFormat[0] != RPC_FC_END) {
1636 switch (pFormat[0]) {
1638 FIXME("unknown repeat type %d\n", pFormat[0]);
1639 case RPC_FC_NO_REPEAT:
1645 case RPC_FC_FIXED_REPEAT:
1646 rep = *(const WORD*)&pFormat[2];
1647 stride = *(const WORD*)&pFormat[4];
1648 count = *(const WORD*)&pFormat[8];
1651 case RPC_FC_VARIABLE_REPEAT:
1652 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1653 stride = *(const WORD*)&pFormat[2];
1654 count = *(const WORD*)&pFormat[6];
1658 for (i = 0; i < rep; i++) {
1659 PFORMAT_STRING info = pFormat;
1660 unsigned char *membase = pMemory + (i * stride);
1663 for (u=0; u<count; u++,info+=8) {
1664 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1665 unsigned char *saved_memory = pStubMsg->Memory;
1667 pStubMsg->Memory = pMemory;
1668 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1669 pStubMsg->Memory = saved_memory;
1672 pFormat += 8 * count;
1676 /***********************************************************************
1677 * NdrPointerMarshall [RPCRT4.@]
1679 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1680 unsigned char *pMemory,
1681 PFORMAT_STRING pFormat)
1683 unsigned char *Buffer;
1685 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1687 /* incremement the buffer here instead of in PointerMarshall,
1688 * as that is used by embedded pointers which already handle the incrementing
1689 * the buffer, and shouldn't write any additional pointer data to the wire */
1690 if (*pFormat != RPC_FC_RP)
1692 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
1693 Buffer = pStubMsg->Buffer;
1694 safe_buffer_increment(pStubMsg, 4);
1697 Buffer = pStubMsg->Buffer;
1699 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1704 /***********************************************************************
1705 * NdrPointerUnmarshall [RPCRT4.@]
1707 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1708 unsigned char **ppMemory,
1709 PFORMAT_STRING pFormat,
1710 unsigned char fMustAlloc)
1712 unsigned char *Buffer;
1714 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1716 /* incremement the buffer here instead of in PointerUnmarshall,
1717 * as that is used by embedded pointers which already handle the incrementing
1718 * the buffer, and shouldn't read any additional pointer data from the
1720 if (*pFormat != RPC_FC_RP)
1722 ALIGN_POINTER(pStubMsg->Buffer, 4);
1723 Buffer = pStubMsg->Buffer;
1724 safe_buffer_increment(pStubMsg, 4);
1727 Buffer = pStubMsg->Buffer;
1729 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1734 /***********************************************************************
1735 * NdrPointerBufferSize [RPCRT4.@]
1737 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1738 unsigned char *pMemory,
1739 PFORMAT_STRING pFormat)
1741 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1743 /* incremement the buffer length here instead of in PointerBufferSize,
1744 * as that is used by embedded pointers which already handle the buffer
1745 * length, and shouldn't write anything more to the wire */
1746 if (*pFormat != RPC_FC_RP)
1748 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1749 safe_buffer_length_increment(pStubMsg, 4);
1752 PointerBufferSize(pStubMsg, pMemory, pFormat);
1755 /***********************************************************************
1756 * NdrPointerMemorySize [RPCRT4.@]
1758 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1759 PFORMAT_STRING pFormat)
1761 /* unsigned size = *(LPWORD)(pFormat+2); */
1762 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1763 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1767 /***********************************************************************
1768 * NdrPointerFree [RPCRT4.@]
1770 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1771 unsigned char *pMemory,
1772 PFORMAT_STRING pFormat)
1774 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1775 PointerFree(pStubMsg, pMemory, pFormat);
1778 /***********************************************************************
1779 * NdrSimpleTypeMarshall [RPCRT4.@]
1781 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1782 unsigned char FormatChar )
1784 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1787 /***********************************************************************
1788 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1790 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1791 unsigned char FormatChar )
1793 NdrBaseTypeUnmarshall(pStubMsg, &pMemory, &FormatChar, 0);
1796 /***********************************************************************
1797 * NdrSimpleStructMarshall [RPCRT4.@]
1799 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1800 unsigned char *pMemory,
1801 PFORMAT_STRING pFormat)
1803 unsigned size = *(const WORD*)(pFormat+2);
1804 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1806 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
1808 pStubMsg->BufferMark = pStubMsg->Buffer;
1809 safe_copy_to_buffer(pStubMsg, pMemory, size);
1811 if (pFormat[0] != RPC_FC_STRUCT)
1812 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1817 /***********************************************************************
1818 * NdrSimpleStructUnmarshall [RPCRT4.@]
1820 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1821 unsigned char **ppMemory,
1822 PFORMAT_STRING pFormat,
1823 unsigned char fMustAlloc)
1825 unsigned size = *(const WORD*)(pFormat+2);
1826 unsigned char *saved_buffer;
1827 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1829 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1832 *ppMemory = NdrAllocate(pStubMsg, size);
1835 if (!pStubMsg->IsClient && !*ppMemory)
1836 /* for servers, we just point straight into the RPC buffer */
1837 *ppMemory = pStubMsg->Buffer;
1840 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1841 safe_buffer_increment(pStubMsg, size);
1842 if (pFormat[0] == RPC_FC_PSTRUCT)
1843 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1845 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1846 if (*ppMemory != saved_buffer)
1847 memcpy(*ppMemory, saved_buffer, size);
1852 /***********************************************************************
1853 * NdrSimpleStructBufferSize [RPCRT4.@]
1855 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1856 unsigned char *pMemory,
1857 PFORMAT_STRING pFormat)
1859 unsigned size = *(const WORD*)(pFormat+2);
1860 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1862 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1864 safe_buffer_length_increment(pStubMsg, size);
1865 if (pFormat[0] != RPC_FC_STRUCT)
1866 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1869 /***********************************************************************
1870 * NdrSimpleStructMemorySize [RPCRT4.@]
1872 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1873 PFORMAT_STRING pFormat)
1875 unsigned short size = *(const WORD *)(pFormat+2);
1877 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1879 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1880 pStubMsg->MemorySize += size;
1881 safe_buffer_increment(pStubMsg, size);
1883 if (pFormat[0] != RPC_FC_STRUCT)
1884 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1885 return pStubMsg->MemorySize;
1888 /***********************************************************************
1889 * NdrSimpleStructFree [RPCRT4.@]
1891 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1892 unsigned char *pMemory,
1893 PFORMAT_STRING pFormat)
1895 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1896 if (pFormat[0] != RPC_FC_STRUCT)
1897 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1901 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE *pStubMsg,
1902 PFORMAT_STRING pFormat)
1906 case RPC_FC_PSTRUCT:
1907 case RPC_FC_CSTRUCT:
1908 case RPC_FC_BOGUS_STRUCT:
1909 case RPC_FC_SMFARRAY:
1910 case RPC_FC_SMVARRAY:
1911 return *(const WORD*)&pFormat[2];
1912 case RPC_FC_USER_MARSHAL:
1913 return *(const WORD*)&pFormat[4];
1914 case RPC_FC_NON_ENCAPSULATED_UNION:
1916 if (pStubMsg->fHasNewCorrDesc)
1921 pFormat += *(const SHORT*)pFormat;
1922 return *(const SHORT*)pFormat;
1924 return sizeof(void *);
1926 FIXME("unhandled embedded type %02x\n", *pFormat);
1932 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1933 PFORMAT_STRING pFormat)
1935 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1939 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1943 return m(pStubMsg, pFormat);
1947 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1948 unsigned char *pMemory,
1949 PFORMAT_STRING pFormat,
1950 PFORMAT_STRING pPointer)
1952 PFORMAT_STRING desc;
1956 while (*pFormat != RPC_FC_END) {
1962 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
1963 safe_copy_to_buffer(pStubMsg, pMemory, 1);
1969 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1970 safe_copy_to_buffer(pStubMsg, pMemory, 2);
1976 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
1977 safe_copy_to_buffer(pStubMsg, pMemory, 4);
1981 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1982 safe_copy_to_buffer(pStubMsg, pMemory, 8);
1985 case RPC_FC_POINTER:
1987 unsigned char *saved_buffer;
1988 int pointer_buffer_mark_set = 0;
1989 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1990 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
1991 saved_buffer = pStubMsg->Buffer;
1992 if (pStubMsg->PointerBufferMark)
1994 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1995 pStubMsg->PointerBufferMark = NULL;
1996 pointer_buffer_mark_set = 1;
1999 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2000 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2001 if (pointer_buffer_mark_set)
2003 STD_OVERFLOW_CHECK(pStubMsg);
2004 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2005 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2007 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2008 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2009 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2011 pStubMsg->Buffer = saved_buffer + 4;
2017 case RPC_FC_ALIGNM4:
2018 ALIGN_POINTER(pMemory, 4);
2020 case RPC_FC_ALIGNM8:
2021 ALIGN_POINTER(pMemory, 8);
2023 case RPC_FC_STRUCTPAD1:
2024 case RPC_FC_STRUCTPAD2:
2025 case RPC_FC_STRUCTPAD3:
2026 case RPC_FC_STRUCTPAD4:
2027 case RPC_FC_STRUCTPAD5:
2028 case RPC_FC_STRUCTPAD6:
2029 case RPC_FC_STRUCTPAD7:
2030 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2032 case RPC_FC_EMBEDDED_COMPLEX:
2033 pMemory += pFormat[1];
2035 desc = pFormat + *(const SHORT*)pFormat;
2036 size = EmbeddedComplexSize(pStubMsg, desc);
2037 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
2038 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2041 /* for some reason interface pointers aren't generated as
2042 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2043 * they still need the derefencing treatment that pointers are
2045 if (*desc == RPC_FC_IP)
2046 m(pStubMsg, *(unsigned char **)pMemory, desc);
2048 m(pStubMsg, pMemory, desc);
2050 else FIXME("no marshaller for embedded type %02x\n", *desc);
2057 FIXME("unhandled format 0x%02x\n", *pFormat);
2065 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2066 unsigned char *pMemory,
2067 PFORMAT_STRING pFormat,
2068 PFORMAT_STRING pPointer)
2070 PFORMAT_STRING desc;
2074 while (*pFormat != RPC_FC_END) {
2080 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2081 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2087 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2088 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2094 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2095 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2099 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2100 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2103 case RPC_FC_POINTER:
2105 unsigned char *saved_buffer;
2106 int pointer_buffer_mark_set = 0;
2107 TRACE("pointer => %p\n", pMemory);
2108 ALIGN_POINTER(pStubMsg->Buffer, 4);
2109 saved_buffer = pStubMsg->Buffer;
2110 if (pStubMsg->PointerBufferMark)
2112 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2113 pStubMsg->PointerBufferMark = NULL;
2114 pointer_buffer_mark_set = 1;
2117 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2119 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, TRUE);
2120 if (pointer_buffer_mark_set)
2122 STD_OVERFLOW_CHECK(pStubMsg);
2123 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2124 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2126 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2127 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2128 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2130 pStubMsg->Buffer = saved_buffer + 4;
2136 case RPC_FC_ALIGNM4:
2137 ALIGN_POINTER_CLEAR(pMemory, 4);
2139 case RPC_FC_ALIGNM8:
2140 ALIGN_POINTER_CLEAR(pMemory, 8);
2142 case RPC_FC_STRUCTPAD1:
2143 case RPC_FC_STRUCTPAD2:
2144 case RPC_FC_STRUCTPAD3:
2145 case RPC_FC_STRUCTPAD4:
2146 case RPC_FC_STRUCTPAD5:
2147 case RPC_FC_STRUCTPAD6:
2148 case RPC_FC_STRUCTPAD7:
2149 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2150 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2152 case RPC_FC_EMBEDDED_COMPLEX:
2153 pMemory += pFormat[1];
2155 desc = pFormat + *(const SHORT*)pFormat;
2156 size = EmbeddedComplexSize(pStubMsg, desc);
2157 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2158 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2159 memset(pMemory, 0, size); /* just in case */
2162 /* for some reason interface pointers aren't generated as
2163 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2164 * they still need the derefencing treatment that pointers are
2166 if (*desc == RPC_FC_IP)
2167 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2169 m(pStubMsg, &pMemory, desc, FALSE);
2171 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2178 FIXME("unhandled format %d\n", *pFormat);
2186 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2187 unsigned char *pMemory,
2188 PFORMAT_STRING pFormat,
2189 PFORMAT_STRING pPointer)
2191 PFORMAT_STRING desc;
2195 while (*pFormat != RPC_FC_END) {
2201 safe_buffer_length_increment(pStubMsg, 1);
2207 safe_buffer_length_increment(pStubMsg, 2);
2213 safe_buffer_length_increment(pStubMsg, 4);
2217 safe_buffer_length_increment(pStubMsg, 8);
2220 case RPC_FC_POINTER:
2221 if (!pStubMsg->IgnoreEmbeddedPointers)
2223 int saved_buffer_length = pStubMsg->BufferLength;
2224 pStubMsg->BufferLength = pStubMsg->PointerLength;
2225 pStubMsg->PointerLength = 0;
2226 if(!pStubMsg->BufferLength)
2227 ERR("BufferLength == 0??\n");
2228 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2229 pStubMsg->PointerLength = pStubMsg->BufferLength;
2230 pStubMsg->BufferLength = saved_buffer_length;
2232 safe_buffer_length_increment(pStubMsg, 4);
2236 case RPC_FC_ALIGNM4:
2237 ALIGN_POINTER(pMemory, 4);
2239 case RPC_FC_ALIGNM8:
2240 ALIGN_POINTER(pMemory, 8);
2242 case RPC_FC_STRUCTPAD1:
2243 case RPC_FC_STRUCTPAD2:
2244 case RPC_FC_STRUCTPAD3:
2245 case RPC_FC_STRUCTPAD4:
2246 case RPC_FC_STRUCTPAD5:
2247 case RPC_FC_STRUCTPAD6:
2248 case RPC_FC_STRUCTPAD7:
2249 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2251 case RPC_FC_EMBEDDED_COMPLEX:
2252 pMemory += pFormat[1];
2254 desc = pFormat + *(const SHORT*)pFormat;
2255 size = EmbeddedComplexSize(pStubMsg, desc);
2256 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2259 /* for some reason interface pointers aren't generated as
2260 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2261 * they still need the derefencing treatment that pointers are
2263 if (*desc == RPC_FC_IP)
2264 m(pStubMsg, *(unsigned char **)pMemory, desc);
2266 m(pStubMsg, pMemory, desc);
2268 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2275 FIXME("unhandled format 0x%02x\n", *pFormat);
2283 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2284 unsigned char *pMemory,
2285 PFORMAT_STRING pFormat,
2286 PFORMAT_STRING pPointer)
2288 PFORMAT_STRING desc;
2292 while (*pFormat != RPC_FC_END) {
2313 case RPC_FC_POINTER:
2314 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
2318 case RPC_FC_ALIGNM4:
2319 ALIGN_POINTER(pMemory, 4);
2321 case RPC_FC_ALIGNM8:
2322 ALIGN_POINTER(pMemory, 8);
2324 case RPC_FC_STRUCTPAD1:
2325 case RPC_FC_STRUCTPAD2:
2326 case RPC_FC_STRUCTPAD3:
2327 case RPC_FC_STRUCTPAD4:
2328 case RPC_FC_STRUCTPAD5:
2329 case RPC_FC_STRUCTPAD6:
2330 case RPC_FC_STRUCTPAD7:
2331 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2333 case RPC_FC_EMBEDDED_COMPLEX:
2334 pMemory += pFormat[1];
2336 desc = pFormat + *(const SHORT*)pFormat;
2337 size = EmbeddedComplexSize(pStubMsg, desc);
2338 m = NdrFreer[*desc & NDR_TABLE_MASK];
2341 /* for some reason interface pointers aren't generated as
2342 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2343 * they still need the derefencing treatment that pointers are
2345 if (*desc == RPC_FC_IP)
2346 m(pStubMsg, *(unsigned char **)pMemory, desc);
2348 m(pStubMsg, pMemory, desc);
2350 else FIXME("no freer for embedded type %02x\n", *desc);
2357 FIXME("unhandled format 0x%02x\n", *pFormat);
2365 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2366 PFORMAT_STRING pFormat)
2368 PFORMAT_STRING desc;
2369 unsigned long size = 0;
2371 while (*pFormat != RPC_FC_END) {
2378 safe_buffer_increment(pStubMsg, 1);
2384 safe_buffer_increment(pStubMsg, 2);
2390 safe_buffer_increment(pStubMsg, 4);
2394 safe_buffer_increment(pStubMsg, 8);
2396 case RPC_FC_POINTER:
2398 safe_buffer_increment(pStubMsg, 4);
2399 if (!pStubMsg->IgnoreEmbeddedPointers)
2400 FIXME("embedded pointers\n");
2402 case RPC_FC_ALIGNM4:
2403 ALIGN_LENGTH(size, 4);
2404 ALIGN_POINTER(pStubMsg->Buffer, 4);
2406 case RPC_FC_ALIGNM8:
2407 ALIGN_LENGTH(size, 8);
2408 ALIGN_POINTER(pStubMsg->Buffer, 8);
2410 case RPC_FC_STRUCTPAD1:
2411 case RPC_FC_STRUCTPAD2:
2412 case RPC_FC_STRUCTPAD3:
2413 case RPC_FC_STRUCTPAD4:
2414 case RPC_FC_STRUCTPAD5:
2415 case RPC_FC_STRUCTPAD6:
2416 case RPC_FC_STRUCTPAD7:
2417 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2419 case RPC_FC_EMBEDDED_COMPLEX:
2422 desc = pFormat + *(const SHORT*)pFormat;
2423 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2429 FIXME("unhandled format 0x%02x\n", *pFormat);
2437 /***********************************************************************
2438 * NdrComplexStructMarshall [RPCRT4.@]
2440 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2441 unsigned char *pMemory,
2442 PFORMAT_STRING pFormat)
2444 PFORMAT_STRING conf_array = NULL;
2445 PFORMAT_STRING pointer_desc = NULL;
2446 unsigned char *OldMemory = pStubMsg->Memory;
2447 int pointer_buffer_mark_set = 0;
2449 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2451 if (!pStubMsg->PointerBufferMark)
2453 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2454 /* save buffer length */
2455 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2457 /* get the buffer pointer after complex array data, but before
2459 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2460 pStubMsg->IgnoreEmbeddedPointers = 1;
2461 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2462 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2464 /* save it for use by embedded pointer code later */
2465 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2466 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
2467 pointer_buffer_mark_set = 1;
2469 /* restore the original buffer length */
2470 pStubMsg->BufferLength = saved_buffer_length;
2473 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
2476 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2478 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2481 pStubMsg->Memory = pMemory;
2483 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2486 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2488 pStubMsg->Memory = OldMemory;
2490 if (pointer_buffer_mark_set)
2492 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2493 pStubMsg->PointerBufferMark = NULL;
2496 STD_OVERFLOW_CHECK(pStubMsg);
2501 /***********************************************************************
2502 * NdrComplexStructUnmarshall [RPCRT4.@]
2504 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2505 unsigned char **ppMemory,
2506 PFORMAT_STRING pFormat,
2507 unsigned char fMustAlloc)
2509 unsigned size = *(const WORD*)(pFormat+2);
2510 PFORMAT_STRING conf_array = NULL;
2511 PFORMAT_STRING pointer_desc = NULL;
2512 unsigned char *pMemory;
2513 int pointer_buffer_mark_set = 0;
2515 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2517 if (!pStubMsg->PointerBufferMark)
2519 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2520 /* save buffer pointer */
2521 unsigned char *saved_buffer = pStubMsg->Buffer;
2523 /* get the buffer pointer after complex array data, but before
2525 pStubMsg->IgnoreEmbeddedPointers = 1;
2526 NdrComplexStructMemorySize(pStubMsg, pFormat);
2527 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2529 /* save it for use by embedded pointer code later */
2530 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2531 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
2532 pointer_buffer_mark_set = 1;
2534 /* restore the original buffer */
2535 pStubMsg->Buffer = saved_buffer;
2538 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2540 if (fMustAlloc || !*ppMemory)
2542 *ppMemory = NdrAllocate(pStubMsg, size);
2543 memset(*ppMemory, 0, size);
2547 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2549 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2552 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2555 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2557 if (pointer_buffer_mark_set)
2559 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2560 pStubMsg->PointerBufferMark = NULL;
2566 /***********************************************************************
2567 * NdrComplexStructBufferSize [RPCRT4.@]
2569 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2570 unsigned char *pMemory,
2571 PFORMAT_STRING pFormat)
2573 PFORMAT_STRING conf_array = NULL;
2574 PFORMAT_STRING pointer_desc = NULL;
2575 unsigned char *OldMemory = pStubMsg->Memory;
2576 int pointer_length_set = 0;
2578 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2580 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2582 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2584 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2585 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2587 /* get the buffer length after complex struct data, but before
2589 pStubMsg->IgnoreEmbeddedPointers = 1;
2590 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2591 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2593 /* save it for use by embedded pointer code later */
2594 pStubMsg->PointerLength = pStubMsg->BufferLength;
2595 pointer_length_set = 1;
2596 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
2598 /* restore the original buffer length */
2599 pStubMsg->BufferLength = saved_buffer_length;
2603 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2605 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2608 pStubMsg->Memory = pMemory;
2610 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2613 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2615 pStubMsg->Memory = OldMemory;
2617 if(pointer_length_set)
2619 pStubMsg->BufferLength = pStubMsg->PointerLength;
2620 pStubMsg->PointerLength = 0;
2625 /***********************************************************************
2626 * NdrComplexStructMemorySize [RPCRT4.@]
2628 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2629 PFORMAT_STRING pFormat)
2631 unsigned size = *(const WORD*)(pFormat+2);
2632 PFORMAT_STRING conf_array = NULL;
2633 PFORMAT_STRING pointer_desc = NULL;
2635 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2637 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2640 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2642 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2645 ComplexStructMemorySize(pStubMsg, pFormat);
2648 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2653 /***********************************************************************
2654 * NdrComplexStructFree [RPCRT4.@]
2656 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2657 unsigned char *pMemory,
2658 PFORMAT_STRING pFormat)
2660 PFORMAT_STRING conf_array = NULL;
2661 PFORMAT_STRING pointer_desc = NULL;
2662 unsigned char *OldMemory = pStubMsg->Memory;
2664 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2667 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2669 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2672 pStubMsg->Memory = pMemory;
2674 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2677 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2679 pStubMsg->Memory = OldMemory;
2682 /***********************************************************************
2683 * NdrConformantArrayMarshall [RPCRT4.@]
2685 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2686 unsigned char *pMemory,
2687 PFORMAT_STRING pFormat)
2689 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2690 unsigned char alignment = pFormat[1] + 1;
2692 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2693 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2695 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2697 WriteConformance(pStubMsg);
2699 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
2701 size = safe_multiply(esize, pStubMsg->MaxCount);
2702 pStubMsg->BufferMark = pStubMsg->Buffer;
2703 safe_copy_to_buffer(pStubMsg, pMemory, size);
2705 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2710 /***********************************************************************
2711 * NdrConformantArrayUnmarshall [RPCRT4.@]
2713 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2714 unsigned char **ppMemory,
2715 PFORMAT_STRING pFormat,
2716 unsigned char fMustAlloc)
2718 DWORD size, esize = *(const WORD*)(pFormat+2);
2719 unsigned char alignment = pFormat[1] + 1;
2720 unsigned char *saved_buffer;
2722 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2723 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2725 pFormat = ReadConformance(pStubMsg, pFormat+4);
2727 size = safe_multiply(esize, pStubMsg->MaxCount);
2728 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2731 *ppMemory = NdrAllocate(pStubMsg, size);
2734 if (!pStubMsg->IsClient && !*ppMemory)
2735 /* for servers, we just point straight into the RPC buffer */
2736 *ppMemory = pStubMsg->Buffer;
2739 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
2740 safe_buffer_increment(pStubMsg, size);
2741 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2743 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2744 if (*ppMemory != saved_buffer)
2745 memcpy(*ppMemory, saved_buffer, size);
2750 /***********************************************************************
2751 * NdrConformantArrayBufferSize [RPCRT4.@]
2753 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2754 unsigned char *pMemory,
2755 PFORMAT_STRING pFormat)
2757 DWORD size, esize = *(const WORD*)(pFormat+2);
2758 unsigned char alignment = pFormat[1] + 1;
2760 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2761 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2763 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2765 SizeConformance(pStubMsg);
2767 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2769 size = safe_multiply(esize, pStubMsg->MaxCount);
2770 /* conformance value plus array */
2771 safe_buffer_length_increment(pStubMsg, size);
2773 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2776 /***********************************************************************
2777 * NdrConformantArrayMemorySize [RPCRT4.@]
2779 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2780 PFORMAT_STRING pFormat)
2782 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2783 unsigned char alignment = pFormat[1] + 1;
2785 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2786 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2788 pFormat = ReadConformance(pStubMsg, pFormat+4);
2789 size = safe_multiply(esize, pStubMsg->MaxCount);
2790 pStubMsg->MemorySize += size;
2792 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2793 pStubMsg->BufferMark = pStubMsg->Buffer;
2794 safe_buffer_increment(pStubMsg, size);
2796 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2798 return pStubMsg->MemorySize;
2801 /***********************************************************************
2802 * NdrConformantArrayFree [RPCRT4.@]
2804 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2805 unsigned char *pMemory,
2806 PFORMAT_STRING pFormat)
2808 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2809 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2811 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2813 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2817 /***********************************************************************
2818 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2820 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2821 unsigned char* pMemory,
2822 PFORMAT_STRING pFormat )
2825 unsigned char alignment = pFormat[1] + 1;
2826 DWORD esize = *(const WORD*)(pFormat+2);
2828 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2830 if (pFormat[0] != RPC_FC_CVARRAY)
2832 ERR("invalid format type %x\n", pFormat[0]);
2833 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2837 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2838 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2840 WriteConformance(pStubMsg);
2841 WriteVariance(pStubMsg);
2843 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
2845 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2847 pStubMsg->BufferMark = pStubMsg->Buffer;
2848 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
2850 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2856 /***********************************************************************
2857 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2859 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2860 unsigned char** ppMemory,
2861 PFORMAT_STRING pFormat,
2862 unsigned char fMustAlloc )
2864 ULONG bufsize, memsize;
2865 unsigned char alignment = pFormat[1] + 1;
2866 DWORD esize = *(const WORD*)(pFormat+2);
2868 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2870 if (pFormat[0] != RPC_FC_CVARRAY)
2872 ERR("invalid format type %x\n", pFormat[0]);
2873 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2877 pFormat = ReadConformance(pStubMsg, pFormat+4);
2878 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2880 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2882 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2883 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2885 if (!*ppMemory || fMustAlloc)
2886 *ppMemory = NdrAllocate(pStubMsg, memsize);
2887 pStubMsg->BufferMark = pStubMsg->Buffer;
2888 safe_copy_from_buffer(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize);
2890 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
2896 /***********************************************************************
2897 * NdrConformantVaryingArrayFree [RPCRT4.@]
2899 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2900 unsigned char* pMemory,
2901 PFORMAT_STRING pFormat )
2903 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2905 if (pFormat[0] != RPC_FC_CVARRAY)
2907 ERR("invalid format type %x\n", pFormat[0]);
2908 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2912 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2913 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2915 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2919 /***********************************************************************
2920 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2922 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2923 unsigned char* pMemory, PFORMAT_STRING pFormat )
2925 unsigned char alignment = pFormat[1] + 1;
2926 DWORD esize = *(const WORD*)(pFormat+2);
2928 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2930 if (pFormat[0] != RPC_FC_CVARRAY)
2932 ERR("invalid format type %x\n", pFormat[0]);
2933 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2938 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2939 /* compute length */
2940 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2942 SizeConformance(pStubMsg);
2943 SizeVariance(pStubMsg);
2945 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2947 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2949 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2953 /***********************************************************************
2954 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2956 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2957 PFORMAT_STRING pFormat )
2959 ULONG bufsize, memsize;
2960 unsigned char alignment = pFormat[1] + 1;
2961 DWORD esize = *(const WORD*)(pFormat+2);
2963 TRACE("(%p, %p)\n", pStubMsg, pFormat);
2965 if (pFormat[0] != RPC_FC_CVARRAY)
2967 ERR("invalid format type %x\n", pFormat[0]);
2968 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2969 return pStubMsg->MemorySize;
2972 pFormat = ReadConformance(pStubMsg, pFormat+4);
2973 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2975 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2977 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2978 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2980 safe_buffer_increment(pStubMsg, bufsize);
2981 pStubMsg->MemorySize += memsize;
2983 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2985 return pStubMsg->MemorySize;
2989 /***********************************************************************
2990 * NdrComplexArrayMarshall [RPCRT4.@]
2992 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2993 unsigned char *pMemory,
2994 PFORMAT_STRING pFormat)
2996 ULONG i, count, def;
2997 BOOL variance_present;
2998 unsigned char alignment;
2999 int pointer_buffer_mark_set = 0;
3001 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3003 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3005 ERR("invalid format type %x\n", pFormat[0]);
3006 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3010 alignment = pFormat[1] + 1;
3012 if (!pStubMsg->PointerBufferMark)
3014 /* save buffer fields that may be changed by buffer sizer functions
3015 * and that may be needed later on */
3016 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3017 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3018 unsigned long saved_max_count = pStubMsg->MaxCount;
3019 unsigned long saved_offset = pStubMsg->Offset;
3020 unsigned long saved_actual_count = pStubMsg->ActualCount;
3022 /* get the buffer pointer after complex array data, but before
3024 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3025 pStubMsg->IgnoreEmbeddedPointers = 1;
3026 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3027 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3029 /* save it for use by embedded pointer code later */
3030 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3031 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
3032 pointer_buffer_mark_set = 1;
3034 /* restore fields */
3035 pStubMsg->ActualCount = saved_actual_count;
3036 pStubMsg->Offset = saved_offset;
3037 pStubMsg->MaxCount = saved_max_count;
3038 pStubMsg->BufferLength = saved_buffer_length;
3041 def = *(const WORD*)&pFormat[2];
3044 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3045 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3047 variance_present = IsConformanceOrVariancePresent(pFormat);
3048 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3049 TRACE("variance = %d\n", pStubMsg->ActualCount);
3051 WriteConformance(pStubMsg);
3052 if (variance_present)
3053 WriteVariance(pStubMsg);
3055 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3057 count = pStubMsg->ActualCount;
3058 for (i = 0; i < count; i++)
3059 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3061 STD_OVERFLOW_CHECK(pStubMsg);
3063 if (pointer_buffer_mark_set)
3065 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3066 pStubMsg->PointerBufferMark = NULL;
3072 /***********************************************************************
3073 * NdrComplexArrayUnmarshall [RPCRT4.@]
3075 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3076 unsigned char **ppMemory,
3077 PFORMAT_STRING pFormat,
3078 unsigned char fMustAlloc)
3080 ULONG i, count, size;
3081 unsigned char alignment;
3082 unsigned char *pMemory;
3083 unsigned char *saved_buffer;
3084 int pointer_buffer_mark_set = 0;
3085 int saved_ignore_embedded;
3087 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3089 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3091 ERR("invalid format type %x\n", pFormat[0]);
3092 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3096 alignment = pFormat[1] + 1;
3098 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3099 /* save buffer pointer */
3100 saved_buffer = pStubMsg->Buffer;
3101 /* get the buffer pointer after complex array data, but before
3103 pStubMsg->IgnoreEmbeddedPointers = 1;
3104 pStubMsg->MemorySize = 0;
3105 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3106 size = pStubMsg->MemorySize;
3107 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3109 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
3110 if (!pStubMsg->PointerBufferMark)
3112 /* save it for use by embedded pointer code later */
3113 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3114 pointer_buffer_mark_set = 1;
3116 /* restore the original buffer */
3117 pStubMsg->Buffer = saved_buffer;
3121 pFormat = ReadConformance(pStubMsg, pFormat);
3122 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3124 if (fMustAlloc || !*ppMemory)
3126 *ppMemory = NdrAllocate(pStubMsg, size);
3127 memset(*ppMemory, 0, size);
3130 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3132 pMemory = *ppMemory;
3133 count = pStubMsg->ActualCount;
3134 for (i = 0; i < count; i++)
3135 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
3137 if (pointer_buffer_mark_set)
3139 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3140 pStubMsg->PointerBufferMark = NULL;
3146 /***********************************************************************
3147 * NdrComplexArrayBufferSize [RPCRT4.@]
3149 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3150 unsigned char *pMemory,
3151 PFORMAT_STRING pFormat)
3153 ULONG i, count, def;
3154 unsigned char alignment;
3155 BOOL variance_present;
3156 int pointer_length_set = 0;
3158 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3160 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3162 ERR("invalid format type %x\n", pFormat[0]);
3163 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3167 alignment = pFormat[1] + 1;
3169 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3171 /* save buffer fields that may be changed by buffer sizer functions
3172 * and that may be needed later on */
3173 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3174 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3175 unsigned long saved_max_count = pStubMsg->MaxCount;
3176 unsigned long saved_offset = pStubMsg->Offset;
3177 unsigned long saved_actual_count = pStubMsg->ActualCount;
3179 /* get the buffer pointer after complex array data, but before
3181 pStubMsg->IgnoreEmbeddedPointers = 1;
3182 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3183 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3185 /* save it for use by embedded pointer code later */
3186 pStubMsg->PointerLength = pStubMsg->BufferLength;
3187 pointer_length_set = 1;
3189 /* restore fields */
3190 pStubMsg->ActualCount = saved_actual_count;
3191 pStubMsg->Offset = saved_offset;
3192 pStubMsg->MaxCount = saved_max_count;
3193 pStubMsg->BufferLength = saved_buffer_length;
3195 def = *(const WORD*)&pFormat[2];
3198 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3199 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3200 SizeConformance(pStubMsg);
3202 variance_present = IsConformanceOrVariancePresent(pFormat);
3203 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3204 TRACE("variance = %d\n", pStubMsg->ActualCount);
3206 if (variance_present)
3207 SizeVariance(pStubMsg);
3209 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3211 count = pStubMsg->ActualCount;
3212 for (i = 0; i < count; i++)
3213 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
3215 if(pointer_length_set)
3217 pStubMsg->BufferLength = pStubMsg->PointerLength;
3218 pStubMsg->PointerLength = 0;
3222 /***********************************************************************
3223 * NdrComplexArrayMemorySize [RPCRT4.@]
3225 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3226 PFORMAT_STRING pFormat)
3228 ULONG i, count, esize, SavedMemorySize, MemorySize;
3229 unsigned char alignment;
3230 unsigned char *Buffer;
3232 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3234 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3236 ERR("invalid format type %x\n", pFormat[0]);
3237 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3241 alignment = pFormat[1] + 1;
3245 pFormat = ReadConformance(pStubMsg, pFormat);
3246 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3248 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3250 SavedMemorySize = pStubMsg->MemorySize;
3252 Buffer = pStubMsg->Buffer;
3253 pStubMsg->MemorySize = 0;
3254 esize = ComplexStructMemorySize(pStubMsg, pFormat);
3255 pStubMsg->Buffer = Buffer;
3257 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
3259 count = pStubMsg->ActualCount;
3260 for (i = 0; i < count; i++)
3261 ComplexStructMemorySize(pStubMsg, pFormat);
3263 pStubMsg->MemorySize = SavedMemorySize;
3265 pStubMsg->MemorySize += MemorySize;
3269 /***********************************************************************
3270 * NdrComplexArrayFree [RPCRT4.@]
3272 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3273 unsigned char *pMemory,
3274 PFORMAT_STRING pFormat)
3276 ULONG i, count, def;
3278 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3280 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3282 ERR("invalid format type %x\n", pFormat[0]);
3283 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3287 def = *(const WORD*)&pFormat[2];
3290 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3291 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3293 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3294 TRACE("variance = %d\n", pStubMsg->ActualCount);
3296 count = pStubMsg->ActualCount;
3297 for (i = 0; i < count; i++)
3298 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
3301 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
3302 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
3303 USER_MARSHAL_CB *umcb)
3305 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
3306 pStubMsg->RpcMsg->DataRepresentation);
3307 umcb->pStubMsg = pStubMsg;
3308 umcb->pReserve = NULL;
3309 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
3310 umcb->CBType = cbtype;
3311 umcb->pFormat = pFormat;
3312 umcb->pTypeFormat = NULL /* FIXME */;
3315 #define USER_MARSHAL_PTR_PREFIX \
3316 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3317 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3319 /***********************************************************************
3320 * NdrUserMarshalMarshall [RPCRT4.@]
3322 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3323 unsigned char *pMemory,
3324 PFORMAT_STRING pFormat)
3326 unsigned flags = pFormat[1];
3327 unsigned index = *(const WORD*)&pFormat[2];
3328 unsigned char *saved_buffer = NULL;
3329 USER_MARSHAL_CB umcb;
3331 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3332 TRACE("index=%d\n", index);
3334 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
3336 if (flags & USER_MARSHAL_POINTER)
3338 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
3339 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
3340 pStubMsg->Buffer += 4;
3341 if (pStubMsg->PointerBufferMark)
3343 saved_buffer = pStubMsg->Buffer;
3344 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3345 pStubMsg->PointerBufferMark = NULL;
3347 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
3350 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
3353 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
3354 &umcb.Flags, pStubMsg->Buffer, pMemory);
3358 STD_OVERFLOW_CHECK(pStubMsg);
3359 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3360 pStubMsg->Buffer = saved_buffer;
3363 STD_OVERFLOW_CHECK(pStubMsg);
3368 /***********************************************************************
3369 * NdrUserMarshalUnmarshall [RPCRT4.@]
3371 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3372 unsigned char **ppMemory,
3373 PFORMAT_STRING pFormat,
3374 unsigned char fMustAlloc)
3376 unsigned flags = pFormat[1];
3377 unsigned index = *(const WORD*)&pFormat[2];
3378 DWORD memsize = *(const WORD*)&pFormat[4];
3379 unsigned char *saved_buffer = NULL;
3380 USER_MARSHAL_CB umcb;
3382 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3383 TRACE("index=%d\n", index);
3385 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
3387 if (flags & USER_MARSHAL_POINTER)
3389 ALIGN_POINTER(pStubMsg->Buffer, 4);
3390 /* skip pointer prefix */
3391 pStubMsg->Buffer += 4;
3392 if (pStubMsg->PointerBufferMark)
3394 saved_buffer = pStubMsg->Buffer;
3395 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3396 pStubMsg->PointerBufferMark = NULL;
3398 ALIGN_POINTER(pStubMsg->Buffer, 8);
3401 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3403 if (fMustAlloc || !*ppMemory)
3404 *ppMemory = NdrAllocate(pStubMsg, memsize);
3407 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
3408 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
3412 STD_OVERFLOW_CHECK(pStubMsg);
3413 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3414 pStubMsg->Buffer = saved_buffer;
3420 /***********************************************************************
3421 * NdrUserMarshalBufferSize [RPCRT4.@]
3423 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3424 unsigned char *pMemory,
3425 PFORMAT_STRING pFormat)
3427 unsigned flags = pFormat[1];
3428 unsigned index = *(const WORD*)&pFormat[2];
3429 DWORD bufsize = *(const WORD*)&pFormat[6];
3430 USER_MARSHAL_CB umcb;
3431 unsigned long saved_buffer_length = 0;
3433 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3434 TRACE("index=%d\n", index);
3436 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
3438 if (flags & USER_MARSHAL_POINTER)
3440 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3441 /* skip pointer prefix */
3442 safe_buffer_length_increment(pStubMsg, 4);
3443 if (pStubMsg->IgnoreEmbeddedPointers)
3445 if (pStubMsg->PointerLength)
3447 saved_buffer_length = pStubMsg->BufferLength;
3448 pStubMsg->BufferLength = pStubMsg->PointerLength;
3449 pStubMsg->PointerLength = 0;
3451 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
3454 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
3457 TRACE("size=%d\n", bufsize);
3458 safe_buffer_length_increment(pStubMsg, bufsize);
3461 pStubMsg->BufferLength =
3462 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
3463 &umcb.Flags, pStubMsg->BufferLength, pMemory);
3465 if (saved_buffer_length)
3467 pStubMsg->PointerLength = pStubMsg->BufferLength;
3468 pStubMsg->BufferLength = saved_buffer_length;
3473 /***********************************************************************
3474 * NdrUserMarshalMemorySize [RPCRT4.@]
3476 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3477 PFORMAT_STRING pFormat)
3479 unsigned flags = pFormat[1];
3480 unsigned index = *(const WORD*)&pFormat[2];
3481 DWORD memsize = *(const WORD*)&pFormat[4];
3482 DWORD bufsize = *(const WORD*)&pFormat[6];
3484 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3485 TRACE("index=%d\n", index);
3487 pStubMsg->MemorySize += memsize;
3489 if (flags & USER_MARSHAL_POINTER)
3491 ALIGN_POINTER(pStubMsg->Buffer, 4);
3492 /* skip pointer prefix */
3493 pStubMsg->Buffer += 4;
3494 if (pStubMsg->IgnoreEmbeddedPointers)
3495 return pStubMsg->MemorySize;
3496 ALIGN_POINTER(pStubMsg->Buffer, 8);
3499 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3502 FIXME("not implemented for varying buffer size\n");
3504 pStubMsg->Buffer += bufsize;
3506 return pStubMsg->MemorySize;
3509 /***********************************************************************
3510 * NdrUserMarshalFree [RPCRT4.@]
3512 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
3513 unsigned char *pMemory,
3514 PFORMAT_STRING pFormat)
3516 /* unsigned flags = pFormat[1]; */
3517 unsigned index = *(const WORD*)&pFormat[2];
3518 USER_MARSHAL_CB umcb;
3520 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3521 TRACE("index=%d\n", index);
3523 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
3525 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
3526 &umcb.Flags, pMemory);
3529 /***********************************************************************
3530 * NdrClearOutParameters [RPCRT4.@]
3532 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
3533 PFORMAT_STRING pFormat,
3536 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
3539 /***********************************************************************
3540 * NdrConvert [RPCRT4.@]
3542 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
3544 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
3545 /* FIXME: since this stub doesn't do any converting, the proper behavior
3546 is to raise an exception */
3549 /***********************************************************************
3550 * NdrConvert2 [RPCRT4.@]
3552 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
3554 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3555 pStubMsg, pFormat, NumberParams);
3556 /* FIXME: since this stub doesn't do any converting, the proper behavior
3557 is to raise an exception */
3560 #include "pshpack1.h"
3561 typedef struct _NDR_CSTRUCT_FORMAT
3564 unsigned char alignment;
3565 unsigned short memory_size;
3566 short offset_to_array_description;
3567 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
3568 #include "poppack.h"
3570 /***********************************************************************
3571 * NdrConformantStructMarshall [RPCRT4.@]
3573 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3574 unsigned char *pMemory,
3575 PFORMAT_STRING pFormat)
3577 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3578 PFORMAT_STRING pCArrayFormat;
3579 ULONG esize, bufsize;
3581 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3583 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3584 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3586 ERR("invalid format type %x\n", pCStructFormat->type);
3587 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3591 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3592 pCStructFormat->offset_to_array_description;
3593 if (*pCArrayFormat != RPC_FC_CARRAY)
3595 ERR("invalid array format type %x\n", pCStructFormat->type);
3596 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3599 esize = *(const WORD*)(pCArrayFormat+2);
3601 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3602 pCArrayFormat + 4, 0);
3604 WriteConformance(pStubMsg);
3606 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3608 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3610 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3611 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3613 ERR("integer overflow of memory_size %u with bufsize %u\n",
3614 pCStructFormat->memory_size, bufsize);
3615 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3617 /* copy constant sized part of struct */
3618 pStubMsg->BufferMark = pStubMsg->Buffer;
3619 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
3621 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3622 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3627 /***********************************************************************
3628 * NdrConformantStructUnmarshall [RPCRT4.@]
3630 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3631 unsigned char **ppMemory,
3632 PFORMAT_STRING pFormat,
3633 unsigned char fMustAlloc)
3635 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3636 PFORMAT_STRING pCArrayFormat;
3637 ULONG esize, bufsize;
3638 unsigned char *saved_buffer;
3640 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3642 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3643 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3645 ERR("invalid format type %x\n", pCStructFormat->type);
3646 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3649 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3650 pCStructFormat->offset_to_array_description;
3651 if (*pCArrayFormat != RPC_FC_CARRAY)
3653 ERR("invalid array format type %x\n", pCStructFormat->type);
3654 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3657 esize = *(const WORD*)(pCArrayFormat+2);
3659 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3661 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3663 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3665 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3666 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3668 ERR("integer overflow of memory_size %u with bufsize %u\n",
3669 pCStructFormat->memory_size, bufsize);
3670 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3675 SIZE_T size = pCStructFormat->memory_size + bufsize;
3676 *ppMemory = NdrAllocate(pStubMsg, size);
3680 if (!pStubMsg->IsClient && !*ppMemory)
3681 /* for servers, we just point straight into the RPC buffer */
3682 *ppMemory = pStubMsg->Buffer;
3685 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3686 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
3687 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3688 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3690 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
3691 if (*ppMemory != saved_buffer)
3692 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
3697 /***********************************************************************
3698 * NdrConformantStructBufferSize [RPCRT4.@]
3700 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3701 unsigned char *pMemory,
3702 PFORMAT_STRING pFormat)
3704 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3705 PFORMAT_STRING pCArrayFormat;
3708 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3710 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3711 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3713 ERR("invalid format type %x\n", pCStructFormat->type);
3714 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3717 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3718 pCStructFormat->offset_to_array_description;
3719 if (*pCArrayFormat != RPC_FC_CARRAY)
3721 ERR("invalid array format type %x\n", pCStructFormat->type);
3722 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3725 esize = *(const WORD*)(pCArrayFormat+2);
3727 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
3728 SizeConformance(pStubMsg);
3730 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
3732 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3734 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
3735 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
3737 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3738 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3741 /***********************************************************************
3742 * NdrConformantStructMemorySize [RPCRT4.@]
3744 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3745 PFORMAT_STRING pFormat)
3751 /***********************************************************************
3752 * NdrConformantStructFree [RPCRT4.@]
3754 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3755 unsigned char *pMemory,
3756 PFORMAT_STRING pFormat)
3758 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3759 PFORMAT_STRING pCArrayFormat;
3762 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3764 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3765 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3767 ERR("invalid format type %x\n", pCStructFormat->type);
3768 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3772 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3773 pCStructFormat->offset_to_array_description;
3774 if (*pCArrayFormat != RPC_FC_CARRAY)
3776 ERR("invalid array format type %x\n", pCStructFormat->type);
3777 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3780 esize = *(const WORD*)(pCArrayFormat+2);
3782 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3783 pCArrayFormat + 4, 0);
3785 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3787 /* copy constant sized part of struct */
3788 pStubMsg->BufferMark = pStubMsg->Buffer;
3790 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3791 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3794 /***********************************************************************
3795 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3797 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3798 unsigned char *pMemory,
3799 PFORMAT_STRING pFormat)
3801 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3802 PFORMAT_STRING pCVArrayFormat;
3803 ULONG esize, bufsize;
3805 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3807 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3808 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3810 ERR("invalid format type %x\n", pCVStructFormat->type);
3811 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3815 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3816 pCVStructFormat->offset_to_array_description;
3817 switch (*pCVArrayFormat)
3819 case RPC_FC_CVARRAY:
3820 esize = *(const WORD*)(pCVArrayFormat+2);
3822 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3823 pCVArrayFormat + 4, 0);
3824 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3827 case RPC_FC_C_CSTRING:
3828 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3829 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3830 esize = sizeof(char);
3831 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3832 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3833 pCVArrayFormat + 2, 0);
3835 pStubMsg->MaxCount = pStubMsg->ActualCount;
3837 case RPC_FC_C_WSTRING:
3838 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3839 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3840 esize = sizeof(WCHAR);
3841 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3842 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3843 pCVArrayFormat + 2, 0);
3845 pStubMsg->MaxCount = pStubMsg->ActualCount;
3848 ERR("invalid array format type %x\n", *pCVArrayFormat);
3849 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3853 WriteConformance(pStubMsg);
3855 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3857 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3859 /* write constant sized part */
3860 pStubMsg->BufferMark = pStubMsg->Buffer;
3861 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
3863 WriteVariance(pStubMsg);
3865 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3867 /* write array part */
3868 safe_copy_to_buffer(pStubMsg, pMemory + pCVStructFormat->memory_size, bufsize);
3870 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3875 /***********************************************************************
3876 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3878 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3879 unsigned char **ppMemory,
3880 PFORMAT_STRING pFormat,
3881 unsigned char fMustAlloc)
3883 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3884 PFORMAT_STRING pCVArrayFormat;
3885 ULONG esize, bufsize;
3886 unsigned char cvarray_type;
3888 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3890 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3891 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3893 ERR("invalid format type %x\n", pCVStructFormat->type);
3894 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3898 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3899 pCVStructFormat->offset_to_array_description;
3900 cvarray_type = *pCVArrayFormat;
3901 switch (cvarray_type)
3903 case RPC_FC_CVARRAY:
3904 esize = *(const WORD*)(pCVArrayFormat+2);
3905 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3907 case RPC_FC_C_CSTRING:
3908 esize = sizeof(char);
3909 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3910 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3912 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3914 case RPC_FC_C_WSTRING:
3915 esize = sizeof(WCHAR);
3916 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3917 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3919 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3922 ERR("invalid array format type %x\n", *pCVArrayFormat);
3923 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3927 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3929 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3931 /* work out how much memory to allocate if we need to do so */
3932 if (!*ppMemory || fMustAlloc)
3934 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3935 *ppMemory = NdrAllocate(pStubMsg, size);
3938 /* copy the constant data */
3939 pStubMsg->BufferMark = pStubMsg->Buffer;
3940 safe_copy_from_buffer(pStubMsg, *ppMemory, pCVStructFormat->memory_size);
3942 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3944 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3946 if ((cvarray_type == RPC_FC_C_CSTRING) ||
3947 (cvarray_type == RPC_FC_C_WSTRING))
3950 /* strings must always have null terminating bytes */
3951 if (bufsize < esize)
3953 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
3954 RpcRaiseException(RPC_S_INVALID_BOUND);
3957 for (i = bufsize - esize; i < bufsize; i++)
3958 if (pStubMsg->Buffer[i] != 0)
3960 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3961 i, pStubMsg->Buffer[i]);
3962 RpcRaiseException(RPC_S_INVALID_BOUND);
3967 /* copy the array data */
3968 safe_copy_from_buffer(pStubMsg, *ppMemory + pCVStructFormat->memory_size, bufsize);
3970 if (cvarray_type == RPC_FC_C_CSTRING)
3971 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3972 else if (cvarray_type == RPC_FC_C_WSTRING)
3973 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3975 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
3980 /***********************************************************************
3981 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3983 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3984 unsigned char *pMemory,
3985 PFORMAT_STRING pFormat)
3987 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3988 PFORMAT_STRING pCVArrayFormat;
3991 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3993 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3994 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3996 ERR("invalid format type %x\n", pCVStructFormat->type);
3997 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4001 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4002 pCVStructFormat->offset_to_array_description;
4003 switch (*pCVArrayFormat)
4005 case RPC_FC_CVARRAY:
4006 esize = *(const WORD*)(pCVArrayFormat+2);
4008 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4009 pCVArrayFormat + 4, 0);
4010 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4013 case RPC_FC_C_CSTRING:
4014 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4015 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4016 esize = sizeof(char);
4017 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4018 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4019 pCVArrayFormat + 2, 0);
4021 pStubMsg->MaxCount = pStubMsg->ActualCount;
4023 case RPC_FC_C_WSTRING:
4024 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4025 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4026 esize = sizeof(WCHAR);
4027 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4028 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4029 pCVArrayFormat + 2, 0);
4031 pStubMsg->MaxCount = pStubMsg->ActualCount;
4034 ERR("invalid array format type %x\n", *pCVArrayFormat);
4035 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4039 SizeConformance(pStubMsg);
4041 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4043 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4045 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4046 SizeVariance(pStubMsg);
4047 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4049 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4052 /***********************************************************************
4053 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4055 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4056 PFORMAT_STRING pFormat)
4058 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4059 PFORMAT_STRING pCVArrayFormat;
4061 unsigned char cvarray_type;
4063 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4065 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4066 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4068 ERR("invalid format type %x\n", pCVStructFormat->type);
4069 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4073 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4074 pCVStructFormat->offset_to_array_description;
4075 cvarray_type = *pCVArrayFormat;
4076 switch (cvarray_type)
4078 case RPC_FC_CVARRAY:
4079 esize = *(const WORD*)(pCVArrayFormat+2);
4080 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4082 case RPC_FC_C_CSTRING:
4083 esize = sizeof(char);
4084 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4085 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4087 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4089 case RPC_FC_C_WSTRING:
4090 esize = sizeof(WCHAR);
4091 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4092 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4094 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4097 ERR("invalid array format type %x\n", *pCVArrayFormat);
4098 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4102 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4104 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4106 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4107 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4108 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4110 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4112 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4114 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
4117 /***********************************************************************
4118 * NdrConformantVaryingStructFree [RPCRT4.@]
4120 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4121 unsigned char *pMemory,
4122 PFORMAT_STRING pFormat)
4124 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4125 PFORMAT_STRING pCVArrayFormat;
4128 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4130 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4131 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4133 ERR("invalid format type %x\n", pCVStructFormat->type);
4134 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4138 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4139 pCVStructFormat->offset_to_array_description;
4140 switch (*pCVArrayFormat)
4142 case RPC_FC_CVARRAY:
4143 esize = *(const WORD*)(pCVArrayFormat+2);
4145 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4146 pCVArrayFormat + 4, 0);
4147 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4150 case RPC_FC_C_CSTRING:
4151 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4152 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4153 esize = sizeof(char);
4154 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4155 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4156 pCVArrayFormat + 2, 0);
4158 pStubMsg->MaxCount = pStubMsg->ActualCount;
4160 case RPC_FC_C_WSTRING:
4161 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4162 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4163 esize = sizeof(WCHAR);
4164 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4165 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4166 pCVArrayFormat + 2, 0);
4168 pStubMsg->MaxCount = pStubMsg->ActualCount;
4171 ERR("invalid array format type %x\n", *pCVArrayFormat);
4172 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4176 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4178 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4181 #include "pshpack1.h"
4185 unsigned char alignment;
4186 unsigned short total_size;
4187 } NDR_SMFARRAY_FORMAT;
4192 unsigned char alignment;
4193 unsigned long total_size;
4194 } NDR_LGFARRAY_FORMAT;
4195 #include "poppack.h"
4197 /***********************************************************************
4198 * NdrFixedArrayMarshall [RPCRT4.@]
4200 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4201 unsigned char *pMemory,
4202 PFORMAT_STRING pFormat)
4204 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4205 unsigned long total_size;
4207 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4209 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4210 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4212 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4213 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4217 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4219 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4221 total_size = pSmFArrayFormat->total_size;
4222 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4226 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4227 total_size = pLgFArrayFormat->total_size;
4228 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4231 pStubMsg->BufferMark = pStubMsg->Buffer;
4232 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4234 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4239 /***********************************************************************
4240 * NdrFixedArrayUnmarshall [RPCRT4.@]
4242 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4243 unsigned char **ppMemory,
4244 PFORMAT_STRING pFormat,
4245 unsigned char fMustAlloc)
4247 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4248 unsigned long total_size;
4249 unsigned char *saved_buffer;
4251 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4253 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4254 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4256 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4257 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4261 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4263 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4265 total_size = pSmFArrayFormat->total_size;
4266 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4270 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4271 total_size = pLgFArrayFormat->total_size;
4272 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4276 *ppMemory = NdrAllocate(pStubMsg, total_size);
4279 if (!pStubMsg->IsClient && !*ppMemory)
4280 /* for servers, we just point straight into the RPC buffer */
4281 *ppMemory = pStubMsg->Buffer;
4284 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4285 safe_buffer_increment(pStubMsg, total_size);
4286 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4288 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4289 if (*ppMemory != saved_buffer)
4290 memcpy(*ppMemory, saved_buffer, total_size);
4295 /***********************************************************************
4296 * NdrFixedArrayBufferSize [RPCRT4.@]
4298 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4299 unsigned char *pMemory,
4300 PFORMAT_STRING pFormat)
4302 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4303 unsigned long total_size;
4305 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4307 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4308 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4310 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4311 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4315 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4317 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4319 total_size = pSmFArrayFormat->total_size;
4320 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4324 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4325 total_size = pLgFArrayFormat->total_size;
4326 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4328 safe_buffer_length_increment(pStubMsg, total_size);
4330 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4333 /***********************************************************************
4334 * NdrFixedArrayMemorySize [RPCRT4.@]
4336 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4337 PFORMAT_STRING pFormat)
4339 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4342 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4344 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4345 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4347 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4348 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4352 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4354 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4356 total_size = pSmFArrayFormat->total_size;
4357 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4361 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4362 total_size = pLgFArrayFormat->total_size;
4363 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4365 pStubMsg->BufferMark = pStubMsg->Buffer;
4366 safe_buffer_increment(pStubMsg, total_size);
4367 pStubMsg->MemorySize += total_size;
4369 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4374 /***********************************************************************
4375 * NdrFixedArrayFree [RPCRT4.@]
4377 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4378 unsigned char *pMemory,
4379 PFORMAT_STRING pFormat)
4381 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4383 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4385 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4386 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4388 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4389 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4393 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4394 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4397 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4398 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4401 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4404 /***********************************************************************
4405 * NdrVaryingArrayMarshall [RPCRT4.@]
4407 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4408 unsigned char *pMemory,
4409 PFORMAT_STRING pFormat)
4411 unsigned char alignment;
4412 DWORD elements, esize;
4415 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4417 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4418 (pFormat[0] != RPC_FC_LGVARRAY))
4420 ERR("invalid format type %x\n", pFormat[0]);
4421 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4425 alignment = pFormat[1] + 1;
4427 if (pFormat[0] == RPC_FC_SMVARRAY)
4430 pFormat += sizeof(WORD);
4431 elements = *(const WORD*)pFormat;
4432 pFormat += sizeof(WORD);
4437 pFormat += sizeof(DWORD);
4438 elements = *(const DWORD*)pFormat;
4439 pFormat += sizeof(DWORD);
4442 esize = *(const WORD*)pFormat;
4443 pFormat += sizeof(WORD);
4445 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4446 if ((pStubMsg->ActualCount > elements) ||
4447 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4449 RpcRaiseException(RPC_S_INVALID_BOUND);
4453 WriteVariance(pStubMsg);
4455 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
4457 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4458 pStubMsg->BufferMark = pStubMsg->Buffer;
4459 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
4461 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4466 /***********************************************************************
4467 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4469 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4470 unsigned char **ppMemory,
4471 PFORMAT_STRING pFormat,
4472 unsigned char fMustAlloc)
4474 unsigned char alignment;
4475 DWORD size, elements, esize;
4478 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4480 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4481 (pFormat[0] != RPC_FC_LGVARRAY))
4483 ERR("invalid format type %x\n", pFormat[0]);
4484 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4488 alignment = pFormat[1] + 1;
4490 if (pFormat[0] == RPC_FC_SMVARRAY)
4493 size = *(const WORD*)pFormat;
4494 pFormat += sizeof(WORD);
4495 elements = *(const WORD*)pFormat;
4496 pFormat += sizeof(WORD);
4501 size = *(const DWORD*)pFormat;
4502 pFormat += sizeof(DWORD);
4503 elements = *(const DWORD*)pFormat;
4504 pFormat += sizeof(DWORD);
4507 esize = *(const WORD*)pFormat;
4508 pFormat += sizeof(WORD);
4510 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4512 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4514 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4516 if (!*ppMemory || fMustAlloc)
4517 *ppMemory = NdrAllocate(pStubMsg, size);
4518 pStubMsg->BufferMark = pStubMsg->Buffer;
4519 safe_copy_from_buffer(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize);
4521 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
4526 /***********************************************************************
4527 * NdrVaryingArrayBufferSize [RPCRT4.@]
4529 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4530 unsigned char *pMemory,
4531 PFORMAT_STRING pFormat)
4533 unsigned char alignment;
4534 DWORD elements, esize;
4536 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4538 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4539 (pFormat[0] != RPC_FC_LGVARRAY))
4541 ERR("invalid format type %x\n", pFormat[0]);
4542 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4546 alignment = pFormat[1] + 1;
4548 if (pFormat[0] == RPC_FC_SMVARRAY)
4551 pFormat += sizeof(WORD);
4552 elements = *(const WORD*)pFormat;
4553 pFormat += sizeof(WORD);
4558 pFormat += sizeof(DWORD);
4559 elements = *(const DWORD*)pFormat;
4560 pFormat += sizeof(DWORD);
4563 esize = *(const WORD*)pFormat;
4564 pFormat += sizeof(WORD);
4566 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4567 if ((pStubMsg->ActualCount > elements) ||
4568 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4570 RpcRaiseException(RPC_S_INVALID_BOUND);
4574 SizeVariance(pStubMsg);
4576 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4578 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4580 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4583 /***********************************************************************
4584 * NdrVaryingArrayMemorySize [RPCRT4.@]
4586 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4587 PFORMAT_STRING pFormat)
4589 unsigned char alignment;
4590 DWORD size, elements, esize;
4592 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4594 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4595 (pFormat[0] != RPC_FC_LGVARRAY))
4597 ERR("invalid format type %x\n", pFormat[0]);
4598 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4602 alignment = pFormat[1] + 1;
4604 if (pFormat[0] == RPC_FC_SMVARRAY)
4607 size = *(const WORD*)pFormat;
4608 pFormat += sizeof(WORD);
4609 elements = *(const WORD*)pFormat;
4610 pFormat += sizeof(WORD);
4615 size = *(const DWORD*)pFormat;
4616 pFormat += sizeof(DWORD);
4617 elements = *(const DWORD*)pFormat;
4618 pFormat += sizeof(DWORD);
4621 esize = *(const WORD*)pFormat;
4622 pFormat += sizeof(WORD);
4624 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4626 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4628 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4629 pStubMsg->MemorySize += size;
4631 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4633 return pStubMsg->MemorySize;
4636 /***********************************************************************
4637 * NdrVaryingArrayFree [RPCRT4.@]
4639 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4640 unsigned char *pMemory,
4641 PFORMAT_STRING pFormat)
4643 unsigned char alignment;
4646 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4648 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4649 (pFormat[0] != RPC_FC_LGVARRAY))
4651 ERR("invalid format type %x\n", pFormat[0]);
4652 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4656 alignment = pFormat[1] + 1;
4658 if (pFormat[0] == RPC_FC_SMVARRAY)
4661 pFormat += sizeof(WORD);
4662 elements = *(const WORD*)pFormat;
4663 pFormat += sizeof(WORD);
4668 pFormat += sizeof(DWORD);
4669 elements = *(const DWORD*)pFormat;
4670 pFormat += sizeof(DWORD);
4673 pFormat += sizeof(WORD);
4675 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4676 if ((pStubMsg->ActualCount > elements) ||
4677 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4679 RpcRaiseException(RPC_S_INVALID_BOUND);
4683 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4686 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
4694 return *(const UCHAR *)pMemory;
4699 return *(const USHORT *)pMemory;
4703 return *(const ULONG *)pMemory;
4705 FIXME("Unhandled base type: 0x%02x\n", fc);
4710 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4711 unsigned long discriminant,
4712 PFORMAT_STRING pFormat)
4714 unsigned short num_arms, arm, type;
4716 num_arms = *(const SHORT*)pFormat & 0x0fff;
4718 for(arm = 0; arm < num_arms; arm++)
4720 if(discriminant == *(const ULONG*)pFormat)
4728 type = *(const unsigned short*)pFormat;
4729 TRACE("type %04x\n", type);
4730 if(arm == num_arms) /* default arm extras */
4734 ERR("no arm for 0x%lx and no default case\n", discriminant);
4735 RpcRaiseException(RPC_S_INVALID_TAG);
4740 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
4747 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
4749 unsigned short type;
4753 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4757 type = *(const unsigned short*)pFormat;
4758 if((type & 0xff00) == 0x8000)
4760 unsigned char basetype = LOBYTE(type);
4761 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
4765 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4766 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
4769 unsigned char *saved_buffer = NULL;
4770 int pointer_buffer_mark_set = 0;
4777 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
4778 saved_buffer = pStubMsg->Buffer;
4779 if (pStubMsg->PointerBufferMark)
4781 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4782 pStubMsg->PointerBufferMark = NULL;
4783 pointer_buffer_mark_set = 1;
4786 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
4788 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
4789 if (pointer_buffer_mark_set)
4791 STD_OVERFLOW_CHECK(pStubMsg);
4792 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4793 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
4795 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4796 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
4797 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4799 pStubMsg->Buffer = saved_buffer + 4;
4803 m(pStubMsg, pMemory, desc);
4806 else FIXME("no marshaller for embedded type %02x\n", *desc);
4811 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4812 unsigned char **ppMemory,
4814 PFORMAT_STRING pFormat,
4815 unsigned char fMustAlloc)
4817 unsigned short type;
4821 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4825 type = *(const unsigned short*)pFormat;
4826 if((type & 0xff00) == 0x8000)
4828 unsigned char basetype = LOBYTE(type);
4829 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
4833 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4834 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
4837 unsigned char *saved_buffer = NULL;
4838 int pointer_buffer_mark_set = 0;
4845 **(void***)ppMemory = NULL;
4846 ALIGN_POINTER(pStubMsg->Buffer, 4);
4847 saved_buffer = pStubMsg->Buffer;
4848 if (pStubMsg->PointerBufferMark)
4850 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4851 pStubMsg->PointerBufferMark = NULL;
4852 pointer_buffer_mark_set = 1;
4855 pStubMsg->Buffer += 4; /* for pointer ID */
4857 if (saved_buffer + 4 > pStubMsg->BufferEnd)
4859 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4860 saved_buffer, pStubMsg->BufferEnd);
4861 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4864 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
4865 if (pointer_buffer_mark_set)
4867 STD_OVERFLOW_CHECK(pStubMsg);
4868 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4869 pStubMsg->Buffer = saved_buffer + 4;
4873 m(pStubMsg, ppMemory, desc, fMustAlloc);
4876 else FIXME("no marshaller for embedded type %02x\n", *desc);
4881 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
4882 unsigned char *pMemory,
4884 PFORMAT_STRING pFormat)
4886 unsigned short type;
4890 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4894 type = *(const unsigned short*)pFormat;
4895 if((type & 0xff00) == 0x8000)
4897 unsigned char basetype = LOBYTE(type);
4898 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
4902 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4903 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
4912 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4913 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
4914 if (!pStubMsg->IgnoreEmbeddedPointers)
4916 int saved_buffer_length = pStubMsg->BufferLength;
4917 pStubMsg->BufferLength = pStubMsg->PointerLength;
4918 pStubMsg->PointerLength = 0;
4919 if(!pStubMsg->BufferLength)
4920 ERR("BufferLength == 0??\n");
4921 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
4922 pStubMsg->PointerLength = pStubMsg->BufferLength;
4923 pStubMsg->BufferLength = saved_buffer_length;
4927 m(pStubMsg, pMemory, desc);
4930 else FIXME("no buffersizer for embedded type %02x\n", *desc);
4934 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
4936 PFORMAT_STRING pFormat)
4938 unsigned short type, size;
4940 size = *(const unsigned short*)pFormat;
4941 pStubMsg->Memory += size;
4944 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4948 type = *(const unsigned short*)pFormat;
4949 if((type & 0xff00) == 0x8000)
4951 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
4955 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4956 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
4957 unsigned char *saved_buffer;
4966 ALIGN_POINTER(pStubMsg->Buffer, 4);
4967 saved_buffer = pStubMsg->Buffer;
4968 safe_buffer_increment(pStubMsg, 4);
4969 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
4970 pStubMsg->MemorySize += 4;
4971 if (!pStubMsg->IgnoreEmbeddedPointers)
4972 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
4975 return m(pStubMsg, desc);
4978 else FIXME("no marshaller for embedded type %02x\n", *desc);
4981 TRACE("size %d\n", size);
4985 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
4986 unsigned char *pMemory,
4988 PFORMAT_STRING pFormat)
4990 unsigned short type;
4994 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4998 type = *(const unsigned short*)pFormat;
4999 if((type & 0xff00) != 0x8000)
5001 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5002 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5011 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5014 m(pStubMsg, pMemory, desc);
5017 else FIXME("no freer for embedded type %02x\n", *desc);
5021 /***********************************************************************
5022 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5024 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5025 unsigned char *pMemory,
5026 PFORMAT_STRING pFormat)
5028 unsigned char switch_type;
5029 unsigned char increment;
5032 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5035 switch_type = *pFormat & 0xf;
5036 increment = (*pFormat & 0xf0) >> 4;
5039 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5041 switch_value = get_discriminant(switch_type, pMemory);
5042 TRACE("got switch value 0x%x\n", switch_value);
5044 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5045 pMemory += increment;
5047 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5050 /***********************************************************************
5051 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5053 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5054 unsigned char **ppMemory,
5055 PFORMAT_STRING pFormat,
5056 unsigned char fMustAlloc)
5058 unsigned char switch_type;
5059 unsigned char increment;
5061 unsigned short size;
5062 unsigned char *pMemoryArm;
5064 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5067 switch_type = *pFormat & 0xf;
5068 increment = (*pFormat & 0xf0) >> 4;
5071 ALIGN_POINTER(pStubMsg->Buffer, increment);
5072 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5073 TRACE("got switch value 0x%x\n", switch_value);
5075 size = *(const unsigned short*)pFormat + increment;
5076 if(!*ppMemory || fMustAlloc)
5077 *ppMemory = NdrAllocate(pStubMsg, size);
5079 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5080 pMemoryArm = *ppMemory + increment;
5082 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
5085 /***********************************************************************
5086 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5088 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5089 unsigned char *pMemory,
5090 PFORMAT_STRING pFormat)
5092 unsigned char switch_type;
5093 unsigned char increment;
5096 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5099 switch_type = *pFormat & 0xf;
5100 increment = (*pFormat & 0xf0) >> 4;
5103 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5104 switch_value = get_discriminant(switch_type, pMemory);
5105 TRACE("got switch value 0x%x\n", switch_value);
5107 /* Add discriminant size */
5108 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5109 pMemory += increment;
5111 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5114 /***********************************************************************
5115 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5117 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5118 PFORMAT_STRING pFormat)
5120 unsigned char switch_type;
5121 unsigned char increment;
5124 switch_type = *pFormat & 0xf;
5125 increment = (*pFormat & 0xf0) >> 4;
5128 ALIGN_POINTER(pStubMsg->Buffer, increment);
5129 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5130 TRACE("got switch value 0x%x\n", switch_value);
5132 pStubMsg->Memory += increment;
5134 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5137 /***********************************************************************
5138 * NdrEncapsulatedUnionFree [RPCRT4.@]
5140 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5141 unsigned char *pMemory,
5142 PFORMAT_STRING pFormat)
5144 unsigned char switch_type;
5145 unsigned char increment;
5148 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5151 switch_type = *pFormat & 0xf;
5152 increment = (*pFormat & 0xf0) >> 4;
5155 switch_value = get_discriminant(switch_type, pMemory);
5156 TRACE("got switch value 0x%x\n", switch_value);
5158 pMemory += increment;
5160 return union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5163 /***********************************************************************
5164 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5166 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5167 unsigned char *pMemory,
5168 PFORMAT_STRING pFormat)
5170 unsigned char switch_type;
5172 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5175 switch_type = *pFormat;
5178 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5179 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5180 /* Marshall discriminant */
5181 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5183 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5186 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5187 PFORMAT_STRING *ppFormat)
5189 long discriminant = 0;
5199 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5208 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5209 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5217 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5218 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5223 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5227 if (pStubMsg->fHasNewCorrDesc)
5231 return discriminant;
5234 /**********************************************************************
5235 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5237 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5238 unsigned char **ppMemory,
5239 PFORMAT_STRING pFormat,
5240 unsigned char fMustAlloc)
5243 unsigned short size;
5245 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5248 /* Unmarshall discriminant */
5249 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5250 TRACE("unmarshalled discriminant %lx\n", discriminant);
5252 pFormat += *(const SHORT*)pFormat;
5254 size = *(const unsigned short*)pFormat;
5256 if(!*ppMemory || fMustAlloc)
5257 *ppMemory = NdrAllocate(pStubMsg, size);
5259 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5262 /***********************************************************************
5263 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5265 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5266 unsigned char *pMemory,
5267 PFORMAT_STRING pFormat)
5269 unsigned char switch_type;
5271 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5274 switch_type = *pFormat;
5277 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5278 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5279 /* Add discriminant size */
5280 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5282 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5285 /***********************************************************************
5286 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5288 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5289 PFORMAT_STRING pFormat)
5294 /* Unmarshall discriminant */
5295 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5296 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
5298 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
5301 /***********************************************************************
5302 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5304 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5305 unsigned char *pMemory,
5306 PFORMAT_STRING pFormat)
5308 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5312 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5313 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5315 return union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5318 /***********************************************************************
5319 * NdrByteCountPointerMarshall [RPCRT4.@]
5321 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5322 unsigned char *pMemory,
5323 PFORMAT_STRING pFormat)
5329 /***********************************************************************
5330 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5332 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5333 unsigned char **ppMemory,
5334 PFORMAT_STRING pFormat,
5335 unsigned char fMustAlloc)
5341 /***********************************************************************
5342 * NdrByteCountPointerBufferSize [RPCRT4.@]
5344 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5345 unsigned char *pMemory,
5346 PFORMAT_STRING pFormat)
5351 /***********************************************************************
5352 * NdrByteCountPointerMemorySize [RPCRT4.@]
5354 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5355 PFORMAT_STRING pFormat)
5361 /***********************************************************************
5362 * NdrByteCountPointerFree [RPCRT4.@]
5364 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
5365 unsigned char *pMemory,
5366 PFORMAT_STRING pFormat)
5371 /***********************************************************************
5372 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5374 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5375 unsigned char *pMemory,
5376 PFORMAT_STRING pFormat)
5382 /***********************************************************************
5383 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5385 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5386 unsigned char **ppMemory,
5387 PFORMAT_STRING pFormat,
5388 unsigned char fMustAlloc)
5394 /***********************************************************************
5395 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5397 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5398 unsigned char *pMemory,
5399 PFORMAT_STRING pFormat)
5404 /***********************************************************************
5405 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5407 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5408 PFORMAT_STRING pFormat)
5414 /***********************************************************************
5415 * NdrXmitOrRepAsFree [RPCRT4.@]
5417 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
5418 unsigned char *pMemory,
5419 PFORMAT_STRING pFormat)
5424 #include "pshpack1.h"
5428 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
5432 #include "poppack.h"
5434 /***********************************************************************
5435 * NdrRangeMarshall [internal]
5437 unsigned char *WINAPI NdrRangeMarshall(
5438 PMIDL_STUB_MESSAGE pStubMsg,
5439 unsigned char *pMemory,
5440 PFORMAT_STRING pFormat)
5442 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5443 unsigned char base_type;
5445 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5447 if (pRange->type != RPC_FC_RANGE)
5449 ERR("invalid format type %x\n", pRange->type);
5450 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5454 base_type = pRange->flags_type & 0xf;
5456 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
5459 /***********************************************************************
5460 * NdrRangeUnmarshall
5462 unsigned char *WINAPI NdrRangeUnmarshall(
5463 PMIDL_STUB_MESSAGE pStubMsg,
5464 unsigned char **ppMemory,
5465 PFORMAT_STRING pFormat,
5466 unsigned char fMustAlloc)
5468 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5469 unsigned char base_type;
5471 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5473 if (pRange->type != RPC_FC_RANGE)
5475 ERR("invalid format type %x\n", pRange->type);
5476 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5479 base_type = pRange->flags_type & 0xf;
5481 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5482 base_type, pRange->low_value, pRange->high_value);
5484 #define RANGE_UNMARSHALL(type, format_spec) \
5487 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5488 if (fMustAlloc || !*ppMemory) \
5489 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5490 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5492 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5493 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5494 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5496 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5497 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5499 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5500 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5501 (type)pRange->high_value); \
5502 RpcRaiseException(RPC_S_INVALID_BOUND); \
5505 TRACE("*ppMemory: %p\n", *ppMemory); \
5506 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5507 pStubMsg->Buffer += sizeof(type); \
5514 RANGE_UNMARSHALL(UCHAR, "%d");
5515 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5519 RANGE_UNMARSHALL(CHAR, "%u");
5520 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5522 case RPC_FC_WCHAR: /* FIXME: valid? */
5524 RANGE_UNMARSHALL(USHORT, "%u");
5525 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5528 RANGE_UNMARSHALL(SHORT, "%d");
5529 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5532 RANGE_UNMARSHALL(LONG, "%d");
5533 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5536 RANGE_UNMARSHALL(ULONG, "%u");
5537 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5541 FIXME("Unhandled enum type\n");
5543 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
5548 ERR("invalid range base type: 0x%02x\n", base_type);
5549 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5555 /***********************************************************************
5556 * NdrRangeBufferSize [internal]
5558 void WINAPI NdrRangeBufferSize(
5559 PMIDL_STUB_MESSAGE pStubMsg,
5560 unsigned char *pMemory,
5561 PFORMAT_STRING pFormat)
5563 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5564 unsigned char base_type;
5566 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5568 if (pRange->type != RPC_FC_RANGE)
5570 ERR("invalid format type %x\n", pRange->type);
5571 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5573 base_type = pRange->flags_type & 0xf;
5575 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
5578 /***********************************************************************
5579 * NdrRangeMemorySize [internal]
5581 ULONG WINAPI NdrRangeMemorySize(
5582 PMIDL_STUB_MESSAGE pStubMsg,
5583 PFORMAT_STRING pFormat)
5585 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5586 unsigned char base_type;
5588 if (pRange->type != RPC_FC_RANGE)
5590 ERR("invalid format type %x\n", pRange->type);
5591 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5594 base_type = pRange->flags_type & 0xf;
5596 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
5599 /***********************************************************************
5600 * NdrRangeFree [internal]
5602 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
5603 unsigned char *pMemory,
5604 PFORMAT_STRING pFormat)
5606 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5611 /***********************************************************************
5612 * NdrBaseTypeMarshall [internal]
5614 static unsigned char *WINAPI NdrBaseTypeMarshall(
5615 PMIDL_STUB_MESSAGE pStubMsg,
5616 unsigned char *pMemory,
5617 PFORMAT_STRING pFormat)
5619 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5627 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
5628 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
5633 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
5634 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
5635 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
5639 case RPC_FC_ERROR_STATUS_T:
5641 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
5642 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
5643 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
5646 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
5647 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
5650 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
5651 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
5654 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
5655 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
5656 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
5659 /* only 16-bits on the wire, so do a sanity check */
5660 if (*(UINT *)pMemory > SHRT_MAX)
5661 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
5662 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
5663 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5664 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5665 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
5666 pStubMsg->Buffer += sizeof(USHORT);
5667 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
5672 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5675 /* FIXME: what is the correct return value? */
5679 /***********************************************************************
5680 * NdrBaseTypeUnmarshall [internal]
5682 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
5683 PMIDL_STUB_MESSAGE pStubMsg,
5684 unsigned char **ppMemory,
5685 PFORMAT_STRING pFormat,
5686 unsigned char fMustAlloc)
5688 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5690 #define BASE_TYPE_UNMARSHALL(type) \
5691 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5692 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
5694 *ppMemory = pStubMsg->Buffer; \
5695 TRACE("*ppMemory: %p\n", *ppMemory); \
5700 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5701 TRACE("*ppMemory: %p\n", *ppMemory); \
5702 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5704 pStubMsg->Buffer += sizeof(type);
5712 BASE_TYPE_UNMARSHALL(UCHAR);
5713 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5718 BASE_TYPE_UNMARSHALL(USHORT);
5719 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5723 case RPC_FC_ERROR_STATUS_T:
5725 BASE_TYPE_UNMARSHALL(ULONG);
5726 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5729 BASE_TYPE_UNMARSHALL(float);
5730 TRACE("value: %f\n", **(float **)ppMemory);
5733 BASE_TYPE_UNMARSHALL(double);
5734 TRACE("value: %f\n", **(double **)ppMemory);
5737 BASE_TYPE_UNMARSHALL(ULONGLONG);
5738 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
5741 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5742 if (fMustAlloc || !*ppMemory)
5743 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
5744 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
5745 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5746 TRACE("*ppMemory: %p\n", *ppMemory);
5747 /* 16-bits on the wire, but int in memory */
5748 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
5749 pStubMsg->Buffer += sizeof(USHORT);
5750 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
5755 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5757 #undef BASE_TYPE_UNMARSHALL
5759 /* FIXME: what is the correct return value? */
5764 /***********************************************************************
5765 * NdrBaseTypeBufferSize [internal]
5767 static void WINAPI NdrBaseTypeBufferSize(
5768 PMIDL_STUB_MESSAGE pStubMsg,
5769 unsigned char *pMemory,
5770 PFORMAT_STRING pFormat)
5772 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5780 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
5786 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
5787 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
5792 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
5793 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
5796 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
5797 safe_buffer_length_increment(pStubMsg, sizeof(float));
5800 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
5801 safe_buffer_length_increment(pStubMsg, sizeof(double));
5804 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
5805 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
5807 case RPC_FC_ERROR_STATUS_T:
5808 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
5809 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
5814 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5818 /***********************************************************************
5819 * NdrBaseTypeMemorySize [internal]
5821 static ULONG WINAPI NdrBaseTypeMemorySize(
5822 PMIDL_STUB_MESSAGE pStubMsg,
5823 PFORMAT_STRING pFormat)
5825 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
5833 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
5834 pStubMsg->MemorySize += sizeof(UCHAR);
5835 return sizeof(UCHAR);
5839 safe_buffer_increment(pStubMsg, sizeof(USHORT));
5840 pStubMsg->MemorySize += sizeof(USHORT);
5841 return sizeof(USHORT);
5845 safe_buffer_increment(pStubMsg, sizeof(ULONG));
5846 pStubMsg->MemorySize += sizeof(ULONG);
5847 return sizeof(ULONG);
5849 safe_buffer_increment(pStubMsg, sizeof(float));
5850 pStubMsg->MemorySize += sizeof(float);
5851 return sizeof(float);
5853 safe_buffer_increment(pStubMsg, sizeof(double));
5854 pStubMsg->MemorySize += sizeof(double);
5855 return sizeof(double);
5857 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
5858 pStubMsg->MemorySize += sizeof(ULONGLONG);
5859 return sizeof(ULONGLONG);
5860 case RPC_FC_ERROR_STATUS_T:
5861 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
5862 pStubMsg->MemorySize += sizeof(error_status_t);
5863 return sizeof(error_status_t);
5865 safe_buffer_increment(pStubMsg, sizeof(USHORT));
5866 pStubMsg->MemorySize += sizeof(UINT);
5867 return sizeof(UINT);
5869 pStubMsg->MemorySize += sizeof(void *);
5870 return sizeof(void *);
5872 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5877 /***********************************************************************
5878 * NdrBaseTypeFree [internal]
5880 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
5881 unsigned char *pMemory,
5882 PFORMAT_STRING pFormat)
5884 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5889 /***********************************************************************
5890 * NdrContextHandleBufferSize [internal]
5892 static void WINAPI NdrContextHandleBufferSize(
5893 PMIDL_STUB_MESSAGE pStubMsg,
5894 unsigned char *pMemory,
5895 PFORMAT_STRING pFormat)
5897 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5899 if (*pFormat != RPC_FC_BIND_CONTEXT)
5901 ERR("invalid format type %x\n", *pFormat);
5902 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5904 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5905 safe_buffer_length_increment(pStubMsg, cbNDRContext);
5908 /***********************************************************************
5909 * NdrContextHandleMarshall [internal]
5911 static unsigned char *WINAPI NdrContextHandleMarshall(
5912 PMIDL_STUB_MESSAGE pStubMsg,
5913 unsigned char *pMemory,
5914 PFORMAT_STRING pFormat)
5916 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5918 if (*pFormat != RPC_FC_BIND_CONTEXT)
5920 ERR("invalid format type %x\n", *pFormat);
5921 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5924 if (pFormat[1] & 0x80)
5925 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
5927 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
5932 /***********************************************************************
5933 * NdrContextHandleUnmarshall [internal]
5935 static unsigned char *WINAPI NdrContextHandleUnmarshall(
5936 PMIDL_STUB_MESSAGE pStubMsg,
5937 unsigned char **ppMemory,
5938 PFORMAT_STRING pFormat,
5939 unsigned char fMustAlloc)
5941 if (*pFormat != RPC_FC_BIND_CONTEXT)
5943 ERR("invalid format type %x\n", *pFormat);
5944 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5947 **(NDR_CCONTEXT **)ppMemory = NULL;
5948 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
5953 /***********************************************************************
5954 * NdrClientContextMarshall [RPCRT4.@]
5956 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5957 NDR_CCONTEXT ContextHandle,
5960 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
5962 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5964 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5966 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
5967 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5968 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5971 /* FIXME: what does fCheck do? */
5972 NDRCContextMarshall(ContextHandle,
5975 pStubMsg->Buffer += cbNDRContext;
5978 /***********************************************************************
5979 * NdrClientContextUnmarshall [RPCRT4.@]
5981 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5982 NDR_CCONTEXT * pContextHandle,
5983 RPC_BINDING_HANDLE BindHandle)
5985 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
5987 ALIGN_POINTER(pStubMsg->Buffer, 4);
5989 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
5990 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5992 NDRCContextUnmarshall(pContextHandle,
5995 pStubMsg->RpcMsg->DataRepresentation);
5997 pStubMsg->Buffer += cbNDRContext;
6000 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6001 NDR_SCONTEXT ContextHandle,
6002 NDR_RUNDOWN RundownRoutine )
6004 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
6007 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6009 FIXME("(%p): stub\n", pStubMsg);
6013 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6014 unsigned char* pMemory,
6015 PFORMAT_STRING pFormat)
6017 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6020 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6021 PFORMAT_STRING pFormat)
6023 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
6027 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6028 NDR_SCONTEXT ContextHandle,
6029 NDR_RUNDOWN RundownRoutine,
6030 PFORMAT_STRING pFormat)
6032 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6035 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6036 PFORMAT_STRING pFormat)
6038 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);