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 >= pStubMsg->BufferStart && Pointer < pStubMsg->BufferEnd)
1533 if (attr & RPC_FC_P_ONSTACK) {
1534 TRACE("not freeing stack ptr %p\n", Pointer);
1537 TRACE("freeing %p\n", Pointer);
1538 NdrFree(pStubMsg, Pointer);
1541 TRACE("not freeing %p\n", Pointer);
1544 /***********************************************************************
1545 * EmbeddedPointerMarshall
1547 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1548 unsigned char *pMemory,
1549 PFORMAT_STRING pFormat)
1551 unsigned char *Mark = pStubMsg->BufferMark;
1552 unsigned rep, count, stride;
1554 unsigned char *saved_buffer = NULL;
1556 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1558 if (*pFormat != RPC_FC_PP) return NULL;
1561 if (pStubMsg->PointerBufferMark)
1563 saved_buffer = pStubMsg->Buffer;
1564 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1565 pStubMsg->PointerBufferMark = NULL;
1568 while (pFormat[0] != RPC_FC_END) {
1569 switch (pFormat[0]) {
1571 FIXME("unknown repeat type %d\n", pFormat[0]);
1572 case RPC_FC_NO_REPEAT:
1578 case RPC_FC_FIXED_REPEAT:
1579 rep = *(const WORD*)&pFormat[2];
1580 stride = *(const WORD*)&pFormat[4];
1581 count = *(const WORD*)&pFormat[8];
1584 case RPC_FC_VARIABLE_REPEAT:
1585 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1586 stride = *(const WORD*)&pFormat[2];
1587 count = *(const WORD*)&pFormat[6];
1591 for (i = 0; i < rep; i++) {
1592 PFORMAT_STRING info = pFormat;
1593 unsigned char *membase = pMemory + (i * stride);
1594 unsigned char *bufbase = Mark + (i * stride);
1597 for (u=0; u<count; u++,info+=8) {
1598 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1599 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1600 unsigned char *saved_memory = pStubMsg->Memory;
1602 pStubMsg->Memory = pMemory;
1603 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1604 pStubMsg->Memory = saved_memory;
1607 pFormat += 8 * count;
1612 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1613 pStubMsg->Buffer = saved_buffer;
1616 STD_OVERFLOW_CHECK(pStubMsg);
1621 /***********************************************************************
1622 * EmbeddedPointerUnmarshall
1624 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1625 unsigned char *pDstMemoryPtrs,
1626 unsigned char *pSrcMemoryPtrs,
1627 PFORMAT_STRING pFormat,
1628 unsigned char fMustAlloc)
1630 unsigned char *Mark = pStubMsg->BufferMark;
1631 unsigned rep, count, stride;
1633 unsigned char *saved_buffer = NULL;
1635 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstMemoryPtrs, pSrcMemoryPtrs, pFormat, fMustAlloc);
1637 if (*pFormat != RPC_FC_PP) return NULL;
1640 if (pStubMsg->PointerBufferMark)
1642 saved_buffer = pStubMsg->Buffer;
1643 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1644 pStubMsg->PointerBufferMark = NULL;
1647 while (pFormat[0] != RPC_FC_END) {
1648 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1649 switch (pFormat[0]) {
1651 FIXME("unknown repeat type %d\n", pFormat[0]);
1652 case RPC_FC_NO_REPEAT:
1658 case RPC_FC_FIXED_REPEAT:
1659 rep = *(const WORD*)&pFormat[2];
1660 stride = *(const WORD*)&pFormat[4];
1661 count = *(const WORD*)&pFormat[8];
1664 case RPC_FC_VARIABLE_REPEAT:
1665 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1666 stride = *(const WORD*)&pFormat[2];
1667 count = *(const WORD*)&pFormat[6];
1671 for (i = 0; i < rep; i++) {
1672 PFORMAT_STRING info = pFormat;
1673 unsigned char *memdstbase = pDstMemoryPtrs + (i * stride);
1674 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1675 unsigned char *bufbase = Mark + (i * stride);
1678 for (u=0; u<count; u++,info+=8) {
1679 unsigned char **memdstptr = (unsigned char **)(memdstbase + *(const SHORT*)&info[0]);
1680 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1681 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1682 PointerUnmarshall(pStubMsg, bufptr, memdstptr, *memsrcptr, info+4, fMustAlloc);
1685 pFormat += 8 * count;
1690 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1691 pStubMsg->Buffer = saved_buffer;
1697 /***********************************************************************
1698 * EmbeddedPointerBufferSize
1700 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1701 unsigned char *pMemory,
1702 PFORMAT_STRING pFormat)
1704 unsigned rep, count, stride;
1706 ULONG saved_buffer_length = 0;
1708 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1710 if (pStubMsg->IgnoreEmbeddedPointers) return;
1712 if (*pFormat != RPC_FC_PP) return;
1715 if (pStubMsg->PointerLength)
1717 saved_buffer_length = pStubMsg->BufferLength;
1718 pStubMsg->BufferLength = pStubMsg->PointerLength;
1719 pStubMsg->PointerLength = 0;
1722 while (pFormat[0] != RPC_FC_END) {
1723 switch (pFormat[0]) {
1725 FIXME("unknown repeat type %d\n", pFormat[0]);
1726 case RPC_FC_NO_REPEAT:
1732 case RPC_FC_FIXED_REPEAT:
1733 rep = *(const WORD*)&pFormat[2];
1734 stride = *(const WORD*)&pFormat[4];
1735 count = *(const WORD*)&pFormat[8];
1738 case RPC_FC_VARIABLE_REPEAT:
1739 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1740 stride = *(const WORD*)&pFormat[2];
1741 count = *(const WORD*)&pFormat[6];
1745 for (i = 0; i < rep; i++) {
1746 PFORMAT_STRING info = pFormat;
1747 unsigned char *membase = pMemory + (i * stride);
1750 for (u=0; u<count; u++,info+=8) {
1751 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1752 unsigned char *saved_memory = pStubMsg->Memory;
1754 pStubMsg->Memory = pMemory;
1755 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1756 pStubMsg->Memory = saved_memory;
1759 pFormat += 8 * count;
1762 if (saved_buffer_length)
1764 pStubMsg->PointerLength = pStubMsg->BufferLength;
1765 pStubMsg->BufferLength = saved_buffer_length;
1769 /***********************************************************************
1770 * EmbeddedPointerMemorySize [internal]
1772 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1773 PFORMAT_STRING pFormat)
1775 unsigned char *Mark = pStubMsg->BufferMark;
1776 unsigned rep, count, stride;
1778 unsigned char *saved_buffer = NULL;
1780 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1782 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1784 if (pStubMsg->PointerBufferMark)
1786 saved_buffer = pStubMsg->Buffer;
1787 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1788 pStubMsg->PointerBufferMark = NULL;
1791 if (*pFormat != RPC_FC_PP) return 0;
1794 while (pFormat[0] != RPC_FC_END) {
1795 switch (pFormat[0]) {
1797 FIXME("unknown repeat type %d\n", pFormat[0]);
1798 case RPC_FC_NO_REPEAT:
1804 case RPC_FC_FIXED_REPEAT:
1805 rep = *(const WORD*)&pFormat[2];
1806 stride = *(const WORD*)&pFormat[4];
1807 count = *(const WORD*)&pFormat[8];
1810 case RPC_FC_VARIABLE_REPEAT:
1811 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1812 stride = *(const WORD*)&pFormat[2];
1813 count = *(const WORD*)&pFormat[6];
1817 for (i = 0; i < rep; i++) {
1818 PFORMAT_STRING info = pFormat;
1819 unsigned char *bufbase = Mark + (i * stride);
1821 for (u=0; u<count; u++,info+=8) {
1822 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1823 PointerMemorySize(pStubMsg, bufptr, info+4);
1826 pFormat += 8 * count;
1831 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1832 pStubMsg->Buffer = saved_buffer;
1838 /***********************************************************************
1839 * EmbeddedPointerFree [internal]
1841 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1842 unsigned char *pMemory,
1843 PFORMAT_STRING pFormat)
1845 unsigned rep, count, stride;
1848 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1849 if (*pFormat != RPC_FC_PP) return;
1852 while (pFormat[0] != RPC_FC_END) {
1853 switch (pFormat[0]) {
1855 FIXME("unknown repeat type %d\n", pFormat[0]);
1856 case RPC_FC_NO_REPEAT:
1862 case RPC_FC_FIXED_REPEAT:
1863 rep = *(const WORD*)&pFormat[2];
1864 stride = *(const WORD*)&pFormat[4];
1865 count = *(const WORD*)&pFormat[8];
1868 case RPC_FC_VARIABLE_REPEAT:
1869 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1870 stride = *(const WORD*)&pFormat[2];
1871 count = *(const WORD*)&pFormat[6];
1875 for (i = 0; i < rep; i++) {
1876 PFORMAT_STRING info = pFormat;
1877 unsigned char *membase = pMemory + (i * stride);
1880 for (u=0; u<count; u++,info+=8) {
1881 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1882 unsigned char *saved_memory = pStubMsg->Memory;
1884 pStubMsg->Memory = pMemory;
1885 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1886 pStubMsg->Memory = saved_memory;
1889 pFormat += 8 * count;
1893 /***********************************************************************
1894 * NdrPointerMarshall [RPCRT4.@]
1896 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1897 unsigned char *pMemory,
1898 PFORMAT_STRING pFormat)
1900 unsigned char *Buffer;
1902 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1904 /* incremement the buffer here instead of in PointerMarshall,
1905 * as that is used by embedded pointers which already handle the incrementing
1906 * the buffer, and shouldn't write any additional pointer data to the wire */
1907 if (*pFormat != RPC_FC_RP)
1909 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
1910 Buffer = pStubMsg->Buffer;
1911 safe_buffer_increment(pStubMsg, 4);
1914 Buffer = pStubMsg->Buffer;
1916 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1921 /***********************************************************************
1922 * NdrPointerUnmarshall [RPCRT4.@]
1924 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1925 unsigned char **ppMemory,
1926 PFORMAT_STRING pFormat,
1927 unsigned char fMustAlloc)
1929 unsigned char *Buffer;
1931 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1933 /* incremement the buffer here instead of in PointerUnmarshall,
1934 * as that is used by embedded pointers which already handle the incrementing
1935 * the buffer, and shouldn't read any additional pointer data from the
1937 if (*pFormat != RPC_FC_RP)
1939 ALIGN_POINTER(pStubMsg->Buffer, 4);
1940 Buffer = pStubMsg->Buffer;
1941 safe_buffer_increment(pStubMsg, 4);
1944 Buffer = pStubMsg->Buffer;
1946 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1951 /***********************************************************************
1952 * NdrPointerBufferSize [RPCRT4.@]
1954 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1955 unsigned char *pMemory,
1956 PFORMAT_STRING pFormat)
1958 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1960 /* incremement the buffer length here instead of in PointerBufferSize,
1961 * as that is used by embedded pointers which already handle the buffer
1962 * length, and shouldn't write anything more to the wire */
1963 if (*pFormat != RPC_FC_RP)
1965 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1966 safe_buffer_length_increment(pStubMsg, 4);
1969 PointerBufferSize(pStubMsg, pMemory, pFormat);
1972 /***********************************************************************
1973 * NdrPointerMemorySize [RPCRT4.@]
1975 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1976 PFORMAT_STRING pFormat)
1978 /* unsigned size = *(LPWORD)(pFormat+2); */
1979 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1980 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1984 /***********************************************************************
1985 * NdrPointerFree [RPCRT4.@]
1987 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1988 unsigned char *pMemory,
1989 PFORMAT_STRING pFormat)
1991 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1992 PointerFree(pStubMsg, pMemory, pFormat);
1995 /***********************************************************************
1996 * NdrSimpleTypeMarshall [RPCRT4.@]
1998 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1999 unsigned char FormatChar )
2001 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
2004 /***********************************************************************
2005 * NdrSimpleTypeUnmarshall [RPCRT4.@]
2007 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
2008 unsigned char FormatChar )
2010 NdrBaseTypeUnmarshall(pStubMsg, &pMemory, &FormatChar, 0);
2013 /***********************************************************************
2014 * NdrSimpleStructMarshall [RPCRT4.@]
2016 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2017 unsigned char *pMemory,
2018 PFORMAT_STRING pFormat)
2020 unsigned size = *(const WORD*)(pFormat+2);
2021 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2023 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
2025 pStubMsg->BufferMark = pStubMsg->Buffer;
2026 safe_copy_to_buffer(pStubMsg, pMemory, size);
2028 if (pFormat[0] != RPC_FC_STRUCT)
2029 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
2034 /***********************************************************************
2035 * NdrSimpleStructUnmarshall [RPCRT4.@]
2037 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2038 unsigned char **ppMemory,
2039 PFORMAT_STRING pFormat,
2040 unsigned char fMustAlloc)
2042 unsigned size = *(const WORD*)(pFormat+2);
2043 unsigned char *saved_buffer;
2044 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2046 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2049 *ppMemory = NdrAllocate(pStubMsg, size);
2052 if (!pStubMsg->IsClient && !*ppMemory)
2053 /* for servers, we just point straight into the RPC buffer */
2054 *ppMemory = pStubMsg->Buffer;
2057 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
2058 safe_buffer_increment(pStubMsg, size);
2059 if (pFormat[0] == RPC_FC_PSTRUCT)
2060 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
2062 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2063 if (*ppMemory != saved_buffer)
2064 memcpy(*ppMemory, saved_buffer, size);
2069 /***********************************************************************
2070 * NdrSimpleStructBufferSize [RPCRT4.@]
2072 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2073 unsigned char *pMemory,
2074 PFORMAT_STRING pFormat)
2076 unsigned size = *(const WORD*)(pFormat+2);
2077 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2079 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2081 safe_buffer_length_increment(pStubMsg, size);
2082 if (pFormat[0] != RPC_FC_STRUCT)
2083 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
2086 /***********************************************************************
2087 * NdrSimpleStructMemorySize [RPCRT4.@]
2089 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2090 PFORMAT_STRING pFormat)
2092 unsigned short size = *(const WORD *)(pFormat+2);
2094 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2096 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2097 pStubMsg->MemorySize += size;
2098 safe_buffer_increment(pStubMsg, size);
2100 if (pFormat[0] != RPC_FC_STRUCT)
2101 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
2102 return pStubMsg->MemorySize;
2105 /***********************************************************************
2106 * NdrSimpleStructFree [RPCRT4.@]
2108 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2109 unsigned char *pMemory,
2110 PFORMAT_STRING pFormat)
2112 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2113 if (pFormat[0] != RPC_FC_STRUCT)
2114 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
2118 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE *pStubMsg,
2119 PFORMAT_STRING pFormat)
2123 case RPC_FC_PSTRUCT:
2124 case RPC_FC_CSTRUCT:
2125 case RPC_FC_BOGUS_STRUCT:
2126 case RPC_FC_SMFARRAY:
2127 case RPC_FC_SMVARRAY:
2128 case RPC_FC_CSTRING:
2129 return *(const WORD*)&pFormat[2];
2130 case RPC_FC_USER_MARSHAL:
2131 return *(const WORD*)&pFormat[4];
2132 case RPC_FC_NON_ENCAPSULATED_UNION:
2134 if (pStubMsg->fHasNewCorrDesc)
2139 pFormat += *(const SHORT*)pFormat;
2140 return *(const SHORT*)pFormat;
2142 return sizeof(void *);
2143 case RPC_FC_WSTRING:
2144 return *(const WORD*)&pFormat[2] * 2;
2146 FIXME("unhandled embedded type %02x\n", *pFormat);
2152 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2153 PFORMAT_STRING pFormat)
2155 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2159 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2163 return m(pStubMsg, pFormat);
2167 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2168 unsigned char *pMemory,
2169 PFORMAT_STRING pFormat,
2170 PFORMAT_STRING pPointer)
2172 PFORMAT_STRING desc;
2176 while (*pFormat != RPC_FC_END) {
2182 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2183 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2189 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2190 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2196 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2197 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2201 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2202 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2205 case RPC_FC_POINTER:
2207 unsigned char *saved_buffer;
2208 int pointer_buffer_mark_set = 0;
2209 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2210 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
2211 saved_buffer = pStubMsg->Buffer;
2212 if (pStubMsg->PointerBufferMark)
2214 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2215 pStubMsg->PointerBufferMark = NULL;
2216 pointer_buffer_mark_set = 1;
2219 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2220 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2221 if (pointer_buffer_mark_set)
2223 STD_OVERFLOW_CHECK(pStubMsg);
2224 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2225 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2227 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2228 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2229 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2231 pStubMsg->Buffer = saved_buffer + 4;
2237 case RPC_FC_ALIGNM4:
2238 ALIGN_POINTER(pMemory, 4);
2240 case RPC_FC_ALIGNM8:
2241 ALIGN_POINTER(pMemory, 8);
2243 case RPC_FC_STRUCTPAD1:
2244 case RPC_FC_STRUCTPAD2:
2245 case RPC_FC_STRUCTPAD3:
2246 case RPC_FC_STRUCTPAD4:
2247 case RPC_FC_STRUCTPAD5:
2248 case RPC_FC_STRUCTPAD6:
2249 case RPC_FC_STRUCTPAD7:
2250 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2252 case RPC_FC_EMBEDDED_COMPLEX:
2253 pMemory += pFormat[1];
2255 desc = pFormat + *(const SHORT*)pFormat;
2256 size = EmbeddedComplexSize(pStubMsg, desc);
2257 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
2258 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2261 /* for some reason interface pointers aren't generated as
2262 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2263 * they still need the derefencing treatment that pointers are
2265 if (*desc == RPC_FC_IP)
2266 m(pStubMsg, *(unsigned char **)pMemory, desc);
2268 m(pStubMsg, pMemory, desc);
2270 else FIXME("no marshaller for embedded type %02x\n", *desc);
2277 FIXME("unhandled format 0x%02x\n", *pFormat);
2285 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2286 unsigned char *pMemory,
2287 PFORMAT_STRING pFormat,
2288 PFORMAT_STRING pPointer)
2290 PFORMAT_STRING desc;
2294 while (*pFormat != RPC_FC_END) {
2300 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2301 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2307 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2308 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2314 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2315 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2319 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2320 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2323 case RPC_FC_POINTER:
2325 unsigned char *saved_buffer;
2326 int pointer_buffer_mark_set = 0;
2327 TRACE("pointer => %p\n", pMemory);
2328 ALIGN_POINTER(pStubMsg->Buffer, 4);
2329 saved_buffer = pStubMsg->Buffer;
2330 if (pStubMsg->PointerBufferMark)
2332 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2333 pStubMsg->PointerBufferMark = NULL;
2334 pointer_buffer_mark_set = 1;
2337 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2339 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, TRUE);
2340 if (pointer_buffer_mark_set)
2342 STD_OVERFLOW_CHECK(pStubMsg);
2343 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2344 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2346 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2347 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2348 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2350 pStubMsg->Buffer = saved_buffer + 4;
2356 case RPC_FC_ALIGNM4:
2357 ALIGN_POINTER_CLEAR(pMemory, 4);
2359 case RPC_FC_ALIGNM8:
2360 ALIGN_POINTER_CLEAR(pMemory, 8);
2362 case RPC_FC_STRUCTPAD1:
2363 case RPC_FC_STRUCTPAD2:
2364 case RPC_FC_STRUCTPAD3:
2365 case RPC_FC_STRUCTPAD4:
2366 case RPC_FC_STRUCTPAD5:
2367 case RPC_FC_STRUCTPAD6:
2368 case RPC_FC_STRUCTPAD7:
2369 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2370 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2372 case RPC_FC_EMBEDDED_COMPLEX:
2373 pMemory += pFormat[1];
2375 desc = pFormat + *(const SHORT*)pFormat;
2376 size = EmbeddedComplexSize(pStubMsg, desc);
2377 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2378 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2379 memset(pMemory, 0, size); /* just in case */
2382 /* for some reason interface pointers aren't generated as
2383 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2384 * they still need the derefencing treatment that pointers are
2386 if (*desc == RPC_FC_IP)
2387 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2389 m(pStubMsg, &pMemory, desc, FALSE);
2391 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2398 FIXME("unhandled format %d\n", *pFormat);
2406 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2407 unsigned char *pMemory,
2408 PFORMAT_STRING pFormat,
2409 PFORMAT_STRING pPointer)
2411 PFORMAT_STRING desc;
2415 while (*pFormat != RPC_FC_END) {
2421 safe_buffer_length_increment(pStubMsg, 1);
2427 safe_buffer_length_increment(pStubMsg, 2);
2433 safe_buffer_length_increment(pStubMsg, 4);
2437 safe_buffer_length_increment(pStubMsg, 8);
2440 case RPC_FC_POINTER:
2441 if (!pStubMsg->IgnoreEmbeddedPointers)
2443 int saved_buffer_length = pStubMsg->BufferLength;
2444 pStubMsg->BufferLength = pStubMsg->PointerLength;
2445 pStubMsg->PointerLength = 0;
2446 if(!pStubMsg->BufferLength)
2447 ERR("BufferLength == 0??\n");
2448 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2449 pStubMsg->PointerLength = pStubMsg->BufferLength;
2450 pStubMsg->BufferLength = saved_buffer_length;
2452 safe_buffer_length_increment(pStubMsg, 4);
2456 case RPC_FC_ALIGNM4:
2457 ALIGN_POINTER(pMemory, 4);
2459 case RPC_FC_ALIGNM8:
2460 ALIGN_POINTER(pMemory, 8);
2462 case RPC_FC_STRUCTPAD1:
2463 case RPC_FC_STRUCTPAD2:
2464 case RPC_FC_STRUCTPAD3:
2465 case RPC_FC_STRUCTPAD4:
2466 case RPC_FC_STRUCTPAD5:
2467 case RPC_FC_STRUCTPAD6:
2468 case RPC_FC_STRUCTPAD7:
2469 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2471 case RPC_FC_EMBEDDED_COMPLEX:
2472 pMemory += pFormat[1];
2474 desc = pFormat + *(const SHORT*)pFormat;
2475 size = EmbeddedComplexSize(pStubMsg, desc);
2476 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2479 /* for some reason interface pointers aren't generated as
2480 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2481 * they still need the derefencing treatment that pointers are
2483 if (*desc == RPC_FC_IP)
2484 m(pStubMsg, *(unsigned char **)pMemory, desc);
2486 m(pStubMsg, pMemory, desc);
2488 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2495 FIXME("unhandled format 0x%02x\n", *pFormat);
2503 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2504 unsigned char *pMemory,
2505 PFORMAT_STRING pFormat,
2506 PFORMAT_STRING pPointer)
2508 PFORMAT_STRING desc;
2512 while (*pFormat != RPC_FC_END) {
2533 case RPC_FC_POINTER:
2534 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
2538 case RPC_FC_ALIGNM4:
2539 ALIGN_POINTER(pMemory, 4);
2541 case RPC_FC_ALIGNM8:
2542 ALIGN_POINTER(pMemory, 8);
2544 case RPC_FC_STRUCTPAD1:
2545 case RPC_FC_STRUCTPAD2:
2546 case RPC_FC_STRUCTPAD3:
2547 case RPC_FC_STRUCTPAD4:
2548 case RPC_FC_STRUCTPAD5:
2549 case RPC_FC_STRUCTPAD6:
2550 case RPC_FC_STRUCTPAD7:
2551 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2553 case RPC_FC_EMBEDDED_COMPLEX:
2554 pMemory += pFormat[1];
2556 desc = pFormat + *(const SHORT*)pFormat;
2557 size = EmbeddedComplexSize(pStubMsg, desc);
2558 m = NdrFreer[*desc & NDR_TABLE_MASK];
2561 /* for some reason interface pointers aren't generated as
2562 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2563 * they still need the derefencing treatment that pointers are
2565 if (*desc == RPC_FC_IP)
2566 m(pStubMsg, *(unsigned char **)pMemory, desc);
2568 m(pStubMsg, pMemory, desc);
2576 FIXME("unhandled format 0x%02x\n", *pFormat);
2584 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2585 PFORMAT_STRING pFormat)
2587 PFORMAT_STRING desc;
2588 unsigned long size = 0;
2590 while (*pFormat != RPC_FC_END) {
2597 safe_buffer_increment(pStubMsg, 1);
2603 safe_buffer_increment(pStubMsg, 2);
2609 safe_buffer_increment(pStubMsg, 4);
2613 safe_buffer_increment(pStubMsg, 8);
2615 case RPC_FC_POINTER:
2617 safe_buffer_increment(pStubMsg, 4);
2618 if (!pStubMsg->IgnoreEmbeddedPointers)
2619 FIXME("embedded pointers\n");
2621 case RPC_FC_ALIGNM4:
2622 ALIGN_LENGTH(size, 4);
2623 ALIGN_POINTER(pStubMsg->Buffer, 4);
2625 case RPC_FC_ALIGNM8:
2626 ALIGN_LENGTH(size, 8);
2627 ALIGN_POINTER(pStubMsg->Buffer, 8);
2629 case RPC_FC_STRUCTPAD1:
2630 case RPC_FC_STRUCTPAD2:
2631 case RPC_FC_STRUCTPAD3:
2632 case RPC_FC_STRUCTPAD4:
2633 case RPC_FC_STRUCTPAD5:
2634 case RPC_FC_STRUCTPAD6:
2635 case RPC_FC_STRUCTPAD7:
2636 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2638 case RPC_FC_EMBEDDED_COMPLEX:
2641 desc = pFormat + *(const SHORT*)pFormat;
2642 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2648 FIXME("unhandled format 0x%02x\n", *pFormat);
2656 unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg,
2657 PFORMAT_STRING pFormat)
2659 PFORMAT_STRING desc;
2660 unsigned long size = 0;
2662 while (*pFormat != RPC_FC_END) {
2683 case RPC_FC_POINTER:
2684 size += sizeof(void *);
2686 case RPC_FC_ALIGNM4:
2687 ALIGN_LENGTH(size, 4);
2689 case RPC_FC_ALIGNM8:
2690 ALIGN_LENGTH(size, 8);
2692 case RPC_FC_STRUCTPAD1:
2693 case RPC_FC_STRUCTPAD2:
2694 case RPC_FC_STRUCTPAD3:
2695 case RPC_FC_STRUCTPAD4:
2696 case RPC_FC_STRUCTPAD5:
2697 case RPC_FC_STRUCTPAD6:
2698 case RPC_FC_STRUCTPAD7:
2699 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2701 case RPC_FC_EMBEDDED_COMPLEX:
2704 desc = pFormat + *(const SHORT*)pFormat;
2705 size += EmbeddedComplexSize(pStubMsg, desc);
2711 FIXME("unhandled format 0x%02x\n", *pFormat);
2719 /***********************************************************************
2720 * NdrComplexStructMarshall [RPCRT4.@]
2722 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2723 unsigned char *pMemory,
2724 PFORMAT_STRING pFormat)
2726 PFORMAT_STRING conf_array = NULL;
2727 PFORMAT_STRING pointer_desc = NULL;
2728 unsigned char *OldMemory = pStubMsg->Memory;
2729 int pointer_buffer_mark_set = 0;
2731 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2733 if (!pStubMsg->PointerBufferMark)
2735 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2736 /* save buffer length */
2737 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2739 /* get the buffer pointer after complex array data, but before
2741 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2742 pStubMsg->IgnoreEmbeddedPointers = 1;
2743 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2744 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2746 /* save it for use by embedded pointer code later */
2747 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2748 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
2749 pointer_buffer_mark_set = 1;
2751 /* restore the original buffer length */
2752 pStubMsg->BufferLength = saved_buffer_length;
2755 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
2758 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2760 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2763 pStubMsg->Memory = pMemory;
2765 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2768 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2770 pStubMsg->Memory = OldMemory;
2772 if (pointer_buffer_mark_set)
2774 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2775 pStubMsg->PointerBufferMark = NULL;
2778 STD_OVERFLOW_CHECK(pStubMsg);
2783 /***********************************************************************
2784 * NdrComplexStructUnmarshall [RPCRT4.@]
2786 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2787 unsigned char **ppMemory,
2788 PFORMAT_STRING pFormat,
2789 unsigned char fMustAlloc)
2791 unsigned size = *(const WORD*)(pFormat+2);
2792 PFORMAT_STRING conf_array = NULL;
2793 PFORMAT_STRING pointer_desc = NULL;
2794 unsigned char *pMemory;
2795 int pointer_buffer_mark_set = 0;
2797 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2799 if (!pStubMsg->PointerBufferMark)
2801 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2802 /* save buffer pointer */
2803 unsigned char *saved_buffer = pStubMsg->Buffer;
2805 /* get the buffer pointer after complex array data, but before
2807 pStubMsg->IgnoreEmbeddedPointers = 1;
2808 NdrComplexStructMemorySize(pStubMsg, pFormat);
2809 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2811 /* save it for use by embedded pointer code later */
2812 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2813 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
2814 pointer_buffer_mark_set = 1;
2816 /* restore the original buffer */
2817 pStubMsg->Buffer = saved_buffer;
2820 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2822 if (fMustAlloc || !*ppMemory)
2824 *ppMemory = NdrAllocate(pStubMsg, size);
2825 memset(*ppMemory, 0, size);
2829 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2831 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2834 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2837 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2839 if (pointer_buffer_mark_set)
2841 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2842 pStubMsg->PointerBufferMark = NULL;
2848 /***********************************************************************
2849 * NdrComplexStructBufferSize [RPCRT4.@]
2851 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2852 unsigned char *pMemory,
2853 PFORMAT_STRING pFormat)
2855 PFORMAT_STRING conf_array = NULL;
2856 PFORMAT_STRING pointer_desc = NULL;
2857 unsigned char *OldMemory = pStubMsg->Memory;
2858 int pointer_length_set = 0;
2860 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2862 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2864 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2866 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2867 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2869 /* get the buffer length after complex struct data, but before
2871 pStubMsg->IgnoreEmbeddedPointers = 1;
2872 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2873 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2875 /* save it for use by embedded pointer code later */
2876 pStubMsg->PointerLength = pStubMsg->BufferLength;
2877 pointer_length_set = 1;
2878 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
2880 /* restore the original buffer length */
2881 pStubMsg->BufferLength = saved_buffer_length;
2885 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2887 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2890 pStubMsg->Memory = pMemory;
2892 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2895 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2897 pStubMsg->Memory = OldMemory;
2899 if(pointer_length_set)
2901 pStubMsg->BufferLength = pStubMsg->PointerLength;
2902 pStubMsg->PointerLength = 0;
2907 /***********************************************************************
2908 * NdrComplexStructMemorySize [RPCRT4.@]
2910 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2911 PFORMAT_STRING pFormat)
2913 unsigned size = *(const WORD*)(pFormat+2);
2914 PFORMAT_STRING conf_array = NULL;
2915 PFORMAT_STRING pointer_desc = NULL;
2917 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2919 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2922 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2924 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2927 ComplexStructMemorySize(pStubMsg, pFormat);
2930 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2935 /***********************************************************************
2936 * NdrComplexStructFree [RPCRT4.@]
2938 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2939 unsigned char *pMemory,
2940 PFORMAT_STRING pFormat)
2942 PFORMAT_STRING conf_array = NULL;
2943 PFORMAT_STRING pointer_desc = NULL;
2944 unsigned char *OldMemory = pStubMsg->Memory;
2946 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2949 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2951 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2954 pStubMsg->Memory = pMemory;
2956 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2959 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2961 pStubMsg->Memory = OldMemory;
2964 /***********************************************************************
2965 * NdrConformantArrayMarshall [RPCRT4.@]
2967 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2968 unsigned char *pMemory,
2969 PFORMAT_STRING pFormat)
2971 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2972 unsigned char alignment = pFormat[1] + 1;
2974 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2975 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2977 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2979 WriteConformance(pStubMsg);
2981 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
2983 size = safe_multiply(esize, pStubMsg->MaxCount);
2984 pStubMsg->BufferMark = pStubMsg->Buffer;
2985 safe_copy_to_buffer(pStubMsg, pMemory, size);
2987 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2992 /***********************************************************************
2993 * NdrConformantArrayUnmarshall [RPCRT4.@]
2995 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2996 unsigned char **ppMemory,
2997 PFORMAT_STRING pFormat,
2998 unsigned char fMustAlloc)
3000 DWORD size, esize = *(const WORD*)(pFormat+2);
3001 unsigned char alignment = pFormat[1] + 1;
3002 unsigned char *saved_buffer;
3004 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3005 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3007 pFormat = ReadConformance(pStubMsg, pFormat+4);
3009 size = safe_multiply(esize, pStubMsg->MaxCount);
3010 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3013 *ppMemory = NdrAllocate(pStubMsg, size);
3016 if (!pStubMsg->IsClient && !*ppMemory)
3017 /* for servers, we just point straight into the RPC buffer */
3018 *ppMemory = pStubMsg->Buffer;
3021 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3022 safe_buffer_increment(pStubMsg, size);
3023 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3025 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
3026 if (*ppMemory != saved_buffer)
3027 memcpy(*ppMemory, saved_buffer, size);
3032 /***********************************************************************
3033 * NdrConformantArrayBufferSize [RPCRT4.@]
3035 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3036 unsigned char *pMemory,
3037 PFORMAT_STRING pFormat)
3039 DWORD size, esize = *(const WORD*)(pFormat+2);
3040 unsigned char alignment = pFormat[1] + 1;
3042 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3043 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3045 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3047 SizeConformance(pStubMsg);
3049 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3051 size = safe_multiply(esize, pStubMsg->MaxCount);
3052 /* conformance value plus array */
3053 safe_buffer_length_increment(pStubMsg, size);
3055 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3058 /***********************************************************************
3059 * NdrConformantArrayMemorySize [RPCRT4.@]
3061 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3062 PFORMAT_STRING pFormat)
3064 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
3065 unsigned char alignment = pFormat[1] + 1;
3067 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3068 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3070 pFormat = ReadConformance(pStubMsg, pFormat+4);
3071 size = safe_multiply(esize, pStubMsg->MaxCount);
3072 pStubMsg->MemorySize += size;
3074 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3075 pStubMsg->BufferMark = pStubMsg->Buffer;
3076 safe_buffer_increment(pStubMsg, size);
3078 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3080 return pStubMsg->MemorySize;
3083 /***********************************************************************
3084 * NdrConformantArrayFree [RPCRT4.@]
3086 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3087 unsigned char *pMemory,
3088 PFORMAT_STRING pFormat)
3090 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3091 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3093 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3095 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3099 /***********************************************************************
3100 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3102 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
3103 unsigned char* pMemory,
3104 PFORMAT_STRING pFormat )
3107 unsigned char alignment = pFormat[1] + 1;
3108 DWORD esize = *(const WORD*)(pFormat+2);
3110 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3112 if (pFormat[0] != RPC_FC_CVARRAY)
3114 ERR("invalid format type %x\n", pFormat[0]);
3115 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3119 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3120 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3122 WriteConformance(pStubMsg);
3123 WriteVariance(pStubMsg);
3125 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3127 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3129 pStubMsg->BufferMark = pStubMsg->Buffer;
3130 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
3132 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3138 /***********************************************************************
3139 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3141 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
3142 unsigned char** ppMemory,
3143 PFORMAT_STRING pFormat,
3144 unsigned char fMustAlloc )
3146 ULONG bufsize, memsize;
3147 unsigned char alignment = pFormat[1] + 1;
3148 DWORD esize = *(const WORD*)(pFormat+2);
3149 unsigned char *saved_buffer;
3152 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3154 if (pFormat[0] != RPC_FC_CVARRAY)
3156 ERR("invalid format type %x\n", pFormat[0]);
3157 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3161 pFormat = ReadConformance(pStubMsg, pFormat+4);
3162 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3164 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3166 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3167 memsize = safe_multiply(esize, pStubMsg->MaxCount);
3168 offset = pStubMsg->Offset;
3170 if (!*ppMemory || fMustAlloc)
3171 *ppMemory = NdrAllocate(pStubMsg, memsize);
3172 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3173 safe_buffer_increment(pStubMsg, bufsize);
3175 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3177 memcpy(*ppMemory + offset, saved_buffer, bufsize);
3183 /***********************************************************************
3184 * NdrConformantVaryingArrayFree [RPCRT4.@]
3186 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
3187 unsigned char* pMemory,
3188 PFORMAT_STRING pFormat )
3190 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3192 if (pFormat[0] != RPC_FC_CVARRAY)
3194 ERR("invalid format type %x\n", pFormat[0]);
3195 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3199 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3200 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3202 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3206 /***********************************************************************
3207 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3209 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
3210 unsigned char* pMemory, PFORMAT_STRING pFormat )
3212 unsigned char alignment = pFormat[1] + 1;
3213 DWORD esize = *(const WORD*)(pFormat+2);
3215 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3217 if (pFormat[0] != RPC_FC_CVARRAY)
3219 ERR("invalid format type %x\n", pFormat[0]);
3220 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3225 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3226 /* compute length */
3227 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3229 SizeConformance(pStubMsg);
3230 SizeVariance(pStubMsg);
3232 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3234 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
3236 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3240 /***********************************************************************
3241 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3243 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
3244 PFORMAT_STRING pFormat )
3246 ULONG bufsize, memsize;
3247 unsigned char alignment = pFormat[1] + 1;
3248 DWORD esize = *(const WORD*)(pFormat+2);
3250 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3252 if (pFormat[0] != RPC_FC_CVARRAY)
3254 ERR("invalid format type %x\n", pFormat[0]);
3255 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3256 return pStubMsg->MemorySize;
3259 pFormat = ReadConformance(pStubMsg, pFormat+4);
3260 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3262 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3264 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3265 memsize = safe_multiply(esize, pStubMsg->MaxCount);
3267 safe_buffer_increment(pStubMsg, bufsize);
3268 pStubMsg->MemorySize += memsize;
3270 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3272 return pStubMsg->MemorySize;
3276 /***********************************************************************
3277 * NdrComplexArrayMarshall [RPCRT4.@]
3279 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3280 unsigned char *pMemory,
3281 PFORMAT_STRING pFormat)
3283 ULONG i, count, def;
3284 BOOL variance_present;
3285 unsigned char alignment;
3286 int pointer_buffer_mark_set = 0;
3288 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3290 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3292 ERR("invalid format type %x\n", pFormat[0]);
3293 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3297 alignment = pFormat[1] + 1;
3299 if (!pStubMsg->PointerBufferMark)
3301 /* save buffer fields that may be changed by buffer sizer functions
3302 * and that may be needed later on */
3303 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3304 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3305 unsigned long saved_max_count = pStubMsg->MaxCount;
3306 unsigned long saved_offset = pStubMsg->Offset;
3307 unsigned long saved_actual_count = pStubMsg->ActualCount;
3309 /* get the buffer pointer after complex array data, but before
3311 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3312 pStubMsg->IgnoreEmbeddedPointers = 1;
3313 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3314 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3316 /* save it for use by embedded pointer code later */
3317 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3318 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
3319 pointer_buffer_mark_set = 1;
3321 /* restore fields */
3322 pStubMsg->ActualCount = saved_actual_count;
3323 pStubMsg->Offset = saved_offset;
3324 pStubMsg->MaxCount = saved_max_count;
3325 pStubMsg->BufferLength = saved_buffer_length;
3328 def = *(const WORD*)&pFormat[2];
3331 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3332 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3334 variance_present = IsConformanceOrVariancePresent(pFormat);
3335 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3336 TRACE("variance = %d\n", pStubMsg->ActualCount);
3338 WriteConformance(pStubMsg);
3339 if (variance_present)
3340 WriteVariance(pStubMsg);
3342 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3344 count = pStubMsg->ActualCount;
3345 for (i = 0; i < count; i++)
3346 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3348 STD_OVERFLOW_CHECK(pStubMsg);
3350 if (pointer_buffer_mark_set)
3352 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3353 pStubMsg->PointerBufferMark = NULL;
3359 /***********************************************************************
3360 * NdrComplexArrayUnmarshall [RPCRT4.@]
3362 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3363 unsigned char **ppMemory,
3364 PFORMAT_STRING pFormat,
3365 unsigned char fMustAlloc)
3367 ULONG i, count, size;
3368 unsigned char alignment;
3369 unsigned char *pMemory;
3370 unsigned char *saved_buffer;
3371 int pointer_buffer_mark_set = 0;
3372 int saved_ignore_embedded;
3374 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3376 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3378 ERR("invalid format type %x\n", pFormat[0]);
3379 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3383 alignment = pFormat[1] + 1;
3385 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3386 /* save buffer pointer */
3387 saved_buffer = pStubMsg->Buffer;
3388 /* get the buffer pointer after complex array data, but before
3390 pStubMsg->IgnoreEmbeddedPointers = 1;
3391 pStubMsg->MemorySize = 0;
3392 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3393 size = pStubMsg->MemorySize;
3394 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3396 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
3397 if (!pStubMsg->PointerBufferMark)
3399 /* save it for use by embedded pointer code later */
3400 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3401 pointer_buffer_mark_set = 1;
3403 /* restore the original buffer */
3404 pStubMsg->Buffer = saved_buffer;
3408 pFormat = ReadConformance(pStubMsg, pFormat);
3409 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3411 if (fMustAlloc || !*ppMemory)
3413 *ppMemory = NdrAllocate(pStubMsg, size);
3414 memset(*ppMemory, 0, size);
3417 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3419 pMemory = *ppMemory;
3420 count = pStubMsg->ActualCount;
3421 for (i = 0; i < count; i++)
3422 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
3424 if (pointer_buffer_mark_set)
3426 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3427 pStubMsg->PointerBufferMark = NULL;
3433 /***********************************************************************
3434 * NdrComplexArrayBufferSize [RPCRT4.@]
3436 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3437 unsigned char *pMemory,
3438 PFORMAT_STRING pFormat)
3440 ULONG i, count, def;
3441 unsigned char alignment;
3442 BOOL variance_present;
3443 int pointer_length_set = 0;
3445 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3447 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3449 ERR("invalid format type %x\n", pFormat[0]);
3450 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3454 alignment = pFormat[1] + 1;
3456 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3458 /* save buffer fields that may be changed by buffer sizer functions
3459 * and that may be needed later on */
3460 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3461 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3462 unsigned long saved_max_count = pStubMsg->MaxCount;
3463 unsigned long saved_offset = pStubMsg->Offset;
3464 unsigned long saved_actual_count = pStubMsg->ActualCount;
3466 /* get the buffer pointer after complex array data, but before
3468 pStubMsg->IgnoreEmbeddedPointers = 1;
3469 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3470 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3472 /* save it for use by embedded pointer code later */
3473 pStubMsg->PointerLength = pStubMsg->BufferLength;
3474 pointer_length_set = 1;
3476 /* restore fields */
3477 pStubMsg->ActualCount = saved_actual_count;
3478 pStubMsg->Offset = saved_offset;
3479 pStubMsg->MaxCount = saved_max_count;
3480 pStubMsg->BufferLength = saved_buffer_length;
3482 def = *(const WORD*)&pFormat[2];
3485 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3486 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3487 SizeConformance(pStubMsg);
3489 variance_present = IsConformanceOrVariancePresent(pFormat);
3490 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3491 TRACE("variance = %d\n", pStubMsg->ActualCount);
3493 if (variance_present)
3494 SizeVariance(pStubMsg);
3496 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3498 count = pStubMsg->ActualCount;
3499 for (i = 0; i < count; i++)
3500 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
3502 if(pointer_length_set)
3504 pStubMsg->BufferLength = pStubMsg->PointerLength;
3505 pStubMsg->PointerLength = 0;
3509 /***********************************************************************
3510 * NdrComplexArrayMemorySize [RPCRT4.@]
3512 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3513 PFORMAT_STRING pFormat)
3515 ULONG i, count, esize, SavedMemorySize, MemorySize;
3516 unsigned char alignment;
3518 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3520 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3522 ERR("invalid format type %x\n", pFormat[0]);
3523 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3527 alignment = pFormat[1] + 1;
3531 pFormat = ReadConformance(pStubMsg, pFormat);
3532 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3534 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3536 SavedMemorySize = pStubMsg->MemorySize;
3538 esize = ComplexStructSize(pStubMsg, pFormat);
3540 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
3542 count = pStubMsg->ActualCount;
3543 for (i = 0; i < count; i++)
3544 ComplexStructMemorySize(pStubMsg, pFormat);
3546 pStubMsg->MemorySize = SavedMemorySize;
3548 pStubMsg->MemorySize += MemorySize;
3552 /***********************************************************************
3553 * NdrComplexArrayFree [RPCRT4.@]
3555 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3556 unsigned char *pMemory,
3557 PFORMAT_STRING pFormat)
3559 ULONG i, count, def;
3561 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3563 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3565 ERR("invalid format type %x\n", pFormat[0]);
3566 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3570 def = *(const WORD*)&pFormat[2];
3573 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3574 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3576 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3577 TRACE("variance = %d\n", pStubMsg->ActualCount);
3579 count = pStubMsg->ActualCount;
3580 for (i = 0; i < count; i++)
3581 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
3584 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
3585 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
3586 USER_MARSHAL_CB *umcb)
3588 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
3589 pStubMsg->RpcMsg->DataRepresentation);
3590 umcb->pStubMsg = pStubMsg;
3591 umcb->pReserve = NULL;
3592 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
3593 umcb->CBType = cbtype;
3594 umcb->pFormat = pFormat;
3595 umcb->pTypeFormat = NULL /* FIXME */;
3598 #define USER_MARSHAL_PTR_PREFIX \
3599 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3600 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3602 /***********************************************************************
3603 * NdrUserMarshalMarshall [RPCRT4.@]
3605 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3606 unsigned char *pMemory,
3607 PFORMAT_STRING pFormat)
3609 unsigned flags = pFormat[1];
3610 unsigned index = *(const WORD*)&pFormat[2];
3611 unsigned char *saved_buffer = NULL;
3612 USER_MARSHAL_CB umcb;
3614 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3615 TRACE("index=%d\n", index);
3617 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
3619 if (flags & USER_MARSHAL_POINTER)
3621 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
3622 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
3623 pStubMsg->Buffer += 4;
3624 if (pStubMsg->PointerBufferMark)
3626 saved_buffer = pStubMsg->Buffer;
3627 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3628 pStubMsg->PointerBufferMark = NULL;
3630 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
3633 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
3636 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
3637 &umcb.Flags, pStubMsg->Buffer, pMemory);
3641 STD_OVERFLOW_CHECK(pStubMsg);
3642 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3643 pStubMsg->Buffer = saved_buffer;
3646 STD_OVERFLOW_CHECK(pStubMsg);
3651 /***********************************************************************
3652 * NdrUserMarshalUnmarshall [RPCRT4.@]
3654 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3655 unsigned char **ppMemory,
3656 PFORMAT_STRING pFormat,
3657 unsigned char fMustAlloc)
3659 unsigned flags = pFormat[1];
3660 unsigned index = *(const WORD*)&pFormat[2];
3661 DWORD memsize = *(const WORD*)&pFormat[4];
3662 unsigned char *saved_buffer = NULL;
3663 USER_MARSHAL_CB umcb;
3665 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3666 TRACE("index=%d\n", index);
3668 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
3670 if (flags & USER_MARSHAL_POINTER)
3672 ALIGN_POINTER(pStubMsg->Buffer, 4);
3673 /* skip pointer prefix */
3674 pStubMsg->Buffer += 4;
3675 if (pStubMsg->PointerBufferMark)
3677 saved_buffer = pStubMsg->Buffer;
3678 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3679 pStubMsg->PointerBufferMark = NULL;
3681 ALIGN_POINTER(pStubMsg->Buffer, 8);
3684 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3686 if (fMustAlloc || !*ppMemory)
3687 *ppMemory = NdrAllocate(pStubMsg, memsize);
3690 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
3691 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
3695 STD_OVERFLOW_CHECK(pStubMsg);
3696 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3697 pStubMsg->Buffer = saved_buffer;
3703 /***********************************************************************
3704 * NdrUserMarshalBufferSize [RPCRT4.@]
3706 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3707 unsigned char *pMemory,
3708 PFORMAT_STRING pFormat)
3710 unsigned flags = pFormat[1];
3711 unsigned index = *(const WORD*)&pFormat[2];
3712 DWORD bufsize = *(const WORD*)&pFormat[6];
3713 USER_MARSHAL_CB umcb;
3714 unsigned long saved_buffer_length = 0;
3716 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3717 TRACE("index=%d\n", index);
3719 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
3721 if (flags & USER_MARSHAL_POINTER)
3723 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3724 /* skip pointer prefix */
3725 safe_buffer_length_increment(pStubMsg, 4);
3726 if (pStubMsg->IgnoreEmbeddedPointers)
3728 if (pStubMsg->PointerLength)
3730 saved_buffer_length = pStubMsg->BufferLength;
3731 pStubMsg->BufferLength = pStubMsg->PointerLength;
3732 pStubMsg->PointerLength = 0;
3734 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
3737 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
3740 TRACE("size=%d\n", bufsize);
3741 safe_buffer_length_increment(pStubMsg, bufsize);
3744 pStubMsg->BufferLength =
3745 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
3746 &umcb.Flags, pStubMsg->BufferLength, pMemory);
3748 if (saved_buffer_length)
3750 pStubMsg->PointerLength = pStubMsg->BufferLength;
3751 pStubMsg->BufferLength = saved_buffer_length;
3756 /***********************************************************************
3757 * NdrUserMarshalMemorySize [RPCRT4.@]
3759 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3760 PFORMAT_STRING pFormat)
3762 unsigned flags = pFormat[1];
3763 unsigned index = *(const WORD*)&pFormat[2];
3764 DWORD memsize = *(const WORD*)&pFormat[4];
3765 DWORD bufsize = *(const WORD*)&pFormat[6];
3767 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3768 TRACE("index=%d\n", index);
3770 pStubMsg->MemorySize += memsize;
3772 if (flags & USER_MARSHAL_POINTER)
3774 ALIGN_POINTER(pStubMsg->Buffer, 4);
3775 /* skip pointer prefix */
3776 pStubMsg->Buffer += 4;
3777 if (pStubMsg->IgnoreEmbeddedPointers)
3778 return pStubMsg->MemorySize;
3779 ALIGN_POINTER(pStubMsg->Buffer, 8);
3782 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3785 FIXME("not implemented for varying buffer size\n");
3787 pStubMsg->Buffer += bufsize;
3789 return pStubMsg->MemorySize;
3792 /***********************************************************************
3793 * NdrUserMarshalFree [RPCRT4.@]
3795 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
3796 unsigned char *pMemory,
3797 PFORMAT_STRING pFormat)
3799 /* unsigned flags = pFormat[1]; */
3800 unsigned index = *(const WORD*)&pFormat[2];
3801 USER_MARSHAL_CB umcb;
3803 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3804 TRACE("index=%d\n", index);
3806 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
3808 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
3809 &umcb.Flags, pMemory);
3812 /***********************************************************************
3813 * NdrClearOutParameters [RPCRT4.@]
3815 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
3816 PFORMAT_STRING pFormat,
3819 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
3822 /***********************************************************************
3823 * NdrConvert [RPCRT4.@]
3825 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
3827 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
3828 /* FIXME: since this stub doesn't do any converting, the proper behavior
3829 is to raise an exception */
3832 /***********************************************************************
3833 * NdrConvert2 [RPCRT4.@]
3835 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
3837 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3838 pStubMsg, pFormat, NumberParams);
3839 /* FIXME: since this stub doesn't do any converting, the proper behavior
3840 is to raise an exception */
3843 #include "pshpack1.h"
3844 typedef struct _NDR_CSTRUCT_FORMAT
3847 unsigned char alignment;
3848 unsigned short memory_size;
3849 short offset_to_array_description;
3850 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
3851 #include "poppack.h"
3853 /***********************************************************************
3854 * NdrConformantStructMarshall [RPCRT4.@]
3856 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3857 unsigned char *pMemory,
3858 PFORMAT_STRING pFormat)
3860 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3861 PFORMAT_STRING pCArrayFormat;
3862 ULONG esize, bufsize;
3864 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3866 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3867 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3869 ERR("invalid format type %x\n", pCStructFormat->type);
3870 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3874 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3875 pCStructFormat->offset_to_array_description;
3876 if (*pCArrayFormat != RPC_FC_CARRAY)
3878 ERR("invalid array format type %x\n", pCStructFormat->type);
3879 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3882 esize = *(const WORD*)(pCArrayFormat+2);
3884 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3885 pCArrayFormat + 4, 0);
3887 WriteConformance(pStubMsg);
3889 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3891 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3893 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3894 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3896 ERR("integer overflow of memory_size %u with bufsize %u\n",
3897 pCStructFormat->memory_size, bufsize);
3898 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3900 /* copy constant sized part of struct */
3901 pStubMsg->BufferMark = pStubMsg->Buffer;
3902 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
3904 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3905 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3910 /***********************************************************************
3911 * NdrConformantStructUnmarshall [RPCRT4.@]
3913 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3914 unsigned char **ppMemory,
3915 PFORMAT_STRING pFormat,
3916 unsigned char fMustAlloc)
3918 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3919 PFORMAT_STRING pCArrayFormat;
3920 ULONG esize, bufsize;
3921 unsigned char *saved_buffer;
3923 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3925 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3926 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3928 ERR("invalid format type %x\n", pCStructFormat->type);
3929 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3932 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3933 pCStructFormat->offset_to_array_description;
3934 if (*pCArrayFormat != RPC_FC_CARRAY)
3936 ERR("invalid array format type %x\n", pCStructFormat->type);
3937 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3940 esize = *(const WORD*)(pCArrayFormat+2);
3942 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3944 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3946 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3948 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3949 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3951 ERR("integer overflow of memory_size %u with bufsize %u\n",
3952 pCStructFormat->memory_size, bufsize);
3953 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3958 SIZE_T size = pCStructFormat->memory_size + bufsize;
3959 *ppMemory = NdrAllocate(pStubMsg, size);
3963 if (!pStubMsg->IsClient && !*ppMemory)
3964 /* for servers, we just point straight into the RPC buffer */
3965 *ppMemory = pStubMsg->Buffer;
3968 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3969 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
3970 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3971 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3973 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
3974 if (*ppMemory != saved_buffer)
3975 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
3980 /***********************************************************************
3981 * NdrConformantStructBufferSize [RPCRT4.@]
3983 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3984 unsigned char *pMemory,
3985 PFORMAT_STRING pFormat)
3987 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3988 PFORMAT_STRING pCArrayFormat;
3991 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3993 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3994 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3996 ERR("invalid format type %x\n", pCStructFormat->type);
3997 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4000 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4001 pCStructFormat->offset_to_array_description;
4002 if (*pCArrayFormat != RPC_FC_CARRAY)
4004 ERR("invalid array format type %x\n", pCStructFormat->type);
4005 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4008 esize = *(const WORD*)(pCArrayFormat+2);
4010 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4011 SizeConformance(pStubMsg);
4013 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4015 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4017 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4018 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4020 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4021 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4024 /***********************************************************************
4025 * NdrConformantStructMemorySize [RPCRT4.@]
4027 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4028 PFORMAT_STRING pFormat)
4034 /***********************************************************************
4035 * NdrConformantStructFree [RPCRT4.@]
4037 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4038 unsigned char *pMemory,
4039 PFORMAT_STRING pFormat)
4041 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4042 PFORMAT_STRING pCArrayFormat;
4045 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4047 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4048 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4050 ERR("invalid format type %x\n", pCStructFormat->type);
4051 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4055 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4056 pCStructFormat->offset_to_array_description;
4057 if (*pCArrayFormat != RPC_FC_CARRAY)
4059 ERR("invalid array format type %x\n", pCStructFormat->type);
4060 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4063 esize = *(const WORD*)(pCArrayFormat+2);
4065 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4066 pCArrayFormat + 4, 0);
4068 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4070 /* copy constant sized part of struct */
4071 pStubMsg->BufferMark = pStubMsg->Buffer;
4073 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4074 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4077 /***********************************************************************
4078 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4080 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4081 unsigned char *pMemory,
4082 PFORMAT_STRING pFormat)
4084 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4085 PFORMAT_STRING pCVArrayFormat;
4086 ULONG esize, bufsize;
4088 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4090 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4091 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4093 ERR("invalid format type %x\n", pCVStructFormat->type);
4094 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4098 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4099 pCVStructFormat->offset_to_array_description;
4100 switch (*pCVArrayFormat)
4102 case RPC_FC_CVARRAY:
4103 esize = *(const WORD*)(pCVArrayFormat+2);
4105 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4106 pCVArrayFormat + 4, 0);
4107 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4110 case RPC_FC_C_CSTRING:
4111 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4112 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4113 esize = sizeof(char);
4114 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4115 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4116 pCVArrayFormat + 2, 0);
4118 pStubMsg->MaxCount = pStubMsg->ActualCount;
4120 case RPC_FC_C_WSTRING:
4121 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4122 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4123 esize = sizeof(WCHAR);
4124 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4125 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4126 pCVArrayFormat + 2, 0);
4128 pStubMsg->MaxCount = pStubMsg->ActualCount;
4131 ERR("invalid array format type %x\n", *pCVArrayFormat);
4132 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4136 WriteConformance(pStubMsg);
4138 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4140 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4142 /* write constant sized part */
4143 pStubMsg->BufferMark = pStubMsg->Buffer;
4144 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4146 WriteVariance(pStubMsg);
4148 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4150 /* write array part */
4151 safe_copy_to_buffer(pStubMsg, pMemory + pCVStructFormat->memory_size, bufsize);
4153 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4158 /***********************************************************************
4159 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4161 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4162 unsigned char **ppMemory,
4163 PFORMAT_STRING pFormat,
4164 unsigned char fMustAlloc)
4166 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4167 PFORMAT_STRING pCVArrayFormat;
4168 ULONG esize, bufsize;
4169 unsigned char cvarray_type;
4171 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4173 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4174 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4176 ERR("invalid format type %x\n", pCVStructFormat->type);
4177 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4181 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4182 pCVStructFormat->offset_to_array_description;
4183 cvarray_type = *pCVArrayFormat;
4184 switch (cvarray_type)
4186 case RPC_FC_CVARRAY:
4187 esize = *(const WORD*)(pCVArrayFormat+2);
4188 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4190 case RPC_FC_C_CSTRING:
4191 esize = sizeof(char);
4192 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4193 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4195 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4197 case RPC_FC_C_WSTRING:
4198 esize = sizeof(WCHAR);
4199 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4200 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4202 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4205 ERR("invalid array format type %x\n", *pCVArrayFormat);
4206 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4210 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4212 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4214 /* work out how much memory to allocate if we need to do so */
4215 if (!*ppMemory || fMustAlloc)
4217 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4218 *ppMemory = NdrAllocate(pStubMsg, size);
4221 /* copy the constant data */
4222 pStubMsg->BufferMark = pStubMsg->Buffer;
4223 safe_copy_from_buffer(pStubMsg, *ppMemory, pCVStructFormat->memory_size);
4225 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4227 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4229 if ((cvarray_type == RPC_FC_C_CSTRING) ||
4230 (cvarray_type == RPC_FC_C_WSTRING))
4233 /* strings must always have null terminating bytes */
4234 if (bufsize < esize)
4236 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
4237 RpcRaiseException(RPC_S_INVALID_BOUND);
4240 for (i = bufsize - esize; i < bufsize; i++)
4241 if (pStubMsg->Buffer[i] != 0)
4243 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
4244 i, pStubMsg->Buffer[i]);
4245 RpcRaiseException(RPC_S_INVALID_BOUND);
4250 /* copy the array data */
4251 safe_copy_from_buffer(pStubMsg, *ppMemory + pCVStructFormat->memory_size, bufsize);
4253 if (cvarray_type == RPC_FC_C_CSTRING)
4254 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
4255 else if (cvarray_type == RPC_FC_C_WSTRING)
4256 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
4258 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
4263 /***********************************************************************
4264 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4266 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4267 unsigned char *pMemory,
4268 PFORMAT_STRING pFormat)
4270 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4271 PFORMAT_STRING pCVArrayFormat;
4274 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4276 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4277 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4279 ERR("invalid format type %x\n", pCVStructFormat->type);
4280 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4284 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4285 pCVStructFormat->offset_to_array_description;
4286 switch (*pCVArrayFormat)
4288 case RPC_FC_CVARRAY:
4289 esize = *(const WORD*)(pCVArrayFormat+2);
4291 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4292 pCVArrayFormat + 4, 0);
4293 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4296 case RPC_FC_C_CSTRING:
4297 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4298 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4299 esize = sizeof(char);
4300 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4301 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4302 pCVArrayFormat + 2, 0);
4304 pStubMsg->MaxCount = pStubMsg->ActualCount;
4306 case RPC_FC_C_WSTRING:
4307 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4308 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4309 esize = sizeof(WCHAR);
4310 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4311 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4312 pCVArrayFormat + 2, 0);
4314 pStubMsg->MaxCount = pStubMsg->ActualCount;
4317 ERR("invalid array format type %x\n", *pCVArrayFormat);
4318 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4322 SizeConformance(pStubMsg);
4324 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4326 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4328 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4329 SizeVariance(pStubMsg);
4330 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4332 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4335 /***********************************************************************
4336 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4338 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4339 PFORMAT_STRING pFormat)
4341 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4342 PFORMAT_STRING pCVArrayFormat;
4344 unsigned char cvarray_type;
4346 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4348 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4349 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4351 ERR("invalid format type %x\n", pCVStructFormat->type);
4352 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4356 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4357 pCVStructFormat->offset_to_array_description;
4358 cvarray_type = *pCVArrayFormat;
4359 switch (cvarray_type)
4361 case RPC_FC_CVARRAY:
4362 esize = *(const WORD*)(pCVArrayFormat+2);
4363 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4365 case RPC_FC_C_CSTRING:
4366 esize = sizeof(char);
4367 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4368 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4370 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4372 case RPC_FC_C_WSTRING:
4373 esize = sizeof(WCHAR);
4374 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4375 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4377 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4380 ERR("invalid array format type %x\n", *pCVArrayFormat);
4381 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4385 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4387 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4389 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4390 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4391 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4393 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4395 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4397 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
4400 /***********************************************************************
4401 * NdrConformantVaryingStructFree [RPCRT4.@]
4403 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4404 unsigned char *pMemory,
4405 PFORMAT_STRING pFormat)
4407 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4408 PFORMAT_STRING pCVArrayFormat;
4411 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4413 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4414 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4416 ERR("invalid format type %x\n", pCVStructFormat->type);
4417 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4421 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4422 pCVStructFormat->offset_to_array_description;
4423 switch (*pCVArrayFormat)
4425 case RPC_FC_CVARRAY:
4426 esize = *(const WORD*)(pCVArrayFormat+2);
4428 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4429 pCVArrayFormat + 4, 0);
4430 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4433 case RPC_FC_C_CSTRING:
4434 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4435 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4436 esize = sizeof(char);
4437 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4438 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4439 pCVArrayFormat + 2, 0);
4441 pStubMsg->MaxCount = pStubMsg->ActualCount;
4443 case RPC_FC_C_WSTRING:
4444 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4445 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4446 esize = sizeof(WCHAR);
4447 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4448 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4449 pCVArrayFormat + 2, 0);
4451 pStubMsg->MaxCount = pStubMsg->ActualCount;
4454 ERR("invalid array format type %x\n", *pCVArrayFormat);
4455 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4459 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4461 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4464 #include "pshpack1.h"
4468 unsigned char alignment;
4469 unsigned short total_size;
4470 } NDR_SMFARRAY_FORMAT;
4475 unsigned char alignment;
4476 unsigned long total_size;
4477 } NDR_LGFARRAY_FORMAT;
4478 #include "poppack.h"
4480 /***********************************************************************
4481 * NdrFixedArrayMarshall [RPCRT4.@]
4483 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4484 unsigned char *pMemory,
4485 PFORMAT_STRING pFormat)
4487 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4488 unsigned long total_size;
4490 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4492 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4493 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4495 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4496 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4500 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4502 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4504 total_size = pSmFArrayFormat->total_size;
4505 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4509 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4510 total_size = pLgFArrayFormat->total_size;
4511 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4514 pStubMsg->BufferMark = pStubMsg->Buffer;
4515 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4517 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4522 /***********************************************************************
4523 * NdrFixedArrayUnmarshall [RPCRT4.@]
4525 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4526 unsigned char **ppMemory,
4527 PFORMAT_STRING pFormat,
4528 unsigned char fMustAlloc)
4530 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4531 unsigned long total_size;
4532 unsigned char *saved_buffer;
4534 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4536 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4537 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4539 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4540 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4544 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4546 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4548 total_size = pSmFArrayFormat->total_size;
4549 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4553 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4554 total_size = pLgFArrayFormat->total_size;
4555 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4559 *ppMemory = NdrAllocate(pStubMsg, total_size);
4562 if (!pStubMsg->IsClient && !*ppMemory)
4563 /* for servers, we just point straight into the RPC buffer */
4564 *ppMemory = pStubMsg->Buffer;
4567 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4568 safe_buffer_increment(pStubMsg, total_size);
4569 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4571 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4572 if (*ppMemory != saved_buffer)
4573 memcpy(*ppMemory, saved_buffer, total_size);
4578 /***********************************************************************
4579 * NdrFixedArrayBufferSize [RPCRT4.@]
4581 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4582 unsigned char *pMemory,
4583 PFORMAT_STRING pFormat)
4585 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4586 unsigned long total_size;
4588 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4590 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4591 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4593 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4594 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4598 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4600 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4602 total_size = pSmFArrayFormat->total_size;
4603 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4607 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4608 total_size = pLgFArrayFormat->total_size;
4609 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4611 safe_buffer_length_increment(pStubMsg, total_size);
4613 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4616 /***********************************************************************
4617 * NdrFixedArrayMemorySize [RPCRT4.@]
4619 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4620 PFORMAT_STRING pFormat)
4622 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4625 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4627 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4628 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4630 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4631 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4635 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4637 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4639 total_size = pSmFArrayFormat->total_size;
4640 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4644 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4645 total_size = pLgFArrayFormat->total_size;
4646 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4648 pStubMsg->BufferMark = pStubMsg->Buffer;
4649 safe_buffer_increment(pStubMsg, total_size);
4650 pStubMsg->MemorySize += total_size;
4652 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4657 /***********************************************************************
4658 * NdrFixedArrayFree [RPCRT4.@]
4660 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4661 unsigned char *pMemory,
4662 PFORMAT_STRING pFormat)
4664 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4666 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4668 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4669 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4671 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4672 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4676 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4677 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4680 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4681 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4684 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4687 /***********************************************************************
4688 * NdrVaryingArrayMarshall [RPCRT4.@]
4690 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4691 unsigned char *pMemory,
4692 PFORMAT_STRING pFormat)
4694 unsigned char alignment;
4695 DWORD elements, esize;
4698 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4700 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4701 (pFormat[0] != RPC_FC_LGVARRAY))
4703 ERR("invalid format type %x\n", pFormat[0]);
4704 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4708 alignment = pFormat[1] + 1;
4710 if (pFormat[0] == RPC_FC_SMVARRAY)
4713 pFormat += sizeof(WORD);
4714 elements = *(const WORD*)pFormat;
4715 pFormat += sizeof(WORD);
4720 pFormat += sizeof(DWORD);
4721 elements = *(const DWORD*)pFormat;
4722 pFormat += sizeof(DWORD);
4725 esize = *(const WORD*)pFormat;
4726 pFormat += sizeof(WORD);
4728 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4729 if ((pStubMsg->ActualCount > elements) ||
4730 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4732 RpcRaiseException(RPC_S_INVALID_BOUND);
4736 WriteVariance(pStubMsg);
4738 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
4740 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4741 pStubMsg->BufferMark = pStubMsg->Buffer;
4742 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
4744 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4749 /***********************************************************************
4750 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4752 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4753 unsigned char **ppMemory,
4754 PFORMAT_STRING pFormat,
4755 unsigned char fMustAlloc)
4757 unsigned char alignment;
4758 DWORD size, elements, esize;
4760 unsigned char *saved_buffer;
4763 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4765 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4766 (pFormat[0] != RPC_FC_LGVARRAY))
4768 ERR("invalid format type %x\n", pFormat[0]);
4769 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4773 alignment = pFormat[1] + 1;
4775 if (pFormat[0] == RPC_FC_SMVARRAY)
4778 size = *(const WORD*)pFormat;
4779 pFormat += sizeof(WORD);
4780 elements = *(const WORD*)pFormat;
4781 pFormat += sizeof(WORD);
4786 size = *(const DWORD*)pFormat;
4787 pFormat += sizeof(DWORD);
4788 elements = *(const DWORD*)pFormat;
4789 pFormat += sizeof(DWORD);
4792 esize = *(const WORD*)pFormat;
4793 pFormat += sizeof(WORD);
4795 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4797 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4799 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4800 offset = pStubMsg->Offset;
4802 if (!*ppMemory || fMustAlloc)
4803 *ppMemory = NdrAllocate(pStubMsg, size);
4804 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4805 safe_buffer_increment(pStubMsg, bufsize);
4807 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4809 memcpy(*ppMemory + offset, saved_buffer, bufsize);
4814 /***********************************************************************
4815 * NdrVaryingArrayBufferSize [RPCRT4.@]
4817 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4818 unsigned char *pMemory,
4819 PFORMAT_STRING pFormat)
4821 unsigned char alignment;
4822 DWORD elements, esize;
4824 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4826 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4827 (pFormat[0] != RPC_FC_LGVARRAY))
4829 ERR("invalid format type %x\n", pFormat[0]);
4830 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4834 alignment = pFormat[1] + 1;
4836 if (pFormat[0] == RPC_FC_SMVARRAY)
4839 pFormat += sizeof(WORD);
4840 elements = *(const WORD*)pFormat;
4841 pFormat += sizeof(WORD);
4846 pFormat += sizeof(DWORD);
4847 elements = *(const DWORD*)pFormat;
4848 pFormat += sizeof(DWORD);
4851 esize = *(const WORD*)pFormat;
4852 pFormat += sizeof(WORD);
4854 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4855 if ((pStubMsg->ActualCount > elements) ||
4856 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4858 RpcRaiseException(RPC_S_INVALID_BOUND);
4862 SizeVariance(pStubMsg);
4864 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4866 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4868 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4871 /***********************************************************************
4872 * NdrVaryingArrayMemorySize [RPCRT4.@]
4874 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4875 PFORMAT_STRING pFormat)
4877 unsigned char alignment;
4878 DWORD size, elements, esize;
4880 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4882 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4883 (pFormat[0] != RPC_FC_LGVARRAY))
4885 ERR("invalid format type %x\n", pFormat[0]);
4886 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4890 alignment = pFormat[1] + 1;
4892 if (pFormat[0] == RPC_FC_SMVARRAY)
4895 size = *(const WORD*)pFormat;
4896 pFormat += sizeof(WORD);
4897 elements = *(const WORD*)pFormat;
4898 pFormat += sizeof(WORD);
4903 size = *(const DWORD*)pFormat;
4904 pFormat += sizeof(DWORD);
4905 elements = *(const DWORD*)pFormat;
4906 pFormat += sizeof(DWORD);
4909 esize = *(const WORD*)pFormat;
4910 pFormat += sizeof(WORD);
4912 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4914 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4916 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4917 pStubMsg->MemorySize += size;
4919 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4921 return pStubMsg->MemorySize;
4924 /***********************************************************************
4925 * NdrVaryingArrayFree [RPCRT4.@]
4927 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4928 unsigned char *pMemory,
4929 PFORMAT_STRING pFormat)
4931 unsigned char alignment;
4934 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4936 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4937 (pFormat[0] != RPC_FC_LGVARRAY))
4939 ERR("invalid format type %x\n", pFormat[0]);
4940 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4944 alignment = pFormat[1] + 1;
4946 if (pFormat[0] == RPC_FC_SMVARRAY)
4949 pFormat += sizeof(WORD);
4950 elements = *(const WORD*)pFormat;
4951 pFormat += sizeof(WORD);
4956 pFormat += sizeof(DWORD);
4957 elements = *(const DWORD*)pFormat;
4958 pFormat += sizeof(DWORD);
4961 pFormat += sizeof(WORD);
4963 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4964 if ((pStubMsg->ActualCount > elements) ||
4965 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4967 RpcRaiseException(RPC_S_INVALID_BOUND);
4971 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4974 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
4987 return *(const USHORT *)pMemory;
4991 return *(const ULONG *)pMemory;
4993 FIXME("Unhandled base type: 0x%02x\n", fc);
4998 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4999 unsigned long discriminant,
5000 PFORMAT_STRING pFormat)
5002 unsigned short num_arms, arm, type;
5004 num_arms = *(const SHORT*)pFormat & 0x0fff;
5006 for(arm = 0; arm < num_arms; arm++)
5008 if(discriminant == *(const ULONG*)pFormat)
5016 type = *(const unsigned short*)pFormat;
5017 TRACE("type %04x\n", type);
5018 if(arm == num_arms) /* default arm extras */
5022 ERR("no arm for 0x%lx and no default case\n", discriminant);
5023 RpcRaiseException(RPC_S_INVALID_TAG);
5028 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
5035 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5037 unsigned short type;
5041 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5045 type = *(const unsigned short*)pFormat;
5046 if((type & 0xff00) == 0x8000)
5048 unsigned char basetype = LOBYTE(type);
5049 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5053 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5054 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5057 unsigned char *saved_buffer = NULL;
5058 int pointer_buffer_mark_set = 0;
5065 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5066 saved_buffer = pStubMsg->Buffer;
5067 if (pStubMsg->PointerBufferMark)
5069 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5070 pStubMsg->PointerBufferMark = NULL;
5071 pointer_buffer_mark_set = 1;
5074 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5076 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5077 if (pointer_buffer_mark_set)
5079 STD_OVERFLOW_CHECK(pStubMsg);
5080 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5081 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5083 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5084 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5085 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5087 pStubMsg->Buffer = saved_buffer + 4;
5091 m(pStubMsg, pMemory, desc);
5094 else FIXME("no marshaller for embedded type %02x\n", *desc);
5099 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5100 unsigned char **ppMemory,
5102 PFORMAT_STRING pFormat,
5103 unsigned char fMustAlloc)
5105 unsigned short type;
5109 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5113 type = *(const unsigned short*)pFormat;
5114 if((type & 0xff00) == 0x8000)
5116 unsigned char basetype = LOBYTE(type);
5117 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5121 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5122 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5125 unsigned char *saved_buffer = NULL;
5126 int pointer_buffer_mark_set = 0;
5133 **(void***)ppMemory = NULL;
5134 ALIGN_POINTER(pStubMsg->Buffer, 4);
5135 saved_buffer = pStubMsg->Buffer;
5136 if (pStubMsg->PointerBufferMark)
5138 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5139 pStubMsg->PointerBufferMark = NULL;
5140 pointer_buffer_mark_set = 1;
5143 pStubMsg->Buffer += 4; /* for pointer ID */
5145 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5147 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5148 saved_buffer, pStubMsg->BufferEnd);
5149 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5152 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5153 if (pointer_buffer_mark_set)
5155 STD_OVERFLOW_CHECK(pStubMsg);
5156 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5157 pStubMsg->Buffer = saved_buffer + 4;
5161 m(pStubMsg, ppMemory, desc, fMustAlloc);
5164 else FIXME("no marshaller for embedded type %02x\n", *desc);
5169 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5170 unsigned char *pMemory,
5172 PFORMAT_STRING pFormat)
5174 unsigned short type;
5178 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5182 type = *(const unsigned short*)pFormat;
5183 if((type & 0xff00) == 0x8000)
5185 unsigned char basetype = LOBYTE(type);
5186 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5190 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5191 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5200 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5201 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5202 if (!pStubMsg->IgnoreEmbeddedPointers)
5204 int saved_buffer_length = pStubMsg->BufferLength;
5205 pStubMsg->BufferLength = pStubMsg->PointerLength;
5206 pStubMsg->PointerLength = 0;
5207 if(!pStubMsg->BufferLength)
5208 ERR("BufferLength == 0??\n");
5209 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5210 pStubMsg->PointerLength = pStubMsg->BufferLength;
5211 pStubMsg->BufferLength = saved_buffer_length;
5215 m(pStubMsg, pMemory, desc);
5218 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5222 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5224 PFORMAT_STRING pFormat)
5226 unsigned short type, size;
5228 size = *(const unsigned short*)pFormat;
5229 pStubMsg->Memory += size;
5232 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5236 type = *(const unsigned short*)pFormat;
5237 if((type & 0xff00) == 0x8000)
5239 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5243 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5244 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5245 unsigned char *saved_buffer;
5254 ALIGN_POINTER(pStubMsg->Buffer, 4);
5255 saved_buffer = pStubMsg->Buffer;
5256 safe_buffer_increment(pStubMsg, 4);
5257 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
5258 pStubMsg->MemorySize += 4;
5259 if (!pStubMsg->IgnoreEmbeddedPointers)
5260 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5263 return m(pStubMsg, desc);
5266 else FIXME("no marshaller for embedded type %02x\n", *desc);
5269 TRACE("size %d\n", size);
5273 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5274 unsigned char *pMemory,
5276 PFORMAT_STRING pFormat)
5278 unsigned short type;
5282 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5286 type = *(const unsigned short*)pFormat;
5287 if((type & 0xff00) != 0x8000)
5289 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5290 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5299 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5302 m(pStubMsg, pMemory, desc);
5308 /***********************************************************************
5309 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5311 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5312 unsigned char *pMemory,
5313 PFORMAT_STRING pFormat)
5315 unsigned char switch_type;
5316 unsigned char increment;
5319 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5322 switch_type = *pFormat & 0xf;
5323 increment = (*pFormat & 0xf0) >> 4;
5326 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5328 switch_value = get_discriminant(switch_type, pMemory);
5329 TRACE("got switch value 0x%x\n", switch_value);
5331 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5332 pMemory += increment;
5334 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5337 /***********************************************************************
5338 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5340 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5341 unsigned char **ppMemory,
5342 PFORMAT_STRING pFormat,
5343 unsigned char fMustAlloc)
5345 unsigned char switch_type;
5346 unsigned char increment;
5348 unsigned short size;
5349 unsigned char *pMemoryArm;
5351 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5354 switch_type = *pFormat & 0xf;
5355 increment = (*pFormat & 0xf0) >> 4;
5358 ALIGN_POINTER(pStubMsg->Buffer, increment);
5359 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5360 TRACE("got switch value 0x%x\n", switch_value);
5362 size = *(const unsigned short*)pFormat + increment;
5363 if(!*ppMemory || fMustAlloc)
5364 *ppMemory = NdrAllocate(pStubMsg, size);
5366 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5367 pMemoryArm = *ppMemory + increment;
5369 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
5372 /***********************************************************************
5373 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5375 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5376 unsigned char *pMemory,
5377 PFORMAT_STRING pFormat)
5379 unsigned char switch_type;
5380 unsigned char increment;
5383 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5386 switch_type = *pFormat & 0xf;
5387 increment = (*pFormat & 0xf0) >> 4;
5390 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5391 switch_value = get_discriminant(switch_type, pMemory);
5392 TRACE("got switch value 0x%x\n", switch_value);
5394 /* Add discriminant size */
5395 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5396 pMemory += increment;
5398 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5401 /***********************************************************************
5402 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5404 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5405 PFORMAT_STRING pFormat)
5407 unsigned char switch_type;
5408 unsigned char increment;
5411 switch_type = *pFormat & 0xf;
5412 increment = (*pFormat & 0xf0) >> 4;
5415 ALIGN_POINTER(pStubMsg->Buffer, increment);
5416 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5417 TRACE("got switch value 0x%x\n", switch_value);
5419 pStubMsg->Memory += increment;
5421 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5424 /***********************************************************************
5425 * NdrEncapsulatedUnionFree [RPCRT4.@]
5427 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5428 unsigned char *pMemory,
5429 PFORMAT_STRING pFormat)
5431 unsigned char switch_type;
5432 unsigned char increment;
5435 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5438 switch_type = *pFormat & 0xf;
5439 increment = (*pFormat & 0xf0) >> 4;
5442 switch_value = get_discriminant(switch_type, pMemory);
5443 TRACE("got switch value 0x%x\n", switch_value);
5445 pMemory += increment;
5447 return union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5450 /***********************************************************************
5451 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5453 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5454 unsigned char *pMemory,
5455 PFORMAT_STRING pFormat)
5457 unsigned char switch_type;
5459 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5462 switch_type = *pFormat;
5465 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5466 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5467 /* Marshall discriminant */
5468 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5470 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5473 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5474 PFORMAT_STRING *ppFormat)
5476 long discriminant = 0;
5486 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5495 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5496 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5504 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5505 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5510 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5514 if (pStubMsg->fHasNewCorrDesc)
5518 return discriminant;
5521 /**********************************************************************
5522 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5524 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5525 unsigned char **ppMemory,
5526 PFORMAT_STRING pFormat,
5527 unsigned char fMustAlloc)
5530 unsigned short size;
5532 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5535 /* Unmarshall discriminant */
5536 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5537 TRACE("unmarshalled discriminant %lx\n", discriminant);
5539 pFormat += *(const SHORT*)pFormat;
5541 size = *(const unsigned short*)pFormat;
5543 if(!*ppMemory || fMustAlloc)
5544 *ppMemory = NdrAllocate(pStubMsg, size);
5546 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5549 /***********************************************************************
5550 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5552 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5553 unsigned char *pMemory,
5554 PFORMAT_STRING pFormat)
5556 unsigned char switch_type;
5558 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5561 switch_type = *pFormat;
5564 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5565 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5566 /* Add discriminant size */
5567 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5569 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5572 /***********************************************************************
5573 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5575 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5576 PFORMAT_STRING pFormat)
5581 /* Unmarshall discriminant */
5582 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5583 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
5585 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
5588 /***********************************************************************
5589 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5591 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5592 unsigned char *pMemory,
5593 PFORMAT_STRING pFormat)
5595 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5599 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5600 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5602 return union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5605 /***********************************************************************
5606 * NdrByteCountPointerMarshall [RPCRT4.@]
5608 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5609 unsigned char *pMemory,
5610 PFORMAT_STRING pFormat)
5616 /***********************************************************************
5617 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5619 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5620 unsigned char **ppMemory,
5621 PFORMAT_STRING pFormat,
5622 unsigned char fMustAlloc)
5628 /***********************************************************************
5629 * NdrByteCountPointerBufferSize [RPCRT4.@]
5631 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5632 unsigned char *pMemory,
5633 PFORMAT_STRING pFormat)
5638 /***********************************************************************
5639 * NdrByteCountPointerMemorySize [RPCRT4.@]
5641 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5642 PFORMAT_STRING pFormat)
5648 /***********************************************************************
5649 * NdrByteCountPointerFree [RPCRT4.@]
5651 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
5652 unsigned char *pMemory,
5653 PFORMAT_STRING pFormat)
5658 /***********************************************************************
5659 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5661 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5662 unsigned char *pMemory,
5663 PFORMAT_STRING pFormat)
5669 /***********************************************************************
5670 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5672 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5673 unsigned char **ppMemory,
5674 PFORMAT_STRING pFormat,
5675 unsigned char fMustAlloc)
5681 /***********************************************************************
5682 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5684 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5685 unsigned char *pMemory,
5686 PFORMAT_STRING pFormat)
5691 /***********************************************************************
5692 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5694 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5695 PFORMAT_STRING pFormat)
5701 /***********************************************************************
5702 * NdrXmitOrRepAsFree [RPCRT4.@]
5704 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
5705 unsigned char *pMemory,
5706 PFORMAT_STRING pFormat)
5711 #include "pshpack1.h"
5715 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
5719 #include "poppack.h"
5721 /***********************************************************************
5722 * NdrRangeMarshall [internal]
5724 unsigned char *WINAPI NdrRangeMarshall(
5725 PMIDL_STUB_MESSAGE pStubMsg,
5726 unsigned char *pMemory,
5727 PFORMAT_STRING pFormat)
5729 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5730 unsigned char base_type;
5732 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5734 if (pRange->type != RPC_FC_RANGE)
5736 ERR("invalid format type %x\n", pRange->type);
5737 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5741 base_type = pRange->flags_type & 0xf;
5743 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
5746 /***********************************************************************
5747 * NdrRangeUnmarshall
5749 unsigned char *WINAPI NdrRangeUnmarshall(
5750 PMIDL_STUB_MESSAGE pStubMsg,
5751 unsigned char **ppMemory,
5752 PFORMAT_STRING pFormat,
5753 unsigned char fMustAlloc)
5755 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5756 unsigned char base_type;
5758 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5760 if (pRange->type != RPC_FC_RANGE)
5762 ERR("invalid format type %x\n", pRange->type);
5763 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5766 base_type = pRange->flags_type & 0xf;
5768 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5769 base_type, pRange->low_value, pRange->high_value);
5771 #define RANGE_UNMARSHALL(type, format_spec) \
5774 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5775 if (fMustAlloc || !*ppMemory) \
5776 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5777 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5779 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5780 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5781 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5783 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5784 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5786 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5787 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5788 (type)pRange->high_value); \
5789 RpcRaiseException(RPC_S_INVALID_BOUND); \
5792 TRACE("*ppMemory: %p\n", *ppMemory); \
5793 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5794 pStubMsg->Buffer += sizeof(type); \
5801 RANGE_UNMARSHALL(UCHAR, "%d");
5802 TRACE("value: 0x%02x\n", **ppMemory);
5806 RANGE_UNMARSHALL(CHAR, "%u");
5807 TRACE("value: 0x%02x\n", **ppMemory);
5809 case RPC_FC_WCHAR: /* FIXME: valid? */
5811 RANGE_UNMARSHALL(USHORT, "%u");
5812 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5815 RANGE_UNMARSHALL(SHORT, "%d");
5816 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5819 RANGE_UNMARSHALL(LONG, "%d");
5820 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5823 RANGE_UNMARSHALL(ULONG, "%u");
5824 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5828 FIXME("Unhandled enum type\n");
5830 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
5835 ERR("invalid range base type: 0x%02x\n", base_type);
5836 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5842 /***********************************************************************
5843 * NdrRangeBufferSize [internal]
5845 void WINAPI NdrRangeBufferSize(
5846 PMIDL_STUB_MESSAGE pStubMsg,
5847 unsigned char *pMemory,
5848 PFORMAT_STRING pFormat)
5850 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5851 unsigned char base_type;
5853 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5855 if (pRange->type != RPC_FC_RANGE)
5857 ERR("invalid format type %x\n", pRange->type);
5858 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5860 base_type = pRange->flags_type & 0xf;
5862 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
5865 /***********************************************************************
5866 * NdrRangeMemorySize [internal]
5868 ULONG WINAPI NdrRangeMemorySize(
5869 PMIDL_STUB_MESSAGE pStubMsg,
5870 PFORMAT_STRING pFormat)
5872 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5873 unsigned char base_type;
5875 if (pRange->type != RPC_FC_RANGE)
5877 ERR("invalid format type %x\n", pRange->type);
5878 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5881 base_type = pRange->flags_type & 0xf;
5883 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
5886 /***********************************************************************
5887 * NdrRangeFree [internal]
5889 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
5890 unsigned char *pMemory,
5891 PFORMAT_STRING pFormat)
5893 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5898 /***********************************************************************
5899 * NdrBaseTypeMarshall [internal]
5901 static unsigned char *WINAPI NdrBaseTypeMarshall(
5902 PMIDL_STUB_MESSAGE pStubMsg,
5903 unsigned char *pMemory,
5904 PFORMAT_STRING pFormat)
5906 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5914 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
5915 TRACE("value: 0x%02x\n", *pMemory);
5920 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
5921 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
5922 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
5926 case RPC_FC_ERROR_STATUS_T:
5928 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
5929 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
5930 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
5933 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
5934 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
5937 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
5938 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
5941 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
5942 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
5943 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
5946 /* only 16-bits on the wire, so do a sanity check */
5947 if (*(UINT *)pMemory > SHRT_MAX)
5948 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
5949 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
5950 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5951 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5952 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
5953 pStubMsg->Buffer += sizeof(USHORT);
5954 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
5959 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5962 /* FIXME: what is the correct return value? */
5966 /***********************************************************************
5967 * NdrBaseTypeUnmarshall [internal]
5969 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
5970 PMIDL_STUB_MESSAGE pStubMsg,
5971 unsigned char **ppMemory,
5972 PFORMAT_STRING pFormat,
5973 unsigned char fMustAlloc)
5975 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5977 #define BASE_TYPE_UNMARSHALL(type) \
5978 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5979 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
5981 *ppMemory = pStubMsg->Buffer; \
5982 TRACE("*ppMemory: %p\n", *ppMemory); \
5987 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5988 TRACE("*ppMemory: %p\n", *ppMemory); \
5989 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5991 pStubMsg->Buffer += sizeof(type);
5999 BASE_TYPE_UNMARSHALL(UCHAR);
6000 TRACE("value: 0x%02x\n", **ppMemory);
6005 BASE_TYPE_UNMARSHALL(USHORT);
6006 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6010 case RPC_FC_ERROR_STATUS_T:
6012 BASE_TYPE_UNMARSHALL(ULONG);
6013 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6016 BASE_TYPE_UNMARSHALL(float);
6017 TRACE("value: %f\n", **(float **)ppMemory);
6020 BASE_TYPE_UNMARSHALL(double);
6021 TRACE("value: %f\n", **(double **)ppMemory);
6024 BASE_TYPE_UNMARSHALL(ULONGLONG);
6025 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6028 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6029 if (fMustAlloc || !*ppMemory)
6030 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6031 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
6032 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6033 TRACE("*ppMemory: %p\n", *ppMemory);
6034 /* 16-bits on the wire, but int in memory */
6035 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
6036 pStubMsg->Buffer += sizeof(USHORT);
6037 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6042 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6044 #undef BASE_TYPE_UNMARSHALL
6046 /* FIXME: what is the correct return value? */
6051 /***********************************************************************
6052 * NdrBaseTypeBufferSize [internal]
6054 static void WINAPI NdrBaseTypeBufferSize(
6055 PMIDL_STUB_MESSAGE pStubMsg,
6056 unsigned char *pMemory,
6057 PFORMAT_STRING pFormat)
6059 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6067 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6073 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
6074 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6079 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
6080 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6083 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
6084 safe_buffer_length_increment(pStubMsg, sizeof(float));
6087 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
6088 safe_buffer_length_increment(pStubMsg, sizeof(double));
6091 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
6092 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6094 case RPC_FC_ERROR_STATUS_T:
6095 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
6096 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6101 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6105 /***********************************************************************
6106 * NdrBaseTypeMemorySize [internal]
6108 static ULONG WINAPI NdrBaseTypeMemorySize(
6109 PMIDL_STUB_MESSAGE pStubMsg,
6110 PFORMAT_STRING pFormat)
6112 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6120 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6121 pStubMsg->MemorySize += sizeof(UCHAR);
6122 return sizeof(UCHAR);
6126 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6127 pStubMsg->MemorySize += sizeof(USHORT);
6128 return sizeof(USHORT);
6132 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6133 pStubMsg->MemorySize += sizeof(ULONG);
6134 return sizeof(ULONG);
6136 safe_buffer_increment(pStubMsg, sizeof(float));
6137 pStubMsg->MemorySize += sizeof(float);
6138 return sizeof(float);
6140 safe_buffer_increment(pStubMsg, sizeof(double));
6141 pStubMsg->MemorySize += sizeof(double);
6142 return sizeof(double);
6144 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6145 pStubMsg->MemorySize += sizeof(ULONGLONG);
6146 return sizeof(ULONGLONG);
6147 case RPC_FC_ERROR_STATUS_T:
6148 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6149 pStubMsg->MemorySize += sizeof(error_status_t);
6150 return sizeof(error_status_t);
6152 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6153 pStubMsg->MemorySize += sizeof(UINT);
6154 return sizeof(UINT);
6156 pStubMsg->MemorySize += sizeof(void *);
6157 return sizeof(void *);
6159 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6164 /***********************************************************************
6165 * NdrBaseTypeFree [internal]
6167 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6168 unsigned char *pMemory,
6169 PFORMAT_STRING pFormat)
6171 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6176 /***********************************************************************
6177 * NdrContextHandleBufferSize [internal]
6179 static void WINAPI NdrContextHandleBufferSize(
6180 PMIDL_STUB_MESSAGE pStubMsg,
6181 unsigned char *pMemory,
6182 PFORMAT_STRING pFormat)
6184 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6186 if (*pFormat != RPC_FC_BIND_CONTEXT)
6188 ERR("invalid format type %x\n", *pFormat);
6189 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6191 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
6192 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6195 /***********************************************************************
6196 * NdrContextHandleMarshall [internal]
6198 static unsigned char *WINAPI NdrContextHandleMarshall(
6199 PMIDL_STUB_MESSAGE pStubMsg,
6200 unsigned char *pMemory,
6201 PFORMAT_STRING pFormat)
6203 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6205 if (*pFormat != RPC_FC_BIND_CONTEXT)
6207 ERR("invalid format type %x\n", *pFormat);
6208 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6210 TRACE("flags: 0x%02x\n", pFormat[1]);
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 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6230 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6232 if (*pFormat != RPC_FC_BIND_CONTEXT)
6234 ERR("invalid format type %x\n", *pFormat);
6235 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6237 TRACE("flags: 0x%02x\n", pFormat[1]);
6239 /* [out]-only or [ret] param */
6240 if ((pFormat[1] & 0x60) == 0x20)
6241 **(NDR_CCONTEXT **)ppMemory = NULL;
6242 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6247 /***********************************************************************
6248 * NdrClientContextMarshall [RPCRT4.@]
6250 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6251 NDR_CCONTEXT ContextHandle,
6254 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
6256 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
6258 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6260 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6261 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6262 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6265 /* FIXME: what does fCheck do? */
6266 NDRCContextMarshall(ContextHandle,
6269 pStubMsg->Buffer += cbNDRContext;
6272 /***********************************************************************
6273 * NdrClientContextUnmarshall [RPCRT4.@]
6275 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6276 NDR_CCONTEXT * pContextHandle,
6277 RPC_BINDING_HANDLE BindHandle)
6279 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
6281 ALIGN_POINTER(pStubMsg->Buffer, 4);
6283 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
6284 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6286 NDRCContextUnmarshall(pContextHandle,
6289 pStubMsg->RpcMsg->DataRepresentation);
6291 pStubMsg->Buffer += cbNDRContext;
6294 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6295 NDR_SCONTEXT ContextHandle,
6296 NDR_RUNDOWN RundownRoutine )
6298 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
6300 ALIGN_POINTER(pStubMsg->Buffer, 4);
6302 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6304 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6305 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6306 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6309 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6310 pStubMsg->Buffer, RundownRoutine, NULL,
6311 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6312 pStubMsg->Buffer += cbNDRContext;
6315 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6317 NDR_SCONTEXT ContextHandle;
6319 TRACE("(%p)\n", pStubMsg);
6321 ALIGN_POINTER(pStubMsg->Buffer, 4);
6323 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6325 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6326 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6327 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6330 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6332 pStubMsg->RpcMsg->DataRepresentation,
6333 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6334 pStubMsg->Buffer += cbNDRContext;
6336 return ContextHandle;
6339 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6340 unsigned char* pMemory,
6341 PFORMAT_STRING pFormat)
6343 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6346 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6347 PFORMAT_STRING pFormat)
6349 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6350 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6352 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6354 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6355 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6356 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6357 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6358 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6360 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6361 if_id = &sif->InterfaceId;
6364 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
6365 pStubMsg->RpcMsg->DataRepresentation, if_id,
6369 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6370 NDR_SCONTEXT ContextHandle,
6371 NDR_RUNDOWN RundownRoutine,
6372 PFORMAT_STRING pFormat)
6374 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6375 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6377 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6379 ALIGN_POINTER(pStubMsg->Buffer, 4);
6381 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6383 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6384 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6385 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6388 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6389 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6390 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6391 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6392 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6394 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6395 if_id = &sif->InterfaceId;
6398 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6399 pStubMsg->Buffer, RundownRoutine, if_id, flags);
6400 pStubMsg->Buffer += cbNDRContext;
6403 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6404 PFORMAT_STRING pFormat)
6406 NDR_SCONTEXT ContextHandle;
6407 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6408 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6410 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6412 ALIGN_POINTER(pStubMsg->Buffer, 4);
6414 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6416 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6417 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6418 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6421 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6422 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6423 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6424 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6425 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6427 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6428 if_id = &sif->InterfaceId;
6431 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6433 pStubMsg->RpcMsg->DataRepresentation,
6435 pStubMsg->Buffer += cbNDRContext;
6437 return ContextHandle;
6440 /***********************************************************************
6441 * NdrCorrelationInitialize [RPCRT4.@]
6443 * Initializes correlation validity checking.
6446 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6447 * pMemory [I] Pointer to memory to use as a cache.
6448 * CacheSize [I] Size of the memory pointed to by pMemory.
6449 * Flags [I] Reserved. Set to zero.
6454 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
6456 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
6457 pStubMsg->fHasNewCorrDesc = TRUE;
6460 /***********************************************************************
6461 * NdrCorrelationPass [RPCRT4.@]
6463 * Performs correlation validity checking.
6466 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6471 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
6473 FIXME("(%p): stub\n", pStubMsg);
6476 /***********************************************************************
6477 * NdrCorrelationFree [RPCRT4.@]
6479 * Frees any resources used while unmarshalling parameters that need
6480 * correlation validity checking.
6483 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6488 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
6490 FIXME("(%p): stub\n", pStubMsg);