4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * - Byte count pointers
24 * - transmit_as/represent as
25 * - Multi-dimensional arrays
26 * - Conversion functions (NdrConvert)
27 * - Checks for integer addition overflow in user marshall functions
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 /* Increment 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 /* Increment 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 /* Increment 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 * Unmarshall a base type.
2010 * Doesn't check that the buffer is long enough before copying, so the caller
2013 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
2014 unsigned char FormatChar )
2016 #define BASE_TYPE_UNMARSHALL(type) \
2017 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
2018 TRACE("pMemory: %p\n", pMemory); \
2019 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
2020 pStubMsg->Buffer += sizeof(type);
2028 BASE_TYPE_UNMARSHALL(UCHAR);
2029 TRACE("value: 0x%02x\n", *pMemory);
2034 BASE_TYPE_UNMARSHALL(USHORT);
2035 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
2039 case RPC_FC_ERROR_STATUS_T:
2041 BASE_TYPE_UNMARSHALL(ULONG);
2042 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
2045 BASE_TYPE_UNMARSHALL(float);
2046 TRACE("value: %f\n", *(float *)pMemory);
2049 BASE_TYPE_UNMARSHALL(double);
2050 TRACE("value: %f\n", *(double *)pMemory);
2053 BASE_TYPE_UNMARSHALL(ULONGLONG);
2054 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
2057 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
2058 TRACE("pMemory: %p\n", pMemory);
2059 /* 16-bits on the wire, but int in memory */
2060 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
2061 pStubMsg->Buffer += sizeof(USHORT);
2062 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
2067 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
2069 #undef BASE_TYPE_UNMARSHALL
2072 /***********************************************************************
2073 * NdrSimpleStructMarshall [RPCRT4.@]
2075 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2076 unsigned char *pMemory,
2077 PFORMAT_STRING pFormat)
2079 unsigned size = *(const WORD*)(pFormat+2);
2080 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2082 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
2084 pStubMsg->BufferMark = pStubMsg->Buffer;
2085 safe_copy_to_buffer(pStubMsg, pMemory, size);
2087 if (pFormat[0] != RPC_FC_STRUCT)
2088 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
2093 /***********************************************************************
2094 * NdrSimpleStructUnmarshall [RPCRT4.@]
2096 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2097 unsigned char **ppMemory,
2098 PFORMAT_STRING pFormat,
2099 unsigned char fMustAlloc)
2101 unsigned size = *(const WORD*)(pFormat+2);
2102 unsigned char *saved_buffer;
2103 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2105 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2108 *ppMemory = NdrAllocate(pStubMsg, size);
2111 if (!pStubMsg->IsClient && !*ppMemory)
2112 /* for servers, we just point straight into the RPC buffer */
2113 *ppMemory = pStubMsg->Buffer;
2116 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
2117 safe_buffer_increment(pStubMsg, size);
2118 if (pFormat[0] == RPC_FC_PSTRUCT)
2119 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
2121 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2122 if (*ppMemory != saved_buffer)
2123 memcpy(*ppMemory, saved_buffer, size);
2128 /***********************************************************************
2129 * NdrSimpleStructBufferSize [RPCRT4.@]
2131 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2132 unsigned char *pMemory,
2133 PFORMAT_STRING pFormat)
2135 unsigned size = *(const WORD*)(pFormat+2);
2136 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2138 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2140 safe_buffer_length_increment(pStubMsg, size);
2141 if (pFormat[0] != RPC_FC_STRUCT)
2142 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
2145 /***********************************************************************
2146 * NdrSimpleStructMemorySize [RPCRT4.@]
2148 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2149 PFORMAT_STRING pFormat)
2151 unsigned short size = *(const WORD *)(pFormat+2);
2153 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2155 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2156 pStubMsg->MemorySize += size;
2157 safe_buffer_increment(pStubMsg, size);
2159 if (pFormat[0] != RPC_FC_STRUCT)
2160 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
2161 return pStubMsg->MemorySize;
2164 /***********************************************************************
2165 * NdrSimpleStructFree [RPCRT4.@]
2167 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2168 unsigned char *pMemory,
2169 PFORMAT_STRING pFormat)
2171 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2172 if (pFormat[0] != RPC_FC_STRUCT)
2173 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
2177 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE *pStubMsg,
2178 PFORMAT_STRING pFormat)
2182 case RPC_FC_PSTRUCT:
2183 case RPC_FC_CSTRUCT:
2184 case RPC_FC_BOGUS_STRUCT:
2185 case RPC_FC_SMFARRAY:
2186 case RPC_FC_SMVARRAY:
2187 case RPC_FC_CSTRING:
2188 return *(const WORD*)&pFormat[2];
2189 case RPC_FC_USER_MARSHAL:
2190 return *(const WORD*)&pFormat[4];
2191 case RPC_FC_NON_ENCAPSULATED_UNION:
2193 if (pStubMsg->fHasNewCorrDesc)
2198 pFormat += *(const SHORT*)pFormat;
2199 return *(const SHORT*)pFormat;
2201 return sizeof(void *);
2202 case RPC_FC_WSTRING:
2203 return *(const WORD*)&pFormat[2] * 2;
2205 FIXME("unhandled embedded type %02x\n", *pFormat);
2211 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2212 PFORMAT_STRING pFormat)
2214 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2218 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2222 return m(pStubMsg, pFormat);
2226 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2227 unsigned char *pMemory,
2228 PFORMAT_STRING pFormat,
2229 PFORMAT_STRING pPointer)
2231 PFORMAT_STRING desc;
2235 while (*pFormat != RPC_FC_END) {
2241 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2242 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2248 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2249 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2253 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2254 if (32767 < *(DWORD*)pMemory)
2255 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2256 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2262 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2263 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2267 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2268 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2271 case RPC_FC_POINTER:
2273 unsigned char *saved_buffer;
2274 int pointer_buffer_mark_set = 0;
2275 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2276 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
2277 saved_buffer = pStubMsg->Buffer;
2278 if (pStubMsg->PointerBufferMark)
2280 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2281 pStubMsg->PointerBufferMark = NULL;
2282 pointer_buffer_mark_set = 1;
2285 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2286 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2287 if (pointer_buffer_mark_set)
2289 STD_OVERFLOW_CHECK(pStubMsg);
2290 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2291 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2293 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2294 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2295 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2297 pStubMsg->Buffer = saved_buffer + 4;
2303 case RPC_FC_ALIGNM4:
2304 ALIGN_POINTER(pMemory, 4);
2306 case RPC_FC_ALIGNM8:
2307 ALIGN_POINTER(pMemory, 8);
2309 case RPC_FC_STRUCTPAD1:
2310 case RPC_FC_STRUCTPAD2:
2311 case RPC_FC_STRUCTPAD3:
2312 case RPC_FC_STRUCTPAD4:
2313 case RPC_FC_STRUCTPAD5:
2314 case RPC_FC_STRUCTPAD6:
2315 case RPC_FC_STRUCTPAD7:
2316 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2318 case RPC_FC_EMBEDDED_COMPLEX:
2319 pMemory += pFormat[1];
2321 desc = pFormat + *(const SHORT*)pFormat;
2322 size = EmbeddedComplexSize(pStubMsg, desc);
2323 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
2324 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2327 /* for some reason interface pointers aren't generated as
2328 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2329 * they still need the derefencing treatment that pointers are
2331 if (*desc == RPC_FC_IP)
2332 m(pStubMsg, *(unsigned char **)pMemory, desc);
2334 m(pStubMsg, pMemory, desc);
2336 else FIXME("no marshaller for embedded type %02x\n", *desc);
2343 FIXME("unhandled format 0x%02x\n", *pFormat);
2351 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2352 unsigned char *pMemory,
2353 PFORMAT_STRING pFormat,
2354 PFORMAT_STRING pPointer)
2356 PFORMAT_STRING desc;
2360 while (*pFormat != RPC_FC_END) {
2366 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2367 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2373 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2374 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2378 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2379 *(DWORD*)pMemory &= 0xffff;
2380 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
2381 if (32767 < *(DWORD*)pMemory)
2382 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2388 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2389 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2393 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2394 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2397 case RPC_FC_POINTER:
2399 unsigned char *saved_buffer;
2400 int pointer_buffer_mark_set = 0;
2401 TRACE("pointer => %p\n", pMemory);
2402 ALIGN_POINTER(pStubMsg->Buffer, 4);
2403 saved_buffer = pStubMsg->Buffer;
2404 if (pStubMsg->PointerBufferMark)
2406 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2407 pStubMsg->PointerBufferMark = NULL;
2408 pointer_buffer_mark_set = 1;
2411 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2413 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, TRUE);
2414 if (pointer_buffer_mark_set)
2416 STD_OVERFLOW_CHECK(pStubMsg);
2417 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2418 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2420 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2421 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2422 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2424 pStubMsg->Buffer = saved_buffer + 4;
2430 case RPC_FC_ALIGNM4:
2431 ALIGN_POINTER_CLEAR(pMemory, 4);
2433 case RPC_FC_ALIGNM8:
2434 ALIGN_POINTER_CLEAR(pMemory, 8);
2436 case RPC_FC_STRUCTPAD1:
2437 case RPC_FC_STRUCTPAD2:
2438 case RPC_FC_STRUCTPAD3:
2439 case RPC_FC_STRUCTPAD4:
2440 case RPC_FC_STRUCTPAD5:
2441 case RPC_FC_STRUCTPAD6:
2442 case RPC_FC_STRUCTPAD7:
2443 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2444 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2446 case RPC_FC_EMBEDDED_COMPLEX:
2447 pMemory += pFormat[1];
2449 desc = pFormat + *(const SHORT*)pFormat;
2450 size = EmbeddedComplexSize(pStubMsg, desc);
2451 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2452 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2453 memset(pMemory, 0, size); /* just in case */
2456 /* for some reason interface pointers aren't generated as
2457 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2458 * they still need the derefencing treatment that pointers are
2460 if (*desc == RPC_FC_IP)
2461 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2463 m(pStubMsg, &pMemory, desc, FALSE);
2465 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2472 FIXME("unhandled format %d\n", *pFormat);
2480 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2481 unsigned char *pMemory,
2482 PFORMAT_STRING pFormat,
2483 PFORMAT_STRING pPointer)
2485 PFORMAT_STRING desc;
2489 while (*pFormat != RPC_FC_END) {
2495 safe_buffer_length_increment(pStubMsg, 1);
2501 safe_buffer_length_increment(pStubMsg, 2);
2505 safe_buffer_length_increment(pStubMsg, 2);
2511 safe_buffer_length_increment(pStubMsg, 4);
2515 safe_buffer_length_increment(pStubMsg, 8);
2518 case RPC_FC_POINTER:
2519 if (!pStubMsg->IgnoreEmbeddedPointers)
2521 int saved_buffer_length = pStubMsg->BufferLength;
2522 pStubMsg->BufferLength = pStubMsg->PointerLength;
2523 pStubMsg->PointerLength = 0;
2524 if(!pStubMsg->BufferLength)
2525 ERR("BufferLength == 0??\n");
2526 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2527 pStubMsg->PointerLength = pStubMsg->BufferLength;
2528 pStubMsg->BufferLength = saved_buffer_length;
2530 safe_buffer_length_increment(pStubMsg, 4);
2534 case RPC_FC_ALIGNM4:
2535 ALIGN_POINTER(pMemory, 4);
2537 case RPC_FC_ALIGNM8:
2538 ALIGN_POINTER(pMemory, 8);
2540 case RPC_FC_STRUCTPAD1:
2541 case RPC_FC_STRUCTPAD2:
2542 case RPC_FC_STRUCTPAD3:
2543 case RPC_FC_STRUCTPAD4:
2544 case RPC_FC_STRUCTPAD5:
2545 case RPC_FC_STRUCTPAD6:
2546 case RPC_FC_STRUCTPAD7:
2547 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2549 case RPC_FC_EMBEDDED_COMPLEX:
2550 pMemory += pFormat[1];
2552 desc = pFormat + *(const SHORT*)pFormat;
2553 size = EmbeddedComplexSize(pStubMsg, desc);
2554 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2557 /* for some reason interface pointers aren't generated as
2558 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2559 * they still need the derefencing treatment that pointers are
2561 if (*desc == RPC_FC_IP)
2562 m(pStubMsg, *(unsigned char **)pMemory, desc);
2564 m(pStubMsg, pMemory, desc);
2566 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2573 FIXME("unhandled format 0x%02x\n", *pFormat);
2581 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2582 unsigned char *pMemory,
2583 PFORMAT_STRING pFormat,
2584 PFORMAT_STRING pPointer)
2586 PFORMAT_STRING desc;
2590 while (*pFormat != RPC_FC_END) {
2612 case RPC_FC_POINTER:
2613 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
2617 case RPC_FC_ALIGNM4:
2618 ALIGN_POINTER(pMemory, 4);
2620 case RPC_FC_ALIGNM8:
2621 ALIGN_POINTER(pMemory, 8);
2623 case RPC_FC_STRUCTPAD1:
2624 case RPC_FC_STRUCTPAD2:
2625 case RPC_FC_STRUCTPAD3:
2626 case RPC_FC_STRUCTPAD4:
2627 case RPC_FC_STRUCTPAD5:
2628 case RPC_FC_STRUCTPAD6:
2629 case RPC_FC_STRUCTPAD7:
2630 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2632 case RPC_FC_EMBEDDED_COMPLEX:
2633 pMemory += pFormat[1];
2635 desc = pFormat + *(const SHORT*)pFormat;
2636 size = EmbeddedComplexSize(pStubMsg, desc);
2637 m = NdrFreer[*desc & NDR_TABLE_MASK];
2640 /* for some reason interface pointers aren't generated as
2641 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2642 * they still need the derefencing treatment that pointers are
2644 if (*desc == RPC_FC_IP)
2645 m(pStubMsg, *(unsigned char **)pMemory, desc);
2647 m(pStubMsg, pMemory, desc);
2655 FIXME("unhandled format 0x%02x\n", *pFormat);
2663 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2664 PFORMAT_STRING pFormat)
2666 PFORMAT_STRING desc;
2667 unsigned long size = 0;
2669 while (*pFormat != RPC_FC_END) {
2676 safe_buffer_increment(pStubMsg, 1);
2682 safe_buffer_increment(pStubMsg, 2);
2686 safe_buffer_increment(pStubMsg, 2);
2692 safe_buffer_increment(pStubMsg, 4);
2696 safe_buffer_increment(pStubMsg, 8);
2698 case RPC_FC_POINTER:
2700 safe_buffer_increment(pStubMsg, 4);
2701 if (!pStubMsg->IgnoreEmbeddedPointers)
2702 FIXME("embedded pointers\n");
2704 case RPC_FC_ALIGNM4:
2705 ALIGN_LENGTH(size, 4);
2706 ALIGN_POINTER(pStubMsg->Buffer, 4);
2708 case RPC_FC_ALIGNM8:
2709 ALIGN_LENGTH(size, 8);
2710 ALIGN_POINTER(pStubMsg->Buffer, 8);
2712 case RPC_FC_STRUCTPAD1:
2713 case RPC_FC_STRUCTPAD2:
2714 case RPC_FC_STRUCTPAD3:
2715 case RPC_FC_STRUCTPAD4:
2716 case RPC_FC_STRUCTPAD5:
2717 case RPC_FC_STRUCTPAD6:
2718 case RPC_FC_STRUCTPAD7:
2719 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2721 case RPC_FC_EMBEDDED_COMPLEX:
2724 desc = pFormat + *(const SHORT*)pFormat;
2725 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2731 FIXME("unhandled format 0x%02x\n", *pFormat);
2739 unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg,
2740 PFORMAT_STRING pFormat)
2742 PFORMAT_STRING desc;
2743 unsigned long size = 0;
2745 while (*pFormat != RPC_FC_END) {
2767 case RPC_FC_POINTER:
2768 size += sizeof(void *);
2770 case RPC_FC_ALIGNM4:
2771 ALIGN_LENGTH(size, 4);
2773 case RPC_FC_ALIGNM8:
2774 ALIGN_LENGTH(size, 8);
2776 case RPC_FC_STRUCTPAD1:
2777 case RPC_FC_STRUCTPAD2:
2778 case RPC_FC_STRUCTPAD3:
2779 case RPC_FC_STRUCTPAD4:
2780 case RPC_FC_STRUCTPAD5:
2781 case RPC_FC_STRUCTPAD6:
2782 case RPC_FC_STRUCTPAD7:
2783 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2785 case RPC_FC_EMBEDDED_COMPLEX:
2788 desc = pFormat + *(const SHORT*)pFormat;
2789 size += EmbeddedComplexSize(pStubMsg, desc);
2795 FIXME("unhandled format 0x%02x\n", *pFormat);
2803 /***********************************************************************
2804 * NdrComplexStructMarshall [RPCRT4.@]
2806 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2807 unsigned char *pMemory,
2808 PFORMAT_STRING pFormat)
2810 PFORMAT_STRING conf_array = NULL;
2811 PFORMAT_STRING pointer_desc = NULL;
2812 unsigned char *OldMemory = pStubMsg->Memory;
2813 int pointer_buffer_mark_set = 0;
2815 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2817 if (!pStubMsg->PointerBufferMark)
2819 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2820 /* save buffer length */
2821 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2823 /* get the buffer pointer after complex array data, but before
2825 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2826 pStubMsg->IgnoreEmbeddedPointers = 1;
2827 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2828 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2830 /* save it for use by embedded pointer code later */
2831 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2832 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
2833 pointer_buffer_mark_set = 1;
2835 /* restore the original buffer length */
2836 pStubMsg->BufferLength = saved_buffer_length;
2839 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
2842 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2844 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2847 pStubMsg->Memory = pMemory;
2849 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2852 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2854 pStubMsg->Memory = OldMemory;
2856 if (pointer_buffer_mark_set)
2858 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2859 pStubMsg->PointerBufferMark = NULL;
2862 STD_OVERFLOW_CHECK(pStubMsg);
2867 /***********************************************************************
2868 * NdrComplexStructUnmarshall [RPCRT4.@]
2870 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2871 unsigned char **ppMemory,
2872 PFORMAT_STRING pFormat,
2873 unsigned char fMustAlloc)
2875 unsigned size = *(const WORD*)(pFormat+2);
2876 PFORMAT_STRING conf_array = NULL;
2877 PFORMAT_STRING pointer_desc = NULL;
2878 unsigned char *pMemory;
2879 int pointer_buffer_mark_set = 0;
2881 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2883 if (!pStubMsg->PointerBufferMark)
2885 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2886 /* save buffer pointer */
2887 unsigned char *saved_buffer = pStubMsg->Buffer;
2889 /* get the buffer pointer after complex array data, but before
2891 pStubMsg->IgnoreEmbeddedPointers = 1;
2892 NdrComplexStructMemorySize(pStubMsg, pFormat);
2893 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2895 /* save it for use by embedded pointer code later */
2896 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2897 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
2898 pointer_buffer_mark_set = 1;
2900 /* restore the original buffer */
2901 pStubMsg->Buffer = saved_buffer;
2904 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2906 if (fMustAlloc || !*ppMemory)
2908 *ppMemory = NdrAllocate(pStubMsg, size);
2909 memset(*ppMemory, 0, size);
2913 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2915 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2918 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2921 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2923 if (pointer_buffer_mark_set)
2925 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2926 pStubMsg->PointerBufferMark = NULL;
2932 /***********************************************************************
2933 * NdrComplexStructBufferSize [RPCRT4.@]
2935 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2936 unsigned char *pMemory,
2937 PFORMAT_STRING pFormat)
2939 PFORMAT_STRING conf_array = NULL;
2940 PFORMAT_STRING pointer_desc = NULL;
2941 unsigned char *OldMemory = pStubMsg->Memory;
2942 int pointer_length_set = 0;
2944 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2946 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2948 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2950 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2951 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2953 /* get the buffer length after complex struct data, but before
2955 pStubMsg->IgnoreEmbeddedPointers = 1;
2956 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2957 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2959 /* save it for use by embedded pointer code later */
2960 pStubMsg->PointerLength = pStubMsg->BufferLength;
2961 pointer_length_set = 1;
2962 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
2964 /* restore the original buffer length */
2965 pStubMsg->BufferLength = saved_buffer_length;
2969 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2971 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2974 pStubMsg->Memory = pMemory;
2976 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2979 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2981 pStubMsg->Memory = OldMemory;
2983 if(pointer_length_set)
2985 pStubMsg->BufferLength = pStubMsg->PointerLength;
2986 pStubMsg->PointerLength = 0;
2991 /***********************************************************************
2992 * NdrComplexStructMemorySize [RPCRT4.@]
2994 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2995 PFORMAT_STRING pFormat)
2997 unsigned size = *(const WORD*)(pFormat+2);
2998 PFORMAT_STRING conf_array = NULL;
2999 PFORMAT_STRING pointer_desc = NULL;
3001 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3003 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3006 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
3008 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3011 ComplexStructMemorySize(pStubMsg, pFormat);
3014 NdrConformantArrayMemorySize(pStubMsg, conf_array);
3019 /***********************************************************************
3020 * NdrComplexStructFree [RPCRT4.@]
3022 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3023 unsigned char *pMemory,
3024 PFORMAT_STRING pFormat)
3026 PFORMAT_STRING conf_array = NULL;
3027 PFORMAT_STRING pointer_desc = NULL;
3028 unsigned char *OldMemory = pStubMsg->Memory;
3030 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3033 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
3035 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3038 pStubMsg->Memory = pMemory;
3040 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3043 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
3045 pStubMsg->Memory = OldMemory;
3048 /***********************************************************************
3049 * NdrConformantArrayMarshall [RPCRT4.@]
3051 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3052 unsigned char *pMemory,
3053 PFORMAT_STRING pFormat)
3055 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
3056 unsigned char alignment = pFormat[1] + 1;
3058 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3059 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3061 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3063 WriteConformance(pStubMsg);
3065 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3067 size = safe_multiply(esize, pStubMsg->MaxCount);
3068 pStubMsg->BufferMark = pStubMsg->Buffer;
3069 safe_copy_to_buffer(pStubMsg, pMemory, size);
3071 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3076 /***********************************************************************
3077 * NdrConformantArrayUnmarshall [RPCRT4.@]
3079 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3080 unsigned char **ppMemory,
3081 PFORMAT_STRING pFormat,
3082 unsigned char fMustAlloc)
3084 DWORD size, esize = *(const WORD*)(pFormat+2);
3085 unsigned char alignment = pFormat[1] + 1;
3086 unsigned char *saved_buffer;
3088 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3089 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3091 pFormat = ReadConformance(pStubMsg, pFormat+4);
3093 size = safe_multiply(esize, pStubMsg->MaxCount);
3094 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3097 *ppMemory = NdrAllocate(pStubMsg, size);
3100 if (!pStubMsg->IsClient && !*ppMemory)
3101 /* for servers, we just point straight into the RPC buffer */
3102 *ppMemory = pStubMsg->Buffer;
3105 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3106 safe_buffer_increment(pStubMsg, size);
3107 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3109 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
3110 if (*ppMemory != saved_buffer)
3111 memcpy(*ppMemory, saved_buffer, size);
3116 /***********************************************************************
3117 * NdrConformantArrayBufferSize [RPCRT4.@]
3119 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3120 unsigned char *pMemory,
3121 PFORMAT_STRING pFormat)
3123 DWORD size, esize = *(const WORD*)(pFormat+2);
3124 unsigned char alignment = pFormat[1] + 1;
3126 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3127 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3129 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3131 SizeConformance(pStubMsg);
3133 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3135 size = safe_multiply(esize, pStubMsg->MaxCount);
3136 /* conformance value plus array */
3137 safe_buffer_length_increment(pStubMsg, size);
3139 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3142 /***********************************************************************
3143 * NdrConformantArrayMemorySize [RPCRT4.@]
3145 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3146 PFORMAT_STRING pFormat)
3148 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
3149 unsigned char alignment = pFormat[1] + 1;
3151 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3152 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3154 pFormat = ReadConformance(pStubMsg, pFormat+4);
3155 size = safe_multiply(esize, pStubMsg->MaxCount);
3156 pStubMsg->MemorySize += size;
3158 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3159 pStubMsg->BufferMark = pStubMsg->Buffer;
3160 safe_buffer_increment(pStubMsg, size);
3162 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3164 return pStubMsg->MemorySize;
3167 /***********************************************************************
3168 * NdrConformantArrayFree [RPCRT4.@]
3170 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3171 unsigned char *pMemory,
3172 PFORMAT_STRING pFormat)
3174 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3175 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3177 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3179 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3183 /***********************************************************************
3184 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3186 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
3187 unsigned char* pMemory,
3188 PFORMAT_STRING pFormat )
3191 unsigned char alignment = pFormat[1] + 1;
3192 DWORD esize = *(const WORD*)(pFormat+2);
3194 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3196 if (pFormat[0] != RPC_FC_CVARRAY)
3198 ERR("invalid format type %x\n", pFormat[0]);
3199 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3203 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3204 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3206 WriteConformance(pStubMsg);
3207 WriteVariance(pStubMsg);
3209 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3211 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3213 pStubMsg->BufferMark = pStubMsg->Buffer;
3214 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
3216 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3222 /***********************************************************************
3223 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3225 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
3226 unsigned char** ppMemory,
3227 PFORMAT_STRING pFormat,
3228 unsigned char fMustAlloc )
3230 ULONG bufsize, memsize;
3231 unsigned char alignment = pFormat[1] + 1;
3232 DWORD esize = *(const WORD*)(pFormat+2);
3233 unsigned char *saved_buffer;
3236 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3238 if (pFormat[0] != RPC_FC_CVARRAY)
3240 ERR("invalid format type %x\n", pFormat[0]);
3241 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3245 pFormat = ReadConformance(pStubMsg, pFormat+4);
3246 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3248 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3250 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3251 memsize = safe_multiply(esize, pStubMsg->MaxCount);
3252 offset = pStubMsg->Offset;
3254 if (!*ppMemory || fMustAlloc)
3255 *ppMemory = NdrAllocate(pStubMsg, memsize);
3256 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3257 safe_buffer_increment(pStubMsg, bufsize);
3259 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3261 memcpy(*ppMemory + offset, saved_buffer, bufsize);
3267 /***********************************************************************
3268 * NdrConformantVaryingArrayFree [RPCRT4.@]
3270 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
3271 unsigned char* pMemory,
3272 PFORMAT_STRING pFormat )
3274 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3276 if (pFormat[0] != RPC_FC_CVARRAY)
3278 ERR("invalid format type %x\n", pFormat[0]);
3279 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3283 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3284 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3286 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3290 /***********************************************************************
3291 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3293 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
3294 unsigned char* pMemory, PFORMAT_STRING pFormat )
3296 unsigned char alignment = pFormat[1] + 1;
3297 DWORD esize = *(const WORD*)(pFormat+2);
3299 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3301 if (pFormat[0] != RPC_FC_CVARRAY)
3303 ERR("invalid format type %x\n", pFormat[0]);
3304 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3309 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3310 /* compute length */
3311 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3313 SizeConformance(pStubMsg);
3314 SizeVariance(pStubMsg);
3316 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3318 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
3320 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3324 /***********************************************************************
3325 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3327 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
3328 PFORMAT_STRING pFormat )
3330 ULONG bufsize, memsize;
3331 unsigned char alignment = pFormat[1] + 1;
3332 DWORD esize = *(const WORD*)(pFormat+2);
3334 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3336 if (pFormat[0] != RPC_FC_CVARRAY)
3338 ERR("invalid format type %x\n", pFormat[0]);
3339 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3340 return pStubMsg->MemorySize;
3343 pFormat = ReadConformance(pStubMsg, pFormat+4);
3344 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3346 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3348 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3349 memsize = safe_multiply(esize, pStubMsg->MaxCount);
3351 safe_buffer_increment(pStubMsg, bufsize);
3352 pStubMsg->MemorySize += memsize;
3354 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3356 return pStubMsg->MemorySize;
3360 /***********************************************************************
3361 * NdrComplexArrayMarshall [RPCRT4.@]
3363 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3364 unsigned char *pMemory,
3365 PFORMAT_STRING pFormat)
3367 ULONG i, count, def;
3368 BOOL variance_present;
3369 unsigned char alignment;
3370 int pointer_buffer_mark_set = 0;
3372 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3374 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3376 ERR("invalid format type %x\n", pFormat[0]);
3377 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3381 alignment = pFormat[1] + 1;
3383 if (!pStubMsg->PointerBufferMark)
3385 /* save buffer fields that may be changed by buffer sizer functions
3386 * and that may be needed later on */
3387 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3388 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3389 unsigned long saved_max_count = pStubMsg->MaxCount;
3390 unsigned long saved_offset = pStubMsg->Offset;
3391 unsigned long saved_actual_count = pStubMsg->ActualCount;
3393 /* get the buffer pointer after complex array data, but before
3395 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3396 pStubMsg->IgnoreEmbeddedPointers = 1;
3397 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3398 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3400 /* save it for use by embedded pointer code later */
3401 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3402 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
3403 pointer_buffer_mark_set = 1;
3405 /* restore fields */
3406 pStubMsg->ActualCount = saved_actual_count;
3407 pStubMsg->Offset = saved_offset;
3408 pStubMsg->MaxCount = saved_max_count;
3409 pStubMsg->BufferLength = saved_buffer_length;
3412 def = *(const WORD*)&pFormat[2];
3415 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3416 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3418 variance_present = IsConformanceOrVariancePresent(pFormat);
3419 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3420 TRACE("variance = %d\n", pStubMsg->ActualCount);
3422 WriteConformance(pStubMsg);
3423 if (variance_present)
3424 WriteVariance(pStubMsg);
3426 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3428 count = pStubMsg->ActualCount;
3429 for (i = 0; i < count; i++)
3430 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3432 STD_OVERFLOW_CHECK(pStubMsg);
3434 if (pointer_buffer_mark_set)
3436 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3437 pStubMsg->PointerBufferMark = NULL;
3443 /***********************************************************************
3444 * NdrComplexArrayUnmarshall [RPCRT4.@]
3446 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3447 unsigned char **ppMemory,
3448 PFORMAT_STRING pFormat,
3449 unsigned char fMustAlloc)
3451 ULONG i, count, size;
3452 unsigned char alignment;
3453 unsigned char *pMemory;
3454 unsigned char *saved_buffer;
3455 int pointer_buffer_mark_set = 0;
3456 int saved_ignore_embedded;
3458 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3460 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3462 ERR("invalid format type %x\n", pFormat[0]);
3463 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3467 alignment = pFormat[1] + 1;
3469 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3470 /* save buffer pointer */
3471 saved_buffer = pStubMsg->Buffer;
3472 /* get the buffer pointer after complex array data, but before
3474 pStubMsg->IgnoreEmbeddedPointers = 1;
3475 pStubMsg->MemorySize = 0;
3476 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3477 size = pStubMsg->MemorySize;
3478 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3480 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
3481 if (!pStubMsg->PointerBufferMark)
3483 /* save it for use by embedded pointer code later */
3484 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3485 pointer_buffer_mark_set = 1;
3487 /* restore the original buffer */
3488 pStubMsg->Buffer = saved_buffer;
3492 pFormat = ReadConformance(pStubMsg, pFormat);
3493 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3495 if (fMustAlloc || !*ppMemory)
3497 *ppMemory = NdrAllocate(pStubMsg, size);
3498 memset(*ppMemory, 0, size);
3501 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3503 pMemory = *ppMemory;
3504 count = pStubMsg->ActualCount;
3505 for (i = 0; i < count; i++)
3506 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
3508 if (pointer_buffer_mark_set)
3510 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3511 pStubMsg->PointerBufferMark = NULL;
3517 /***********************************************************************
3518 * NdrComplexArrayBufferSize [RPCRT4.@]
3520 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3521 unsigned char *pMemory,
3522 PFORMAT_STRING pFormat)
3524 ULONG i, count, def;
3525 unsigned char alignment;
3526 BOOL variance_present;
3527 int pointer_length_set = 0;
3529 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3531 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3533 ERR("invalid format type %x\n", pFormat[0]);
3534 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3538 alignment = pFormat[1] + 1;
3540 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3542 /* save buffer fields that may be changed by buffer sizer functions
3543 * and that may be needed later on */
3544 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3545 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3546 unsigned long saved_max_count = pStubMsg->MaxCount;
3547 unsigned long saved_offset = pStubMsg->Offset;
3548 unsigned long saved_actual_count = pStubMsg->ActualCount;
3550 /* get the buffer pointer after complex array data, but before
3552 pStubMsg->IgnoreEmbeddedPointers = 1;
3553 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3554 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3556 /* save it for use by embedded pointer code later */
3557 pStubMsg->PointerLength = pStubMsg->BufferLength;
3558 pointer_length_set = 1;
3560 /* restore fields */
3561 pStubMsg->ActualCount = saved_actual_count;
3562 pStubMsg->Offset = saved_offset;
3563 pStubMsg->MaxCount = saved_max_count;
3564 pStubMsg->BufferLength = saved_buffer_length;
3566 def = *(const WORD*)&pFormat[2];
3569 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3570 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3571 SizeConformance(pStubMsg);
3573 variance_present = IsConformanceOrVariancePresent(pFormat);
3574 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3575 TRACE("variance = %d\n", pStubMsg->ActualCount);
3577 if (variance_present)
3578 SizeVariance(pStubMsg);
3580 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3582 count = pStubMsg->ActualCount;
3583 for (i = 0; i < count; i++)
3584 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
3586 if(pointer_length_set)
3588 pStubMsg->BufferLength = pStubMsg->PointerLength;
3589 pStubMsg->PointerLength = 0;
3593 /***********************************************************************
3594 * NdrComplexArrayMemorySize [RPCRT4.@]
3596 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3597 PFORMAT_STRING pFormat)
3599 ULONG i, count, esize, SavedMemorySize, MemorySize;
3600 unsigned char alignment;
3602 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3604 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3606 ERR("invalid format type %x\n", pFormat[0]);
3607 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3611 alignment = pFormat[1] + 1;
3615 pFormat = ReadConformance(pStubMsg, pFormat);
3616 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3618 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3620 SavedMemorySize = pStubMsg->MemorySize;
3622 esize = ComplexStructSize(pStubMsg, pFormat);
3624 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
3626 count = pStubMsg->ActualCount;
3627 for (i = 0; i < count; i++)
3628 ComplexStructMemorySize(pStubMsg, pFormat);
3630 pStubMsg->MemorySize = SavedMemorySize;
3632 pStubMsg->MemorySize += MemorySize;
3636 /***********************************************************************
3637 * NdrComplexArrayFree [RPCRT4.@]
3639 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3640 unsigned char *pMemory,
3641 PFORMAT_STRING pFormat)
3643 ULONG i, count, def;
3645 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3647 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3649 ERR("invalid format type %x\n", pFormat[0]);
3650 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3654 def = *(const WORD*)&pFormat[2];
3657 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3658 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3660 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3661 TRACE("variance = %d\n", pStubMsg->ActualCount);
3663 count = pStubMsg->ActualCount;
3664 for (i = 0; i < count; i++)
3665 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
3668 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
3669 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
3670 USER_MARSHAL_CB *umcb)
3672 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
3673 pStubMsg->RpcMsg->DataRepresentation);
3674 umcb->pStubMsg = pStubMsg;
3675 umcb->pReserve = NULL;
3676 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
3677 umcb->CBType = cbtype;
3678 umcb->pFormat = pFormat;
3679 umcb->pTypeFormat = NULL /* FIXME */;
3682 #define USER_MARSHAL_PTR_PREFIX \
3683 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3684 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3686 /***********************************************************************
3687 * NdrUserMarshalMarshall [RPCRT4.@]
3689 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3690 unsigned char *pMemory,
3691 PFORMAT_STRING pFormat)
3693 unsigned flags = pFormat[1];
3694 unsigned index = *(const WORD*)&pFormat[2];
3695 unsigned char *saved_buffer = NULL;
3696 USER_MARSHAL_CB umcb;
3698 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3699 TRACE("index=%d\n", index);
3701 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
3703 if (flags & USER_MARSHAL_POINTER)
3705 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
3706 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
3707 pStubMsg->Buffer += 4;
3708 if (pStubMsg->PointerBufferMark)
3710 saved_buffer = pStubMsg->Buffer;
3711 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3712 pStubMsg->PointerBufferMark = NULL;
3714 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
3717 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
3720 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
3721 &umcb.Flags, pStubMsg->Buffer, pMemory);
3725 STD_OVERFLOW_CHECK(pStubMsg);
3726 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3727 pStubMsg->Buffer = saved_buffer;
3730 STD_OVERFLOW_CHECK(pStubMsg);
3735 /***********************************************************************
3736 * NdrUserMarshalUnmarshall [RPCRT4.@]
3738 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3739 unsigned char **ppMemory,
3740 PFORMAT_STRING pFormat,
3741 unsigned char fMustAlloc)
3743 unsigned flags = pFormat[1];
3744 unsigned index = *(const WORD*)&pFormat[2];
3745 DWORD memsize = *(const WORD*)&pFormat[4];
3746 unsigned char *saved_buffer = NULL;
3747 USER_MARSHAL_CB umcb;
3749 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3750 TRACE("index=%d\n", index);
3752 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
3754 if (flags & USER_MARSHAL_POINTER)
3756 ALIGN_POINTER(pStubMsg->Buffer, 4);
3757 /* skip pointer prefix */
3758 pStubMsg->Buffer += 4;
3759 if (pStubMsg->PointerBufferMark)
3761 saved_buffer = pStubMsg->Buffer;
3762 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3763 pStubMsg->PointerBufferMark = NULL;
3765 ALIGN_POINTER(pStubMsg->Buffer, 8);
3768 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3770 if (fMustAlloc || !*ppMemory)
3771 *ppMemory = NdrAllocate(pStubMsg, memsize);
3774 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
3775 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
3779 STD_OVERFLOW_CHECK(pStubMsg);
3780 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3781 pStubMsg->Buffer = saved_buffer;
3787 /***********************************************************************
3788 * NdrUserMarshalBufferSize [RPCRT4.@]
3790 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3791 unsigned char *pMemory,
3792 PFORMAT_STRING pFormat)
3794 unsigned flags = pFormat[1];
3795 unsigned index = *(const WORD*)&pFormat[2];
3796 DWORD bufsize = *(const WORD*)&pFormat[6];
3797 USER_MARSHAL_CB umcb;
3798 unsigned long saved_buffer_length = 0;
3800 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3801 TRACE("index=%d\n", index);
3803 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
3805 if (flags & USER_MARSHAL_POINTER)
3807 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3808 /* skip pointer prefix */
3809 safe_buffer_length_increment(pStubMsg, 4);
3810 if (pStubMsg->IgnoreEmbeddedPointers)
3812 if (pStubMsg->PointerLength)
3814 saved_buffer_length = pStubMsg->BufferLength;
3815 pStubMsg->BufferLength = pStubMsg->PointerLength;
3816 pStubMsg->PointerLength = 0;
3818 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
3821 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
3824 TRACE("size=%d\n", bufsize);
3825 safe_buffer_length_increment(pStubMsg, bufsize);
3828 pStubMsg->BufferLength =
3829 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
3830 &umcb.Flags, pStubMsg->BufferLength, pMemory);
3832 if (saved_buffer_length)
3834 pStubMsg->PointerLength = pStubMsg->BufferLength;
3835 pStubMsg->BufferLength = saved_buffer_length;
3840 /***********************************************************************
3841 * NdrUserMarshalMemorySize [RPCRT4.@]
3843 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3844 PFORMAT_STRING pFormat)
3846 unsigned flags = pFormat[1];
3847 unsigned index = *(const WORD*)&pFormat[2];
3848 DWORD memsize = *(const WORD*)&pFormat[4];
3849 DWORD bufsize = *(const WORD*)&pFormat[6];
3851 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3852 TRACE("index=%d\n", index);
3854 pStubMsg->MemorySize += memsize;
3856 if (flags & USER_MARSHAL_POINTER)
3858 ALIGN_POINTER(pStubMsg->Buffer, 4);
3859 /* skip pointer prefix */
3860 pStubMsg->Buffer += 4;
3861 if (pStubMsg->IgnoreEmbeddedPointers)
3862 return pStubMsg->MemorySize;
3863 ALIGN_POINTER(pStubMsg->Buffer, 8);
3866 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3869 FIXME("not implemented for varying buffer size\n");
3871 pStubMsg->Buffer += bufsize;
3873 return pStubMsg->MemorySize;
3876 /***********************************************************************
3877 * NdrUserMarshalFree [RPCRT4.@]
3879 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
3880 unsigned char *pMemory,
3881 PFORMAT_STRING pFormat)
3883 /* unsigned flags = pFormat[1]; */
3884 unsigned index = *(const WORD*)&pFormat[2];
3885 USER_MARSHAL_CB umcb;
3887 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3888 TRACE("index=%d\n", index);
3890 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
3892 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
3893 &umcb.Flags, pMemory);
3896 /***********************************************************************
3897 * NdrClearOutParameters [RPCRT4.@]
3899 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
3900 PFORMAT_STRING pFormat,
3903 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
3906 /***********************************************************************
3907 * NdrConvert [RPCRT4.@]
3909 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
3911 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
3912 /* FIXME: since this stub doesn't do any converting, the proper behavior
3913 is to raise an exception */
3916 /***********************************************************************
3917 * NdrConvert2 [RPCRT4.@]
3919 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
3921 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3922 pStubMsg, pFormat, NumberParams);
3923 /* FIXME: since this stub doesn't do any converting, the proper behavior
3924 is to raise an exception */
3927 #include "pshpack1.h"
3928 typedef struct _NDR_CSTRUCT_FORMAT
3931 unsigned char alignment;
3932 unsigned short memory_size;
3933 short offset_to_array_description;
3934 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
3935 #include "poppack.h"
3937 /***********************************************************************
3938 * NdrConformantStructMarshall [RPCRT4.@]
3940 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3941 unsigned char *pMemory,
3942 PFORMAT_STRING pFormat)
3944 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3945 PFORMAT_STRING pCArrayFormat;
3946 ULONG esize, bufsize;
3948 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3950 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3951 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3953 ERR("invalid format type %x\n", pCStructFormat->type);
3954 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3958 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3959 pCStructFormat->offset_to_array_description;
3960 if (*pCArrayFormat != RPC_FC_CARRAY)
3962 ERR("invalid array format type %x\n", pCStructFormat->type);
3963 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3966 esize = *(const WORD*)(pCArrayFormat+2);
3968 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3969 pCArrayFormat + 4, 0);
3971 WriteConformance(pStubMsg);
3973 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3975 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3977 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3978 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3980 ERR("integer overflow of memory_size %u with bufsize %u\n",
3981 pCStructFormat->memory_size, bufsize);
3982 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3984 /* copy constant sized part of struct */
3985 pStubMsg->BufferMark = pStubMsg->Buffer;
3986 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
3988 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3989 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3994 /***********************************************************************
3995 * NdrConformantStructUnmarshall [RPCRT4.@]
3997 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3998 unsigned char **ppMemory,
3999 PFORMAT_STRING pFormat,
4000 unsigned char fMustAlloc)
4002 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4003 PFORMAT_STRING pCArrayFormat;
4004 ULONG esize, bufsize;
4005 unsigned char *saved_buffer;
4007 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4009 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4010 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4012 ERR("invalid format type %x\n", pCStructFormat->type);
4013 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4016 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4017 pCStructFormat->offset_to_array_description;
4018 if (*pCArrayFormat != RPC_FC_CARRAY)
4020 ERR("invalid array format type %x\n", pCStructFormat->type);
4021 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4024 esize = *(const WORD*)(pCArrayFormat+2);
4026 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4028 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4030 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4032 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4033 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4035 ERR("integer overflow of memory_size %u with bufsize %u\n",
4036 pCStructFormat->memory_size, bufsize);
4037 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4042 SIZE_T size = pCStructFormat->memory_size + bufsize;
4043 *ppMemory = NdrAllocate(pStubMsg, size);
4047 if (!pStubMsg->IsClient && !*ppMemory)
4048 /* for servers, we just point straight into the RPC buffer */
4049 *ppMemory = pStubMsg->Buffer;
4052 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4053 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4054 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4055 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4057 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4058 if (*ppMemory != saved_buffer)
4059 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4064 /***********************************************************************
4065 * NdrConformantStructBufferSize [RPCRT4.@]
4067 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4068 unsigned char *pMemory,
4069 PFORMAT_STRING pFormat)
4071 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4072 PFORMAT_STRING pCArrayFormat;
4075 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4077 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4078 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4080 ERR("invalid format type %x\n", pCStructFormat->type);
4081 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4084 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4085 pCStructFormat->offset_to_array_description;
4086 if (*pCArrayFormat != RPC_FC_CARRAY)
4088 ERR("invalid array format type %x\n", pCStructFormat->type);
4089 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4092 esize = *(const WORD*)(pCArrayFormat+2);
4094 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4095 SizeConformance(pStubMsg);
4097 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4099 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4101 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4102 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4104 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4105 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4108 /***********************************************************************
4109 * NdrConformantStructMemorySize [RPCRT4.@]
4111 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4112 PFORMAT_STRING pFormat)
4118 /***********************************************************************
4119 * NdrConformantStructFree [RPCRT4.@]
4121 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4122 unsigned char *pMemory,
4123 PFORMAT_STRING pFormat)
4125 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4126 PFORMAT_STRING pCArrayFormat;
4129 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4131 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4132 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4134 ERR("invalid format type %x\n", pCStructFormat->type);
4135 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4139 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4140 pCStructFormat->offset_to_array_description;
4141 if (*pCArrayFormat != RPC_FC_CARRAY)
4143 ERR("invalid array format type %x\n", pCStructFormat->type);
4144 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4147 esize = *(const WORD*)(pCArrayFormat+2);
4149 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4150 pCArrayFormat + 4, 0);
4152 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4154 /* copy constant sized part of struct */
4155 pStubMsg->BufferMark = pStubMsg->Buffer;
4157 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4158 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4161 /***********************************************************************
4162 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4164 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4165 unsigned char *pMemory,
4166 PFORMAT_STRING pFormat)
4168 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4169 PFORMAT_STRING pCVArrayFormat;
4170 ULONG esize, bufsize;
4172 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4174 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4175 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4177 ERR("invalid format type %x\n", pCVStructFormat->type);
4178 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4182 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4183 pCVStructFormat->offset_to_array_description;
4184 switch (*pCVArrayFormat)
4186 case RPC_FC_CVARRAY:
4187 esize = *(const WORD*)(pCVArrayFormat+2);
4189 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4190 pCVArrayFormat + 4, 0);
4191 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4194 case RPC_FC_C_CSTRING:
4195 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4196 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4197 esize = sizeof(char);
4198 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4199 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4200 pCVArrayFormat + 2, 0);
4202 pStubMsg->MaxCount = pStubMsg->ActualCount;
4204 case RPC_FC_C_WSTRING:
4205 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4206 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4207 esize = sizeof(WCHAR);
4208 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4209 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4210 pCVArrayFormat + 2, 0);
4212 pStubMsg->MaxCount = pStubMsg->ActualCount;
4215 ERR("invalid array format type %x\n", *pCVArrayFormat);
4216 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4220 WriteConformance(pStubMsg);
4222 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4224 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4226 /* write constant sized part */
4227 pStubMsg->BufferMark = pStubMsg->Buffer;
4228 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4230 WriteVariance(pStubMsg);
4232 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4234 /* write array part */
4235 safe_copy_to_buffer(pStubMsg, pMemory + pCVStructFormat->memory_size, bufsize);
4237 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4242 /***********************************************************************
4243 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4245 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4246 unsigned char **ppMemory,
4247 PFORMAT_STRING pFormat,
4248 unsigned char fMustAlloc)
4250 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4251 PFORMAT_STRING pCVArrayFormat;
4252 ULONG esize, bufsize;
4253 unsigned char cvarray_type;
4255 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4257 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4258 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4260 ERR("invalid format type %x\n", pCVStructFormat->type);
4261 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4265 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4266 pCVStructFormat->offset_to_array_description;
4267 cvarray_type = *pCVArrayFormat;
4268 switch (cvarray_type)
4270 case RPC_FC_CVARRAY:
4271 esize = *(const WORD*)(pCVArrayFormat+2);
4272 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4274 case RPC_FC_C_CSTRING:
4275 esize = sizeof(char);
4276 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4277 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4279 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4281 case RPC_FC_C_WSTRING:
4282 esize = sizeof(WCHAR);
4283 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4284 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4286 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4289 ERR("invalid array format type %x\n", *pCVArrayFormat);
4290 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4294 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4296 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4298 /* work out how much memory to allocate if we need to do so */
4299 if (!*ppMemory || fMustAlloc)
4301 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4302 *ppMemory = NdrAllocate(pStubMsg, size);
4305 /* copy the constant data */
4306 pStubMsg->BufferMark = pStubMsg->Buffer;
4307 safe_copy_from_buffer(pStubMsg, *ppMemory, pCVStructFormat->memory_size);
4309 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4311 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4313 if ((cvarray_type == RPC_FC_C_CSTRING) ||
4314 (cvarray_type == RPC_FC_C_WSTRING))
4317 /* strings must always have null terminating bytes */
4318 if (bufsize < esize)
4320 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
4321 RpcRaiseException(RPC_S_INVALID_BOUND);
4324 for (i = bufsize - esize; i < bufsize; i++)
4325 if (pStubMsg->Buffer[i] != 0)
4327 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
4328 i, pStubMsg->Buffer[i]);
4329 RpcRaiseException(RPC_S_INVALID_BOUND);
4334 /* copy the array data */
4335 safe_copy_from_buffer(pStubMsg, *ppMemory + pCVStructFormat->memory_size, bufsize);
4337 if (cvarray_type == RPC_FC_C_CSTRING)
4338 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
4339 else if (cvarray_type == RPC_FC_C_WSTRING)
4340 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
4342 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
4347 /***********************************************************************
4348 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4350 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4351 unsigned char *pMemory,
4352 PFORMAT_STRING pFormat)
4354 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4355 PFORMAT_STRING pCVArrayFormat;
4358 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4360 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4361 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4363 ERR("invalid format type %x\n", pCVStructFormat->type);
4364 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4368 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4369 pCVStructFormat->offset_to_array_description;
4370 switch (*pCVArrayFormat)
4372 case RPC_FC_CVARRAY:
4373 esize = *(const WORD*)(pCVArrayFormat+2);
4375 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4376 pCVArrayFormat + 4, 0);
4377 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4380 case RPC_FC_C_CSTRING:
4381 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4382 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4383 esize = sizeof(char);
4384 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4385 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4386 pCVArrayFormat + 2, 0);
4388 pStubMsg->MaxCount = pStubMsg->ActualCount;
4390 case RPC_FC_C_WSTRING:
4391 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4392 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4393 esize = sizeof(WCHAR);
4394 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4395 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4396 pCVArrayFormat + 2, 0);
4398 pStubMsg->MaxCount = pStubMsg->ActualCount;
4401 ERR("invalid array format type %x\n", *pCVArrayFormat);
4402 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4406 SizeConformance(pStubMsg);
4408 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4410 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4412 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4413 SizeVariance(pStubMsg);
4414 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4416 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4419 /***********************************************************************
4420 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4422 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4423 PFORMAT_STRING pFormat)
4425 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4426 PFORMAT_STRING pCVArrayFormat;
4428 unsigned char cvarray_type;
4430 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4432 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4433 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4435 ERR("invalid format type %x\n", pCVStructFormat->type);
4436 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4440 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4441 pCVStructFormat->offset_to_array_description;
4442 cvarray_type = *pCVArrayFormat;
4443 switch (cvarray_type)
4445 case RPC_FC_CVARRAY:
4446 esize = *(const WORD*)(pCVArrayFormat+2);
4447 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4449 case RPC_FC_C_CSTRING:
4450 esize = sizeof(char);
4451 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4452 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4454 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4456 case RPC_FC_C_WSTRING:
4457 esize = sizeof(WCHAR);
4458 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4459 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4461 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4464 ERR("invalid array format type %x\n", *pCVArrayFormat);
4465 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4469 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4471 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4473 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4474 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4475 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4477 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4479 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4481 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
4484 /***********************************************************************
4485 * NdrConformantVaryingStructFree [RPCRT4.@]
4487 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4488 unsigned char *pMemory,
4489 PFORMAT_STRING pFormat)
4491 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4492 PFORMAT_STRING pCVArrayFormat;
4495 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4497 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4498 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4500 ERR("invalid format type %x\n", pCVStructFormat->type);
4501 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4505 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4506 pCVStructFormat->offset_to_array_description;
4507 switch (*pCVArrayFormat)
4509 case RPC_FC_CVARRAY:
4510 esize = *(const WORD*)(pCVArrayFormat+2);
4512 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4513 pCVArrayFormat + 4, 0);
4514 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4517 case RPC_FC_C_CSTRING:
4518 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4519 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4520 esize = sizeof(char);
4521 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4522 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4523 pCVArrayFormat + 2, 0);
4525 pStubMsg->MaxCount = pStubMsg->ActualCount;
4527 case RPC_FC_C_WSTRING:
4528 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4529 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4530 esize = sizeof(WCHAR);
4531 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4532 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4533 pCVArrayFormat + 2, 0);
4535 pStubMsg->MaxCount = pStubMsg->ActualCount;
4538 ERR("invalid array format type %x\n", *pCVArrayFormat);
4539 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4543 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4545 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4548 #include "pshpack1.h"
4552 unsigned char alignment;
4553 unsigned short total_size;
4554 } NDR_SMFARRAY_FORMAT;
4559 unsigned char alignment;
4560 unsigned long total_size;
4561 } NDR_LGFARRAY_FORMAT;
4562 #include "poppack.h"
4564 /***********************************************************************
4565 * NdrFixedArrayMarshall [RPCRT4.@]
4567 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4568 unsigned char *pMemory,
4569 PFORMAT_STRING pFormat)
4571 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4572 unsigned long total_size;
4574 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4576 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4577 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4579 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4580 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4584 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4586 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4588 total_size = pSmFArrayFormat->total_size;
4589 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4593 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4594 total_size = pLgFArrayFormat->total_size;
4595 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4598 pStubMsg->BufferMark = pStubMsg->Buffer;
4599 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4601 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4606 /***********************************************************************
4607 * NdrFixedArrayUnmarshall [RPCRT4.@]
4609 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4610 unsigned char **ppMemory,
4611 PFORMAT_STRING pFormat,
4612 unsigned char fMustAlloc)
4614 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4615 unsigned long total_size;
4616 unsigned char *saved_buffer;
4618 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4620 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4621 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4623 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4624 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4628 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4630 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4632 total_size = pSmFArrayFormat->total_size;
4633 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4637 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4638 total_size = pLgFArrayFormat->total_size;
4639 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4643 *ppMemory = NdrAllocate(pStubMsg, total_size);
4646 if (!pStubMsg->IsClient && !*ppMemory)
4647 /* for servers, we just point straight into the RPC buffer */
4648 *ppMemory = pStubMsg->Buffer;
4651 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4652 safe_buffer_increment(pStubMsg, total_size);
4653 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4655 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4656 if (*ppMemory != saved_buffer)
4657 memcpy(*ppMemory, saved_buffer, total_size);
4662 /***********************************************************************
4663 * NdrFixedArrayBufferSize [RPCRT4.@]
4665 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4666 unsigned char *pMemory,
4667 PFORMAT_STRING pFormat)
4669 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4670 unsigned long total_size;
4672 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4674 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4675 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4677 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4678 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4682 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4684 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4686 total_size = pSmFArrayFormat->total_size;
4687 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4691 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4692 total_size = pLgFArrayFormat->total_size;
4693 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4695 safe_buffer_length_increment(pStubMsg, total_size);
4697 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4700 /***********************************************************************
4701 * NdrFixedArrayMemorySize [RPCRT4.@]
4703 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4704 PFORMAT_STRING pFormat)
4706 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4709 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4711 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4712 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4714 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4715 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4719 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4721 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4723 total_size = pSmFArrayFormat->total_size;
4724 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4728 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4729 total_size = pLgFArrayFormat->total_size;
4730 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4732 pStubMsg->BufferMark = pStubMsg->Buffer;
4733 safe_buffer_increment(pStubMsg, total_size);
4734 pStubMsg->MemorySize += total_size;
4736 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4741 /***********************************************************************
4742 * NdrFixedArrayFree [RPCRT4.@]
4744 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4745 unsigned char *pMemory,
4746 PFORMAT_STRING pFormat)
4748 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4750 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4752 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4753 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4755 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4756 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4760 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4761 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4764 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4765 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4768 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4771 /***********************************************************************
4772 * NdrVaryingArrayMarshall [RPCRT4.@]
4774 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4775 unsigned char *pMemory,
4776 PFORMAT_STRING pFormat)
4778 unsigned char alignment;
4779 DWORD elements, esize;
4782 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4784 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4785 (pFormat[0] != RPC_FC_LGVARRAY))
4787 ERR("invalid format type %x\n", pFormat[0]);
4788 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4792 alignment = pFormat[1] + 1;
4794 if (pFormat[0] == RPC_FC_SMVARRAY)
4797 pFormat += sizeof(WORD);
4798 elements = *(const WORD*)pFormat;
4799 pFormat += sizeof(WORD);
4804 pFormat += sizeof(DWORD);
4805 elements = *(const DWORD*)pFormat;
4806 pFormat += sizeof(DWORD);
4809 esize = *(const WORD*)pFormat;
4810 pFormat += sizeof(WORD);
4812 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4813 if ((pStubMsg->ActualCount > elements) ||
4814 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4816 RpcRaiseException(RPC_S_INVALID_BOUND);
4820 WriteVariance(pStubMsg);
4822 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
4824 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4825 pStubMsg->BufferMark = pStubMsg->Buffer;
4826 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
4828 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4833 /***********************************************************************
4834 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4836 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4837 unsigned char **ppMemory,
4838 PFORMAT_STRING pFormat,
4839 unsigned char fMustAlloc)
4841 unsigned char alignment;
4842 DWORD size, elements, esize;
4844 unsigned char *saved_buffer;
4847 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4849 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4850 (pFormat[0] != RPC_FC_LGVARRAY))
4852 ERR("invalid format type %x\n", pFormat[0]);
4853 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4857 alignment = pFormat[1] + 1;
4859 if (pFormat[0] == RPC_FC_SMVARRAY)
4862 size = *(const WORD*)pFormat;
4863 pFormat += sizeof(WORD);
4864 elements = *(const WORD*)pFormat;
4865 pFormat += sizeof(WORD);
4870 size = *(const DWORD*)pFormat;
4871 pFormat += sizeof(DWORD);
4872 elements = *(const DWORD*)pFormat;
4873 pFormat += sizeof(DWORD);
4876 esize = *(const WORD*)pFormat;
4877 pFormat += sizeof(WORD);
4879 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4881 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4883 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4884 offset = pStubMsg->Offset;
4886 if (!*ppMemory || fMustAlloc)
4887 *ppMemory = NdrAllocate(pStubMsg, size);
4888 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4889 safe_buffer_increment(pStubMsg, bufsize);
4891 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4893 memcpy(*ppMemory + offset, saved_buffer, bufsize);
4898 /***********************************************************************
4899 * NdrVaryingArrayBufferSize [RPCRT4.@]
4901 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4902 unsigned char *pMemory,
4903 PFORMAT_STRING pFormat)
4905 unsigned char alignment;
4906 DWORD elements, esize;
4908 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4910 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4911 (pFormat[0] != RPC_FC_LGVARRAY))
4913 ERR("invalid format type %x\n", pFormat[0]);
4914 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4918 alignment = pFormat[1] + 1;
4920 if (pFormat[0] == RPC_FC_SMVARRAY)
4923 pFormat += sizeof(WORD);
4924 elements = *(const WORD*)pFormat;
4925 pFormat += sizeof(WORD);
4930 pFormat += sizeof(DWORD);
4931 elements = *(const DWORD*)pFormat;
4932 pFormat += sizeof(DWORD);
4935 esize = *(const WORD*)pFormat;
4936 pFormat += sizeof(WORD);
4938 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4939 if ((pStubMsg->ActualCount > elements) ||
4940 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4942 RpcRaiseException(RPC_S_INVALID_BOUND);
4946 SizeVariance(pStubMsg);
4948 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4950 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4952 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4955 /***********************************************************************
4956 * NdrVaryingArrayMemorySize [RPCRT4.@]
4958 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4959 PFORMAT_STRING pFormat)
4961 unsigned char alignment;
4962 DWORD size, elements, esize;
4964 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4966 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4967 (pFormat[0] != RPC_FC_LGVARRAY))
4969 ERR("invalid format type %x\n", pFormat[0]);
4970 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4974 alignment = pFormat[1] + 1;
4976 if (pFormat[0] == RPC_FC_SMVARRAY)
4979 size = *(const WORD*)pFormat;
4980 pFormat += sizeof(WORD);
4981 elements = *(const WORD*)pFormat;
4982 pFormat += sizeof(WORD);
4987 size = *(const DWORD*)pFormat;
4988 pFormat += sizeof(DWORD);
4989 elements = *(const DWORD*)pFormat;
4990 pFormat += sizeof(DWORD);
4993 esize = *(const WORD*)pFormat;
4994 pFormat += sizeof(WORD);
4996 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4998 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5000 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5001 pStubMsg->MemorySize += size;
5003 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5005 return pStubMsg->MemorySize;
5008 /***********************************************************************
5009 * NdrVaryingArrayFree [RPCRT4.@]
5011 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5012 unsigned char *pMemory,
5013 PFORMAT_STRING pFormat)
5015 unsigned char alignment;
5018 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5020 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5021 (pFormat[0] != RPC_FC_LGVARRAY))
5023 ERR("invalid format type %x\n", pFormat[0]);
5024 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5028 alignment = pFormat[1] + 1;
5030 if (pFormat[0] == RPC_FC_SMVARRAY)
5033 pFormat += sizeof(WORD);
5034 elements = *(const WORD*)pFormat;
5035 pFormat += sizeof(WORD);
5040 pFormat += sizeof(DWORD);
5041 elements = *(const DWORD*)pFormat;
5042 pFormat += sizeof(DWORD);
5045 pFormat += sizeof(WORD);
5047 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5048 if ((pStubMsg->ActualCount > elements) ||
5049 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5051 RpcRaiseException(RPC_S_INVALID_BOUND);
5055 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5058 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5071 return *(const USHORT *)pMemory;
5075 return *(const ULONG *)pMemory;
5077 FIXME("Unhandled base type: 0x%02x\n", fc);
5082 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5083 unsigned long discriminant,
5084 PFORMAT_STRING pFormat)
5086 unsigned short num_arms, arm, type;
5088 num_arms = *(const SHORT*)pFormat & 0x0fff;
5090 for(arm = 0; arm < num_arms; arm++)
5092 if(discriminant == *(const ULONG*)pFormat)
5100 type = *(const unsigned short*)pFormat;
5101 TRACE("type %04x\n", type);
5102 if(arm == num_arms) /* default arm extras */
5106 ERR("no arm for 0x%lx and no default case\n", discriminant);
5107 RpcRaiseException(RPC_S_INVALID_TAG);
5112 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
5119 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5121 unsigned short type;
5125 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5129 type = *(const unsigned short*)pFormat;
5130 if((type & 0xff00) == 0x8000)
5132 unsigned char basetype = LOBYTE(type);
5133 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5137 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5138 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5141 unsigned char *saved_buffer = NULL;
5142 int pointer_buffer_mark_set = 0;
5149 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5150 saved_buffer = pStubMsg->Buffer;
5151 if (pStubMsg->PointerBufferMark)
5153 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5154 pStubMsg->PointerBufferMark = NULL;
5155 pointer_buffer_mark_set = 1;
5158 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5160 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5161 if (pointer_buffer_mark_set)
5163 STD_OVERFLOW_CHECK(pStubMsg);
5164 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5165 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5167 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5168 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5169 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5171 pStubMsg->Buffer = saved_buffer + 4;
5175 m(pStubMsg, pMemory, desc);
5178 else FIXME("no marshaller for embedded type %02x\n", *desc);
5183 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5184 unsigned char **ppMemory,
5186 PFORMAT_STRING pFormat,
5187 unsigned char fMustAlloc)
5189 unsigned short type;
5193 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5197 type = *(const unsigned short*)pFormat;
5198 if((type & 0xff00) == 0x8000)
5200 unsigned char basetype = LOBYTE(type);
5201 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5205 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5206 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5209 unsigned char *saved_buffer = NULL;
5210 int pointer_buffer_mark_set = 0;
5217 **(void***)ppMemory = NULL;
5218 ALIGN_POINTER(pStubMsg->Buffer, 4);
5219 saved_buffer = pStubMsg->Buffer;
5220 if (pStubMsg->PointerBufferMark)
5222 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5223 pStubMsg->PointerBufferMark = NULL;
5224 pointer_buffer_mark_set = 1;
5227 pStubMsg->Buffer += 4; /* for pointer ID */
5229 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5231 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5232 saved_buffer, pStubMsg->BufferEnd);
5233 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5236 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5237 if (pointer_buffer_mark_set)
5239 STD_OVERFLOW_CHECK(pStubMsg);
5240 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5241 pStubMsg->Buffer = saved_buffer + 4;
5245 m(pStubMsg, ppMemory, desc, fMustAlloc);
5248 else FIXME("no marshaller for embedded type %02x\n", *desc);
5253 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5254 unsigned char *pMemory,
5256 PFORMAT_STRING pFormat)
5258 unsigned short type;
5262 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5266 type = *(const unsigned short*)pFormat;
5267 if((type & 0xff00) == 0x8000)
5269 unsigned char basetype = LOBYTE(type);
5270 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5274 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5275 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5284 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5285 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5286 if (!pStubMsg->IgnoreEmbeddedPointers)
5288 int saved_buffer_length = pStubMsg->BufferLength;
5289 pStubMsg->BufferLength = pStubMsg->PointerLength;
5290 pStubMsg->PointerLength = 0;
5291 if(!pStubMsg->BufferLength)
5292 ERR("BufferLength == 0??\n");
5293 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5294 pStubMsg->PointerLength = pStubMsg->BufferLength;
5295 pStubMsg->BufferLength = saved_buffer_length;
5299 m(pStubMsg, pMemory, desc);
5302 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5306 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5308 PFORMAT_STRING pFormat)
5310 unsigned short type, size;
5312 size = *(const unsigned short*)pFormat;
5313 pStubMsg->Memory += size;
5316 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5320 type = *(const unsigned short*)pFormat;
5321 if((type & 0xff00) == 0x8000)
5323 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5327 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5328 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5329 unsigned char *saved_buffer;
5338 ALIGN_POINTER(pStubMsg->Buffer, 4);
5339 saved_buffer = pStubMsg->Buffer;
5340 safe_buffer_increment(pStubMsg, 4);
5341 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
5342 pStubMsg->MemorySize += 4;
5343 if (!pStubMsg->IgnoreEmbeddedPointers)
5344 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5347 return m(pStubMsg, desc);
5350 else FIXME("no marshaller for embedded type %02x\n", *desc);
5353 TRACE("size %d\n", size);
5357 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5358 unsigned char *pMemory,
5360 PFORMAT_STRING pFormat)
5362 unsigned short type;
5366 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5370 type = *(const unsigned short*)pFormat;
5371 if((type & 0xff00) != 0x8000)
5373 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5374 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5383 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5386 m(pStubMsg, pMemory, desc);
5392 /***********************************************************************
5393 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5395 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5396 unsigned char *pMemory,
5397 PFORMAT_STRING pFormat)
5399 unsigned char switch_type;
5400 unsigned char increment;
5403 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5406 switch_type = *pFormat & 0xf;
5407 increment = (*pFormat & 0xf0) >> 4;
5410 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5412 switch_value = get_discriminant(switch_type, pMemory);
5413 TRACE("got switch value 0x%x\n", switch_value);
5415 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5416 pMemory += increment;
5418 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5421 /***********************************************************************
5422 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5424 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5425 unsigned char **ppMemory,
5426 PFORMAT_STRING pFormat,
5427 unsigned char fMustAlloc)
5429 unsigned char switch_type;
5430 unsigned char increment;
5432 unsigned short size;
5433 unsigned char *pMemoryArm;
5435 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5438 switch_type = *pFormat & 0xf;
5439 increment = (*pFormat & 0xf0) >> 4;
5442 ALIGN_POINTER(pStubMsg->Buffer, increment);
5443 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5444 TRACE("got switch value 0x%x\n", switch_value);
5446 size = *(const unsigned short*)pFormat + increment;
5447 if(!*ppMemory || fMustAlloc)
5448 *ppMemory = NdrAllocate(pStubMsg, size);
5450 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5451 pMemoryArm = *ppMemory + increment;
5453 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
5456 /***********************************************************************
5457 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5459 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5460 unsigned char *pMemory,
5461 PFORMAT_STRING pFormat)
5463 unsigned char switch_type;
5464 unsigned char increment;
5467 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5470 switch_type = *pFormat & 0xf;
5471 increment = (*pFormat & 0xf0) >> 4;
5474 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5475 switch_value = get_discriminant(switch_type, pMemory);
5476 TRACE("got switch value 0x%x\n", switch_value);
5478 /* Add discriminant size */
5479 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5480 pMemory += increment;
5482 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5485 /***********************************************************************
5486 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5488 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5489 PFORMAT_STRING pFormat)
5491 unsigned char switch_type;
5492 unsigned char increment;
5495 switch_type = *pFormat & 0xf;
5496 increment = (*pFormat & 0xf0) >> 4;
5499 ALIGN_POINTER(pStubMsg->Buffer, increment);
5500 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5501 TRACE("got switch value 0x%x\n", switch_value);
5503 pStubMsg->Memory += increment;
5505 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5508 /***********************************************************************
5509 * NdrEncapsulatedUnionFree [RPCRT4.@]
5511 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5512 unsigned char *pMemory,
5513 PFORMAT_STRING pFormat)
5515 unsigned char switch_type;
5516 unsigned char increment;
5519 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5522 switch_type = *pFormat & 0xf;
5523 increment = (*pFormat & 0xf0) >> 4;
5526 switch_value = get_discriminant(switch_type, pMemory);
5527 TRACE("got switch value 0x%x\n", switch_value);
5529 pMemory += increment;
5531 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5534 /***********************************************************************
5535 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5537 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5538 unsigned char *pMemory,
5539 PFORMAT_STRING pFormat)
5541 unsigned char switch_type;
5543 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5546 switch_type = *pFormat;
5549 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5550 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5551 /* Marshall discriminant */
5552 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5554 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5557 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5558 PFORMAT_STRING *ppFormat)
5560 long discriminant = 0;
5570 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5579 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5580 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5588 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5589 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5594 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5598 if (pStubMsg->fHasNewCorrDesc)
5602 return discriminant;
5605 /**********************************************************************
5606 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5608 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5609 unsigned char **ppMemory,
5610 PFORMAT_STRING pFormat,
5611 unsigned char fMustAlloc)
5614 unsigned short size;
5616 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5619 /* Unmarshall discriminant */
5620 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5621 TRACE("unmarshalled discriminant %lx\n", discriminant);
5623 pFormat += *(const SHORT*)pFormat;
5625 size = *(const unsigned short*)pFormat;
5627 if(!*ppMemory || fMustAlloc)
5628 *ppMemory = NdrAllocate(pStubMsg, size);
5630 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5633 /***********************************************************************
5634 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5636 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5637 unsigned char *pMemory,
5638 PFORMAT_STRING pFormat)
5640 unsigned char switch_type;
5642 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5645 switch_type = *pFormat;
5648 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5649 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5650 /* Add discriminant size */
5651 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5653 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5656 /***********************************************************************
5657 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5659 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5660 PFORMAT_STRING pFormat)
5665 /* Unmarshall discriminant */
5666 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5667 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
5669 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
5672 /***********************************************************************
5673 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5675 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5676 unsigned char *pMemory,
5677 PFORMAT_STRING pFormat)
5679 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5683 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5684 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5686 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5689 /***********************************************************************
5690 * NdrByteCountPointerMarshall [RPCRT4.@]
5692 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5693 unsigned char *pMemory,
5694 PFORMAT_STRING pFormat)
5700 /***********************************************************************
5701 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5703 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5704 unsigned char **ppMemory,
5705 PFORMAT_STRING pFormat,
5706 unsigned char fMustAlloc)
5712 /***********************************************************************
5713 * NdrByteCountPointerBufferSize [RPCRT4.@]
5715 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5716 unsigned char *pMemory,
5717 PFORMAT_STRING pFormat)
5722 /***********************************************************************
5723 * NdrByteCountPointerMemorySize [RPCRT4.@]
5725 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5726 PFORMAT_STRING pFormat)
5732 /***********************************************************************
5733 * NdrByteCountPointerFree [RPCRT4.@]
5735 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
5736 unsigned char *pMemory,
5737 PFORMAT_STRING pFormat)
5742 /***********************************************************************
5743 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5745 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5746 unsigned char *pMemory,
5747 PFORMAT_STRING pFormat)
5753 /***********************************************************************
5754 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5756 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5757 unsigned char **ppMemory,
5758 PFORMAT_STRING pFormat,
5759 unsigned char fMustAlloc)
5765 /***********************************************************************
5766 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5768 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5769 unsigned char *pMemory,
5770 PFORMAT_STRING pFormat)
5775 /***********************************************************************
5776 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5778 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5779 PFORMAT_STRING pFormat)
5785 /***********************************************************************
5786 * NdrXmitOrRepAsFree [RPCRT4.@]
5788 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
5789 unsigned char *pMemory,
5790 PFORMAT_STRING pFormat)
5795 #include "pshpack1.h"
5799 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
5803 #include "poppack.h"
5805 /***********************************************************************
5806 * NdrRangeMarshall [internal]
5808 unsigned char *WINAPI NdrRangeMarshall(
5809 PMIDL_STUB_MESSAGE pStubMsg,
5810 unsigned char *pMemory,
5811 PFORMAT_STRING pFormat)
5813 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5814 unsigned char base_type;
5816 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5818 if (pRange->type != RPC_FC_RANGE)
5820 ERR("invalid format type %x\n", pRange->type);
5821 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5825 base_type = pRange->flags_type & 0xf;
5827 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
5830 /***********************************************************************
5831 * NdrRangeUnmarshall
5833 unsigned char *WINAPI NdrRangeUnmarshall(
5834 PMIDL_STUB_MESSAGE pStubMsg,
5835 unsigned char **ppMemory,
5836 PFORMAT_STRING pFormat,
5837 unsigned char fMustAlloc)
5839 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5840 unsigned char base_type;
5842 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5844 if (pRange->type != RPC_FC_RANGE)
5846 ERR("invalid format type %x\n", pRange->type);
5847 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5850 base_type = pRange->flags_type & 0xf;
5852 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5853 base_type, pRange->low_value, pRange->high_value);
5855 #define RANGE_UNMARSHALL(type, format_spec) \
5858 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5859 if (fMustAlloc || !*ppMemory) \
5860 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5861 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5863 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5864 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5865 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5867 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5868 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5870 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5871 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5872 (type)pRange->high_value); \
5873 RpcRaiseException(RPC_S_INVALID_BOUND); \
5876 TRACE("*ppMemory: %p\n", *ppMemory); \
5877 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5878 pStubMsg->Buffer += sizeof(type); \
5885 RANGE_UNMARSHALL(UCHAR, "%d");
5886 TRACE("value: 0x%02x\n", **ppMemory);
5890 RANGE_UNMARSHALL(CHAR, "%u");
5891 TRACE("value: 0x%02x\n", **ppMemory);
5893 case RPC_FC_WCHAR: /* FIXME: valid? */
5895 RANGE_UNMARSHALL(USHORT, "%u");
5896 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5899 RANGE_UNMARSHALL(SHORT, "%d");
5900 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5903 RANGE_UNMARSHALL(LONG, "%d");
5904 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5907 RANGE_UNMARSHALL(ULONG, "%u");
5908 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5912 FIXME("Unhandled enum type\n");
5914 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
5919 ERR("invalid range base type: 0x%02x\n", base_type);
5920 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5926 /***********************************************************************
5927 * NdrRangeBufferSize [internal]
5929 void WINAPI NdrRangeBufferSize(
5930 PMIDL_STUB_MESSAGE pStubMsg,
5931 unsigned char *pMemory,
5932 PFORMAT_STRING pFormat)
5934 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5935 unsigned char base_type;
5937 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5939 if (pRange->type != RPC_FC_RANGE)
5941 ERR("invalid format type %x\n", pRange->type);
5942 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5944 base_type = pRange->flags_type & 0xf;
5946 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
5949 /***********************************************************************
5950 * NdrRangeMemorySize [internal]
5952 ULONG WINAPI NdrRangeMemorySize(
5953 PMIDL_STUB_MESSAGE pStubMsg,
5954 PFORMAT_STRING pFormat)
5956 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5957 unsigned char base_type;
5959 if (pRange->type != RPC_FC_RANGE)
5961 ERR("invalid format type %x\n", pRange->type);
5962 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5965 base_type = pRange->flags_type & 0xf;
5967 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
5970 /***********************************************************************
5971 * NdrRangeFree [internal]
5973 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
5974 unsigned char *pMemory,
5975 PFORMAT_STRING pFormat)
5977 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5982 /***********************************************************************
5983 * NdrBaseTypeMarshall [internal]
5985 static unsigned char *WINAPI NdrBaseTypeMarshall(
5986 PMIDL_STUB_MESSAGE pStubMsg,
5987 unsigned char *pMemory,
5988 PFORMAT_STRING pFormat)
5990 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5998 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
5999 TRACE("value: 0x%02x\n", *pMemory);
6004 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6005 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6006 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6010 case RPC_FC_ERROR_STATUS_T:
6012 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
6013 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6014 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6017 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
6018 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6021 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
6022 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6025 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
6026 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6027 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6030 /* only 16-bits on the wire, so do a sanity check */
6031 if (*(UINT *)pMemory > SHRT_MAX)
6032 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6033 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6034 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6035 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6036 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
6037 pStubMsg->Buffer += sizeof(USHORT);
6038 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6043 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6046 /* FIXME: what is the correct return value? */
6050 /***********************************************************************
6051 * NdrBaseTypeUnmarshall [internal]
6053 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6054 PMIDL_STUB_MESSAGE pStubMsg,
6055 unsigned char **ppMemory,
6056 PFORMAT_STRING pFormat,
6057 unsigned char fMustAlloc)
6059 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6061 #define BASE_TYPE_UNMARSHALL(type) \
6062 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6063 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6065 *ppMemory = pStubMsg->Buffer; \
6066 TRACE("*ppMemory: %p\n", *ppMemory); \
6071 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6072 TRACE("*ppMemory: %p\n", *ppMemory); \
6073 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
6075 safe_buffer_increment(pStubMsg, sizeof(type));
6083 BASE_TYPE_UNMARSHALL(UCHAR);
6084 TRACE("value: 0x%02x\n", **ppMemory);
6089 BASE_TYPE_UNMARSHALL(USHORT);
6090 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6094 case RPC_FC_ERROR_STATUS_T:
6096 BASE_TYPE_UNMARSHALL(ULONG);
6097 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6100 BASE_TYPE_UNMARSHALL(float);
6101 TRACE("value: %f\n", **(float **)ppMemory);
6104 BASE_TYPE_UNMARSHALL(double);
6105 TRACE("value: %f\n", **(double **)ppMemory);
6108 BASE_TYPE_UNMARSHALL(ULONGLONG);
6109 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6112 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6113 if (fMustAlloc || !*ppMemory)
6114 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6115 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
6116 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6117 TRACE("*ppMemory: %p\n", *ppMemory);
6118 /* 16-bits on the wire, but int in memory */
6119 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
6120 pStubMsg->Buffer += sizeof(USHORT);
6121 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6126 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6128 #undef BASE_TYPE_UNMARSHALL
6130 /* FIXME: what is the correct return value? */
6135 /***********************************************************************
6136 * NdrBaseTypeBufferSize [internal]
6138 static void WINAPI NdrBaseTypeBufferSize(
6139 PMIDL_STUB_MESSAGE pStubMsg,
6140 unsigned char *pMemory,
6141 PFORMAT_STRING pFormat)
6143 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6151 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6157 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
6158 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6163 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
6164 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6167 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
6168 safe_buffer_length_increment(pStubMsg, sizeof(float));
6171 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
6172 safe_buffer_length_increment(pStubMsg, sizeof(double));
6175 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
6176 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6178 case RPC_FC_ERROR_STATUS_T:
6179 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
6180 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6185 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6189 /***********************************************************************
6190 * NdrBaseTypeMemorySize [internal]
6192 static ULONG WINAPI NdrBaseTypeMemorySize(
6193 PMIDL_STUB_MESSAGE pStubMsg,
6194 PFORMAT_STRING pFormat)
6196 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6204 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6205 pStubMsg->MemorySize += sizeof(UCHAR);
6206 return sizeof(UCHAR);
6210 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6211 pStubMsg->MemorySize += sizeof(USHORT);
6212 return sizeof(USHORT);
6216 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6217 pStubMsg->MemorySize += sizeof(ULONG);
6218 return sizeof(ULONG);
6220 safe_buffer_increment(pStubMsg, sizeof(float));
6221 pStubMsg->MemorySize += sizeof(float);
6222 return sizeof(float);
6224 safe_buffer_increment(pStubMsg, sizeof(double));
6225 pStubMsg->MemorySize += sizeof(double);
6226 return sizeof(double);
6228 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6229 pStubMsg->MemorySize += sizeof(ULONGLONG);
6230 return sizeof(ULONGLONG);
6231 case RPC_FC_ERROR_STATUS_T:
6232 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6233 pStubMsg->MemorySize += sizeof(error_status_t);
6234 return sizeof(error_status_t);
6236 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6237 pStubMsg->MemorySize += sizeof(UINT);
6238 return sizeof(UINT);
6240 pStubMsg->MemorySize += sizeof(void *);
6241 return sizeof(void *);
6243 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6248 /***********************************************************************
6249 * NdrBaseTypeFree [internal]
6251 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6252 unsigned char *pMemory,
6253 PFORMAT_STRING pFormat)
6255 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6260 /***********************************************************************
6261 * NdrContextHandleBufferSize [internal]
6263 static void WINAPI NdrContextHandleBufferSize(
6264 PMIDL_STUB_MESSAGE pStubMsg,
6265 unsigned char *pMemory,
6266 PFORMAT_STRING pFormat)
6268 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6270 if (*pFormat != RPC_FC_BIND_CONTEXT)
6272 ERR("invalid format type %x\n", *pFormat);
6273 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6275 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
6276 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6279 /***********************************************************************
6280 * NdrContextHandleMarshall [internal]
6282 static unsigned char *WINAPI NdrContextHandleMarshall(
6283 PMIDL_STUB_MESSAGE pStubMsg,
6284 unsigned char *pMemory,
6285 PFORMAT_STRING pFormat)
6287 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6289 if (*pFormat != RPC_FC_BIND_CONTEXT)
6291 ERR("invalid format type %x\n", *pFormat);
6292 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6294 TRACE("flags: 0x%02x\n", pFormat[1]);
6296 if (pFormat[1] & 0x80)
6297 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6299 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
6304 /***********************************************************************
6305 * NdrContextHandleUnmarshall [internal]
6307 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6308 PMIDL_STUB_MESSAGE pStubMsg,
6309 unsigned char **ppMemory,
6310 PFORMAT_STRING pFormat,
6311 unsigned char fMustAlloc)
6313 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6314 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6316 if (*pFormat != RPC_FC_BIND_CONTEXT)
6318 ERR("invalid format type %x\n", *pFormat);
6319 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6321 TRACE("flags: 0x%02x\n", pFormat[1]);
6323 /* [out]-only or [ret] param */
6324 if ((pFormat[1] & 0x60) == 0x20)
6325 **(NDR_CCONTEXT **)ppMemory = NULL;
6326 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6331 /***********************************************************************
6332 * NdrClientContextMarshall [RPCRT4.@]
6334 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6335 NDR_CCONTEXT ContextHandle,
6338 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
6340 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
6342 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6344 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6345 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6346 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6349 /* FIXME: what does fCheck do? */
6350 NDRCContextMarshall(ContextHandle,
6353 pStubMsg->Buffer += cbNDRContext;
6356 /***********************************************************************
6357 * NdrClientContextUnmarshall [RPCRT4.@]
6359 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6360 NDR_CCONTEXT * pContextHandle,
6361 RPC_BINDING_HANDLE BindHandle)
6363 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
6365 ALIGN_POINTER(pStubMsg->Buffer, 4);
6367 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
6368 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6370 NDRCContextUnmarshall(pContextHandle,
6373 pStubMsg->RpcMsg->DataRepresentation);
6375 pStubMsg->Buffer += cbNDRContext;
6378 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6379 NDR_SCONTEXT ContextHandle,
6380 NDR_RUNDOWN RundownRoutine )
6382 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
6384 ALIGN_POINTER(pStubMsg->Buffer, 4);
6386 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6388 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6389 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6390 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6393 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6394 pStubMsg->Buffer, RundownRoutine, NULL,
6395 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6396 pStubMsg->Buffer += cbNDRContext;
6399 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6401 NDR_SCONTEXT ContextHandle;
6403 TRACE("(%p)\n", pStubMsg);
6405 ALIGN_POINTER(pStubMsg->Buffer, 4);
6407 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6409 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6410 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6411 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6414 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6416 pStubMsg->RpcMsg->DataRepresentation,
6417 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6418 pStubMsg->Buffer += cbNDRContext;
6420 return ContextHandle;
6423 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6424 unsigned char* pMemory,
6425 PFORMAT_STRING pFormat)
6427 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6430 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6431 PFORMAT_STRING pFormat)
6433 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6434 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6436 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6438 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6439 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6440 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6441 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6442 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6444 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6445 if_id = &sif->InterfaceId;
6448 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
6449 pStubMsg->RpcMsg->DataRepresentation, if_id,
6453 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6454 NDR_SCONTEXT ContextHandle,
6455 NDR_RUNDOWN RundownRoutine,
6456 PFORMAT_STRING pFormat)
6458 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6459 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6461 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6463 ALIGN_POINTER(pStubMsg->Buffer, 4);
6465 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6467 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6468 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6469 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6472 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6473 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6474 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6475 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6476 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6478 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6479 if_id = &sif->InterfaceId;
6482 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6483 pStubMsg->Buffer, RundownRoutine, if_id, flags);
6484 pStubMsg->Buffer += cbNDRContext;
6487 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6488 PFORMAT_STRING pFormat)
6490 NDR_SCONTEXT ContextHandle;
6491 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6492 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6494 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6496 ALIGN_POINTER(pStubMsg->Buffer, 4);
6498 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6500 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6501 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6502 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6505 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6506 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6507 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6508 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6509 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6511 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6512 if_id = &sif->InterfaceId;
6515 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6517 pStubMsg->RpcMsg->DataRepresentation,
6519 pStubMsg->Buffer += cbNDRContext;
6521 return ContextHandle;
6524 /***********************************************************************
6525 * NdrCorrelationInitialize [RPCRT4.@]
6527 * Initializes correlation validity checking.
6530 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6531 * pMemory [I] Pointer to memory to use as a cache.
6532 * CacheSize [I] Size of the memory pointed to by pMemory.
6533 * Flags [I] Reserved. Set to zero.
6538 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
6540 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
6541 pStubMsg->fHasNewCorrDesc = TRUE;
6544 /***********************************************************************
6545 * NdrCorrelationPass [RPCRT4.@]
6547 * Performs correlation validity checking.
6550 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6555 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
6557 FIXME("(%p): stub\n", pStubMsg);
6560 /***********************************************************************
6561 * NdrCorrelationFree [RPCRT4.@]
6563 * Frees any resources used while unmarshalling parameters that need
6564 * correlation validity checking.
6567 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6572 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
6574 FIXME("(%p): stub\n", pStubMsg);