4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * - Byte count pointers
24 * - transmit_as/represent as
25 * - Multi-dimensional arrays
26 * - Conversion functions (NdrConvert)
27 * - Checks for integer addition overflow in base type and user marshall functions
43 #include "wine/unicode.h"
44 #include "wine/rpcfc.h"
46 #include "wine/debug.h"
48 WINE_DEFAULT_DEBUG_CHANNEL(ole);
51 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
52 (*((UINT32 *)(pchar)) = (uint32))
54 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
55 (*((UINT32 *)(pchar)))
57 /* these would work for i386 too, but less efficient */
58 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
59 (*(pchar) = LOBYTE(LOWORD(uint32)), \
60 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
61 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
62 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
63 (uint32)) /* allow as r-value */
65 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
67 MAKEWORD(*(pchar), *((pchar)+1)), \
68 MAKEWORD(*((pchar)+2), *((pchar)+3))))
71 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
72 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
73 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
74 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
75 *(pchar) = HIBYTE(HIWORD(uint32)), \
76 (uint32)) /* allow as r-value */
78 #define BIG_ENDIAN_UINT32_READ(pchar) \
80 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
81 MAKEWORD(*((pchar)+1), *(pchar))))
83 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
84 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
85 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
86 # define NDR_LOCAL_UINT32_READ(pchar) \
87 BIG_ENDIAN_UINT32_READ(pchar)
89 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
90 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
91 # define NDR_LOCAL_UINT32_READ(pchar) \
92 LITTLE_ENDIAN_UINT32_READ(pchar)
95 /* _Align must be the desired alignment,
96 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
97 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
98 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
99 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
100 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
101 #define ALIGN_POINTER_CLEAR(_Ptr, _Align) \
103 memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \
104 ALIGN_POINTER(_Ptr, _Align); \
107 #define STD_OVERFLOW_CHECK(_Msg) do { \
108 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
109 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
110 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
113 #define NDR_TABLE_SIZE 128
114 #define NDR_TABLE_MASK 127
116 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
117 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
118 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
119 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
120 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
122 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
123 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
124 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
126 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
128 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
129 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
130 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
131 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
135 NdrPointerMarshall, NdrPointerMarshall,
136 NdrPointerMarshall, NdrPointerMarshall,
138 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
139 NdrConformantStructMarshall, NdrConformantStructMarshall,
140 NdrConformantVaryingStructMarshall,
141 NdrComplexStructMarshall,
143 NdrConformantArrayMarshall,
144 NdrConformantVaryingArrayMarshall,
145 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
146 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
147 NdrComplexArrayMarshall,
149 NdrConformantStringMarshall, 0, 0,
150 NdrConformantStringMarshall,
151 NdrNonConformantStringMarshall, 0, 0, 0,
153 NdrEncapsulatedUnionMarshall,
154 NdrNonEncapsulatedUnionMarshall,
155 NdrByteCountPointerMarshall,
156 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
158 NdrInterfacePointerMarshall,
160 NdrContextHandleMarshall,
163 NdrUserMarshalMarshall,
168 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
170 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
171 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
172 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
173 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
175 NdrBaseTypeUnmarshall,
177 NdrPointerUnmarshall, NdrPointerUnmarshall,
178 NdrPointerUnmarshall, NdrPointerUnmarshall,
180 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
181 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
182 NdrConformantVaryingStructUnmarshall,
183 NdrComplexStructUnmarshall,
185 NdrConformantArrayUnmarshall,
186 NdrConformantVaryingArrayUnmarshall,
187 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
188 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
189 NdrComplexArrayUnmarshall,
191 NdrConformantStringUnmarshall, 0, 0,
192 NdrConformantStringUnmarshall,
193 NdrNonConformantStringUnmarshall, 0, 0, 0,
195 NdrEncapsulatedUnionUnmarshall,
196 NdrNonEncapsulatedUnionUnmarshall,
197 NdrByteCountPointerUnmarshall,
198 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
200 NdrInterfacePointerUnmarshall,
202 NdrContextHandleUnmarshall,
205 NdrUserMarshalUnmarshall,
210 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
212 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
213 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
214 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
215 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
217 NdrBaseTypeBufferSize,
219 NdrPointerBufferSize, NdrPointerBufferSize,
220 NdrPointerBufferSize, NdrPointerBufferSize,
222 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
223 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
224 NdrConformantVaryingStructBufferSize,
225 NdrComplexStructBufferSize,
227 NdrConformantArrayBufferSize,
228 NdrConformantVaryingArrayBufferSize,
229 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
230 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
231 NdrComplexArrayBufferSize,
233 NdrConformantStringBufferSize, 0, 0,
234 NdrConformantStringBufferSize,
235 NdrNonConformantStringBufferSize, 0, 0, 0,
237 NdrEncapsulatedUnionBufferSize,
238 NdrNonEncapsulatedUnionBufferSize,
239 NdrByteCountPointerBufferSize,
240 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
242 NdrInterfacePointerBufferSize,
244 NdrContextHandleBufferSize,
247 NdrUserMarshalBufferSize,
252 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
254 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
255 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
256 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
257 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
259 NdrBaseTypeMemorySize,
261 NdrPointerMemorySize, NdrPointerMemorySize,
262 NdrPointerMemorySize, NdrPointerMemorySize,
264 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
265 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
266 NdrConformantVaryingStructMemorySize,
267 NdrComplexStructMemorySize,
269 NdrConformantArrayMemorySize,
270 NdrConformantVaryingArrayMemorySize,
271 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
272 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
273 NdrComplexArrayMemorySize,
275 NdrConformantStringMemorySize, 0, 0,
276 NdrConformantStringMemorySize,
277 NdrNonConformantStringMemorySize, 0, 0, 0,
279 NdrEncapsulatedUnionMemorySize,
280 NdrNonEncapsulatedUnionMemorySize,
281 NdrByteCountPointerMemorySize,
282 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
284 NdrInterfacePointerMemorySize,
289 NdrUserMarshalMemorySize,
294 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
296 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
297 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
298 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
299 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
303 NdrPointerFree, NdrPointerFree,
304 NdrPointerFree, NdrPointerFree,
306 NdrSimpleStructFree, NdrSimpleStructFree,
307 NdrConformantStructFree, NdrConformantStructFree,
308 NdrConformantVaryingStructFree,
309 NdrComplexStructFree,
311 NdrConformantArrayFree,
312 NdrConformantVaryingArrayFree,
313 NdrFixedArrayFree, NdrFixedArrayFree,
314 NdrVaryingArrayFree, NdrVaryingArrayFree,
320 NdrEncapsulatedUnionFree,
321 NdrNonEncapsulatedUnionFree,
323 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
325 NdrInterfacePointerFree,
336 typedef struct _NDR_MEMORY_LIST
341 struct _NDR_MEMORY_LIST *next;
344 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
346 /***********************************************************************
347 * NdrAllocate [RPCRT4.@]
349 * Allocates a block of memory using pStubMsg->pfnAllocate.
352 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
353 * len [I] Size of memory block to allocate.
356 * The memory block of size len that was allocated.
359 * The memory block is always 8-byte aligned.
360 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
361 * exception is raised.
363 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
368 NDR_MEMORY_LIST *mem_list;
370 aligned_len = ALIGNED_LENGTH(len, 8);
371 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
372 /* check for overflow */
373 if (adjusted_len < len)
375 ERR("overflow of adjusted_len %d, len %d\n", adjusted_len, len);
376 RpcRaiseException(RPC_X_BAD_STUB_DATA);
379 p = pStubMsg->pfnAllocate(adjusted_len);
380 if (!p) RpcRaiseException(ERROR_OUTOFMEMORY);
382 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
383 mem_list->magic = MEML_MAGIC;
384 mem_list->size = aligned_len;
385 mem_list->reserved = 0;
386 mem_list->next = pStubMsg->pMemoryList;
387 pStubMsg->pMemoryList = mem_list;
393 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
395 TRACE("(%p, %p)\n", pStubMsg, Pointer);
397 pStubMsg->pfnFree(Pointer);
400 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
402 return (*(const ULONG *)pFormat != -1);
405 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
407 ALIGN_POINTER(pStubMsg->Buffer, 4);
408 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
409 RpcRaiseException(RPC_X_BAD_STUB_DATA);
410 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
411 pStubMsg->Buffer += 4;
412 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
413 if (pStubMsg->fHasNewCorrDesc)
419 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
421 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
423 pStubMsg->Offset = 0;
424 pStubMsg->ActualCount = pStubMsg->MaxCount;
428 ALIGN_POINTER(pStubMsg->Buffer, 4);
429 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
430 RpcRaiseException(RPC_X_BAD_STUB_DATA);
431 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
432 pStubMsg->Buffer += 4;
433 TRACE("offset is %d\n", pStubMsg->Offset);
434 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
435 pStubMsg->Buffer += 4;
436 TRACE("variance is %d\n", pStubMsg->ActualCount);
438 if ((pStubMsg->ActualCount > MaxValue) ||
439 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
441 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
442 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
443 RpcRaiseException(RPC_S_INVALID_BOUND);
448 if (pStubMsg->fHasNewCorrDesc)
454 /* writes the conformance value to the buffer */
455 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
457 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
458 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
459 RpcRaiseException(RPC_X_BAD_STUB_DATA);
460 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
461 pStubMsg->Buffer += 4;
464 /* writes the variance values to the buffer */
465 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
467 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
468 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
469 RpcRaiseException(RPC_X_BAD_STUB_DATA);
470 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
471 pStubMsg->Buffer += 4;
472 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
473 pStubMsg->Buffer += 4;
476 /* requests buffer space for the conformance value */
477 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
479 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
480 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
481 RpcRaiseException(RPC_X_BAD_STUB_DATA);
482 pStubMsg->BufferLength += 4;
485 /* requests buffer space for the variance values */
486 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
488 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
489 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
490 RpcRaiseException(RPC_X_BAD_STUB_DATA);
491 pStubMsg->BufferLength += 8;
494 PFORMAT_STRING ComputeConformanceOrVariance(
495 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
496 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
498 BYTE dtype = pFormat[0] & 0xf;
499 short ofs = *(const short *)&pFormat[2];
503 if (!IsConformanceOrVariancePresent(pFormat)) {
504 /* null descriptor */
509 switch (pFormat[0] & 0xf0) {
510 case RPC_FC_NORMAL_CONFORMANCE:
511 TRACE("normal conformance, ofs=%d\n", ofs);
514 case RPC_FC_POINTER_CONFORMANCE:
515 TRACE("pointer conformance, ofs=%d\n", ofs);
516 ptr = pStubMsg->Memory;
518 case RPC_FC_TOP_LEVEL_CONFORMANCE:
519 TRACE("toplevel conformance, ofs=%d\n", ofs);
520 if (pStubMsg->StackTop) {
521 ptr = pStubMsg->StackTop;
524 /* -Os mode, *pCount is already set */
528 case RPC_FC_CONSTANT_CONFORMANCE:
529 data = ofs | ((DWORD)pFormat[1] << 16);
530 TRACE("constant conformance, val=%d\n", data);
533 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
534 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
535 if (pStubMsg->StackTop) {
536 ptr = pStubMsg->StackTop;
544 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
547 switch (pFormat[1]) {
548 case RPC_FC_DEREFERENCE:
549 ptr = *(LPVOID*)((char *)ptr + ofs);
551 case RPC_FC_CALLBACK:
553 unsigned char *old_stack_top = pStubMsg->StackTop;
554 pStubMsg->StackTop = ptr;
556 /* ofs is index into StubDesc->apfnExprEval */
557 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
558 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
560 pStubMsg->StackTop = old_stack_top;
562 /* the callback function always stores the computed value in MaxCount */
563 *pCount = pStubMsg->MaxCount;
567 ptr = (char *)ptr + ofs;
580 data = *(USHORT*)ptr;
591 FIXME("unknown conformance data type %x\n", dtype);
594 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
597 switch (pFormat[1]) {
598 case RPC_FC_DEREFERENCE: /* already handled */
615 FIXME("unknown conformance op %d\n", pFormat[1]);
620 TRACE("resulting conformance is %ld\n", *pCount);
621 if (pStubMsg->fHasNewCorrDesc)
627 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
628 * the result overflows 32-bits */
629 static inline ULONG safe_multiply(ULONG a, ULONG b)
631 ULONGLONG ret = (ULONGLONG)a * b;
632 if (ret > 0xffffffff)
634 RpcRaiseException(RPC_S_INVALID_BOUND);
640 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
642 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
643 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
644 RpcRaiseException(RPC_X_BAD_STUB_DATA);
645 pStubMsg->Buffer += size;
648 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
650 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
652 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
653 pStubMsg->BufferLength, size);
654 RpcRaiseException(RPC_X_BAD_STUB_DATA);
656 pStubMsg->BufferLength += size;
659 /* copies data from the buffer, checking that there is enough data in the buffer
661 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
663 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
664 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
666 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
667 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
668 RpcRaiseException(RPC_X_BAD_STUB_DATA);
670 if (p == pStubMsg->Buffer)
671 ERR("pointer is the same as the buffer\n");
672 memcpy(p, pStubMsg->Buffer, size);
673 pStubMsg->Buffer += size;
676 /* copies data to the buffer, checking that there is enough space to do so */
677 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
679 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
680 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
682 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
683 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
685 RpcRaiseException(RPC_X_BAD_STUB_DATA);
687 memcpy(pStubMsg->Buffer, p, size);
688 pStubMsg->Buffer += size;
692 * NdrConformantString:
694 * What MS calls a ConformantString is, in DCE terminology,
695 * a Varying-Conformant String.
697 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
698 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
699 * into unmarshalled string)
700 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
702 * data: CHARTYPE[maxlen]
704 * ], where CHARTYPE is the appropriate character type (specified externally)
708 /***********************************************************************
709 * NdrConformantStringMarshall [RPCRT4.@]
711 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
712 unsigned char *pszMessage, PFORMAT_STRING pFormat)
716 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
718 if (*pFormat == RPC_FC_C_CSTRING) {
719 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
720 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
723 else if (*pFormat == RPC_FC_C_WSTRING) {
724 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
725 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
729 ERR("Unhandled string type: %#x\n", *pFormat);
730 /* FIXME: raise an exception. */
734 if (pFormat[1] == RPC_FC_STRING_SIZED)
735 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
737 pStubMsg->MaxCount = pStubMsg->ActualCount;
738 pStubMsg->Offset = 0;
739 WriteConformance(pStubMsg);
740 WriteVariance(pStubMsg);
742 size = safe_multiply(esize, pStubMsg->ActualCount);
743 safe_copy_to_buffer(pStubMsg, pszMessage, size); /* the string itself */
746 return NULL; /* is this always right? */
749 /***********************************************************************
750 * NdrConformantStringBufferSize [RPCRT4.@]
752 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
753 unsigned char* pMemory, PFORMAT_STRING pFormat)
757 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
759 SizeConformance(pStubMsg);
760 SizeVariance(pStubMsg);
762 if (*pFormat == RPC_FC_C_CSTRING) {
763 TRACE("string=%s\n", debugstr_a((char*)pMemory));
764 pStubMsg->ActualCount = strlen((char*)pMemory)+1;
767 else if (*pFormat == RPC_FC_C_WSTRING) {
768 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
769 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;
773 ERR("Unhandled string type: %#x\n", *pFormat);
774 /* FIXME: raise an exception */
778 if (pFormat[1] == RPC_FC_STRING_SIZED)
779 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
781 pStubMsg->MaxCount = pStubMsg->ActualCount;
783 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
786 /************************************************************************
787 * NdrConformantStringMemorySize [RPCRT4.@]
789 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
790 PFORMAT_STRING pFormat )
792 ULONG bufsize, memsize, esize, i;
794 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
796 ReadConformance(pStubMsg, NULL);
797 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
799 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
801 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
802 pStubMsg->ActualCount, pStubMsg->MaxCount);
803 RpcRaiseException(RPC_S_INVALID_BOUND);
805 if (pStubMsg->Offset)
807 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
808 RpcRaiseException(RPC_S_INVALID_BOUND);
811 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
812 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
814 ERR("Unhandled string type: %#x\n", *pFormat);
815 /* FIXME: raise an exception */
819 memsize = safe_multiply(esize, pStubMsg->MaxCount);
820 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
822 /* strings must always have null terminating bytes */
825 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
826 RpcRaiseException(RPC_S_INVALID_BOUND);
829 /* verify the buffer is safe to access */
830 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
831 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
833 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
834 pStubMsg->BufferEnd, pStubMsg->Buffer);
835 RpcRaiseException(RPC_X_BAD_STUB_DATA);
838 for (i = bufsize - esize; i < bufsize; i++)
839 if (pStubMsg->Buffer[i] != 0)
841 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
842 i, pStubMsg->Buffer[i]);
843 RpcRaiseException(RPC_S_INVALID_BOUND);
846 safe_buffer_increment(pStubMsg, bufsize);
847 pStubMsg->MemorySize += memsize;
849 return pStubMsg->MemorySize;
852 /************************************************************************
853 * NdrConformantStringUnmarshall [RPCRT4.@]
855 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
856 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
858 ULONG bufsize, memsize, esize, i;
860 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
861 pStubMsg, *ppMemory, pFormat, fMustAlloc);
863 assert(pFormat && ppMemory && pStubMsg);
865 ReadConformance(pStubMsg, NULL);
866 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
868 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
870 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
871 pStubMsg->ActualCount, pStubMsg->MaxCount);
872 RpcRaiseException(RPC_S_INVALID_BOUND);
875 if (pStubMsg->Offset)
877 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
878 RpcRaiseException(RPC_S_INVALID_BOUND);
882 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
883 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
885 ERR("Unhandled string type: %#x\n", *pFormat);
886 /* FIXME: raise an exception */
890 memsize = safe_multiply(esize, pStubMsg->MaxCount);
891 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
893 /* strings must always have null terminating bytes */
896 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
897 RpcRaiseException(RPC_S_INVALID_BOUND);
901 /* verify the buffer is safe to access */
902 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
903 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
905 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
906 pStubMsg->BufferEnd, pStubMsg->Buffer);
907 RpcRaiseException(RPC_X_BAD_STUB_DATA);
911 for (i = bufsize - esize; i < bufsize; i++)
912 if (pStubMsg->Buffer[i] != 0)
914 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
915 i, pStubMsg->Buffer[i]);
916 RpcRaiseException(RPC_S_INVALID_BOUND);
921 *ppMemory = NdrAllocate(pStubMsg, memsize);
924 if (!pStubMsg->IsClient && !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
925 /* if the data in the RPC buffer is big enough, we just point straight
927 *ppMemory = pStubMsg->Buffer;
929 *ppMemory = NdrAllocate(pStubMsg, memsize);
932 if (*ppMemory == pStubMsg->Buffer)
933 safe_buffer_increment(pStubMsg, bufsize);
935 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
937 if (*pFormat == RPC_FC_C_CSTRING) {
938 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
940 else if (*pFormat == RPC_FC_C_WSTRING) {
941 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
944 return NULL; /* FIXME: is this always right? */
947 /***********************************************************************
948 * NdrNonConformantStringMarshall [RPCRT4.@]
950 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
951 unsigned char *pMemory,
952 PFORMAT_STRING pFormat)
954 ULONG esize, size, maxsize;
956 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
958 maxsize = *(USHORT *)&pFormat[2];
960 if (*pFormat == RPC_FC_CSTRING)
963 const char *str = (const char *)pMemory;
964 for (i = 0; i < maxsize && *str; i++, str++)
966 TRACE("string=%s\n", debugstr_an(str, i));
967 pStubMsg->ActualCount = i + 1;
970 else if (*pFormat == RPC_FC_WSTRING)
973 const WCHAR *str = (const WCHAR *)pMemory;
974 for (i = 0; i < maxsize && *str; i++, str++)
976 TRACE("string=%s\n", debugstr_wn(str, i));
977 pStubMsg->ActualCount = i + 1;
982 ERR("Unhandled string type: %#x\n", *pFormat);
983 RpcRaiseException(RPC_X_BAD_STUB_DATA);
986 pStubMsg->Offset = 0;
987 WriteVariance(pStubMsg);
989 size = safe_multiply(esize, pStubMsg->ActualCount);
990 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
995 /***********************************************************************
996 * NdrNonConformantStringUnmarshall [RPCRT4.@]
998 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
999 unsigned char **ppMemory,
1000 PFORMAT_STRING pFormat,
1001 unsigned char fMustAlloc)
1003 ULONG bufsize, memsize, esize, i, maxsize;
1005 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
1006 pStubMsg, *ppMemory, pFormat, fMustAlloc);
1008 maxsize = *(USHORT *)&pFormat[2];
1010 ReadVariance(pStubMsg, NULL, maxsize);
1011 if (pStubMsg->Offset)
1013 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
1014 RpcRaiseException(RPC_S_INVALID_BOUND);
1017 if (*pFormat == RPC_FC_CSTRING) esize = 1;
1018 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
1021 ERR("Unhandled string type: %#x\n", *pFormat);
1022 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1025 memsize = esize * maxsize;
1026 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
1028 if (bufsize < esize)
1030 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
1031 RpcRaiseException(RPC_S_INVALID_BOUND);
1035 /* verify the buffer is safe to access */
1036 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
1037 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
1039 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
1040 pStubMsg->BufferEnd, pStubMsg->Buffer);
1041 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1045 /* strings must always have null terminating bytes */
1046 for (i = bufsize - esize; i < bufsize; i++)
1047 if (pStubMsg->Buffer[i] != 0)
1049 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
1050 i, pStubMsg->Buffer[i]);
1051 RpcRaiseException(RPC_S_INVALID_BOUND);
1054 if (fMustAlloc || !*ppMemory)
1055 *ppMemory = NdrAllocate(pStubMsg, memsize);
1057 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
1059 if (*pFormat == RPC_FC_CSTRING) {
1060 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
1062 else if (*pFormat == RPC_FC_WSTRING) {
1063 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
1069 /***********************************************************************
1070 * NdrNonConformantStringBufferSize [RPCRT4.@]
1072 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1073 unsigned char *pMemory,
1074 PFORMAT_STRING pFormat)
1076 ULONG esize, maxsize;
1078 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
1080 maxsize = *(USHORT *)&pFormat[2];
1082 SizeVariance(pStubMsg);
1084 if (*pFormat == RPC_FC_CSTRING)
1087 const char *str = (const char *)pMemory;
1088 for (i = 0; i < maxsize && *str; i++, str++)
1090 TRACE("string=%s\n", debugstr_an(str, i));
1091 pStubMsg->ActualCount = i + 1;
1094 else if (*pFormat == RPC_FC_WSTRING)
1097 const WCHAR *str = (const WCHAR *)pMemory;
1098 for (i = 0; i < maxsize && *str; i++, str++)
1100 TRACE("string=%s\n", debugstr_wn(str, i));
1101 pStubMsg->ActualCount = i + 1;
1106 ERR("Unhandled string type: %#x\n", *pFormat);
1107 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1110 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
1113 /***********************************************************************
1114 * NdrNonConformantStringMemorySize [RPCRT4.@]
1116 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1117 PFORMAT_STRING pFormat)
1119 ULONG bufsize, memsize, esize, i, maxsize;
1121 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
1123 maxsize = *(USHORT *)&pFormat[2];
1125 ReadVariance(pStubMsg, NULL, maxsize);
1127 if (pStubMsg->Offset)
1129 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
1130 RpcRaiseException(RPC_S_INVALID_BOUND);
1133 if (*pFormat == RPC_FC_CSTRING) esize = 1;
1134 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
1137 ERR("Unhandled string type: %#x\n", *pFormat);
1138 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1141 memsize = esize * maxsize;
1142 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
1144 /* strings must always have null terminating bytes */
1145 if (bufsize < esize)
1147 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
1148 RpcRaiseException(RPC_S_INVALID_BOUND);
1151 /* verify the buffer is safe to access */
1152 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
1153 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
1155 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
1156 pStubMsg->BufferEnd, pStubMsg->Buffer);
1157 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1160 for (i = bufsize - esize; i < bufsize; i++)
1161 if (pStubMsg->Buffer[i] != 0)
1163 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
1164 i, pStubMsg->Buffer[i]);
1165 RpcRaiseException(RPC_S_INVALID_BOUND);
1168 safe_buffer_increment(pStubMsg, bufsize);
1169 pStubMsg->MemorySize += memsize;
1171 return pStubMsg->MemorySize;
1174 static inline void dump_pointer_attr(unsigned char attr)
1176 if (attr & RPC_FC_P_ALLOCALLNODES)
1177 TRACE(" RPC_FC_P_ALLOCALLNODES");
1178 if (attr & RPC_FC_P_DONTFREE)
1179 TRACE(" RPC_FC_P_DONTFREE");
1180 if (attr & RPC_FC_P_ONSTACK)
1181 TRACE(" RPC_FC_P_ONSTACK");
1182 if (attr & RPC_FC_P_SIMPLEPOINTER)
1183 TRACE(" RPC_FC_P_SIMPLEPOINTER");
1184 if (attr & RPC_FC_P_DEREF)
1185 TRACE(" RPC_FC_P_DEREF");
1189 /***********************************************************************
1190 * PointerMarshall [internal]
1192 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1193 unsigned char *Buffer,
1194 unsigned char *Pointer,
1195 PFORMAT_STRING pFormat)
1197 unsigned type = pFormat[0], attr = pFormat[1];
1198 PFORMAT_STRING desc;
1201 int pointer_needs_marshaling;
1203 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
1204 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1206 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1207 else desc = pFormat + *(const SHORT*)pFormat;
1210 case RPC_FC_RP: /* ref pointer (always non-null) */
1213 ERR("NULL ref pointer is not allowed\n");
1214 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1216 pointer_needs_marshaling = 1;
1218 case RPC_FC_UP: /* unique pointer */
1219 case RPC_FC_OP: /* object pointer - same as unique here */
1221 pointer_needs_marshaling = 1;
1223 pointer_needs_marshaling = 0;
1224 pointer_id = (ULONG)Pointer;
1225 TRACE("writing 0x%08x to buffer\n", pointer_id);
1226 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
1229 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
1230 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
1231 TRACE("writing 0x%08x to buffer\n", pointer_id);
1232 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
1235 FIXME("unhandled ptr type=%02x\n", type);
1236 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1240 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
1242 if (pointer_needs_marshaling) {
1243 if (attr & RPC_FC_P_DEREF) {
1244 Pointer = *(unsigned char**)Pointer;
1245 TRACE("deref => %p\n", Pointer);
1247 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1248 if (m) m(pStubMsg, Pointer, desc);
1249 else FIXME("no marshaller for data type=%02x\n", *desc);
1252 STD_OVERFLOW_CHECK(pStubMsg);
1255 /***********************************************************************
1256 * PointerUnmarshall [internal]
1258 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1259 unsigned char *Buffer,
1260 unsigned char **pPointer,
1261 unsigned char *pSrcPointer,
1262 PFORMAT_STRING pFormat,
1263 unsigned char fMustAlloc)
1265 unsigned type = pFormat[0], attr = pFormat[1];
1266 PFORMAT_STRING desc;
1268 DWORD pointer_id = 0;
1269 int pointer_needs_unmarshaling;
1271 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
1272 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1274 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1275 else desc = pFormat + *(const SHORT*)pFormat;
1278 case RPC_FC_RP: /* ref pointer (always non-null) */
1279 pointer_needs_unmarshaling = 1;
1281 case RPC_FC_UP: /* unique pointer */
1282 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1283 TRACE("pointer_id is 0x%08x\n", pointer_id);
1285 pointer_needs_unmarshaling = 1;
1288 pointer_needs_unmarshaling = 0;
1291 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1292 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1293 TRACE("pointer_id is 0x%08x\n", pointer_id);
1294 if (!fMustAlloc && pSrcPointer)
1296 FIXME("free object pointer %p\n", pSrcPointer);
1300 pointer_needs_unmarshaling = 1;
1302 pointer_needs_unmarshaling = 0;
1305 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1306 TRACE("pointer_id is 0x%08x\n", pointer_id);
1307 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
1308 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
1311 FIXME("unhandled ptr type=%02x\n", type);
1312 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1316 if (pointer_needs_unmarshaling) {
1317 unsigned char *base_ptr_val = *pPointer;
1318 unsigned char **current_ptr = pPointer;
1319 if (pStubMsg->IsClient) {
1321 /* if we aren't forcing allocation of memory then try to use the existing
1322 * (source) pointer to unmarshall the data into so that [in,out]
1323 * parameters behave correctly. it doesn't matter if the parameter is
1324 * [out] only since in that case the pointer will be NULL. we force
1325 * allocation when the source pointer is NULL here instead of in the type
1326 * unmarshalling routine for the benefit of the deref code below */
1329 TRACE("setting *pPointer to %p\n", pSrcPointer);
1330 *pPointer = base_ptr_val = pSrcPointer;
1336 /* the memory in a stub is never initialised, so we have to work out here
1337 * whether we have to initialise it so we can use the optimisation of
1338 * setting the pointer to the buffer, if possible, or set fMustAlloc to
1340 if (attr & RPC_FC_P_DEREF) {
1343 base_ptr_val = NULL;
1344 *current_ptr = NULL;
1348 if (attr & RPC_FC_P_ALLOCALLNODES)
1349 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
1351 if (attr & RPC_FC_P_DEREF) {
1353 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
1354 *pPointer = base_ptr_val;
1355 current_ptr = (unsigned char **)base_ptr_val;
1357 current_ptr = *(unsigned char***)current_ptr;
1358 TRACE("deref => %p\n", current_ptr);
1359 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
1361 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1362 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
1363 else FIXME("no unmarshaller for data type=%02x\n", *desc);
1365 if (type == RPC_FC_FP)
1366 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
1370 TRACE("pointer=%p\n", *pPointer);
1373 /***********************************************************************
1374 * PointerBufferSize [internal]
1376 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1377 unsigned char *Pointer,
1378 PFORMAT_STRING pFormat)
1380 unsigned type = pFormat[0], attr = pFormat[1];
1381 PFORMAT_STRING desc;
1383 int pointer_needs_sizing;
1386 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1387 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1389 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1390 else desc = pFormat + *(const SHORT*)pFormat;
1393 case RPC_FC_RP: /* ref pointer (always non-null) */
1396 ERR("NULL ref pointer is not allowed\n");
1397 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1402 /* NULL pointer has no further representation */
1407 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1408 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1409 if (!pointer_needs_sizing)
1413 FIXME("unhandled ptr type=%02x\n", type);
1414 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1418 if (attr & RPC_FC_P_DEREF) {
1419 Pointer = *(unsigned char**)Pointer;
1420 TRACE("deref => %p\n", Pointer);
1423 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1424 if (m) m(pStubMsg, Pointer, desc);
1425 else FIXME("no buffersizer for data type=%02x\n", *desc);
1428 /***********************************************************************
1429 * PointerMemorySize [internal]
1431 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1432 unsigned char *Buffer,
1433 PFORMAT_STRING pFormat)
1435 unsigned type = pFormat[0], attr = pFormat[1];
1436 PFORMAT_STRING desc;
1438 DWORD pointer_id = 0;
1439 int pointer_needs_sizing;
1441 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1442 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1444 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1445 else desc = pFormat + *(const SHORT*)pFormat;
1448 case RPC_FC_RP: /* ref pointer (always non-null) */
1449 pointer_needs_sizing = 1;
1451 case RPC_FC_UP: /* unique pointer */
1452 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1453 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1454 TRACE("pointer_id is 0x%08x\n", pointer_id);
1456 pointer_needs_sizing = 1;
1458 pointer_needs_sizing = 0;
1463 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1464 TRACE("pointer_id is 0x%08x\n", pointer_id);
1465 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1466 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1470 FIXME("unhandled ptr type=%02x\n", type);
1471 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1475 if (attr & RPC_FC_P_DEREF) {
1479 if (pointer_needs_sizing) {
1480 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1481 if (m) m(pStubMsg, desc);
1482 else FIXME("no memorysizer for data type=%02x\n", *desc);
1485 return pStubMsg->MemorySize;
1488 /***********************************************************************
1489 * PointerFree [internal]
1491 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1492 unsigned char *Pointer,
1493 PFORMAT_STRING pFormat)
1495 unsigned type = pFormat[0], attr = pFormat[1];
1496 PFORMAT_STRING desc;
1498 unsigned char *current_pointer = Pointer;
1500 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1501 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1502 if (attr & RPC_FC_P_DONTFREE) return;
1504 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1505 else desc = pFormat + *(const SHORT*)pFormat;
1507 if (!Pointer) return;
1509 if (type == RPC_FC_FP) {
1510 int pointer_needs_freeing = NdrFullPointerFree(
1511 pStubMsg->FullPtrXlatTables, Pointer);
1512 if (!pointer_needs_freeing)
1516 if (attr & RPC_FC_P_DEREF) {
1517 current_pointer = *(unsigned char**)Pointer;
1518 TRACE("deref => %p\n", current_pointer);
1521 m = NdrFreer[*desc & NDR_TABLE_MASK];
1522 if (m) m(pStubMsg, current_pointer, desc);
1524 /* this check stops us from trying to free buffer memory. we don't have to
1525 * worry about clients, since they won't call this function.
1526 * we don't have to check for the buffer being reallocated because
1527 * BufferStart and BufferEnd won't be reset when allocating memory for
1528 * sending the response. we don't have to check for the new buffer here as
1529 * it won't be used a type memory, only for buffer memory */
1530 if (Pointer >= (unsigned char *)pStubMsg->BufferStart &&
1531 Pointer < (unsigned char *)pStubMsg->BufferEnd)
1534 if (attr & RPC_FC_P_ONSTACK) {
1535 TRACE("not freeing stack ptr %p\n", Pointer);
1538 TRACE("freeing %p\n", Pointer);
1539 NdrFree(pStubMsg, Pointer);
1542 TRACE("not freeing %p\n", Pointer);
1545 /***********************************************************************
1546 * EmbeddedPointerMarshall
1548 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1549 unsigned char *pMemory,
1550 PFORMAT_STRING pFormat)
1552 unsigned char *Mark = pStubMsg->BufferMark;
1553 unsigned rep, count, stride;
1555 unsigned char *saved_buffer = NULL;
1557 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1559 if (*pFormat != RPC_FC_PP) return NULL;
1562 if (pStubMsg->PointerBufferMark)
1564 saved_buffer = pStubMsg->Buffer;
1565 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1566 pStubMsg->PointerBufferMark = NULL;
1569 while (pFormat[0] != RPC_FC_END) {
1570 switch (pFormat[0]) {
1572 FIXME("unknown repeat type %d\n", pFormat[0]);
1573 case RPC_FC_NO_REPEAT:
1579 case RPC_FC_FIXED_REPEAT:
1580 rep = *(const WORD*)&pFormat[2];
1581 stride = *(const WORD*)&pFormat[4];
1582 count = *(const WORD*)&pFormat[8];
1585 case RPC_FC_VARIABLE_REPEAT:
1586 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1587 stride = *(const WORD*)&pFormat[2];
1588 count = *(const WORD*)&pFormat[6];
1592 for (i = 0; i < rep; i++) {
1593 PFORMAT_STRING info = pFormat;
1594 unsigned char *membase = pMemory + (i * stride);
1595 unsigned char *bufbase = Mark + (i * stride);
1598 for (u=0; u<count; u++,info+=8) {
1599 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1600 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1601 unsigned char *saved_memory = pStubMsg->Memory;
1603 pStubMsg->Memory = pMemory;
1604 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1605 pStubMsg->Memory = saved_memory;
1608 pFormat += 8 * count;
1613 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1614 pStubMsg->Buffer = saved_buffer;
1617 STD_OVERFLOW_CHECK(pStubMsg);
1622 /***********************************************************************
1623 * EmbeddedPointerUnmarshall
1625 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1626 unsigned char *pDstMemoryPtrs,
1627 unsigned char *pSrcMemoryPtrs,
1628 PFORMAT_STRING pFormat,
1629 unsigned char fMustAlloc)
1631 unsigned char *Mark = pStubMsg->BufferMark;
1632 unsigned rep, count, stride;
1634 unsigned char *saved_buffer = NULL;
1636 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstMemoryPtrs, pSrcMemoryPtrs, pFormat, fMustAlloc);
1638 if (*pFormat != RPC_FC_PP) return NULL;
1641 if (pStubMsg->PointerBufferMark)
1643 saved_buffer = pStubMsg->Buffer;
1644 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1645 pStubMsg->PointerBufferMark = NULL;
1648 while (pFormat[0] != RPC_FC_END) {
1649 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1650 switch (pFormat[0]) {
1652 FIXME("unknown repeat type %d\n", pFormat[0]);
1653 case RPC_FC_NO_REPEAT:
1659 case RPC_FC_FIXED_REPEAT:
1660 rep = *(const WORD*)&pFormat[2];
1661 stride = *(const WORD*)&pFormat[4];
1662 count = *(const WORD*)&pFormat[8];
1665 case RPC_FC_VARIABLE_REPEAT:
1666 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1667 stride = *(const WORD*)&pFormat[2];
1668 count = *(const WORD*)&pFormat[6];
1672 for (i = 0; i < rep; i++) {
1673 PFORMAT_STRING info = pFormat;
1674 unsigned char *memdstbase = pDstMemoryPtrs + (i * stride);
1675 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1676 unsigned char *bufbase = Mark + (i * stride);
1679 for (u=0; u<count; u++,info+=8) {
1680 unsigned char **memdstptr = (unsigned char **)(memdstbase + *(const SHORT*)&info[0]);
1681 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1682 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1683 PointerUnmarshall(pStubMsg, bufptr, memdstptr, *memsrcptr, info+4, fMustAlloc);
1686 pFormat += 8 * count;
1691 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1692 pStubMsg->Buffer = saved_buffer;
1698 /***********************************************************************
1699 * EmbeddedPointerBufferSize
1701 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1702 unsigned char *pMemory,
1703 PFORMAT_STRING pFormat)
1705 unsigned rep, count, stride;
1707 ULONG saved_buffer_length = 0;
1709 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1711 if (pStubMsg->IgnoreEmbeddedPointers) return;
1713 if (*pFormat != RPC_FC_PP) return;
1716 if (pStubMsg->PointerLength)
1718 saved_buffer_length = pStubMsg->BufferLength;
1719 pStubMsg->BufferLength = pStubMsg->PointerLength;
1720 pStubMsg->PointerLength = 0;
1723 while (pFormat[0] != RPC_FC_END) {
1724 switch (pFormat[0]) {
1726 FIXME("unknown repeat type %d\n", pFormat[0]);
1727 case RPC_FC_NO_REPEAT:
1733 case RPC_FC_FIXED_REPEAT:
1734 rep = *(const WORD*)&pFormat[2];
1735 stride = *(const WORD*)&pFormat[4];
1736 count = *(const WORD*)&pFormat[8];
1739 case RPC_FC_VARIABLE_REPEAT:
1740 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1741 stride = *(const WORD*)&pFormat[2];
1742 count = *(const WORD*)&pFormat[6];
1746 for (i = 0; i < rep; i++) {
1747 PFORMAT_STRING info = pFormat;
1748 unsigned char *membase = pMemory + (i * stride);
1751 for (u=0; u<count; u++,info+=8) {
1752 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1753 unsigned char *saved_memory = pStubMsg->Memory;
1755 pStubMsg->Memory = pMemory;
1756 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1757 pStubMsg->Memory = saved_memory;
1760 pFormat += 8 * count;
1763 if (saved_buffer_length)
1765 pStubMsg->PointerLength = pStubMsg->BufferLength;
1766 pStubMsg->BufferLength = saved_buffer_length;
1770 /***********************************************************************
1771 * EmbeddedPointerMemorySize [internal]
1773 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1774 PFORMAT_STRING pFormat)
1776 unsigned char *Mark = pStubMsg->BufferMark;
1777 unsigned rep, count, stride;
1779 unsigned char *saved_buffer = NULL;
1781 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1783 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1785 if (pStubMsg->PointerBufferMark)
1787 saved_buffer = pStubMsg->Buffer;
1788 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1789 pStubMsg->PointerBufferMark = NULL;
1792 if (*pFormat != RPC_FC_PP) return 0;
1795 while (pFormat[0] != RPC_FC_END) {
1796 switch (pFormat[0]) {
1798 FIXME("unknown repeat type %d\n", pFormat[0]);
1799 case RPC_FC_NO_REPEAT:
1805 case RPC_FC_FIXED_REPEAT:
1806 rep = *(const WORD*)&pFormat[2];
1807 stride = *(const WORD*)&pFormat[4];
1808 count = *(const WORD*)&pFormat[8];
1811 case RPC_FC_VARIABLE_REPEAT:
1812 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1813 stride = *(const WORD*)&pFormat[2];
1814 count = *(const WORD*)&pFormat[6];
1818 for (i = 0; i < rep; i++) {
1819 PFORMAT_STRING info = pFormat;
1820 unsigned char *bufbase = Mark + (i * stride);
1822 for (u=0; u<count; u++,info+=8) {
1823 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1824 PointerMemorySize(pStubMsg, bufptr, info+4);
1827 pFormat += 8 * count;
1832 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1833 pStubMsg->Buffer = saved_buffer;
1839 /***********************************************************************
1840 * EmbeddedPointerFree [internal]
1842 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1843 unsigned char *pMemory,
1844 PFORMAT_STRING pFormat)
1846 unsigned rep, count, stride;
1849 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1850 if (*pFormat != RPC_FC_PP) return;
1853 while (pFormat[0] != RPC_FC_END) {
1854 switch (pFormat[0]) {
1856 FIXME("unknown repeat type %d\n", pFormat[0]);
1857 case RPC_FC_NO_REPEAT:
1863 case RPC_FC_FIXED_REPEAT:
1864 rep = *(const WORD*)&pFormat[2];
1865 stride = *(const WORD*)&pFormat[4];
1866 count = *(const WORD*)&pFormat[8];
1869 case RPC_FC_VARIABLE_REPEAT:
1870 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1871 stride = *(const WORD*)&pFormat[2];
1872 count = *(const WORD*)&pFormat[6];
1876 for (i = 0; i < rep; i++) {
1877 PFORMAT_STRING info = pFormat;
1878 unsigned char *membase = pMemory + (i * stride);
1881 for (u=0; u<count; u++,info+=8) {
1882 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1883 unsigned char *saved_memory = pStubMsg->Memory;
1885 pStubMsg->Memory = pMemory;
1886 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1887 pStubMsg->Memory = saved_memory;
1890 pFormat += 8 * count;
1894 /***********************************************************************
1895 * NdrPointerMarshall [RPCRT4.@]
1897 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1898 unsigned char *pMemory,
1899 PFORMAT_STRING pFormat)
1901 unsigned char *Buffer;
1903 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1905 /* incremement the buffer here instead of in PointerMarshall,
1906 * as that is used by embedded pointers which already handle the incrementing
1907 * the buffer, and shouldn't write any additional pointer data to the wire */
1908 if (*pFormat != RPC_FC_RP)
1910 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
1911 Buffer = pStubMsg->Buffer;
1912 safe_buffer_increment(pStubMsg, 4);
1915 Buffer = pStubMsg->Buffer;
1917 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1922 /***********************************************************************
1923 * NdrPointerUnmarshall [RPCRT4.@]
1925 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1926 unsigned char **ppMemory,
1927 PFORMAT_STRING pFormat,
1928 unsigned char fMustAlloc)
1930 unsigned char *Buffer;
1932 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1934 /* incremement the buffer here instead of in PointerUnmarshall,
1935 * as that is used by embedded pointers which already handle the incrementing
1936 * the buffer, and shouldn't read any additional pointer data from the
1938 if (*pFormat != RPC_FC_RP)
1940 ALIGN_POINTER(pStubMsg->Buffer, 4);
1941 Buffer = pStubMsg->Buffer;
1942 safe_buffer_increment(pStubMsg, 4);
1945 Buffer = pStubMsg->Buffer;
1947 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1952 /***********************************************************************
1953 * NdrPointerBufferSize [RPCRT4.@]
1955 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1956 unsigned char *pMemory,
1957 PFORMAT_STRING pFormat)
1959 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1961 /* incremement the buffer length here instead of in PointerBufferSize,
1962 * as that is used by embedded pointers which already handle the buffer
1963 * length, and shouldn't write anything more to the wire */
1964 if (*pFormat != RPC_FC_RP)
1966 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1967 safe_buffer_length_increment(pStubMsg, 4);
1970 PointerBufferSize(pStubMsg, pMemory, pFormat);
1973 /***********************************************************************
1974 * NdrPointerMemorySize [RPCRT4.@]
1976 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1977 PFORMAT_STRING pFormat)
1979 /* unsigned size = *(LPWORD)(pFormat+2); */
1980 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1981 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1985 /***********************************************************************
1986 * NdrPointerFree [RPCRT4.@]
1988 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1989 unsigned char *pMemory,
1990 PFORMAT_STRING pFormat)
1992 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1993 PointerFree(pStubMsg, pMemory, pFormat);
1996 /***********************************************************************
1997 * NdrSimpleTypeMarshall [RPCRT4.@]
1999 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
2000 unsigned char FormatChar )
2002 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
2005 /***********************************************************************
2006 * NdrSimpleTypeUnmarshall [RPCRT4.@]
2008 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
2009 unsigned char FormatChar )
2011 NdrBaseTypeUnmarshall(pStubMsg, &pMemory, &FormatChar, 0);
2014 /***********************************************************************
2015 * NdrSimpleStructMarshall [RPCRT4.@]
2017 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2018 unsigned char *pMemory,
2019 PFORMAT_STRING pFormat)
2021 unsigned size = *(const WORD*)(pFormat+2);
2022 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2024 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
2026 pStubMsg->BufferMark = pStubMsg->Buffer;
2027 safe_copy_to_buffer(pStubMsg, pMemory, size);
2029 if (pFormat[0] != RPC_FC_STRUCT)
2030 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
2035 /***********************************************************************
2036 * NdrSimpleStructUnmarshall [RPCRT4.@]
2038 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2039 unsigned char **ppMemory,
2040 PFORMAT_STRING pFormat,
2041 unsigned char fMustAlloc)
2043 unsigned size = *(const WORD*)(pFormat+2);
2044 unsigned char *saved_buffer;
2045 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2047 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2050 *ppMemory = NdrAllocate(pStubMsg, size);
2053 if (!pStubMsg->IsClient && !*ppMemory)
2054 /* for servers, we just point straight into the RPC buffer */
2055 *ppMemory = pStubMsg->Buffer;
2058 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
2059 safe_buffer_increment(pStubMsg, size);
2060 if (pFormat[0] == RPC_FC_PSTRUCT)
2061 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
2063 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2064 if (*ppMemory != saved_buffer)
2065 memcpy(*ppMemory, saved_buffer, size);
2070 /***********************************************************************
2071 * NdrSimpleStructBufferSize [RPCRT4.@]
2073 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2074 unsigned char *pMemory,
2075 PFORMAT_STRING pFormat)
2077 unsigned size = *(const WORD*)(pFormat+2);
2078 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2080 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2082 safe_buffer_length_increment(pStubMsg, size);
2083 if (pFormat[0] != RPC_FC_STRUCT)
2084 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
2087 /***********************************************************************
2088 * NdrSimpleStructMemorySize [RPCRT4.@]
2090 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2091 PFORMAT_STRING pFormat)
2093 unsigned short size = *(const WORD *)(pFormat+2);
2095 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2097 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2098 pStubMsg->MemorySize += size;
2099 safe_buffer_increment(pStubMsg, size);
2101 if (pFormat[0] != RPC_FC_STRUCT)
2102 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
2103 return pStubMsg->MemorySize;
2106 /***********************************************************************
2107 * NdrSimpleStructFree [RPCRT4.@]
2109 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2110 unsigned char *pMemory,
2111 PFORMAT_STRING pFormat)
2113 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2114 if (pFormat[0] != RPC_FC_STRUCT)
2115 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
2119 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE *pStubMsg,
2120 PFORMAT_STRING pFormat)
2124 case RPC_FC_PSTRUCT:
2125 case RPC_FC_CSTRUCT:
2126 case RPC_FC_BOGUS_STRUCT:
2127 case RPC_FC_SMFARRAY:
2128 case RPC_FC_SMVARRAY:
2129 case RPC_FC_CSTRING:
2130 return *(const WORD*)&pFormat[2];
2131 case RPC_FC_USER_MARSHAL:
2132 return *(const WORD*)&pFormat[4];
2133 case RPC_FC_NON_ENCAPSULATED_UNION:
2135 if (pStubMsg->fHasNewCorrDesc)
2140 pFormat += *(const SHORT*)pFormat;
2141 return *(const SHORT*)pFormat;
2143 return sizeof(void *);
2144 case RPC_FC_WSTRING:
2145 return *(const WORD*)&pFormat[2] * 2;
2147 FIXME("unhandled embedded type %02x\n", *pFormat);
2153 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2154 PFORMAT_STRING pFormat)
2156 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2160 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2164 return m(pStubMsg, pFormat);
2168 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2169 unsigned char *pMemory,
2170 PFORMAT_STRING pFormat,
2171 PFORMAT_STRING pPointer)
2173 PFORMAT_STRING desc;
2177 while (*pFormat != RPC_FC_END) {
2183 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2184 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2190 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2191 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2197 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2198 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2202 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2203 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2206 case RPC_FC_POINTER:
2208 unsigned char *saved_buffer;
2209 int pointer_buffer_mark_set = 0;
2210 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2211 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
2212 saved_buffer = pStubMsg->Buffer;
2213 if (pStubMsg->PointerBufferMark)
2215 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2216 pStubMsg->PointerBufferMark = NULL;
2217 pointer_buffer_mark_set = 1;
2220 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2221 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2222 if (pointer_buffer_mark_set)
2224 STD_OVERFLOW_CHECK(pStubMsg);
2225 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2226 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2228 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2229 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2230 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2232 pStubMsg->Buffer = saved_buffer + 4;
2238 case RPC_FC_ALIGNM4:
2239 ALIGN_POINTER(pMemory, 4);
2241 case RPC_FC_ALIGNM8:
2242 ALIGN_POINTER(pMemory, 8);
2244 case RPC_FC_STRUCTPAD1:
2245 case RPC_FC_STRUCTPAD2:
2246 case RPC_FC_STRUCTPAD3:
2247 case RPC_FC_STRUCTPAD4:
2248 case RPC_FC_STRUCTPAD5:
2249 case RPC_FC_STRUCTPAD6:
2250 case RPC_FC_STRUCTPAD7:
2251 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2253 case RPC_FC_EMBEDDED_COMPLEX:
2254 pMemory += pFormat[1];
2256 desc = pFormat + *(const SHORT*)pFormat;
2257 size = EmbeddedComplexSize(pStubMsg, desc);
2258 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
2259 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2262 /* for some reason interface pointers aren't generated as
2263 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2264 * they still need the derefencing treatment that pointers are
2266 if (*desc == RPC_FC_IP)
2267 m(pStubMsg, *(unsigned char **)pMemory, desc);
2269 m(pStubMsg, pMemory, desc);
2271 else FIXME("no marshaller for embedded type %02x\n", *desc);
2278 FIXME("unhandled format 0x%02x\n", *pFormat);
2286 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2287 unsigned char *pMemory,
2288 PFORMAT_STRING pFormat,
2289 PFORMAT_STRING pPointer)
2291 PFORMAT_STRING desc;
2295 while (*pFormat != RPC_FC_END) {
2301 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2302 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2308 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2309 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2315 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2316 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2320 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2321 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2324 case RPC_FC_POINTER:
2326 unsigned char *saved_buffer;
2327 int pointer_buffer_mark_set = 0;
2328 TRACE("pointer => %p\n", pMemory);
2329 ALIGN_POINTER(pStubMsg->Buffer, 4);
2330 saved_buffer = pStubMsg->Buffer;
2331 if (pStubMsg->PointerBufferMark)
2333 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2334 pStubMsg->PointerBufferMark = NULL;
2335 pointer_buffer_mark_set = 1;
2338 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2340 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, TRUE);
2341 if (pointer_buffer_mark_set)
2343 STD_OVERFLOW_CHECK(pStubMsg);
2344 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2345 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2347 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2348 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2349 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2351 pStubMsg->Buffer = saved_buffer + 4;
2357 case RPC_FC_ALIGNM4:
2358 ALIGN_POINTER_CLEAR(pMemory, 4);
2360 case RPC_FC_ALIGNM8:
2361 ALIGN_POINTER_CLEAR(pMemory, 8);
2363 case RPC_FC_STRUCTPAD1:
2364 case RPC_FC_STRUCTPAD2:
2365 case RPC_FC_STRUCTPAD3:
2366 case RPC_FC_STRUCTPAD4:
2367 case RPC_FC_STRUCTPAD5:
2368 case RPC_FC_STRUCTPAD6:
2369 case RPC_FC_STRUCTPAD7:
2370 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2371 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2373 case RPC_FC_EMBEDDED_COMPLEX:
2374 pMemory += pFormat[1];
2376 desc = pFormat + *(const SHORT*)pFormat;
2377 size = EmbeddedComplexSize(pStubMsg, desc);
2378 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2379 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2380 memset(pMemory, 0, size); /* just in case */
2383 /* for some reason interface pointers aren't generated as
2384 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2385 * they still need the derefencing treatment that pointers are
2387 if (*desc == RPC_FC_IP)
2388 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2390 m(pStubMsg, &pMemory, desc, FALSE);
2392 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2399 FIXME("unhandled format %d\n", *pFormat);
2407 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2408 unsigned char *pMemory,
2409 PFORMAT_STRING pFormat,
2410 PFORMAT_STRING pPointer)
2412 PFORMAT_STRING desc;
2416 while (*pFormat != RPC_FC_END) {
2422 safe_buffer_length_increment(pStubMsg, 1);
2428 safe_buffer_length_increment(pStubMsg, 2);
2434 safe_buffer_length_increment(pStubMsg, 4);
2438 safe_buffer_length_increment(pStubMsg, 8);
2441 case RPC_FC_POINTER:
2442 if (!pStubMsg->IgnoreEmbeddedPointers)
2444 int saved_buffer_length = pStubMsg->BufferLength;
2445 pStubMsg->BufferLength = pStubMsg->PointerLength;
2446 pStubMsg->PointerLength = 0;
2447 if(!pStubMsg->BufferLength)
2448 ERR("BufferLength == 0??\n");
2449 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2450 pStubMsg->PointerLength = pStubMsg->BufferLength;
2451 pStubMsg->BufferLength = saved_buffer_length;
2453 safe_buffer_length_increment(pStubMsg, 4);
2457 case RPC_FC_ALIGNM4:
2458 ALIGN_POINTER(pMemory, 4);
2460 case RPC_FC_ALIGNM8:
2461 ALIGN_POINTER(pMemory, 8);
2463 case RPC_FC_STRUCTPAD1:
2464 case RPC_FC_STRUCTPAD2:
2465 case RPC_FC_STRUCTPAD3:
2466 case RPC_FC_STRUCTPAD4:
2467 case RPC_FC_STRUCTPAD5:
2468 case RPC_FC_STRUCTPAD6:
2469 case RPC_FC_STRUCTPAD7:
2470 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2472 case RPC_FC_EMBEDDED_COMPLEX:
2473 pMemory += pFormat[1];
2475 desc = pFormat + *(const SHORT*)pFormat;
2476 size = EmbeddedComplexSize(pStubMsg, desc);
2477 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2480 /* for some reason interface pointers aren't generated as
2481 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2482 * they still need the derefencing treatment that pointers are
2484 if (*desc == RPC_FC_IP)
2485 m(pStubMsg, *(unsigned char **)pMemory, desc);
2487 m(pStubMsg, pMemory, desc);
2489 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2496 FIXME("unhandled format 0x%02x\n", *pFormat);
2504 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2505 unsigned char *pMemory,
2506 PFORMAT_STRING pFormat,
2507 PFORMAT_STRING pPointer)
2509 PFORMAT_STRING desc;
2513 while (*pFormat != RPC_FC_END) {
2534 case RPC_FC_POINTER:
2535 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
2539 case RPC_FC_ALIGNM4:
2540 ALIGN_POINTER(pMemory, 4);
2542 case RPC_FC_ALIGNM8:
2543 ALIGN_POINTER(pMemory, 8);
2545 case RPC_FC_STRUCTPAD1:
2546 case RPC_FC_STRUCTPAD2:
2547 case RPC_FC_STRUCTPAD3:
2548 case RPC_FC_STRUCTPAD4:
2549 case RPC_FC_STRUCTPAD5:
2550 case RPC_FC_STRUCTPAD6:
2551 case RPC_FC_STRUCTPAD7:
2552 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2554 case RPC_FC_EMBEDDED_COMPLEX:
2555 pMemory += pFormat[1];
2557 desc = pFormat + *(const SHORT*)pFormat;
2558 size = EmbeddedComplexSize(pStubMsg, desc);
2559 m = NdrFreer[*desc & NDR_TABLE_MASK];
2562 /* for some reason interface pointers aren't generated as
2563 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2564 * they still need the derefencing treatment that pointers are
2566 if (*desc == RPC_FC_IP)
2567 m(pStubMsg, *(unsigned char **)pMemory, desc);
2569 m(pStubMsg, pMemory, desc);
2571 else FIXME("no freer for embedded type %02x\n", *desc);
2578 FIXME("unhandled format 0x%02x\n", *pFormat);
2586 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2587 PFORMAT_STRING pFormat)
2589 PFORMAT_STRING desc;
2590 unsigned long size = 0;
2592 while (*pFormat != RPC_FC_END) {
2599 safe_buffer_increment(pStubMsg, 1);
2605 safe_buffer_increment(pStubMsg, 2);
2611 safe_buffer_increment(pStubMsg, 4);
2615 safe_buffer_increment(pStubMsg, 8);
2617 case RPC_FC_POINTER:
2619 safe_buffer_increment(pStubMsg, 4);
2620 if (!pStubMsg->IgnoreEmbeddedPointers)
2621 FIXME("embedded pointers\n");
2623 case RPC_FC_ALIGNM4:
2624 ALIGN_LENGTH(size, 4);
2625 ALIGN_POINTER(pStubMsg->Buffer, 4);
2627 case RPC_FC_ALIGNM8:
2628 ALIGN_LENGTH(size, 8);
2629 ALIGN_POINTER(pStubMsg->Buffer, 8);
2631 case RPC_FC_STRUCTPAD1:
2632 case RPC_FC_STRUCTPAD2:
2633 case RPC_FC_STRUCTPAD3:
2634 case RPC_FC_STRUCTPAD4:
2635 case RPC_FC_STRUCTPAD5:
2636 case RPC_FC_STRUCTPAD6:
2637 case RPC_FC_STRUCTPAD7:
2638 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2640 case RPC_FC_EMBEDDED_COMPLEX:
2643 desc = pFormat + *(const SHORT*)pFormat;
2644 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2650 FIXME("unhandled format 0x%02x\n", *pFormat);
2658 /***********************************************************************
2659 * NdrComplexStructMarshall [RPCRT4.@]
2661 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2662 unsigned char *pMemory,
2663 PFORMAT_STRING pFormat)
2665 PFORMAT_STRING conf_array = NULL;
2666 PFORMAT_STRING pointer_desc = NULL;
2667 unsigned char *OldMemory = pStubMsg->Memory;
2668 int pointer_buffer_mark_set = 0;
2670 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2672 if (!pStubMsg->PointerBufferMark)
2674 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2675 /* save buffer length */
2676 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2678 /* get the buffer pointer after complex array data, but before
2680 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2681 pStubMsg->IgnoreEmbeddedPointers = 1;
2682 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2683 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2685 /* save it for use by embedded pointer code later */
2686 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2687 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
2688 pointer_buffer_mark_set = 1;
2690 /* restore the original buffer length */
2691 pStubMsg->BufferLength = saved_buffer_length;
2694 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
2697 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2699 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2702 pStubMsg->Memory = pMemory;
2704 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2707 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2709 pStubMsg->Memory = OldMemory;
2711 if (pointer_buffer_mark_set)
2713 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2714 pStubMsg->PointerBufferMark = NULL;
2717 STD_OVERFLOW_CHECK(pStubMsg);
2722 /***********************************************************************
2723 * NdrComplexStructUnmarshall [RPCRT4.@]
2725 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2726 unsigned char **ppMemory,
2727 PFORMAT_STRING pFormat,
2728 unsigned char fMustAlloc)
2730 unsigned size = *(const WORD*)(pFormat+2);
2731 PFORMAT_STRING conf_array = NULL;
2732 PFORMAT_STRING pointer_desc = NULL;
2733 unsigned char *pMemory;
2734 int pointer_buffer_mark_set = 0;
2736 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2738 if (!pStubMsg->PointerBufferMark)
2740 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2741 /* save buffer pointer */
2742 unsigned char *saved_buffer = pStubMsg->Buffer;
2744 /* get the buffer pointer after complex array data, but before
2746 pStubMsg->IgnoreEmbeddedPointers = 1;
2747 NdrComplexStructMemorySize(pStubMsg, pFormat);
2748 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2750 /* save it for use by embedded pointer code later */
2751 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2752 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
2753 pointer_buffer_mark_set = 1;
2755 /* restore the original buffer */
2756 pStubMsg->Buffer = saved_buffer;
2759 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2761 if (fMustAlloc || !*ppMemory)
2763 *ppMemory = NdrAllocate(pStubMsg, size);
2764 memset(*ppMemory, 0, size);
2768 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2770 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2773 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2776 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2778 if (pointer_buffer_mark_set)
2780 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2781 pStubMsg->PointerBufferMark = NULL;
2787 /***********************************************************************
2788 * NdrComplexStructBufferSize [RPCRT4.@]
2790 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2791 unsigned char *pMemory,
2792 PFORMAT_STRING pFormat)
2794 PFORMAT_STRING conf_array = NULL;
2795 PFORMAT_STRING pointer_desc = NULL;
2796 unsigned char *OldMemory = pStubMsg->Memory;
2797 int pointer_length_set = 0;
2799 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2801 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2803 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2805 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2806 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2808 /* get the buffer length after complex struct data, but before
2810 pStubMsg->IgnoreEmbeddedPointers = 1;
2811 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2812 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2814 /* save it for use by embedded pointer code later */
2815 pStubMsg->PointerLength = pStubMsg->BufferLength;
2816 pointer_length_set = 1;
2817 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
2819 /* restore the original buffer length */
2820 pStubMsg->BufferLength = saved_buffer_length;
2824 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2826 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2829 pStubMsg->Memory = pMemory;
2831 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2834 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2836 pStubMsg->Memory = OldMemory;
2838 if(pointer_length_set)
2840 pStubMsg->BufferLength = pStubMsg->PointerLength;
2841 pStubMsg->PointerLength = 0;
2846 /***********************************************************************
2847 * NdrComplexStructMemorySize [RPCRT4.@]
2849 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2850 PFORMAT_STRING pFormat)
2852 unsigned size = *(const WORD*)(pFormat+2);
2853 PFORMAT_STRING conf_array = NULL;
2854 PFORMAT_STRING pointer_desc = NULL;
2856 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2858 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2861 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2863 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2866 ComplexStructMemorySize(pStubMsg, pFormat);
2869 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2874 /***********************************************************************
2875 * NdrComplexStructFree [RPCRT4.@]
2877 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2878 unsigned char *pMemory,
2879 PFORMAT_STRING pFormat)
2881 PFORMAT_STRING conf_array = NULL;
2882 PFORMAT_STRING pointer_desc = NULL;
2883 unsigned char *OldMemory = pStubMsg->Memory;
2885 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2888 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2890 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2893 pStubMsg->Memory = pMemory;
2895 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2898 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2900 pStubMsg->Memory = OldMemory;
2903 /***********************************************************************
2904 * NdrConformantArrayMarshall [RPCRT4.@]
2906 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2907 unsigned char *pMemory,
2908 PFORMAT_STRING pFormat)
2910 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2911 unsigned char alignment = pFormat[1] + 1;
2913 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2914 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2916 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2918 WriteConformance(pStubMsg);
2920 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
2922 size = safe_multiply(esize, pStubMsg->MaxCount);
2923 pStubMsg->BufferMark = pStubMsg->Buffer;
2924 safe_copy_to_buffer(pStubMsg, pMemory, size);
2926 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2931 /***********************************************************************
2932 * NdrConformantArrayUnmarshall [RPCRT4.@]
2934 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2935 unsigned char **ppMemory,
2936 PFORMAT_STRING pFormat,
2937 unsigned char fMustAlloc)
2939 DWORD size, esize = *(const WORD*)(pFormat+2);
2940 unsigned char alignment = pFormat[1] + 1;
2941 unsigned char *saved_buffer;
2943 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2944 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2946 pFormat = ReadConformance(pStubMsg, pFormat+4);
2948 size = safe_multiply(esize, pStubMsg->MaxCount);
2949 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2952 *ppMemory = NdrAllocate(pStubMsg, size);
2955 if (!pStubMsg->IsClient && !*ppMemory)
2956 /* for servers, we just point straight into the RPC buffer */
2957 *ppMemory = pStubMsg->Buffer;
2960 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
2961 safe_buffer_increment(pStubMsg, size);
2962 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2964 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2965 if (*ppMemory != saved_buffer)
2966 memcpy(*ppMemory, saved_buffer, size);
2971 /***********************************************************************
2972 * NdrConformantArrayBufferSize [RPCRT4.@]
2974 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2975 unsigned char *pMemory,
2976 PFORMAT_STRING pFormat)
2978 DWORD size, esize = *(const WORD*)(pFormat+2);
2979 unsigned char alignment = pFormat[1] + 1;
2981 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2982 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2984 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2986 SizeConformance(pStubMsg);
2988 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2990 size = safe_multiply(esize, pStubMsg->MaxCount);
2991 /* conformance value plus array */
2992 safe_buffer_length_increment(pStubMsg, size);
2994 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2997 /***********************************************************************
2998 * NdrConformantArrayMemorySize [RPCRT4.@]
3000 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3001 PFORMAT_STRING pFormat)
3003 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
3004 unsigned char alignment = pFormat[1] + 1;
3006 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3007 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3009 pFormat = ReadConformance(pStubMsg, pFormat+4);
3010 size = safe_multiply(esize, pStubMsg->MaxCount);
3011 pStubMsg->MemorySize += size;
3013 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3014 pStubMsg->BufferMark = pStubMsg->Buffer;
3015 safe_buffer_increment(pStubMsg, size);
3017 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3019 return pStubMsg->MemorySize;
3022 /***********************************************************************
3023 * NdrConformantArrayFree [RPCRT4.@]
3025 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3026 unsigned char *pMemory,
3027 PFORMAT_STRING pFormat)
3029 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3030 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3032 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3034 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3038 /***********************************************************************
3039 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3041 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
3042 unsigned char* pMemory,
3043 PFORMAT_STRING pFormat )
3046 unsigned char alignment = pFormat[1] + 1;
3047 DWORD esize = *(const WORD*)(pFormat+2);
3049 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3051 if (pFormat[0] != RPC_FC_CVARRAY)
3053 ERR("invalid format type %x\n", pFormat[0]);
3054 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3058 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3059 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3061 WriteConformance(pStubMsg);
3062 WriteVariance(pStubMsg);
3064 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3066 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3068 pStubMsg->BufferMark = pStubMsg->Buffer;
3069 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
3071 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3077 /***********************************************************************
3078 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3080 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
3081 unsigned char** ppMemory,
3082 PFORMAT_STRING pFormat,
3083 unsigned char fMustAlloc )
3085 ULONG bufsize, memsize;
3086 unsigned char alignment = pFormat[1] + 1;
3087 DWORD esize = *(const WORD*)(pFormat+2);
3088 unsigned char *saved_buffer;
3091 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3093 if (pFormat[0] != RPC_FC_CVARRAY)
3095 ERR("invalid format type %x\n", pFormat[0]);
3096 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3100 pFormat = ReadConformance(pStubMsg, pFormat+4);
3101 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3103 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3105 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3106 memsize = safe_multiply(esize, pStubMsg->MaxCount);
3107 offset = pStubMsg->Offset;
3109 if (!*ppMemory || fMustAlloc)
3110 *ppMemory = NdrAllocate(pStubMsg, memsize);
3111 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3112 safe_buffer_increment(pStubMsg, bufsize);
3114 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3116 memcpy(*ppMemory + offset, saved_buffer, bufsize);
3122 /***********************************************************************
3123 * NdrConformantVaryingArrayFree [RPCRT4.@]
3125 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
3126 unsigned char* pMemory,
3127 PFORMAT_STRING pFormat )
3129 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3131 if (pFormat[0] != RPC_FC_CVARRAY)
3133 ERR("invalid format type %x\n", pFormat[0]);
3134 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3138 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3139 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3141 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3145 /***********************************************************************
3146 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3148 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
3149 unsigned char* pMemory, PFORMAT_STRING pFormat )
3151 unsigned char alignment = pFormat[1] + 1;
3152 DWORD esize = *(const WORD*)(pFormat+2);
3154 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3156 if (pFormat[0] != RPC_FC_CVARRAY)
3158 ERR("invalid format type %x\n", pFormat[0]);
3159 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3164 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3165 /* compute length */
3166 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3168 SizeConformance(pStubMsg);
3169 SizeVariance(pStubMsg);
3171 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3173 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
3175 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3179 /***********************************************************************
3180 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3182 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
3183 PFORMAT_STRING pFormat )
3185 ULONG bufsize, memsize;
3186 unsigned char alignment = pFormat[1] + 1;
3187 DWORD esize = *(const WORD*)(pFormat+2);
3189 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3191 if (pFormat[0] != RPC_FC_CVARRAY)
3193 ERR("invalid format type %x\n", pFormat[0]);
3194 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3195 return pStubMsg->MemorySize;
3198 pFormat = ReadConformance(pStubMsg, pFormat+4);
3199 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3201 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3203 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3204 memsize = safe_multiply(esize, pStubMsg->MaxCount);
3206 safe_buffer_increment(pStubMsg, bufsize);
3207 pStubMsg->MemorySize += memsize;
3209 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3211 return pStubMsg->MemorySize;
3215 /***********************************************************************
3216 * NdrComplexArrayMarshall [RPCRT4.@]
3218 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3219 unsigned char *pMemory,
3220 PFORMAT_STRING pFormat)
3222 ULONG i, count, def;
3223 BOOL variance_present;
3224 unsigned char alignment;
3225 int pointer_buffer_mark_set = 0;
3227 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3229 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3231 ERR("invalid format type %x\n", pFormat[0]);
3232 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3236 alignment = pFormat[1] + 1;
3238 if (!pStubMsg->PointerBufferMark)
3240 /* save buffer fields that may be changed by buffer sizer functions
3241 * and that may be needed later on */
3242 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3243 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3244 unsigned long saved_max_count = pStubMsg->MaxCount;
3245 unsigned long saved_offset = pStubMsg->Offset;
3246 unsigned long saved_actual_count = pStubMsg->ActualCount;
3248 /* get the buffer pointer after complex array data, but before
3250 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3251 pStubMsg->IgnoreEmbeddedPointers = 1;
3252 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3253 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3255 /* save it for use by embedded pointer code later */
3256 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3257 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
3258 pointer_buffer_mark_set = 1;
3260 /* restore fields */
3261 pStubMsg->ActualCount = saved_actual_count;
3262 pStubMsg->Offset = saved_offset;
3263 pStubMsg->MaxCount = saved_max_count;
3264 pStubMsg->BufferLength = saved_buffer_length;
3267 def = *(const WORD*)&pFormat[2];
3270 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3271 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3273 variance_present = IsConformanceOrVariancePresent(pFormat);
3274 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3275 TRACE("variance = %d\n", pStubMsg->ActualCount);
3277 WriteConformance(pStubMsg);
3278 if (variance_present)
3279 WriteVariance(pStubMsg);
3281 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3283 count = pStubMsg->ActualCount;
3284 for (i = 0; i < count; i++)
3285 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3287 STD_OVERFLOW_CHECK(pStubMsg);
3289 if (pointer_buffer_mark_set)
3291 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3292 pStubMsg->PointerBufferMark = NULL;
3298 /***********************************************************************
3299 * NdrComplexArrayUnmarshall [RPCRT4.@]
3301 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3302 unsigned char **ppMemory,
3303 PFORMAT_STRING pFormat,
3304 unsigned char fMustAlloc)
3306 ULONG i, count, size;
3307 unsigned char alignment;
3308 unsigned char *pMemory;
3309 unsigned char *saved_buffer;
3310 int pointer_buffer_mark_set = 0;
3311 int saved_ignore_embedded;
3313 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3315 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3317 ERR("invalid format type %x\n", pFormat[0]);
3318 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3322 alignment = pFormat[1] + 1;
3324 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3325 /* save buffer pointer */
3326 saved_buffer = pStubMsg->Buffer;
3327 /* get the buffer pointer after complex array data, but before
3329 pStubMsg->IgnoreEmbeddedPointers = 1;
3330 pStubMsg->MemorySize = 0;
3331 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3332 size = pStubMsg->MemorySize;
3333 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3335 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
3336 if (!pStubMsg->PointerBufferMark)
3338 /* save it for use by embedded pointer code later */
3339 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3340 pointer_buffer_mark_set = 1;
3342 /* restore the original buffer */
3343 pStubMsg->Buffer = saved_buffer;
3347 pFormat = ReadConformance(pStubMsg, pFormat);
3348 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3350 if (fMustAlloc || !*ppMemory)
3352 *ppMemory = NdrAllocate(pStubMsg, size);
3353 memset(*ppMemory, 0, size);
3356 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3358 pMemory = *ppMemory;
3359 count = pStubMsg->ActualCount;
3360 for (i = 0; i < count; i++)
3361 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
3363 if (pointer_buffer_mark_set)
3365 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3366 pStubMsg->PointerBufferMark = NULL;
3372 /***********************************************************************
3373 * NdrComplexArrayBufferSize [RPCRT4.@]
3375 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3376 unsigned char *pMemory,
3377 PFORMAT_STRING pFormat)
3379 ULONG i, count, def;
3380 unsigned char alignment;
3381 BOOL variance_present;
3382 int pointer_length_set = 0;
3384 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3386 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3388 ERR("invalid format type %x\n", pFormat[0]);
3389 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3393 alignment = pFormat[1] + 1;
3395 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3397 /* save buffer fields that may be changed by buffer sizer functions
3398 * and that may be needed later on */
3399 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3400 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3401 unsigned long saved_max_count = pStubMsg->MaxCount;
3402 unsigned long saved_offset = pStubMsg->Offset;
3403 unsigned long saved_actual_count = pStubMsg->ActualCount;
3405 /* get the buffer pointer after complex array data, but before
3407 pStubMsg->IgnoreEmbeddedPointers = 1;
3408 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3409 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3411 /* save it for use by embedded pointer code later */
3412 pStubMsg->PointerLength = pStubMsg->BufferLength;
3413 pointer_length_set = 1;
3415 /* restore fields */
3416 pStubMsg->ActualCount = saved_actual_count;
3417 pStubMsg->Offset = saved_offset;
3418 pStubMsg->MaxCount = saved_max_count;
3419 pStubMsg->BufferLength = saved_buffer_length;
3421 def = *(const WORD*)&pFormat[2];
3424 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3425 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3426 SizeConformance(pStubMsg);
3428 variance_present = IsConformanceOrVariancePresent(pFormat);
3429 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3430 TRACE("variance = %d\n", pStubMsg->ActualCount);
3432 if (variance_present)
3433 SizeVariance(pStubMsg);
3435 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3437 count = pStubMsg->ActualCount;
3438 for (i = 0; i < count; i++)
3439 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
3441 if(pointer_length_set)
3443 pStubMsg->BufferLength = pStubMsg->PointerLength;
3444 pStubMsg->PointerLength = 0;
3448 /***********************************************************************
3449 * NdrComplexArrayMemorySize [RPCRT4.@]
3451 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3452 PFORMAT_STRING pFormat)
3454 ULONG i, count, esize, SavedMemorySize, MemorySize;
3455 unsigned char alignment;
3456 unsigned char *Buffer;
3458 TRACE("(%p,%p)\n", pStubMsg, pFormat);
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;
3471 pFormat = ReadConformance(pStubMsg, pFormat);
3472 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3474 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3476 SavedMemorySize = pStubMsg->MemorySize;
3478 Buffer = pStubMsg->Buffer;
3479 pStubMsg->MemorySize = 0;
3480 esize = ComplexStructMemorySize(pStubMsg, pFormat);
3481 pStubMsg->Buffer = Buffer;
3483 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
3485 count = pStubMsg->ActualCount;
3486 for (i = 0; i < count; i++)
3487 ComplexStructMemorySize(pStubMsg, pFormat);
3489 pStubMsg->MemorySize = SavedMemorySize;
3491 pStubMsg->MemorySize += MemorySize;
3495 /***********************************************************************
3496 * NdrComplexArrayFree [RPCRT4.@]
3498 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3499 unsigned char *pMemory,
3500 PFORMAT_STRING pFormat)
3502 ULONG i, count, def;
3504 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3506 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3508 ERR("invalid format type %x\n", pFormat[0]);
3509 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3513 def = *(const WORD*)&pFormat[2];
3516 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3517 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3519 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3520 TRACE("variance = %d\n", pStubMsg->ActualCount);
3522 count = pStubMsg->ActualCount;
3523 for (i = 0; i < count; i++)
3524 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
3527 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
3528 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
3529 USER_MARSHAL_CB *umcb)
3531 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
3532 pStubMsg->RpcMsg->DataRepresentation);
3533 umcb->pStubMsg = pStubMsg;
3534 umcb->pReserve = NULL;
3535 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
3536 umcb->CBType = cbtype;
3537 umcb->pFormat = pFormat;
3538 umcb->pTypeFormat = NULL /* FIXME */;
3541 #define USER_MARSHAL_PTR_PREFIX \
3542 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3543 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3545 /***********************************************************************
3546 * NdrUserMarshalMarshall [RPCRT4.@]
3548 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3549 unsigned char *pMemory,
3550 PFORMAT_STRING pFormat)
3552 unsigned flags = pFormat[1];
3553 unsigned index = *(const WORD*)&pFormat[2];
3554 unsigned char *saved_buffer = NULL;
3555 USER_MARSHAL_CB umcb;
3557 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3558 TRACE("index=%d\n", index);
3560 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
3562 if (flags & USER_MARSHAL_POINTER)
3564 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
3565 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
3566 pStubMsg->Buffer += 4;
3567 if (pStubMsg->PointerBufferMark)
3569 saved_buffer = pStubMsg->Buffer;
3570 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3571 pStubMsg->PointerBufferMark = NULL;
3573 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
3576 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
3579 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
3580 &umcb.Flags, pStubMsg->Buffer, pMemory);
3584 STD_OVERFLOW_CHECK(pStubMsg);
3585 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3586 pStubMsg->Buffer = saved_buffer;
3589 STD_OVERFLOW_CHECK(pStubMsg);
3594 /***********************************************************************
3595 * NdrUserMarshalUnmarshall [RPCRT4.@]
3597 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3598 unsigned char **ppMemory,
3599 PFORMAT_STRING pFormat,
3600 unsigned char fMustAlloc)
3602 unsigned flags = pFormat[1];
3603 unsigned index = *(const WORD*)&pFormat[2];
3604 DWORD memsize = *(const WORD*)&pFormat[4];
3605 unsigned char *saved_buffer = NULL;
3606 USER_MARSHAL_CB umcb;
3608 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3609 TRACE("index=%d\n", index);
3611 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
3613 if (flags & USER_MARSHAL_POINTER)
3615 ALIGN_POINTER(pStubMsg->Buffer, 4);
3616 /* skip pointer prefix */
3617 pStubMsg->Buffer += 4;
3618 if (pStubMsg->PointerBufferMark)
3620 saved_buffer = pStubMsg->Buffer;
3621 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3622 pStubMsg->PointerBufferMark = NULL;
3624 ALIGN_POINTER(pStubMsg->Buffer, 8);
3627 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3629 if (fMustAlloc || !*ppMemory)
3630 *ppMemory = NdrAllocate(pStubMsg, memsize);
3633 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
3634 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
3638 STD_OVERFLOW_CHECK(pStubMsg);
3639 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3640 pStubMsg->Buffer = saved_buffer;
3646 /***********************************************************************
3647 * NdrUserMarshalBufferSize [RPCRT4.@]
3649 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3650 unsigned char *pMemory,
3651 PFORMAT_STRING pFormat)
3653 unsigned flags = pFormat[1];
3654 unsigned index = *(const WORD*)&pFormat[2];
3655 DWORD bufsize = *(const WORD*)&pFormat[6];
3656 USER_MARSHAL_CB umcb;
3657 unsigned long saved_buffer_length = 0;
3659 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3660 TRACE("index=%d\n", index);
3662 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
3664 if (flags & USER_MARSHAL_POINTER)
3666 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3667 /* skip pointer prefix */
3668 safe_buffer_length_increment(pStubMsg, 4);
3669 if (pStubMsg->IgnoreEmbeddedPointers)
3671 if (pStubMsg->PointerLength)
3673 saved_buffer_length = pStubMsg->BufferLength;
3674 pStubMsg->BufferLength = pStubMsg->PointerLength;
3675 pStubMsg->PointerLength = 0;
3677 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
3680 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
3683 TRACE("size=%d\n", bufsize);
3684 safe_buffer_length_increment(pStubMsg, bufsize);
3687 pStubMsg->BufferLength =
3688 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
3689 &umcb.Flags, pStubMsg->BufferLength, pMemory);
3691 if (saved_buffer_length)
3693 pStubMsg->PointerLength = pStubMsg->BufferLength;
3694 pStubMsg->BufferLength = saved_buffer_length;
3699 /***********************************************************************
3700 * NdrUserMarshalMemorySize [RPCRT4.@]
3702 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3703 PFORMAT_STRING pFormat)
3705 unsigned flags = pFormat[1];
3706 unsigned index = *(const WORD*)&pFormat[2];
3707 DWORD memsize = *(const WORD*)&pFormat[4];
3708 DWORD bufsize = *(const WORD*)&pFormat[6];
3710 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3711 TRACE("index=%d\n", index);
3713 pStubMsg->MemorySize += memsize;
3715 if (flags & USER_MARSHAL_POINTER)
3717 ALIGN_POINTER(pStubMsg->Buffer, 4);
3718 /* skip pointer prefix */
3719 pStubMsg->Buffer += 4;
3720 if (pStubMsg->IgnoreEmbeddedPointers)
3721 return pStubMsg->MemorySize;
3722 ALIGN_POINTER(pStubMsg->Buffer, 8);
3725 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3728 FIXME("not implemented for varying buffer size\n");
3730 pStubMsg->Buffer += bufsize;
3732 return pStubMsg->MemorySize;
3735 /***********************************************************************
3736 * NdrUserMarshalFree [RPCRT4.@]
3738 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
3739 unsigned char *pMemory,
3740 PFORMAT_STRING pFormat)
3742 /* unsigned flags = pFormat[1]; */
3743 unsigned index = *(const WORD*)&pFormat[2];
3744 USER_MARSHAL_CB umcb;
3746 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3747 TRACE("index=%d\n", index);
3749 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
3751 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
3752 &umcb.Flags, pMemory);
3755 /***********************************************************************
3756 * NdrClearOutParameters [RPCRT4.@]
3758 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
3759 PFORMAT_STRING pFormat,
3762 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
3765 /***********************************************************************
3766 * NdrConvert [RPCRT4.@]
3768 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
3770 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
3771 /* FIXME: since this stub doesn't do any converting, the proper behavior
3772 is to raise an exception */
3775 /***********************************************************************
3776 * NdrConvert2 [RPCRT4.@]
3778 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
3780 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3781 pStubMsg, pFormat, NumberParams);
3782 /* FIXME: since this stub doesn't do any converting, the proper behavior
3783 is to raise an exception */
3786 #include "pshpack1.h"
3787 typedef struct _NDR_CSTRUCT_FORMAT
3790 unsigned char alignment;
3791 unsigned short memory_size;
3792 short offset_to_array_description;
3793 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
3794 #include "poppack.h"
3796 /***********************************************************************
3797 * NdrConformantStructMarshall [RPCRT4.@]
3799 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3800 unsigned char *pMemory,
3801 PFORMAT_STRING pFormat)
3803 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3804 PFORMAT_STRING pCArrayFormat;
3805 ULONG esize, bufsize;
3807 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3809 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3810 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3812 ERR("invalid format type %x\n", pCStructFormat->type);
3813 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3817 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3818 pCStructFormat->offset_to_array_description;
3819 if (*pCArrayFormat != RPC_FC_CARRAY)
3821 ERR("invalid array format type %x\n", pCStructFormat->type);
3822 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3825 esize = *(const WORD*)(pCArrayFormat+2);
3827 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3828 pCArrayFormat + 4, 0);
3830 WriteConformance(pStubMsg);
3832 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3834 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3836 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3837 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3839 ERR("integer overflow of memory_size %u with bufsize %u\n",
3840 pCStructFormat->memory_size, bufsize);
3841 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3843 /* copy constant sized part of struct */
3844 pStubMsg->BufferMark = pStubMsg->Buffer;
3845 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
3847 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3848 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3853 /***********************************************************************
3854 * NdrConformantStructUnmarshall [RPCRT4.@]
3856 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3857 unsigned char **ppMemory,
3858 PFORMAT_STRING pFormat,
3859 unsigned char fMustAlloc)
3861 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3862 PFORMAT_STRING pCArrayFormat;
3863 ULONG esize, bufsize;
3864 unsigned char *saved_buffer;
3866 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3868 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3869 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3871 ERR("invalid format type %x\n", pCStructFormat->type);
3872 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3875 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3876 pCStructFormat->offset_to_array_description;
3877 if (*pCArrayFormat != RPC_FC_CARRAY)
3879 ERR("invalid array format type %x\n", pCStructFormat->type);
3880 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3883 esize = *(const WORD*)(pCArrayFormat+2);
3885 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3887 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3889 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3891 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3892 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3894 ERR("integer overflow of memory_size %u with bufsize %u\n",
3895 pCStructFormat->memory_size, bufsize);
3896 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3901 SIZE_T size = pCStructFormat->memory_size + bufsize;
3902 *ppMemory = NdrAllocate(pStubMsg, size);
3906 if (!pStubMsg->IsClient && !*ppMemory)
3907 /* for servers, we just point straight into the RPC buffer */
3908 *ppMemory = pStubMsg->Buffer;
3911 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3912 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
3913 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3914 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3916 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
3917 if (*ppMemory != saved_buffer)
3918 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
3923 /***********************************************************************
3924 * NdrConformantStructBufferSize [RPCRT4.@]
3926 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3927 unsigned char *pMemory,
3928 PFORMAT_STRING pFormat)
3930 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3931 PFORMAT_STRING pCArrayFormat;
3934 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3936 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3937 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3939 ERR("invalid format type %x\n", pCStructFormat->type);
3940 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3943 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3944 pCStructFormat->offset_to_array_description;
3945 if (*pCArrayFormat != RPC_FC_CARRAY)
3947 ERR("invalid array format type %x\n", pCStructFormat->type);
3948 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3951 esize = *(const WORD*)(pCArrayFormat+2);
3953 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
3954 SizeConformance(pStubMsg);
3956 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
3958 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3960 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
3961 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
3963 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3964 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3967 /***********************************************************************
3968 * NdrConformantStructMemorySize [RPCRT4.@]
3970 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3971 PFORMAT_STRING pFormat)
3977 /***********************************************************************
3978 * NdrConformantStructFree [RPCRT4.@]
3980 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3981 unsigned char *pMemory,
3982 PFORMAT_STRING pFormat)
3984 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3985 PFORMAT_STRING pCArrayFormat;
3988 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3990 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3991 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3993 ERR("invalid format type %x\n", pCStructFormat->type);
3994 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3998 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3999 pCStructFormat->offset_to_array_description;
4000 if (*pCArrayFormat != RPC_FC_CARRAY)
4002 ERR("invalid array format type %x\n", pCStructFormat->type);
4003 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4006 esize = *(const WORD*)(pCArrayFormat+2);
4008 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4009 pCArrayFormat + 4, 0);
4011 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4013 /* copy constant sized part of struct */
4014 pStubMsg->BufferMark = pStubMsg->Buffer;
4016 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4017 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4020 /***********************************************************************
4021 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4023 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4024 unsigned char *pMemory,
4025 PFORMAT_STRING pFormat)
4027 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4028 PFORMAT_STRING pCVArrayFormat;
4029 ULONG esize, bufsize;
4031 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4033 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4034 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4036 ERR("invalid format type %x\n", pCVStructFormat->type);
4037 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4041 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4042 pCVStructFormat->offset_to_array_description;
4043 switch (*pCVArrayFormat)
4045 case RPC_FC_CVARRAY:
4046 esize = *(const WORD*)(pCVArrayFormat+2);
4048 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4049 pCVArrayFormat + 4, 0);
4050 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4053 case RPC_FC_C_CSTRING:
4054 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4055 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4056 esize = sizeof(char);
4057 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4058 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4059 pCVArrayFormat + 2, 0);
4061 pStubMsg->MaxCount = pStubMsg->ActualCount;
4063 case RPC_FC_C_WSTRING:
4064 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4065 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4066 esize = sizeof(WCHAR);
4067 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4068 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4069 pCVArrayFormat + 2, 0);
4071 pStubMsg->MaxCount = pStubMsg->ActualCount;
4074 ERR("invalid array format type %x\n", *pCVArrayFormat);
4075 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4079 WriteConformance(pStubMsg);
4081 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4083 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4085 /* write constant sized part */
4086 pStubMsg->BufferMark = pStubMsg->Buffer;
4087 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4089 WriteVariance(pStubMsg);
4091 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4093 /* write array part */
4094 safe_copy_to_buffer(pStubMsg, pMemory + pCVStructFormat->memory_size, bufsize);
4096 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4101 /***********************************************************************
4102 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4104 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4105 unsigned char **ppMemory,
4106 PFORMAT_STRING pFormat,
4107 unsigned char fMustAlloc)
4109 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4110 PFORMAT_STRING pCVArrayFormat;
4111 ULONG esize, bufsize;
4112 unsigned char cvarray_type;
4114 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4116 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4117 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4119 ERR("invalid format type %x\n", pCVStructFormat->type);
4120 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4124 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4125 pCVStructFormat->offset_to_array_description;
4126 cvarray_type = *pCVArrayFormat;
4127 switch (cvarray_type)
4129 case RPC_FC_CVARRAY:
4130 esize = *(const WORD*)(pCVArrayFormat+2);
4131 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4133 case RPC_FC_C_CSTRING:
4134 esize = sizeof(char);
4135 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4136 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4138 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4140 case RPC_FC_C_WSTRING:
4141 esize = sizeof(WCHAR);
4142 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4143 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4145 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4148 ERR("invalid array format type %x\n", *pCVArrayFormat);
4149 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4153 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4155 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4157 /* work out how much memory to allocate if we need to do so */
4158 if (!*ppMemory || fMustAlloc)
4160 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4161 *ppMemory = NdrAllocate(pStubMsg, size);
4164 /* copy the constant data */
4165 pStubMsg->BufferMark = pStubMsg->Buffer;
4166 safe_copy_from_buffer(pStubMsg, *ppMemory, pCVStructFormat->memory_size);
4168 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4170 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4172 if ((cvarray_type == RPC_FC_C_CSTRING) ||
4173 (cvarray_type == RPC_FC_C_WSTRING))
4176 /* strings must always have null terminating bytes */
4177 if (bufsize < esize)
4179 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
4180 RpcRaiseException(RPC_S_INVALID_BOUND);
4183 for (i = bufsize - esize; i < bufsize; i++)
4184 if (pStubMsg->Buffer[i] != 0)
4186 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
4187 i, pStubMsg->Buffer[i]);
4188 RpcRaiseException(RPC_S_INVALID_BOUND);
4193 /* copy the array data */
4194 safe_copy_from_buffer(pStubMsg, *ppMemory + pCVStructFormat->memory_size, bufsize);
4196 if (cvarray_type == RPC_FC_C_CSTRING)
4197 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
4198 else if (cvarray_type == RPC_FC_C_WSTRING)
4199 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
4201 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
4206 /***********************************************************************
4207 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4209 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4210 unsigned char *pMemory,
4211 PFORMAT_STRING pFormat)
4213 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4214 PFORMAT_STRING pCVArrayFormat;
4217 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4219 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4220 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4222 ERR("invalid format type %x\n", pCVStructFormat->type);
4223 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4227 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4228 pCVStructFormat->offset_to_array_description;
4229 switch (*pCVArrayFormat)
4231 case RPC_FC_CVARRAY:
4232 esize = *(const WORD*)(pCVArrayFormat+2);
4234 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4235 pCVArrayFormat + 4, 0);
4236 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4239 case RPC_FC_C_CSTRING:
4240 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4241 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4242 esize = sizeof(char);
4243 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4244 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4245 pCVArrayFormat + 2, 0);
4247 pStubMsg->MaxCount = pStubMsg->ActualCount;
4249 case RPC_FC_C_WSTRING:
4250 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4251 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4252 esize = sizeof(WCHAR);
4253 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4254 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4255 pCVArrayFormat + 2, 0);
4257 pStubMsg->MaxCount = pStubMsg->ActualCount;
4260 ERR("invalid array format type %x\n", *pCVArrayFormat);
4261 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4265 SizeConformance(pStubMsg);
4267 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4269 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4271 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4272 SizeVariance(pStubMsg);
4273 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4275 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4278 /***********************************************************************
4279 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4281 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4282 PFORMAT_STRING pFormat)
4284 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4285 PFORMAT_STRING pCVArrayFormat;
4287 unsigned char cvarray_type;
4289 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4291 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4292 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4294 ERR("invalid format type %x\n", pCVStructFormat->type);
4295 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4299 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4300 pCVStructFormat->offset_to_array_description;
4301 cvarray_type = *pCVArrayFormat;
4302 switch (cvarray_type)
4304 case RPC_FC_CVARRAY:
4305 esize = *(const WORD*)(pCVArrayFormat+2);
4306 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4308 case RPC_FC_C_CSTRING:
4309 esize = sizeof(char);
4310 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4311 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4313 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4315 case RPC_FC_C_WSTRING:
4316 esize = sizeof(WCHAR);
4317 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4318 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4320 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4323 ERR("invalid array format type %x\n", *pCVArrayFormat);
4324 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4328 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4330 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4332 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4333 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4334 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4336 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4338 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4340 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
4343 /***********************************************************************
4344 * NdrConformantVaryingStructFree [RPCRT4.@]
4346 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4347 unsigned char *pMemory,
4348 PFORMAT_STRING pFormat)
4350 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4351 PFORMAT_STRING pCVArrayFormat;
4354 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4356 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4357 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4359 ERR("invalid format type %x\n", pCVStructFormat->type);
4360 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4364 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4365 pCVStructFormat->offset_to_array_description;
4366 switch (*pCVArrayFormat)
4368 case RPC_FC_CVARRAY:
4369 esize = *(const WORD*)(pCVArrayFormat+2);
4371 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4372 pCVArrayFormat + 4, 0);
4373 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4376 case RPC_FC_C_CSTRING:
4377 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4378 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4379 esize = sizeof(char);
4380 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4381 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4382 pCVArrayFormat + 2, 0);
4384 pStubMsg->MaxCount = pStubMsg->ActualCount;
4386 case RPC_FC_C_WSTRING:
4387 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4388 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4389 esize = sizeof(WCHAR);
4390 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4391 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4392 pCVArrayFormat + 2, 0);
4394 pStubMsg->MaxCount = pStubMsg->ActualCount;
4397 ERR("invalid array format type %x\n", *pCVArrayFormat);
4398 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4402 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4404 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4407 #include "pshpack1.h"
4411 unsigned char alignment;
4412 unsigned short total_size;
4413 } NDR_SMFARRAY_FORMAT;
4418 unsigned char alignment;
4419 unsigned long total_size;
4420 } NDR_LGFARRAY_FORMAT;
4421 #include "poppack.h"
4423 /***********************************************************************
4424 * NdrFixedArrayMarshall [RPCRT4.@]
4426 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4427 unsigned char *pMemory,
4428 PFORMAT_STRING pFormat)
4430 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4431 unsigned long total_size;
4433 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4435 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4436 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4438 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4439 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4443 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4445 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4447 total_size = pSmFArrayFormat->total_size;
4448 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4452 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4453 total_size = pLgFArrayFormat->total_size;
4454 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4457 pStubMsg->BufferMark = pStubMsg->Buffer;
4458 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4460 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4465 /***********************************************************************
4466 * NdrFixedArrayUnmarshall [RPCRT4.@]
4468 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4469 unsigned char **ppMemory,
4470 PFORMAT_STRING pFormat,
4471 unsigned char fMustAlloc)
4473 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4474 unsigned long total_size;
4475 unsigned char *saved_buffer;
4477 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4479 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4480 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4482 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4483 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4487 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4489 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4491 total_size = pSmFArrayFormat->total_size;
4492 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4496 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4497 total_size = pLgFArrayFormat->total_size;
4498 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4502 *ppMemory = NdrAllocate(pStubMsg, total_size);
4505 if (!pStubMsg->IsClient && !*ppMemory)
4506 /* for servers, we just point straight into the RPC buffer */
4507 *ppMemory = pStubMsg->Buffer;
4510 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4511 safe_buffer_increment(pStubMsg, total_size);
4512 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4514 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4515 if (*ppMemory != saved_buffer)
4516 memcpy(*ppMemory, saved_buffer, total_size);
4521 /***********************************************************************
4522 * NdrFixedArrayBufferSize [RPCRT4.@]
4524 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4525 unsigned char *pMemory,
4526 PFORMAT_STRING pFormat)
4528 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4529 unsigned long total_size;
4531 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4533 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4534 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4536 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4537 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4541 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4543 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4545 total_size = pSmFArrayFormat->total_size;
4546 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4550 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4551 total_size = pLgFArrayFormat->total_size;
4552 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4554 safe_buffer_length_increment(pStubMsg, total_size);
4556 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4559 /***********************************************************************
4560 * NdrFixedArrayMemorySize [RPCRT4.@]
4562 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4563 PFORMAT_STRING pFormat)
4565 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4568 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4570 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4571 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4573 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4574 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4578 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4580 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4582 total_size = pSmFArrayFormat->total_size;
4583 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4587 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4588 total_size = pLgFArrayFormat->total_size;
4589 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4591 pStubMsg->BufferMark = pStubMsg->Buffer;
4592 safe_buffer_increment(pStubMsg, total_size);
4593 pStubMsg->MemorySize += total_size;
4595 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4600 /***********************************************************************
4601 * NdrFixedArrayFree [RPCRT4.@]
4603 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4604 unsigned char *pMemory,
4605 PFORMAT_STRING pFormat)
4607 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4609 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4611 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4612 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4614 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4615 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4619 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4620 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4623 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4624 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4627 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4630 /***********************************************************************
4631 * NdrVaryingArrayMarshall [RPCRT4.@]
4633 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4634 unsigned char *pMemory,
4635 PFORMAT_STRING pFormat)
4637 unsigned char alignment;
4638 DWORD elements, esize;
4641 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4643 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4644 (pFormat[0] != RPC_FC_LGVARRAY))
4646 ERR("invalid format type %x\n", pFormat[0]);
4647 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4651 alignment = pFormat[1] + 1;
4653 if (pFormat[0] == RPC_FC_SMVARRAY)
4656 pFormat += sizeof(WORD);
4657 elements = *(const WORD*)pFormat;
4658 pFormat += sizeof(WORD);
4663 pFormat += sizeof(DWORD);
4664 elements = *(const DWORD*)pFormat;
4665 pFormat += sizeof(DWORD);
4668 esize = *(const WORD*)pFormat;
4669 pFormat += sizeof(WORD);
4671 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4672 if ((pStubMsg->ActualCount > elements) ||
4673 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4675 RpcRaiseException(RPC_S_INVALID_BOUND);
4679 WriteVariance(pStubMsg);
4681 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
4683 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4684 pStubMsg->BufferMark = pStubMsg->Buffer;
4685 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
4687 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4692 /***********************************************************************
4693 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4695 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4696 unsigned char **ppMemory,
4697 PFORMAT_STRING pFormat,
4698 unsigned char fMustAlloc)
4700 unsigned char alignment;
4701 DWORD size, elements, esize;
4703 unsigned char *saved_buffer;
4706 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4708 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4709 (pFormat[0] != RPC_FC_LGVARRAY))
4711 ERR("invalid format type %x\n", pFormat[0]);
4712 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4716 alignment = pFormat[1] + 1;
4718 if (pFormat[0] == RPC_FC_SMVARRAY)
4721 size = *(const WORD*)pFormat;
4722 pFormat += sizeof(WORD);
4723 elements = *(const WORD*)pFormat;
4724 pFormat += sizeof(WORD);
4729 size = *(const DWORD*)pFormat;
4730 pFormat += sizeof(DWORD);
4731 elements = *(const DWORD*)pFormat;
4732 pFormat += sizeof(DWORD);
4735 esize = *(const WORD*)pFormat;
4736 pFormat += sizeof(WORD);
4738 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4740 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4742 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4743 offset = pStubMsg->Offset;
4745 if (!*ppMemory || fMustAlloc)
4746 *ppMemory = NdrAllocate(pStubMsg, size);
4747 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4748 safe_buffer_increment(pStubMsg, bufsize);
4750 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4752 memcpy(*ppMemory + offset, saved_buffer, bufsize);
4757 /***********************************************************************
4758 * NdrVaryingArrayBufferSize [RPCRT4.@]
4760 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4761 unsigned char *pMemory,
4762 PFORMAT_STRING pFormat)
4764 unsigned char alignment;
4765 DWORD elements, esize;
4767 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4769 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4770 (pFormat[0] != RPC_FC_LGVARRAY))
4772 ERR("invalid format type %x\n", pFormat[0]);
4773 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4777 alignment = pFormat[1] + 1;
4779 if (pFormat[0] == RPC_FC_SMVARRAY)
4782 pFormat += sizeof(WORD);
4783 elements = *(const WORD*)pFormat;
4784 pFormat += sizeof(WORD);
4789 pFormat += sizeof(DWORD);
4790 elements = *(const DWORD*)pFormat;
4791 pFormat += sizeof(DWORD);
4794 esize = *(const WORD*)pFormat;
4795 pFormat += sizeof(WORD);
4797 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4798 if ((pStubMsg->ActualCount > elements) ||
4799 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4801 RpcRaiseException(RPC_S_INVALID_BOUND);
4805 SizeVariance(pStubMsg);
4807 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4809 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4811 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4814 /***********************************************************************
4815 * NdrVaryingArrayMemorySize [RPCRT4.@]
4817 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4818 PFORMAT_STRING pFormat)
4820 unsigned char alignment;
4821 DWORD size, elements, esize;
4823 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4825 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4826 (pFormat[0] != RPC_FC_LGVARRAY))
4828 ERR("invalid format type %x\n", pFormat[0]);
4829 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4833 alignment = pFormat[1] + 1;
4835 if (pFormat[0] == RPC_FC_SMVARRAY)
4838 size = *(const WORD*)pFormat;
4839 pFormat += sizeof(WORD);
4840 elements = *(const WORD*)pFormat;
4841 pFormat += sizeof(WORD);
4846 size = *(const DWORD*)pFormat;
4847 pFormat += sizeof(DWORD);
4848 elements = *(const DWORD*)pFormat;
4849 pFormat += sizeof(DWORD);
4852 esize = *(const WORD*)pFormat;
4853 pFormat += sizeof(WORD);
4855 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4857 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4859 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4860 pStubMsg->MemorySize += size;
4862 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4864 return pStubMsg->MemorySize;
4867 /***********************************************************************
4868 * NdrVaryingArrayFree [RPCRT4.@]
4870 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4871 unsigned char *pMemory,
4872 PFORMAT_STRING pFormat)
4874 unsigned char alignment;
4877 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4879 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4880 (pFormat[0] != RPC_FC_LGVARRAY))
4882 ERR("invalid format type %x\n", pFormat[0]);
4883 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4887 alignment = pFormat[1] + 1;
4889 if (pFormat[0] == RPC_FC_SMVARRAY)
4892 pFormat += sizeof(WORD);
4893 elements = *(const WORD*)pFormat;
4894 pFormat += sizeof(WORD);
4899 pFormat += sizeof(DWORD);
4900 elements = *(const DWORD*)pFormat;
4901 pFormat += sizeof(DWORD);
4904 pFormat += sizeof(WORD);
4906 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4907 if ((pStubMsg->ActualCount > elements) ||
4908 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4910 RpcRaiseException(RPC_S_INVALID_BOUND);
4914 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4917 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
4925 return *(const UCHAR *)pMemory;
4930 return *(const USHORT *)pMemory;
4934 return *(const ULONG *)pMemory;
4936 FIXME("Unhandled base type: 0x%02x\n", fc);
4941 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4942 unsigned long discriminant,
4943 PFORMAT_STRING pFormat)
4945 unsigned short num_arms, arm, type;
4947 num_arms = *(const SHORT*)pFormat & 0x0fff;
4949 for(arm = 0; arm < num_arms; arm++)
4951 if(discriminant == *(const ULONG*)pFormat)
4959 type = *(const unsigned short*)pFormat;
4960 TRACE("type %04x\n", type);
4961 if(arm == num_arms) /* default arm extras */
4965 ERR("no arm for 0x%lx and no default case\n", discriminant);
4966 RpcRaiseException(RPC_S_INVALID_TAG);
4971 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
4978 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
4980 unsigned short type;
4984 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4988 type = *(const unsigned short*)pFormat;
4989 if((type & 0xff00) == 0x8000)
4991 unsigned char basetype = LOBYTE(type);
4992 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
4996 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4997 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5000 unsigned char *saved_buffer = NULL;
5001 int pointer_buffer_mark_set = 0;
5008 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5009 saved_buffer = pStubMsg->Buffer;
5010 if (pStubMsg->PointerBufferMark)
5012 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5013 pStubMsg->PointerBufferMark = NULL;
5014 pointer_buffer_mark_set = 1;
5017 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5019 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5020 if (pointer_buffer_mark_set)
5022 STD_OVERFLOW_CHECK(pStubMsg);
5023 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5024 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5026 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5027 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5028 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5030 pStubMsg->Buffer = saved_buffer + 4;
5034 m(pStubMsg, pMemory, desc);
5037 else FIXME("no marshaller for embedded type %02x\n", *desc);
5042 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5043 unsigned char **ppMemory,
5045 PFORMAT_STRING pFormat,
5046 unsigned char fMustAlloc)
5048 unsigned short type;
5052 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5056 type = *(const unsigned short*)pFormat;
5057 if((type & 0xff00) == 0x8000)
5059 unsigned char basetype = LOBYTE(type);
5060 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5064 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5065 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5068 unsigned char *saved_buffer = NULL;
5069 int pointer_buffer_mark_set = 0;
5076 **(void***)ppMemory = NULL;
5077 ALIGN_POINTER(pStubMsg->Buffer, 4);
5078 saved_buffer = pStubMsg->Buffer;
5079 if (pStubMsg->PointerBufferMark)
5081 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5082 pStubMsg->PointerBufferMark = NULL;
5083 pointer_buffer_mark_set = 1;
5086 pStubMsg->Buffer += 4; /* for pointer ID */
5088 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5090 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5091 saved_buffer, pStubMsg->BufferEnd);
5092 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5095 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5096 if (pointer_buffer_mark_set)
5098 STD_OVERFLOW_CHECK(pStubMsg);
5099 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5100 pStubMsg->Buffer = saved_buffer + 4;
5104 m(pStubMsg, ppMemory, desc, fMustAlloc);
5107 else FIXME("no marshaller for embedded type %02x\n", *desc);
5112 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5113 unsigned char *pMemory,
5115 PFORMAT_STRING pFormat)
5117 unsigned short type;
5121 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5125 type = *(const unsigned short*)pFormat;
5126 if((type & 0xff00) == 0x8000)
5128 unsigned char basetype = LOBYTE(type);
5129 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5133 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5134 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5143 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5144 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5145 if (!pStubMsg->IgnoreEmbeddedPointers)
5147 int saved_buffer_length = pStubMsg->BufferLength;
5148 pStubMsg->BufferLength = pStubMsg->PointerLength;
5149 pStubMsg->PointerLength = 0;
5150 if(!pStubMsg->BufferLength)
5151 ERR("BufferLength == 0??\n");
5152 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5153 pStubMsg->PointerLength = pStubMsg->BufferLength;
5154 pStubMsg->BufferLength = saved_buffer_length;
5158 m(pStubMsg, pMemory, desc);
5161 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5165 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5167 PFORMAT_STRING pFormat)
5169 unsigned short type, size;
5171 size = *(const unsigned short*)pFormat;
5172 pStubMsg->Memory += size;
5175 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5179 type = *(const unsigned short*)pFormat;
5180 if((type & 0xff00) == 0x8000)
5182 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5186 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5187 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5188 unsigned char *saved_buffer;
5197 ALIGN_POINTER(pStubMsg->Buffer, 4);
5198 saved_buffer = pStubMsg->Buffer;
5199 safe_buffer_increment(pStubMsg, 4);
5200 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
5201 pStubMsg->MemorySize += 4;
5202 if (!pStubMsg->IgnoreEmbeddedPointers)
5203 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5206 return m(pStubMsg, desc);
5209 else FIXME("no marshaller for embedded type %02x\n", *desc);
5212 TRACE("size %d\n", size);
5216 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5217 unsigned char *pMemory,
5219 PFORMAT_STRING pFormat)
5221 unsigned short type;
5225 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5229 type = *(const unsigned short*)pFormat;
5230 if((type & 0xff00) != 0x8000)
5232 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5233 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5242 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5245 m(pStubMsg, pMemory, desc);
5248 else FIXME("no freer for embedded type %02x\n", *desc);
5252 /***********************************************************************
5253 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5255 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5256 unsigned char *pMemory,
5257 PFORMAT_STRING pFormat)
5259 unsigned char switch_type;
5260 unsigned char increment;
5263 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5266 switch_type = *pFormat & 0xf;
5267 increment = (*pFormat & 0xf0) >> 4;
5270 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5272 switch_value = get_discriminant(switch_type, pMemory);
5273 TRACE("got switch value 0x%x\n", switch_value);
5275 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5276 pMemory += increment;
5278 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5281 /***********************************************************************
5282 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5284 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5285 unsigned char **ppMemory,
5286 PFORMAT_STRING pFormat,
5287 unsigned char fMustAlloc)
5289 unsigned char switch_type;
5290 unsigned char increment;
5292 unsigned short size;
5293 unsigned char *pMemoryArm;
5295 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5298 switch_type = *pFormat & 0xf;
5299 increment = (*pFormat & 0xf0) >> 4;
5302 ALIGN_POINTER(pStubMsg->Buffer, increment);
5303 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5304 TRACE("got switch value 0x%x\n", switch_value);
5306 size = *(const unsigned short*)pFormat + increment;
5307 if(!*ppMemory || fMustAlloc)
5308 *ppMemory = NdrAllocate(pStubMsg, size);
5310 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5311 pMemoryArm = *ppMemory + increment;
5313 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
5316 /***********************************************************************
5317 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5319 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5320 unsigned char *pMemory,
5321 PFORMAT_STRING pFormat)
5323 unsigned char switch_type;
5324 unsigned char increment;
5327 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5330 switch_type = *pFormat & 0xf;
5331 increment = (*pFormat & 0xf0) >> 4;
5334 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5335 switch_value = get_discriminant(switch_type, pMemory);
5336 TRACE("got switch value 0x%x\n", switch_value);
5338 /* Add discriminant size */
5339 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5340 pMemory += increment;
5342 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5345 /***********************************************************************
5346 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5348 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5349 PFORMAT_STRING pFormat)
5351 unsigned char switch_type;
5352 unsigned char increment;
5355 switch_type = *pFormat & 0xf;
5356 increment = (*pFormat & 0xf0) >> 4;
5359 ALIGN_POINTER(pStubMsg->Buffer, increment);
5360 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5361 TRACE("got switch value 0x%x\n", switch_value);
5363 pStubMsg->Memory += increment;
5365 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5368 /***********************************************************************
5369 * NdrEncapsulatedUnionFree [RPCRT4.@]
5371 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5372 unsigned char *pMemory,
5373 PFORMAT_STRING pFormat)
5375 unsigned char switch_type;
5376 unsigned char increment;
5379 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5382 switch_type = *pFormat & 0xf;
5383 increment = (*pFormat & 0xf0) >> 4;
5386 switch_value = get_discriminant(switch_type, pMemory);
5387 TRACE("got switch value 0x%x\n", switch_value);
5389 pMemory += increment;
5391 return union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5394 /***********************************************************************
5395 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5397 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5398 unsigned char *pMemory,
5399 PFORMAT_STRING pFormat)
5401 unsigned char switch_type;
5403 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5406 switch_type = *pFormat;
5409 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5410 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5411 /* Marshall discriminant */
5412 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5414 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5417 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5418 PFORMAT_STRING *ppFormat)
5420 long discriminant = 0;
5430 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5439 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5440 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5448 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5449 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5454 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5458 if (pStubMsg->fHasNewCorrDesc)
5462 return discriminant;
5465 /**********************************************************************
5466 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5468 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5469 unsigned char **ppMemory,
5470 PFORMAT_STRING pFormat,
5471 unsigned char fMustAlloc)
5474 unsigned short size;
5476 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5479 /* Unmarshall discriminant */
5480 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5481 TRACE("unmarshalled discriminant %lx\n", discriminant);
5483 pFormat += *(const SHORT*)pFormat;
5485 size = *(const unsigned short*)pFormat;
5487 if(!*ppMemory || fMustAlloc)
5488 *ppMemory = NdrAllocate(pStubMsg, size);
5490 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5493 /***********************************************************************
5494 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5496 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5497 unsigned char *pMemory,
5498 PFORMAT_STRING pFormat)
5500 unsigned char switch_type;
5502 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5505 switch_type = *pFormat;
5508 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5509 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5510 /* Add discriminant size */
5511 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5513 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5516 /***********************************************************************
5517 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5519 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5520 PFORMAT_STRING pFormat)
5525 /* Unmarshall discriminant */
5526 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5527 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
5529 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
5532 /***********************************************************************
5533 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5535 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5536 unsigned char *pMemory,
5537 PFORMAT_STRING pFormat)
5539 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5543 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5544 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5546 return union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5549 /***********************************************************************
5550 * NdrByteCountPointerMarshall [RPCRT4.@]
5552 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5553 unsigned char *pMemory,
5554 PFORMAT_STRING pFormat)
5560 /***********************************************************************
5561 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5563 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5564 unsigned char **ppMemory,
5565 PFORMAT_STRING pFormat,
5566 unsigned char fMustAlloc)
5572 /***********************************************************************
5573 * NdrByteCountPointerBufferSize [RPCRT4.@]
5575 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5576 unsigned char *pMemory,
5577 PFORMAT_STRING pFormat)
5582 /***********************************************************************
5583 * NdrByteCountPointerMemorySize [RPCRT4.@]
5585 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5586 PFORMAT_STRING pFormat)
5592 /***********************************************************************
5593 * NdrByteCountPointerFree [RPCRT4.@]
5595 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
5596 unsigned char *pMemory,
5597 PFORMAT_STRING pFormat)
5602 /***********************************************************************
5603 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5605 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5606 unsigned char *pMemory,
5607 PFORMAT_STRING pFormat)
5613 /***********************************************************************
5614 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5616 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5617 unsigned char **ppMemory,
5618 PFORMAT_STRING pFormat,
5619 unsigned char fMustAlloc)
5625 /***********************************************************************
5626 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5628 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5629 unsigned char *pMemory,
5630 PFORMAT_STRING pFormat)
5635 /***********************************************************************
5636 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5638 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5639 PFORMAT_STRING pFormat)
5645 /***********************************************************************
5646 * NdrXmitOrRepAsFree [RPCRT4.@]
5648 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
5649 unsigned char *pMemory,
5650 PFORMAT_STRING pFormat)
5655 #include "pshpack1.h"
5659 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
5663 #include "poppack.h"
5665 /***********************************************************************
5666 * NdrRangeMarshall [internal]
5668 unsigned char *WINAPI NdrRangeMarshall(
5669 PMIDL_STUB_MESSAGE pStubMsg,
5670 unsigned char *pMemory,
5671 PFORMAT_STRING pFormat)
5673 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5674 unsigned char base_type;
5676 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5678 if (pRange->type != RPC_FC_RANGE)
5680 ERR("invalid format type %x\n", pRange->type);
5681 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5685 base_type = pRange->flags_type & 0xf;
5687 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
5690 /***********************************************************************
5691 * NdrRangeUnmarshall
5693 unsigned char *WINAPI NdrRangeUnmarshall(
5694 PMIDL_STUB_MESSAGE pStubMsg,
5695 unsigned char **ppMemory,
5696 PFORMAT_STRING pFormat,
5697 unsigned char fMustAlloc)
5699 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5700 unsigned char base_type;
5702 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5704 if (pRange->type != RPC_FC_RANGE)
5706 ERR("invalid format type %x\n", pRange->type);
5707 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5710 base_type = pRange->flags_type & 0xf;
5712 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5713 base_type, pRange->low_value, pRange->high_value);
5715 #define RANGE_UNMARSHALL(type, format_spec) \
5718 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5719 if (fMustAlloc || !*ppMemory) \
5720 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5721 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5723 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5724 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5725 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5727 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5728 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5730 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5731 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5732 (type)pRange->high_value); \
5733 RpcRaiseException(RPC_S_INVALID_BOUND); \
5736 TRACE("*ppMemory: %p\n", *ppMemory); \
5737 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5738 pStubMsg->Buffer += sizeof(type); \
5745 RANGE_UNMARSHALL(UCHAR, "%d");
5746 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5750 RANGE_UNMARSHALL(CHAR, "%u");
5751 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5753 case RPC_FC_WCHAR: /* FIXME: valid? */
5755 RANGE_UNMARSHALL(USHORT, "%u");
5756 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5759 RANGE_UNMARSHALL(SHORT, "%d");
5760 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5763 RANGE_UNMARSHALL(LONG, "%d");
5764 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5767 RANGE_UNMARSHALL(ULONG, "%u");
5768 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5772 FIXME("Unhandled enum type\n");
5774 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
5779 ERR("invalid range base type: 0x%02x\n", base_type);
5780 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5786 /***********************************************************************
5787 * NdrRangeBufferSize [internal]
5789 void WINAPI NdrRangeBufferSize(
5790 PMIDL_STUB_MESSAGE pStubMsg,
5791 unsigned char *pMemory,
5792 PFORMAT_STRING pFormat)
5794 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5795 unsigned char base_type;
5797 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5799 if (pRange->type != RPC_FC_RANGE)
5801 ERR("invalid format type %x\n", pRange->type);
5802 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5804 base_type = pRange->flags_type & 0xf;
5806 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
5809 /***********************************************************************
5810 * NdrRangeMemorySize [internal]
5812 ULONG WINAPI NdrRangeMemorySize(
5813 PMIDL_STUB_MESSAGE pStubMsg,
5814 PFORMAT_STRING pFormat)
5816 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5817 unsigned char base_type;
5819 if (pRange->type != RPC_FC_RANGE)
5821 ERR("invalid format type %x\n", pRange->type);
5822 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5825 base_type = pRange->flags_type & 0xf;
5827 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
5830 /***********************************************************************
5831 * NdrRangeFree [internal]
5833 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
5834 unsigned char *pMemory,
5835 PFORMAT_STRING pFormat)
5837 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5842 /***********************************************************************
5843 * NdrBaseTypeMarshall [internal]
5845 static unsigned char *WINAPI NdrBaseTypeMarshall(
5846 PMIDL_STUB_MESSAGE pStubMsg,
5847 unsigned char *pMemory,
5848 PFORMAT_STRING pFormat)
5850 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5858 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
5859 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
5864 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
5865 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
5866 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
5870 case RPC_FC_ERROR_STATUS_T:
5872 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
5873 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
5874 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
5877 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
5878 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
5881 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
5882 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
5885 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
5886 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
5887 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
5890 /* only 16-bits on the wire, so do a sanity check */
5891 if (*(UINT *)pMemory > SHRT_MAX)
5892 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
5893 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
5894 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5895 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5896 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
5897 pStubMsg->Buffer += sizeof(USHORT);
5898 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
5903 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5906 /* FIXME: what is the correct return value? */
5910 /***********************************************************************
5911 * NdrBaseTypeUnmarshall [internal]
5913 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
5914 PMIDL_STUB_MESSAGE pStubMsg,
5915 unsigned char **ppMemory,
5916 PFORMAT_STRING pFormat,
5917 unsigned char fMustAlloc)
5919 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5921 #define BASE_TYPE_UNMARSHALL(type) \
5922 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5923 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
5925 *ppMemory = pStubMsg->Buffer; \
5926 TRACE("*ppMemory: %p\n", *ppMemory); \
5931 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5932 TRACE("*ppMemory: %p\n", *ppMemory); \
5933 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5935 pStubMsg->Buffer += sizeof(type);
5943 BASE_TYPE_UNMARSHALL(UCHAR);
5944 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5949 BASE_TYPE_UNMARSHALL(USHORT);
5950 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5954 case RPC_FC_ERROR_STATUS_T:
5956 BASE_TYPE_UNMARSHALL(ULONG);
5957 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5960 BASE_TYPE_UNMARSHALL(float);
5961 TRACE("value: %f\n", **(float **)ppMemory);
5964 BASE_TYPE_UNMARSHALL(double);
5965 TRACE("value: %f\n", **(double **)ppMemory);
5968 BASE_TYPE_UNMARSHALL(ULONGLONG);
5969 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
5972 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5973 if (fMustAlloc || !*ppMemory)
5974 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
5975 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
5976 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5977 TRACE("*ppMemory: %p\n", *ppMemory);
5978 /* 16-bits on the wire, but int in memory */
5979 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
5980 pStubMsg->Buffer += sizeof(USHORT);
5981 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
5986 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5988 #undef BASE_TYPE_UNMARSHALL
5990 /* FIXME: what is the correct return value? */
5995 /***********************************************************************
5996 * NdrBaseTypeBufferSize [internal]
5998 static void WINAPI NdrBaseTypeBufferSize(
5999 PMIDL_STUB_MESSAGE pStubMsg,
6000 unsigned char *pMemory,
6001 PFORMAT_STRING pFormat)
6003 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6011 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6017 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
6018 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6023 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
6024 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6027 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
6028 safe_buffer_length_increment(pStubMsg, sizeof(float));
6031 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
6032 safe_buffer_length_increment(pStubMsg, sizeof(double));
6035 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
6036 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6038 case RPC_FC_ERROR_STATUS_T:
6039 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
6040 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6045 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6049 /***********************************************************************
6050 * NdrBaseTypeMemorySize [internal]
6052 static ULONG WINAPI NdrBaseTypeMemorySize(
6053 PMIDL_STUB_MESSAGE pStubMsg,
6054 PFORMAT_STRING pFormat)
6056 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6064 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6065 pStubMsg->MemorySize += sizeof(UCHAR);
6066 return sizeof(UCHAR);
6070 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6071 pStubMsg->MemorySize += sizeof(USHORT);
6072 return sizeof(USHORT);
6076 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6077 pStubMsg->MemorySize += sizeof(ULONG);
6078 return sizeof(ULONG);
6080 safe_buffer_increment(pStubMsg, sizeof(float));
6081 pStubMsg->MemorySize += sizeof(float);
6082 return sizeof(float);
6084 safe_buffer_increment(pStubMsg, sizeof(double));
6085 pStubMsg->MemorySize += sizeof(double);
6086 return sizeof(double);
6088 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6089 pStubMsg->MemorySize += sizeof(ULONGLONG);
6090 return sizeof(ULONGLONG);
6091 case RPC_FC_ERROR_STATUS_T:
6092 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6093 pStubMsg->MemorySize += sizeof(error_status_t);
6094 return sizeof(error_status_t);
6096 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6097 pStubMsg->MemorySize += sizeof(UINT);
6098 return sizeof(UINT);
6100 pStubMsg->MemorySize += sizeof(void *);
6101 return sizeof(void *);
6103 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6108 /***********************************************************************
6109 * NdrBaseTypeFree [internal]
6111 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6112 unsigned char *pMemory,
6113 PFORMAT_STRING pFormat)
6115 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6120 /***********************************************************************
6121 * NdrContextHandleBufferSize [internal]
6123 static void WINAPI NdrContextHandleBufferSize(
6124 PMIDL_STUB_MESSAGE pStubMsg,
6125 unsigned char *pMemory,
6126 PFORMAT_STRING pFormat)
6128 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6130 if (*pFormat != RPC_FC_BIND_CONTEXT)
6132 ERR("invalid format type %x\n", *pFormat);
6133 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6135 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
6136 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6139 /***********************************************************************
6140 * NdrContextHandleMarshall [internal]
6142 static unsigned char *WINAPI NdrContextHandleMarshall(
6143 PMIDL_STUB_MESSAGE pStubMsg,
6144 unsigned char *pMemory,
6145 PFORMAT_STRING pFormat)
6147 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6149 if (*pFormat != RPC_FC_BIND_CONTEXT)
6151 ERR("invalid format type %x\n", *pFormat);
6152 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6155 if (pFormat[1] & 0x80)
6156 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6158 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
6163 /***********************************************************************
6164 * NdrContextHandleUnmarshall [internal]
6166 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6167 PMIDL_STUB_MESSAGE pStubMsg,
6168 unsigned char **ppMemory,
6169 PFORMAT_STRING pFormat,
6170 unsigned char fMustAlloc)
6172 if (*pFormat != RPC_FC_BIND_CONTEXT)
6174 ERR("invalid format type %x\n", *pFormat);
6175 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6178 **(NDR_CCONTEXT **)ppMemory = NULL;
6179 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6184 /***********************************************************************
6185 * NdrClientContextMarshall [RPCRT4.@]
6187 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6188 NDR_CCONTEXT ContextHandle,
6191 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
6193 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
6195 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6197 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6198 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6199 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6202 /* FIXME: what does fCheck do? */
6203 NDRCContextMarshall(ContextHandle,
6206 pStubMsg->Buffer += cbNDRContext;
6209 /***********************************************************************
6210 * NdrClientContextUnmarshall [RPCRT4.@]
6212 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6213 NDR_CCONTEXT * pContextHandle,
6214 RPC_BINDING_HANDLE BindHandle)
6216 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
6218 ALIGN_POINTER(pStubMsg->Buffer, 4);
6220 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
6221 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6223 NDRCContextUnmarshall(pContextHandle,
6226 pStubMsg->RpcMsg->DataRepresentation);
6228 pStubMsg->Buffer += cbNDRContext;
6231 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6232 NDR_SCONTEXT ContextHandle,
6233 NDR_RUNDOWN RundownRoutine )
6235 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
6237 ALIGN_POINTER(pStubMsg->Buffer, 4);
6239 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6241 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6242 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6243 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6246 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6247 pStubMsg->Buffer, RundownRoutine, NULL,
6248 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6249 pStubMsg->Buffer += cbNDRContext;
6252 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6254 NDR_SCONTEXT ContextHandle;
6256 TRACE("(%p)\n", pStubMsg);
6258 ALIGN_POINTER(pStubMsg->Buffer, 4);
6260 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6262 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6263 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6264 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6267 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6269 pStubMsg->RpcMsg->DataRepresentation,
6270 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6271 pStubMsg->Buffer += cbNDRContext;
6273 return ContextHandle;
6276 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6277 unsigned char* pMemory,
6278 PFORMAT_STRING pFormat)
6280 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6283 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6284 PFORMAT_STRING pFormat)
6286 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6287 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6289 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6291 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6292 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6293 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6294 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6295 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6297 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6298 if_id = &sif->InterfaceId;
6301 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
6302 pStubMsg->RpcMsg->DataRepresentation, if_id,
6306 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6307 NDR_SCONTEXT ContextHandle,
6308 NDR_RUNDOWN RundownRoutine,
6309 PFORMAT_STRING pFormat)
6311 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6312 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6314 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6316 ALIGN_POINTER(pStubMsg->Buffer, 4);
6318 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6320 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6321 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6322 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6325 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6326 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6327 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6328 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6329 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6331 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6332 if_id = &sif->InterfaceId;
6335 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6336 pStubMsg->Buffer, RundownRoutine, if_id, flags);
6337 pStubMsg->Buffer += cbNDRContext;
6340 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6341 PFORMAT_STRING pFormat)
6343 NDR_SCONTEXT ContextHandle;
6344 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6345 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6347 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6349 ALIGN_POINTER(pStubMsg->Buffer, 4);
6351 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6353 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6354 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6355 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6358 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6359 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6360 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6361 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6362 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6364 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6365 if_id = &sif->InterfaceId;
6368 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6370 pStubMsg->RpcMsg->DataRepresentation,
6372 pStubMsg->Buffer += cbNDRContext;
6374 return ContextHandle;
6377 /***********************************************************************
6378 * NdrCorrelationInitialize [RPCRT4.@]
6380 * Initializes correlation validity checking.
6383 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6384 * pMemory [I] Pointer to memory to use as a cache.
6385 * CacheSize [I] Size of the memory pointed to by pMemory.
6386 * Flags [I] Reserved. Set to zero.
6391 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
6393 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
6394 pStubMsg->fHasNewCorrDesc = TRUE;
6397 /***********************************************************************
6398 * NdrCorrelationPass [RPCRT4.@]
6400 * Performs correlation validity checking.
6403 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6408 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
6410 FIXME("(%p): stub\n", pStubMsg);
6413 /***********************************************************************
6414 * NdrCorrelationFree [RPCRT4.@]
6416 * Frees any resources used while unmarshalling parameters that need
6417 * correlation validity checking.
6420 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6425 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
6427 FIXME("(%p): stub\n", pStubMsg);