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 /* Increment the buffer here instead of in PointerUnmarshall,
1504 * as that is used by embedded pointers which already handle the incrementing
1505 * the buffer, and shouldn't read any additional pointer data from the
1507 if (*pFormat != RPC_FC_RP)
1509 ALIGN_POINTER(pStubMsg->Buffer, 4);
1510 Buffer = pStubMsg->Buffer;
1511 safe_buffer_increment(pStubMsg, 4);
1514 Buffer = pStubMsg->Buffer;
1516 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1521 /***********************************************************************
1522 * NdrPointerBufferSize [RPCRT4.@]
1524 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1525 unsigned char *pMemory,
1526 PFORMAT_STRING pFormat)
1528 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1530 /* Increment the buffer length here instead of in PointerBufferSize,
1531 * as that is used by embedded pointers which already handle the buffer
1532 * length, and shouldn't write anything more to the wire */
1533 if (*pFormat != RPC_FC_RP)
1535 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1536 safe_buffer_length_increment(pStubMsg, 4);
1539 PointerBufferSize(pStubMsg, pMemory, pFormat);
1542 /***********************************************************************
1543 * NdrPointerMemorySize [RPCRT4.@]
1545 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1546 PFORMAT_STRING pFormat)
1548 /* unsigned size = *(LPWORD)(pFormat+2); */
1549 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1550 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1554 /***********************************************************************
1555 * NdrPointerFree [RPCRT4.@]
1557 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1558 unsigned char *pMemory,
1559 PFORMAT_STRING pFormat)
1561 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1562 PointerFree(pStubMsg, pMemory, pFormat);
1565 /***********************************************************************
1566 * NdrSimpleTypeMarshall [RPCRT4.@]
1568 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1569 unsigned char FormatChar )
1571 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1574 /***********************************************************************
1575 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1577 * Unmarshall a base type.
1580 * Doesn't check that the buffer is long enough before copying, so the caller
1583 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1584 unsigned char FormatChar )
1586 #define BASE_TYPE_UNMARSHALL(type) \
1587 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
1588 TRACE("pMemory: %p\n", pMemory); \
1589 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1590 pStubMsg->Buffer += sizeof(type);
1598 BASE_TYPE_UNMARSHALL(UCHAR);
1599 TRACE("value: 0x%02x\n", *pMemory);
1604 BASE_TYPE_UNMARSHALL(USHORT);
1605 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
1609 case RPC_FC_ERROR_STATUS_T:
1611 BASE_TYPE_UNMARSHALL(ULONG);
1612 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
1615 BASE_TYPE_UNMARSHALL(float);
1616 TRACE("value: %f\n", *(float *)pMemory);
1619 BASE_TYPE_UNMARSHALL(double);
1620 TRACE("value: %f\n", *(double *)pMemory);
1623 BASE_TYPE_UNMARSHALL(ULONGLONG);
1624 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
1627 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
1628 TRACE("pMemory: %p\n", pMemory);
1629 /* 16-bits on the wire, but int in memory */
1630 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
1631 pStubMsg->Buffer += sizeof(USHORT);
1632 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
1637 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
1639 #undef BASE_TYPE_UNMARSHALL
1642 /***********************************************************************
1643 * NdrSimpleStructMarshall [RPCRT4.@]
1645 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1646 unsigned char *pMemory,
1647 PFORMAT_STRING pFormat)
1649 unsigned size = *(const WORD*)(pFormat+2);
1650 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1652 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
1654 pStubMsg->BufferMark = pStubMsg->Buffer;
1655 safe_copy_to_buffer(pStubMsg, pMemory, size);
1657 if (pFormat[0] != RPC_FC_STRUCT)
1658 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1663 /***********************************************************************
1664 * NdrSimpleStructUnmarshall [RPCRT4.@]
1666 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1667 unsigned char **ppMemory,
1668 PFORMAT_STRING pFormat,
1669 unsigned char fMustAlloc)
1671 unsigned size = *(const WORD*)(pFormat+2);
1672 unsigned char *saved_buffer;
1673 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1675 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1678 *ppMemory = NdrAllocate(pStubMsg, size);
1681 if (!pStubMsg->IsClient && !*ppMemory)
1682 /* for servers, we just point straight into the RPC buffer */
1683 *ppMemory = pStubMsg->Buffer;
1686 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1687 safe_buffer_increment(pStubMsg, size);
1688 if (pFormat[0] == RPC_FC_PSTRUCT)
1689 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1691 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1692 if (*ppMemory != saved_buffer)
1693 memcpy(*ppMemory, saved_buffer, size);
1698 /***********************************************************************
1699 * NdrSimpleStructBufferSize [RPCRT4.@]
1701 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1702 unsigned char *pMemory,
1703 PFORMAT_STRING pFormat)
1705 unsigned size = *(const WORD*)(pFormat+2);
1706 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1708 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1710 safe_buffer_length_increment(pStubMsg, size);
1711 if (pFormat[0] != RPC_FC_STRUCT)
1712 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1715 /***********************************************************************
1716 * NdrSimpleStructMemorySize [RPCRT4.@]
1718 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1719 PFORMAT_STRING pFormat)
1721 unsigned short size = *(const WORD *)(pFormat+2);
1723 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1725 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1726 pStubMsg->MemorySize += size;
1727 safe_buffer_increment(pStubMsg, size);
1729 if (pFormat[0] != RPC_FC_STRUCT)
1730 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1731 return pStubMsg->MemorySize;
1734 /***********************************************************************
1735 * NdrSimpleStructFree [RPCRT4.@]
1737 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1738 unsigned char *pMemory,
1739 PFORMAT_STRING pFormat)
1741 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1742 if (pFormat[0] != RPC_FC_STRUCT)
1743 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1748 static inline void array_compute_and_size_conformance(
1749 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1750 PFORMAT_STRING pFormat)
1755 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1756 SizeConformance(pStubMsg);
1758 case RPC_FC_CVARRAY:
1759 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1760 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1761 SizeConformance(pStubMsg);
1763 case RPC_FC_C_CSTRING:
1764 case RPC_FC_C_WSTRING:
1765 if (pFormat[0] == RPC_FC_C_CSTRING)
1767 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1768 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1772 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1773 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1776 if (fc == RPC_FC_STRING_SIZED)
1777 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1779 pStubMsg->MaxCount = pStubMsg->ActualCount;
1781 SizeConformance(pStubMsg);
1784 ERR("unknown array format 0x%x\n", fc);
1785 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1789 static inline void array_buffer_size(
1790 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1791 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1795 unsigned char alignment;
1800 esize = *(const WORD*)(pFormat+2);
1801 alignment = pFormat[1] + 1;
1803 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1805 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
1807 size = safe_multiply(esize, pStubMsg->MaxCount);
1808 /* conformance value plus array */
1809 safe_buffer_length_increment(pStubMsg, size);
1812 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1814 case RPC_FC_CVARRAY:
1815 esize = *(const WORD*)(pFormat+2);
1816 alignment = pFormat[1] + 1;
1818 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1819 pFormat = SkipConformance(pStubMsg, pFormat);
1821 SizeVariance(pStubMsg);
1823 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
1825 size = safe_multiply(esize, pStubMsg->ActualCount);
1826 safe_buffer_length_increment(pStubMsg, size);
1829 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1831 case RPC_FC_C_CSTRING:
1832 case RPC_FC_C_WSTRING:
1833 if (fc == RPC_FC_C_CSTRING)
1838 SizeVariance(pStubMsg);
1840 size = safe_multiply(esize, pStubMsg->ActualCount);
1841 safe_buffer_length_increment(pStubMsg, size);
1844 ERR("unknown array format 0x%x\n", fc);
1845 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1849 static inline void array_compute_and_write_conformance(
1850 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1851 PFORMAT_STRING pFormat)
1856 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1857 WriteConformance(pStubMsg);
1859 case RPC_FC_CVARRAY:
1860 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1861 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1862 WriteConformance(pStubMsg);
1864 case RPC_FC_C_CSTRING:
1865 case RPC_FC_C_WSTRING:
1866 if (fc == RPC_FC_C_CSTRING)
1868 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1869 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1873 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1874 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1876 if (pFormat[1] == RPC_FC_STRING_SIZED)
1877 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1879 pStubMsg->MaxCount = pStubMsg->ActualCount;
1880 pStubMsg->Offset = 0;
1881 WriteConformance(pStubMsg);
1884 ERR("unknown array format 0x%x\n", fc);
1885 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1889 static inline void array_write_variance_and_marshall(
1890 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1891 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1895 unsigned char alignment;
1900 esize = *(const WORD*)(pFormat+2);
1901 alignment = pFormat[1] + 1;
1903 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1905 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
1907 size = safe_multiply(esize, pStubMsg->MaxCount);
1909 pStubMsg->BufferMark = pStubMsg->Buffer;
1910 safe_copy_to_buffer(pStubMsg, pMemory, size);
1913 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1915 case RPC_FC_CVARRAY:
1916 esize = *(const WORD*)(pFormat+2);
1917 alignment = pFormat[1] + 1;
1920 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1922 pFormat = SkipConformance(pStubMsg, pFormat);
1924 WriteVariance(pStubMsg);
1926 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
1928 size = safe_multiply(esize, pStubMsg->ActualCount);
1931 pStubMsg->BufferMark = pStubMsg->Buffer;
1932 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size);
1935 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1937 case RPC_FC_C_CSTRING:
1938 case RPC_FC_C_WSTRING:
1939 if (fc == RPC_FC_C_CSTRING)
1944 WriteVariance(pStubMsg);
1946 size = safe_multiply(esize, pStubMsg->ActualCount);
1947 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
1950 ERR("unknown array format 0x%x\n", fc);
1951 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1955 static inline ULONG array_read_conformance(
1956 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
1963 esize = *(const WORD*)(pFormat+2);
1964 pFormat = ReadConformance(pStubMsg, pFormat+4);
1965 return safe_multiply(esize, pStubMsg->MaxCount);
1966 case RPC_FC_CVARRAY:
1967 esize = *(const WORD*)(pFormat+2);
1968 pFormat = ReadConformance(pStubMsg, pFormat+4);
1969 return safe_multiply(esize, pStubMsg->MaxCount);
1970 case RPC_FC_C_CSTRING:
1971 case RPC_FC_C_WSTRING:
1972 if (fc == RPC_FC_C_CSTRING)
1977 if (pFormat[1] == RPC_FC_STRING_SIZED)
1978 ReadConformance(pStubMsg, pFormat + 2);
1980 ReadConformance(pStubMsg, NULL);
1981 return safe_multiply(esize, pStubMsg->MaxCount);
1983 ERR("unknown array format 0x%x\n", fc);
1984 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1988 static inline ULONG array_read_variance_and_unmarshall(
1989 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory,
1990 PFORMAT_STRING pFormat, unsigned char fMustAlloc,
1991 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall)
1993 ULONG bufsize, memsize;
1995 unsigned char alignment;
1996 unsigned char *saved_buffer;
2002 esize = *(const WORD*)(pFormat+2);
2003 alignment = pFormat[1] + 1;
2005 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2007 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2009 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2014 *ppMemory = NdrAllocate(pStubMsg, memsize);
2017 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory)
2018 /* for servers, we just point straight into the RPC buffer */
2019 *ppMemory = pStubMsg->Buffer;
2022 saved_buffer = pStubMsg->Buffer;
2023 safe_buffer_increment(pStubMsg, bufsize);
2025 pStubMsg->BufferMark = saved_buffer;
2026 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2028 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2029 if (*ppMemory != saved_buffer)
2030 memcpy(*ppMemory, saved_buffer, bufsize);
2033 case RPC_FC_CVARRAY:
2034 esize = *(const WORD*)(pFormat+2);
2035 alignment = pFormat[1] + 1;
2037 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2039 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2041 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2043 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2044 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2048 offset = pStubMsg->Offset;
2050 if (!fMustAlloc && !*ppMemory)
2053 *ppMemory = NdrAllocate(pStubMsg, memsize);
2054 saved_buffer = pStubMsg->Buffer;
2055 safe_buffer_increment(pStubMsg, bufsize);
2057 pStubMsg->BufferMark = saved_buffer;
2058 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat,
2061 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2064 case RPC_FC_C_CSTRING:
2065 case RPC_FC_C_WSTRING:
2066 if (fc == RPC_FC_C_CSTRING)
2071 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2073 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2075 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2076 pStubMsg->ActualCount, pStubMsg->MaxCount);
2077 RpcRaiseException(RPC_S_INVALID_BOUND);
2079 if (pStubMsg->Offset)
2081 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2082 RpcRaiseException(RPC_S_INVALID_BOUND);
2085 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2086 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2088 validate_string_data(pStubMsg, bufsize, esize);
2093 *ppMemory = NdrAllocate(pStubMsg, memsize);
2096 if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
2097 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
2098 /* if the data in the RPC buffer is big enough, we just point
2099 * straight into it */
2100 *ppMemory = pStubMsg->Buffer;
2101 else if (!*ppMemory)
2102 *ppMemory = NdrAllocate(pStubMsg, memsize);
2105 if (*ppMemory == pStubMsg->Buffer)
2106 safe_buffer_increment(pStubMsg, bufsize);
2108 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2110 if (*pFormat == RPC_FC_C_CSTRING)
2111 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
2113 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
2117 ERR("unknown array format 0x%x\n", fc);
2118 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2122 static inline void array_memory_size(
2123 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
2124 unsigned char fHasPointers)
2126 ULONG bufsize, memsize;
2128 unsigned char alignment;
2133 esize = *(const WORD*)(pFormat+2);
2134 alignment = pFormat[1] + 1;
2136 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2138 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2139 pStubMsg->MemorySize += memsize;
2141 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2143 pStubMsg->BufferMark = pStubMsg->Buffer;
2144 safe_buffer_increment(pStubMsg, bufsize);
2147 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2149 case RPC_FC_CVARRAY:
2150 esize = *(const WORD*)(pFormat+2);
2151 alignment = pFormat[1] + 1;
2153 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2155 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2157 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2158 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2159 pStubMsg->MemorySize += memsize;
2161 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2163 pStubMsg->BufferMark = pStubMsg->Buffer;
2164 safe_buffer_increment(pStubMsg, bufsize);
2167 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2169 case RPC_FC_C_CSTRING:
2170 case RPC_FC_C_WSTRING:
2171 if (fc == RPC_FC_C_CSTRING)
2176 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2178 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2180 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2181 pStubMsg->ActualCount, pStubMsg->MaxCount);
2182 RpcRaiseException(RPC_S_INVALID_BOUND);
2184 if (pStubMsg->Offset)
2186 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2187 RpcRaiseException(RPC_S_INVALID_BOUND);
2190 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2191 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2193 validate_string_data(pStubMsg, bufsize, esize);
2195 safe_buffer_increment(pStubMsg, bufsize);
2196 pStubMsg->MemorySize += memsize;
2199 ERR("unknown array format 0x%x\n", fc);
2200 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2204 static inline void array_free(
2205 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
2206 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
2211 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2213 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2215 case RPC_FC_CVARRAY:
2216 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2217 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2219 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2221 case RPC_FC_C_CSTRING:
2222 case RPC_FC_C_WSTRING:
2223 /* No embedded pointers so nothing to do */
2226 ERR("unknown array format 0x%x\n", fc);
2227 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2232 * NdrConformantString:
2234 * What MS calls a ConformantString is, in DCE terminology,
2235 * a Varying-Conformant String.
2237 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2238 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2239 * into unmarshalled string)
2240 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2242 * data: CHARTYPE[maxlen]
2244 * ], where CHARTYPE is the appropriate character type (specified externally)
2248 /***********************************************************************
2249 * NdrConformantStringMarshall [RPCRT4.@]
2251 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
2252 unsigned char *pszMessage, PFORMAT_STRING pFormat)
2254 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
2256 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2257 ERR("Unhandled string type: %#x\n", pFormat[0]);
2258 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2261 /* allow compiler to optimise inline function by passing constant into
2262 * these functions */
2263 if (pFormat[0] == RPC_FC_C_CSTRING) {
2264 array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2266 array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2267 pFormat, TRUE /* fHasPointers */);
2269 array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2271 array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2272 pFormat, TRUE /* fHasPointers */);
2278 /***********************************************************************
2279 * NdrConformantStringBufferSize [RPCRT4.@]
2281 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2282 unsigned char* pMemory, PFORMAT_STRING pFormat)
2284 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2286 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2287 ERR("Unhandled string type: %#x\n", pFormat[0]);
2288 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2291 /* allow compiler to optimise inline function by passing constant into
2292 * these functions */
2293 if (pFormat[0] == RPC_FC_C_CSTRING) {
2294 array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory,
2296 array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat,
2297 TRUE /* fHasPointers */);
2299 array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory,
2301 array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat,
2302 TRUE /* fHasPointers */);
2306 /************************************************************************
2307 * NdrConformantStringMemorySize [RPCRT4.@]
2309 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2310 PFORMAT_STRING pFormat )
2312 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2314 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2315 ERR("Unhandled string type: %#x\n", pFormat[0]);
2316 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2319 /* allow compiler to optimise inline function by passing constant into
2320 * these functions */
2321 if (pFormat[0] == RPC_FC_C_CSTRING) {
2322 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2323 array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat,
2324 TRUE /* fHasPointers */);
2326 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2327 array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat,
2328 TRUE /* fHasPointers */);
2331 return pStubMsg->MemorySize;
2334 /************************************************************************
2335 * NdrConformantStringUnmarshall [RPCRT4.@]
2337 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2338 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
2340 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2341 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2343 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2344 ERR("Unhandled string type: %#x\n", *pFormat);
2345 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2348 /* allow compiler to optimise inline function by passing constant into
2349 * these functions */
2350 if (pFormat[0] == RPC_FC_C_CSTRING) {
2351 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2352 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory,
2353 pFormat, fMustAlloc,
2354 TRUE /* fUseBufferMemoryServer */,
2355 TRUE /* fUnmarshall */);
2357 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2358 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory,
2359 pFormat, fMustAlloc,
2360 TRUE /* fUseBufferMemoryServer */,
2361 TRUE /* fUnmarshall */);
2367 /***********************************************************************
2368 * NdrNonConformantStringMarshall [RPCRT4.@]
2370 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2371 unsigned char *pMemory,
2372 PFORMAT_STRING pFormat)
2374 ULONG esize, size, maxsize;
2376 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2378 maxsize = *(USHORT *)&pFormat[2];
2380 if (*pFormat == RPC_FC_CSTRING)
2383 const char *str = (const char *)pMemory;
2384 for (i = 0; i < maxsize && *str; i++, str++)
2386 TRACE("string=%s\n", debugstr_an(str, i));
2387 pStubMsg->ActualCount = i + 1;
2390 else if (*pFormat == RPC_FC_WSTRING)
2393 const WCHAR *str = (const WCHAR *)pMemory;
2394 for (i = 0; i < maxsize && *str; i++, str++)
2396 TRACE("string=%s\n", debugstr_wn(str, i));
2397 pStubMsg->ActualCount = i + 1;
2402 ERR("Unhandled string type: %#x\n", *pFormat);
2403 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2406 pStubMsg->Offset = 0;
2407 WriteVariance(pStubMsg);
2409 size = safe_multiply(esize, pStubMsg->ActualCount);
2410 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2415 /***********************************************************************
2416 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2418 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2419 unsigned char **ppMemory,
2420 PFORMAT_STRING pFormat,
2421 unsigned char fMustAlloc)
2423 ULONG bufsize, memsize, esize, maxsize;
2425 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2426 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2428 maxsize = *(USHORT *)&pFormat[2];
2430 ReadVariance(pStubMsg, NULL, maxsize);
2431 if (pStubMsg->Offset)
2433 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2434 RpcRaiseException(RPC_S_INVALID_BOUND);
2437 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2438 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2441 ERR("Unhandled string type: %#x\n", *pFormat);
2442 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2445 memsize = esize * maxsize;
2446 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2448 validate_string_data(pStubMsg, bufsize, esize);
2450 if (!fMustAlloc && !*ppMemory)
2453 *ppMemory = NdrAllocate(pStubMsg, memsize);
2455 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2457 if (*pFormat == RPC_FC_CSTRING) {
2458 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
2460 else if (*pFormat == RPC_FC_WSTRING) {
2461 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
2467 /***********************************************************************
2468 * NdrNonConformantStringBufferSize [RPCRT4.@]
2470 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2471 unsigned char *pMemory,
2472 PFORMAT_STRING pFormat)
2474 ULONG esize, maxsize;
2476 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2478 maxsize = *(USHORT *)&pFormat[2];
2480 SizeVariance(pStubMsg);
2482 if (*pFormat == RPC_FC_CSTRING)
2485 const char *str = (const char *)pMemory;
2486 for (i = 0; i < maxsize && *str; i++, str++)
2488 TRACE("string=%s\n", debugstr_an(str, i));
2489 pStubMsg->ActualCount = i + 1;
2492 else if (*pFormat == RPC_FC_WSTRING)
2495 const WCHAR *str = (const WCHAR *)pMemory;
2496 for (i = 0; i < maxsize && *str; i++, str++)
2498 TRACE("string=%s\n", debugstr_wn(str, i));
2499 pStubMsg->ActualCount = i + 1;
2504 ERR("Unhandled string type: %#x\n", *pFormat);
2505 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2508 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2511 /***********************************************************************
2512 * NdrNonConformantStringMemorySize [RPCRT4.@]
2514 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2515 PFORMAT_STRING pFormat)
2517 ULONG bufsize, memsize, esize, maxsize;
2519 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2521 maxsize = *(USHORT *)&pFormat[2];
2523 ReadVariance(pStubMsg, NULL, maxsize);
2525 if (pStubMsg->Offset)
2527 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2528 RpcRaiseException(RPC_S_INVALID_BOUND);
2531 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2532 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2535 ERR("Unhandled string type: %#x\n", *pFormat);
2536 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2539 memsize = esize * maxsize;
2540 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2542 validate_string_data(pStubMsg, bufsize, esize);
2544 safe_buffer_increment(pStubMsg, bufsize);
2545 pStubMsg->MemorySize += memsize;
2547 return pStubMsg->MemorySize;
2552 #include "pshpack1.h"
2556 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2560 #include "poppack.h"
2562 static unsigned long EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2563 PFORMAT_STRING pFormat)
2567 case RPC_FC_PSTRUCT:
2568 case RPC_FC_CSTRUCT:
2569 case RPC_FC_BOGUS_STRUCT:
2570 case RPC_FC_SMFARRAY:
2571 case RPC_FC_SMVARRAY:
2572 case RPC_FC_CSTRING:
2573 return *(const WORD*)&pFormat[2];
2574 case RPC_FC_USER_MARSHAL:
2575 return *(const WORD*)&pFormat[4];
2576 case RPC_FC_RANGE: {
2577 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2582 return sizeof(UCHAR);
2586 return sizeof(USHORT);
2590 return sizeof(ULONG);
2592 return sizeof(float);
2594 return sizeof(double);
2596 return sizeof(ULONGLONG);
2598 return sizeof(UINT);
2600 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2601 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2604 case RPC_FC_NON_ENCAPSULATED_UNION:
2606 if (pStubMsg->fHasNewCorrDesc)
2611 pFormat += *(const SHORT*)pFormat;
2612 return *(const SHORT*)pFormat;
2614 return sizeof(void *);
2615 case RPC_FC_WSTRING:
2616 return *(const WORD*)&pFormat[2] * 2;
2618 FIXME("unhandled embedded type %02x\n", *pFormat);
2624 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2625 PFORMAT_STRING pFormat)
2627 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2631 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2635 return m(pStubMsg, pFormat);
2639 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2640 unsigned char *pMemory,
2641 PFORMAT_STRING pFormat,
2642 PFORMAT_STRING pPointer)
2644 PFORMAT_STRING desc;
2648 while (*pFormat != RPC_FC_END) {
2654 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2655 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2661 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2662 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2666 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2667 if (32767 < *(DWORD*)pMemory)
2668 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2669 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2675 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2676 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2680 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2681 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2684 case RPC_FC_POINTER:
2686 unsigned char *saved_buffer;
2687 int pointer_buffer_mark_set = 0;
2688 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2689 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2690 if (*pPointer != RPC_FC_RP)
2691 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
2692 saved_buffer = pStubMsg->Buffer;
2693 if (pStubMsg->PointerBufferMark)
2695 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2696 pStubMsg->PointerBufferMark = NULL;
2697 pointer_buffer_mark_set = 1;
2699 else if (*pPointer != RPC_FC_RP)
2700 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2701 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2702 if (pointer_buffer_mark_set)
2704 STD_OVERFLOW_CHECK(pStubMsg);
2705 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2706 pStubMsg->Buffer = saved_buffer;
2707 if (*pPointer != RPC_FC_RP)
2708 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2710 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2715 case RPC_FC_ALIGNM4:
2716 ALIGN_POINTER(pMemory, 4);
2718 case RPC_FC_ALIGNM8:
2719 ALIGN_POINTER(pMemory, 8);
2721 case RPC_FC_STRUCTPAD1:
2722 case RPC_FC_STRUCTPAD2:
2723 case RPC_FC_STRUCTPAD3:
2724 case RPC_FC_STRUCTPAD4:
2725 case RPC_FC_STRUCTPAD5:
2726 case RPC_FC_STRUCTPAD6:
2727 case RPC_FC_STRUCTPAD7:
2728 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2730 case RPC_FC_EMBEDDED_COMPLEX:
2731 pMemory += pFormat[1];
2733 desc = pFormat + *(const SHORT*)pFormat;
2734 size = EmbeddedComplexSize(pStubMsg, desc);
2735 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
2736 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2739 /* for some reason interface pointers aren't generated as
2740 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2741 * they still need the derefencing treatment that pointers are
2743 if (*desc == RPC_FC_IP)
2744 m(pStubMsg, *(unsigned char **)pMemory, desc);
2746 m(pStubMsg, pMemory, desc);
2748 else FIXME("no marshaller for embedded type %02x\n", *desc);
2755 FIXME("unhandled format 0x%02x\n", *pFormat);
2763 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2764 unsigned char *pMemory,
2765 PFORMAT_STRING pFormat,
2766 PFORMAT_STRING pPointer,
2767 unsigned char fMustAlloc)
2769 PFORMAT_STRING desc;
2773 while (*pFormat != RPC_FC_END) {
2779 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2780 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2786 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2787 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2791 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2792 *(DWORD*)pMemory &= 0xffff;
2793 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
2794 if (32767 < *(DWORD*)pMemory)
2795 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2801 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2802 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2806 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2807 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2810 case RPC_FC_POINTER:
2812 unsigned char *saved_buffer;
2813 int pointer_buffer_mark_set = 0;
2814 TRACE("pointer => %p\n", pMemory);
2815 if (*pPointer != RPC_FC_RP)
2816 ALIGN_POINTER(pStubMsg->Buffer, 4);
2817 saved_buffer = pStubMsg->Buffer;
2818 if (pStubMsg->PointerBufferMark)
2820 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2821 pStubMsg->PointerBufferMark = NULL;
2822 pointer_buffer_mark_set = 1;
2824 else if (*pPointer != RPC_FC_RP)
2825 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2827 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
2828 if (pointer_buffer_mark_set)
2830 STD_OVERFLOW_CHECK(pStubMsg);
2831 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2832 pStubMsg->Buffer = saved_buffer;
2833 if (*pPointer != RPC_FC_RP)
2834 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2840 case RPC_FC_ALIGNM4:
2841 ALIGN_POINTER_CLEAR(pMemory, 4);
2843 case RPC_FC_ALIGNM8:
2844 ALIGN_POINTER_CLEAR(pMemory, 8);
2846 case RPC_FC_STRUCTPAD1:
2847 case RPC_FC_STRUCTPAD2:
2848 case RPC_FC_STRUCTPAD3:
2849 case RPC_FC_STRUCTPAD4:
2850 case RPC_FC_STRUCTPAD5:
2851 case RPC_FC_STRUCTPAD6:
2852 case RPC_FC_STRUCTPAD7:
2853 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2854 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2856 case RPC_FC_EMBEDDED_COMPLEX:
2857 pMemory += pFormat[1];
2859 desc = pFormat + *(const SHORT*)pFormat;
2860 size = EmbeddedComplexSize(pStubMsg, desc);
2861 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2863 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
2864 * since the type is part of the memory block that is encompassed by
2865 * the whole complex type. Memory is forced to allocate when pointers
2866 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
2867 * clearing the memory we pass in to the unmarshaller */
2868 memset(pMemory, 0, size);
2869 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2872 /* for some reason interface pointers aren't generated as
2873 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2874 * they still need the derefencing treatment that pointers are
2876 if (*desc == RPC_FC_IP)
2877 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2879 m(pStubMsg, &pMemory, desc, FALSE);
2881 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2888 FIXME("unhandled format %d\n", *pFormat);
2896 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2897 unsigned char *pMemory,
2898 PFORMAT_STRING pFormat,
2899 PFORMAT_STRING pPointer)
2901 PFORMAT_STRING desc;
2905 while (*pFormat != RPC_FC_END) {
2911 safe_buffer_length_increment(pStubMsg, 1);
2917 safe_buffer_length_increment(pStubMsg, 2);
2921 safe_buffer_length_increment(pStubMsg, 2);
2927 safe_buffer_length_increment(pStubMsg, 4);
2931 safe_buffer_length_increment(pStubMsg, 8);
2934 case RPC_FC_POINTER:
2935 if (!pStubMsg->IgnoreEmbeddedPointers)
2937 int saved_buffer_length = pStubMsg->BufferLength;
2938 pStubMsg->BufferLength = pStubMsg->PointerLength;
2939 pStubMsg->PointerLength = 0;
2940 if(!pStubMsg->BufferLength)
2941 ERR("BufferLength == 0??\n");
2942 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2943 pStubMsg->PointerLength = pStubMsg->BufferLength;
2944 pStubMsg->BufferLength = saved_buffer_length;
2946 if (*pPointer != RPC_FC_RP)
2948 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2949 safe_buffer_length_increment(pStubMsg, 4);
2954 case RPC_FC_ALIGNM4:
2955 ALIGN_POINTER(pMemory, 4);
2957 case RPC_FC_ALIGNM8:
2958 ALIGN_POINTER(pMemory, 8);
2960 case RPC_FC_STRUCTPAD1:
2961 case RPC_FC_STRUCTPAD2:
2962 case RPC_FC_STRUCTPAD3:
2963 case RPC_FC_STRUCTPAD4:
2964 case RPC_FC_STRUCTPAD5:
2965 case RPC_FC_STRUCTPAD6:
2966 case RPC_FC_STRUCTPAD7:
2967 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2969 case RPC_FC_EMBEDDED_COMPLEX:
2970 pMemory += pFormat[1];
2972 desc = pFormat + *(const SHORT*)pFormat;
2973 size = EmbeddedComplexSize(pStubMsg, desc);
2974 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2977 /* for some reason interface pointers aren't generated as
2978 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2979 * they still need the derefencing treatment that pointers are
2981 if (*desc == RPC_FC_IP)
2982 m(pStubMsg, *(unsigned char **)pMemory, desc);
2984 m(pStubMsg, pMemory, desc);
2986 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2993 FIXME("unhandled format 0x%02x\n", *pFormat);
3001 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
3002 unsigned char *pMemory,
3003 PFORMAT_STRING pFormat,
3004 PFORMAT_STRING pPointer)
3006 PFORMAT_STRING desc;
3010 while (*pFormat != RPC_FC_END) {
3032 case RPC_FC_POINTER:
3033 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3037 case RPC_FC_ALIGNM4:
3038 ALIGN_POINTER(pMemory, 4);
3040 case RPC_FC_ALIGNM8:
3041 ALIGN_POINTER(pMemory, 8);
3043 case RPC_FC_STRUCTPAD1:
3044 case RPC_FC_STRUCTPAD2:
3045 case RPC_FC_STRUCTPAD3:
3046 case RPC_FC_STRUCTPAD4:
3047 case RPC_FC_STRUCTPAD5:
3048 case RPC_FC_STRUCTPAD6:
3049 case RPC_FC_STRUCTPAD7:
3050 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3052 case RPC_FC_EMBEDDED_COMPLEX:
3053 pMemory += pFormat[1];
3055 desc = pFormat + *(const SHORT*)pFormat;
3056 size = EmbeddedComplexSize(pStubMsg, desc);
3057 m = NdrFreer[*desc & NDR_TABLE_MASK];
3060 /* for some reason interface pointers aren't generated as
3061 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3062 * they still need the derefencing treatment that pointers are
3064 if (*desc == RPC_FC_IP)
3065 m(pStubMsg, *(unsigned char **)pMemory, desc);
3067 m(pStubMsg, pMemory, desc);
3075 FIXME("unhandled format 0x%02x\n", *pFormat);
3083 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3084 PFORMAT_STRING pFormat,
3085 PFORMAT_STRING pPointer)
3087 PFORMAT_STRING desc;
3088 unsigned long size = 0;
3090 while (*pFormat != RPC_FC_END) {
3097 safe_buffer_increment(pStubMsg, 1);
3103 safe_buffer_increment(pStubMsg, 2);
3107 safe_buffer_increment(pStubMsg, 2);
3113 safe_buffer_increment(pStubMsg, 4);
3117 safe_buffer_increment(pStubMsg, 8);
3119 case RPC_FC_POINTER:
3121 unsigned char *saved_buffer;
3122 int pointer_buffer_mark_set = 0;
3123 if (*pPointer != RPC_FC_RP)
3124 ALIGN_POINTER(pStubMsg->Buffer, 4);
3125 saved_buffer = pStubMsg->Buffer;
3126 if (pStubMsg->PointerBufferMark)
3128 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3129 pStubMsg->PointerBufferMark = NULL;
3130 pointer_buffer_mark_set = 1;
3132 else if (*pPointer != RPC_FC_RP)
3133 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3135 if (!pStubMsg->IgnoreEmbeddedPointers)
3136 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3137 if (pointer_buffer_mark_set)
3139 STD_OVERFLOW_CHECK(pStubMsg);
3140 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3141 pStubMsg->Buffer = saved_buffer;
3142 if (*pPointer != RPC_FC_RP)
3143 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3149 case RPC_FC_ALIGNM4:
3150 ALIGN_LENGTH(size, 4);
3152 case RPC_FC_ALIGNM8:
3153 ALIGN_LENGTH(size, 8);
3155 case RPC_FC_STRUCTPAD1:
3156 case RPC_FC_STRUCTPAD2:
3157 case RPC_FC_STRUCTPAD3:
3158 case RPC_FC_STRUCTPAD4:
3159 case RPC_FC_STRUCTPAD5:
3160 case RPC_FC_STRUCTPAD6:
3161 case RPC_FC_STRUCTPAD7:
3162 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3164 case RPC_FC_EMBEDDED_COMPLEX:
3167 desc = pFormat + *(const SHORT*)pFormat;
3168 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3174 FIXME("unhandled format 0x%02x\n", *pFormat);
3182 unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg,
3183 PFORMAT_STRING pFormat)
3185 PFORMAT_STRING desc;
3186 unsigned long size = 0;
3188 while (*pFormat != RPC_FC_END) {
3210 case RPC_FC_POINTER:
3211 size += sizeof(void *);
3213 case RPC_FC_ALIGNM4:
3214 ALIGN_LENGTH(size, 4);
3216 case RPC_FC_ALIGNM8:
3217 ALIGN_LENGTH(size, 8);
3219 case RPC_FC_STRUCTPAD1:
3220 case RPC_FC_STRUCTPAD2:
3221 case RPC_FC_STRUCTPAD3:
3222 case RPC_FC_STRUCTPAD4:
3223 case RPC_FC_STRUCTPAD5:
3224 case RPC_FC_STRUCTPAD6:
3225 case RPC_FC_STRUCTPAD7:
3226 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3228 case RPC_FC_EMBEDDED_COMPLEX:
3231 desc = pFormat + *(const SHORT*)pFormat;
3232 size += EmbeddedComplexSize(pStubMsg, desc);
3238 FIXME("unhandled format 0x%02x\n", *pFormat);
3246 /***********************************************************************
3247 * NdrComplexStructMarshall [RPCRT4.@]
3249 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3250 unsigned char *pMemory,
3251 PFORMAT_STRING pFormat)
3253 PFORMAT_STRING conf_array = NULL;
3254 PFORMAT_STRING pointer_desc = NULL;
3255 unsigned char *OldMemory = pStubMsg->Memory;
3256 int pointer_buffer_mark_set = 0;
3258 ULONG max_count = 0;
3261 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3263 if (!pStubMsg->PointerBufferMark)
3265 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3266 /* save buffer length */
3267 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3269 /* get the buffer pointer after complex array data, but before
3271 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3272 pStubMsg->IgnoreEmbeddedPointers = 1;
3273 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3274 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3276 /* save it for use by embedded pointer code later */
3277 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3278 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
3279 pointer_buffer_mark_set = 1;
3281 /* restore the original buffer length */
3282 pStubMsg->BufferLength = saved_buffer_length;
3285 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
3288 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3290 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3293 pStubMsg->Memory = pMemory;
3297 unsigned long struct_size = ComplexStructSize(pStubMsg, pFormat);
3298 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3299 pMemory + struct_size, conf_array);
3300 /* these could be changed in ComplexMarshall so save them for later */
3301 max_count = pStubMsg->MaxCount;
3302 count = pStubMsg->ActualCount;
3303 offset = pStubMsg->Offset;
3306 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3310 pStubMsg->MaxCount = max_count;
3311 pStubMsg->ActualCount = count;
3312 pStubMsg->Offset = offset;
3313 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3314 conf_array, TRUE /* fHasPointers */);
3317 pStubMsg->Memory = OldMemory;
3319 if (pointer_buffer_mark_set)
3321 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3322 pStubMsg->PointerBufferMark = NULL;
3325 STD_OVERFLOW_CHECK(pStubMsg);
3330 /***********************************************************************
3331 * NdrComplexStructUnmarshall [RPCRT4.@]
3333 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3334 unsigned char **ppMemory,
3335 PFORMAT_STRING pFormat,
3336 unsigned char fMustAlloc)
3338 unsigned size = *(const WORD*)(pFormat+2);
3339 PFORMAT_STRING conf_array = NULL;
3340 PFORMAT_STRING pointer_desc = NULL;
3341 unsigned char *pMemory;
3342 int pointer_buffer_mark_set = 0;
3344 ULONG max_count = 0;
3346 ULONG array_size = 0;
3348 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3350 if (!pStubMsg->PointerBufferMark)
3352 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3353 /* save buffer pointer */
3354 unsigned char *saved_buffer = pStubMsg->Buffer;
3356 /* get the buffer pointer after complex array data, but before
3358 pStubMsg->IgnoreEmbeddedPointers = 1;
3359 NdrComplexStructMemorySize(pStubMsg, pFormat);
3360 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3362 /* save it for use by embedded pointer code later */
3363 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3364 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
3365 pointer_buffer_mark_set = 1;
3367 /* restore the original buffer */
3368 pStubMsg->Buffer = saved_buffer;
3371 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3374 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3376 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3381 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3384 /* these could be changed in ComplexMarshall so save them for later */
3385 max_count = pStubMsg->MaxCount;
3386 count = pStubMsg->ActualCount;
3387 offset = pStubMsg->Offset;
3390 if (!fMustAlloc && !*ppMemory)
3393 *ppMemory = NdrAllocate(pStubMsg, size);
3395 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3399 pStubMsg->MaxCount = max_count;
3400 pStubMsg->ActualCount = count;
3401 pStubMsg->Offset = offset;
3403 memset(pMemory, 0, array_size);
3404 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3406 FALSE /* fUseBufferMemoryServer */,
3407 TRUE /* fUnmarshall */);
3410 if (pointer_buffer_mark_set)
3412 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3413 pStubMsg->PointerBufferMark = NULL;
3419 /***********************************************************************
3420 * NdrComplexStructBufferSize [RPCRT4.@]
3422 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3423 unsigned char *pMemory,
3424 PFORMAT_STRING pFormat)
3426 PFORMAT_STRING conf_array = NULL;
3427 PFORMAT_STRING pointer_desc = NULL;
3428 unsigned char *OldMemory = pStubMsg->Memory;
3429 int pointer_length_set = 0;
3431 ULONG max_count = 0;
3434 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3436 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
3438 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3440 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3441 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3443 /* get the buffer length after complex struct data, but before
3445 pStubMsg->IgnoreEmbeddedPointers = 1;
3446 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3447 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3449 /* save it for use by embedded pointer code later */
3450 pStubMsg->PointerLength = pStubMsg->BufferLength;
3451 pointer_length_set = 1;
3452 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
3454 /* restore the original buffer length */
3455 pStubMsg->BufferLength = saved_buffer_length;
3459 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3461 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3464 pStubMsg->Memory = pMemory;
3468 unsigned long struct_size = ComplexStructSize(pStubMsg, pFormat);
3469 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3472 /* these could be changed in ComplexMarshall so save them for later */
3473 max_count = pStubMsg->MaxCount;
3474 count = pStubMsg->ActualCount;
3475 offset = pStubMsg->Offset;
3478 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3482 pStubMsg->MaxCount = max_count;
3483 pStubMsg->ActualCount = count;
3484 pStubMsg->Offset = offset;
3485 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3486 TRUE /* fHasPointers */);
3489 pStubMsg->Memory = OldMemory;
3491 if(pointer_length_set)
3493 pStubMsg->BufferLength = pStubMsg->PointerLength;
3494 pStubMsg->PointerLength = 0;
3499 /***********************************************************************
3500 * NdrComplexStructMemorySize [RPCRT4.@]
3502 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3503 PFORMAT_STRING pFormat)
3505 unsigned size = *(const WORD*)(pFormat+2);
3506 PFORMAT_STRING conf_array = NULL;
3507 PFORMAT_STRING pointer_desc = NULL;
3509 ULONG max_count = 0;
3512 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3514 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3517 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3519 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3524 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3526 /* these could be changed in ComplexStructMemorySize so save them for
3528 max_count = pStubMsg->MaxCount;
3529 count = pStubMsg->ActualCount;
3530 offset = pStubMsg->Offset;
3533 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3537 pStubMsg->MaxCount = max_count;
3538 pStubMsg->ActualCount = count;
3539 pStubMsg->Offset = offset;
3540 array_memory_size(conf_array[0], pStubMsg, conf_array,
3541 TRUE /* fHasPointers */);
3547 /***********************************************************************
3548 * NdrComplexStructFree [RPCRT4.@]
3550 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3551 unsigned char *pMemory,
3552 PFORMAT_STRING pFormat)
3554 PFORMAT_STRING conf_array = NULL;
3555 PFORMAT_STRING pointer_desc = NULL;
3556 unsigned char *OldMemory = pStubMsg->Memory;
3558 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3561 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3563 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3566 pStubMsg->Memory = pMemory;
3568 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3571 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3572 TRUE /* fHasPointers */);
3574 pStubMsg->Memory = OldMemory;
3577 /***********************************************************************
3578 * NdrConformantArrayMarshall [RPCRT4.@]
3580 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3581 unsigned char *pMemory,
3582 PFORMAT_STRING pFormat)
3584 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3585 if (pFormat[0] != RPC_FC_CARRAY)
3587 ERR("invalid format = 0x%x\n", pFormat[0]);
3588 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3591 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory,
3593 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3594 TRUE /* fHasPointers */);
3599 /***********************************************************************
3600 * NdrConformantArrayUnmarshall [RPCRT4.@]
3602 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3603 unsigned char **ppMemory,
3604 PFORMAT_STRING pFormat,
3605 unsigned char fMustAlloc)
3607 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3608 if (pFormat[0] != RPC_FC_CARRAY)
3610 ERR("invalid format = 0x%x\n", pFormat[0]);
3611 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3614 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3615 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat,
3617 TRUE /* fUseBufferMemoryServer */,
3618 TRUE /* fUnmarshall */);
3623 /***********************************************************************
3624 * NdrConformantArrayBufferSize [RPCRT4.@]
3626 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3627 unsigned char *pMemory,
3628 PFORMAT_STRING pFormat)
3630 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3631 if (pFormat[0] != RPC_FC_CARRAY)
3633 ERR("invalid format = 0x%x\n", pFormat[0]);
3634 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3637 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat);
3638 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3639 TRUE /* fHasPointers */);
3642 /***********************************************************************
3643 * NdrConformantArrayMemorySize [RPCRT4.@]
3645 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3646 PFORMAT_STRING pFormat)
3648 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3649 if (pFormat[0] != RPC_FC_CARRAY)
3651 ERR("invalid format = 0x%x\n", pFormat[0]);
3652 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3655 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3656 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
3658 return pStubMsg->MemorySize;
3661 /***********************************************************************
3662 * NdrConformantArrayFree [RPCRT4.@]
3664 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3665 unsigned char *pMemory,
3666 PFORMAT_STRING pFormat)
3668 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3669 if (pFormat[0] != RPC_FC_CARRAY)
3671 ERR("invalid format = 0x%x\n", pFormat[0]);
3672 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3675 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3676 TRUE /* fHasPointers */);
3680 /***********************************************************************
3681 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3683 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
3684 unsigned char* pMemory,
3685 PFORMAT_STRING pFormat )
3687 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3689 if (pFormat[0] != RPC_FC_CVARRAY)
3691 ERR("invalid format type %x\n", pFormat[0]);
3692 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3696 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3698 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory,
3699 pFormat, TRUE /* fHasPointers */);
3705 /***********************************************************************
3706 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3708 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
3709 unsigned char** ppMemory,
3710 PFORMAT_STRING pFormat,
3711 unsigned char fMustAlloc )
3713 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3715 if (pFormat[0] != RPC_FC_CVARRAY)
3717 ERR("invalid format type %x\n", pFormat[0]);
3718 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3722 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3723 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory,
3724 pFormat, fMustAlloc,
3725 TRUE /* fUseBufferMemoryServer */,
3726 TRUE /* fUnmarshall */);
3732 /***********************************************************************
3733 * NdrConformantVaryingArrayFree [RPCRT4.@]
3735 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
3736 unsigned char* pMemory,
3737 PFORMAT_STRING pFormat )
3739 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3741 if (pFormat[0] != RPC_FC_CVARRAY)
3743 ERR("invalid format type %x\n", pFormat[0]);
3744 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3748 array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3749 TRUE /* fHasPointers */);
3753 /***********************************************************************
3754 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3756 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
3757 unsigned char* pMemory, PFORMAT_STRING pFormat )
3759 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3761 if (pFormat[0] != RPC_FC_CVARRAY)
3763 ERR("invalid format type %x\n", pFormat[0]);
3764 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3768 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3770 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3771 TRUE /* fHasPointers */);
3775 /***********************************************************************
3776 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3778 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
3779 PFORMAT_STRING pFormat )
3781 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3783 if (pFormat[0] != RPC_FC_CVARRAY)
3785 ERR("invalid format type %x\n", pFormat[0]);
3786 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3787 return pStubMsg->MemorySize;
3790 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3791 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat,
3792 TRUE /* fHasPointers */);
3794 return pStubMsg->MemorySize;
3798 /***********************************************************************
3799 * NdrComplexArrayMarshall [RPCRT4.@]
3801 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3802 unsigned char *pMemory,
3803 PFORMAT_STRING pFormat)
3805 ULONG i, count, def;
3806 BOOL variance_present;
3807 unsigned char alignment;
3808 int pointer_buffer_mark_set = 0;
3810 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3812 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3814 ERR("invalid format type %x\n", pFormat[0]);
3815 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3819 alignment = pFormat[1] + 1;
3821 if (!pStubMsg->PointerBufferMark)
3823 /* save buffer fields that may be changed by buffer sizer functions
3824 * and that may be needed later on */
3825 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3826 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3827 unsigned long saved_max_count = pStubMsg->MaxCount;
3828 unsigned long saved_offset = pStubMsg->Offset;
3829 unsigned long saved_actual_count = pStubMsg->ActualCount;
3831 /* get the buffer pointer after complex array data, but before
3833 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3834 pStubMsg->IgnoreEmbeddedPointers = 1;
3835 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3836 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3838 /* save it for use by embedded pointer code later */
3839 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3840 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
3841 pointer_buffer_mark_set = 1;
3843 /* restore fields */
3844 pStubMsg->ActualCount = saved_actual_count;
3845 pStubMsg->Offset = saved_offset;
3846 pStubMsg->MaxCount = saved_max_count;
3847 pStubMsg->BufferLength = saved_buffer_length;
3850 def = *(const WORD*)&pFormat[2];
3853 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3854 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3856 variance_present = IsConformanceOrVariancePresent(pFormat);
3857 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3858 TRACE("variance = %d\n", pStubMsg->ActualCount);
3860 WriteConformance(pStubMsg);
3861 if (variance_present)
3862 WriteVariance(pStubMsg);
3864 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3866 count = pStubMsg->ActualCount;
3867 for (i = 0; i < count; i++)
3868 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3870 STD_OVERFLOW_CHECK(pStubMsg);
3872 if (pointer_buffer_mark_set)
3874 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3875 pStubMsg->PointerBufferMark = NULL;
3881 /***********************************************************************
3882 * NdrComplexArrayUnmarshall [RPCRT4.@]
3884 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3885 unsigned char **ppMemory,
3886 PFORMAT_STRING pFormat,
3887 unsigned char fMustAlloc)
3889 ULONG i, count, size;
3890 unsigned char alignment;
3891 unsigned char *pMemory;
3892 unsigned char *saved_buffer;
3893 int pointer_buffer_mark_set = 0;
3894 int saved_ignore_embedded;
3896 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3898 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3900 ERR("invalid format type %x\n", pFormat[0]);
3901 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3905 alignment = pFormat[1] + 1;
3907 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3908 /* save buffer pointer */
3909 saved_buffer = pStubMsg->Buffer;
3910 /* get the buffer pointer after complex array data, but before
3912 pStubMsg->IgnoreEmbeddedPointers = 1;
3913 pStubMsg->MemorySize = 0;
3914 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3915 size = pStubMsg->MemorySize;
3916 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3918 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
3919 if (!pStubMsg->PointerBufferMark)
3921 /* save it for use by embedded pointer code later */
3922 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3923 pointer_buffer_mark_set = 1;
3925 /* restore the original buffer */
3926 pStubMsg->Buffer = saved_buffer;
3930 pFormat = ReadConformance(pStubMsg, pFormat);
3931 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3933 if (!fMustAlloc && !*ppMemory)
3936 *ppMemory = NdrAllocate(pStubMsg, size);
3938 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3940 pMemory = *ppMemory;
3941 count = pStubMsg->ActualCount;
3942 for (i = 0; i < count; i++)
3943 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
3945 if (pointer_buffer_mark_set)
3947 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3948 pStubMsg->PointerBufferMark = NULL;
3954 /***********************************************************************
3955 * NdrComplexArrayBufferSize [RPCRT4.@]
3957 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3958 unsigned char *pMemory,
3959 PFORMAT_STRING pFormat)
3961 ULONG i, count, def;
3962 unsigned char alignment;
3963 BOOL variance_present;
3964 int pointer_length_set = 0;
3966 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3968 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3970 ERR("invalid format type %x\n", pFormat[0]);
3971 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3975 alignment = pFormat[1] + 1;
3977 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3979 /* save buffer fields that may be changed by buffer sizer functions
3980 * and that may be needed later on */
3981 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3982 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3983 unsigned long saved_max_count = pStubMsg->MaxCount;
3984 unsigned long saved_offset = pStubMsg->Offset;
3985 unsigned long saved_actual_count = pStubMsg->ActualCount;
3987 /* get the buffer pointer after complex array data, but before
3989 pStubMsg->IgnoreEmbeddedPointers = 1;
3990 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3991 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3993 /* save it for use by embedded pointer code later */
3994 pStubMsg->PointerLength = pStubMsg->BufferLength;
3995 pointer_length_set = 1;
3997 /* restore fields */
3998 pStubMsg->ActualCount = saved_actual_count;
3999 pStubMsg->Offset = saved_offset;
4000 pStubMsg->MaxCount = saved_max_count;
4001 pStubMsg->BufferLength = saved_buffer_length;
4003 def = *(const WORD*)&pFormat[2];
4006 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4007 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4008 SizeConformance(pStubMsg);
4010 variance_present = IsConformanceOrVariancePresent(pFormat);
4011 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4012 TRACE("variance = %d\n", pStubMsg->ActualCount);
4014 if (variance_present)
4015 SizeVariance(pStubMsg);
4017 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4019 count = pStubMsg->ActualCount;
4020 for (i = 0; i < count; i++)
4021 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
4023 if(pointer_length_set)
4025 pStubMsg->BufferLength = pStubMsg->PointerLength;
4026 pStubMsg->PointerLength = 0;
4030 /***********************************************************************
4031 * NdrComplexArrayMemorySize [RPCRT4.@]
4033 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4034 PFORMAT_STRING pFormat)
4036 ULONG i, count, esize, SavedMemorySize, MemorySize;
4037 unsigned char alignment;
4039 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4041 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4043 ERR("invalid format type %x\n", pFormat[0]);
4044 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4048 alignment = pFormat[1] + 1;
4052 pFormat = ReadConformance(pStubMsg, pFormat);
4053 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
4055 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4057 SavedMemorySize = pStubMsg->MemorySize;
4059 esize = ComplexStructSize(pStubMsg, pFormat);
4061 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
4063 count = pStubMsg->ActualCount;
4064 for (i = 0; i < count; i++)
4065 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
4067 pStubMsg->MemorySize = SavedMemorySize;
4069 pStubMsg->MemorySize += MemorySize;
4073 /***********************************************************************
4074 * NdrComplexArrayFree [RPCRT4.@]
4076 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4077 unsigned char *pMemory,
4078 PFORMAT_STRING pFormat)
4080 ULONG i, count, def;
4082 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4084 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4086 ERR("invalid format type %x\n", pFormat[0]);
4087 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4091 def = *(const WORD*)&pFormat[2];
4094 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4095 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4097 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4098 TRACE("variance = %d\n", pStubMsg->ActualCount);
4100 count = pStubMsg->ActualCount;
4101 for (i = 0; i < count; i++)
4102 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4105 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4106 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4107 USER_MARSHAL_CB *umcb)
4109 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4110 pStubMsg->RpcMsg->DataRepresentation);
4111 umcb->pStubMsg = pStubMsg;
4112 umcb->pReserve = NULL;
4113 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4114 umcb->CBType = cbtype;
4115 umcb->pFormat = pFormat;
4116 umcb->pTypeFormat = NULL /* FIXME */;
4119 #define USER_MARSHAL_PTR_PREFIX \
4120 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4121 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4123 /***********************************************************************
4124 * NdrUserMarshalMarshall [RPCRT4.@]
4126 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4127 unsigned char *pMemory,
4128 PFORMAT_STRING pFormat)
4130 unsigned flags = pFormat[1];
4131 unsigned index = *(const WORD*)&pFormat[2];
4132 unsigned char *saved_buffer = NULL;
4133 USER_MARSHAL_CB umcb;
4135 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4136 TRACE("index=%d\n", index);
4138 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4140 if (flags & USER_MARSHAL_POINTER)
4142 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
4143 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4144 pStubMsg->Buffer += 4;
4145 if (pStubMsg->PointerBufferMark)
4147 saved_buffer = pStubMsg->Buffer;
4148 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4149 pStubMsg->PointerBufferMark = NULL;
4151 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
4154 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
4157 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4158 &umcb.Flags, pStubMsg->Buffer, pMemory);
4162 STD_OVERFLOW_CHECK(pStubMsg);
4163 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4164 pStubMsg->Buffer = saved_buffer;
4167 STD_OVERFLOW_CHECK(pStubMsg);
4172 /***********************************************************************
4173 * NdrUserMarshalUnmarshall [RPCRT4.@]
4175 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4176 unsigned char **ppMemory,
4177 PFORMAT_STRING pFormat,
4178 unsigned char fMustAlloc)
4180 unsigned flags = pFormat[1];
4181 unsigned index = *(const WORD*)&pFormat[2];
4182 DWORD memsize = *(const WORD*)&pFormat[4];
4183 unsigned char *saved_buffer = NULL;
4184 USER_MARSHAL_CB umcb;
4186 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4187 TRACE("index=%d\n", index);
4189 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4191 if (flags & USER_MARSHAL_POINTER)
4193 ALIGN_POINTER(pStubMsg->Buffer, 4);
4194 /* skip pointer prefix */
4195 pStubMsg->Buffer += 4;
4196 if (pStubMsg->PointerBufferMark)
4198 saved_buffer = pStubMsg->Buffer;
4199 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4200 pStubMsg->PointerBufferMark = NULL;
4202 ALIGN_POINTER(pStubMsg->Buffer, 8);
4205 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4207 if (!fMustAlloc && !*ppMemory)
4211 *ppMemory = NdrAllocate(pStubMsg, memsize);
4212 memset(*ppMemory, 0, memsize);
4216 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4217 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4221 STD_OVERFLOW_CHECK(pStubMsg);
4222 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4223 pStubMsg->Buffer = saved_buffer;
4229 /***********************************************************************
4230 * NdrUserMarshalBufferSize [RPCRT4.@]
4232 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4233 unsigned char *pMemory,
4234 PFORMAT_STRING pFormat)
4236 unsigned flags = pFormat[1];
4237 unsigned index = *(const WORD*)&pFormat[2];
4238 DWORD bufsize = *(const WORD*)&pFormat[6];
4239 USER_MARSHAL_CB umcb;
4240 unsigned long saved_buffer_length = 0;
4242 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4243 TRACE("index=%d\n", index);
4245 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4247 if (flags & USER_MARSHAL_POINTER)
4249 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4250 /* skip pointer prefix */
4251 safe_buffer_length_increment(pStubMsg, 4);
4252 if (pStubMsg->IgnoreEmbeddedPointers)
4254 if (pStubMsg->PointerLength)
4256 saved_buffer_length = pStubMsg->BufferLength;
4257 pStubMsg->BufferLength = pStubMsg->PointerLength;
4258 pStubMsg->PointerLength = 0;
4260 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
4263 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
4266 TRACE("size=%d\n", bufsize);
4267 safe_buffer_length_increment(pStubMsg, bufsize);
4270 pStubMsg->BufferLength =
4271 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4272 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4274 if (saved_buffer_length)
4276 pStubMsg->PointerLength = pStubMsg->BufferLength;
4277 pStubMsg->BufferLength = saved_buffer_length;
4282 /***********************************************************************
4283 * NdrUserMarshalMemorySize [RPCRT4.@]
4285 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4286 PFORMAT_STRING pFormat)
4288 unsigned flags = pFormat[1];
4289 unsigned index = *(const WORD*)&pFormat[2];
4290 DWORD memsize = *(const WORD*)&pFormat[4];
4291 DWORD bufsize = *(const WORD*)&pFormat[6];
4293 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4294 TRACE("index=%d\n", index);
4296 pStubMsg->MemorySize += memsize;
4298 if (flags & USER_MARSHAL_POINTER)
4300 ALIGN_POINTER(pStubMsg->Buffer, 4);
4301 /* skip pointer prefix */
4302 pStubMsg->Buffer += 4;
4303 if (pStubMsg->IgnoreEmbeddedPointers)
4304 return pStubMsg->MemorySize;
4305 ALIGN_POINTER(pStubMsg->Buffer, 8);
4308 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4311 FIXME("not implemented for varying buffer size\n");
4313 pStubMsg->Buffer += bufsize;
4315 return pStubMsg->MemorySize;
4318 /***********************************************************************
4319 * NdrUserMarshalFree [RPCRT4.@]
4321 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4322 unsigned char *pMemory,
4323 PFORMAT_STRING pFormat)
4325 /* unsigned flags = pFormat[1]; */
4326 unsigned index = *(const WORD*)&pFormat[2];
4327 USER_MARSHAL_CB umcb;
4329 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4330 TRACE("index=%d\n", index);
4332 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4334 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4335 &umcb.Flags, pMemory);
4338 /***********************************************************************
4339 * NdrGetUserMarshalInfo [RPCRT4.@]
4341 RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi)
4343 USER_MARSHAL_CB *umcb = CONTAINING_RECORD(flags, USER_MARSHAL_CB, Flags);
4345 TRACE("(%p,%u,%p)\n", flags, level, umi);
4348 return RPC_S_INVALID_ARG;
4350 memset(&umi->Level1, 0, sizeof(umi->Level1));
4351 umi->InformationLevel = level;
4353 if (umcb->Signature != USER_MARSHAL_CB_SIGNATURE)
4354 return RPC_S_INVALID_ARG;
4356 umi->Level1.pfnAllocate = umcb->pStubMsg->pfnAllocate;
4357 umi->Level1.pfnFree = umcb->pStubMsg->pfnFree;
4358 umi->Level1.pRpcChannelBuffer = umcb->pStubMsg->pRpcChannelBuffer;
4360 switch (umcb->CBType)
4362 case USER_MARSHAL_CB_MARSHALL:
4363 case USER_MARSHAL_CB_UNMARSHALL:
4365 RPC_MESSAGE *msg = umcb->pStubMsg->RpcMsg;
4366 unsigned char *buffer_start = msg->Buffer;
4367 unsigned char *buffer_end =
4368 (unsigned char *)msg->Buffer + msg->BufferLength;
4370 if (umcb->pStubMsg->Buffer < buffer_start ||
4371 umcb->pStubMsg->Buffer > buffer_end)
4372 return ERROR_INVALID_USER_BUFFER;
4374 umi->Level1.Buffer = umcb->pStubMsg->Buffer;
4375 umi->Level1.BufferSize = buffer_end - umcb->pStubMsg->Buffer;
4378 case USER_MARSHAL_CB_BUFFER_SIZE:
4379 case USER_MARSHAL_CB_FREE:
4382 WARN("unrecognised CBType %d\n", umcb->CBType);
4388 /***********************************************************************
4389 * NdrClearOutParameters [RPCRT4.@]
4391 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4392 PFORMAT_STRING pFormat,
4395 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4398 /***********************************************************************
4399 * NdrConvert [RPCRT4.@]
4401 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4403 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4404 /* FIXME: since this stub doesn't do any converting, the proper behavior
4405 is to raise an exception */
4408 /***********************************************************************
4409 * NdrConvert2 [RPCRT4.@]
4411 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4413 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4414 pStubMsg, pFormat, NumberParams);
4415 /* FIXME: since this stub doesn't do any converting, the proper behavior
4416 is to raise an exception */
4419 #include "pshpack1.h"
4420 typedef struct _NDR_CSTRUCT_FORMAT
4423 unsigned char alignment;
4424 unsigned short memory_size;
4425 short offset_to_array_description;
4426 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4427 #include "poppack.h"
4429 /***********************************************************************
4430 * NdrConformantStructMarshall [RPCRT4.@]
4432 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4433 unsigned char *pMemory,
4434 PFORMAT_STRING pFormat)
4436 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4437 PFORMAT_STRING pCArrayFormat;
4438 ULONG esize, bufsize;
4440 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4442 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4443 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4445 ERR("invalid format type %x\n", pCStructFormat->type);
4446 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4450 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4451 pCStructFormat->offset_to_array_description;
4452 if (*pCArrayFormat != RPC_FC_CARRAY)
4454 ERR("invalid array format type %x\n", pCStructFormat->type);
4455 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4458 esize = *(const WORD*)(pCArrayFormat+2);
4460 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4461 pCArrayFormat + 4, 0);
4463 WriteConformance(pStubMsg);
4465 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4467 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4469 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4470 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4472 ERR("integer overflow of memory_size %u with bufsize %u\n",
4473 pCStructFormat->memory_size, bufsize);
4474 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4476 /* copy constant sized part of struct */
4477 pStubMsg->BufferMark = pStubMsg->Buffer;
4478 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4480 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4481 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4486 /***********************************************************************
4487 * NdrConformantStructUnmarshall [RPCRT4.@]
4489 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4490 unsigned char **ppMemory,
4491 PFORMAT_STRING pFormat,
4492 unsigned char fMustAlloc)
4494 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4495 PFORMAT_STRING pCArrayFormat;
4496 ULONG esize, bufsize;
4497 unsigned char *saved_buffer;
4499 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4501 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4502 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4504 ERR("invalid format type %x\n", pCStructFormat->type);
4505 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4508 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4509 pCStructFormat->offset_to_array_description;
4510 if (*pCArrayFormat != RPC_FC_CARRAY)
4512 ERR("invalid array format type %x\n", pCStructFormat->type);
4513 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4516 esize = *(const WORD*)(pCArrayFormat+2);
4518 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4520 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4522 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4524 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4525 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4527 ERR("integer overflow of memory_size %u with bufsize %u\n",
4528 pCStructFormat->memory_size, bufsize);
4529 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4534 SIZE_T size = pCStructFormat->memory_size + bufsize;
4535 *ppMemory = NdrAllocate(pStubMsg, size);
4539 if (!pStubMsg->IsClient && !*ppMemory)
4540 /* for servers, we just point straight into the RPC buffer */
4541 *ppMemory = pStubMsg->Buffer;
4544 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4545 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4546 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4547 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4549 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4550 if (*ppMemory != saved_buffer)
4551 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4556 /***********************************************************************
4557 * NdrConformantStructBufferSize [RPCRT4.@]
4559 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4560 unsigned char *pMemory,
4561 PFORMAT_STRING pFormat)
4563 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4564 PFORMAT_STRING pCArrayFormat;
4567 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4569 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4570 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4572 ERR("invalid format type %x\n", pCStructFormat->type);
4573 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4576 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4577 pCStructFormat->offset_to_array_description;
4578 if (*pCArrayFormat != RPC_FC_CARRAY)
4580 ERR("invalid array format type %x\n", pCStructFormat->type);
4581 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4584 esize = *(const WORD*)(pCArrayFormat+2);
4586 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4587 SizeConformance(pStubMsg);
4589 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4591 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4593 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4594 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4596 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4597 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4600 /***********************************************************************
4601 * NdrConformantStructMemorySize [RPCRT4.@]
4603 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4604 PFORMAT_STRING pFormat)
4610 /***********************************************************************
4611 * NdrConformantStructFree [RPCRT4.@]
4613 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4614 unsigned char *pMemory,
4615 PFORMAT_STRING pFormat)
4617 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4618 PFORMAT_STRING pCArrayFormat;
4620 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4622 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4623 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4625 ERR("invalid format type %x\n", pCStructFormat->type);
4626 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4630 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4631 pCStructFormat->offset_to_array_description;
4632 if (*pCArrayFormat != RPC_FC_CARRAY)
4634 ERR("invalid array format type %x\n", pCStructFormat->type);
4635 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4639 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4640 pCArrayFormat + 4, 0);
4642 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4644 /* copy constant sized part of struct */
4645 pStubMsg->BufferMark = pStubMsg->Buffer;
4647 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4648 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4651 /***********************************************************************
4652 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4654 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4655 unsigned char *pMemory,
4656 PFORMAT_STRING pFormat)
4658 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4659 PFORMAT_STRING pCVArrayFormat;
4661 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4663 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4664 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4666 ERR("invalid format type %x\n", pCVStructFormat->type);
4667 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4671 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4672 pCVStructFormat->offset_to_array_description;
4674 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4675 pMemory + pCVStructFormat->memory_size,
4678 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4680 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4682 /* write constant sized part */
4683 pStubMsg->BufferMark = pStubMsg->Buffer;
4684 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4686 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4687 pMemory + pCVStructFormat->memory_size,
4688 pCVArrayFormat, FALSE /* fHasPointers */);
4690 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4695 /***********************************************************************
4696 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4698 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4699 unsigned char **ppMemory,
4700 PFORMAT_STRING pFormat,
4701 unsigned char fMustAlloc)
4703 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4704 PFORMAT_STRING pCVArrayFormat;
4705 ULONG memsize, bufsize;
4706 unsigned char *saved_buffer, *saved_array_buffer;
4708 unsigned char *array_memory;
4710 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4712 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4713 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4715 ERR("invalid format type %x\n", pCVStructFormat->type);
4716 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4720 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4721 pCVStructFormat->offset_to_array_description;
4723 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4726 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4728 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4730 /* work out how much memory to allocate if we need to do so */
4731 if (!fMustAlloc && !*ppMemory)
4735 SIZE_T size = pCVStructFormat->memory_size + memsize;
4736 *ppMemory = NdrAllocate(pStubMsg, size);
4739 /* mark the start of the constant data */
4740 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4741 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4743 array_memory = *ppMemory + pCVStructFormat->memory_size;
4744 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
4745 &array_memory, pCVArrayFormat,
4746 FALSE /* fMustAlloc */,
4747 FALSE /* fUseServerBufferMemory */,
4748 FALSE /* fUnmarshall */);
4750 /* save offset in case unmarshalling pointers changes it */
4751 offset = pStubMsg->Offset;
4753 /* mark the start of the array data */
4754 saved_array_buffer = pStubMsg->Buffer;
4755 safe_buffer_increment(pStubMsg, bufsize);
4757 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4759 /* copy the constant data */
4760 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
4761 /* copy the array data */
4762 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
4763 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
4764 saved_array_buffer, bufsize);
4766 if (*pCVArrayFormat == RPC_FC_C_CSTRING)
4767 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
4768 else if (*pCVArrayFormat == RPC_FC_C_WSTRING)
4769 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
4774 /***********************************************************************
4775 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4777 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4778 unsigned char *pMemory,
4779 PFORMAT_STRING pFormat)
4781 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4782 PFORMAT_STRING pCVArrayFormat;
4784 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4786 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4787 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4789 ERR("invalid format type %x\n", pCVStructFormat->type);
4790 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4794 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4795 pCVStructFormat->offset_to_array_description;
4796 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
4797 pMemory + pCVStructFormat->memory_size,
4800 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4802 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4804 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4806 array_buffer_size(*pCVArrayFormat, pStubMsg,
4807 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4808 FALSE /* fHasPointers */);
4810 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4813 /***********************************************************************
4814 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4816 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4817 PFORMAT_STRING pFormat)
4819 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4820 PFORMAT_STRING pCVArrayFormat;
4822 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4824 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4825 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4827 ERR("invalid format type %x\n", pCVStructFormat->type);
4828 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4832 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4833 pCVStructFormat->offset_to_array_description;
4834 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
4836 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4838 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4840 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4841 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
4842 FALSE /* fHasPointers */);
4844 pStubMsg->MemorySize += pCVStructFormat->memory_size;
4846 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4848 return pStubMsg->MemorySize;
4851 /***********************************************************************
4852 * NdrConformantVaryingStructFree [RPCRT4.@]
4854 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4855 unsigned char *pMemory,
4856 PFORMAT_STRING pFormat)
4858 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4859 PFORMAT_STRING pCVArrayFormat;
4861 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4863 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4864 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4866 ERR("invalid format type %x\n", pCVStructFormat->type);
4867 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4871 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4872 pCVStructFormat->offset_to_array_description;
4873 array_free(*pCVArrayFormat, pStubMsg,
4874 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4875 FALSE /* fHasPointers */);
4877 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4879 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4882 #include "pshpack1.h"
4886 unsigned char alignment;
4887 unsigned short total_size;
4888 } NDR_SMFARRAY_FORMAT;
4893 unsigned char alignment;
4894 unsigned long total_size;
4895 } NDR_LGFARRAY_FORMAT;
4896 #include "poppack.h"
4898 /***********************************************************************
4899 * NdrFixedArrayMarshall [RPCRT4.@]
4901 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4902 unsigned char *pMemory,
4903 PFORMAT_STRING pFormat)
4905 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4906 unsigned long total_size;
4908 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4910 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4911 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4913 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4914 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4918 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4920 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4922 total_size = pSmFArrayFormat->total_size;
4923 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4927 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4928 total_size = pLgFArrayFormat->total_size;
4929 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4932 pStubMsg->BufferMark = pStubMsg->Buffer;
4933 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4935 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4940 /***********************************************************************
4941 * NdrFixedArrayUnmarshall [RPCRT4.@]
4943 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4944 unsigned char **ppMemory,
4945 PFORMAT_STRING pFormat,
4946 unsigned char fMustAlloc)
4948 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4949 unsigned long total_size;
4950 unsigned char *saved_buffer;
4952 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4954 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4955 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4957 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4958 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4962 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4964 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4966 total_size = pSmFArrayFormat->total_size;
4967 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4971 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4972 total_size = pLgFArrayFormat->total_size;
4973 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4977 *ppMemory = NdrAllocate(pStubMsg, total_size);
4980 if (!pStubMsg->IsClient && !*ppMemory)
4981 /* for servers, we just point straight into the RPC buffer */
4982 *ppMemory = pStubMsg->Buffer;
4985 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4986 safe_buffer_increment(pStubMsg, total_size);
4987 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4989 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4990 if (*ppMemory != saved_buffer)
4991 memcpy(*ppMemory, saved_buffer, total_size);
4996 /***********************************************************************
4997 * NdrFixedArrayBufferSize [RPCRT4.@]
4999 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5000 unsigned char *pMemory,
5001 PFORMAT_STRING pFormat)
5003 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5004 unsigned long total_size;
5006 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5008 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5009 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5011 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5012 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5016 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
5018 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5020 total_size = pSmFArrayFormat->total_size;
5021 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5025 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5026 total_size = pLgFArrayFormat->total_size;
5027 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5029 safe_buffer_length_increment(pStubMsg, total_size);
5031 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5034 /***********************************************************************
5035 * NdrFixedArrayMemorySize [RPCRT4.@]
5037 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5038 PFORMAT_STRING pFormat)
5040 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5043 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5045 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5046 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5048 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5049 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5053 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5055 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5057 total_size = pSmFArrayFormat->total_size;
5058 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5062 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5063 total_size = pLgFArrayFormat->total_size;
5064 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5066 pStubMsg->BufferMark = pStubMsg->Buffer;
5067 safe_buffer_increment(pStubMsg, total_size);
5068 pStubMsg->MemorySize += total_size;
5070 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5075 /***********************************************************************
5076 * NdrFixedArrayFree [RPCRT4.@]
5078 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5079 unsigned char *pMemory,
5080 PFORMAT_STRING pFormat)
5082 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5084 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5086 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5087 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5089 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5090 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5094 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5095 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5098 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5099 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5102 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5105 /***********************************************************************
5106 * NdrVaryingArrayMarshall [RPCRT4.@]
5108 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5109 unsigned char *pMemory,
5110 PFORMAT_STRING pFormat)
5112 unsigned char alignment;
5113 DWORD elements, esize;
5116 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5118 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5119 (pFormat[0] != RPC_FC_LGVARRAY))
5121 ERR("invalid format type %x\n", pFormat[0]);
5122 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5126 alignment = pFormat[1] + 1;
5128 if (pFormat[0] == RPC_FC_SMVARRAY)
5131 pFormat += sizeof(WORD);
5132 elements = *(const WORD*)pFormat;
5133 pFormat += sizeof(WORD);
5138 pFormat += sizeof(DWORD);
5139 elements = *(const DWORD*)pFormat;
5140 pFormat += sizeof(DWORD);
5143 esize = *(const WORD*)pFormat;
5144 pFormat += sizeof(WORD);
5146 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5147 if ((pStubMsg->ActualCount > elements) ||
5148 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5150 RpcRaiseException(RPC_S_INVALID_BOUND);
5154 WriteVariance(pStubMsg);
5156 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
5158 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5159 pStubMsg->BufferMark = pStubMsg->Buffer;
5160 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5162 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5167 /***********************************************************************
5168 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5170 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5171 unsigned char **ppMemory,
5172 PFORMAT_STRING pFormat,
5173 unsigned char fMustAlloc)
5175 unsigned char alignment;
5176 DWORD size, elements, esize;
5178 unsigned char *saved_buffer;
5181 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5183 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5184 (pFormat[0] != RPC_FC_LGVARRAY))
5186 ERR("invalid format type %x\n", pFormat[0]);
5187 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5191 alignment = pFormat[1] + 1;
5193 if (pFormat[0] == RPC_FC_SMVARRAY)
5196 size = *(const WORD*)pFormat;
5197 pFormat += sizeof(WORD);
5198 elements = *(const WORD*)pFormat;
5199 pFormat += sizeof(WORD);
5204 size = *(const DWORD*)pFormat;
5205 pFormat += sizeof(DWORD);
5206 elements = *(const DWORD*)pFormat;
5207 pFormat += sizeof(DWORD);
5210 esize = *(const WORD*)pFormat;
5211 pFormat += sizeof(WORD);
5213 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5215 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5217 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5218 offset = pStubMsg->Offset;
5220 if (!fMustAlloc && !*ppMemory)
5223 *ppMemory = NdrAllocate(pStubMsg, size);
5224 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5225 safe_buffer_increment(pStubMsg, bufsize);
5227 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5229 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5234 /***********************************************************************
5235 * NdrVaryingArrayBufferSize [RPCRT4.@]
5237 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5238 unsigned char *pMemory,
5239 PFORMAT_STRING pFormat)
5241 unsigned char alignment;
5242 DWORD elements, esize;
5244 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5246 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5247 (pFormat[0] != RPC_FC_LGVARRAY))
5249 ERR("invalid format type %x\n", pFormat[0]);
5250 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5254 alignment = pFormat[1] + 1;
5256 if (pFormat[0] == RPC_FC_SMVARRAY)
5259 pFormat += sizeof(WORD);
5260 elements = *(const WORD*)pFormat;
5261 pFormat += sizeof(WORD);
5266 pFormat += sizeof(DWORD);
5267 elements = *(const DWORD*)pFormat;
5268 pFormat += sizeof(DWORD);
5271 esize = *(const WORD*)pFormat;
5272 pFormat += sizeof(WORD);
5274 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5275 if ((pStubMsg->ActualCount > elements) ||
5276 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5278 RpcRaiseException(RPC_S_INVALID_BOUND);
5282 SizeVariance(pStubMsg);
5284 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
5286 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5288 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5291 /***********************************************************************
5292 * NdrVaryingArrayMemorySize [RPCRT4.@]
5294 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5295 PFORMAT_STRING pFormat)
5297 unsigned char alignment;
5298 DWORD size, elements, esize;
5300 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5302 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5303 (pFormat[0] != RPC_FC_LGVARRAY))
5305 ERR("invalid format type %x\n", pFormat[0]);
5306 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5310 alignment = pFormat[1] + 1;
5312 if (pFormat[0] == RPC_FC_SMVARRAY)
5315 size = *(const WORD*)pFormat;
5316 pFormat += sizeof(WORD);
5317 elements = *(const WORD*)pFormat;
5318 pFormat += sizeof(WORD);
5323 size = *(const DWORD*)pFormat;
5324 pFormat += sizeof(DWORD);
5325 elements = *(const DWORD*)pFormat;
5326 pFormat += sizeof(DWORD);
5329 esize = *(const WORD*)pFormat;
5330 pFormat += sizeof(WORD);
5332 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5334 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5336 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5337 pStubMsg->MemorySize += size;
5339 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5341 return pStubMsg->MemorySize;
5344 /***********************************************************************
5345 * NdrVaryingArrayFree [RPCRT4.@]
5347 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5348 unsigned char *pMemory,
5349 PFORMAT_STRING pFormat)
5353 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5355 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5356 (pFormat[0] != RPC_FC_LGVARRAY))
5358 ERR("invalid format type %x\n", pFormat[0]);
5359 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5363 if (pFormat[0] == RPC_FC_SMVARRAY)
5366 pFormat += sizeof(WORD);
5367 elements = *(const WORD*)pFormat;
5368 pFormat += sizeof(WORD);
5373 pFormat += sizeof(DWORD);
5374 elements = *(const DWORD*)pFormat;
5375 pFormat += sizeof(DWORD);
5378 pFormat += sizeof(WORD);
5380 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5381 if ((pStubMsg->ActualCount > elements) ||
5382 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5384 RpcRaiseException(RPC_S_INVALID_BOUND);
5388 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5391 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5404 return *(const USHORT *)pMemory;
5408 return *(const ULONG *)pMemory;
5410 FIXME("Unhandled base type: 0x%02x\n", fc);
5415 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5416 unsigned long discriminant,
5417 PFORMAT_STRING pFormat)
5419 unsigned short num_arms, arm, type;
5421 num_arms = *(const SHORT*)pFormat & 0x0fff;
5423 for(arm = 0; arm < num_arms; arm++)
5425 if(discriminant == *(const ULONG*)pFormat)
5433 type = *(const unsigned short*)pFormat;
5434 TRACE("type %04x\n", type);
5435 if(arm == num_arms) /* default arm extras */
5439 ERR("no arm for 0x%lx and no default case\n", discriminant);
5440 RpcRaiseException(RPC_S_INVALID_TAG);
5445 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
5452 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5454 unsigned short type;
5458 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5462 type = *(const unsigned short*)pFormat;
5463 if((type & 0xff00) == 0x8000)
5465 unsigned char basetype = LOBYTE(type);
5466 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5470 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5471 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5474 unsigned char *saved_buffer = NULL;
5475 int pointer_buffer_mark_set = 0;
5482 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5483 saved_buffer = pStubMsg->Buffer;
5484 if (pStubMsg->PointerBufferMark)
5486 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5487 pStubMsg->PointerBufferMark = NULL;
5488 pointer_buffer_mark_set = 1;
5491 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5493 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5494 if (pointer_buffer_mark_set)
5496 STD_OVERFLOW_CHECK(pStubMsg);
5497 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5498 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5500 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5501 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5502 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5504 pStubMsg->Buffer = saved_buffer + 4;
5508 m(pStubMsg, pMemory, desc);
5511 else FIXME("no marshaller for embedded type %02x\n", *desc);
5516 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5517 unsigned char **ppMemory,
5519 PFORMAT_STRING pFormat,
5520 unsigned char fMustAlloc)
5522 unsigned short type;
5526 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5530 type = *(const unsigned short*)pFormat;
5531 if((type & 0xff00) == 0x8000)
5533 unsigned char basetype = LOBYTE(type);
5534 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5538 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5539 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5542 unsigned char *saved_buffer = NULL;
5543 int pointer_buffer_mark_set = 0;
5550 **(void***)ppMemory = NULL;
5551 ALIGN_POINTER(pStubMsg->Buffer, 4);
5552 saved_buffer = pStubMsg->Buffer;
5553 if (pStubMsg->PointerBufferMark)
5555 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5556 pStubMsg->PointerBufferMark = NULL;
5557 pointer_buffer_mark_set = 1;
5560 pStubMsg->Buffer += 4; /* for pointer ID */
5562 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5564 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5565 saved_buffer, pStubMsg->BufferEnd);
5566 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5569 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5570 if (pointer_buffer_mark_set)
5572 STD_OVERFLOW_CHECK(pStubMsg);
5573 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5574 pStubMsg->Buffer = saved_buffer + 4;
5578 m(pStubMsg, ppMemory, desc, fMustAlloc);
5581 else FIXME("no marshaller for embedded type %02x\n", *desc);
5586 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5587 unsigned char *pMemory,
5589 PFORMAT_STRING pFormat)
5591 unsigned short type;
5595 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5599 type = *(const unsigned short*)pFormat;
5600 if((type & 0xff00) == 0x8000)
5602 unsigned char basetype = LOBYTE(type);
5603 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5607 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5608 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5617 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5618 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5619 if (!pStubMsg->IgnoreEmbeddedPointers)
5621 int saved_buffer_length = pStubMsg->BufferLength;
5622 pStubMsg->BufferLength = pStubMsg->PointerLength;
5623 pStubMsg->PointerLength = 0;
5624 if(!pStubMsg->BufferLength)
5625 ERR("BufferLength == 0??\n");
5626 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5627 pStubMsg->PointerLength = pStubMsg->BufferLength;
5628 pStubMsg->BufferLength = saved_buffer_length;
5632 m(pStubMsg, pMemory, desc);
5635 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5639 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5641 PFORMAT_STRING pFormat)
5643 unsigned short type, size;
5645 size = *(const unsigned short*)pFormat;
5646 pStubMsg->Memory += size;
5649 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5653 type = *(const unsigned short*)pFormat;
5654 if((type & 0xff00) == 0x8000)
5656 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5660 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5661 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5662 unsigned char *saved_buffer;
5671 ALIGN_POINTER(pStubMsg->Buffer, 4);
5672 saved_buffer = pStubMsg->Buffer;
5673 safe_buffer_increment(pStubMsg, 4);
5674 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
5675 pStubMsg->MemorySize += 4;
5676 if (!pStubMsg->IgnoreEmbeddedPointers)
5677 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5680 return m(pStubMsg, desc);
5683 else FIXME("no marshaller for embedded type %02x\n", *desc);
5686 TRACE("size %d\n", size);
5690 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5691 unsigned char *pMemory,
5693 PFORMAT_STRING pFormat)
5695 unsigned short type;
5699 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5703 type = *(const unsigned short*)pFormat;
5704 if((type & 0xff00) != 0x8000)
5706 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5707 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5716 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5719 m(pStubMsg, pMemory, desc);
5725 /***********************************************************************
5726 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5728 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5729 unsigned char *pMemory,
5730 PFORMAT_STRING pFormat)
5732 unsigned char switch_type;
5733 unsigned char increment;
5736 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5739 switch_type = *pFormat & 0xf;
5740 increment = (*pFormat & 0xf0) >> 4;
5743 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5745 switch_value = get_discriminant(switch_type, pMemory);
5746 TRACE("got switch value 0x%x\n", switch_value);
5748 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5749 pMemory += increment;
5751 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5754 /***********************************************************************
5755 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5757 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5758 unsigned char **ppMemory,
5759 PFORMAT_STRING pFormat,
5760 unsigned char fMustAlloc)
5762 unsigned char switch_type;
5763 unsigned char increment;
5765 unsigned short size;
5766 unsigned char *pMemoryArm;
5768 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5771 switch_type = *pFormat & 0xf;
5772 increment = (*pFormat & 0xf0) >> 4;
5775 ALIGN_POINTER(pStubMsg->Buffer, increment);
5776 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5777 TRACE("got switch value 0x%x\n", switch_value);
5779 size = *(const unsigned short*)pFormat + increment;
5780 if (!fMustAlloc && !*ppMemory)
5783 *ppMemory = NdrAllocate(pStubMsg, size);
5785 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5786 pMemoryArm = *ppMemory + increment;
5788 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
5791 /***********************************************************************
5792 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5794 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5795 unsigned char *pMemory,
5796 PFORMAT_STRING pFormat)
5798 unsigned char switch_type;
5799 unsigned char increment;
5802 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5805 switch_type = *pFormat & 0xf;
5806 increment = (*pFormat & 0xf0) >> 4;
5809 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5810 switch_value = get_discriminant(switch_type, pMemory);
5811 TRACE("got switch value 0x%x\n", switch_value);
5813 /* Add discriminant size */
5814 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5815 pMemory += increment;
5817 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5820 /***********************************************************************
5821 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5823 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5824 PFORMAT_STRING pFormat)
5826 unsigned char switch_type;
5827 unsigned char increment;
5830 switch_type = *pFormat & 0xf;
5831 increment = (*pFormat & 0xf0) >> 4;
5834 ALIGN_POINTER(pStubMsg->Buffer, increment);
5835 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5836 TRACE("got switch value 0x%x\n", switch_value);
5838 pStubMsg->Memory += increment;
5840 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5843 /***********************************************************************
5844 * NdrEncapsulatedUnionFree [RPCRT4.@]
5846 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5847 unsigned char *pMemory,
5848 PFORMAT_STRING pFormat)
5850 unsigned char switch_type;
5851 unsigned char increment;
5854 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5857 switch_type = *pFormat & 0xf;
5858 increment = (*pFormat & 0xf0) >> 4;
5861 switch_value = get_discriminant(switch_type, pMemory);
5862 TRACE("got switch value 0x%x\n", switch_value);
5864 pMemory += increment;
5866 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5869 /***********************************************************************
5870 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5872 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5873 unsigned char *pMemory,
5874 PFORMAT_STRING pFormat)
5876 unsigned char switch_type;
5878 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5881 switch_type = *pFormat;
5884 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5885 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5886 /* Marshall discriminant */
5887 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5889 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5892 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5893 PFORMAT_STRING *ppFormat)
5895 long discriminant = 0;
5905 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5914 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5915 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5923 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5924 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5929 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5933 if (pStubMsg->fHasNewCorrDesc)
5937 return discriminant;
5940 /**********************************************************************
5941 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5943 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5944 unsigned char **ppMemory,
5945 PFORMAT_STRING pFormat,
5946 unsigned char fMustAlloc)
5949 unsigned short size;
5951 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5954 /* Unmarshall discriminant */
5955 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5956 TRACE("unmarshalled discriminant %lx\n", discriminant);
5958 pFormat += *(const SHORT*)pFormat;
5960 size = *(const unsigned short*)pFormat;
5962 if (!fMustAlloc && !*ppMemory)
5965 *ppMemory = NdrAllocate(pStubMsg, size);
5967 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5970 /***********************************************************************
5971 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5973 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5974 unsigned char *pMemory,
5975 PFORMAT_STRING pFormat)
5977 unsigned char switch_type;
5979 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5982 switch_type = *pFormat;
5985 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5986 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5987 /* Add discriminant size */
5988 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5990 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5993 /***********************************************************************
5994 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5996 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5997 PFORMAT_STRING pFormat)
6002 /* Unmarshall discriminant */
6003 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6004 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
6006 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
6009 /***********************************************************************
6010 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6012 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6013 unsigned char *pMemory,
6014 PFORMAT_STRING pFormat)
6016 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6020 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6021 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6023 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6026 /***********************************************************************
6027 * NdrByteCountPointerMarshall [RPCRT4.@]
6029 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6030 unsigned char *pMemory,
6031 PFORMAT_STRING pFormat)
6037 /***********************************************************************
6038 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6040 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6041 unsigned char **ppMemory,
6042 PFORMAT_STRING pFormat,
6043 unsigned char fMustAlloc)
6049 /***********************************************************************
6050 * NdrByteCountPointerBufferSize [RPCRT4.@]
6052 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6053 unsigned char *pMemory,
6054 PFORMAT_STRING pFormat)
6059 /***********************************************************************
6060 * NdrByteCountPointerMemorySize [internal]
6062 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6063 PFORMAT_STRING pFormat)
6069 /***********************************************************************
6070 * NdrByteCountPointerFree [RPCRT4.@]
6072 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6073 unsigned char *pMemory,
6074 PFORMAT_STRING pFormat)
6079 /***********************************************************************
6080 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6082 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6083 unsigned char *pMemory,
6084 PFORMAT_STRING pFormat)
6090 /***********************************************************************
6091 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6093 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6094 unsigned char **ppMemory,
6095 PFORMAT_STRING pFormat,
6096 unsigned char fMustAlloc)
6102 /***********************************************************************
6103 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6105 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6106 unsigned char *pMemory,
6107 PFORMAT_STRING pFormat)
6112 /***********************************************************************
6113 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6115 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6116 PFORMAT_STRING pFormat)
6122 /***********************************************************************
6123 * NdrXmitOrRepAsFree [RPCRT4.@]
6125 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6126 unsigned char *pMemory,
6127 PFORMAT_STRING pFormat)
6132 /***********************************************************************
6133 * NdrRangeMarshall [internal]
6135 static unsigned char *WINAPI NdrRangeMarshall(
6136 PMIDL_STUB_MESSAGE pStubMsg,
6137 unsigned char *pMemory,
6138 PFORMAT_STRING pFormat)
6140 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6141 unsigned char base_type;
6143 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6145 if (pRange->type != RPC_FC_RANGE)
6147 ERR("invalid format type %x\n", pRange->type);
6148 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6152 base_type = pRange->flags_type & 0xf;
6154 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6157 /***********************************************************************
6158 * NdrRangeUnmarshall [RPCRT4.@]
6160 unsigned char *WINAPI NdrRangeUnmarshall(
6161 PMIDL_STUB_MESSAGE pStubMsg,
6162 unsigned char **ppMemory,
6163 PFORMAT_STRING pFormat,
6164 unsigned char fMustAlloc)
6166 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6167 unsigned char base_type;
6169 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6171 if (pRange->type != RPC_FC_RANGE)
6173 ERR("invalid format type %x\n", pRange->type);
6174 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6177 base_type = pRange->flags_type & 0xf;
6179 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6180 base_type, pRange->low_value, pRange->high_value);
6182 #define RANGE_UNMARSHALL(type, format_spec) \
6185 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6186 if (!fMustAlloc && !*ppMemory) \
6187 fMustAlloc = TRUE; \
6189 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6190 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
6192 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6193 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6194 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6196 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
6197 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
6199 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6200 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
6201 (type)pRange->high_value); \
6202 RpcRaiseException(RPC_S_INVALID_BOUND); \
6205 TRACE("*ppMemory: %p\n", *ppMemory); \
6206 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
6207 pStubMsg->Buffer += sizeof(type); \
6214 RANGE_UNMARSHALL(UCHAR, "%d");
6215 TRACE("value: 0x%02x\n", **ppMemory);
6219 RANGE_UNMARSHALL(CHAR, "%u");
6220 TRACE("value: 0x%02x\n", **ppMemory);
6222 case RPC_FC_WCHAR: /* FIXME: valid? */
6224 RANGE_UNMARSHALL(USHORT, "%u");
6225 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6228 RANGE_UNMARSHALL(SHORT, "%d");
6229 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6232 RANGE_UNMARSHALL(LONG, "%d");
6233 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6236 RANGE_UNMARSHALL(ULONG, "%u");
6237 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6241 FIXME("Unhandled enum type\n");
6243 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
6248 ERR("invalid range base type: 0x%02x\n", base_type);
6249 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6255 /***********************************************************************
6256 * NdrRangeBufferSize [internal]
6258 static void WINAPI NdrRangeBufferSize(
6259 PMIDL_STUB_MESSAGE pStubMsg,
6260 unsigned char *pMemory,
6261 PFORMAT_STRING pFormat)
6263 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6264 unsigned char base_type;
6266 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6268 if (pRange->type != RPC_FC_RANGE)
6270 ERR("invalid format type %x\n", pRange->type);
6271 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6273 base_type = pRange->flags_type & 0xf;
6275 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6278 /***********************************************************************
6279 * NdrRangeMemorySize [internal]
6281 static ULONG WINAPI NdrRangeMemorySize(
6282 PMIDL_STUB_MESSAGE pStubMsg,
6283 PFORMAT_STRING pFormat)
6285 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6286 unsigned char base_type;
6288 if (pRange->type != RPC_FC_RANGE)
6290 ERR("invalid format type %x\n", pRange->type);
6291 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6294 base_type = pRange->flags_type & 0xf;
6296 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6299 /***********************************************************************
6300 * NdrRangeFree [internal]
6302 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6303 unsigned char *pMemory,
6304 PFORMAT_STRING pFormat)
6306 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6311 /***********************************************************************
6312 * NdrBaseTypeMarshall [internal]
6314 static unsigned char *WINAPI NdrBaseTypeMarshall(
6315 PMIDL_STUB_MESSAGE pStubMsg,
6316 unsigned char *pMemory,
6317 PFORMAT_STRING pFormat)
6319 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6327 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6328 TRACE("value: 0x%02x\n", *pMemory);
6333 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6334 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6335 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6339 case RPC_FC_ERROR_STATUS_T:
6341 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
6342 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6343 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6346 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
6347 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6350 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
6351 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6354 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
6355 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6356 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6359 /* only 16-bits on the wire, so do a sanity check */
6360 if (*(UINT *)pMemory > SHRT_MAX)
6361 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6362 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6363 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6364 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6365 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
6366 pStubMsg->Buffer += sizeof(USHORT);
6367 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6372 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6375 /* FIXME: what is the correct return value? */
6379 /***********************************************************************
6380 * NdrBaseTypeUnmarshall [internal]
6382 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6383 PMIDL_STUB_MESSAGE pStubMsg,
6384 unsigned char **ppMemory,
6385 PFORMAT_STRING pFormat,
6386 unsigned char fMustAlloc)
6388 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6390 #define BASE_TYPE_UNMARSHALL(type) \
6391 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6392 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6394 *ppMemory = pStubMsg->Buffer; \
6395 TRACE("*ppMemory: %p\n", *ppMemory); \
6396 safe_buffer_increment(pStubMsg, sizeof(type)); \
6401 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6402 TRACE("*ppMemory: %p\n", *ppMemory); \
6403 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6412 BASE_TYPE_UNMARSHALL(UCHAR);
6413 TRACE("value: 0x%02x\n", **ppMemory);
6418 BASE_TYPE_UNMARSHALL(USHORT);
6419 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6423 case RPC_FC_ERROR_STATUS_T:
6425 BASE_TYPE_UNMARSHALL(ULONG);
6426 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6429 BASE_TYPE_UNMARSHALL(float);
6430 TRACE("value: %f\n", **(float **)ppMemory);
6433 BASE_TYPE_UNMARSHALL(double);
6434 TRACE("value: %f\n", **(double **)ppMemory);
6437 BASE_TYPE_UNMARSHALL(ULONGLONG);
6438 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6441 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6442 if (!fMustAlloc && !*ppMemory)
6445 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6446 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
6447 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6448 TRACE("*ppMemory: %p\n", *ppMemory);
6449 /* 16-bits on the wire, but int in memory */
6450 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
6451 pStubMsg->Buffer += sizeof(USHORT);
6452 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6457 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6459 #undef BASE_TYPE_UNMARSHALL
6461 /* FIXME: what is the correct return value? */
6466 /***********************************************************************
6467 * NdrBaseTypeBufferSize [internal]
6469 static void WINAPI NdrBaseTypeBufferSize(
6470 PMIDL_STUB_MESSAGE pStubMsg,
6471 unsigned char *pMemory,
6472 PFORMAT_STRING pFormat)
6474 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6482 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6488 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
6489 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6494 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
6495 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6498 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
6499 safe_buffer_length_increment(pStubMsg, sizeof(float));
6502 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
6503 safe_buffer_length_increment(pStubMsg, sizeof(double));
6506 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
6507 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6509 case RPC_FC_ERROR_STATUS_T:
6510 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
6511 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6516 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6520 /***********************************************************************
6521 * NdrBaseTypeMemorySize [internal]
6523 static ULONG WINAPI NdrBaseTypeMemorySize(
6524 PMIDL_STUB_MESSAGE pStubMsg,
6525 PFORMAT_STRING pFormat)
6527 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6535 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6536 pStubMsg->MemorySize += sizeof(UCHAR);
6537 return sizeof(UCHAR);
6541 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6542 pStubMsg->MemorySize += sizeof(USHORT);
6543 return sizeof(USHORT);
6547 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6548 pStubMsg->MemorySize += sizeof(ULONG);
6549 return sizeof(ULONG);
6551 safe_buffer_increment(pStubMsg, sizeof(float));
6552 pStubMsg->MemorySize += sizeof(float);
6553 return sizeof(float);
6555 safe_buffer_increment(pStubMsg, sizeof(double));
6556 pStubMsg->MemorySize += sizeof(double);
6557 return sizeof(double);
6559 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6560 pStubMsg->MemorySize += sizeof(ULONGLONG);
6561 return sizeof(ULONGLONG);
6562 case RPC_FC_ERROR_STATUS_T:
6563 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6564 pStubMsg->MemorySize += sizeof(error_status_t);
6565 return sizeof(error_status_t);
6567 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6568 pStubMsg->MemorySize += sizeof(UINT);
6569 return sizeof(UINT);
6571 pStubMsg->MemorySize += sizeof(void *);
6572 return sizeof(void *);
6574 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6579 /***********************************************************************
6580 * NdrBaseTypeFree [internal]
6582 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6583 unsigned char *pMemory,
6584 PFORMAT_STRING pFormat)
6586 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6591 /***********************************************************************
6592 * NdrContextHandleBufferSize [internal]
6594 static void WINAPI NdrContextHandleBufferSize(
6595 PMIDL_STUB_MESSAGE pStubMsg,
6596 unsigned char *pMemory,
6597 PFORMAT_STRING pFormat)
6599 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6601 if (*pFormat != RPC_FC_BIND_CONTEXT)
6603 ERR("invalid format type %x\n", *pFormat);
6604 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6606 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
6607 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6610 /***********************************************************************
6611 * NdrContextHandleMarshall [internal]
6613 static unsigned char *WINAPI NdrContextHandleMarshall(
6614 PMIDL_STUB_MESSAGE pStubMsg,
6615 unsigned char *pMemory,
6616 PFORMAT_STRING pFormat)
6618 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6620 if (*pFormat != RPC_FC_BIND_CONTEXT)
6622 ERR("invalid format type %x\n", *pFormat);
6623 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6625 TRACE("flags: 0x%02x\n", pFormat[1]);
6627 if (pFormat[1] & 0x80)
6628 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6630 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
6635 /***********************************************************************
6636 * NdrContextHandleUnmarshall [internal]
6638 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6639 PMIDL_STUB_MESSAGE pStubMsg,
6640 unsigned char **ppMemory,
6641 PFORMAT_STRING pFormat,
6642 unsigned char fMustAlloc)
6644 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6645 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6647 if (*pFormat != RPC_FC_BIND_CONTEXT)
6649 ERR("invalid format type %x\n", *pFormat);
6650 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6652 TRACE("flags: 0x%02x\n", pFormat[1]);
6654 /* [out]-only or [ret] param */
6655 if ((pFormat[1] & 0x60) == 0x20)
6656 **(NDR_CCONTEXT **)ppMemory = NULL;
6657 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6662 /***********************************************************************
6663 * NdrClientContextMarshall [RPCRT4.@]
6665 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6666 NDR_CCONTEXT ContextHandle,
6669 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
6671 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
6673 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6675 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6676 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6677 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6680 /* FIXME: what does fCheck do? */
6681 NDRCContextMarshall(ContextHandle,
6684 pStubMsg->Buffer += cbNDRContext;
6687 /***********************************************************************
6688 * NdrClientContextUnmarshall [RPCRT4.@]
6690 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6691 NDR_CCONTEXT * pContextHandle,
6692 RPC_BINDING_HANDLE BindHandle)
6694 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
6696 ALIGN_POINTER(pStubMsg->Buffer, 4);
6698 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
6699 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6701 NDRCContextUnmarshall(pContextHandle,
6704 pStubMsg->RpcMsg->DataRepresentation);
6706 pStubMsg->Buffer += cbNDRContext;
6709 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6710 NDR_SCONTEXT ContextHandle,
6711 NDR_RUNDOWN RundownRoutine )
6713 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
6715 ALIGN_POINTER(pStubMsg->Buffer, 4);
6717 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6719 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6720 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6721 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6724 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6725 pStubMsg->Buffer, RundownRoutine, NULL,
6726 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6727 pStubMsg->Buffer += cbNDRContext;
6730 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6732 NDR_SCONTEXT ContextHandle;
6734 TRACE("(%p)\n", pStubMsg);
6736 ALIGN_POINTER(pStubMsg->Buffer, 4);
6738 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6740 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6741 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6742 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6745 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6747 pStubMsg->RpcMsg->DataRepresentation,
6748 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6749 pStubMsg->Buffer += cbNDRContext;
6751 return ContextHandle;
6754 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6755 unsigned char* pMemory,
6756 PFORMAT_STRING pFormat)
6758 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6761 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6762 PFORMAT_STRING pFormat)
6764 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6765 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6767 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6769 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6770 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6771 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6772 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6773 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6775 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6776 if_id = &sif->InterfaceId;
6779 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
6780 pStubMsg->RpcMsg->DataRepresentation, if_id,
6784 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6785 NDR_SCONTEXT ContextHandle,
6786 NDR_RUNDOWN RundownRoutine,
6787 PFORMAT_STRING pFormat)
6789 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6790 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6792 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6794 ALIGN_POINTER(pStubMsg->Buffer, 4);
6796 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6798 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6799 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6800 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6803 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6804 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6805 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6806 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6807 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6809 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6810 if_id = &sif->InterfaceId;
6813 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6814 pStubMsg->Buffer, RundownRoutine, if_id, flags);
6815 pStubMsg->Buffer += cbNDRContext;
6818 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6819 PFORMAT_STRING pFormat)
6821 NDR_SCONTEXT ContextHandle;
6822 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6823 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6825 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6827 ALIGN_POINTER(pStubMsg->Buffer, 4);
6829 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6831 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6832 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6833 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6836 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6837 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6838 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6839 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6840 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6842 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6843 if_id = &sif->InterfaceId;
6846 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6848 pStubMsg->RpcMsg->DataRepresentation,
6850 pStubMsg->Buffer += cbNDRContext;
6852 return ContextHandle;
6855 /***********************************************************************
6856 * NdrCorrelationInitialize [RPCRT4.@]
6858 * Initializes correlation validity checking.
6861 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6862 * pMemory [I] Pointer to memory to use as a cache.
6863 * CacheSize [I] Size of the memory pointed to by pMemory.
6864 * Flags [I] Reserved. Set to zero.
6869 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
6871 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
6872 pStubMsg->fHasNewCorrDesc = TRUE;
6875 /***********************************************************************
6876 * NdrCorrelationPass [RPCRT4.@]
6878 * Performs correlation validity checking.
6881 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6886 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
6888 FIXME("(%p): stub\n", pStubMsg);
6891 /***********************************************************************
6892 * NdrCorrelationFree [RPCRT4.@]
6894 * Frees any resources used while unmarshalling parameters that need
6895 * correlation validity checking.
6898 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6903 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
6905 FIXME("(%p): stub\n", pStubMsg);