4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * - Byte count pointers
24 * - transmit_as/represent as
25 * - Multi-dimensional arrays
26 * - Conversion functions (NdrConvert)
27 * - Checks for integer addition overflow in user marshall functions
42 #include "wine/unicode.h"
43 #include "wine/rpcfc.h"
45 #include "wine/debug.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(ole);
50 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
51 (*((UINT32 *)(pchar)) = (uint32))
53 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
54 (*((UINT32 *)(pchar)))
56 /* these would work for i386 too, but less efficient */
57 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
58 (*(pchar) = LOBYTE(LOWORD(uint32)), \
59 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
60 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
61 *((pchar)+3) = HIBYTE(HIWORD(uint32)))
63 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
65 MAKEWORD(*(pchar), *((pchar)+1)), \
66 MAKEWORD(*((pchar)+2), *((pchar)+3))))
69 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
70 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
71 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
72 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
73 *(pchar) = HIBYTE(HIWORD(uint32)))
75 #define BIG_ENDIAN_UINT32_READ(pchar) \
77 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
78 MAKEWORD(*((pchar)+1), *(pchar))))
80 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
81 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
82 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
83 # define NDR_LOCAL_UINT32_READ(pchar) \
84 BIG_ENDIAN_UINT32_READ(pchar)
86 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
87 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
88 # define NDR_LOCAL_UINT32_READ(pchar) \
89 LITTLE_ENDIAN_UINT32_READ(pchar)
92 /* _Align must be the desired alignment,
93 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
94 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
95 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
96 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
97 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
98 #define ALIGN_POINTER_CLEAR(_Ptr, _Align) \
100 memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \
101 ALIGN_POINTER(_Ptr, _Align); \
104 #define STD_OVERFLOW_CHECK(_Msg) do { \
105 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
106 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
107 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
110 #define NDR_POINTER_ID_BASE 0x20000
111 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
112 #define NDR_TABLE_SIZE 128
113 #define NDR_TABLE_MASK 127
115 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
116 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
117 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
118 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
119 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
121 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
122 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
123 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
125 static unsigned char *WINAPI NdrRangeMarshall(PMIDL_STUB_MESSAGE,unsigned char *, PFORMAT_STRING);
126 static void WINAPI NdrRangeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
127 static ULONG WINAPI NdrRangeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
128 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
130 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
132 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
134 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
135 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
136 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
137 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
141 NdrPointerMarshall, NdrPointerMarshall,
142 NdrPointerMarshall, NdrPointerMarshall,
144 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
145 NdrConformantStructMarshall, NdrConformantStructMarshall,
146 NdrConformantVaryingStructMarshall,
147 NdrComplexStructMarshall,
149 NdrConformantArrayMarshall,
150 NdrConformantVaryingArrayMarshall,
151 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
152 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
153 NdrComplexArrayMarshall,
155 NdrConformantStringMarshall, 0, 0,
156 NdrConformantStringMarshall,
157 NdrNonConformantStringMarshall, 0, 0, 0,
159 NdrEncapsulatedUnionMarshall,
160 NdrNonEncapsulatedUnionMarshall,
161 NdrByteCountPointerMarshall,
162 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
164 NdrInterfacePointerMarshall,
166 NdrContextHandleMarshall,
169 NdrUserMarshalMarshall,
174 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
176 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
177 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
178 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
179 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
181 NdrBaseTypeUnmarshall,
183 NdrPointerUnmarshall, NdrPointerUnmarshall,
184 NdrPointerUnmarshall, NdrPointerUnmarshall,
186 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
187 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
188 NdrConformantVaryingStructUnmarshall,
189 NdrComplexStructUnmarshall,
191 NdrConformantArrayUnmarshall,
192 NdrConformantVaryingArrayUnmarshall,
193 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
194 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
195 NdrComplexArrayUnmarshall,
197 NdrConformantStringUnmarshall, 0, 0,
198 NdrConformantStringUnmarshall,
199 NdrNonConformantStringUnmarshall, 0, 0, 0,
201 NdrEncapsulatedUnionUnmarshall,
202 NdrNonEncapsulatedUnionUnmarshall,
203 NdrByteCountPointerUnmarshall,
204 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
206 NdrInterfacePointerUnmarshall,
208 NdrContextHandleUnmarshall,
211 NdrUserMarshalUnmarshall,
216 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
218 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
219 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
220 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
221 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
223 NdrBaseTypeBufferSize,
225 NdrPointerBufferSize, NdrPointerBufferSize,
226 NdrPointerBufferSize, NdrPointerBufferSize,
228 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
229 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
230 NdrConformantVaryingStructBufferSize,
231 NdrComplexStructBufferSize,
233 NdrConformantArrayBufferSize,
234 NdrConformantVaryingArrayBufferSize,
235 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
236 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
237 NdrComplexArrayBufferSize,
239 NdrConformantStringBufferSize, 0, 0,
240 NdrConformantStringBufferSize,
241 NdrNonConformantStringBufferSize, 0, 0, 0,
243 NdrEncapsulatedUnionBufferSize,
244 NdrNonEncapsulatedUnionBufferSize,
245 NdrByteCountPointerBufferSize,
246 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
248 NdrInterfacePointerBufferSize,
250 NdrContextHandleBufferSize,
253 NdrUserMarshalBufferSize,
258 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
260 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
261 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
262 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
263 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
265 NdrBaseTypeMemorySize,
267 NdrPointerMemorySize, NdrPointerMemorySize,
268 NdrPointerMemorySize, NdrPointerMemorySize,
270 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
271 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
272 NdrConformantVaryingStructMemorySize,
273 NdrComplexStructMemorySize,
275 NdrConformantArrayMemorySize,
276 NdrConformantVaryingArrayMemorySize,
277 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
278 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
279 NdrComplexArrayMemorySize,
281 NdrConformantStringMemorySize, 0, 0,
282 NdrConformantStringMemorySize,
283 NdrNonConformantStringMemorySize, 0, 0, 0,
285 NdrEncapsulatedUnionMemorySize,
286 NdrNonEncapsulatedUnionMemorySize,
287 NdrByteCountPointerMemorySize,
288 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
290 NdrInterfacePointerMemorySize,
295 NdrUserMarshalMemorySize,
300 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
302 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
303 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
304 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
305 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
309 NdrPointerFree, NdrPointerFree,
310 NdrPointerFree, NdrPointerFree,
312 NdrSimpleStructFree, NdrSimpleStructFree,
313 NdrConformantStructFree, NdrConformantStructFree,
314 NdrConformantVaryingStructFree,
315 NdrComplexStructFree,
317 NdrConformantArrayFree,
318 NdrConformantVaryingArrayFree,
319 NdrFixedArrayFree, NdrFixedArrayFree,
320 NdrVaryingArrayFree, NdrVaryingArrayFree,
326 NdrEncapsulatedUnionFree,
327 NdrNonEncapsulatedUnionFree,
329 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
331 NdrInterfacePointerFree,
342 typedef struct _NDR_MEMORY_LIST
347 struct _NDR_MEMORY_LIST *next;
350 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
352 /***********************************************************************
353 * NdrAllocate [RPCRT4.@]
355 * Allocates a block of memory using pStubMsg->pfnAllocate.
358 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
359 * len [I] Size of memory block to allocate.
362 * The memory block of size len that was allocated.
365 * The memory block is always 8-byte aligned.
366 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
367 * exception is raised.
369 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, SIZE_T len)
374 NDR_MEMORY_LIST *mem_list;
376 aligned_len = ALIGNED_LENGTH(len, 8);
377 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
378 /* check for overflow */
379 if (adjusted_len < len)
381 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len, len);
382 RpcRaiseException(RPC_X_BAD_STUB_DATA);
385 p = pStubMsg->pfnAllocate(adjusted_len);
386 if (!p) RpcRaiseException(ERROR_OUTOFMEMORY);
388 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
389 mem_list->magic = MEML_MAGIC;
390 mem_list->size = aligned_len;
391 mem_list->reserved = 0;
392 mem_list->next = pStubMsg->pMemoryList;
393 pStubMsg->pMemoryList = mem_list;
399 static void NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
401 TRACE("(%p, %p)\n", pStubMsg, Pointer);
403 pStubMsg->pfnFree(Pointer);
406 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
408 return (*(const ULONG *)pFormat != -1);
411 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
413 ALIGN_POINTER(pStubMsg->Buffer, 4);
414 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
415 RpcRaiseException(RPC_X_BAD_STUB_DATA);
416 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
417 pStubMsg->Buffer += 4;
418 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
419 if (pStubMsg->fHasNewCorrDesc)
425 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
427 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
429 pStubMsg->Offset = 0;
430 pStubMsg->ActualCount = pStubMsg->MaxCount;
434 ALIGN_POINTER(pStubMsg->Buffer, 4);
435 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
436 RpcRaiseException(RPC_X_BAD_STUB_DATA);
437 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
438 pStubMsg->Buffer += 4;
439 TRACE("offset is %d\n", pStubMsg->Offset);
440 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
441 pStubMsg->Buffer += 4;
442 TRACE("variance is %d\n", pStubMsg->ActualCount);
444 if ((pStubMsg->ActualCount > MaxValue) ||
445 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
447 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
448 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
449 RpcRaiseException(RPC_S_INVALID_BOUND);
454 if (pStubMsg->fHasNewCorrDesc)
460 /* writes the conformance value to the buffer */
461 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
463 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
464 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
465 RpcRaiseException(RPC_X_BAD_STUB_DATA);
466 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
467 pStubMsg->Buffer += 4;
470 /* writes the variance values to the buffer */
471 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
473 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
474 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
475 RpcRaiseException(RPC_X_BAD_STUB_DATA);
476 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
477 pStubMsg->Buffer += 4;
478 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
479 pStubMsg->Buffer += 4;
482 /* requests buffer space for the conformance value */
483 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
485 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
486 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
487 RpcRaiseException(RPC_X_BAD_STUB_DATA);
488 pStubMsg->BufferLength += 4;
491 /* requests buffer space for the variance values */
492 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
494 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
495 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
496 RpcRaiseException(RPC_X_BAD_STUB_DATA);
497 pStubMsg->BufferLength += 8;
500 PFORMAT_STRING ComputeConformanceOrVariance(
501 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
502 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
504 BYTE dtype = pFormat[0] & 0xf;
505 short ofs = *(const short *)&pFormat[2];
509 if (!IsConformanceOrVariancePresent(pFormat)) {
510 /* null descriptor */
515 switch (pFormat[0] & 0xf0) {
516 case RPC_FC_NORMAL_CONFORMANCE:
517 TRACE("normal conformance, ofs=%d\n", ofs);
520 case RPC_FC_POINTER_CONFORMANCE:
521 TRACE("pointer conformance, ofs=%d\n", ofs);
522 ptr = pStubMsg->Memory;
524 case RPC_FC_TOP_LEVEL_CONFORMANCE:
525 TRACE("toplevel conformance, ofs=%d\n", ofs);
526 if (pStubMsg->StackTop) {
527 ptr = pStubMsg->StackTop;
530 /* -Os mode, *pCount is already set */
534 case RPC_FC_CONSTANT_CONFORMANCE:
535 data = ofs | ((DWORD)pFormat[1] << 16);
536 TRACE("constant conformance, val=%d\n", data);
539 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
540 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
541 if (pStubMsg->StackTop) {
542 ptr = pStubMsg->StackTop;
550 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
553 switch (pFormat[1]) {
554 case RPC_FC_DEREFERENCE:
555 ptr = *(LPVOID*)((char *)ptr + ofs);
557 case RPC_FC_CALLBACK:
559 unsigned char *old_stack_top = pStubMsg->StackTop;
560 pStubMsg->StackTop = ptr;
562 /* ofs is index into StubDesc->apfnExprEval */
563 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
564 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
566 pStubMsg->StackTop = old_stack_top;
568 /* the callback function always stores the computed value in MaxCount */
569 *pCount = pStubMsg->MaxCount;
573 ptr = (char *)ptr + ofs;
586 data = *(USHORT*)ptr;
597 FIXME("unknown conformance data type %x\n", dtype);
600 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
603 switch (pFormat[1]) {
604 case RPC_FC_DEREFERENCE: /* already handled */
621 FIXME("unknown conformance op %d\n", pFormat[1]);
626 TRACE("resulting conformance is %ld\n", *pCount);
627 if (pStubMsg->fHasNewCorrDesc)
633 static inline PFORMAT_STRING SkipConformance(PMIDL_STUB_MESSAGE pStubMsg,
634 PFORMAT_STRING pFormat)
636 if (IsConformanceOrVariancePresent(pFormat))
638 if (pStubMsg->fHasNewCorrDesc)
646 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
647 * the result overflows 32-bits */
648 static inline ULONG safe_multiply(ULONG a, ULONG b)
650 ULONGLONG ret = (ULONGLONG)a * b;
651 if (ret > 0xffffffff)
653 RpcRaiseException(RPC_S_INVALID_BOUND);
659 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
661 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
662 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
663 RpcRaiseException(RPC_X_BAD_STUB_DATA);
664 pStubMsg->Buffer += size;
667 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
669 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
671 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
672 pStubMsg->BufferLength, size);
673 RpcRaiseException(RPC_X_BAD_STUB_DATA);
675 pStubMsg->BufferLength += size;
678 /* copies data from the buffer, checking that there is enough data in the buffer
680 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
682 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
683 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
685 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
686 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
687 RpcRaiseException(RPC_X_BAD_STUB_DATA);
689 if (p == pStubMsg->Buffer)
690 ERR("pointer is the same as the buffer\n");
691 memcpy(p, pStubMsg->Buffer, size);
692 pStubMsg->Buffer += size;
695 /* copies data to the buffer, checking that there is enough space to do so */
696 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
698 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
699 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
701 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
702 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
704 RpcRaiseException(RPC_X_BAD_STUB_DATA);
706 memcpy(pStubMsg->Buffer, p, size);
707 pStubMsg->Buffer += size;
710 /* verify that string data sitting in the buffer is valid and safe to
712 static void validate_string_data(MIDL_STUB_MESSAGE *pStubMsg, ULONG bufsize, ULONG esize)
716 /* verify the buffer is safe to access */
717 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
718 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
720 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
721 pStubMsg->BufferEnd, pStubMsg->Buffer);
722 RpcRaiseException(RPC_X_BAD_STUB_DATA);
725 /* strings must always have null terminating bytes */
728 ERR("invalid string length of %d\n", bufsize / esize);
729 RpcRaiseException(RPC_S_INVALID_BOUND);
732 for (i = bufsize - esize; i < bufsize; i++)
733 if (pStubMsg->Buffer[i] != 0)
735 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
736 i, pStubMsg->Buffer[i]);
737 RpcRaiseException(RPC_S_INVALID_BOUND);
741 static inline void dump_pointer_attr(unsigned char attr)
743 if (attr & RPC_FC_P_ALLOCALLNODES)
744 TRACE(" RPC_FC_P_ALLOCALLNODES");
745 if (attr & RPC_FC_P_DONTFREE)
746 TRACE(" RPC_FC_P_DONTFREE");
747 if (attr & RPC_FC_P_ONSTACK)
748 TRACE(" RPC_FC_P_ONSTACK");
749 if (attr & RPC_FC_P_SIMPLEPOINTER)
750 TRACE(" RPC_FC_P_SIMPLEPOINTER");
751 if (attr & RPC_FC_P_DEREF)
752 TRACE(" RPC_FC_P_DEREF");
756 /***********************************************************************
757 * PointerMarshall [internal]
759 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
760 unsigned char *Buffer,
761 unsigned char *Pointer,
762 PFORMAT_STRING pFormat)
764 unsigned type = pFormat[0], attr = pFormat[1];
768 int pointer_needs_marshaling;
770 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
771 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
773 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
774 else desc = pFormat + *(const SHORT*)pFormat;
777 case RPC_FC_RP: /* ref pointer (always non-null) */
780 ERR("NULL ref pointer is not allowed\n");
781 RpcRaiseException(RPC_X_NULL_REF_POINTER);
783 pointer_needs_marshaling = 1;
785 case RPC_FC_UP: /* unique pointer */
786 case RPC_FC_OP: /* object pointer - same as unique here */
788 pointer_needs_marshaling = 1;
790 pointer_needs_marshaling = 0;
791 pointer_id = Pointer ? NDR_POINTER_ID(pStubMsg) : 0;
792 TRACE("writing 0x%08x to buffer\n", pointer_id);
793 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
796 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
797 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
798 TRACE("writing 0x%08x to buffer\n", pointer_id);
799 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
802 FIXME("unhandled ptr type=%02x\n", type);
803 RpcRaiseException(RPC_X_BAD_STUB_DATA);
807 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
809 if (pointer_needs_marshaling) {
810 if (attr & RPC_FC_P_DEREF) {
811 Pointer = *(unsigned char**)Pointer;
812 TRACE("deref => %p\n", Pointer);
814 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
815 if (m) m(pStubMsg, Pointer, desc);
816 else FIXME("no marshaller for data type=%02x\n", *desc);
819 STD_OVERFLOW_CHECK(pStubMsg);
822 /***********************************************************************
823 * PointerUnmarshall [internal]
825 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
826 unsigned char *Buffer,
827 unsigned char **pPointer,
828 unsigned char *pSrcPointer,
829 PFORMAT_STRING pFormat,
830 unsigned char fMustAlloc)
832 unsigned type = pFormat[0], attr = pFormat[1];
835 DWORD pointer_id = 0;
836 int pointer_needs_unmarshaling;
838 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
839 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
841 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
842 else desc = pFormat + *(const SHORT*)pFormat;
845 case RPC_FC_RP: /* ref pointer (always non-null) */
846 pointer_needs_unmarshaling = 1;
848 case RPC_FC_UP: /* unique pointer */
849 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
850 TRACE("pointer_id is 0x%08x\n", pointer_id);
852 pointer_needs_unmarshaling = 1;
855 pointer_needs_unmarshaling = 0;
858 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
859 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
860 TRACE("pointer_id is 0x%08x\n", pointer_id);
861 if (!fMustAlloc && pSrcPointer)
863 FIXME("free object pointer %p\n", pSrcPointer);
867 pointer_needs_unmarshaling = 1;
871 pointer_needs_unmarshaling = 0;
875 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
876 TRACE("pointer_id is 0x%08x\n", pointer_id);
877 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
878 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
881 FIXME("unhandled ptr type=%02x\n", type);
882 RpcRaiseException(RPC_X_BAD_STUB_DATA);
886 if (pointer_needs_unmarshaling) {
887 unsigned char *base_ptr_val = *pPointer;
888 unsigned char **current_ptr = pPointer;
889 if (pStubMsg->IsClient) {
891 /* if we aren't forcing allocation of memory then try to use the existing
892 * (source) pointer to unmarshall the data into so that [in,out]
893 * parameters behave correctly. it doesn't matter if the parameter is
894 * [out] only since in that case the pointer will be NULL. we force
895 * allocation when the source pointer is NULL here instead of in the type
896 * unmarshalling routine for the benefit of the deref code below */
899 TRACE("setting *pPointer to %p\n", pSrcPointer);
900 *pPointer = base_ptr_val = pSrcPointer;
906 /* the memory in a stub is never initialised, so we have to work out here
907 * whether we have to initialise it so we can use the optimisation of
908 * setting the pointer to the buffer, if possible, or set fMustAlloc to
910 if (attr & RPC_FC_P_DEREF) {
918 if (attr & RPC_FC_P_ALLOCALLNODES)
919 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
921 if (attr & RPC_FC_P_DEREF) {
923 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
924 *pPointer = base_ptr_val;
925 current_ptr = (unsigned char **)base_ptr_val;
927 current_ptr = *(unsigned char***)current_ptr;
928 TRACE("deref => %p\n", current_ptr);
929 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
931 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
932 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
933 else FIXME("no unmarshaller for data type=%02x\n", *desc);
935 if (type == RPC_FC_FP)
936 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
940 TRACE("pointer=%p\n", *pPointer);
943 /***********************************************************************
944 * PointerBufferSize [internal]
946 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
947 unsigned char *Pointer,
948 PFORMAT_STRING pFormat)
950 unsigned type = pFormat[0], attr = pFormat[1];
953 int pointer_needs_sizing;
956 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
957 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
959 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
960 else desc = pFormat + *(const SHORT*)pFormat;
963 case RPC_FC_RP: /* ref pointer (always non-null) */
966 ERR("NULL ref pointer is not allowed\n");
967 RpcRaiseException(RPC_X_NULL_REF_POINTER);
972 /* NULL pointer has no further representation */
977 pointer_needs_sizing = !NdrFullPointerQueryPointer(
978 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
979 if (!pointer_needs_sizing)
983 FIXME("unhandled ptr type=%02x\n", type);
984 RpcRaiseException(RPC_X_BAD_STUB_DATA);
988 if (attr & RPC_FC_P_DEREF) {
989 Pointer = *(unsigned char**)Pointer;
990 TRACE("deref => %p\n", Pointer);
993 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
994 if (m) m(pStubMsg, Pointer, desc);
995 else FIXME("no buffersizer for data type=%02x\n", *desc);
998 /***********************************************************************
999 * PointerMemorySize [internal]
1001 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1002 unsigned char *Buffer,
1003 PFORMAT_STRING pFormat)
1005 unsigned type = pFormat[0], attr = pFormat[1];
1006 PFORMAT_STRING desc;
1008 DWORD pointer_id = 0;
1009 int pointer_needs_sizing;
1011 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1012 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1014 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1015 else desc = pFormat + *(const SHORT*)pFormat;
1018 case RPC_FC_RP: /* ref pointer (always non-null) */
1019 pointer_needs_sizing = 1;
1021 case RPC_FC_UP: /* unique pointer */
1022 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1023 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1024 TRACE("pointer_id is 0x%08x\n", pointer_id);
1026 pointer_needs_sizing = 1;
1028 pointer_needs_sizing = 0;
1033 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1034 TRACE("pointer_id is 0x%08x\n", pointer_id);
1035 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1036 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1040 FIXME("unhandled ptr type=%02x\n", type);
1041 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1045 if (attr & RPC_FC_P_DEREF) {
1049 if (pointer_needs_sizing) {
1050 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1051 if (m) m(pStubMsg, desc);
1052 else FIXME("no memorysizer for data type=%02x\n", *desc);
1055 return pStubMsg->MemorySize;
1058 /***********************************************************************
1059 * PointerFree [internal]
1061 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1062 unsigned char *Pointer,
1063 PFORMAT_STRING pFormat)
1065 unsigned type = pFormat[0], attr = pFormat[1];
1066 PFORMAT_STRING desc;
1068 unsigned char *current_pointer = Pointer;
1070 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1071 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1072 if (attr & RPC_FC_P_DONTFREE) return;
1074 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1075 else desc = pFormat + *(const SHORT*)pFormat;
1077 if (!Pointer) return;
1079 if (type == RPC_FC_FP) {
1080 int pointer_needs_freeing = NdrFullPointerFree(
1081 pStubMsg->FullPtrXlatTables, Pointer);
1082 if (!pointer_needs_freeing)
1086 if (attr & RPC_FC_P_DEREF) {
1087 current_pointer = *(unsigned char**)Pointer;
1088 TRACE("deref => %p\n", current_pointer);
1091 m = NdrFreer[*desc & NDR_TABLE_MASK];
1092 if (m) m(pStubMsg, current_pointer, desc);
1094 /* this check stops us from trying to free buffer memory. we don't have to
1095 * worry about clients, since they won't call this function.
1096 * we don't have to check for the buffer being reallocated because
1097 * BufferStart and BufferEnd won't be reset when allocating memory for
1098 * sending the response. we don't have to check for the new buffer here as
1099 * it won't be used a type memory, only for buffer memory */
1100 if (Pointer >= pStubMsg->BufferStart && Pointer < pStubMsg->BufferEnd)
1103 if (attr & RPC_FC_P_ONSTACK) {
1104 TRACE("not freeing stack ptr %p\n", Pointer);
1107 TRACE("freeing %p\n", Pointer);
1108 NdrFree(pStubMsg, Pointer);
1111 TRACE("not freeing %p\n", Pointer);
1114 /***********************************************************************
1115 * EmbeddedPointerMarshall
1117 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1118 unsigned char *pMemory,
1119 PFORMAT_STRING pFormat)
1121 unsigned char *Mark = pStubMsg->BufferMark;
1122 unsigned rep, count, stride;
1124 unsigned char *saved_buffer = NULL;
1126 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1128 if (*pFormat != RPC_FC_PP) return NULL;
1131 if (pStubMsg->PointerBufferMark)
1133 saved_buffer = pStubMsg->Buffer;
1134 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1135 pStubMsg->PointerBufferMark = NULL;
1138 while (pFormat[0] != RPC_FC_END) {
1139 switch (pFormat[0]) {
1141 FIXME("unknown repeat type %d\n", pFormat[0]);
1142 case RPC_FC_NO_REPEAT:
1148 case RPC_FC_FIXED_REPEAT:
1149 rep = *(const WORD*)&pFormat[2];
1150 stride = *(const WORD*)&pFormat[4];
1151 count = *(const WORD*)&pFormat[8];
1154 case RPC_FC_VARIABLE_REPEAT:
1155 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1156 stride = *(const WORD*)&pFormat[2];
1157 count = *(const WORD*)&pFormat[6];
1161 for (i = 0; i < rep; i++) {
1162 PFORMAT_STRING info = pFormat;
1163 unsigned char *membase = pMemory + (i * stride);
1164 unsigned char *bufbase = Mark + (i * stride);
1167 for (u=0; u<count; u++,info+=8) {
1168 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1169 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1170 unsigned char *saved_memory = pStubMsg->Memory;
1172 pStubMsg->Memory = pMemory;
1173 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1174 pStubMsg->Memory = saved_memory;
1177 pFormat += 8 * count;
1182 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1183 pStubMsg->Buffer = saved_buffer;
1186 STD_OVERFLOW_CHECK(pStubMsg);
1191 /***********************************************************************
1192 * EmbeddedPointerUnmarshall
1194 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1195 unsigned char *pDstBuffer,
1196 unsigned char *pSrcMemoryPtrs,
1197 PFORMAT_STRING pFormat,
1198 unsigned char fMustAlloc)
1200 unsigned char *Mark = pStubMsg->BufferMark;
1201 unsigned rep, count, stride;
1203 unsigned char *saved_buffer = NULL;
1205 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc);
1207 if (*pFormat != RPC_FC_PP) return NULL;
1210 if (pStubMsg->PointerBufferMark)
1212 saved_buffer = pStubMsg->Buffer;
1213 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1214 pStubMsg->PointerBufferMark = NULL;
1217 while (pFormat[0] != RPC_FC_END) {
1218 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1219 switch (pFormat[0]) {
1221 FIXME("unknown repeat type %d\n", pFormat[0]);
1222 case RPC_FC_NO_REPEAT:
1228 case RPC_FC_FIXED_REPEAT:
1229 rep = *(const WORD*)&pFormat[2];
1230 stride = *(const WORD*)&pFormat[4];
1231 count = *(const WORD*)&pFormat[8];
1234 case RPC_FC_VARIABLE_REPEAT:
1235 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1236 stride = *(const WORD*)&pFormat[2];
1237 count = *(const WORD*)&pFormat[6];
1241 for (i = 0; i < rep; i++) {
1242 PFORMAT_STRING info = pFormat;
1243 unsigned char *bufdstbase = pDstBuffer + (i * stride);
1244 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1245 unsigned char *bufbase = Mark + (i * stride);
1248 for (u=0; u<count; u++,info+=8) {
1249 unsigned char **bufdstptr = (unsigned char **)(bufdstbase + *(const SHORT*)&info[2]);
1250 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1251 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1252 PointerUnmarshall(pStubMsg, bufptr, bufdstptr, *memsrcptr, info+4, fMustAlloc);
1255 pFormat += 8 * count;
1260 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1261 pStubMsg->Buffer = saved_buffer;
1267 /***********************************************************************
1268 * EmbeddedPointerBufferSize
1270 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1271 unsigned char *pMemory,
1272 PFORMAT_STRING pFormat)
1274 unsigned rep, count, stride;
1276 ULONG saved_buffer_length = 0;
1278 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1280 if (pStubMsg->IgnoreEmbeddedPointers) return;
1282 if (*pFormat != RPC_FC_PP) return;
1285 if (pStubMsg->PointerLength)
1287 saved_buffer_length = pStubMsg->BufferLength;
1288 pStubMsg->BufferLength = pStubMsg->PointerLength;
1289 pStubMsg->PointerLength = 0;
1292 while (pFormat[0] != RPC_FC_END) {
1293 switch (pFormat[0]) {
1295 FIXME("unknown repeat type %d\n", pFormat[0]);
1296 case RPC_FC_NO_REPEAT:
1302 case RPC_FC_FIXED_REPEAT:
1303 rep = *(const WORD*)&pFormat[2];
1304 stride = *(const WORD*)&pFormat[4];
1305 count = *(const WORD*)&pFormat[8];
1308 case RPC_FC_VARIABLE_REPEAT:
1309 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1310 stride = *(const WORD*)&pFormat[2];
1311 count = *(const WORD*)&pFormat[6];
1315 for (i = 0; i < rep; i++) {
1316 PFORMAT_STRING info = pFormat;
1317 unsigned char *membase = pMemory + (i * stride);
1320 for (u=0; u<count; u++,info+=8) {
1321 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1322 unsigned char *saved_memory = pStubMsg->Memory;
1324 pStubMsg->Memory = pMemory;
1325 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1326 pStubMsg->Memory = saved_memory;
1329 pFormat += 8 * count;
1332 if (saved_buffer_length)
1334 pStubMsg->PointerLength = pStubMsg->BufferLength;
1335 pStubMsg->BufferLength = saved_buffer_length;
1339 /***********************************************************************
1340 * EmbeddedPointerMemorySize [internal]
1342 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1343 PFORMAT_STRING pFormat)
1345 unsigned char *Mark = pStubMsg->BufferMark;
1346 unsigned rep, count, stride;
1348 unsigned char *saved_buffer = NULL;
1350 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1352 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1354 if (pStubMsg->PointerBufferMark)
1356 saved_buffer = pStubMsg->Buffer;
1357 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1358 pStubMsg->PointerBufferMark = NULL;
1361 if (*pFormat != RPC_FC_PP) return 0;
1364 while (pFormat[0] != RPC_FC_END) {
1365 switch (pFormat[0]) {
1367 FIXME("unknown repeat type %d\n", pFormat[0]);
1368 case RPC_FC_NO_REPEAT:
1374 case RPC_FC_FIXED_REPEAT:
1375 rep = *(const WORD*)&pFormat[2];
1376 stride = *(const WORD*)&pFormat[4];
1377 count = *(const WORD*)&pFormat[8];
1380 case RPC_FC_VARIABLE_REPEAT:
1381 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1382 stride = *(const WORD*)&pFormat[2];
1383 count = *(const WORD*)&pFormat[6];
1387 for (i = 0; i < rep; i++) {
1388 PFORMAT_STRING info = pFormat;
1389 unsigned char *bufbase = Mark + (i * stride);
1391 for (u=0; u<count; u++,info+=8) {
1392 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1393 PointerMemorySize(pStubMsg, bufptr, info+4);
1396 pFormat += 8 * count;
1401 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1402 pStubMsg->Buffer = saved_buffer;
1408 /***********************************************************************
1409 * EmbeddedPointerFree [internal]
1411 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1412 unsigned char *pMemory,
1413 PFORMAT_STRING pFormat)
1415 unsigned rep, count, stride;
1418 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1419 if (*pFormat != RPC_FC_PP) return;
1422 while (pFormat[0] != RPC_FC_END) {
1423 switch (pFormat[0]) {
1425 FIXME("unknown repeat type %d\n", pFormat[0]);
1426 case RPC_FC_NO_REPEAT:
1432 case RPC_FC_FIXED_REPEAT:
1433 rep = *(const WORD*)&pFormat[2];
1434 stride = *(const WORD*)&pFormat[4];
1435 count = *(const WORD*)&pFormat[8];
1438 case RPC_FC_VARIABLE_REPEAT:
1439 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1440 stride = *(const WORD*)&pFormat[2];
1441 count = *(const WORD*)&pFormat[6];
1445 for (i = 0; i < rep; i++) {
1446 PFORMAT_STRING info = pFormat;
1447 unsigned char *membase = pMemory + (i * stride);
1450 for (u=0; u<count; u++,info+=8) {
1451 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1452 unsigned char *saved_memory = pStubMsg->Memory;
1454 pStubMsg->Memory = pMemory;
1455 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1456 pStubMsg->Memory = saved_memory;
1459 pFormat += 8 * count;
1463 /***********************************************************************
1464 * NdrPointerMarshall [RPCRT4.@]
1466 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1467 unsigned char *pMemory,
1468 PFORMAT_STRING pFormat)
1470 unsigned char *Buffer;
1472 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1474 /* Increment the buffer here instead of in PointerMarshall,
1475 * as that is used by embedded pointers which already handle the incrementing
1476 * the buffer, and shouldn't write any additional pointer data to the wire */
1477 if (*pFormat != RPC_FC_RP)
1479 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
1480 Buffer = pStubMsg->Buffer;
1481 safe_buffer_increment(pStubMsg, 4);
1484 Buffer = pStubMsg->Buffer;
1486 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1491 /***********************************************************************
1492 * NdrPointerUnmarshall [RPCRT4.@]
1494 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1495 unsigned char **ppMemory,
1496 PFORMAT_STRING pFormat,
1497 unsigned char fMustAlloc)
1499 unsigned char *Buffer;
1501 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1503 if (*pFormat == RPC_FC_RP)
1505 Buffer = pStubMsg->Buffer;
1506 /* Do the NULL ref pointer check here because embedded pointers can be
1507 * NULL if the type the pointer is embedded in was allocated rather than
1508 * being passed in by the client */
1509 if (pStubMsg->IsClient && !*ppMemory)
1511 ERR("NULL ref pointer is not allowed\n");
1512 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1517 /* Increment the buffer here instead of in PointerUnmarshall,
1518 * as that is used by embedded pointers which already handle the incrementing
1519 * the buffer, and shouldn't read any additional pointer data from the
1521 ALIGN_POINTER(pStubMsg->Buffer, 4);
1522 Buffer = pStubMsg->Buffer;
1523 safe_buffer_increment(pStubMsg, 4);
1526 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1531 /***********************************************************************
1532 * NdrPointerBufferSize [RPCRT4.@]
1534 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1535 unsigned char *pMemory,
1536 PFORMAT_STRING pFormat)
1538 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1540 /* Increment the buffer length here instead of in PointerBufferSize,
1541 * as that is used by embedded pointers which already handle the buffer
1542 * length, and shouldn't write anything more to the wire */
1543 if (*pFormat != RPC_FC_RP)
1545 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1546 safe_buffer_length_increment(pStubMsg, 4);
1549 PointerBufferSize(pStubMsg, pMemory, pFormat);
1552 /***********************************************************************
1553 * NdrPointerMemorySize [RPCRT4.@]
1555 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1556 PFORMAT_STRING pFormat)
1558 /* unsigned size = *(LPWORD)(pFormat+2); */
1559 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1560 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1564 /***********************************************************************
1565 * NdrPointerFree [RPCRT4.@]
1567 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1568 unsigned char *pMemory,
1569 PFORMAT_STRING pFormat)
1571 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1572 PointerFree(pStubMsg, pMemory, pFormat);
1575 /***********************************************************************
1576 * NdrSimpleTypeMarshall [RPCRT4.@]
1578 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1579 unsigned char FormatChar )
1581 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1584 /***********************************************************************
1585 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1587 * Unmarshall a base type.
1590 * Doesn't check that the buffer is long enough before copying, so the caller
1593 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1594 unsigned char FormatChar )
1596 #define BASE_TYPE_UNMARSHALL(type) \
1597 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
1598 TRACE("pMemory: %p\n", pMemory); \
1599 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1600 pStubMsg->Buffer += sizeof(type);
1608 BASE_TYPE_UNMARSHALL(UCHAR);
1609 TRACE("value: 0x%02x\n", *pMemory);
1614 BASE_TYPE_UNMARSHALL(USHORT);
1615 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
1619 case RPC_FC_ERROR_STATUS_T:
1621 BASE_TYPE_UNMARSHALL(ULONG);
1622 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
1625 BASE_TYPE_UNMARSHALL(float);
1626 TRACE("value: %f\n", *(float *)pMemory);
1629 BASE_TYPE_UNMARSHALL(double);
1630 TRACE("value: %f\n", *(double *)pMemory);
1633 BASE_TYPE_UNMARSHALL(ULONGLONG);
1634 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
1637 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
1638 TRACE("pMemory: %p\n", pMemory);
1639 /* 16-bits on the wire, but int in memory */
1640 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
1641 pStubMsg->Buffer += sizeof(USHORT);
1642 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
1647 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
1649 #undef BASE_TYPE_UNMARSHALL
1652 /***********************************************************************
1653 * NdrSimpleStructMarshall [RPCRT4.@]
1655 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1656 unsigned char *pMemory,
1657 PFORMAT_STRING pFormat)
1659 unsigned size = *(const WORD*)(pFormat+2);
1660 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1662 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
1664 pStubMsg->BufferMark = pStubMsg->Buffer;
1665 safe_copy_to_buffer(pStubMsg, pMemory, size);
1667 if (pFormat[0] != RPC_FC_STRUCT)
1668 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1673 /***********************************************************************
1674 * NdrSimpleStructUnmarshall [RPCRT4.@]
1676 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1677 unsigned char **ppMemory,
1678 PFORMAT_STRING pFormat,
1679 unsigned char fMustAlloc)
1681 unsigned size = *(const WORD*)(pFormat+2);
1682 unsigned char *saved_buffer;
1683 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1685 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1688 *ppMemory = NdrAllocate(pStubMsg, size);
1691 if (!pStubMsg->IsClient && !*ppMemory)
1692 /* for servers, we just point straight into the RPC buffer */
1693 *ppMemory = pStubMsg->Buffer;
1696 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1697 safe_buffer_increment(pStubMsg, size);
1698 if (pFormat[0] == RPC_FC_PSTRUCT)
1699 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1701 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1702 if (*ppMemory != saved_buffer)
1703 memcpy(*ppMemory, saved_buffer, size);
1708 /***********************************************************************
1709 * NdrSimpleStructBufferSize [RPCRT4.@]
1711 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1712 unsigned char *pMemory,
1713 PFORMAT_STRING pFormat)
1715 unsigned size = *(const WORD*)(pFormat+2);
1716 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1718 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1720 safe_buffer_length_increment(pStubMsg, size);
1721 if (pFormat[0] != RPC_FC_STRUCT)
1722 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1725 /***********************************************************************
1726 * NdrSimpleStructMemorySize [RPCRT4.@]
1728 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1729 PFORMAT_STRING pFormat)
1731 unsigned short size = *(const WORD *)(pFormat+2);
1733 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1735 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1736 pStubMsg->MemorySize += size;
1737 safe_buffer_increment(pStubMsg, size);
1739 if (pFormat[0] != RPC_FC_STRUCT)
1740 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1741 return pStubMsg->MemorySize;
1744 /***********************************************************************
1745 * NdrSimpleStructFree [RPCRT4.@]
1747 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1748 unsigned char *pMemory,
1749 PFORMAT_STRING pFormat)
1751 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1752 if (pFormat[0] != RPC_FC_STRUCT)
1753 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1758 static inline void array_compute_and_size_conformance(
1759 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1760 PFORMAT_STRING pFormat)
1765 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1766 SizeConformance(pStubMsg);
1768 case RPC_FC_CVARRAY:
1769 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1770 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1771 SizeConformance(pStubMsg);
1773 case RPC_FC_C_CSTRING:
1774 case RPC_FC_C_WSTRING:
1775 if (pFormat[0] == RPC_FC_C_CSTRING)
1777 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1778 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1782 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1783 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1786 if (fc == RPC_FC_STRING_SIZED)
1787 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1789 pStubMsg->MaxCount = pStubMsg->ActualCount;
1791 SizeConformance(pStubMsg);
1794 ERR("unknown array format 0x%x\n", fc);
1795 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1799 static inline void array_buffer_size(
1800 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1801 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1805 unsigned char alignment;
1810 esize = *(const WORD*)(pFormat+2);
1811 alignment = pFormat[1] + 1;
1813 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1815 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
1817 size = safe_multiply(esize, pStubMsg->MaxCount);
1818 /* conformance value plus array */
1819 safe_buffer_length_increment(pStubMsg, size);
1822 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1824 case RPC_FC_CVARRAY:
1825 esize = *(const WORD*)(pFormat+2);
1826 alignment = pFormat[1] + 1;
1828 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1829 pFormat = SkipConformance(pStubMsg, pFormat);
1831 SizeVariance(pStubMsg);
1833 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
1835 size = safe_multiply(esize, pStubMsg->ActualCount);
1836 safe_buffer_length_increment(pStubMsg, size);
1839 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1841 case RPC_FC_C_CSTRING:
1842 case RPC_FC_C_WSTRING:
1843 if (fc == RPC_FC_C_CSTRING)
1848 SizeVariance(pStubMsg);
1850 size = safe_multiply(esize, pStubMsg->ActualCount);
1851 safe_buffer_length_increment(pStubMsg, size);
1854 ERR("unknown array format 0x%x\n", fc);
1855 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1859 static inline void array_compute_and_write_conformance(
1860 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1861 PFORMAT_STRING pFormat)
1866 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1867 WriteConformance(pStubMsg);
1869 case RPC_FC_CVARRAY:
1870 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1871 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1872 WriteConformance(pStubMsg);
1874 case RPC_FC_C_CSTRING:
1875 case RPC_FC_C_WSTRING:
1876 if (fc == RPC_FC_C_CSTRING)
1878 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1879 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1883 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1884 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1886 if (pFormat[1] == RPC_FC_STRING_SIZED)
1887 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1889 pStubMsg->MaxCount = pStubMsg->ActualCount;
1890 pStubMsg->Offset = 0;
1891 WriteConformance(pStubMsg);
1894 ERR("unknown array format 0x%x\n", fc);
1895 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1899 static inline void array_write_variance_and_marshall(
1900 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1901 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1905 unsigned char alignment;
1910 esize = *(const WORD*)(pFormat+2);
1911 alignment = pFormat[1] + 1;
1913 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1915 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
1917 size = safe_multiply(esize, pStubMsg->MaxCount);
1919 pStubMsg->BufferMark = pStubMsg->Buffer;
1920 safe_copy_to_buffer(pStubMsg, pMemory, size);
1923 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1925 case RPC_FC_CVARRAY:
1926 esize = *(const WORD*)(pFormat+2);
1927 alignment = pFormat[1] + 1;
1930 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1932 pFormat = SkipConformance(pStubMsg, pFormat);
1934 WriteVariance(pStubMsg);
1936 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
1938 size = safe_multiply(esize, pStubMsg->ActualCount);
1941 pStubMsg->BufferMark = pStubMsg->Buffer;
1942 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size);
1945 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1947 case RPC_FC_C_CSTRING:
1948 case RPC_FC_C_WSTRING:
1949 if (fc == RPC_FC_C_CSTRING)
1954 WriteVariance(pStubMsg);
1956 size = safe_multiply(esize, pStubMsg->ActualCount);
1957 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
1960 ERR("unknown array format 0x%x\n", fc);
1961 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1965 static inline ULONG array_read_conformance(
1966 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
1973 esize = *(const WORD*)(pFormat+2);
1974 pFormat = ReadConformance(pStubMsg, pFormat+4);
1975 return safe_multiply(esize, pStubMsg->MaxCount);
1976 case RPC_FC_CVARRAY:
1977 esize = *(const WORD*)(pFormat+2);
1978 pFormat = ReadConformance(pStubMsg, pFormat+4);
1979 return safe_multiply(esize, pStubMsg->MaxCount);
1980 case RPC_FC_C_CSTRING:
1981 case RPC_FC_C_WSTRING:
1982 if (fc == RPC_FC_C_CSTRING)
1987 if (pFormat[1] == RPC_FC_STRING_SIZED)
1988 ReadConformance(pStubMsg, pFormat + 2);
1990 ReadConformance(pStubMsg, NULL);
1991 return safe_multiply(esize, pStubMsg->MaxCount);
1993 ERR("unknown array format 0x%x\n", fc);
1994 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1998 static inline ULONG array_read_variance_and_unmarshall(
1999 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory,
2000 PFORMAT_STRING pFormat, unsigned char fMustAlloc,
2001 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall)
2003 ULONG bufsize, memsize;
2005 unsigned char alignment;
2006 unsigned char *saved_buffer;
2012 esize = *(const WORD*)(pFormat+2);
2013 alignment = pFormat[1] + 1;
2015 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2017 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2019 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2024 *ppMemory = NdrAllocate(pStubMsg, memsize);
2027 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory)
2028 /* for servers, we just point straight into the RPC buffer */
2029 *ppMemory = pStubMsg->Buffer;
2032 saved_buffer = pStubMsg->Buffer;
2033 safe_buffer_increment(pStubMsg, bufsize);
2035 pStubMsg->BufferMark = saved_buffer;
2036 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2038 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2039 if (*ppMemory != saved_buffer)
2040 memcpy(*ppMemory, saved_buffer, bufsize);
2043 case RPC_FC_CVARRAY:
2044 esize = *(const WORD*)(pFormat+2);
2045 alignment = pFormat[1] + 1;
2047 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2049 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2051 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2053 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2054 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2058 offset = pStubMsg->Offset;
2060 if (!fMustAlloc && !*ppMemory)
2063 *ppMemory = NdrAllocate(pStubMsg, memsize);
2064 saved_buffer = pStubMsg->Buffer;
2065 safe_buffer_increment(pStubMsg, bufsize);
2067 pStubMsg->BufferMark = saved_buffer;
2068 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat,
2071 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2074 case RPC_FC_C_CSTRING:
2075 case RPC_FC_C_WSTRING:
2076 if (fc == RPC_FC_C_CSTRING)
2081 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2083 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2085 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2086 pStubMsg->ActualCount, pStubMsg->MaxCount);
2087 RpcRaiseException(RPC_S_INVALID_BOUND);
2089 if (pStubMsg->Offset)
2091 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2092 RpcRaiseException(RPC_S_INVALID_BOUND);
2095 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2096 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2098 validate_string_data(pStubMsg, bufsize, esize);
2103 *ppMemory = NdrAllocate(pStubMsg, memsize);
2106 if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
2107 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
2108 /* if the data in the RPC buffer is big enough, we just point
2109 * straight into it */
2110 *ppMemory = pStubMsg->Buffer;
2111 else if (!*ppMemory)
2112 *ppMemory = NdrAllocate(pStubMsg, memsize);
2115 if (*ppMemory == pStubMsg->Buffer)
2116 safe_buffer_increment(pStubMsg, bufsize);
2118 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2120 if (*pFormat == RPC_FC_C_CSTRING)
2121 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
2123 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
2127 ERR("unknown array format 0x%x\n", fc);
2128 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2132 static inline void array_memory_size(
2133 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
2134 unsigned char fHasPointers)
2136 ULONG bufsize, memsize;
2138 unsigned char alignment;
2143 esize = *(const WORD*)(pFormat+2);
2144 alignment = pFormat[1] + 1;
2146 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2148 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2149 pStubMsg->MemorySize += memsize;
2151 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2153 pStubMsg->BufferMark = pStubMsg->Buffer;
2154 safe_buffer_increment(pStubMsg, bufsize);
2157 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2159 case RPC_FC_CVARRAY:
2160 esize = *(const WORD*)(pFormat+2);
2161 alignment = pFormat[1] + 1;
2163 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2165 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2167 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2168 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2169 pStubMsg->MemorySize += memsize;
2171 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2173 pStubMsg->BufferMark = pStubMsg->Buffer;
2174 safe_buffer_increment(pStubMsg, bufsize);
2177 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2179 case RPC_FC_C_CSTRING:
2180 case RPC_FC_C_WSTRING:
2181 if (fc == RPC_FC_C_CSTRING)
2186 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2188 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2190 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2191 pStubMsg->ActualCount, pStubMsg->MaxCount);
2192 RpcRaiseException(RPC_S_INVALID_BOUND);
2194 if (pStubMsg->Offset)
2196 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2197 RpcRaiseException(RPC_S_INVALID_BOUND);
2200 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2201 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2203 validate_string_data(pStubMsg, bufsize, esize);
2205 safe_buffer_increment(pStubMsg, bufsize);
2206 pStubMsg->MemorySize += memsize;
2209 ERR("unknown array format 0x%x\n", fc);
2210 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2214 static inline void array_free(
2215 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
2216 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
2221 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2223 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2225 case RPC_FC_CVARRAY:
2226 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2227 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2229 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2231 case RPC_FC_C_CSTRING:
2232 case RPC_FC_C_WSTRING:
2233 /* No embedded pointers so nothing to do */
2236 ERR("unknown array format 0x%x\n", fc);
2237 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2242 * NdrConformantString:
2244 * What MS calls a ConformantString is, in DCE terminology,
2245 * a Varying-Conformant String.
2247 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2248 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2249 * into unmarshalled string)
2250 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2252 * data: CHARTYPE[maxlen]
2254 * ], where CHARTYPE is the appropriate character type (specified externally)
2258 /***********************************************************************
2259 * NdrConformantStringMarshall [RPCRT4.@]
2261 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
2262 unsigned char *pszMessage, PFORMAT_STRING pFormat)
2264 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
2266 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2267 ERR("Unhandled string type: %#x\n", pFormat[0]);
2268 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2271 /* allow compiler to optimise inline function by passing constant into
2272 * these functions */
2273 if (pFormat[0] == RPC_FC_C_CSTRING) {
2274 array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2276 array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2277 pFormat, TRUE /* fHasPointers */);
2279 array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2281 array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2282 pFormat, TRUE /* fHasPointers */);
2288 /***********************************************************************
2289 * NdrConformantStringBufferSize [RPCRT4.@]
2291 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2292 unsigned char* pMemory, PFORMAT_STRING pFormat)
2294 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2296 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2297 ERR("Unhandled string type: %#x\n", pFormat[0]);
2298 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2301 /* allow compiler to optimise inline function by passing constant into
2302 * these functions */
2303 if (pFormat[0] == RPC_FC_C_CSTRING) {
2304 array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory,
2306 array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat,
2307 TRUE /* fHasPointers */);
2309 array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory,
2311 array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat,
2312 TRUE /* fHasPointers */);
2316 /************************************************************************
2317 * NdrConformantStringMemorySize [RPCRT4.@]
2319 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2320 PFORMAT_STRING pFormat )
2322 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2324 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2325 ERR("Unhandled string type: %#x\n", pFormat[0]);
2326 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2329 /* allow compiler to optimise inline function by passing constant into
2330 * these functions */
2331 if (pFormat[0] == RPC_FC_C_CSTRING) {
2332 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2333 array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat,
2334 TRUE /* fHasPointers */);
2336 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2337 array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat,
2338 TRUE /* fHasPointers */);
2341 return pStubMsg->MemorySize;
2344 /************************************************************************
2345 * NdrConformantStringUnmarshall [RPCRT4.@]
2347 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2348 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
2350 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2351 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2353 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2354 ERR("Unhandled string type: %#x\n", *pFormat);
2355 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2358 /* allow compiler to optimise inline function by passing constant into
2359 * these functions */
2360 if (pFormat[0] == RPC_FC_C_CSTRING) {
2361 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2362 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory,
2363 pFormat, fMustAlloc,
2364 TRUE /* fUseBufferMemoryServer */,
2365 TRUE /* fUnmarshall */);
2367 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2368 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory,
2369 pFormat, fMustAlloc,
2370 TRUE /* fUseBufferMemoryServer */,
2371 TRUE /* fUnmarshall */);
2377 /***********************************************************************
2378 * NdrNonConformantStringMarshall [RPCRT4.@]
2380 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2381 unsigned char *pMemory,
2382 PFORMAT_STRING pFormat)
2384 ULONG esize, size, maxsize;
2386 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2388 maxsize = *(USHORT *)&pFormat[2];
2390 if (*pFormat == RPC_FC_CSTRING)
2393 const char *str = (const char *)pMemory;
2394 for (i = 0; i < maxsize && *str; i++, str++)
2396 TRACE("string=%s\n", debugstr_an(str, i));
2397 pStubMsg->ActualCount = i + 1;
2400 else if (*pFormat == RPC_FC_WSTRING)
2403 const WCHAR *str = (const WCHAR *)pMemory;
2404 for (i = 0; i < maxsize && *str; i++, str++)
2406 TRACE("string=%s\n", debugstr_wn(str, i));
2407 pStubMsg->ActualCount = i + 1;
2412 ERR("Unhandled string type: %#x\n", *pFormat);
2413 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2416 pStubMsg->Offset = 0;
2417 WriteVariance(pStubMsg);
2419 size = safe_multiply(esize, pStubMsg->ActualCount);
2420 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2425 /***********************************************************************
2426 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2428 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2429 unsigned char **ppMemory,
2430 PFORMAT_STRING pFormat,
2431 unsigned char fMustAlloc)
2433 ULONG bufsize, memsize, esize, maxsize;
2435 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2436 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2438 maxsize = *(USHORT *)&pFormat[2];
2440 ReadVariance(pStubMsg, NULL, maxsize);
2441 if (pStubMsg->Offset)
2443 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2444 RpcRaiseException(RPC_S_INVALID_BOUND);
2447 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2448 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2451 ERR("Unhandled string type: %#x\n", *pFormat);
2452 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2455 memsize = esize * maxsize;
2456 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2458 validate_string_data(pStubMsg, bufsize, esize);
2460 if (!fMustAlloc && !*ppMemory)
2463 *ppMemory = NdrAllocate(pStubMsg, memsize);
2465 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2467 if (*pFormat == RPC_FC_CSTRING) {
2468 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
2470 else if (*pFormat == RPC_FC_WSTRING) {
2471 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
2477 /***********************************************************************
2478 * NdrNonConformantStringBufferSize [RPCRT4.@]
2480 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2481 unsigned char *pMemory,
2482 PFORMAT_STRING pFormat)
2484 ULONG esize, maxsize;
2486 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2488 maxsize = *(USHORT *)&pFormat[2];
2490 SizeVariance(pStubMsg);
2492 if (*pFormat == RPC_FC_CSTRING)
2495 const char *str = (const char *)pMemory;
2496 for (i = 0; i < maxsize && *str; i++, str++)
2498 TRACE("string=%s\n", debugstr_an(str, i));
2499 pStubMsg->ActualCount = i + 1;
2502 else if (*pFormat == RPC_FC_WSTRING)
2505 const WCHAR *str = (const WCHAR *)pMemory;
2506 for (i = 0; i < maxsize && *str; i++, str++)
2508 TRACE("string=%s\n", debugstr_wn(str, i));
2509 pStubMsg->ActualCount = i + 1;
2514 ERR("Unhandled string type: %#x\n", *pFormat);
2515 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2518 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2521 /***********************************************************************
2522 * NdrNonConformantStringMemorySize [RPCRT4.@]
2524 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2525 PFORMAT_STRING pFormat)
2527 ULONG bufsize, memsize, esize, maxsize;
2529 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2531 maxsize = *(USHORT *)&pFormat[2];
2533 ReadVariance(pStubMsg, NULL, maxsize);
2535 if (pStubMsg->Offset)
2537 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2538 RpcRaiseException(RPC_S_INVALID_BOUND);
2541 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2542 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2545 ERR("Unhandled string type: %#x\n", *pFormat);
2546 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2549 memsize = esize * maxsize;
2550 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2552 validate_string_data(pStubMsg, bufsize, esize);
2554 safe_buffer_increment(pStubMsg, bufsize);
2555 pStubMsg->MemorySize += memsize;
2557 return pStubMsg->MemorySize;
2562 #include "pshpack1.h"
2566 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2570 #include "poppack.h"
2572 static unsigned long EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2573 PFORMAT_STRING pFormat)
2577 case RPC_FC_PSTRUCT:
2578 case RPC_FC_CSTRUCT:
2579 case RPC_FC_BOGUS_STRUCT:
2580 case RPC_FC_SMFARRAY:
2581 case RPC_FC_SMVARRAY:
2582 case RPC_FC_CSTRING:
2583 return *(const WORD*)&pFormat[2];
2584 case RPC_FC_USER_MARSHAL:
2585 return *(const WORD*)&pFormat[4];
2586 case RPC_FC_RANGE: {
2587 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2592 return sizeof(UCHAR);
2596 return sizeof(USHORT);
2600 return sizeof(ULONG);
2602 return sizeof(float);
2604 return sizeof(double);
2606 return sizeof(ULONGLONG);
2608 return sizeof(UINT);
2610 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2611 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2614 case RPC_FC_NON_ENCAPSULATED_UNION:
2616 if (pStubMsg->fHasNewCorrDesc)
2621 pFormat += *(const SHORT*)pFormat;
2622 return *(const SHORT*)pFormat;
2624 return sizeof(void *);
2625 case RPC_FC_WSTRING:
2626 return *(const WORD*)&pFormat[2] * 2;
2628 FIXME("unhandled embedded type %02x\n", *pFormat);
2634 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2635 PFORMAT_STRING pFormat)
2637 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2641 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2645 return m(pStubMsg, pFormat);
2649 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2650 unsigned char *pMemory,
2651 PFORMAT_STRING pFormat,
2652 PFORMAT_STRING pPointer)
2654 PFORMAT_STRING desc;
2658 while (*pFormat != RPC_FC_END) {
2664 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2665 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2671 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2672 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2676 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2677 if (32767 < *(DWORD*)pMemory)
2678 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2679 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2685 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2686 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2690 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2691 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2694 case RPC_FC_POINTER:
2696 unsigned char *saved_buffer;
2697 int pointer_buffer_mark_set = 0;
2698 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2699 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2700 if (*pPointer != RPC_FC_RP)
2701 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
2702 saved_buffer = pStubMsg->Buffer;
2703 if (pStubMsg->PointerBufferMark)
2705 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2706 pStubMsg->PointerBufferMark = NULL;
2707 pointer_buffer_mark_set = 1;
2709 else if (*pPointer != RPC_FC_RP)
2710 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2711 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2712 if (pointer_buffer_mark_set)
2714 STD_OVERFLOW_CHECK(pStubMsg);
2715 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2716 pStubMsg->Buffer = saved_buffer;
2717 if (*pPointer != RPC_FC_RP)
2718 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2720 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2725 case RPC_FC_ALIGNM4:
2726 ALIGN_POINTER(pMemory, 4);
2728 case RPC_FC_ALIGNM8:
2729 ALIGN_POINTER(pMemory, 8);
2731 case RPC_FC_STRUCTPAD1:
2732 case RPC_FC_STRUCTPAD2:
2733 case RPC_FC_STRUCTPAD3:
2734 case RPC_FC_STRUCTPAD4:
2735 case RPC_FC_STRUCTPAD5:
2736 case RPC_FC_STRUCTPAD6:
2737 case RPC_FC_STRUCTPAD7:
2738 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2740 case RPC_FC_EMBEDDED_COMPLEX:
2741 pMemory += pFormat[1];
2743 desc = pFormat + *(const SHORT*)pFormat;
2744 size = EmbeddedComplexSize(pStubMsg, desc);
2745 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
2746 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2749 /* for some reason interface pointers aren't generated as
2750 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2751 * they still need the derefencing treatment that pointers are
2753 if (*desc == RPC_FC_IP)
2754 m(pStubMsg, *(unsigned char **)pMemory, desc);
2756 m(pStubMsg, pMemory, desc);
2758 else FIXME("no marshaller for embedded type %02x\n", *desc);
2765 FIXME("unhandled format 0x%02x\n", *pFormat);
2773 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2774 unsigned char *pMemory,
2775 PFORMAT_STRING pFormat,
2776 PFORMAT_STRING pPointer,
2777 unsigned char fMustAlloc)
2779 PFORMAT_STRING desc;
2783 while (*pFormat != RPC_FC_END) {
2789 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2790 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2796 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2797 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2801 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2802 *(DWORD*)pMemory &= 0xffff;
2803 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
2804 if (32767 < *(DWORD*)pMemory)
2805 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2811 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2812 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2816 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2817 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2820 case RPC_FC_POINTER:
2822 unsigned char *saved_buffer;
2823 int pointer_buffer_mark_set = 0;
2824 TRACE("pointer => %p\n", pMemory);
2825 if (*pPointer != RPC_FC_RP)
2826 ALIGN_POINTER(pStubMsg->Buffer, 4);
2827 saved_buffer = pStubMsg->Buffer;
2828 if (pStubMsg->PointerBufferMark)
2830 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2831 pStubMsg->PointerBufferMark = NULL;
2832 pointer_buffer_mark_set = 1;
2834 else if (*pPointer != RPC_FC_RP)
2835 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2837 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
2838 if (pointer_buffer_mark_set)
2840 STD_OVERFLOW_CHECK(pStubMsg);
2841 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2842 pStubMsg->Buffer = saved_buffer;
2843 if (*pPointer != RPC_FC_RP)
2844 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2850 case RPC_FC_ALIGNM4:
2851 ALIGN_POINTER_CLEAR(pMemory, 4);
2853 case RPC_FC_ALIGNM8:
2854 ALIGN_POINTER_CLEAR(pMemory, 8);
2856 case RPC_FC_STRUCTPAD1:
2857 case RPC_FC_STRUCTPAD2:
2858 case RPC_FC_STRUCTPAD3:
2859 case RPC_FC_STRUCTPAD4:
2860 case RPC_FC_STRUCTPAD5:
2861 case RPC_FC_STRUCTPAD6:
2862 case RPC_FC_STRUCTPAD7:
2863 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2864 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2866 case RPC_FC_EMBEDDED_COMPLEX:
2867 pMemory += pFormat[1];
2869 desc = pFormat + *(const SHORT*)pFormat;
2870 size = EmbeddedComplexSize(pStubMsg, desc);
2871 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2873 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
2874 * since the type is part of the memory block that is encompassed by
2875 * the whole complex type. Memory is forced to allocate when pointers
2876 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
2877 * clearing the memory we pass in to the unmarshaller */
2878 memset(pMemory, 0, size);
2879 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2882 /* for some reason interface pointers aren't generated as
2883 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2884 * they still need the derefencing treatment that pointers are
2886 if (*desc == RPC_FC_IP)
2887 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2889 m(pStubMsg, &pMemory, desc, FALSE);
2891 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2898 FIXME("unhandled format %d\n", *pFormat);
2906 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2907 unsigned char *pMemory,
2908 PFORMAT_STRING pFormat,
2909 PFORMAT_STRING pPointer)
2911 PFORMAT_STRING desc;
2915 while (*pFormat != RPC_FC_END) {
2921 safe_buffer_length_increment(pStubMsg, 1);
2927 safe_buffer_length_increment(pStubMsg, 2);
2931 safe_buffer_length_increment(pStubMsg, 2);
2937 safe_buffer_length_increment(pStubMsg, 4);
2941 safe_buffer_length_increment(pStubMsg, 8);
2944 case RPC_FC_POINTER:
2945 if (!pStubMsg->IgnoreEmbeddedPointers)
2947 int saved_buffer_length = pStubMsg->BufferLength;
2948 pStubMsg->BufferLength = pStubMsg->PointerLength;
2949 pStubMsg->PointerLength = 0;
2950 if(!pStubMsg->BufferLength)
2951 ERR("BufferLength == 0??\n");
2952 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2953 pStubMsg->PointerLength = pStubMsg->BufferLength;
2954 pStubMsg->BufferLength = saved_buffer_length;
2956 if (*pPointer != RPC_FC_RP)
2958 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2959 safe_buffer_length_increment(pStubMsg, 4);
2964 case RPC_FC_ALIGNM4:
2965 ALIGN_POINTER(pMemory, 4);
2967 case RPC_FC_ALIGNM8:
2968 ALIGN_POINTER(pMemory, 8);
2970 case RPC_FC_STRUCTPAD1:
2971 case RPC_FC_STRUCTPAD2:
2972 case RPC_FC_STRUCTPAD3:
2973 case RPC_FC_STRUCTPAD4:
2974 case RPC_FC_STRUCTPAD5:
2975 case RPC_FC_STRUCTPAD6:
2976 case RPC_FC_STRUCTPAD7:
2977 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2979 case RPC_FC_EMBEDDED_COMPLEX:
2980 pMemory += pFormat[1];
2982 desc = pFormat + *(const SHORT*)pFormat;
2983 size = EmbeddedComplexSize(pStubMsg, desc);
2984 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2987 /* for some reason interface pointers aren't generated as
2988 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2989 * they still need the derefencing treatment that pointers are
2991 if (*desc == RPC_FC_IP)
2992 m(pStubMsg, *(unsigned char **)pMemory, desc);
2994 m(pStubMsg, pMemory, desc);
2996 else FIXME("no buffersizer for embedded type %02x\n", *desc);
3003 FIXME("unhandled format 0x%02x\n", *pFormat);
3011 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
3012 unsigned char *pMemory,
3013 PFORMAT_STRING pFormat,
3014 PFORMAT_STRING pPointer)
3016 PFORMAT_STRING desc;
3020 while (*pFormat != RPC_FC_END) {
3042 case RPC_FC_POINTER:
3043 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3047 case RPC_FC_ALIGNM4:
3048 ALIGN_POINTER(pMemory, 4);
3050 case RPC_FC_ALIGNM8:
3051 ALIGN_POINTER(pMemory, 8);
3053 case RPC_FC_STRUCTPAD1:
3054 case RPC_FC_STRUCTPAD2:
3055 case RPC_FC_STRUCTPAD3:
3056 case RPC_FC_STRUCTPAD4:
3057 case RPC_FC_STRUCTPAD5:
3058 case RPC_FC_STRUCTPAD6:
3059 case RPC_FC_STRUCTPAD7:
3060 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3062 case RPC_FC_EMBEDDED_COMPLEX:
3063 pMemory += pFormat[1];
3065 desc = pFormat + *(const SHORT*)pFormat;
3066 size = EmbeddedComplexSize(pStubMsg, desc);
3067 m = NdrFreer[*desc & NDR_TABLE_MASK];
3070 /* for some reason interface pointers aren't generated as
3071 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3072 * they still need the derefencing treatment that pointers are
3074 if (*desc == RPC_FC_IP)
3075 m(pStubMsg, *(unsigned char **)pMemory, desc);
3077 m(pStubMsg, pMemory, desc);
3085 FIXME("unhandled format 0x%02x\n", *pFormat);
3093 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3094 PFORMAT_STRING pFormat,
3095 PFORMAT_STRING pPointer)
3097 PFORMAT_STRING desc;
3098 unsigned long size = 0;
3100 while (*pFormat != RPC_FC_END) {
3107 safe_buffer_increment(pStubMsg, 1);
3113 safe_buffer_increment(pStubMsg, 2);
3117 safe_buffer_increment(pStubMsg, 2);
3123 safe_buffer_increment(pStubMsg, 4);
3127 safe_buffer_increment(pStubMsg, 8);
3129 case RPC_FC_POINTER:
3131 unsigned char *saved_buffer;
3132 int pointer_buffer_mark_set = 0;
3133 if (*pPointer != RPC_FC_RP)
3134 ALIGN_POINTER(pStubMsg->Buffer, 4);
3135 saved_buffer = pStubMsg->Buffer;
3136 if (pStubMsg->PointerBufferMark)
3138 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3139 pStubMsg->PointerBufferMark = NULL;
3140 pointer_buffer_mark_set = 1;
3142 else if (*pPointer != RPC_FC_RP)
3143 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3145 if (!pStubMsg->IgnoreEmbeddedPointers)
3146 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3147 if (pointer_buffer_mark_set)
3149 STD_OVERFLOW_CHECK(pStubMsg);
3150 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3151 pStubMsg->Buffer = saved_buffer;
3152 if (*pPointer != RPC_FC_RP)
3153 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3159 case RPC_FC_ALIGNM4:
3160 ALIGN_LENGTH(size, 4);
3162 case RPC_FC_ALIGNM8:
3163 ALIGN_LENGTH(size, 8);
3165 case RPC_FC_STRUCTPAD1:
3166 case RPC_FC_STRUCTPAD2:
3167 case RPC_FC_STRUCTPAD3:
3168 case RPC_FC_STRUCTPAD4:
3169 case RPC_FC_STRUCTPAD5:
3170 case RPC_FC_STRUCTPAD6:
3171 case RPC_FC_STRUCTPAD7:
3172 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3174 case RPC_FC_EMBEDDED_COMPLEX:
3177 desc = pFormat + *(const SHORT*)pFormat;
3178 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3184 FIXME("unhandled format 0x%02x\n", *pFormat);
3192 unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg,
3193 PFORMAT_STRING pFormat)
3195 PFORMAT_STRING desc;
3196 unsigned long size = 0;
3198 while (*pFormat != RPC_FC_END) {
3220 case RPC_FC_POINTER:
3221 size += sizeof(void *);
3223 case RPC_FC_ALIGNM4:
3224 ALIGN_LENGTH(size, 4);
3226 case RPC_FC_ALIGNM8:
3227 ALIGN_LENGTH(size, 8);
3229 case RPC_FC_STRUCTPAD1:
3230 case RPC_FC_STRUCTPAD2:
3231 case RPC_FC_STRUCTPAD3:
3232 case RPC_FC_STRUCTPAD4:
3233 case RPC_FC_STRUCTPAD5:
3234 case RPC_FC_STRUCTPAD6:
3235 case RPC_FC_STRUCTPAD7:
3236 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3238 case RPC_FC_EMBEDDED_COMPLEX:
3241 desc = pFormat + *(const SHORT*)pFormat;
3242 size += EmbeddedComplexSize(pStubMsg, desc);
3248 FIXME("unhandled format 0x%02x\n", *pFormat);
3256 /***********************************************************************
3257 * NdrComplexStructMarshall [RPCRT4.@]
3259 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3260 unsigned char *pMemory,
3261 PFORMAT_STRING pFormat)
3263 PFORMAT_STRING conf_array = NULL;
3264 PFORMAT_STRING pointer_desc = NULL;
3265 unsigned char *OldMemory = pStubMsg->Memory;
3266 int pointer_buffer_mark_set = 0;
3268 ULONG max_count = 0;
3271 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3273 if (!pStubMsg->PointerBufferMark)
3275 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3276 /* save buffer length */
3277 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3279 /* get the buffer pointer after complex array data, but before
3281 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3282 pStubMsg->IgnoreEmbeddedPointers = 1;
3283 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3284 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3286 /* save it for use by embedded pointer code later */
3287 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3288 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
3289 pointer_buffer_mark_set = 1;
3291 /* restore the original buffer length */
3292 pStubMsg->BufferLength = saved_buffer_length;
3295 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
3298 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3300 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3303 pStubMsg->Memory = pMemory;
3307 unsigned long struct_size = ComplexStructSize(pStubMsg, pFormat);
3308 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3309 pMemory + struct_size, conf_array);
3310 /* these could be changed in ComplexMarshall so save them for later */
3311 max_count = pStubMsg->MaxCount;
3312 count = pStubMsg->ActualCount;
3313 offset = pStubMsg->Offset;
3316 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3320 pStubMsg->MaxCount = max_count;
3321 pStubMsg->ActualCount = count;
3322 pStubMsg->Offset = offset;
3323 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3324 conf_array, TRUE /* fHasPointers */);
3327 pStubMsg->Memory = OldMemory;
3329 if (pointer_buffer_mark_set)
3331 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3332 pStubMsg->PointerBufferMark = NULL;
3335 STD_OVERFLOW_CHECK(pStubMsg);
3340 /***********************************************************************
3341 * NdrComplexStructUnmarshall [RPCRT4.@]
3343 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3344 unsigned char **ppMemory,
3345 PFORMAT_STRING pFormat,
3346 unsigned char fMustAlloc)
3348 unsigned size = *(const WORD*)(pFormat+2);
3349 PFORMAT_STRING conf_array = NULL;
3350 PFORMAT_STRING pointer_desc = NULL;
3351 unsigned char *pMemory;
3352 int pointer_buffer_mark_set = 0;
3354 ULONG max_count = 0;
3356 ULONG array_size = 0;
3358 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3360 if (!pStubMsg->PointerBufferMark)
3362 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3363 /* save buffer pointer */
3364 unsigned char *saved_buffer = pStubMsg->Buffer;
3366 /* get the buffer pointer after complex array data, but before
3368 pStubMsg->IgnoreEmbeddedPointers = 1;
3369 NdrComplexStructMemorySize(pStubMsg, pFormat);
3370 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3372 /* save it for use by embedded pointer code later */
3373 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3374 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
3375 pointer_buffer_mark_set = 1;
3377 /* restore the original buffer */
3378 pStubMsg->Buffer = saved_buffer;
3381 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3384 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3386 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3391 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3394 /* these could be changed in ComplexMarshall so save them for later */
3395 max_count = pStubMsg->MaxCount;
3396 count = pStubMsg->ActualCount;
3397 offset = pStubMsg->Offset;
3400 if (!fMustAlloc && !*ppMemory)
3403 *ppMemory = NdrAllocate(pStubMsg, size);
3405 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3409 pStubMsg->MaxCount = max_count;
3410 pStubMsg->ActualCount = count;
3411 pStubMsg->Offset = offset;
3413 memset(pMemory, 0, array_size);
3414 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3416 FALSE /* fUseBufferMemoryServer */,
3417 TRUE /* fUnmarshall */);
3420 if (pointer_buffer_mark_set)
3422 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3423 pStubMsg->PointerBufferMark = NULL;
3429 /***********************************************************************
3430 * NdrComplexStructBufferSize [RPCRT4.@]
3432 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3433 unsigned char *pMemory,
3434 PFORMAT_STRING pFormat)
3436 PFORMAT_STRING conf_array = NULL;
3437 PFORMAT_STRING pointer_desc = NULL;
3438 unsigned char *OldMemory = pStubMsg->Memory;
3439 int pointer_length_set = 0;
3441 ULONG max_count = 0;
3444 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3446 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
3448 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3450 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3451 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3453 /* get the buffer length after complex struct data, but before
3455 pStubMsg->IgnoreEmbeddedPointers = 1;
3456 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3457 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3459 /* save it for use by embedded pointer code later */
3460 pStubMsg->PointerLength = pStubMsg->BufferLength;
3461 pointer_length_set = 1;
3462 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
3464 /* restore the original buffer length */
3465 pStubMsg->BufferLength = saved_buffer_length;
3469 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3471 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3474 pStubMsg->Memory = pMemory;
3478 unsigned long struct_size = ComplexStructSize(pStubMsg, pFormat);
3479 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3482 /* these could be changed in ComplexMarshall so save them for later */
3483 max_count = pStubMsg->MaxCount;
3484 count = pStubMsg->ActualCount;
3485 offset = pStubMsg->Offset;
3488 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3492 pStubMsg->MaxCount = max_count;
3493 pStubMsg->ActualCount = count;
3494 pStubMsg->Offset = offset;
3495 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3496 TRUE /* fHasPointers */);
3499 pStubMsg->Memory = OldMemory;
3501 if(pointer_length_set)
3503 pStubMsg->BufferLength = pStubMsg->PointerLength;
3504 pStubMsg->PointerLength = 0;
3509 /***********************************************************************
3510 * NdrComplexStructMemorySize [RPCRT4.@]
3512 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3513 PFORMAT_STRING pFormat)
3515 unsigned size = *(const WORD*)(pFormat+2);
3516 PFORMAT_STRING conf_array = NULL;
3517 PFORMAT_STRING pointer_desc = NULL;
3519 ULONG max_count = 0;
3522 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3524 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3527 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3529 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3534 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3536 /* these could be changed in ComplexStructMemorySize so save them for
3538 max_count = pStubMsg->MaxCount;
3539 count = pStubMsg->ActualCount;
3540 offset = pStubMsg->Offset;
3543 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3547 pStubMsg->MaxCount = max_count;
3548 pStubMsg->ActualCount = count;
3549 pStubMsg->Offset = offset;
3550 array_memory_size(conf_array[0], pStubMsg, conf_array,
3551 TRUE /* fHasPointers */);
3557 /***********************************************************************
3558 * NdrComplexStructFree [RPCRT4.@]
3560 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3561 unsigned char *pMemory,
3562 PFORMAT_STRING pFormat)
3564 PFORMAT_STRING conf_array = NULL;
3565 PFORMAT_STRING pointer_desc = NULL;
3566 unsigned char *OldMemory = pStubMsg->Memory;
3568 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3571 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3573 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3576 pStubMsg->Memory = pMemory;
3578 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3581 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3582 TRUE /* fHasPointers */);
3584 pStubMsg->Memory = OldMemory;
3587 /***********************************************************************
3588 * NdrConformantArrayMarshall [RPCRT4.@]
3590 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3591 unsigned char *pMemory,
3592 PFORMAT_STRING pFormat)
3594 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3595 if (pFormat[0] != RPC_FC_CARRAY)
3597 ERR("invalid format = 0x%x\n", pFormat[0]);
3598 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3601 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory,
3603 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3604 TRUE /* fHasPointers */);
3609 /***********************************************************************
3610 * NdrConformantArrayUnmarshall [RPCRT4.@]
3612 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3613 unsigned char **ppMemory,
3614 PFORMAT_STRING pFormat,
3615 unsigned char fMustAlloc)
3617 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3618 if (pFormat[0] != RPC_FC_CARRAY)
3620 ERR("invalid format = 0x%x\n", pFormat[0]);
3621 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3624 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3625 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat,
3627 TRUE /* fUseBufferMemoryServer */,
3628 TRUE /* fUnmarshall */);
3633 /***********************************************************************
3634 * NdrConformantArrayBufferSize [RPCRT4.@]
3636 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3637 unsigned char *pMemory,
3638 PFORMAT_STRING pFormat)
3640 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3641 if (pFormat[0] != RPC_FC_CARRAY)
3643 ERR("invalid format = 0x%x\n", pFormat[0]);
3644 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3647 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat);
3648 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3649 TRUE /* fHasPointers */);
3652 /***********************************************************************
3653 * NdrConformantArrayMemorySize [RPCRT4.@]
3655 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3656 PFORMAT_STRING pFormat)
3658 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3659 if (pFormat[0] != RPC_FC_CARRAY)
3661 ERR("invalid format = 0x%x\n", pFormat[0]);
3662 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3665 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3666 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
3668 return pStubMsg->MemorySize;
3671 /***********************************************************************
3672 * NdrConformantArrayFree [RPCRT4.@]
3674 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3675 unsigned char *pMemory,
3676 PFORMAT_STRING pFormat)
3678 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3679 if (pFormat[0] != RPC_FC_CARRAY)
3681 ERR("invalid format = 0x%x\n", pFormat[0]);
3682 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3685 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3686 TRUE /* fHasPointers */);
3690 /***********************************************************************
3691 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3693 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
3694 unsigned char* pMemory,
3695 PFORMAT_STRING pFormat )
3697 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3699 if (pFormat[0] != RPC_FC_CVARRAY)
3701 ERR("invalid format type %x\n", pFormat[0]);
3702 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3706 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3708 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory,
3709 pFormat, TRUE /* fHasPointers */);
3715 /***********************************************************************
3716 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3718 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
3719 unsigned char** ppMemory,
3720 PFORMAT_STRING pFormat,
3721 unsigned char fMustAlloc )
3723 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3725 if (pFormat[0] != RPC_FC_CVARRAY)
3727 ERR("invalid format type %x\n", pFormat[0]);
3728 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3732 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3733 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory,
3734 pFormat, fMustAlloc,
3735 TRUE /* fUseBufferMemoryServer */,
3736 TRUE /* fUnmarshall */);
3742 /***********************************************************************
3743 * NdrConformantVaryingArrayFree [RPCRT4.@]
3745 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
3746 unsigned char* pMemory,
3747 PFORMAT_STRING pFormat )
3749 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3751 if (pFormat[0] != RPC_FC_CVARRAY)
3753 ERR("invalid format type %x\n", pFormat[0]);
3754 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3758 array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3759 TRUE /* fHasPointers */);
3763 /***********************************************************************
3764 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3766 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
3767 unsigned char* pMemory, PFORMAT_STRING pFormat )
3769 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3771 if (pFormat[0] != RPC_FC_CVARRAY)
3773 ERR("invalid format type %x\n", pFormat[0]);
3774 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3778 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3780 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3781 TRUE /* fHasPointers */);
3785 /***********************************************************************
3786 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3788 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
3789 PFORMAT_STRING pFormat )
3791 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3793 if (pFormat[0] != RPC_FC_CVARRAY)
3795 ERR("invalid format type %x\n", pFormat[0]);
3796 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3797 return pStubMsg->MemorySize;
3800 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3801 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat,
3802 TRUE /* fHasPointers */);
3804 return pStubMsg->MemorySize;
3808 /***********************************************************************
3809 * NdrComplexArrayMarshall [RPCRT4.@]
3811 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3812 unsigned char *pMemory,
3813 PFORMAT_STRING pFormat)
3815 ULONG i, count, def;
3816 BOOL variance_present;
3817 unsigned char alignment;
3818 int pointer_buffer_mark_set = 0;
3820 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3822 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3824 ERR("invalid format type %x\n", pFormat[0]);
3825 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3829 alignment = pFormat[1] + 1;
3831 if (!pStubMsg->PointerBufferMark)
3833 /* save buffer fields that may be changed by buffer sizer functions
3834 * and that may be needed later on */
3835 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3836 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3837 unsigned long saved_max_count = pStubMsg->MaxCount;
3838 unsigned long saved_offset = pStubMsg->Offset;
3839 unsigned long saved_actual_count = pStubMsg->ActualCount;
3841 /* get the buffer pointer after complex array data, but before
3843 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3844 pStubMsg->IgnoreEmbeddedPointers = 1;
3845 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3846 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3848 /* save it for use by embedded pointer code later */
3849 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3850 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
3851 pointer_buffer_mark_set = 1;
3853 /* restore fields */
3854 pStubMsg->ActualCount = saved_actual_count;
3855 pStubMsg->Offset = saved_offset;
3856 pStubMsg->MaxCount = saved_max_count;
3857 pStubMsg->BufferLength = saved_buffer_length;
3860 def = *(const WORD*)&pFormat[2];
3863 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3864 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3866 variance_present = IsConformanceOrVariancePresent(pFormat);
3867 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3868 TRACE("variance = %d\n", pStubMsg->ActualCount);
3870 WriteConformance(pStubMsg);
3871 if (variance_present)
3872 WriteVariance(pStubMsg);
3874 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3876 count = pStubMsg->ActualCount;
3877 for (i = 0; i < count; i++)
3878 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3880 STD_OVERFLOW_CHECK(pStubMsg);
3882 if (pointer_buffer_mark_set)
3884 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3885 pStubMsg->PointerBufferMark = NULL;
3891 /***********************************************************************
3892 * NdrComplexArrayUnmarshall [RPCRT4.@]
3894 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3895 unsigned char **ppMemory,
3896 PFORMAT_STRING pFormat,
3897 unsigned char fMustAlloc)
3899 ULONG i, count, size;
3900 unsigned char alignment;
3901 unsigned char *pMemory;
3902 unsigned char *saved_buffer;
3903 int pointer_buffer_mark_set = 0;
3904 int saved_ignore_embedded;
3906 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3908 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3910 ERR("invalid format type %x\n", pFormat[0]);
3911 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3915 alignment = pFormat[1] + 1;
3917 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3918 /* save buffer pointer */
3919 saved_buffer = pStubMsg->Buffer;
3920 /* get the buffer pointer after complex array data, but before
3922 pStubMsg->IgnoreEmbeddedPointers = 1;
3923 pStubMsg->MemorySize = 0;
3924 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3925 size = pStubMsg->MemorySize;
3926 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3928 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
3929 if (!pStubMsg->PointerBufferMark)
3931 /* save it for use by embedded pointer code later */
3932 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3933 pointer_buffer_mark_set = 1;
3935 /* restore the original buffer */
3936 pStubMsg->Buffer = saved_buffer;
3940 pFormat = ReadConformance(pStubMsg, pFormat);
3941 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3943 if (!fMustAlloc && !*ppMemory)
3946 *ppMemory = NdrAllocate(pStubMsg, size);
3948 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3950 pMemory = *ppMemory;
3951 count = pStubMsg->ActualCount;
3952 for (i = 0; i < count; i++)
3953 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
3955 if (pointer_buffer_mark_set)
3957 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3958 pStubMsg->PointerBufferMark = NULL;
3964 /***********************************************************************
3965 * NdrComplexArrayBufferSize [RPCRT4.@]
3967 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3968 unsigned char *pMemory,
3969 PFORMAT_STRING pFormat)
3971 ULONG i, count, def;
3972 unsigned char alignment;
3973 BOOL variance_present;
3974 int pointer_length_set = 0;
3976 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3978 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3980 ERR("invalid format type %x\n", pFormat[0]);
3981 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3985 alignment = pFormat[1] + 1;
3987 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3989 /* save buffer fields that may be changed by buffer sizer functions
3990 * and that may be needed later on */
3991 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3992 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3993 unsigned long saved_max_count = pStubMsg->MaxCount;
3994 unsigned long saved_offset = pStubMsg->Offset;
3995 unsigned long saved_actual_count = pStubMsg->ActualCount;
3997 /* get the buffer pointer after complex array data, but before
3999 pStubMsg->IgnoreEmbeddedPointers = 1;
4000 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4001 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4003 /* save it for use by embedded pointer code later */
4004 pStubMsg->PointerLength = pStubMsg->BufferLength;
4005 pointer_length_set = 1;
4007 /* restore fields */
4008 pStubMsg->ActualCount = saved_actual_count;
4009 pStubMsg->Offset = saved_offset;
4010 pStubMsg->MaxCount = saved_max_count;
4011 pStubMsg->BufferLength = saved_buffer_length;
4013 def = *(const WORD*)&pFormat[2];
4016 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4017 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4018 SizeConformance(pStubMsg);
4020 variance_present = IsConformanceOrVariancePresent(pFormat);
4021 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4022 TRACE("variance = %d\n", pStubMsg->ActualCount);
4024 if (variance_present)
4025 SizeVariance(pStubMsg);
4027 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4029 count = pStubMsg->ActualCount;
4030 for (i = 0; i < count; i++)
4031 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
4033 if(pointer_length_set)
4035 pStubMsg->BufferLength = pStubMsg->PointerLength;
4036 pStubMsg->PointerLength = 0;
4040 /***********************************************************************
4041 * NdrComplexArrayMemorySize [RPCRT4.@]
4043 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4044 PFORMAT_STRING pFormat)
4046 ULONG i, count, esize, SavedMemorySize, MemorySize;
4047 unsigned char alignment;
4049 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4051 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4053 ERR("invalid format type %x\n", pFormat[0]);
4054 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4058 alignment = pFormat[1] + 1;
4062 pFormat = ReadConformance(pStubMsg, pFormat);
4063 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
4065 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4067 SavedMemorySize = pStubMsg->MemorySize;
4069 esize = ComplexStructSize(pStubMsg, pFormat);
4071 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
4073 count = pStubMsg->ActualCount;
4074 for (i = 0; i < count; i++)
4075 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
4077 pStubMsg->MemorySize = SavedMemorySize;
4079 pStubMsg->MemorySize += MemorySize;
4083 /***********************************************************************
4084 * NdrComplexArrayFree [RPCRT4.@]
4086 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4087 unsigned char *pMemory,
4088 PFORMAT_STRING pFormat)
4090 ULONG i, count, def;
4092 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4094 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4096 ERR("invalid format type %x\n", pFormat[0]);
4097 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4101 def = *(const WORD*)&pFormat[2];
4104 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4105 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4107 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4108 TRACE("variance = %d\n", pStubMsg->ActualCount);
4110 count = pStubMsg->ActualCount;
4111 for (i = 0; i < count; i++)
4112 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4115 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4116 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4117 USER_MARSHAL_CB *umcb)
4119 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4120 pStubMsg->RpcMsg->DataRepresentation);
4121 umcb->pStubMsg = pStubMsg;
4122 umcb->pReserve = NULL;
4123 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4124 umcb->CBType = cbtype;
4125 umcb->pFormat = pFormat;
4126 umcb->pTypeFormat = NULL /* FIXME */;
4129 #define USER_MARSHAL_PTR_PREFIX \
4130 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4131 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4133 /***********************************************************************
4134 * NdrUserMarshalMarshall [RPCRT4.@]
4136 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4137 unsigned char *pMemory,
4138 PFORMAT_STRING pFormat)
4140 unsigned flags = pFormat[1];
4141 unsigned index = *(const WORD*)&pFormat[2];
4142 unsigned char *saved_buffer = NULL;
4143 USER_MARSHAL_CB umcb;
4145 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4146 TRACE("index=%d\n", index);
4148 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4150 if (flags & USER_MARSHAL_POINTER)
4152 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
4153 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4154 pStubMsg->Buffer += 4;
4155 if (pStubMsg->PointerBufferMark)
4157 saved_buffer = pStubMsg->Buffer;
4158 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4159 pStubMsg->PointerBufferMark = NULL;
4161 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
4164 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
4167 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4168 &umcb.Flags, pStubMsg->Buffer, pMemory);
4172 STD_OVERFLOW_CHECK(pStubMsg);
4173 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4174 pStubMsg->Buffer = saved_buffer;
4177 STD_OVERFLOW_CHECK(pStubMsg);
4182 /***********************************************************************
4183 * NdrUserMarshalUnmarshall [RPCRT4.@]
4185 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4186 unsigned char **ppMemory,
4187 PFORMAT_STRING pFormat,
4188 unsigned char fMustAlloc)
4190 unsigned flags = pFormat[1];
4191 unsigned index = *(const WORD*)&pFormat[2];
4192 DWORD memsize = *(const WORD*)&pFormat[4];
4193 unsigned char *saved_buffer = NULL;
4194 USER_MARSHAL_CB umcb;
4196 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4197 TRACE("index=%d\n", index);
4199 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4201 if (flags & USER_MARSHAL_POINTER)
4203 ALIGN_POINTER(pStubMsg->Buffer, 4);
4204 /* skip pointer prefix */
4205 pStubMsg->Buffer += 4;
4206 if (pStubMsg->PointerBufferMark)
4208 saved_buffer = pStubMsg->Buffer;
4209 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4210 pStubMsg->PointerBufferMark = NULL;
4212 ALIGN_POINTER(pStubMsg->Buffer, 8);
4215 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4217 if (!fMustAlloc && !*ppMemory)
4221 *ppMemory = NdrAllocate(pStubMsg, memsize);
4222 memset(*ppMemory, 0, memsize);
4226 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4227 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4231 STD_OVERFLOW_CHECK(pStubMsg);
4232 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4233 pStubMsg->Buffer = saved_buffer;
4239 /***********************************************************************
4240 * NdrUserMarshalBufferSize [RPCRT4.@]
4242 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4243 unsigned char *pMemory,
4244 PFORMAT_STRING pFormat)
4246 unsigned flags = pFormat[1];
4247 unsigned index = *(const WORD*)&pFormat[2];
4248 DWORD bufsize = *(const WORD*)&pFormat[6];
4249 USER_MARSHAL_CB umcb;
4250 unsigned long saved_buffer_length = 0;
4252 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4253 TRACE("index=%d\n", index);
4255 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4257 if (flags & USER_MARSHAL_POINTER)
4259 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4260 /* skip pointer prefix */
4261 safe_buffer_length_increment(pStubMsg, 4);
4262 if (pStubMsg->IgnoreEmbeddedPointers)
4264 if (pStubMsg->PointerLength)
4266 saved_buffer_length = pStubMsg->BufferLength;
4267 pStubMsg->BufferLength = pStubMsg->PointerLength;
4268 pStubMsg->PointerLength = 0;
4270 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
4273 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
4276 TRACE("size=%d\n", bufsize);
4277 safe_buffer_length_increment(pStubMsg, bufsize);
4280 pStubMsg->BufferLength =
4281 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4282 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4284 if (saved_buffer_length)
4286 pStubMsg->PointerLength = pStubMsg->BufferLength;
4287 pStubMsg->BufferLength = saved_buffer_length;
4292 /***********************************************************************
4293 * NdrUserMarshalMemorySize [RPCRT4.@]
4295 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4296 PFORMAT_STRING pFormat)
4298 unsigned flags = pFormat[1];
4299 unsigned index = *(const WORD*)&pFormat[2];
4300 DWORD memsize = *(const WORD*)&pFormat[4];
4301 DWORD bufsize = *(const WORD*)&pFormat[6];
4303 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4304 TRACE("index=%d\n", index);
4306 pStubMsg->MemorySize += memsize;
4308 if (flags & USER_MARSHAL_POINTER)
4310 ALIGN_POINTER(pStubMsg->Buffer, 4);
4311 /* skip pointer prefix */
4312 pStubMsg->Buffer += 4;
4313 if (pStubMsg->IgnoreEmbeddedPointers)
4314 return pStubMsg->MemorySize;
4315 ALIGN_POINTER(pStubMsg->Buffer, 8);
4318 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4321 FIXME("not implemented for varying buffer size\n");
4323 pStubMsg->Buffer += bufsize;
4325 return pStubMsg->MemorySize;
4328 /***********************************************************************
4329 * NdrUserMarshalFree [RPCRT4.@]
4331 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4332 unsigned char *pMemory,
4333 PFORMAT_STRING pFormat)
4335 /* unsigned flags = pFormat[1]; */
4336 unsigned index = *(const WORD*)&pFormat[2];
4337 USER_MARSHAL_CB umcb;
4339 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4340 TRACE("index=%d\n", index);
4342 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4344 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4345 &umcb.Flags, pMemory);
4348 /***********************************************************************
4349 * NdrGetUserMarshalInfo [RPCRT4.@]
4351 RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi)
4353 USER_MARSHAL_CB *umcb = CONTAINING_RECORD(flags, USER_MARSHAL_CB, Flags);
4355 TRACE("(%p,%u,%p)\n", flags, level, umi);
4358 return RPC_S_INVALID_ARG;
4360 memset(&umi->Level1, 0, sizeof(umi->Level1));
4361 umi->InformationLevel = level;
4363 if (umcb->Signature != USER_MARSHAL_CB_SIGNATURE)
4364 return RPC_S_INVALID_ARG;
4366 umi->Level1.pfnAllocate = umcb->pStubMsg->pfnAllocate;
4367 umi->Level1.pfnFree = umcb->pStubMsg->pfnFree;
4368 umi->Level1.pRpcChannelBuffer = umcb->pStubMsg->pRpcChannelBuffer;
4370 switch (umcb->CBType)
4372 case USER_MARSHAL_CB_MARSHALL:
4373 case USER_MARSHAL_CB_UNMARSHALL:
4375 RPC_MESSAGE *msg = umcb->pStubMsg->RpcMsg;
4376 unsigned char *buffer_start = msg->Buffer;
4377 unsigned char *buffer_end =
4378 (unsigned char *)msg->Buffer + msg->BufferLength;
4380 if (umcb->pStubMsg->Buffer < buffer_start ||
4381 umcb->pStubMsg->Buffer > buffer_end)
4382 return ERROR_INVALID_USER_BUFFER;
4384 umi->Level1.Buffer = umcb->pStubMsg->Buffer;
4385 umi->Level1.BufferSize = buffer_end - umcb->pStubMsg->Buffer;
4388 case USER_MARSHAL_CB_BUFFER_SIZE:
4389 case USER_MARSHAL_CB_FREE:
4392 WARN("unrecognised CBType %d\n", umcb->CBType);
4398 /***********************************************************************
4399 * NdrClearOutParameters [RPCRT4.@]
4401 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4402 PFORMAT_STRING pFormat,
4405 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4408 /***********************************************************************
4409 * NdrConvert [RPCRT4.@]
4411 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4413 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4414 /* FIXME: since this stub doesn't do any converting, the proper behavior
4415 is to raise an exception */
4418 /***********************************************************************
4419 * NdrConvert2 [RPCRT4.@]
4421 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4423 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4424 pStubMsg, pFormat, NumberParams);
4425 /* FIXME: since this stub doesn't do any converting, the proper behavior
4426 is to raise an exception */
4429 #include "pshpack1.h"
4430 typedef struct _NDR_CSTRUCT_FORMAT
4433 unsigned char alignment;
4434 unsigned short memory_size;
4435 short offset_to_array_description;
4436 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4437 #include "poppack.h"
4439 /***********************************************************************
4440 * NdrConformantStructMarshall [RPCRT4.@]
4442 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4443 unsigned char *pMemory,
4444 PFORMAT_STRING pFormat)
4446 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4447 PFORMAT_STRING pCArrayFormat;
4448 ULONG esize, bufsize;
4450 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4452 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4453 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4455 ERR("invalid format type %x\n", pCStructFormat->type);
4456 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4460 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4461 pCStructFormat->offset_to_array_description;
4462 if (*pCArrayFormat != RPC_FC_CARRAY)
4464 ERR("invalid array format type %x\n", pCStructFormat->type);
4465 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4468 esize = *(const WORD*)(pCArrayFormat+2);
4470 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4471 pCArrayFormat + 4, 0);
4473 WriteConformance(pStubMsg);
4475 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4477 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4479 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4480 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4482 ERR("integer overflow of memory_size %u with bufsize %u\n",
4483 pCStructFormat->memory_size, bufsize);
4484 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4486 /* copy constant sized part of struct */
4487 pStubMsg->BufferMark = pStubMsg->Buffer;
4488 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4490 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4491 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4496 /***********************************************************************
4497 * NdrConformantStructUnmarshall [RPCRT4.@]
4499 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4500 unsigned char **ppMemory,
4501 PFORMAT_STRING pFormat,
4502 unsigned char fMustAlloc)
4504 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4505 PFORMAT_STRING pCArrayFormat;
4506 ULONG esize, bufsize;
4507 unsigned char *saved_buffer;
4509 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4511 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4512 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4514 ERR("invalid format type %x\n", pCStructFormat->type);
4515 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4518 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4519 pCStructFormat->offset_to_array_description;
4520 if (*pCArrayFormat != RPC_FC_CARRAY)
4522 ERR("invalid array format type %x\n", pCStructFormat->type);
4523 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4526 esize = *(const WORD*)(pCArrayFormat+2);
4528 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4530 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4532 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4534 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4535 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4537 ERR("integer overflow of memory_size %u with bufsize %u\n",
4538 pCStructFormat->memory_size, bufsize);
4539 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4544 SIZE_T size = pCStructFormat->memory_size + bufsize;
4545 *ppMemory = NdrAllocate(pStubMsg, size);
4549 if (!pStubMsg->IsClient && !*ppMemory)
4550 /* for servers, we just point straight into the RPC buffer */
4551 *ppMemory = pStubMsg->Buffer;
4554 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4555 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4556 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4557 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4559 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4560 if (*ppMemory != saved_buffer)
4561 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4566 /***********************************************************************
4567 * NdrConformantStructBufferSize [RPCRT4.@]
4569 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4570 unsigned char *pMemory,
4571 PFORMAT_STRING pFormat)
4573 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4574 PFORMAT_STRING pCArrayFormat;
4577 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4579 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4580 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4582 ERR("invalid format type %x\n", pCStructFormat->type);
4583 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4586 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4587 pCStructFormat->offset_to_array_description;
4588 if (*pCArrayFormat != RPC_FC_CARRAY)
4590 ERR("invalid array format type %x\n", pCStructFormat->type);
4591 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4594 esize = *(const WORD*)(pCArrayFormat+2);
4596 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4597 SizeConformance(pStubMsg);
4599 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4601 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4603 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4604 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4606 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4607 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4610 /***********************************************************************
4611 * NdrConformantStructMemorySize [RPCRT4.@]
4613 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4614 PFORMAT_STRING pFormat)
4620 /***********************************************************************
4621 * NdrConformantStructFree [RPCRT4.@]
4623 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4624 unsigned char *pMemory,
4625 PFORMAT_STRING pFormat)
4627 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4628 PFORMAT_STRING pCArrayFormat;
4630 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4632 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4633 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4635 ERR("invalid format type %x\n", pCStructFormat->type);
4636 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4640 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4641 pCStructFormat->offset_to_array_description;
4642 if (*pCArrayFormat != RPC_FC_CARRAY)
4644 ERR("invalid array format type %x\n", pCStructFormat->type);
4645 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4649 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4650 pCArrayFormat + 4, 0);
4652 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4654 /* copy constant sized part of struct */
4655 pStubMsg->BufferMark = pStubMsg->Buffer;
4657 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4658 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4661 /***********************************************************************
4662 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4664 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4665 unsigned char *pMemory,
4666 PFORMAT_STRING pFormat)
4668 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4669 PFORMAT_STRING pCVArrayFormat;
4671 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4673 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4674 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4676 ERR("invalid format type %x\n", pCVStructFormat->type);
4677 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4681 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4682 pCVStructFormat->offset_to_array_description;
4684 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4685 pMemory + pCVStructFormat->memory_size,
4688 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4690 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4692 /* write constant sized part */
4693 pStubMsg->BufferMark = pStubMsg->Buffer;
4694 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4696 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4697 pMemory + pCVStructFormat->memory_size,
4698 pCVArrayFormat, FALSE /* fHasPointers */);
4700 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4705 /***********************************************************************
4706 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4708 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4709 unsigned char **ppMemory,
4710 PFORMAT_STRING pFormat,
4711 unsigned char fMustAlloc)
4713 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4714 PFORMAT_STRING pCVArrayFormat;
4715 ULONG memsize, bufsize;
4716 unsigned char *saved_buffer, *saved_array_buffer;
4718 unsigned char *array_memory;
4720 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4722 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4723 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4725 ERR("invalid format type %x\n", pCVStructFormat->type);
4726 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4730 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4731 pCVStructFormat->offset_to_array_description;
4733 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4736 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4738 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4740 /* work out how much memory to allocate if we need to do so */
4741 if (!fMustAlloc && !*ppMemory)
4745 SIZE_T size = pCVStructFormat->memory_size + memsize;
4746 *ppMemory = NdrAllocate(pStubMsg, size);
4749 /* mark the start of the constant data */
4750 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4751 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4753 array_memory = *ppMemory + pCVStructFormat->memory_size;
4754 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
4755 &array_memory, pCVArrayFormat,
4756 FALSE /* fMustAlloc */,
4757 FALSE /* fUseServerBufferMemory */,
4758 FALSE /* fUnmarshall */);
4760 /* save offset in case unmarshalling pointers changes it */
4761 offset = pStubMsg->Offset;
4763 /* mark the start of the array data */
4764 saved_array_buffer = pStubMsg->Buffer;
4765 safe_buffer_increment(pStubMsg, bufsize);
4767 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4769 /* copy the constant data */
4770 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
4771 /* copy the array data */
4772 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
4773 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
4774 saved_array_buffer, bufsize);
4776 if (*pCVArrayFormat == RPC_FC_C_CSTRING)
4777 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
4778 else if (*pCVArrayFormat == RPC_FC_C_WSTRING)
4779 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
4784 /***********************************************************************
4785 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4787 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4788 unsigned char *pMemory,
4789 PFORMAT_STRING pFormat)
4791 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4792 PFORMAT_STRING pCVArrayFormat;
4794 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4796 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4797 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4799 ERR("invalid format type %x\n", pCVStructFormat->type);
4800 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4804 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4805 pCVStructFormat->offset_to_array_description;
4806 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
4807 pMemory + pCVStructFormat->memory_size,
4810 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4812 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4814 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4816 array_buffer_size(*pCVArrayFormat, pStubMsg,
4817 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4818 FALSE /* fHasPointers */);
4820 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4823 /***********************************************************************
4824 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4826 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4827 PFORMAT_STRING pFormat)
4829 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4830 PFORMAT_STRING pCVArrayFormat;
4832 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4834 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4835 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4837 ERR("invalid format type %x\n", pCVStructFormat->type);
4838 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4842 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4843 pCVStructFormat->offset_to_array_description;
4844 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
4846 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4848 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4850 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4851 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
4852 FALSE /* fHasPointers */);
4854 pStubMsg->MemorySize += pCVStructFormat->memory_size;
4856 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4858 return pStubMsg->MemorySize;
4861 /***********************************************************************
4862 * NdrConformantVaryingStructFree [RPCRT4.@]
4864 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4865 unsigned char *pMemory,
4866 PFORMAT_STRING pFormat)
4868 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4869 PFORMAT_STRING pCVArrayFormat;
4871 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4873 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4874 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4876 ERR("invalid format type %x\n", pCVStructFormat->type);
4877 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4881 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4882 pCVStructFormat->offset_to_array_description;
4883 array_free(*pCVArrayFormat, pStubMsg,
4884 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4885 FALSE /* fHasPointers */);
4887 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4889 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4892 #include "pshpack1.h"
4896 unsigned char alignment;
4897 unsigned short total_size;
4898 } NDR_SMFARRAY_FORMAT;
4903 unsigned char alignment;
4904 unsigned long total_size;
4905 } NDR_LGFARRAY_FORMAT;
4906 #include "poppack.h"
4908 /***********************************************************************
4909 * NdrFixedArrayMarshall [RPCRT4.@]
4911 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4912 unsigned char *pMemory,
4913 PFORMAT_STRING pFormat)
4915 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4916 unsigned long total_size;
4918 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4920 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4921 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4923 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4924 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4928 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4930 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4932 total_size = pSmFArrayFormat->total_size;
4933 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4937 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4938 total_size = pLgFArrayFormat->total_size;
4939 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4942 pStubMsg->BufferMark = pStubMsg->Buffer;
4943 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4945 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4950 /***********************************************************************
4951 * NdrFixedArrayUnmarshall [RPCRT4.@]
4953 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4954 unsigned char **ppMemory,
4955 PFORMAT_STRING pFormat,
4956 unsigned char fMustAlloc)
4958 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4959 unsigned long total_size;
4960 unsigned char *saved_buffer;
4962 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4964 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4965 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4967 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4968 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4972 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4974 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4976 total_size = pSmFArrayFormat->total_size;
4977 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4981 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4982 total_size = pLgFArrayFormat->total_size;
4983 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4987 *ppMemory = NdrAllocate(pStubMsg, total_size);
4990 if (!pStubMsg->IsClient && !*ppMemory)
4991 /* for servers, we just point straight into the RPC buffer */
4992 *ppMemory = pStubMsg->Buffer;
4995 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4996 safe_buffer_increment(pStubMsg, total_size);
4997 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4999 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
5000 if (*ppMemory != saved_buffer)
5001 memcpy(*ppMemory, saved_buffer, total_size);
5006 /***********************************************************************
5007 * NdrFixedArrayBufferSize [RPCRT4.@]
5009 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5010 unsigned char *pMemory,
5011 PFORMAT_STRING pFormat)
5013 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5014 unsigned long total_size;
5016 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5018 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5019 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5021 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5022 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5026 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
5028 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5030 total_size = pSmFArrayFormat->total_size;
5031 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5035 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5036 total_size = pLgFArrayFormat->total_size;
5037 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5039 safe_buffer_length_increment(pStubMsg, total_size);
5041 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5044 /***********************************************************************
5045 * NdrFixedArrayMemorySize [RPCRT4.@]
5047 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5048 PFORMAT_STRING pFormat)
5050 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5053 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5055 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5056 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5058 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5059 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5063 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5065 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5067 total_size = pSmFArrayFormat->total_size;
5068 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5072 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5073 total_size = pLgFArrayFormat->total_size;
5074 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5076 pStubMsg->BufferMark = pStubMsg->Buffer;
5077 safe_buffer_increment(pStubMsg, total_size);
5078 pStubMsg->MemorySize += total_size;
5080 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5085 /***********************************************************************
5086 * NdrFixedArrayFree [RPCRT4.@]
5088 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5089 unsigned char *pMemory,
5090 PFORMAT_STRING pFormat)
5092 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5094 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5096 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5097 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5099 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5100 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5104 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5105 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5108 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5109 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5112 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5115 /***********************************************************************
5116 * NdrVaryingArrayMarshall [RPCRT4.@]
5118 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5119 unsigned char *pMemory,
5120 PFORMAT_STRING pFormat)
5122 unsigned char alignment;
5123 DWORD elements, esize;
5126 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5128 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5129 (pFormat[0] != RPC_FC_LGVARRAY))
5131 ERR("invalid format type %x\n", pFormat[0]);
5132 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5136 alignment = pFormat[1] + 1;
5138 if (pFormat[0] == RPC_FC_SMVARRAY)
5141 pFormat += sizeof(WORD);
5142 elements = *(const WORD*)pFormat;
5143 pFormat += sizeof(WORD);
5148 pFormat += sizeof(DWORD);
5149 elements = *(const DWORD*)pFormat;
5150 pFormat += sizeof(DWORD);
5153 esize = *(const WORD*)pFormat;
5154 pFormat += sizeof(WORD);
5156 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5157 if ((pStubMsg->ActualCount > elements) ||
5158 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5160 RpcRaiseException(RPC_S_INVALID_BOUND);
5164 WriteVariance(pStubMsg);
5166 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
5168 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5169 pStubMsg->BufferMark = pStubMsg->Buffer;
5170 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5172 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5177 /***********************************************************************
5178 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5180 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5181 unsigned char **ppMemory,
5182 PFORMAT_STRING pFormat,
5183 unsigned char fMustAlloc)
5185 unsigned char alignment;
5186 DWORD size, elements, esize;
5188 unsigned char *saved_buffer;
5191 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5193 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5194 (pFormat[0] != RPC_FC_LGVARRAY))
5196 ERR("invalid format type %x\n", pFormat[0]);
5197 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5201 alignment = pFormat[1] + 1;
5203 if (pFormat[0] == RPC_FC_SMVARRAY)
5206 size = *(const WORD*)pFormat;
5207 pFormat += sizeof(WORD);
5208 elements = *(const WORD*)pFormat;
5209 pFormat += sizeof(WORD);
5214 size = *(const DWORD*)pFormat;
5215 pFormat += sizeof(DWORD);
5216 elements = *(const DWORD*)pFormat;
5217 pFormat += sizeof(DWORD);
5220 esize = *(const WORD*)pFormat;
5221 pFormat += sizeof(WORD);
5223 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5225 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5227 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5228 offset = pStubMsg->Offset;
5230 if (!fMustAlloc && !*ppMemory)
5233 *ppMemory = NdrAllocate(pStubMsg, size);
5234 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5235 safe_buffer_increment(pStubMsg, bufsize);
5237 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5239 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5244 /***********************************************************************
5245 * NdrVaryingArrayBufferSize [RPCRT4.@]
5247 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5248 unsigned char *pMemory,
5249 PFORMAT_STRING pFormat)
5251 unsigned char alignment;
5252 DWORD elements, esize;
5254 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5256 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5257 (pFormat[0] != RPC_FC_LGVARRAY))
5259 ERR("invalid format type %x\n", pFormat[0]);
5260 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5264 alignment = pFormat[1] + 1;
5266 if (pFormat[0] == RPC_FC_SMVARRAY)
5269 pFormat += sizeof(WORD);
5270 elements = *(const WORD*)pFormat;
5271 pFormat += sizeof(WORD);
5276 pFormat += sizeof(DWORD);
5277 elements = *(const DWORD*)pFormat;
5278 pFormat += sizeof(DWORD);
5281 esize = *(const WORD*)pFormat;
5282 pFormat += sizeof(WORD);
5284 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5285 if ((pStubMsg->ActualCount > elements) ||
5286 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5288 RpcRaiseException(RPC_S_INVALID_BOUND);
5292 SizeVariance(pStubMsg);
5294 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
5296 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5298 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5301 /***********************************************************************
5302 * NdrVaryingArrayMemorySize [RPCRT4.@]
5304 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5305 PFORMAT_STRING pFormat)
5307 unsigned char alignment;
5308 DWORD size, elements, esize;
5310 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5312 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5313 (pFormat[0] != RPC_FC_LGVARRAY))
5315 ERR("invalid format type %x\n", pFormat[0]);
5316 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5320 alignment = pFormat[1] + 1;
5322 if (pFormat[0] == RPC_FC_SMVARRAY)
5325 size = *(const WORD*)pFormat;
5326 pFormat += sizeof(WORD);
5327 elements = *(const WORD*)pFormat;
5328 pFormat += sizeof(WORD);
5333 size = *(const DWORD*)pFormat;
5334 pFormat += sizeof(DWORD);
5335 elements = *(const DWORD*)pFormat;
5336 pFormat += sizeof(DWORD);
5339 esize = *(const WORD*)pFormat;
5340 pFormat += sizeof(WORD);
5342 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5344 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5346 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5347 pStubMsg->MemorySize += size;
5349 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5351 return pStubMsg->MemorySize;
5354 /***********************************************************************
5355 * NdrVaryingArrayFree [RPCRT4.@]
5357 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5358 unsigned char *pMemory,
5359 PFORMAT_STRING pFormat)
5363 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5365 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5366 (pFormat[0] != RPC_FC_LGVARRAY))
5368 ERR("invalid format type %x\n", pFormat[0]);
5369 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5373 if (pFormat[0] == RPC_FC_SMVARRAY)
5376 pFormat += sizeof(WORD);
5377 elements = *(const WORD*)pFormat;
5378 pFormat += sizeof(WORD);
5383 pFormat += sizeof(DWORD);
5384 elements = *(const DWORD*)pFormat;
5385 pFormat += sizeof(DWORD);
5388 pFormat += sizeof(WORD);
5390 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5391 if ((pStubMsg->ActualCount > elements) ||
5392 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5394 RpcRaiseException(RPC_S_INVALID_BOUND);
5398 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5401 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5414 return *(const USHORT *)pMemory;
5418 return *(const ULONG *)pMemory;
5420 FIXME("Unhandled base type: 0x%02x\n", fc);
5425 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5426 unsigned long discriminant,
5427 PFORMAT_STRING pFormat)
5429 unsigned short num_arms, arm, type;
5431 num_arms = *(const SHORT*)pFormat & 0x0fff;
5433 for(arm = 0; arm < num_arms; arm++)
5435 if(discriminant == *(const ULONG*)pFormat)
5443 type = *(const unsigned short*)pFormat;
5444 TRACE("type %04x\n", type);
5445 if(arm == num_arms) /* default arm extras */
5449 ERR("no arm for 0x%lx and no default case\n", discriminant);
5450 RpcRaiseException(RPC_S_INVALID_TAG);
5455 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
5462 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5464 unsigned short type;
5468 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5472 type = *(const unsigned short*)pFormat;
5473 if((type & 0xff00) == 0x8000)
5475 unsigned char basetype = LOBYTE(type);
5476 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5480 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5481 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5484 unsigned char *saved_buffer = NULL;
5485 int pointer_buffer_mark_set = 0;
5492 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5493 saved_buffer = pStubMsg->Buffer;
5494 if (pStubMsg->PointerBufferMark)
5496 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5497 pStubMsg->PointerBufferMark = NULL;
5498 pointer_buffer_mark_set = 1;
5501 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5503 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5504 if (pointer_buffer_mark_set)
5506 STD_OVERFLOW_CHECK(pStubMsg);
5507 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5508 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5510 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5511 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5512 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5514 pStubMsg->Buffer = saved_buffer + 4;
5518 m(pStubMsg, pMemory, desc);
5521 else FIXME("no marshaller for embedded type %02x\n", *desc);
5526 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5527 unsigned char **ppMemory,
5529 PFORMAT_STRING pFormat,
5530 unsigned char fMustAlloc)
5532 unsigned short type;
5536 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5540 type = *(const unsigned short*)pFormat;
5541 if((type & 0xff00) == 0x8000)
5543 unsigned char basetype = LOBYTE(type);
5544 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5548 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5549 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5552 unsigned char *saved_buffer = NULL;
5553 int pointer_buffer_mark_set = 0;
5560 **(void***)ppMemory = NULL;
5561 ALIGN_POINTER(pStubMsg->Buffer, 4);
5562 saved_buffer = pStubMsg->Buffer;
5563 if (pStubMsg->PointerBufferMark)
5565 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5566 pStubMsg->PointerBufferMark = NULL;
5567 pointer_buffer_mark_set = 1;
5570 pStubMsg->Buffer += 4; /* for pointer ID */
5572 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5574 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5575 saved_buffer, pStubMsg->BufferEnd);
5576 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5579 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5580 if (pointer_buffer_mark_set)
5582 STD_OVERFLOW_CHECK(pStubMsg);
5583 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5584 pStubMsg->Buffer = saved_buffer + 4;
5588 m(pStubMsg, ppMemory, desc, fMustAlloc);
5591 else FIXME("no marshaller for embedded type %02x\n", *desc);
5596 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5597 unsigned char *pMemory,
5599 PFORMAT_STRING pFormat)
5601 unsigned short type;
5605 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5609 type = *(const unsigned short*)pFormat;
5610 if((type & 0xff00) == 0x8000)
5612 unsigned char basetype = LOBYTE(type);
5613 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5617 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5618 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5627 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5628 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5629 if (!pStubMsg->IgnoreEmbeddedPointers)
5631 int saved_buffer_length = pStubMsg->BufferLength;
5632 pStubMsg->BufferLength = pStubMsg->PointerLength;
5633 pStubMsg->PointerLength = 0;
5634 if(!pStubMsg->BufferLength)
5635 ERR("BufferLength == 0??\n");
5636 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5637 pStubMsg->PointerLength = pStubMsg->BufferLength;
5638 pStubMsg->BufferLength = saved_buffer_length;
5642 m(pStubMsg, pMemory, desc);
5645 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5649 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5651 PFORMAT_STRING pFormat)
5653 unsigned short type, size;
5655 size = *(const unsigned short*)pFormat;
5656 pStubMsg->Memory += size;
5659 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5663 type = *(const unsigned short*)pFormat;
5664 if((type & 0xff00) == 0x8000)
5666 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5670 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5671 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5672 unsigned char *saved_buffer;
5681 ALIGN_POINTER(pStubMsg->Buffer, 4);
5682 saved_buffer = pStubMsg->Buffer;
5683 safe_buffer_increment(pStubMsg, 4);
5684 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
5685 pStubMsg->MemorySize += 4;
5686 if (!pStubMsg->IgnoreEmbeddedPointers)
5687 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5690 return m(pStubMsg, desc);
5693 else FIXME("no marshaller for embedded type %02x\n", *desc);
5696 TRACE("size %d\n", size);
5700 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5701 unsigned char *pMemory,
5703 PFORMAT_STRING pFormat)
5705 unsigned short type;
5709 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5713 type = *(const unsigned short*)pFormat;
5714 if((type & 0xff00) != 0x8000)
5716 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5717 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5726 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5729 m(pStubMsg, pMemory, desc);
5735 /***********************************************************************
5736 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5738 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5739 unsigned char *pMemory,
5740 PFORMAT_STRING pFormat)
5742 unsigned char switch_type;
5743 unsigned char increment;
5746 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5749 switch_type = *pFormat & 0xf;
5750 increment = (*pFormat & 0xf0) >> 4;
5753 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5755 switch_value = get_discriminant(switch_type, pMemory);
5756 TRACE("got switch value 0x%x\n", switch_value);
5758 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5759 pMemory += increment;
5761 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5764 /***********************************************************************
5765 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5767 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5768 unsigned char **ppMemory,
5769 PFORMAT_STRING pFormat,
5770 unsigned char fMustAlloc)
5772 unsigned char switch_type;
5773 unsigned char increment;
5775 unsigned short size;
5776 unsigned char *pMemoryArm;
5778 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5781 switch_type = *pFormat & 0xf;
5782 increment = (*pFormat & 0xf0) >> 4;
5785 ALIGN_POINTER(pStubMsg->Buffer, increment);
5786 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5787 TRACE("got switch value 0x%x\n", switch_value);
5789 size = *(const unsigned short*)pFormat + increment;
5790 if (!fMustAlloc && !*ppMemory)
5793 *ppMemory = NdrAllocate(pStubMsg, size);
5795 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5796 pMemoryArm = *ppMemory + increment;
5798 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
5801 /***********************************************************************
5802 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5804 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5805 unsigned char *pMemory,
5806 PFORMAT_STRING pFormat)
5808 unsigned char switch_type;
5809 unsigned char increment;
5812 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5815 switch_type = *pFormat & 0xf;
5816 increment = (*pFormat & 0xf0) >> 4;
5819 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5820 switch_value = get_discriminant(switch_type, pMemory);
5821 TRACE("got switch value 0x%x\n", switch_value);
5823 /* Add discriminant size */
5824 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5825 pMemory += increment;
5827 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5830 /***********************************************************************
5831 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5833 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5834 PFORMAT_STRING pFormat)
5836 unsigned char switch_type;
5837 unsigned char increment;
5840 switch_type = *pFormat & 0xf;
5841 increment = (*pFormat & 0xf0) >> 4;
5844 ALIGN_POINTER(pStubMsg->Buffer, increment);
5845 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5846 TRACE("got switch value 0x%x\n", switch_value);
5848 pStubMsg->Memory += increment;
5850 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5853 /***********************************************************************
5854 * NdrEncapsulatedUnionFree [RPCRT4.@]
5856 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5857 unsigned char *pMemory,
5858 PFORMAT_STRING pFormat)
5860 unsigned char switch_type;
5861 unsigned char increment;
5864 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5867 switch_type = *pFormat & 0xf;
5868 increment = (*pFormat & 0xf0) >> 4;
5871 switch_value = get_discriminant(switch_type, pMemory);
5872 TRACE("got switch value 0x%x\n", switch_value);
5874 pMemory += increment;
5876 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5879 /***********************************************************************
5880 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5882 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5883 unsigned char *pMemory,
5884 PFORMAT_STRING pFormat)
5886 unsigned char switch_type;
5888 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5891 switch_type = *pFormat;
5894 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5895 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5896 /* Marshall discriminant */
5897 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5899 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5902 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5903 PFORMAT_STRING *ppFormat)
5905 long discriminant = 0;
5915 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5924 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5925 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5933 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5934 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5939 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5943 if (pStubMsg->fHasNewCorrDesc)
5947 return discriminant;
5950 /**********************************************************************
5951 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5953 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5954 unsigned char **ppMemory,
5955 PFORMAT_STRING pFormat,
5956 unsigned char fMustAlloc)
5959 unsigned short size;
5961 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5964 /* Unmarshall discriminant */
5965 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5966 TRACE("unmarshalled discriminant %lx\n", discriminant);
5968 pFormat += *(const SHORT*)pFormat;
5970 size = *(const unsigned short*)pFormat;
5972 if (!fMustAlloc && !*ppMemory)
5975 *ppMemory = NdrAllocate(pStubMsg, size);
5977 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5980 /***********************************************************************
5981 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5983 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5984 unsigned char *pMemory,
5985 PFORMAT_STRING pFormat)
5987 unsigned char switch_type;
5989 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5992 switch_type = *pFormat;
5995 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5996 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5997 /* Add discriminant size */
5998 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6000 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6003 /***********************************************************************
6004 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6006 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6007 PFORMAT_STRING pFormat)
6012 /* Unmarshall discriminant */
6013 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6014 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
6016 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
6019 /***********************************************************************
6020 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6022 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6023 unsigned char *pMemory,
6024 PFORMAT_STRING pFormat)
6026 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6030 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6031 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6033 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6036 /***********************************************************************
6037 * NdrByteCountPointerMarshall [RPCRT4.@]
6039 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6040 unsigned char *pMemory,
6041 PFORMAT_STRING pFormat)
6047 /***********************************************************************
6048 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6050 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6051 unsigned char **ppMemory,
6052 PFORMAT_STRING pFormat,
6053 unsigned char fMustAlloc)
6059 /***********************************************************************
6060 * NdrByteCountPointerBufferSize [RPCRT4.@]
6062 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6063 unsigned char *pMemory,
6064 PFORMAT_STRING pFormat)
6069 /***********************************************************************
6070 * NdrByteCountPointerMemorySize [internal]
6072 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6073 PFORMAT_STRING pFormat)
6079 /***********************************************************************
6080 * NdrByteCountPointerFree [RPCRT4.@]
6082 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6083 unsigned char *pMemory,
6084 PFORMAT_STRING pFormat)
6089 /***********************************************************************
6090 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6092 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6093 unsigned char *pMemory,
6094 PFORMAT_STRING pFormat)
6100 /***********************************************************************
6101 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6103 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6104 unsigned char **ppMemory,
6105 PFORMAT_STRING pFormat,
6106 unsigned char fMustAlloc)
6112 /***********************************************************************
6113 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6115 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6116 unsigned char *pMemory,
6117 PFORMAT_STRING pFormat)
6122 /***********************************************************************
6123 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6125 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6126 PFORMAT_STRING pFormat)
6132 /***********************************************************************
6133 * NdrXmitOrRepAsFree [RPCRT4.@]
6135 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6136 unsigned char *pMemory,
6137 PFORMAT_STRING pFormat)
6142 /***********************************************************************
6143 * NdrRangeMarshall [internal]
6145 static unsigned char *WINAPI NdrRangeMarshall(
6146 PMIDL_STUB_MESSAGE pStubMsg,
6147 unsigned char *pMemory,
6148 PFORMAT_STRING pFormat)
6150 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6151 unsigned char base_type;
6153 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6155 if (pRange->type != RPC_FC_RANGE)
6157 ERR("invalid format type %x\n", pRange->type);
6158 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6162 base_type = pRange->flags_type & 0xf;
6164 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6167 /***********************************************************************
6168 * NdrRangeUnmarshall [RPCRT4.@]
6170 unsigned char *WINAPI NdrRangeUnmarshall(
6171 PMIDL_STUB_MESSAGE pStubMsg,
6172 unsigned char **ppMemory,
6173 PFORMAT_STRING pFormat,
6174 unsigned char fMustAlloc)
6176 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6177 unsigned char base_type;
6179 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6181 if (pRange->type != RPC_FC_RANGE)
6183 ERR("invalid format type %x\n", pRange->type);
6184 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6187 base_type = pRange->flags_type & 0xf;
6189 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6190 base_type, pRange->low_value, pRange->high_value);
6192 #define RANGE_UNMARSHALL(type, format_spec) \
6195 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6196 if (!fMustAlloc && !*ppMemory) \
6197 fMustAlloc = TRUE; \
6199 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6200 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
6202 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6203 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6204 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6206 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
6207 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
6209 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6210 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
6211 (type)pRange->high_value); \
6212 RpcRaiseException(RPC_S_INVALID_BOUND); \
6215 TRACE("*ppMemory: %p\n", *ppMemory); \
6216 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
6217 pStubMsg->Buffer += sizeof(type); \
6224 RANGE_UNMARSHALL(UCHAR, "%d");
6225 TRACE("value: 0x%02x\n", **ppMemory);
6229 RANGE_UNMARSHALL(CHAR, "%u");
6230 TRACE("value: 0x%02x\n", **ppMemory);
6232 case RPC_FC_WCHAR: /* FIXME: valid? */
6234 RANGE_UNMARSHALL(USHORT, "%u");
6235 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6238 RANGE_UNMARSHALL(SHORT, "%d");
6239 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6242 RANGE_UNMARSHALL(LONG, "%d");
6243 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6246 RANGE_UNMARSHALL(ULONG, "%u");
6247 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6251 FIXME("Unhandled enum type\n");
6253 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
6258 ERR("invalid range base type: 0x%02x\n", base_type);
6259 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6265 /***********************************************************************
6266 * NdrRangeBufferSize [internal]
6268 static void WINAPI NdrRangeBufferSize(
6269 PMIDL_STUB_MESSAGE pStubMsg,
6270 unsigned char *pMemory,
6271 PFORMAT_STRING pFormat)
6273 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6274 unsigned char base_type;
6276 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6278 if (pRange->type != RPC_FC_RANGE)
6280 ERR("invalid format type %x\n", pRange->type);
6281 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6283 base_type = pRange->flags_type & 0xf;
6285 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6288 /***********************************************************************
6289 * NdrRangeMemorySize [internal]
6291 static ULONG WINAPI NdrRangeMemorySize(
6292 PMIDL_STUB_MESSAGE pStubMsg,
6293 PFORMAT_STRING pFormat)
6295 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6296 unsigned char base_type;
6298 if (pRange->type != RPC_FC_RANGE)
6300 ERR("invalid format type %x\n", pRange->type);
6301 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6304 base_type = pRange->flags_type & 0xf;
6306 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6309 /***********************************************************************
6310 * NdrRangeFree [internal]
6312 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6313 unsigned char *pMemory,
6314 PFORMAT_STRING pFormat)
6316 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6321 /***********************************************************************
6322 * NdrBaseTypeMarshall [internal]
6324 static unsigned char *WINAPI NdrBaseTypeMarshall(
6325 PMIDL_STUB_MESSAGE pStubMsg,
6326 unsigned char *pMemory,
6327 PFORMAT_STRING pFormat)
6329 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6337 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6338 TRACE("value: 0x%02x\n", *pMemory);
6343 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6344 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6345 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6349 case RPC_FC_ERROR_STATUS_T:
6351 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
6352 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6353 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6356 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
6357 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6360 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
6361 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6364 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
6365 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6366 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6369 /* only 16-bits on the wire, so do a sanity check */
6370 if (*(UINT *)pMemory > SHRT_MAX)
6371 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6372 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6373 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6374 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6375 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
6376 pStubMsg->Buffer += sizeof(USHORT);
6377 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6382 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6385 /* FIXME: what is the correct return value? */
6389 /***********************************************************************
6390 * NdrBaseTypeUnmarshall [internal]
6392 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6393 PMIDL_STUB_MESSAGE pStubMsg,
6394 unsigned char **ppMemory,
6395 PFORMAT_STRING pFormat,
6396 unsigned char fMustAlloc)
6398 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6400 #define BASE_TYPE_UNMARSHALL(type) \
6401 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6402 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6404 *ppMemory = pStubMsg->Buffer; \
6405 TRACE("*ppMemory: %p\n", *ppMemory); \
6406 safe_buffer_increment(pStubMsg, sizeof(type)); \
6411 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6412 TRACE("*ppMemory: %p\n", *ppMemory); \
6413 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6422 BASE_TYPE_UNMARSHALL(UCHAR);
6423 TRACE("value: 0x%02x\n", **ppMemory);
6428 BASE_TYPE_UNMARSHALL(USHORT);
6429 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6433 case RPC_FC_ERROR_STATUS_T:
6435 BASE_TYPE_UNMARSHALL(ULONG);
6436 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6439 BASE_TYPE_UNMARSHALL(float);
6440 TRACE("value: %f\n", **(float **)ppMemory);
6443 BASE_TYPE_UNMARSHALL(double);
6444 TRACE("value: %f\n", **(double **)ppMemory);
6447 BASE_TYPE_UNMARSHALL(ULONGLONG);
6448 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6451 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6452 if (!fMustAlloc && !*ppMemory)
6455 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6456 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
6457 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6458 TRACE("*ppMemory: %p\n", *ppMemory);
6459 /* 16-bits on the wire, but int in memory */
6460 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
6461 pStubMsg->Buffer += sizeof(USHORT);
6462 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6467 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6469 #undef BASE_TYPE_UNMARSHALL
6471 /* FIXME: what is the correct return value? */
6476 /***********************************************************************
6477 * NdrBaseTypeBufferSize [internal]
6479 static void WINAPI NdrBaseTypeBufferSize(
6480 PMIDL_STUB_MESSAGE pStubMsg,
6481 unsigned char *pMemory,
6482 PFORMAT_STRING pFormat)
6484 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6492 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6498 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
6499 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6504 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
6505 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6508 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
6509 safe_buffer_length_increment(pStubMsg, sizeof(float));
6512 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
6513 safe_buffer_length_increment(pStubMsg, sizeof(double));
6516 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
6517 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6519 case RPC_FC_ERROR_STATUS_T:
6520 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
6521 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6526 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6530 /***********************************************************************
6531 * NdrBaseTypeMemorySize [internal]
6533 static ULONG WINAPI NdrBaseTypeMemorySize(
6534 PMIDL_STUB_MESSAGE pStubMsg,
6535 PFORMAT_STRING pFormat)
6537 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6545 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6546 pStubMsg->MemorySize += sizeof(UCHAR);
6547 return sizeof(UCHAR);
6551 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6552 pStubMsg->MemorySize += sizeof(USHORT);
6553 return sizeof(USHORT);
6557 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6558 pStubMsg->MemorySize += sizeof(ULONG);
6559 return sizeof(ULONG);
6561 safe_buffer_increment(pStubMsg, sizeof(float));
6562 pStubMsg->MemorySize += sizeof(float);
6563 return sizeof(float);
6565 safe_buffer_increment(pStubMsg, sizeof(double));
6566 pStubMsg->MemorySize += sizeof(double);
6567 return sizeof(double);
6569 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6570 pStubMsg->MemorySize += sizeof(ULONGLONG);
6571 return sizeof(ULONGLONG);
6572 case RPC_FC_ERROR_STATUS_T:
6573 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6574 pStubMsg->MemorySize += sizeof(error_status_t);
6575 return sizeof(error_status_t);
6577 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6578 pStubMsg->MemorySize += sizeof(UINT);
6579 return sizeof(UINT);
6581 pStubMsg->MemorySize += sizeof(void *);
6582 return sizeof(void *);
6584 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6589 /***********************************************************************
6590 * NdrBaseTypeFree [internal]
6592 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6593 unsigned char *pMemory,
6594 PFORMAT_STRING pFormat)
6596 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6601 /***********************************************************************
6602 * NdrContextHandleBufferSize [internal]
6604 static void WINAPI NdrContextHandleBufferSize(
6605 PMIDL_STUB_MESSAGE pStubMsg,
6606 unsigned char *pMemory,
6607 PFORMAT_STRING pFormat)
6609 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6611 if (*pFormat != RPC_FC_BIND_CONTEXT)
6613 ERR("invalid format type %x\n", *pFormat);
6614 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6616 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
6617 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6620 /***********************************************************************
6621 * NdrContextHandleMarshall [internal]
6623 static unsigned char *WINAPI NdrContextHandleMarshall(
6624 PMIDL_STUB_MESSAGE pStubMsg,
6625 unsigned char *pMemory,
6626 PFORMAT_STRING pFormat)
6628 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6630 if (*pFormat != RPC_FC_BIND_CONTEXT)
6632 ERR("invalid format type %x\n", *pFormat);
6633 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6635 TRACE("flags: 0x%02x\n", pFormat[1]);
6637 if (pFormat[1] & 0x80)
6638 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6640 NdrClientContextMarshall(pStubMsg, pMemory, FALSE);
6645 /***********************************************************************
6646 * NdrContextHandleUnmarshall [internal]
6648 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6649 PMIDL_STUB_MESSAGE pStubMsg,
6650 unsigned char **ppMemory,
6651 PFORMAT_STRING pFormat,
6652 unsigned char fMustAlloc)
6654 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6655 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6657 if (*pFormat != RPC_FC_BIND_CONTEXT)
6659 ERR("invalid format type %x\n", *pFormat);
6660 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6662 TRACE("flags: 0x%02x\n", pFormat[1]);
6664 /* [out]-only or [ret] param */
6665 if ((pFormat[1] & 0x60) == 0x20)
6666 **(NDR_CCONTEXT **)ppMemory = NULL;
6667 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6672 /***********************************************************************
6673 * NdrClientContextMarshall [RPCRT4.@]
6675 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6676 NDR_CCONTEXT ContextHandle,
6679 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
6681 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
6683 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6685 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6686 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6687 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6690 /* FIXME: what does fCheck do? */
6691 NDRCContextMarshall(ContextHandle,
6694 pStubMsg->Buffer += cbNDRContext;
6697 /***********************************************************************
6698 * NdrClientContextUnmarshall [RPCRT4.@]
6700 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6701 NDR_CCONTEXT * pContextHandle,
6702 RPC_BINDING_HANDLE BindHandle)
6704 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
6706 ALIGN_POINTER(pStubMsg->Buffer, 4);
6708 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
6709 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6711 NDRCContextUnmarshall(pContextHandle,
6714 pStubMsg->RpcMsg->DataRepresentation);
6716 pStubMsg->Buffer += cbNDRContext;
6719 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6720 NDR_SCONTEXT ContextHandle,
6721 NDR_RUNDOWN RundownRoutine )
6723 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
6725 ALIGN_POINTER(pStubMsg->Buffer, 4);
6727 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6729 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6730 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6731 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6734 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6735 pStubMsg->Buffer, RundownRoutine, NULL,
6736 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6737 pStubMsg->Buffer += cbNDRContext;
6740 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6742 NDR_SCONTEXT ContextHandle;
6744 TRACE("(%p)\n", pStubMsg);
6746 ALIGN_POINTER(pStubMsg->Buffer, 4);
6748 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6750 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6751 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6752 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6755 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6757 pStubMsg->RpcMsg->DataRepresentation,
6758 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6759 pStubMsg->Buffer += cbNDRContext;
6761 return ContextHandle;
6764 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6765 unsigned char* pMemory,
6766 PFORMAT_STRING pFormat)
6768 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6771 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6772 PFORMAT_STRING pFormat)
6774 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6775 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6777 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6779 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6780 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6781 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6782 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6783 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6785 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6786 if_id = &sif->InterfaceId;
6789 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
6790 pStubMsg->RpcMsg->DataRepresentation, if_id,
6794 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6795 NDR_SCONTEXT ContextHandle,
6796 NDR_RUNDOWN RundownRoutine,
6797 PFORMAT_STRING pFormat)
6799 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6800 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6802 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6804 ALIGN_POINTER(pStubMsg->Buffer, 4);
6806 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6808 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6809 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6810 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6813 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6814 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6815 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6816 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6817 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6819 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6820 if_id = &sif->InterfaceId;
6823 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6824 pStubMsg->Buffer, RundownRoutine, if_id, flags);
6825 pStubMsg->Buffer += cbNDRContext;
6828 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6829 PFORMAT_STRING pFormat)
6831 NDR_SCONTEXT ContextHandle;
6832 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6833 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6835 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6837 ALIGN_POINTER(pStubMsg->Buffer, 4);
6839 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6841 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6842 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6843 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6846 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6847 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6848 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6849 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6850 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6852 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6853 if_id = &sif->InterfaceId;
6856 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6858 pStubMsg->RpcMsg->DataRepresentation,
6860 pStubMsg->Buffer += cbNDRContext;
6862 return ContextHandle;
6865 /***********************************************************************
6866 * NdrCorrelationInitialize [RPCRT4.@]
6868 * Initializes correlation validity checking.
6871 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6872 * pMemory [I] Pointer to memory to use as a cache.
6873 * CacheSize [I] Size of the memory pointed to by pMemory.
6874 * Flags [I] Reserved. Set to zero.
6879 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
6881 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
6882 pStubMsg->fHasNewCorrDesc = TRUE;
6885 /***********************************************************************
6886 * NdrCorrelationPass [RPCRT4.@]
6888 * Performs correlation validity checking.
6891 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6896 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
6898 FIXME("(%p): stub\n", pStubMsg);
6901 /***********************************************************************
6902 * NdrCorrelationFree [RPCRT4.@]
6904 * Frees any resources used while unmarshalling parameters that need
6905 * correlation validity checking.
6908 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6913 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
6915 FIXME("(%p): stub\n", pStubMsg);