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 base type and user marshall functions
43 #include "wine/unicode.h"
44 #include "wine/rpcfc.h"
46 #include "wine/debug.h"
48 WINE_DEFAULT_DEBUG_CHANNEL(ole);
51 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
52 (*((UINT32 *)(pchar)) = (uint32))
54 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
55 (*((UINT32 *)(pchar)))
57 /* these would work for i386 too, but less efficient */
58 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
59 (*(pchar) = LOBYTE(LOWORD(uint32)), \
60 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
61 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
62 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
63 (uint32)) /* allow as r-value */
65 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
67 MAKEWORD(*(pchar), *((pchar)+1)), \
68 MAKEWORD(*((pchar)+2), *((pchar)+3))))
71 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
72 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
73 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
74 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
75 *(pchar) = HIBYTE(HIWORD(uint32)), \
76 (uint32)) /* allow as r-value */
78 #define BIG_ENDIAN_UINT32_READ(pchar) \
80 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
81 MAKEWORD(*((pchar)+1), *(pchar))))
83 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
84 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
85 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
86 # define NDR_LOCAL_UINT32_READ(pchar) \
87 BIG_ENDIAN_UINT32_READ(pchar)
89 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
90 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
91 # define NDR_LOCAL_UINT32_READ(pchar) \
92 LITTLE_ENDIAN_UINT32_READ(pchar)
95 /* _Align must be the desired alignment,
96 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
97 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
98 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
99 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
100 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
101 #define ALIGN_POINTER_CLEAR(_Ptr, _Align) \
103 memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \
104 ALIGN_POINTER(_Ptr, _Align); \
107 #define STD_OVERFLOW_CHECK(_Msg) do { \
108 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
109 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
110 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
113 #define NDR_TABLE_SIZE 128
114 #define NDR_TABLE_MASK 127
116 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
117 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
118 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
119 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
120 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
122 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
123 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
124 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
126 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
128 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
129 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
130 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
131 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
135 NdrPointerMarshall, NdrPointerMarshall,
136 NdrPointerMarshall, NdrPointerMarshall,
138 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
139 NdrConformantStructMarshall, NdrConformantStructMarshall,
140 NdrConformantVaryingStructMarshall,
141 NdrComplexStructMarshall,
143 NdrConformantArrayMarshall,
144 NdrConformantVaryingArrayMarshall,
145 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
146 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
147 NdrComplexArrayMarshall,
149 NdrConformantStringMarshall, 0, 0,
150 NdrConformantStringMarshall,
151 NdrNonConformantStringMarshall, 0, 0, 0,
153 NdrEncapsulatedUnionMarshall,
154 NdrNonEncapsulatedUnionMarshall,
155 NdrByteCountPointerMarshall,
156 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
158 NdrInterfacePointerMarshall,
160 NdrContextHandleMarshall,
163 NdrUserMarshalMarshall,
168 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
170 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
171 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
172 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
173 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
175 NdrBaseTypeUnmarshall,
177 NdrPointerUnmarshall, NdrPointerUnmarshall,
178 NdrPointerUnmarshall, NdrPointerUnmarshall,
180 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
181 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
182 NdrConformantVaryingStructUnmarshall,
183 NdrComplexStructUnmarshall,
185 NdrConformantArrayUnmarshall,
186 NdrConformantVaryingArrayUnmarshall,
187 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
188 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
189 NdrComplexArrayUnmarshall,
191 NdrConformantStringUnmarshall, 0, 0,
192 NdrConformantStringUnmarshall,
193 NdrNonConformantStringUnmarshall, 0, 0, 0,
195 NdrEncapsulatedUnionUnmarshall,
196 NdrNonEncapsulatedUnionUnmarshall,
197 NdrByteCountPointerUnmarshall,
198 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
200 NdrInterfacePointerUnmarshall,
202 NdrContextHandleUnmarshall,
205 NdrUserMarshalUnmarshall,
210 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
212 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
213 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
214 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
215 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
217 NdrBaseTypeBufferSize,
219 NdrPointerBufferSize, NdrPointerBufferSize,
220 NdrPointerBufferSize, NdrPointerBufferSize,
222 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
223 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
224 NdrConformantVaryingStructBufferSize,
225 NdrComplexStructBufferSize,
227 NdrConformantArrayBufferSize,
228 NdrConformantVaryingArrayBufferSize,
229 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
230 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
231 NdrComplexArrayBufferSize,
233 NdrConformantStringBufferSize, 0, 0,
234 NdrConformantStringBufferSize,
235 NdrNonConformantStringBufferSize, 0, 0, 0,
237 NdrEncapsulatedUnionBufferSize,
238 NdrNonEncapsulatedUnionBufferSize,
239 NdrByteCountPointerBufferSize,
240 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
242 NdrInterfacePointerBufferSize,
244 NdrContextHandleBufferSize,
247 NdrUserMarshalBufferSize,
252 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
254 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
255 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
256 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
257 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
259 NdrBaseTypeMemorySize,
261 NdrPointerMemorySize, NdrPointerMemorySize,
262 NdrPointerMemorySize, NdrPointerMemorySize,
264 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
265 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
266 NdrConformantVaryingStructMemorySize,
267 NdrComplexStructMemorySize,
269 NdrConformantArrayMemorySize,
270 NdrConformantVaryingArrayMemorySize,
271 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
272 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
273 NdrComplexArrayMemorySize,
275 NdrConformantStringMemorySize, 0, 0,
276 NdrConformantStringMemorySize,
277 NdrNonConformantStringMemorySize, 0, 0, 0,
279 NdrEncapsulatedUnionMemorySize,
280 NdrNonEncapsulatedUnionMemorySize,
281 NdrByteCountPointerMemorySize,
282 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
284 NdrInterfacePointerMemorySize,
289 NdrUserMarshalMemorySize,
294 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
296 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
297 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
298 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
299 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
303 NdrPointerFree, NdrPointerFree,
304 NdrPointerFree, NdrPointerFree,
306 NdrSimpleStructFree, NdrSimpleStructFree,
307 NdrConformantStructFree, NdrConformantStructFree,
308 NdrConformantVaryingStructFree,
309 NdrComplexStructFree,
311 NdrConformantArrayFree,
312 NdrConformantVaryingArrayFree,
313 NdrFixedArrayFree, NdrFixedArrayFree,
314 NdrVaryingArrayFree, NdrVaryingArrayFree,
320 NdrEncapsulatedUnionFree,
321 NdrNonEncapsulatedUnionFree,
323 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
325 NdrInterfacePointerFree,
336 typedef struct _NDR_MEMORY_LIST
341 struct _NDR_MEMORY_LIST *next;
344 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
346 /***********************************************************************
347 * NdrAllocate [RPCRT4.@]
349 * Allocates a block of memory using pStubMsg->pfnAllocate.
352 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
353 * len [I] Size of memory block to allocate.
356 * The memory block of size len that was allocated.
359 * The memory block is always 8-byte aligned.
360 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
361 * exception is raised.
363 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
368 NDR_MEMORY_LIST *mem_list;
370 aligned_len = ALIGNED_LENGTH(len, 8);
371 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
372 /* check for overflow */
373 if (adjusted_len < len)
375 ERR("overflow of adjusted_len %d, len %d\n", adjusted_len, len);
376 RpcRaiseException(RPC_X_BAD_STUB_DATA);
379 p = pStubMsg->pfnAllocate(adjusted_len);
380 if (!p) RpcRaiseException(ERROR_OUTOFMEMORY);
382 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
383 mem_list->magic = MEML_MAGIC;
384 mem_list->size = aligned_len;
385 mem_list->reserved = 0;
386 mem_list->next = pStubMsg->pMemoryList;
387 pStubMsg->pMemoryList = mem_list;
393 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
395 TRACE("(%p, %p)\n", pStubMsg, Pointer);
397 pStubMsg->pfnFree(Pointer);
400 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
402 return (*(const ULONG *)pFormat != -1);
405 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
407 ALIGN_POINTER(pStubMsg->Buffer, 4);
408 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
409 RpcRaiseException(RPC_X_BAD_STUB_DATA);
410 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
411 pStubMsg->Buffer += 4;
412 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
413 if (pStubMsg->fHasNewCorrDesc)
419 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
421 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
423 pStubMsg->Offset = 0;
424 pStubMsg->ActualCount = pStubMsg->MaxCount;
428 ALIGN_POINTER(pStubMsg->Buffer, 4);
429 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
430 RpcRaiseException(RPC_X_BAD_STUB_DATA);
431 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
432 pStubMsg->Buffer += 4;
433 TRACE("offset is %d\n", pStubMsg->Offset);
434 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
435 pStubMsg->Buffer += 4;
436 TRACE("variance is %d\n", pStubMsg->ActualCount);
438 if ((pStubMsg->ActualCount > MaxValue) ||
439 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
441 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
442 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
443 RpcRaiseException(RPC_S_INVALID_BOUND);
448 if (pStubMsg->fHasNewCorrDesc)
454 /* writes the conformance value to the buffer */
455 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
457 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
458 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
459 RpcRaiseException(RPC_X_BAD_STUB_DATA);
460 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
461 pStubMsg->Buffer += 4;
464 /* writes the variance values to the buffer */
465 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
467 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
468 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
469 RpcRaiseException(RPC_X_BAD_STUB_DATA);
470 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
471 pStubMsg->Buffer += 4;
472 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
473 pStubMsg->Buffer += 4;
476 /* requests buffer space for the conformance value */
477 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
479 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
480 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
481 RpcRaiseException(RPC_X_BAD_STUB_DATA);
482 pStubMsg->BufferLength += 4;
485 /* requests buffer space for the variance values */
486 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
488 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
489 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
490 RpcRaiseException(RPC_X_BAD_STUB_DATA);
491 pStubMsg->BufferLength += 8;
494 PFORMAT_STRING ComputeConformanceOrVariance(
495 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
496 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
498 BYTE dtype = pFormat[0] & 0xf;
499 short ofs = *(const short *)&pFormat[2];
503 if (!IsConformanceOrVariancePresent(pFormat)) {
504 /* null descriptor */
509 switch (pFormat[0] & 0xf0) {
510 case RPC_FC_NORMAL_CONFORMANCE:
511 TRACE("normal conformance, ofs=%d\n", ofs);
514 case RPC_FC_POINTER_CONFORMANCE:
515 TRACE("pointer conformance, ofs=%d\n", ofs);
516 ptr = pStubMsg->Memory;
518 case RPC_FC_TOP_LEVEL_CONFORMANCE:
519 TRACE("toplevel conformance, ofs=%d\n", ofs);
520 if (pStubMsg->StackTop) {
521 ptr = pStubMsg->StackTop;
524 /* -Os mode, *pCount is already set */
528 case RPC_FC_CONSTANT_CONFORMANCE:
529 data = ofs | ((DWORD)pFormat[1] << 16);
530 TRACE("constant conformance, val=%d\n", data);
533 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
534 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
535 if (pStubMsg->StackTop) {
536 ptr = pStubMsg->StackTop;
544 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
547 switch (pFormat[1]) {
548 case RPC_FC_DEREFERENCE:
549 ptr = *(LPVOID*)((char *)ptr + ofs);
551 case RPC_FC_CALLBACK:
553 unsigned char *old_stack_top = pStubMsg->StackTop;
554 pStubMsg->StackTop = ptr;
556 /* ofs is index into StubDesc->apfnExprEval */
557 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
558 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
560 pStubMsg->StackTop = old_stack_top;
562 /* the callback function always stores the computed value in MaxCount */
563 *pCount = pStubMsg->MaxCount;
567 ptr = (char *)ptr + ofs;
580 data = *(USHORT*)ptr;
591 FIXME("unknown conformance data type %x\n", dtype);
594 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
597 switch (pFormat[1]) {
598 case RPC_FC_DEREFERENCE: /* already handled */
615 FIXME("unknown conformance op %d\n", pFormat[1]);
620 TRACE("resulting conformance is %ld\n", *pCount);
621 if (pStubMsg->fHasNewCorrDesc)
627 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
628 * the result overflows 32-bits */
629 static inline ULONG safe_multiply(ULONG a, ULONG b)
631 ULONGLONG ret = (ULONGLONG)a * b;
632 if (ret > 0xffffffff)
634 RpcRaiseException(RPC_S_INVALID_BOUND);
640 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
642 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
643 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
644 RpcRaiseException(RPC_X_BAD_STUB_DATA);
645 pStubMsg->Buffer += size;
648 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
650 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
652 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
653 pStubMsg->BufferLength, size);
654 RpcRaiseException(RPC_X_BAD_STUB_DATA);
656 pStubMsg->BufferLength += size;
659 /* copies data from the buffer, checking that there is enough data in the buffer
661 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
663 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
664 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
666 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
667 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
668 RpcRaiseException(RPC_X_BAD_STUB_DATA);
670 if (p == pStubMsg->Buffer)
671 ERR("pointer is the same as the buffer\n");
672 memcpy(p, pStubMsg->Buffer, size);
673 pStubMsg->Buffer += size;
676 /* copies data to the buffer, checking that there is enough space to do so */
677 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
679 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
680 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
682 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
683 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
685 RpcRaiseException(RPC_X_BAD_STUB_DATA);
687 memcpy(pStubMsg->Buffer, p, size);
688 pStubMsg->Buffer += size;
692 * NdrConformantString:
694 * What MS calls a ConformantString is, in DCE terminology,
695 * a Varying-Conformant String.
697 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
698 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
699 * into unmarshalled string)
700 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
702 * data: CHARTYPE[maxlen]
704 * ], where CHARTYPE is the appropriate character type (specified externally)
708 /***********************************************************************
709 * NdrConformantStringMarshall [RPCRT4.@]
711 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
712 unsigned char *pszMessage, PFORMAT_STRING pFormat)
716 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
718 if (*pFormat == RPC_FC_C_CSTRING) {
719 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
720 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
723 else if (*pFormat == RPC_FC_C_WSTRING) {
724 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
725 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
729 ERR("Unhandled string type: %#x\n", *pFormat);
730 /* FIXME: raise an exception. */
734 if (pFormat[1] == RPC_FC_STRING_SIZED)
735 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
737 pStubMsg->MaxCount = pStubMsg->ActualCount;
738 pStubMsg->Offset = 0;
739 WriteConformance(pStubMsg);
740 WriteVariance(pStubMsg);
742 size = safe_multiply(esize, pStubMsg->ActualCount);
743 safe_copy_to_buffer(pStubMsg, pszMessage, size); /* the string itself */
746 return NULL; /* is this always right? */
749 /***********************************************************************
750 * NdrConformantStringBufferSize [RPCRT4.@]
752 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
753 unsigned char* pMemory, PFORMAT_STRING pFormat)
757 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
759 SizeConformance(pStubMsg);
760 SizeVariance(pStubMsg);
762 if (*pFormat == RPC_FC_C_CSTRING) {
763 TRACE("string=%s\n", debugstr_a((char*)pMemory));
764 pStubMsg->ActualCount = strlen((char*)pMemory)+1;
767 else if (*pFormat == RPC_FC_C_WSTRING) {
768 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
769 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;
773 ERR("Unhandled string type: %#x\n", *pFormat);
774 /* FIXME: raise an exception */
778 if (pFormat[1] == RPC_FC_STRING_SIZED)
779 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
781 pStubMsg->MaxCount = pStubMsg->ActualCount;
783 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
786 /************************************************************************
787 * NdrConformantStringMemorySize [RPCRT4.@]
789 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
790 PFORMAT_STRING pFormat )
792 ULONG bufsize, memsize, esize, i;
794 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
796 ReadConformance(pStubMsg, NULL);
797 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
799 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
801 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
802 pStubMsg->ActualCount, pStubMsg->MaxCount);
803 RpcRaiseException(RPC_S_INVALID_BOUND);
805 if (pStubMsg->Offset)
807 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
808 RpcRaiseException(RPC_S_INVALID_BOUND);
811 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
812 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
814 ERR("Unhandled string type: %#x\n", *pFormat);
815 /* FIXME: raise an exception */
819 memsize = safe_multiply(esize, pStubMsg->MaxCount);
820 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
822 /* strings must always have null terminating bytes */
825 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
826 RpcRaiseException(RPC_S_INVALID_BOUND);
829 /* verify the buffer is safe to access */
830 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
831 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
833 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
834 pStubMsg->BufferEnd, pStubMsg->Buffer);
835 RpcRaiseException(RPC_X_BAD_STUB_DATA);
838 for (i = bufsize - esize; i < bufsize; i++)
839 if (pStubMsg->Buffer[i] != 0)
841 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
842 i, pStubMsg->Buffer[i]);
843 RpcRaiseException(RPC_S_INVALID_BOUND);
846 safe_buffer_increment(pStubMsg, bufsize);
847 pStubMsg->MemorySize += memsize;
849 return pStubMsg->MemorySize;
852 /************************************************************************
853 * NdrConformantStringUnmarshall [RPCRT4.@]
855 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
856 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
858 ULONG bufsize, memsize, esize, i;
860 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
861 pStubMsg, *ppMemory, pFormat, fMustAlloc);
863 assert(pFormat && ppMemory && pStubMsg);
865 ReadConformance(pStubMsg, NULL);
866 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
868 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
870 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
871 pStubMsg->ActualCount, pStubMsg->MaxCount);
872 RpcRaiseException(RPC_S_INVALID_BOUND);
875 if (pStubMsg->Offset)
877 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
878 RpcRaiseException(RPC_S_INVALID_BOUND);
882 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
883 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
885 ERR("Unhandled string type: %#x\n", *pFormat);
886 /* FIXME: raise an exception */
890 memsize = safe_multiply(esize, pStubMsg->MaxCount);
891 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
893 /* strings must always have null terminating bytes */
896 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
897 RpcRaiseException(RPC_S_INVALID_BOUND);
901 /* verify the buffer is safe to access */
902 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
903 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
905 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
906 pStubMsg->BufferEnd, pStubMsg->Buffer);
907 RpcRaiseException(RPC_X_BAD_STUB_DATA);
911 for (i = bufsize - esize; i < bufsize; i++)
912 if (pStubMsg->Buffer[i] != 0)
914 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
915 i, pStubMsg->Buffer[i]);
916 RpcRaiseException(RPC_S_INVALID_BOUND);
921 *ppMemory = NdrAllocate(pStubMsg, memsize);
924 if (!pStubMsg->IsClient && !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
925 /* if the data in the RPC buffer is big enough, we just point straight
927 *ppMemory = pStubMsg->Buffer;
929 *ppMemory = NdrAllocate(pStubMsg, memsize);
932 if (*ppMemory == pStubMsg->Buffer)
933 safe_buffer_increment(pStubMsg, bufsize);
935 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
937 if (*pFormat == RPC_FC_C_CSTRING) {
938 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
940 else if (*pFormat == RPC_FC_C_WSTRING) {
941 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
944 return NULL; /* FIXME: is this always right? */
947 /***********************************************************************
948 * NdrNonConformantStringMarshall [RPCRT4.@]
950 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
951 unsigned char *pMemory,
952 PFORMAT_STRING pFormat)
954 ULONG esize, size, maxsize;
956 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
958 maxsize = *(USHORT *)&pFormat[2];
960 if (*pFormat == RPC_FC_CSTRING)
963 const char *str = (const char *)pMemory;
964 for (i = 0; i < maxsize && *str; i++, str++)
966 TRACE("string=%s\n", debugstr_an(str, i));
967 pStubMsg->ActualCount = i + 1;
970 else if (*pFormat == RPC_FC_WSTRING)
973 const WCHAR *str = (const WCHAR *)pMemory;
974 for (i = 0; i < maxsize && *str; i++, str++)
976 TRACE("string=%s\n", debugstr_wn(str, i));
977 pStubMsg->ActualCount = i + 1;
982 ERR("Unhandled string type: %#x\n", *pFormat);
983 RpcRaiseException(RPC_X_BAD_STUB_DATA);
986 pStubMsg->Offset = 0;
987 WriteVariance(pStubMsg);
989 size = safe_multiply(esize, pStubMsg->ActualCount);
990 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
995 /***********************************************************************
996 * NdrNonConformantStringUnmarshall [RPCRT4.@]
998 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
999 unsigned char **ppMemory,
1000 PFORMAT_STRING pFormat,
1001 unsigned char fMustAlloc)
1003 ULONG bufsize, memsize, esize, i, maxsize;
1005 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
1006 pStubMsg, *ppMemory, pFormat, fMustAlloc);
1008 maxsize = *(USHORT *)&pFormat[2];
1010 ReadVariance(pStubMsg, NULL, maxsize);
1011 if (pStubMsg->Offset)
1013 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
1014 RpcRaiseException(RPC_S_INVALID_BOUND);
1017 if (*pFormat == RPC_FC_CSTRING) esize = 1;
1018 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
1021 ERR("Unhandled string type: %#x\n", *pFormat);
1022 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1025 memsize = esize * maxsize;
1026 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
1028 if (bufsize < esize)
1030 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
1031 RpcRaiseException(RPC_S_INVALID_BOUND);
1035 /* verify the buffer is safe to access */
1036 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
1037 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
1039 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
1040 pStubMsg->BufferEnd, pStubMsg->Buffer);
1041 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1045 /* strings must always have null terminating bytes */
1046 for (i = bufsize - esize; i < bufsize; i++)
1047 if (pStubMsg->Buffer[i] != 0)
1049 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
1050 i, pStubMsg->Buffer[i]);
1051 RpcRaiseException(RPC_S_INVALID_BOUND);
1054 if (fMustAlloc || !*ppMemory)
1055 *ppMemory = NdrAllocate(pStubMsg, memsize);
1057 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
1059 if (*pFormat == RPC_FC_CSTRING) {
1060 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
1062 else if (*pFormat == RPC_FC_WSTRING) {
1063 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
1069 /***********************************************************************
1070 * NdrNonConformantStringBufferSize [RPCRT4.@]
1072 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1073 unsigned char *pMemory,
1074 PFORMAT_STRING pFormat)
1076 ULONG esize, maxsize;
1078 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
1080 maxsize = *(USHORT *)&pFormat[2];
1082 SizeVariance(pStubMsg);
1084 if (*pFormat == RPC_FC_CSTRING)
1087 const char *str = (const char *)pMemory;
1088 for (i = 0; i < maxsize && *str; i++, str++)
1090 TRACE("string=%s\n", debugstr_an(str, i));
1091 pStubMsg->ActualCount = i + 1;
1094 else if (*pFormat == RPC_FC_WSTRING)
1097 const WCHAR *str = (const WCHAR *)pMemory;
1098 for (i = 0; i < maxsize && *str; i++, str++)
1100 TRACE("string=%s\n", debugstr_wn(str, i));
1101 pStubMsg->ActualCount = i + 1;
1106 ERR("Unhandled string type: %#x\n", *pFormat);
1107 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1110 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
1113 /***********************************************************************
1114 * NdrNonConformantStringMemorySize [RPCRT4.@]
1116 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1117 PFORMAT_STRING pFormat)
1119 ULONG bufsize, memsize, esize, i, maxsize;
1121 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
1123 maxsize = *(USHORT *)&pFormat[2];
1125 ReadVariance(pStubMsg, NULL, maxsize);
1127 if (pStubMsg->Offset)
1129 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
1130 RpcRaiseException(RPC_S_INVALID_BOUND);
1133 if (*pFormat == RPC_FC_CSTRING) esize = 1;
1134 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
1137 ERR("Unhandled string type: %#x\n", *pFormat);
1138 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1141 memsize = esize * maxsize;
1142 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
1144 /* strings must always have null terminating bytes */
1145 if (bufsize < esize)
1147 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
1148 RpcRaiseException(RPC_S_INVALID_BOUND);
1151 /* verify the buffer is safe to access */
1152 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
1153 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
1155 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
1156 pStubMsg->BufferEnd, pStubMsg->Buffer);
1157 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1160 for (i = bufsize - esize; i < bufsize; i++)
1161 if (pStubMsg->Buffer[i] != 0)
1163 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
1164 i, pStubMsg->Buffer[i]);
1165 RpcRaiseException(RPC_S_INVALID_BOUND);
1168 safe_buffer_increment(pStubMsg, bufsize);
1169 pStubMsg->MemorySize += memsize;
1171 return pStubMsg->MemorySize;
1174 static inline void dump_pointer_attr(unsigned char attr)
1176 if (attr & RPC_FC_P_ALLOCALLNODES)
1177 TRACE(" RPC_FC_P_ALLOCALLNODES");
1178 if (attr & RPC_FC_P_DONTFREE)
1179 TRACE(" RPC_FC_P_DONTFREE");
1180 if (attr & RPC_FC_P_ONSTACK)
1181 TRACE(" RPC_FC_P_ONSTACK");
1182 if (attr & RPC_FC_P_SIMPLEPOINTER)
1183 TRACE(" RPC_FC_P_SIMPLEPOINTER");
1184 if (attr & RPC_FC_P_DEREF)
1185 TRACE(" RPC_FC_P_DEREF");
1189 /***********************************************************************
1190 * PointerMarshall [internal]
1192 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1193 unsigned char *Buffer,
1194 unsigned char *Pointer,
1195 PFORMAT_STRING pFormat)
1197 unsigned type = pFormat[0], attr = pFormat[1];
1198 PFORMAT_STRING desc;
1201 int pointer_needs_marshaling;
1203 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
1204 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1206 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1207 else desc = pFormat + *(const SHORT*)pFormat;
1210 case RPC_FC_RP: /* ref pointer (always non-null) */
1213 ERR("NULL ref pointer is not allowed\n");
1214 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1216 pointer_needs_marshaling = 1;
1218 case RPC_FC_UP: /* unique pointer */
1219 case RPC_FC_OP: /* object pointer - same as unique here */
1221 pointer_needs_marshaling = 1;
1223 pointer_needs_marshaling = 0;
1224 pointer_id = (ULONG)Pointer;
1225 TRACE("writing 0x%08x to buffer\n", pointer_id);
1226 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
1229 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
1230 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
1231 TRACE("writing 0x%08x to buffer\n", pointer_id);
1232 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
1235 FIXME("unhandled ptr type=%02x\n", type);
1236 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1240 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
1242 if (pointer_needs_marshaling) {
1243 if (attr & RPC_FC_P_DEREF) {
1244 Pointer = *(unsigned char**)Pointer;
1245 TRACE("deref => %p\n", Pointer);
1247 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1248 if (m) m(pStubMsg, Pointer, desc);
1249 else FIXME("no marshaller for data type=%02x\n", *desc);
1252 STD_OVERFLOW_CHECK(pStubMsg);
1255 /***********************************************************************
1256 * PointerUnmarshall [internal]
1258 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1259 unsigned char *Buffer,
1260 unsigned char **pPointer,
1261 unsigned char *pSrcPointer,
1262 PFORMAT_STRING pFormat,
1263 unsigned char fMustAlloc)
1265 unsigned type = pFormat[0], attr = pFormat[1];
1266 PFORMAT_STRING desc;
1268 DWORD pointer_id = 0;
1269 int pointer_needs_unmarshaling;
1271 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
1272 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1274 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1275 else desc = pFormat + *(const SHORT*)pFormat;
1278 case RPC_FC_RP: /* ref pointer (always non-null) */
1279 pointer_needs_unmarshaling = 1;
1281 case RPC_FC_UP: /* unique pointer */
1282 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1283 TRACE("pointer_id is 0x%08x\n", pointer_id);
1285 pointer_needs_unmarshaling = 1;
1288 pointer_needs_unmarshaling = 0;
1291 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1292 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1293 TRACE("pointer_id is 0x%08x\n", pointer_id);
1294 if (!fMustAlloc && pSrcPointer)
1296 FIXME("free object pointer %p\n", pSrcPointer);
1300 pointer_needs_unmarshaling = 1;
1302 pointer_needs_unmarshaling = 0;
1305 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1306 TRACE("pointer_id is 0x%08x\n", pointer_id);
1307 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
1308 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
1311 FIXME("unhandled ptr type=%02x\n", type);
1312 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1316 if (pointer_needs_unmarshaling) {
1317 unsigned char *base_ptr_val = *pPointer;
1318 unsigned char **current_ptr = pPointer;
1319 if (pStubMsg->IsClient) {
1321 /* if we aren't forcing allocation of memory then try to use the existing
1322 * (source) pointer to unmarshall the data into so that [in,out]
1323 * parameters behave correctly. it doesn't matter if the parameter is
1324 * [out] only since in that case the pointer will be NULL. we force
1325 * allocation when the source pointer is NULL here instead of in the type
1326 * unmarshalling routine for the benefit of the deref code below */
1329 TRACE("setting *pPointer to %p\n", pSrcPointer);
1330 *pPointer = base_ptr_val = pSrcPointer;
1336 /* the memory in a stub is never initialised, so we have to work out here
1337 * whether we have to initialise it so we can use the optimisation of
1338 * setting the pointer to the buffer, if possible, or set fMustAlloc to
1340 if (attr & RPC_FC_P_DEREF) {
1343 base_ptr_val = NULL;
1344 *current_ptr = NULL;
1348 if (attr & RPC_FC_P_ALLOCALLNODES)
1349 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
1351 if (attr & RPC_FC_P_DEREF) {
1353 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
1354 *pPointer = base_ptr_val;
1355 current_ptr = (unsigned char **)base_ptr_val;
1357 current_ptr = *(unsigned char***)current_ptr;
1358 TRACE("deref => %p\n", current_ptr);
1359 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
1361 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1362 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
1363 else FIXME("no unmarshaller for data type=%02x\n", *desc);
1365 if (type == RPC_FC_FP)
1366 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
1370 TRACE("pointer=%p\n", *pPointer);
1373 /***********************************************************************
1374 * PointerBufferSize [internal]
1376 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1377 unsigned char *Pointer,
1378 PFORMAT_STRING pFormat)
1380 unsigned type = pFormat[0], attr = pFormat[1];
1381 PFORMAT_STRING desc;
1383 int pointer_needs_sizing;
1386 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1387 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1389 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1390 else desc = pFormat + *(const SHORT*)pFormat;
1393 case RPC_FC_RP: /* ref pointer (always non-null) */
1396 ERR("NULL ref pointer is not allowed\n");
1397 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1402 /* NULL pointer has no further representation */
1407 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1408 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1409 if (!pointer_needs_sizing)
1413 FIXME("unhandled ptr type=%02x\n", type);
1414 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1418 if (attr & RPC_FC_P_DEREF) {
1419 Pointer = *(unsigned char**)Pointer;
1420 TRACE("deref => %p\n", Pointer);
1423 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1424 if (m) m(pStubMsg, Pointer, desc);
1425 else FIXME("no buffersizer for data type=%02x\n", *desc);
1428 /***********************************************************************
1429 * PointerMemorySize [internal]
1431 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1432 unsigned char *Buffer,
1433 PFORMAT_STRING pFormat)
1435 unsigned type = pFormat[0], attr = pFormat[1];
1436 PFORMAT_STRING desc;
1438 DWORD pointer_id = 0;
1439 int pointer_needs_sizing;
1441 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1442 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1444 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1445 else desc = pFormat + *(const SHORT*)pFormat;
1448 case RPC_FC_RP: /* ref pointer (always non-null) */
1449 pointer_needs_sizing = 1;
1451 case RPC_FC_UP: /* unique pointer */
1452 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1453 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1454 TRACE("pointer_id is 0x%08x\n", pointer_id);
1456 pointer_needs_sizing = 1;
1458 pointer_needs_sizing = 0;
1463 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1464 TRACE("pointer_id is 0x%08x\n", pointer_id);
1465 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1466 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1470 FIXME("unhandled ptr type=%02x\n", type);
1471 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1475 if (attr & RPC_FC_P_DEREF) {
1479 if (pointer_needs_sizing) {
1480 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1481 if (m) m(pStubMsg, desc);
1482 else FIXME("no memorysizer for data type=%02x\n", *desc);
1485 return pStubMsg->MemorySize;
1488 /***********************************************************************
1489 * PointerFree [internal]
1491 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1492 unsigned char *Pointer,
1493 PFORMAT_STRING pFormat)
1495 unsigned type = pFormat[0], attr = pFormat[1];
1496 PFORMAT_STRING desc;
1498 unsigned char *current_pointer = Pointer;
1500 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1501 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1502 if (attr & RPC_FC_P_DONTFREE) return;
1504 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1505 else desc = pFormat + *(const SHORT*)pFormat;
1507 if (!Pointer) return;
1509 if (type == RPC_FC_FP) {
1510 int pointer_needs_freeing = NdrFullPointerFree(
1511 pStubMsg->FullPtrXlatTables, Pointer);
1512 if (!pointer_needs_freeing)
1516 if (attr & RPC_FC_P_DEREF) {
1517 current_pointer = *(unsigned char**)Pointer;
1518 TRACE("deref => %p\n", current_pointer);
1521 m = NdrFreer[*desc & NDR_TABLE_MASK];
1522 if (m) m(pStubMsg, current_pointer, desc);
1524 /* this check stops us from trying to free buffer memory. we don't have to
1525 * worry about clients, since they won't call this function.
1526 * we don't have to check for the buffer being reallocated because
1527 * BufferStart and BufferEnd won't be reset when allocating memory for
1528 * sending the response. we don't have to check for the new buffer here as
1529 * it won't be used a type memory, only for buffer memory */
1530 if (Pointer >= (unsigned char *)pStubMsg->BufferStart &&
1531 Pointer < (unsigned char *)pStubMsg->BufferEnd)
1534 if (attr & RPC_FC_P_ONSTACK) {
1535 TRACE("not freeing stack ptr %p\n", Pointer);
1538 TRACE("freeing %p\n", Pointer);
1539 NdrFree(pStubMsg, Pointer);
1542 TRACE("not freeing %p\n", Pointer);
1545 /***********************************************************************
1546 * EmbeddedPointerMarshall
1548 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1549 unsigned char *pMemory,
1550 PFORMAT_STRING pFormat)
1552 unsigned char *Mark = pStubMsg->BufferMark;
1553 unsigned rep, count, stride;
1555 unsigned char *saved_buffer = NULL;
1557 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1559 if (*pFormat != RPC_FC_PP) return NULL;
1562 if (pStubMsg->PointerBufferMark)
1564 saved_buffer = pStubMsg->Buffer;
1565 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1566 pStubMsg->PointerBufferMark = NULL;
1569 while (pFormat[0] != RPC_FC_END) {
1570 switch (pFormat[0]) {
1572 FIXME("unknown repeat type %d\n", pFormat[0]);
1573 case RPC_FC_NO_REPEAT:
1579 case RPC_FC_FIXED_REPEAT:
1580 rep = *(const WORD*)&pFormat[2];
1581 stride = *(const WORD*)&pFormat[4];
1582 count = *(const WORD*)&pFormat[8];
1585 case RPC_FC_VARIABLE_REPEAT:
1586 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1587 stride = *(const WORD*)&pFormat[2];
1588 count = *(const WORD*)&pFormat[6];
1592 for (i = 0; i < rep; i++) {
1593 PFORMAT_STRING info = pFormat;
1594 unsigned char *membase = pMemory + (i * stride);
1595 unsigned char *bufbase = Mark + (i * stride);
1598 for (u=0; u<count; u++,info+=8) {
1599 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1600 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1601 unsigned char *saved_memory = pStubMsg->Memory;
1603 pStubMsg->Memory = pMemory;
1604 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1605 pStubMsg->Memory = saved_memory;
1608 pFormat += 8 * count;
1613 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1614 pStubMsg->Buffer = saved_buffer;
1617 STD_OVERFLOW_CHECK(pStubMsg);
1622 /***********************************************************************
1623 * EmbeddedPointerUnmarshall
1625 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1626 unsigned char *pDstMemoryPtrs,
1627 unsigned char *pSrcMemoryPtrs,
1628 PFORMAT_STRING pFormat,
1629 unsigned char fMustAlloc)
1631 unsigned char *Mark = pStubMsg->BufferMark;
1632 unsigned rep, count, stride;
1634 unsigned char *saved_buffer = NULL;
1636 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstMemoryPtrs, pSrcMemoryPtrs, pFormat, fMustAlloc);
1638 if (*pFormat != RPC_FC_PP) return NULL;
1641 if (pStubMsg->PointerBufferMark)
1643 saved_buffer = pStubMsg->Buffer;
1644 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1645 pStubMsg->PointerBufferMark = NULL;
1648 while (pFormat[0] != RPC_FC_END) {
1649 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1650 switch (pFormat[0]) {
1652 FIXME("unknown repeat type %d\n", pFormat[0]);
1653 case RPC_FC_NO_REPEAT:
1659 case RPC_FC_FIXED_REPEAT:
1660 rep = *(const WORD*)&pFormat[2];
1661 stride = *(const WORD*)&pFormat[4];
1662 count = *(const WORD*)&pFormat[8];
1665 case RPC_FC_VARIABLE_REPEAT:
1666 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1667 stride = *(const WORD*)&pFormat[2];
1668 count = *(const WORD*)&pFormat[6];
1672 for (i = 0; i < rep; i++) {
1673 PFORMAT_STRING info = pFormat;
1674 unsigned char *memdstbase = pDstMemoryPtrs + (i * stride);
1675 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1676 unsigned char *bufbase = Mark + (i * stride);
1679 for (u=0; u<count; u++,info+=8) {
1680 unsigned char **memdstptr = (unsigned char **)(memdstbase + *(const SHORT*)&info[0]);
1681 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1682 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1683 PointerUnmarshall(pStubMsg, bufptr, memdstptr, *memsrcptr, info+4, fMustAlloc);
1686 pFormat += 8 * count;
1691 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1692 pStubMsg->Buffer = saved_buffer;
1698 /***********************************************************************
1699 * EmbeddedPointerBufferSize
1701 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1702 unsigned char *pMemory,
1703 PFORMAT_STRING pFormat)
1705 unsigned rep, count, stride;
1707 ULONG saved_buffer_length = 0;
1709 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1711 if (pStubMsg->IgnoreEmbeddedPointers) return;
1713 if (*pFormat != RPC_FC_PP) return;
1716 if (pStubMsg->PointerLength)
1718 saved_buffer_length = pStubMsg->BufferLength;
1719 pStubMsg->BufferLength = pStubMsg->PointerLength;
1720 pStubMsg->PointerLength = 0;
1723 while (pFormat[0] != RPC_FC_END) {
1724 switch (pFormat[0]) {
1726 FIXME("unknown repeat type %d\n", pFormat[0]);
1727 case RPC_FC_NO_REPEAT:
1733 case RPC_FC_FIXED_REPEAT:
1734 rep = *(const WORD*)&pFormat[2];
1735 stride = *(const WORD*)&pFormat[4];
1736 count = *(const WORD*)&pFormat[8];
1739 case RPC_FC_VARIABLE_REPEAT:
1740 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1741 stride = *(const WORD*)&pFormat[2];
1742 count = *(const WORD*)&pFormat[6];
1746 for (i = 0; i < rep; i++) {
1747 PFORMAT_STRING info = pFormat;
1748 unsigned char *membase = pMemory + (i * stride);
1751 for (u=0; u<count; u++,info+=8) {
1752 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1753 unsigned char *saved_memory = pStubMsg->Memory;
1755 pStubMsg->Memory = pMemory;
1756 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1757 pStubMsg->Memory = saved_memory;
1760 pFormat += 8 * count;
1763 if (saved_buffer_length)
1765 pStubMsg->PointerLength = pStubMsg->BufferLength;
1766 pStubMsg->BufferLength = saved_buffer_length;
1770 /***********************************************************************
1771 * EmbeddedPointerMemorySize [internal]
1773 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1774 PFORMAT_STRING pFormat)
1776 unsigned char *Mark = pStubMsg->BufferMark;
1777 unsigned rep, count, stride;
1779 unsigned char *saved_buffer = NULL;
1781 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1783 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1785 if (pStubMsg->PointerBufferMark)
1787 saved_buffer = pStubMsg->Buffer;
1788 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1789 pStubMsg->PointerBufferMark = NULL;
1792 if (*pFormat != RPC_FC_PP) return 0;
1795 while (pFormat[0] != RPC_FC_END) {
1796 switch (pFormat[0]) {
1798 FIXME("unknown repeat type %d\n", pFormat[0]);
1799 case RPC_FC_NO_REPEAT:
1805 case RPC_FC_FIXED_REPEAT:
1806 rep = *(const WORD*)&pFormat[2];
1807 stride = *(const WORD*)&pFormat[4];
1808 count = *(const WORD*)&pFormat[8];
1811 case RPC_FC_VARIABLE_REPEAT:
1812 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1813 stride = *(const WORD*)&pFormat[2];
1814 count = *(const WORD*)&pFormat[6];
1818 for (i = 0; i < rep; i++) {
1819 PFORMAT_STRING info = pFormat;
1820 unsigned char *bufbase = Mark + (i * stride);
1822 for (u=0; u<count; u++,info+=8) {
1823 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1824 PointerMemorySize(pStubMsg, bufptr, info+4);
1827 pFormat += 8 * count;
1832 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1833 pStubMsg->Buffer = saved_buffer;
1839 /***********************************************************************
1840 * EmbeddedPointerFree [internal]
1842 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1843 unsigned char *pMemory,
1844 PFORMAT_STRING pFormat)
1846 unsigned rep, count, stride;
1849 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1850 if (*pFormat != RPC_FC_PP) return;
1853 while (pFormat[0] != RPC_FC_END) {
1854 switch (pFormat[0]) {
1856 FIXME("unknown repeat type %d\n", pFormat[0]);
1857 case RPC_FC_NO_REPEAT:
1863 case RPC_FC_FIXED_REPEAT:
1864 rep = *(const WORD*)&pFormat[2];
1865 stride = *(const WORD*)&pFormat[4];
1866 count = *(const WORD*)&pFormat[8];
1869 case RPC_FC_VARIABLE_REPEAT:
1870 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1871 stride = *(const WORD*)&pFormat[2];
1872 count = *(const WORD*)&pFormat[6];
1876 for (i = 0; i < rep; i++) {
1877 PFORMAT_STRING info = pFormat;
1878 unsigned char *membase = pMemory + (i * stride);
1881 for (u=0; u<count; u++,info+=8) {
1882 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1883 unsigned char *saved_memory = pStubMsg->Memory;
1885 pStubMsg->Memory = pMemory;
1886 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1887 pStubMsg->Memory = saved_memory;
1890 pFormat += 8 * count;
1894 /***********************************************************************
1895 * NdrPointerMarshall [RPCRT4.@]
1897 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1898 unsigned char *pMemory,
1899 PFORMAT_STRING pFormat)
1901 unsigned char *Buffer;
1903 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1905 /* incremement the buffer here instead of in PointerMarshall,
1906 * as that is used by embedded pointers which already handle the incrementing
1907 * the buffer, and shouldn't write any additional pointer data to the wire */
1908 if (*pFormat != RPC_FC_RP)
1910 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
1911 Buffer = pStubMsg->Buffer;
1912 safe_buffer_increment(pStubMsg, 4);
1915 Buffer = pStubMsg->Buffer;
1917 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1922 /***********************************************************************
1923 * NdrPointerUnmarshall [RPCRT4.@]
1925 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1926 unsigned char **ppMemory,
1927 PFORMAT_STRING pFormat,
1928 unsigned char fMustAlloc)
1930 unsigned char *Buffer;
1932 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1934 /* incremement the buffer here instead of in PointerUnmarshall,
1935 * as that is used by embedded pointers which already handle the incrementing
1936 * the buffer, and shouldn't read any additional pointer data from the
1938 if (*pFormat != RPC_FC_RP)
1940 ALIGN_POINTER(pStubMsg->Buffer, 4);
1941 Buffer = pStubMsg->Buffer;
1942 safe_buffer_increment(pStubMsg, 4);
1945 Buffer = pStubMsg->Buffer;
1947 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1952 /***********************************************************************
1953 * NdrPointerBufferSize [RPCRT4.@]
1955 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1956 unsigned char *pMemory,
1957 PFORMAT_STRING pFormat)
1959 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1961 /* incremement the buffer length here instead of in PointerBufferSize,
1962 * as that is used by embedded pointers which already handle the buffer
1963 * length, and shouldn't write anything more to the wire */
1964 if (*pFormat != RPC_FC_RP)
1966 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1967 safe_buffer_length_increment(pStubMsg, 4);
1970 PointerBufferSize(pStubMsg, pMemory, pFormat);
1973 /***********************************************************************
1974 * NdrPointerMemorySize [RPCRT4.@]
1976 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1977 PFORMAT_STRING pFormat)
1979 /* unsigned size = *(LPWORD)(pFormat+2); */
1980 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1981 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1985 /***********************************************************************
1986 * NdrPointerFree [RPCRT4.@]
1988 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1989 unsigned char *pMemory,
1990 PFORMAT_STRING pFormat)
1992 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1993 PointerFree(pStubMsg, pMemory, pFormat);
1996 /***********************************************************************
1997 * NdrSimpleTypeMarshall [RPCRT4.@]
1999 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
2000 unsigned char FormatChar )
2002 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
2005 /***********************************************************************
2006 * NdrSimpleTypeUnmarshall [RPCRT4.@]
2008 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
2009 unsigned char FormatChar )
2011 NdrBaseTypeUnmarshall(pStubMsg, &pMemory, &FormatChar, 0);
2014 /***********************************************************************
2015 * NdrSimpleStructMarshall [RPCRT4.@]
2017 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2018 unsigned char *pMemory,
2019 PFORMAT_STRING pFormat)
2021 unsigned size = *(const WORD*)(pFormat+2);
2022 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2024 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
2026 pStubMsg->BufferMark = pStubMsg->Buffer;
2027 safe_copy_to_buffer(pStubMsg, pMemory, size);
2029 if (pFormat[0] != RPC_FC_STRUCT)
2030 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
2035 /***********************************************************************
2036 * NdrSimpleStructUnmarshall [RPCRT4.@]
2038 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2039 unsigned char **ppMemory,
2040 PFORMAT_STRING pFormat,
2041 unsigned char fMustAlloc)
2043 unsigned size = *(const WORD*)(pFormat+2);
2044 unsigned char *saved_buffer;
2045 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2047 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2050 *ppMemory = NdrAllocate(pStubMsg, size);
2053 if (!pStubMsg->IsClient && !*ppMemory)
2054 /* for servers, we just point straight into the RPC buffer */
2055 *ppMemory = pStubMsg->Buffer;
2058 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
2059 safe_buffer_increment(pStubMsg, size);
2060 if (pFormat[0] == RPC_FC_PSTRUCT)
2061 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
2063 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2064 if (*ppMemory != saved_buffer)
2065 memcpy(*ppMemory, saved_buffer, size);
2070 /***********************************************************************
2071 * NdrSimpleStructBufferSize [RPCRT4.@]
2073 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2074 unsigned char *pMemory,
2075 PFORMAT_STRING pFormat)
2077 unsigned size = *(const WORD*)(pFormat+2);
2078 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2080 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2082 safe_buffer_length_increment(pStubMsg, size);
2083 if (pFormat[0] != RPC_FC_STRUCT)
2084 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
2087 /***********************************************************************
2088 * NdrSimpleStructMemorySize [RPCRT4.@]
2090 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2091 PFORMAT_STRING pFormat)
2093 unsigned short size = *(const WORD *)(pFormat+2);
2095 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2097 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2098 pStubMsg->MemorySize += size;
2099 safe_buffer_increment(pStubMsg, size);
2101 if (pFormat[0] != RPC_FC_STRUCT)
2102 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
2103 return pStubMsg->MemorySize;
2106 /***********************************************************************
2107 * NdrSimpleStructFree [RPCRT4.@]
2109 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2110 unsigned char *pMemory,
2111 PFORMAT_STRING pFormat)
2113 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2114 if (pFormat[0] != RPC_FC_STRUCT)
2115 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
2119 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE *pStubMsg,
2120 PFORMAT_STRING pFormat)
2124 case RPC_FC_PSTRUCT:
2125 case RPC_FC_CSTRUCT:
2126 case RPC_FC_BOGUS_STRUCT:
2127 case RPC_FC_SMFARRAY:
2128 case RPC_FC_SMVARRAY:
2129 case RPC_FC_CSTRING:
2130 return *(const WORD*)&pFormat[2];
2131 case RPC_FC_USER_MARSHAL:
2132 return *(const WORD*)&pFormat[4];
2133 case RPC_FC_NON_ENCAPSULATED_UNION:
2135 if (pStubMsg->fHasNewCorrDesc)
2140 pFormat += *(const SHORT*)pFormat;
2141 return *(const SHORT*)pFormat;
2143 return sizeof(void *);
2144 case RPC_FC_WSTRING:
2145 return *(const WORD*)&pFormat[2] * 2;
2147 FIXME("unhandled embedded type %02x\n", *pFormat);
2153 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2154 PFORMAT_STRING pFormat)
2156 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2160 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2164 return m(pStubMsg, pFormat);
2168 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2169 unsigned char *pMemory,
2170 PFORMAT_STRING pFormat,
2171 PFORMAT_STRING pPointer)
2173 PFORMAT_STRING desc;
2177 while (*pFormat != RPC_FC_END) {
2183 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2184 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2190 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2191 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2197 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2198 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2202 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2203 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2206 case RPC_FC_POINTER:
2208 unsigned char *saved_buffer;
2209 int pointer_buffer_mark_set = 0;
2210 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2211 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
2212 saved_buffer = pStubMsg->Buffer;
2213 if (pStubMsg->PointerBufferMark)
2215 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2216 pStubMsg->PointerBufferMark = NULL;
2217 pointer_buffer_mark_set = 1;
2220 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2221 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2222 if (pointer_buffer_mark_set)
2224 STD_OVERFLOW_CHECK(pStubMsg);
2225 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2226 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2228 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2229 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2230 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2232 pStubMsg->Buffer = saved_buffer + 4;
2238 case RPC_FC_ALIGNM4:
2239 ALIGN_POINTER(pMemory, 4);
2241 case RPC_FC_ALIGNM8:
2242 ALIGN_POINTER(pMemory, 8);
2244 case RPC_FC_STRUCTPAD1:
2245 case RPC_FC_STRUCTPAD2:
2246 case RPC_FC_STRUCTPAD3:
2247 case RPC_FC_STRUCTPAD4:
2248 case RPC_FC_STRUCTPAD5:
2249 case RPC_FC_STRUCTPAD6:
2250 case RPC_FC_STRUCTPAD7:
2251 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2253 case RPC_FC_EMBEDDED_COMPLEX:
2254 pMemory += pFormat[1];
2256 desc = pFormat + *(const SHORT*)pFormat;
2257 size = EmbeddedComplexSize(pStubMsg, desc);
2258 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
2259 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2262 /* for some reason interface pointers aren't generated as
2263 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2264 * they still need the derefencing treatment that pointers are
2266 if (*desc == RPC_FC_IP)
2267 m(pStubMsg, *(unsigned char **)pMemory, desc);
2269 m(pStubMsg, pMemory, desc);
2271 else FIXME("no marshaller for embedded type %02x\n", *desc);
2278 FIXME("unhandled format 0x%02x\n", *pFormat);
2286 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2287 unsigned char *pMemory,
2288 PFORMAT_STRING pFormat,
2289 PFORMAT_STRING pPointer)
2291 PFORMAT_STRING desc;
2295 while (*pFormat != RPC_FC_END) {
2301 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2302 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2308 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2309 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2315 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2316 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2320 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2321 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2324 case RPC_FC_POINTER:
2326 unsigned char *saved_buffer;
2327 int pointer_buffer_mark_set = 0;
2328 TRACE("pointer => %p\n", pMemory);
2329 ALIGN_POINTER(pStubMsg->Buffer, 4);
2330 saved_buffer = pStubMsg->Buffer;
2331 if (pStubMsg->PointerBufferMark)
2333 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2334 pStubMsg->PointerBufferMark = NULL;
2335 pointer_buffer_mark_set = 1;
2338 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2340 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, TRUE);
2341 if (pointer_buffer_mark_set)
2343 STD_OVERFLOW_CHECK(pStubMsg);
2344 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2345 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2347 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2348 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2349 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2351 pStubMsg->Buffer = saved_buffer + 4;
2357 case RPC_FC_ALIGNM4:
2358 ALIGN_POINTER_CLEAR(pMemory, 4);
2360 case RPC_FC_ALIGNM8:
2361 ALIGN_POINTER_CLEAR(pMemory, 8);
2363 case RPC_FC_STRUCTPAD1:
2364 case RPC_FC_STRUCTPAD2:
2365 case RPC_FC_STRUCTPAD3:
2366 case RPC_FC_STRUCTPAD4:
2367 case RPC_FC_STRUCTPAD5:
2368 case RPC_FC_STRUCTPAD6:
2369 case RPC_FC_STRUCTPAD7:
2370 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2371 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2373 case RPC_FC_EMBEDDED_COMPLEX:
2374 pMemory += pFormat[1];
2376 desc = pFormat + *(const SHORT*)pFormat;
2377 size = EmbeddedComplexSize(pStubMsg, desc);
2378 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2379 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2380 memset(pMemory, 0, size); /* just in case */
2383 /* for some reason interface pointers aren't generated as
2384 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2385 * they still need the derefencing treatment that pointers are
2387 if (*desc == RPC_FC_IP)
2388 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2390 m(pStubMsg, &pMemory, desc, FALSE);
2392 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2399 FIXME("unhandled format %d\n", *pFormat);
2407 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2408 unsigned char *pMemory,
2409 PFORMAT_STRING pFormat,
2410 PFORMAT_STRING pPointer)
2412 PFORMAT_STRING desc;
2416 while (*pFormat != RPC_FC_END) {
2422 safe_buffer_length_increment(pStubMsg, 1);
2428 safe_buffer_length_increment(pStubMsg, 2);
2434 safe_buffer_length_increment(pStubMsg, 4);
2438 safe_buffer_length_increment(pStubMsg, 8);
2441 case RPC_FC_POINTER:
2442 if (!pStubMsg->IgnoreEmbeddedPointers)
2444 int saved_buffer_length = pStubMsg->BufferLength;
2445 pStubMsg->BufferLength = pStubMsg->PointerLength;
2446 pStubMsg->PointerLength = 0;
2447 if(!pStubMsg->BufferLength)
2448 ERR("BufferLength == 0??\n");
2449 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2450 pStubMsg->PointerLength = pStubMsg->BufferLength;
2451 pStubMsg->BufferLength = saved_buffer_length;
2453 safe_buffer_length_increment(pStubMsg, 4);
2457 case RPC_FC_ALIGNM4:
2458 ALIGN_POINTER(pMemory, 4);
2460 case RPC_FC_ALIGNM8:
2461 ALIGN_POINTER(pMemory, 8);
2463 case RPC_FC_STRUCTPAD1:
2464 case RPC_FC_STRUCTPAD2:
2465 case RPC_FC_STRUCTPAD3:
2466 case RPC_FC_STRUCTPAD4:
2467 case RPC_FC_STRUCTPAD5:
2468 case RPC_FC_STRUCTPAD6:
2469 case RPC_FC_STRUCTPAD7:
2470 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2472 case RPC_FC_EMBEDDED_COMPLEX:
2473 pMemory += pFormat[1];
2475 desc = pFormat + *(const SHORT*)pFormat;
2476 size = EmbeddedComplexSize(pStubMsg, desc);
2477 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2480 /* for some reason interface pointers aren't generated as
2481 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2482 * they still need the derefencing treatment that pointers are
2484 if (*desc == RPC_FC_IP)
2485 m(pStubMsg, *(unsigned char **)pMemory, desc);
2487 m(pStubMsg, pMemory, desc);
2489 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2496 FIXME("unhandled format 0x%02x\n", *pFormat);
2504 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2505 unsigned char *pMemory,
2506 PFORMAT_STRING pFormat,
2507 PFORMAT_STRING pPointer)
2509 PFORMAT_STRING desc;
2513 while (*pFormat != RPC_FC_END) {
2534 case RPC_FC_POINTER:
2535 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
2539 case RPC_FC_ALIGNM4:
2540 ALIGN_POINTER(pMemory, 4);
2542 case RPC_FC_ALIGNM8:
2543 ALIGN_POINTER(pMemory, 8);
2545 case RPC_FC_STRUCTPAD1:
2546 case RPC_FC_STRUCTPAD2:
2547 case RPC_FC_STRUCTPAD3:
2548 case RPC_FC_STRUCTPAD4:
2549 case RPC_FC_STRUCTPAD5:
2550 case RPC_FC_STRUCTPAD6:
2551 case RPC_FC_STRUCTPAD7:
2552 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2554 case RPC_FC_EMBEDDED_COMPLEX:
2555 pMemory += pFormat[1];
2557 desc = pFormat + *(const SHORT*)pFormat;
2558 size = EmbeddedComplexSize(pStubMsg, desc);
2559 m = NdrFreer[*desc & NDR_TABLE_MASK];
2562 /* for some reason interface pointers aren't generated as
2563 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2564 * they still need the derefencing treatment that pointers are
2566 if (*desc == RPC_FC_IP)
2567 m(pStubMsg, *(unsigned char **)pMemory, desc);
2569 m(pStubMsg, pMemory, desc);
2577 FIXME("unhandled format 0x%02x\n", *pFormat);
2585 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2586 PFORMAT_STRING pFormat)
2588 PFORMAT_STRING desc;
2589 unsigned long size = 0;
2591 while (*pFormat != RPC_FC_END) {
2598 safe_buffer_increment(pStubMsg, 1);
2604 safe_buffer_increment(pStubMsg, 2);
2610 safe_buffer_increment(pStubMsg, 4);
2614 safe_buffer_increment(pStubMsg, 8);
2616 case RPC_FC_POINTER:
2618 safe_buffer_increment(pStubMsg, 4);
2619 if (!pStubMsg->IgnoreEmbeddedPointers)
2620 FIXME("embedded pointers\n");
2622 case RPC_FC_ALIGNM4:
2623 ALIGN_LENGTH(size, 4);
2624 ALIGN_POINTER(pStubMsg->Buffer, 4);
2626 case RPC_FC_ALIGNM8:
2627 ALIGN_LENGTH(size, 8);
2628 ALIGN_POINTER(pStubMsg->Buffer, 8);
2630 case RPC_FC_STRUCTPAD1:
2631 case RPC_FC_STRUCTPAD2:
2632 case RPC_FC_STRUCTPAD3:
2633 case RPC_FC_STRUCTPAD4:
2634 case RPC_FC_STRUCTPAD5:
2635 case RPC_FC_STRUCTPAD6:
2636 case RPC_FC_STRUCTPAD7:
2637 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2639 case RPC_FC_EMBEDDED_COMPLEX:
2642 desc = pFormat + *(const SHORT*)pFormat;
2643 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2649 FIXME("unhandled format 0x%02x\n", *pFormat);
2657 static unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg,
2658 PFORMAT_STRING pFormat)
2660 PFORMAT_STRING desc;
2661 unsigned long size = 0;
2663 while (*pFormat != RPC_FC_END) {
2684 case RPC_FC_POINTER:
2685 size += sizeof(void *);
2687 case RPC_FC_ALIGNM4:
2688 ALIGN_LENGTH(size, 4);
2690 case RPC_FC_ALIGNM8:
2691 ALIGN_LENGTH(size, 8);
2693 case RPC_FC_STRUCTPAD1:
2694 case RPC_FC_STRUCTPAD2:
2695 case RPC_FC_STRUCTPAD3:
2696 case RPC_FC_STRUCTPAD4:
2697 case RPC_FC_STRUCTPAD5:
2698 case RPC_FC_STRUCTPAD6:
2699 case RPC_FC_STRUCTPAD7:
2700 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2702 case RPC_FC_EMBEDDED_COMPLEX:
2705 desc = pFormat + *(const SHORT*)pFormat;
2706 size += EmbeddedComplexSize(pStubMsg, desc);
2712 FIXME("unhandled format 0x%02x\n", *pFormat);
2720 /***********************************************************************
2721 * NdrComplexStructMarshall [RPCRT4.@]
2723 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2724 unsigned char *pMemory,
2725 PFORMAT_STRING pFormat)
2727 PFORMAT_STRING conf_array = NULL;
2728 PFORMAT_STRING pointer_desc = NULL;
2729 unsigned char *OldMemory = pStubMsg->Memory;
2730 int pointer_buffer_mark_set = 0;
2732 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2734 if (!pStubMsg->PointerBufferMark)
2736 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2737 /* save buffer length */
2738 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2740 /* get the buffer pointer after complex array data, but before
2742 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2743 pStubMsg->IgnoreEmbeddedPointers = 1;
2744 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2745 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2747 /* save it for use by embedded pointer code later */
2748 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2749 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
2750 pointer_buffer_mark_set = 1;
2752 /* restore the original buffer length */
2753 pStubMsg->BufferLength = saved_buffer_length;
2756 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
2759 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2761 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2764 pStubMsg->Memory = pMemory;
2766 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2769 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2771 pStubMsg->Memory = OldMemory;
2773 if (pointer_buffer_mark_set)
2775 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2776 pStubMsg->PointerBufferMark = NULL;
2779 STD_OVERFLOW_CHECK(pStubMsg);
2784 /***********************************************************************
2785 * NdrComplexStructUnmarshall [RPCRT4.@]
2787 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2788 unsigned char **ppMemory,
2789 PFORMAT_STRING pFormat,
2790 unsigned char fMustAlloc)
2792 unsigned size = *(const WORD*)(pFormat+2);
2793 PFORMAT_STRING conf_array = NULL;
2794 PFORMAT_STRING pointer_desc = NULL;
2795 unsigned char *pMemory;
2796 int pointer_buffer_mark_set = 0;
2798 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2800 if (!pStubMsg->PointerBufferMark)
2802 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2803 /* save buffer pointer */
2804 unsigned char *saved_buffer = pStubMsg->Buffer;
2806 /* get the buffer pointer after complex array data, but before
2808 pStubMsg->IgnoreEmbeddedPointers = 1;
2809 NdrComplexStructMemorySize(pStubMsg, pFormat);
2810 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2812 /* save it for use by embedded pointer code later */
2813 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2814 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
2815 pointer_buffer_mark_set = 1;
2817 /* restore the original buffer */
2818 pStubMsg->Buffer = saved_buffer;
2821 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2823 if (fMustAlloc || !*ppMemory)
2825 *ppMemory = NdrAllocate(pStubMsg, size);
2826 memset(*ppMemory, 0, size);
2830 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2832 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2835 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2838 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2840 if (pointer_buffer_mark_set)
2842 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2843 pStubMsg->PointerBufferMark = NULL;
2849 /***********************************************************************
2850 * NdrComplexStructBufferSize [RPCRT4.@]
2852 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2853 unsigned char *pMemory,
2854 PFORMAT_STRING pFormat)
2856 PFORMAT_STRING conf_array = NULL;
2857 PFORMAT_STRING pointer_desc = NULL;
2858 unsigned char *OldMemory = pStubMsg->Memory;
2859 int pointer_length_set = 0;
2861 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2863 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2865 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2867 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2868 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2870 /* get the buffer length after complex struct data, but before
2872 pStubMsg->IgnoreEmbeddedPointers = 1;
2873 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2874 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2876 /* save it for use by embedded pointer code later */
2877 pStubMsg->PointerLength = pStubMsg->BufferLength;
2878 pointer_length_set = 1;
2879 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
2881 /* restore the original buffer length */
2882 pStubMsg->BufferLength = saved_buffer_length;
2886 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2888 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2891 pStubMsg->Memory = pMemory;
2893 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2896 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2898 pStubMsg->Memory = OldMemory;
2900 if(pointer_length_set)
2902 pStubMsg->BufferLength = pStubMsg->PointerLength;
2903 pStubMsg->PointerLength = 0;
2908 /***********************************************************************
2909 * NdrComplexStructMemorySize [RPCRT4.@]
2911 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2912 PFORMAT_STRING pFormat)
2914 unsigned size = *(const WORD*)(pFormat+2);
2915 PFORMAT_STRING conf_array = NULL;
2916 PFORMAT_STRING pointer_desc = NULL;
2918 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2920 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2923 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2925 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2928 ComplexStructMemorySize(pStubMsg, pFormat);
2931 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2936 /***********************************************************************
2937 * NdrComplexStructFree [RPCRT4.@]
2939 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2940 unsigned char *pMemory,
2941 PFORMAT_STRING pFormat)
2943 PFORMAT_STRING conf_array = NULL;
2944 PFORMAT_STRING pointer_desc = NULL;
2945 unsigned char *OldMemory = pStubMsg->Memory;
2947 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2950 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2952 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2955 pStubMsg->Memory = pMemory;
2957 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2960 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2962 pStubMsg->Memory = OldMemory;
2965 /***********************************************************************
2966 * NdrConformantArrayMarshall [RPCRT4.@]
2968 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2969 unsigned char *pMemory,
2970 PFORMAT_STRING pFormat)
2972 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2973 unsigned char alignment = pFormat[1] + 1;
2975 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2976 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2978 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2980 WriteConformance(pStubMsg);
2982 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
2984 size = safe_multiply(esize, pStubMsg->MaxCount);
2985 pStubMsg->BufferMark = pStubMsg->Buffer;
2986 safe_copy_to_buffer(pStubMsg, pMemory, size);
2988 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2993 /***********************************************************************
2994 * NdrConformantArrayUnmarshall [RPCRT4.@]
2996 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2997 unsigned char **ppMemory,
2998 PFORMAT_STRING pFormat,
2999 unsigned char fMustAlloc)
3001 DWORD size, esize = *(const WORD*)(pFormat+2);
3002 unsigned char alignment = pFormat[1] + 1;
3003 unsigned char *saved_buffer;
3005 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3006 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3008 pFormat = ReadConformance(pStubMsg, pFormat+4);
3010 size = safe_multiply(esize, pStubMsg->MaxCount);
3011 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3014 *ppMemory = NdrAllocate(pStubMsg, size);
3017 if (!pStubMsg->IsClient && !*ppMemory)
3018 /* for servers, we just point straight into the RPC buffer */
3019 *ppMemory = pStubMsg->Buffer;
3022 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3023 safe_buffer_increment(pStubMsg, size);
3024 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3026 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
3027 if (*ppMemory != saved_buffer)
3028 memcpy(*ppMemory, saved_buffer, size);
3033 /***********************************************************************
3034 * NdrConformantArrayBufferSize [RPCRT4.@]
3036 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3037 unsigned char *pMemory,
3038 PFORMAT_STRING pFormat)
3040 DWORD size, esize = *(const WORD*)(pFormat+2);
3041 unsigned char alignment = pFormat[1] + 1;
3043 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3044 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3046 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3048 SizeConformance(pStubMsg);
3050 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3052 size = safe_multiply(esize, pStubMsg->MaxCount);
3053 /* conformance value plus array */
3054 safe_buffer_length_increment(pStubMsg, size);
3056 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3059 /***********************************************************************
3060 * NdrConformantArrayMemorySize [RPCRT4.@]
3062 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3063 PFORMAT_STRING pFormat)
3065 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
3066 unsigned char alignment = pFormat[1] + 1;
3068 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3069 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3071 pFormat = ReadConformance(pStubMsg, pFormat+4);
3072 size = safe_multiply(esize, pStubMsg->MaxCount);
3073 pStubMsg->MemorySize += size;
3075 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3076 pStubMsg->BufferMark = pStubMsg->Buffer;
3077 safe_buffer_increment(pStubMsg, size);
3079 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3081 return pStubMsg->MemorySize;
3084 /***********************************************************************
3085 * NdrConformantArrayFree [RPCRT4.@]
3087 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3088 unsigned char *pMemory,
3089 PFORMAT_STRING pFormat)
3091 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3092 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3094 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3096 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3100 /***********************************************************************
3101 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3103 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
3104 unsigned char* pMemory,
3105 PFORMAT_STRING pFormat )
3108 unsigned char alignment = pFormat[1] + 1;
3109 DWORD esize = *(const WORD*)(pFormat+2);
3111 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3113 if (pFormat[0] != RPC_FC_CVARRAY)
3115 ERR("invalid format type %x\n", pFormat[0]);
3116 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3120 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3121 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3123 WriteConformance(pStubMsg);
3124 WriteVariance(pStubMsg);
3126 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3128 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3130 pStubMsg->BufferMark = pStubMsg->Buffer;
3131 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
3133 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3139 /***********************************************************************
3140 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3142 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
3143 unsigned char** ppMemory,
3144 PFORMAT_STRING pFormat,
3145 unsigned char fMustAlloc )
3147 ULONG bufsize, memsize;
3148 unsigned char alignment = pFormat[1] + 1;
3149 DWORD esize = *(const WORD*)(pFormat+2);
3150 unsigned char *saved_buffer;
3153 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3155 if (pFormat[0] != RPC_FC_CVARRAY)
3157 ERR("invalid format type %x\n", pFormat[0]);
3158 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3162 pFormat = ReadConformance(pStubMsg, pFormat+4);
3163 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3165 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3167 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3168 memsize = safe_multiply(esize, pStubMsg->MaxCount);
3169 offset = pStubMsg->Offset;
3171 if (!*ppMemory || fMustAlloc)
3172 *ppMemory = NdrAllocate(pStubMsg, memsize);
3173 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3174 safe_buffer_increment(pStubMsg, bufsize);
3176 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3178 memcpy(*ppMemory + offset, saved_buffer, bufsize);
3184 /***********************************************************************
3185 * NdrConformantVaryingArrayFree [RPCRT4.@]
3187 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
3188 unsigned char* pMemory,
3189 PFORMAT_STRING pFormat )
3191 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3193 if (pFormat[0] != RPC_FC_CVARRAY)
3195 ERR("invalid format type %x\n", pFormat[0]);
3196 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3200 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3201 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3203 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3207 /***********************************************************************
3208 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3210 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
3211 unsigned char* pMemory, PFORMAT_STRING pFormat )
3213 unsigned char alignment = pFormat[1] + 1;
3214 DWORD esize = *(const WORD*)(pFormat+2);
3216 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3218 if (pFormat[0] != RPC_FC_CVARRAY)
3220 ERR("invalid format type %x\n", pFormat[0]);
3221 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3226 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3227 /* compute length */
3228 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3230 SizeConformance(pStubMsg);
3231 SizeVariance(pStubMsg);
3233 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3235 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
3237 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3241 /***********************************************************************
3242 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3244 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
3245 PFORMAT_STRING pFormat )
3247 ULONG bufsize, memsize;
3248 unsigned char alignment = pFormat[1] + 1;
3249 DWORD esize = *(const WORD*)(pFormat+2);
3251 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3253 if (pFormat[0] != RPC_FC_CVARRAY)
3255 ERR("invalid format type %x\n", pFormat[0]);
3256 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3257 return pStubMsg->MemorySize;
3260 pFormat = ReadConformance(pStubMsg, pFormat+4);
3261 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3263 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3265 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3266 memsize = safe_multiply(esize, pStubMsg->MaxCount);
3268 safe_buffer_increment(pStubMsg, bufsize);
3269 pStubMsg->MemorySize += memsize;
3271 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3273 return pStubMsg->MemorySize;
3277 /***********************************************************************
3278 * NdrComplexArrayMarshall [RPCRT4.@]
3280 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3281 unsigned char *pMemory,
3282 PFORMAT_STRING pFormat)
3284 ULONG i, count, def;
3285 BOOL variance_present;
3286 unsigned char alignment;
3287 int pointer_buffer_mark_set = 0;
3289 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3291 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3293 ERR("invalid format type %x\n", pFormat[0]);
3294 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3298 alignment = pFormat[1] + 1;
3300 if (!pStubMsg->PointerBufferMark)
3302 /* save buffer fields that may be changed by buffer sizer functions
3303 * and that may be needed later on */
3304 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3305 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3306 unsigned long saved_max_count = pStubMsg->MaxCount;
3307 unsigned long saved_offset = pStubMsg->Offset;
3308 unsigned long saved_actual_count = pStubMsg->ActualCount;
3310 /* get the buffer pointer after complex array data, but before
3312 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3313 pStubMsg->IgnoreEmbeddedPointers = 1;
3314 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3315 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3317 /* save it for use by embedded pointer code later */
3318 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3319 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
3320 pointer_buffer_mark_set = 1;
3322 /* restore fields */
3323 pStubMsg->ActualCount = saved_actual_count;
3324 pStubMsg->Offset = saved_offset;
3325 pStubMsg->MaxCount = saved_max_count;
3326 pStubMsg->BufferLength = saved_buffer_length;
3329 def = *(const WORD*)&pFormat[2];
3332 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3333 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3335 variance_present = IsConformanceOrVariancePresent(pFormat);
3336 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3337 TRACE("variance = %d\n", pStubMsg->ActualCount);
3339 WriteConformance(pStubMsg);
3340 if (variance_present)
3341 WriteVariance(pStubMsg);
3343 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3345 count = pStubMsg->ActualCount;
3346 for (i = 0; i < count; i++)
3347 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3349 STD_OVERFLOW_CHECK(pStubMsg);
3351 if (pointer_buffer_mark_set)
3353 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3354 pStubMsg->PointerBufferMark = NULL;
3360 /***********************************************************************
3361 * NdrComplexArrayUnmarshall [RPCRT4.@]
3363 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3364 unsigned char **ppMemory,
3365 PFORMAT_STRING pFormat,
3366 unsigned char fMustAlloc)
3368 ULONG i, count, size;
3369 unsigned char alignment;
3370 unsigned char *pMemory;
3371 unsigned char *saved_buffer;
3372 int pointer_buffer_mark_set = 0;
3373 int saved_ignore_embedded;
3375 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3377 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3379 ERR("invalid format type %x\n", pFormat[0]);
3380 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3384 alignment = pFormat[1] + 1;
3386 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3387 /* save buffer pointer */
3388 saved_buffer = pStubMsg->Buffer;
3389 /* get the buffer pointer after complex array data, but before
3391 pStubMsg->IgnoreEmbeddedPointers = 1;
3392 pStubMsg->MemorySize = 0;
3393 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3394 size = pStubMsg->MemorySize;
3395 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3397 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
3398 if (!pStubMsg->PointerBufferMark)
3400 /* save it for use by embedded pointer code later */
3401 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3402 pointer_buffer_mark_set = 1;
3404 /* restore the original buffer */
3405 pStubMsg->Buffer = saved_buffer;
3409 pFormat = ReadConformance(pStubMsg, pFormat);
3410 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3412 if (fMustAlloc || !*ppMemory)
3414 *ppMemory = NdrAllocate(pStubMsg, size);
3415 memset(*ppMemory, 0, size);
3418 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3420 pMemory = *ppMemory;
3421 count = pStubMsg->ActualCount;
3422 for (i = 0; i < count; i++)
3423 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
3425 if (pointer_buffer_mark_set)
3427 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3428 pStubMsg->PointerBufferMark = NULL;
3434 /***********************************************************************
3435 * NdrComplexArrayBufferSize [RPCRT4.@]
3437 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3438 unsigned char *pMemory,
3439 PFORMAT_STRING pFormat)
3441 ULONG i, count, def;
3442 unsigned char alignment;
3443 BOOL variance_present;
3444 int pointer_length_set = 0;
3446 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3448 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3450 ERR("invalid format type %x\n", pFormat[0]);
3451 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3455 alignment = pFormat[1] + 1;
3457 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3459 /* save buffer fields that may be changed by buffer sizer functions
3460 * and that may be needed later on */
3461 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3462 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3463 unsigned long saved_max_count = pStubMsg->MaxCount;
3464 unsigned long saved_offset = pStubMsg->Offset;
3465 unsigned long saved_actual_count = pStubMsg->ActualCount;
3467 /* get the buffer pointer after complex array data, but before
3469 pStubMsg->IgnoreEmbeddedPointers = 1;
3470 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3471 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3473 /* save it for use by embedded pointer code later */
3474 pStubMsg->PointerLength = pStubMsg->BufferLength;
3475 pointer_length_set = 1;
3477 /* restore fields */
3478 pStubMsg->ActualCount = saved_actual_count;
3479 pStubMsg->Offset = saved_offset;
3480 pStubMsg->MaxCount = saved_max_count;
3481 pStubMsg->BufferLength = saved_buffer_length;
3483 def = *(const WORD*)&pFormat[2];
3486 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3487 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3488 SizeConformance(pStubMsg);
3490 variance_present = IsConformanceOrVariancePresent(pFormat);
3491 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3492 TRACE("variance = %d\n", pStubMsg->ActualCount);
3494 if (variance_present)
3495 SizeVariance(pStubMsg);
3497 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3499 count = pStubMsg->ActualCount;
3500 for (i = 0; i < count; i++)
3501 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
3503 if(pointer_length_set)
3505 pStubMsg->BufferLength = pStubMsg->PointerLength;
3506 pStubMsg->PointerLength = 0;
3510 /***********************************************************************
3511 * NdrComplexArrayMemorySize [RPCRT4.@]
3513 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3514 PFORMAT_STRING pFormat)
3516 ULONG i, count, esize, SavedMemorySize, MemorySize;
3517 unsigned char alignment;
3519 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3521 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3523 ERR("invalid format type %x\n", pFormat[0]);
3524 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3528 alignment = pFormat[1] + 1;
3532 pFormat = ReadConformance(pStubMsg, pFormat);
3533 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3535 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3537 SavedMemorySize = pStubMsg->MemorySize;
3539 esize = ComplexStructSize(pStubMsg, pFormat);
3541 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
3543 count = pStubMsg->ActualCount;
3544 for (i = 0; i < count; i++)
3545 ComplexStructMemorySize(pStubMsg, pFormat);
3547 pStubMsg->MemorySize = SavedMemorySize;
3549 pStubMsg->MemorySize += MemorySize;
3553 /***********************************************************************
3554 * NdrComplexArrayFree [RPCRT4.@]
3556 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3557 unsigned char *pMemory,
3558 PFORMAT_STRING pFormat)
3560 ULONG i, count, def;
3562 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3564 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3566 ERR("invalid format type %x\n", pFormat[0]);
3567 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3571 def = *(const WORD*)&pFormat[2];
3574 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3575 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3577 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3578 TRACE("variance = %d\n", pStubMsg->ActualCount);
3580 count = pStubMsg->ActualCount;
3581 for (i = 0; i < count; i++)
3582 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
3585 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
3586 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
3587 USER_MARSHAL_CB *umcb)
3589 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
3590 pStubMsg->RpcMsg->DataRepresentation);
3591 umcb->pStubMsg = pStubMsg;
3592 umcb->pReserve = NULL;
3593 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
3594 umcb->CBType = cbtype;
3595 umcb->pFormat = pFormat;
3596 umcb->pTypeFormat = NULL /* FIXME */;
3599 #define USER_MARSHAL_PTR_PREFIX \
3600 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3601 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3603 /***********************************************************************
3604 * NdrUserMarshalMarshall [RPCRT4.@]
3606 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3607 unsigned char *pMemory,
3608 PFORMAT_STRING pFormat)
3610 unsigned flags = pFormat[1];
3611 unsigned index = *(const WORD*)&pFormat[2];
3612 unsigned char *saved_buffer = NULL;
3613 USER_MARSHAL_CB umcb;
3615 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3616 TRACE("index=%d\n", index);
3618 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
3620 if (flags & USER_MARSHAL_POINTER)
3622 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
3623 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
3624 pStubMsg->Buffer += 4;
3625 if (pStubMsg->PointerBufferMark)
3627 saved_buffer = pStubMsg->Buffer;
3628 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3629 pStubMsg->PointerBufferMark = NULL;
3631 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
3634 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
3637 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
3638 &umcb.Flags, pStubMsg->Buffer, pMemory);
3642 STD_OVERFLOW_CHECK(pStubMsg);
3643 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3644 pStubMsg->Buffer = saved_buffer;
3647 STD_OVERFLOW_CHECK(pStubMsg);
3652 /***********************************************************************
3653 * NdrUserMarshalUnmarshall [RPCRT4.@]
3655 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3656 unsigned char **ppMemory,
3657 PFORMAT_STRING pFormat,
3658 unsigned char fMustAlloc)
3660 unsigned flags = pFormat[1];
3661 unsigned index = *(const WORD*)&pFormat[2];
3662 DWORD memsize = *(const WORD*)&pFormat[4];
3663 unsigned char *saved_buffer = NULL;
3664 USER_MARSHAL_CB umcb;
3666 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3667 TRACE("index=%d\n", index);
3669 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
3671 if (flags & USER_MARSHAL_POINTER)
3673 ALIGN_POINTER(pStubMsg->Buffer, 4);
3674 /* skip pointer prefix */
3675 pStubMsg->Buffer += 4;
3676 if (pStubMsg->PointerBufferMark)
3678 saved_buffer = pStubMsg->Buffer;
3679 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3680 pStubMsg->PointerBufferMark = NULL;
3682 ALIGN_POINTER(pStubMsg->Buffer, 8);
3685 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3687 if (fMustAlloc || !*ppMemory)
3688 *ppMemory = NdrAllocate(pStubMsg, memsize);
3691 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
3692 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
3696 STD_OVERFLOW_CHECK(pStubMsg);
3697 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3698 pStubMsg->Buffer = saved_buffer;
3704 /***********************************************************************
3705 * NdrUserMarshalBufferSize [RPCRT4.@]
3707 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3708 unsigned char *pMemory,
3709 PFORMAT_STRING pFormat)
3711 unsigned flags = pFormat[1];
3712 unsigned index = *(const WORD*)&pFormat[2];
3713 DWORD bufsize = *(const WORD*)&pFormat[6];
3714 USER_MARSHAL_CB umcb;
3715 unsigned long saved_buffer_length = 0;
3717 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3718 TRACE("index=%d\n", index);
3720 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
3722 if (flags & USER_MARSHAL_POINTER)
3724 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3725 /* skip pointer prefix */
3726 safe_buffer_length_increment(pStubMsg, 4);
3727 if (pStubMsg->IgnoreEmbeddedPointers)
3729 if (pStubMsg->PointerLength)
3731 saved_buffer_length = pStubMsg->BufferLength;
3732 pStubMsg->BufferLength = pStubMsg->PointerLength;
3733 pStubMsg->PointerLength = 0;
3735 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
3738 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
3741 TRACE("size=%d\n", bufsize);
3742 safe_buffer_length_increment(pStubMsg, bufsize);
3745 pStubMsg->BufferLength =
3746 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
3747 &umcb.Flags, pStubMsg->BufferLength, pMemory);
3749 if (saved_buffer_length)
3751 pStubMsg->PointerLength = pStubMsg->BufferLength;
3752 pStubMsg->BufferLength = saved_buffer_length;
3757 /***********************************************************************
3758 * NdrUserMarshalMemorySize [RPCRT4.@]
3760 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3761 PFORMAT_STRING pFormat)
3763 unsigned flags = pFormat[1];
3764 unsigned index = *(const WORD*)&pFormat[2];
3765 DWORD memsize = *(const WORD*)&pFormat[4];
3766 DWORD bufsize = *(const WORD*)&pFormat[6];
3768 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3769 TRACE("index=%d\n", index);
3771 pStubMsg->MemorySize += memsize;
3773 if (flags & USER_MARSHAL_POINTER)
3775 ALIGN_POINTER(pStubMsg->Buffer, 4);
3776 /* skip pointer prefix */
3777 pStubMsg->Buffer += 4;
3778 if (pStubMsg->IgnoreEmbeddedPointers)
3779 return pStubMsg->MemorySize;
3780 ALIGN_POINTER(pStubMsg->Buffer, 8);
3783 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3786 FIXME("not implemented for varying buffer size\n");
3788 pStubMsg->Buffer += bufsize;
3790 return pStubMsg->MemorySize;
3793 /***********************************************************************
3794 * NdrUserMarshalFree [RPCRT4.@]
3796 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
3797 unsigned char *pMemory,
3798 PFORMAT_STRING pFormat)
3800 /* unsigned flags = pFormat[1]; */
3801 unsigned index = *(const WORD*)&pFormat[2];
3802 USER_MARSHAL_CB umcb;
3804 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3805 TRACE("index=%d\n", index);
3807 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
3809 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
3810 &umcb.Flags, pMemory);
3813 /***********************************************************************
3814 * NdrClearOutParameters [RPCRT4.@]
3816 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
3817 PFORMAT_STRING pFormat,
3820 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
3823 /***********************************************************************
3824 * NdrConvert [RPCRT4.@]
3826 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
3828 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
3829 /* FIXME: since this stub doesn't do any converting, the proper behavior
3830 is to raise an exception */
3833 /***********************************************************************
3834 * NdrConvert2 [RPCRT4.@]
3836 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
3838 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3839 pStubMsg, pFormat, NumberParams);
3840 /* FIXME: since this stub doesn't do any converting, the proper behavior
3841 is to raise an exception */
3844 #include "pshpack1.h"
3845 typedef struct _NDR_CSTRUCT_FORMAT
3848 unsigned char alignment;
3849 unsigned short memory_size;
3850 short offset_to_array_description;
3851 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
3852 #include "poppack.h"
3854 /***********************************************************************
3855 * NdrConformantStructMarshall [RPCRT4.@]
3857 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3858 unsigned char *pMemory,
3859 PFORMAT_STRING pFormat)
3861 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3862 PFORMAT_STRING pCArrayFormat;
3863 ULONG esize, bufsize;
3865 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3867 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3868 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3870 ERR("invalid format type %x\n", pCStructFormat->type);
3871 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3875 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3876 pCStructFormat->offset_to_array_description;
3877 if (*pCArrayFormat != RPC_FC_CARRAY)
3879 ERR("invalid array format type %x\n", pCStructFormat->type);
3880 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3883 esize = *(const WORD*)(pCArrayFormat+2);
3885 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3886 pCArrayFormat + 4, 0);
3888 WriteConformance(pStubMsg);
3890 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3892 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3894 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3895 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3897 ERR("integer overflow of memory_size %u with bufsize %u\n",
3898 pCStructFormat->memory_size, bufsize);
3899 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3901 /* copy constant sized part of struct */
3902 pStubMsg->BufferMark = pStubMsg->Buffer;
3903 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
3905 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3906 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3911 /***********************************************************************
3912 * NdrConformantStructUnmarshall [RPCRT4.@]
3914 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3915 unsigned char **ppMemory,
3916 PFORMAT_STRING pFormat,
3917 unsigned char fMustAlloc)
3919 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3920 PFORMAT_STRING pCArrayFormat;
3921 ULONG esize, bufsize;
3922 unsigned char *saved_buffer;
3924 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3926 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3927 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3929 ERR("invalid format type %x\n", pCStructFormat->type);
3930 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3933 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3934 pCStructFormat->offset_to_array_description;
3935 if (*pCArrayFormat != RPC_FC_CARRAY)
3937 ERR("invalid array format type %x\n", pCStructFormat->type);
3938 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3941 esize = *(const WORD*)(pCArrayFormat+2);
3943 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3945 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3947 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3949 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3950 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3952 ERR("integer overflow of memory_size %u with bufsize %u\n",
3953 pCStructFormat->memory_size, bufsize);
3954 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3959 SIZE_T size = pCStructFormat->memory_size + bufsize;
3960 *ppMemory = NdrAllocate(pStubMsg, size);
3964 if (!pStubMsg->IsClient && !*ppMemory)
3965 /* for servers, we just point straight into the RPC buffer */
3966 *ppMemory = pStubMsg->Buffer;
3969 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3970 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
3971 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3972 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3974 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
3975 if (*ppMemory != saved_buffer)
3976 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
3981 /***********************************************************************
3982 * NdrConformantStructBufferSize [RPCRT4.@]
3984 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3985 unsigned char *pMemory,
3986 PFORMAT_STRING pFormat)
3988 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3989 PFORMAT_STRING pCArrayFormat;
3992 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3994 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3995 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3997 ERR("invalid format type %x\n", pCStructFormat->type);
3998 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4001 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4002 pCStructFormat->offset_to_array_description;
4003 if (*pCArrayFormat != RPC_FC_CARRAY)
4005 ERR("invalid array format type %x\n", pCStructFormat->type);
4006 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4009 esize = *(const WORD*)(pCArrayFormat+2);
4011 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4012 SizeConformance(pStubMsg);
4014 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4016 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4018 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4019 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4021 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4022 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4025 /***********************************************************************
4026 * NdrConformantStructMemorySize [RPCRT4.@]
4028 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4029 PFORMAT_STRING pFormat)
4035 /***********************************************************************
4036 * NdrConformantStructFree [RPCRT4.@]
4038 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4039 unsigned char *pMemory,
4040 PFORMAT_STRING pFormat)
4042 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4043 PFORMAT_STRING pCArrayFormat;
4046 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4048 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4049 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4051 ERR("invalid format type %x\n", pCStructFormat->type);
4052 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4056 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4057 pCStructFormat->offset_to_array_description;
4058 if (*pCArrayFormat != RPC_FC_CARRAY)
4060 ERR("invalid array format type %x\n", pCStructFormat->type);
4061 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4064 esize = *(const WORD*)(pCArrayFormat+2);
4066 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4067 pCArrayFormat + 4, 0);
4069 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4071 /* copy constant sized part of struct */
4072 pStubMsg->BufferMark = pStubMsg->Buffer;
4074 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4075 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4078 /***********************************************************************
4079 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4081 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4082 unsigned char *pMemory,
4083 PFORMAT_STRING pFormat)
4085 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4086 PFORMAT_STRING pCVArrayFormat;
4087 ULONG esize, bufsize;
4089 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4091 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4092 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4094 ERR("invalid format type %x\n", pCVStructFormat->type);
4095 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4099 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4100 pCVStructFormat->offset_to_array_description;
4101 switch (*pCVArrayFormat)
4103 case RPC_FC_CVARRAY:
4104 esize = *(const WORD*)(pCVArrayFormat+2);
4106 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4107 pCVArrayFormat + 4, 0);
4108 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4111 case RPC_FC_C_CSTRING:
4112 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4113 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4114 esize = sizeof(char);
4115 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4116 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4117 pCVArrayFormat + 2, 0);
4119 pStubMsg->MaxCount = pStubMsg->ActualCount;
4121 case RPC_FC_C_WSTRING:
4122 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4123 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4124 esize = sizeof(WCHAR);
4125 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4126 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4127 pCVArrayFormat + 2, 0);
4129 pStubMsg->MaxCount = pStubMsg->ActualCount;
4132 ERR("invalid array format type %x\n", *pCVArrayFormat);
4133 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4137 WriteConformance(pStubMsg);
4139 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4141 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4143 /* write constant sized part */
4144 pStubMsg->BufferMark = pStubMsg->Buffer;
4145 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4147 WriteVariance(pStubMsg);
4149 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4151 /* write array part */
4152 safe_copy_to_buffer(pStubMsg, pMemory + pCVStructFormat->memory_size, bufsize);
4154 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4159 /***********************************************************************
4160 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4162 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4163 unsigned char **ppMemory,
4164 PFORMAT_STRING pFormat,
4165 unsigned char fMustAlloc)
4167 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4168 PFORMAT_STRING pCVArrayFormat;
4169 ULONG esize, bufsize;
4170 unsigned char cvarray_type;
4172 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4174 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4175 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4177 ERR("invalid format type %x\n", pCVStructFormat->type);
4178 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4182 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4183 pCVStructFormat->offset_to_array_description;
4184 cvarray_type = *pCVArrayFormat;
4185 switch (cvarray_type)
4187 case RPC_FC_CVARRAY:
4188 esize = *(const WORD*)(pCVArrayFormat+2);
4189 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4191 case RPC_FC_C_CSTRING:
4192 esize = sizeof(char);
4193 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4194 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4196 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4198 case RPC_FC_C_WSTRING:
4199 esize = sizeof(WCHAR);
4200 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4201 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4203 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4206 ERR("invalid array format type %x\n", *pCVArrayFormat);
4207 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4211 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4213 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4215 /* work out how much memory to allocate if we need to do so */
4216 if (!*ppMemory || fMustAlloc)
4218 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4219 *ppMemory = NdrAllocate(pStubMsg, size);
4222 /* copy the constant data */
4223 pStubMsg->BufferMark = pStubMsg->Buffer;
4224 safe_copy_from_buffer(pStubMsg, *ppMemory, pCVStructFormat->memory_size);
4226 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4228 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4230 if ((cvarray_type == RPC_FC_C_CSTRING) ||
4231 (cvarray_type == RPC_FC_C_WSTRING))
4234 /* strings must always have null terminating bytes */
4235 if (bufsize < esize)
4237 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
4238 RpcRaiseException(RPC_S_INVALID_BOUND);
4241 for (i = bufsize - esize; i < bufsize; i++)
4242 if (pStubMsg->Buffer[i] != 0)
4244 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
4245 i, pStubMsg->Buffer[i]);
4246 RpcRaiseException(RPC_S_INVALID_BOUND);
4251 /* copy the array data */
4252 safe_copy_from_buffer(pStubMsg, *ppMemory + pCVStructFormat->memory_size, bufsize);
4254 if (cvarray_type == RPC_FC_C_CSTRING)
4255 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
4256 else if (cvarray_type == RPC_FC_C_WSTRING)
4257 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
4259 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
4264 /***********************************************************************
4265 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4267 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4268 unsigned char *pMemory,
4269 PFORMAT_STRING pFormat)
4271 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4272 PFORMAT_STRING pCVArrayFormat;
4275 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4277 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4278 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4280 ERR("invalid format type %x\n", pCVStructFormat->type);
4281 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4285 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4286 pCVStructFormat->offset_to_array_description;
4287 switch (*pCVArrayFormat)
4289 case RPC_FC_CVARRAY:
4290 esize = *(const WORD*)(pCVArrayFormat+2);
4292 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4293 pCVArrayFormat + 4, 0);
4294 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4297 case RPC_FC_C_CSTRING:
4298 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4299 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4300 esize = sizeof(char);
4301 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4302 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4303 pCVArrayFormat + 2, 0);
4305 pStubMsg->MaxCount = pStubMsg->ActualCount;
4307 case RPC_FC_C_WSTRING:
4308 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4309 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4310 esize = sizeof(WCHAR);
4311 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4312 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4313 pCVArrayFormat + 2, 0);
4315 pStubMsg->MaxCount = pStubMsg->ActualCount;
4318 ERR("invalid array format type %x\n", *pCVArrayFormat);
4319 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4323 SizeConformance(pStubMsg);
4325 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4327 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4329 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4330 SizeVariance(pStubMsg);
4331 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4333 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4336 /***********************************************************************
4337 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4339 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4340 PFORMAT_STRING pFormat)
4342 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4343 PFORMAT_STRING pCVArrayFormat;
4345 unsigned char cvarray_type;
4347 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4349 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4350 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4352 ERR("invalid format type %x\n", pCVStructFormat->type);
4353 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4357 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4358 pCVStructFormat->offset_to_array_description;
4359 cvarray_type = *pCVArrayFormat;
4360 switch (cvarray_type)
4362 case RPC_FC_CVARRAY:
4363 esize = *(const WORD*)(pCVArrayFormat+2);
4364 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4366 case RPC_FC_C_CSTRING:
4367 esize = sizeof(char);
4368 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4369 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4371 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4373 case RPC_FC_C_WSTRING:
4374 esize = sizeof(WCHAR);
4375 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4376 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4378 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4381 ERR("invalid array format type %x\n", *pCVArrayFormat);
4382 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4386 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4388 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4390 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4391 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4392 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4394 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4396 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4398 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
4401 /***********************************************************************
4402 * NdrConformantVaryingStructFree [RPCRT4.@]
4404 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4405 unsigned char *pMemory,
4406 PFORMAT_STRING pFormat)
4408 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4409 PFORMAT_STRING pCVArrayFormat;
4412 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4414 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4415 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4417 ERR("invalid format type %x\n", pCVStructFormat->type);
4418 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4422 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4423 pCVStructFormat->offset_to_array_description;
4424 switch (*pCVArrayFormat)
4426 case RPC_FC_CVARRAY:
4427 esize = *(const WORD*)(pCVArrayFormat+2);
4429 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4430 pCVArrayFormat + 4, 0);
4431 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4434 case RPC_FC_C_CSTRING:
4435 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4436 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4437 esize = sizeof(char);
4438 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4439 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4440 pCVArrayFormat + 2, 0);
4442 pStubMsg->MaxCount = pStubMsg->ActualCount;
4444 case RPC_FC_C_WSTRING:
4445 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4446 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4447 esize = sizeof(WCHAR);
4448 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4449 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4450 pCVArrayFormat + 2, 0);
4452 pStubMsg->MaxCount = pStubMsg->ActualCount;
4455 ERR("invalid array format type %x\n", *pCVArrayFormat);
4456 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4460 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4462 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4465 #include "pshpack1.h"
4469 unsigned char alignment;
4470 unsigned short total_size;
4471 } NDR_SMFARRAY_FORMAT;
4476 unsigned char alignment;
4477 unsigned long total_size;
4478 } NDR_LGFARRAY_FORMAT;
4479 #include "poppack.h"
4481 /***********************************************************************
4482 * NdrFixedArrayMarshall [RPCRT4.@]
4484 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4485 unsigned char *pMemory,
4486 PFORMAT_STRING pFormat)
4488 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4489 unsigned long total_size;
4491 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4493 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4494 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4496 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4497 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4501 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4503 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4505 total_size = pSmFArrayFormat->total_size;
4506 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4510 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4511 total_size = pLgFArrayFormat->total_size;
4512 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4515 pStubMsg->BufferMark = pStubMsg->Buffer;
4516 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4518 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4523 /***********************************************************************
4524 * NdrFixedArrayUnmarshall [RPCRT4.@]
4526 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4527 unsigned char **ppMemory,
4528 PFORMAT_STRING pFormat,
4529 unsigned char fMustAlloc)
4531 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4532 unsigned long total_size;
4533 unsigned char *saved_buffer;
4535 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4537 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4538 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4540 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4541 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4545 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4547 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4549 total_size = pSmFArrayFormat->total_size;
4550 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4554 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4555 total_size = pLgFArrayFormat->total_size;
4556 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4560 *ppMemory = NdrAllocate(pStubMsg, total_size);
4563 if (!pStubMsg->IsClient && !*ppMemory)
4564 /* for servers, we just point straight into the RPC buffer */
4565 *ppMemory = pStubMsg->Buffer;
4568 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4569 safe_buffer_increment(pStubMsg, total_size);
4570 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4572 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4573 if (*ppMemory != saved_buffer)
4574 memcpy(*ppMemory, saved_buffer, total_size);
4579 /***********************************************************************
4580 * NdrFixedArrayBufferSize [RPCRT4.@]
4582 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4583 unsigned char *pMemory,
4584 PFORMAT_STRING pFormat)
4586 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4587 unsigned long total_size;
4589 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4591 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4592 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4594 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4595 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4599 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4601 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4603 total_size = pSmFArrayFormat->total_size;
4604 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4608 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4609 total_size = pLgFArrayFormat->total_size;
4610 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4612 safe_buffer_length_increment(pStubMsg, total_size);
4614 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4617 /***********************************************************************
4618 * NdrFixedArrayMemorySize [RPCRT4.@]
4620 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4621 PFORMAT_STRING pFormat)
4623 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4626 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4628 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4629 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4631 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4632 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4636 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4638 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4640 total_size = pSmFArrayFormat->total_size;
4641 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4645 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4646 total_size = pLgFArrayFormat->total_size;
4647 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4649 pStubMsg->BufferMark = pStubMsg->Buffer;
4650 safe_buffer_increment(pStubMsg, total_size);
4651 pStubMsg->MemorySize += total_size;
4653 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4658 /***********************************************************************
4659 * NdrFixedArrayFree [RPCRT4.@]
4661 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4662 unsigned char *pMemory,
4663 PFORMAT_STRING pFormat)
4665 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4667 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4669 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4670 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4672 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4673 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4677 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4678 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4681 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4682 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4685 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4688 /***********************************************************************
4689 * NdrVaryingArrayMarshall [RPCRT4.@]
4691 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4692 unsigned char *pMemory,
4693 PFORMAT_STRING pFormat)
4695 unsigned char alignment;
4696 DWORD elements, esize;
4699 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4701 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4702 (pFormat[0] != RPC_FC_LGVARRAY))
4704 ERR("invalid format type %x\n", pFormat[0]);
4705 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4709 alignment = pFormat[1] + 1;
4711 if (pFormat[0] == RPC_FC_SMVARRAY)
4714 pFormat += sizeof(WORD);
4715 elements = *(const WORD*)pFormat;
4716 pFormat += sizeof(WORD);
4721 pFormat += sizeof(DWORD);
4722 elements = *(const DWORD*)pFormat;
4723 pFormat += sizeof(DWORD);
4726 esize = *(const WORD*)pFormat;
4727 pFormat += sizeof(WORD);
4729 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4730 if ((pStubMsg->ActualCount > elements) ||
4731 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4733 RpcRaiseException(RPC_S_INVALID_BOUND);
4737 WriteVariance(pStubMsg);
4739 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
4741 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4742 pStubMsg->BufferMark = pStubMsg->Buffer;
4743 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
4745 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4750 /***********************************************************************
4751 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4753 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4754 unsigned char **ppMemory,
4755 PFORMAT_STRING pFormat,
4756 unsigned char fMustAlloc)
4758 unsigned char alignment;
4759 DWORD size, elements, esize;
4761 unsigned char *saved_buffer;
4764 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4766 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4767 (pFormat[0] != RPC_FC_LGVARRAY))
4769 ERR("invalid format type %x\n", pFormat[0]);
4770 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4774 alignment = pFormat[1] + 1;
4776 if (pFormat[0] == RPC_FC_SMVARRAY)
4779 size = *(const WORD*)pFormat;
4780 pFormat += sizeof(WORD);
4781 elements = *(const WORD*)pFormat;
4782 pFormat += sizeof(WORD);
4787 size = *(const DWORD*)pFormat;
4788 pFormat += sizeof(DWORD);
4789 elements = *(const DWORD*)pFormat;
4790 pFormat += sizeof(DWORD);
4793 esize = *(const WORD*)pFormat;
4794 pFormat += sizeof(WORD);
4796 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4798 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4800 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4801 offset = pStubMsg->Offset;
4803 if (!*ppMemory || fMustAlloc)
4804 *ppMemory = NdrAllocate(pStubMsg, size);
4805 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4806 safe_buffer_increment(pStubMsg, bufsize);
4808 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4810 memcpy(*ppMemory + offset, saved_buffer, bufsize);
4815 /***********************************************************************
4816 * NdrVaryingArrayBufferSize [RPCRT4.@]
4818 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4819 unsigned char *pMemory,
4820 PFORMAT_STRING pFormat)
4822 unsigned char alignment;
4823 DWORD elements, esize;
4825 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4827 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4828 (pFormat[0] != RPC_FC_LGVARRAY))
4830 ERR("invalid format type %x\n", pFormat[0]);
4831 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4835 alignment = pFormat[1] + 1;
4837 if (pFormat[0] == RPC_FC_SMVARRAY)
4840 pFormat += sizeof(WORD);
4841 elements = *(const WORD*)pFormat;
4842 pFormat += sizeof(WORD);
4847 pFormat += sizeof(DWORD);
4848 elements = *(const DWORD*)pFormat;
4849 pFormat += sizeof(DWORD);
4852 esize = *(const WORD*)pFormat;
4853 pFormat += sizeof(WORD);
4855 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4856 if ((pStubMsg->ActualCount > elements) ||
4857 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4859 RpcRaiseException(RPC_S_INVALID_BOUND);
4863 SizeVariance(pStubMsg);
4865 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4867 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4869 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4872 /***********************************************************************
4873 * NdrVaryingArrayMemorySize [RPCRT4.@]
4875 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4876 PFORMAT_STRING pFormat)
4878 unsigned char alignment;
4879 DWORD size, elements, esize;
4881 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4883 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4884 (pFormat[0] != RPC_FC_LGVARRAY))
4886 ERR("invalid format type %x\n", pFormat[0]);
4887 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4891 alignment = pFormat[1] + 1;
4893 if (pFormat[0] == RPC_FC_SMVARRAY)
4896 size = *(const WORD*)pFormat;
4897 pFormat += sizeof(WORD);
4898 elements = *(const WORD*)pFormat;
4899 pFormat += sizeof(WORD);
4904 size = *(const DWORD*)pFormat;
4905 pFormat += sizeof(DWORD);
4906 elements = *(const DWORD*)pFormat;
4907 pFormat += sizeof(DWORD);
4910 esize = *(const WORD*)pFormat;
4911 pFormat += sizeof(WORD);
4913 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4915 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4917 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4918 pStubMsg->MemorySize += size;
4920 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4922 return pStubMsg->MemorySize;
4925 /***********************************************************************
4926 * NdrVaryingArrayFree [RPCRT4.@]
4928 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4929 unsigned char *pMemory,
4930 PFORMAT_STRING pFormat)
4932 unsigned char alignment;
4935 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4937 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4938 (pFormat[0] != RPC_FC_LGVARRAY))
4940 ERR("invalid format type %x\n", pFormat[0]);
4941 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4945 alignment = pFormat[1] + 1;
4947 if (pFormat[0] == RPC_FC_SMVARRAY)
4950 pFormat += sizeof(WORD);
4951 elements = *(const WORD*)pFormat;
4952 pFormat += sizeof(WORD);
4957 pFormat += sizeof(DWORD);
4958 elements = *(const DWORD*)pFormat;
4959 pFormat += sizeof(DWORD);
4962 pFormat += sizeof(WORD);
4964 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4965 if ((pStubMsg->ActualCount > elements) ||
4966 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4968 RpcRaiseException(RPC_S_INVALID_BOUND);
4972 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4975 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
4983 return *(const UCHAR *)pMemory;
4988 return *(const USHORT *)pMemory;
4992 return *(const ULONG *)pMemory;
4994 FIXME("Unhandled base type: 0x%02x\n", fc);
4999 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5000 unsigned long discriminant,
5001 PFORMAT_STRING pFormat)
5003 unsigned short num_arms, arm, type;
5005 num_arms = *(const SHORT*)pFormat & 0x0fff;
5007 for(arm = 0; arm < num_arms; arm++)
5009 if(discriminant == *(const ULONG*)pFormat)
5017 type = *(const unsigned short*)pFormat;
5018 TRACE("type %04x\n", type);
5019 if(arm == num_arms) /* default arm extras */
5023 ERR("no arm for 0x%lx and no default case\n", discriminant);
5024 RpcRaiseException(RPC_S_INVALID_TAG);
5029 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
5036 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5038 unsigned short type;
5042 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5046 type = *(const unsigned short*)pFormat;
5047 if((type & 0xff00) == 0x8000)
5049 unsigned char basetype = LOBYTE(type);
5050 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5054 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5055 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5058 unsigned char *saved_buffer = NULL;
5059 int pointer_buffer_mark_set = 0;
5066 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5067 saved_buffer = pStubMsg->Buffer;
5068 if (pStubMsg->PointerBufferMark)
5070 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5071 pStubMsg->PointerBufferMark = NULL;
5072 pointer_buffer_mark_set = 1;
5075 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5077 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5078 if (pointer_buffer_mark_set)
5080 STD_OVERFLOW_CHECK(pStubMsg);
5081 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5082 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5084 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5085 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5086 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5088 pStubMsg->Buffer = saved_buffer + 4;
5092 m(pStubMsg, pMemory, desc);
5095 else FIXME("no marshaller for embedded type %02x\n", *desc);
5100 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5101 unsigned char **ppMemory,
5103 PFORMAT_STRING pFormat,
5104 unsigned char fMustAlloc)
5106 unsigned short type;
5110 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5114 type = *(const unsigned short*)pFormat;
5115 if((type & 0xff00) == 0x8000)
5117 unsigned char basetype = LOBYTE(type);
5118 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5122 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5123 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5126 unsigned char *saved_buffer = NULL;
5127 int pointer_buffer_mark_set = 0;
5134 **(void***)ppMemory = NULL;
5135 ALIGN_POINTER(pStubMsg->Buffer, 4);
5136 saved_buffer = pStubMsg->Buffer;
5137 if (pStubMsg->PointerBufferMark)
5139 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5140 pStubMsg->PointerBufferMark = NULL;
5141 pointer_buffer_mark_set = 1;
5144 pStubMsg->Buffer += 4; /* for pointer ID */
5146 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5148 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5149 saved_buffer, pStubMsg->BufferEnd);
5150 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5153 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5154 if (pointer_buffer_mark_set)
5156 STD_OVERFLOW_CHECK(pStubMsg);
5157 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5158 pStubMsg->Buffer = saved_buffer + 4;
5162 m(pStubMsg, ppMemory, desc, fMustAlloc);
5165 else FIXME("no marshaller for embedded type %02x\n", *desc);
5170 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5171 unsigned char *pMemory,
5173 PFORMAT_STRING pFormat)
5175 unsigned short type;
5179 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5183 type = *(const unsigned short*)pFormat;
5184 if((type & 0xff00) == 0x8000)
5186 unsigned char basetype = LOBYTE(type);
5187 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5191 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5192 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5201 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5202 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5203 if (!pStubMsg->IgnoreEmbeddedPointers)
5205 int saved_buffer_length = pStubMsg->BufferLength;
5206 pStubMsg->BufferLength = pStubMsg->PointerLength;
5207 pStubMsg->PointerLength = 0;
5208 if(!pStubMsg->BufferLength)
5209 ERR("BufferLength == 0??\n");
5210 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5211 pStubMsg->PointerLength = pStubMsg->BufferLength;
5212 pStubMsg->BufferLength = saved_buffer_length;
5216 m(pStubMsg, pMemory, desc);
5219 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5223 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5225 PFORMAT_STRING pFormat)
5227 unsigned short type, size;
5229 size = *(const unsigned short*)pFormat;
5230 pStubMsg->Memory += size;
5233 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5237 type = *(const unsigned short*)pFormat;
5238 if((type & 0xff00) == 0x8000)
5240 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5244 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5245 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5246 unsigned char *saved_buffer;
5255 ALIGN_POINTER(pStubMsg->Buffer, 4);
5256 saved_buffer = pStubMsg->Buffer;
5257 safe_buffer_increment(pStubMsg, 4);
5258 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
5259 pStubMsg->MemorySize += 4;
5260 if (!pStubMsg->IgnoreEmbeddedPointers)
5261 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5264 return m(pStubMsg, desc);
5267 else FIXME("no marshaller for embedded type %02x\n", *desc);
5270 TRACE("size %d\n", size);
5274 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5275 unsigned char *pMemory,
5277 PFORMAT_STRING pFormat)
5279 unsigned short type;
5283 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5287 type = *(const unsigned short*)pFormat;
5288 if((type & 0xff00) != 0x8000)
5290 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5291 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5300 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5303 m(pStubMsg, pMemory, desc);
5309 /***********************************************************************
5310 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5312 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5313 unsigned char *pMemory,
5314 PFORMAT_STRING pFormat)
5316 unsigned char switch_type;
5317 unsigned char increment;
5320 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5323 switch_type = *pFormat & 0xf;
5324 increment = (*pFormat & 0xf0) >> 4;
5327 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5329 switch_value = get_discriminant(switch_type, pMemory);
5330 TRACE("got switch value 0x%x\n", switch_value);
5332 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5333 pMemory += increment;
5335 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5338 /***********************************************************************
5339 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5341 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5342 unsigned char **ppMemory,
5343 PFORMAT_STRING pFormat,
5344 unsigned char fMustAlloc)
5346 unsigned char switch_type;
5347 unsigned char increment;
5349 unsigned short size;
5350 unsigned char *pMemoryArm;
5352 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5355 switch_type = *pFormat & 0xf;
5356 increment = (*pFormat & 0xf0) >> 4;
5359 ALIGN_POINTER(pStubMsg->Buffer, increment);
5360 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5361 TRACE("got switch value 0x%x\n", switch_value);
5363 size = *(const unsigned short*)pFormat + increment;
5364 if(!*ppMemory || fMustAlloc)
5365 *ppMemory = NdrAllocate(pStubMsg, size);
5367 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5368 pMemoryArm = *ppMemory + increment;
5370 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
5373 /***********************************************************************
5374 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5376 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5377 unsigned char *pMemory,
5378 PFORMAT_STRING pFormat)
5380 unsigned char switch_type;
5381 unsigned char increment;
5384 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5387 switch_type = *pFormat & 0xf;
5388 increment = (*pFormat & 0xf0) >> 4;
5391 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5392 switch_value = get_discriminant(switch_type, pMemory);
5393 TRACE("got switch value 0x%x\n", switch_value);
5395 /* Add discriminant size */
5396 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5397 pMemory += increment;
5399 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5402 /***********************************************************************
5403 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5405 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5406 PFORMAT_STRING pFormat)
5408 unsigned char switch_type;
5409 unsigned char increment;
5412 switch_type = *pFormat & 0xf;
5413 increment = (*pFormat & 0xf0) >> 4;
5416 ALIGN_POINTER(pStubMsg->Buffer, increment);
5417 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5418 TRACE("got switch value 0x%x\n", switch_value);
5420 pStubMsg->Memory += increment;
5422 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5425 /***********************************************************************
5426 * NdrEncapsulatedUnionFree [RPCRT4.@]
5428 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5429 unsigned char *pMemory,
5430 PFORMAT_STRING pFormat)
5432 unsigned char switch_type;
5433 unsigned char increment;
5436 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5439 switch_type = *pFormat & 0xf;
5440 increment = (*pFormat & 0xf0) >> 4;
5443 switch_value = get_discriminant(switch_type, pMemory);
5444 TRACE("got switch value 0x%x\n", switch_value);
5446 pMemory += increment;
5448 return union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5451 /***********************************************************************
5452 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5454 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5455 unsigned char *pMemory,
5456 PFORMAT_STRING pFormat)
5458 unsigned char switch_type;
5460 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5463 switch_type = *pFormat;
5466 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5467 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5468 /* Marshall discriminant */
5469 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5471 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5474 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5475 PFORMAT_STRING *ppFormat)
5477 long discriminant = 0;
5487 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5496 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5497 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5505 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5506 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5511 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5515 if (pStubMsg->fHasNewCorrDesc)
5519 return discriminant;
5522 /**********************************************************************
5523 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5525 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5526 unsigned char **ppMemory,
5527 PFORMAT_STRING pFormat,
5528 unsigned char fMustAlloc)
5531 unsigned short size;
5533 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5536 /* Unmarshall discriminant */
5537 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5538 TRACE("unmarshalled discriminant %lx\n", discriminant);
5540 pFormat += *(const SHORT*)pFormat;
5542 size = *(const unsigned short*)pFormat;
5544 if(!*ppMemory || fMustAlloc)
5545 *ppMemory = NdrAllocate(pStubMsg, size);
5547 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5550 /***********************************************************************
5551 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5553 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5554 unsigned char *pMemory,
5555 PFORMAT_STRING pFormat)
5557 unsigned char switch_type;
5559 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5562 switch_type = *pFormat;
5565 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5566 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5567 /* Add discriminant size */
5568 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5570 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5573 /***********************************************************************
5574 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5576 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5577 PFORMAT_STRING pFormat)
5582 /* Unmarshall discriminant */
5583 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5584 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
5586 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
5589 /***********************************************************************
5590 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5592 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5593 unsigned char *pMemory,
5594 PFORMAT_STRING pFormat)
5596 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5600 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5601 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5603 return union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5606 /***********************************************************************
5607 * NdrByteCountPointerMarshall [RPCRT4.@]
5609 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5610 unsigned char *pMemory,
5611 PFORMAT_STRING pFormat)
5617 /***********************************************************************
5618 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5620 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5621 unsigned char **ppMemory,
5622 PFORMAT_STRING pFormat,
5623 unsigned char fMustAlloc)
5629 /***********************************************************************
5630 * NdrByteCountPointerBufferSize [RPCRT4.@]
5632 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5633 unsigned char *pMemory,
5634 PFORMAT_STRING pFormat)
5639 /***********************************************************************
5640 * NdrByteCountPointerMemorySize [RPCRT4.@]
5642 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5643 PFORMAT_STRING pFormat)
5649 /***********************************************************************
5650 * NdrByteCountPointerFree [RPCRT4.@]
5652 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
5653 unsigned char *pMemory,
5654 PFORMAT_STRING pFormat)
5659 /***********************************************************************
5660 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5662 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5663 unsigned char *pMemory,
5664 PFORMAT_STRING pFormat)
5670 /***********************************************************************
5671 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5673 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5674 unsigned char **ppMemory,
5675 PFORMAT_STRING pFormat,
5676 unsigned char fMustAlloc)
5682 /***********************************************************************
5683 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5685 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5686 unsigned char *pMemory,
5687 PFORMAT_STRING pFormat)
5692 /***********************************************************************
5693 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5695 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5696 PFORMAT_STRING pFormat)
5702 /***********************************************************************
5703 * NdrXmitOrRepAsFree [RPCRT4.@]
5705 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
5706 unsigned char *pMemory,
5707 PFORMAT_STRING pFormat)
5712 #include "pshpack1.h"
5716 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
5720 #include "poppack.h"
5722 /***********************************************************************
5723 * NdrRangeMarshall [internal]
5725 unsigned char *WINAPI NdrRangeMarshall(
5726 PMIDL_STUB_MESSAGE pStubMsg,
5727 unsigned char *pMemory,
5728 PFORMAT_STRING pFormat)
5730 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5731 unsigned char base_type;
5733 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5735 if (pRange->type != RPC_FC_RANGE)
5737 ERR("invalid format type %x\n", pRange->type);
5738 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5742 base_type = pRange->flags_type & 0xf;
5744 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
5747 /***********************************************************************
5748 * NdrRangeUnmarshall
5750 unsigned char *WINAPI NdrRangeUnmarshall(
5751 PMIDL_STUB_MESSAGE pStubMsg,
5752 unsigned char **ppMemory,
5753 PFORMAT_STRING pFormat,
5754 unsigned char fMustAlloc)
5756 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5757 unsigned char base_type;
5759 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5761 if (pRange->type != RPC_FC_RANGE)
5763 ERR("invalid format type %x\n", pRange->type);
5764 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5767 base_type = pRange->flags_type & 0xf;
5769 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5770 base_type, pRange->low_value, pRange->high_value);
5772 #define RANGE_UNMARSHALL(type, format_spec) \
5775 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5776 if (fMustAlloc || !*ppMemory) \
5777 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5778 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5780 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5781 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5782 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5784 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5785 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5787 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5788 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5789 (type)pRange->high_value); \
5790 RpcRaiseException(RPC_S_INVALID_BOUND); \
5793 TRACE("*ppMemory: %p\n", *ppMemory); \
5794 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5795 pStubMsg->Buffer += sizeof(type); \
5802 RANGE_UNMARSHALL(UCHAR, "%d");
5803 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5807 RANGE_UNMARSHALL(CHAR, "%u");
5808 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5810 case RPC_FC_WCHAR: /* FIXME: valid? */
5812 RANGE_UNMARSHALL(USHORT, "%u");
5813 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5816 RANGE_UNMARSHALL(SHORT, "%d");
5817 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5820 RANGE_UNMARSHALL(LONG, "%d");
5821 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5824 RANGE_UNMARSHALL(ULONG, "%u");
5825 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5829 FIXME("Unhandled enum type\n");
5831 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
5836 ERR("invalid range base type: 0x%02x\n", base_type);
5837 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5843 /***********************************************************************
5844 * NdrRangeBufferSize [internal]
5846 void WINAPI NdrRangeBufferSize(
5847 PMIDL_STUB_MESSAGE pStubMsg,
5848 unsigned char *pMemory,
5849 PFORMAT_STRING pFormat)
5851 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5852 unsigned char base_type;
5854 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5856 if (pRange->type != RPC_FC_RANGE)
5858 ERR("invalid format type %x\n", pRange->type);
5859 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5861 base_type = pRange->flags_type & 0xf;
5863 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
5866 /***********************************************************************
5867 * NdrRangeMemorySize [internal]
5869 ULONG WINAPI NdrRangeMemorySize(
5870 PMIDL_STUB_MESSAGE pStubMsg,
5871 PFORMAT_STRING pFormat)
5873 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5874 unsigned char base_type;
5876 if (pRange->type != RPC_FC_RANGE)
5878 ERR("invalid format type %x\n", pRange->type);
5879 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5882 base_type = pRange->flags_type & 0xf;
5884 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
5887 /***********************************************************************
5888 * NdrRangeFree [internal]
5890 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
5891 unsigned char *pMemory,
5892 PFORMAT_STRING pFormat)
5894 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5899 /***********************************************************************
5900 * NdrBaseTypeMarshall [internal]
5902 static unsigned char *WINAPI NdrBaseTypeMarshall(
5903 PMIDL_STUB_MESSAGE pStubMsg,
5904 unsigned char *pMemory,
5905 PFORMAT_STRING pFormat)
5907 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5915 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
5916 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
5921 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
5922 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
5923 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
5927 case RPC_FC_ERROR_STATUS_T:
5929 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
5930 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
5931 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
5934 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
5935 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
5938 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
5939 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
5942 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
5943 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
5944 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
5947 /* only 16-bits on the wire, so do a sanity check */
5948 if (*(UINT *)pMemory > SHRT_MAX)
5949 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
5950 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
5951 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5952 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5953 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
5954 pStubMsg->Buffer += sizeof(USHORT);
5955 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
5960 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5963 /* FIXME: what is the correct return value? */
5967 /***********************************************************************
5968 * NdrBaseTypeUnmarshall [internal]
5970 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
5971 PMIDL_STUB_MESSAGE pStubMsg,
5972 unsigned char **ppMemory,
5973 PFORMAT_STRING pFormat,
5974 unsigned char fMustAlloc)
5976 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5978 #define BASE_TYPE_UNMARSHALL(type) \
5979 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5980 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
5982 *ppMemory = pStubMsg->Buffer; \
5983 TRACE("*ppMemory: %p\n", *ppMemory); \
5988 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5989 TRACE("*ppMemory: %p\n", *ppMemory); \
5990 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5992 pStubMsg->Buffer += sizeof(type);
6000 BASE_TYPE_UNMARSHALL(UCHAR);
6001 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
6006 BASE_TYPE_UNMARSHALL(USHORT);
6007 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6011 case RPC_FC_ERROR_STATUS_T:
6013 BASE_TYPE_UNMARSHALL(ULONG);
6014 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6017 BASE_TYPE_UNMARSHALL(float);
6018 TRACE("value: %f\n", **(float **)ppMemory);
6021 BASE_TYPE_UNMARSHALL(double);
6022 TRACE("value: %f\n", **(double **)ppMemory);
6025 BASE_TYPE_UNMARSHALL(ULONGLONG);
6026 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6029 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6030 if (fMustAlloc || !*ppMemory)
6031 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6032 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
6033 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6034 TRACE("*ppMemory: %p\n", *ppMemory);
6035 /* 16-bits on the wire, but int in memory */
6036 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
6037 pStubMsg->Buffer += sizeof(USHORT);
6038 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6043 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6045 #undef BASE_TYPE_UNMARSHALL
6047 /* FIXME: what is the correct return value? */
6052 /***********************************************************************
6053 * NdrBaseTypeBufferSize [internal]
6055 static void WINAPI NdrBaseTypeBufferSize(
6056 PMIDL_STUB_MESSAGE pStubMsg,
6057 unsigned char *pMemory,
6058 PFORMAT_STRING pFormat)
6060 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6068 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6074 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
6075 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6080 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
6081 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6084 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
6085 safe_buffer_length_increment(pStubMsg, sizeof(float));
6088 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
6089 safe_buffer_length_increment(pStubMsg, sizeof(double));
6092 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
6093 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6095 case RPC_FC_ERROR_STATUS_T:
6096 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
6097 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6102 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6106 /***********************************************************************
6107 * NdrBaseTypeMemorySize [internal]
6109 static ULONG WINAPI NdrBaseTypeMemorySize(
6110 PMIDL_STUB_MESSAGE pStubMsg,
6111 PFORMAT_STRING pFormat)
6113 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6121 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6122 pStubMsg->MemorySize += sizeof(UCHAR);
6123 return sizeof(UCHAR);
6127 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6128 pStubMsg->MemorySize += sizeof(USHORT);
6129 return sizeof(USHORT);
6133 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6134 pStubMsg->MemorySize += sizeof(ULONG);
6135 return sizeof(ULONG);
6137 safe_buffer_increment(pStubMsg, sizeof(float));
6138 pStubMsg->MemorySize += sizeof(float);
6139 return sizeof(float);
6141 safe_buffer_increment(pStubMsg, sizeof(double));
6142 pStubMsg->MemorySize += sizeof(double);
6143 return sizeof(double);
6145 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6146 pStubMsg->MemorySize += sizeof(ULONGLONG);
6147 return sizeof(ULONGLONG);
6148 case RPC_FC_ERROR_STATUS_T:
6149 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6150 pStubMsg->MemorySize += sizeof(error_status_t);
6151 return sizeof(error_status_t);
6153 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6154 pStubMsg->MemorySize += sizeof(UINT);
6155 return sizeof(UINT);
6157 pStubMsg->MemorySize += sizeof(void *);
6158 return sizeof(void *);
6160 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6165 /***********************************************************************
6166 * NdrBaseTypeFree [internal]
6168 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6169 unsigned char *pMemory,
6170 PFORMAT_STRING pFormat)
6172 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6177 /***********************************************************************
6178 * NdrContextHandleBufferSize [internal]
6180 static void WINAPI NdrContextHandleBufferSize(
6181 PMIDL_STUB_MESSAGE pStubMsg,
6182 unsigned char *pMemory,
6183 PFORMAT_STRING pFormat)
6185 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6187 if (*pFormat != RPC_FC_BIND_CONTEXT)
6189 ERR("invalid format type %x\n", *pFormat);
6190 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6192 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
6193 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6196 /***********************************************************************
6197 * NdrContextHandleMarshall [internal]
6199 static unsigned char *WINAPI NdrContextHandleMarshall(
6200 PMIDL_STUB_MESSAGE pStubMsg,
6201 unsigned char *pMemory,
6202 PFORMAT_STRING pFormat)
6204 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6206 if (*pFormat != RPC_FC_BIND_CONTEXT)
6208 ERR("invalid format type %x\n", *pFormat);
6209 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6212 if (pFormat[1] & 0x80)
6213 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6215 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
6220 /***********************************************************************
6221 * NdrContextHandleUnmarshall [internal]
6223 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6224 PMIDL_STUB_MESSAGE pStubMsg,
6225 unsigned char **ppMemory,
6226 PFORMAT_STRING pFormat,
6227 unsigned char fMustAlloc)
6229 if (*pFormat != RPC_FC_BIND_CONTEXT)
6231 ERR("invalid format type %x\n", *pFormat);
6232 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6235 **(NDR_CCONTEXT **)ppMemory = NULL;
6236 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6241 /***********************************************************************
6242 * NdrClientContextMarshall [RPCRT4.@]
6244 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6245 NDR_CCONTEXT ContextHandle,
6248 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
6250 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
6252 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6254 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6255 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6256 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6259 /* FIXME: what does fCheck do? */
6260 NDRCContextMarshall(ContextHandle,
6263 pStubMsg->Buffer += cbNDRContext;
6266 /***********************************************************************
6267 * NdrClientContextUnmarshall [RPCRT4.@]
6269 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6270 NDR_CCONTEXT * pContextHandle,
6271 RPC_BINDING_HANDLE BindHandle)
6273 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
6275 ALIGN_POINTER(pStubMsg->Buffer, 4);
6277 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
6278 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6280 NDRCContextUnmarshall(pContextHandle,
6283 pStubMsg->RpcMsg->DataRepresentation);
6285 pStubMsg->Buffer += cbNDRContext;
6288 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6289 NDR_SCONTEXT ContextHandle,
6290 NDR_RUNDOWN RundownRoutine )
6292 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
6294 ALIGN_POINTER(pStubMsg->Buffer, 4);
6296 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6298 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6299 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6300 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6303 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6304 pStubMsg->Buffer, RundownRoutine, NULL,
6305 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6306 pStubMsg->Buffer += cbNDRContext;
6309 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6311 NDR_SCONTEXT ContextHandle;
6313 TRACE("(%p)\n", pStubMsg);
6315 ALIGN_POINTER(pStubMsg->Buffer, 4);
6317 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6319 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6320 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6321 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6324 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6326 pStubMsg->RpcMsg->DataRepresentation,
6327 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6328 pStubMsg->Buffer += cbNDRContext;
6330 return ContextHandle;
6333 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6334 unsigned char* pMemory,
6335 PFORMAT_STRING pFormat)
6337 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6340 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6341 PFORMAT_STRING pFormat)
6343 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6344 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6346 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6348 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6349 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6350 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6351 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6352 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6354 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6355 if_id = &sif->InterfaceId;
6358 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
6359 pStubMsg->RpcMsg->DataRepresentation, if_id,
6363 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6364 NDR_SCONTEXT ContextHandle,
6365 NDR_RUNDOWN RundownRoutine,
6366 PFORMAT_STRING pFormat)
6368 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6369 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6371 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6373 ALIGN_POINTER(pStubMsg->Buffer, 4);
6375 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6377 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6378 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6379 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6382 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6383 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6384 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6385 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6386 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6388 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6389 if_id = &sif->InterfaceId;
6392 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6393 pStubMsg->Buffer, RundownRoutine, if_id, flags);
6394 pStubMsg->Buffer += cbNDRContext;
6397 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6398 PFORMAT_STRING pFormat)
6400 NDR_SCONTEXT ContextHandle;
6401 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6402 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6404 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6406 ALIGN_POINTER(pStubMsg->Buffer, 4);
6408 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6410 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6411 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6412 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6415 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6416 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6417 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6418 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6419 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6421 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6422 if_id = &sif->InterfaceId;
6425 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6427 pStubMsg->RpcMsg->DataRepresentation,
6429 pStubMsg->Buffer += cbNDRContext;
6431 return ContextHandle;
6434 /***********************************************************************
6435 * NdrCorrelationInitialize [RPCRT4.@]
6437 * Initializes correlation validity checking.
6440 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6441 * pMemory [I] Pointer to memory to use as a cache.
6442 * CacheSize [I] Size of the memory pointed to by pMemory.
6443 * Flags [I] Reserved. Set to zero.
6448 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
6450 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
6451 pStubMsg->fHasNewCorrDesc = TRUE;
6454 /***********************************************************************
6455 * NdrCorrelationPass [RPCRT4.@]
6457 * Performs correlation validity checking.
6460 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6465 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
6467 FIXME("(%p): stub\n", pStubMsg);
6470 /***********************************************************************
6471 * NdrCorrelationFree [RPCRT4.@]
6473 * Frees any resources used while unmarshalling parameters that need
6474 * correlation validity checking.
6477 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6482 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
6484 FIXME("(%p): stub\n", pStubMsg);