4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * - Byte count pointers
24 * - transmit_as/represent as
25 * - Multi-dimensional arrays
26 * - Conversion functions (NdrConvert)
27 * - Checks for integer addition overflow in base type and user marshall functions
43 #include "wine/unicode.h"
44 #include "wine/rpcfc.h"
46 #include "wine/debug.h"
48 WINE_DEFAULT_DEBUG_CHANNEL(ole);
51 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
52 (*((UINT32 *)(pchar)) = (uint32))
54 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
55 (*((UINT32 *)(pchar)))
57 /* these would work for i386 too, but less efficient */
58 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
59 (*(pchar) = LOBYTE(LOWORD(uint32)), \
60 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
61 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
62 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
63 (uint32)) /* allow as r-value */
65 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
67 MAKEWORD(*(pchar), *((pchar)+1)), \
68 MAKEWORD(*((pchar)+2), *((pchar)+3))))
71 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
72 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
73 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
74 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
75 *(pchar) = HIBYTE(HIWORD(uint32)), \
76 (uint32)) /* allow as r-value */
78 #define BIG_ENDIAN_UINT32_READ(pchar) \
80 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
81 MAKEWORD(*((pchar)+1), *(pchar))))
83 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
84 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
85 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
86 # define NDR_LOCAL_UINT32_READ(pchar) \
87 BIG_ENDIAN_UINT32_READ(pchar)
89 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
90 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
91 # define NDR_LOCAL_UINT32_READ(pchar) \
92 LITTLE_ENDIAN_UINT32_READ(pchar)
95 /* _Align must be the desired alignment,
96 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
97 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
98 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
99 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
100 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
101 #define ALIGN_POINTER_CLEAR(_Ptr, _Align) \
103 memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \
104 ALIGN_POINTER(_Ptr, _Align); \
107 #define STD_OVERFLOW_CHECK(_Msg) do { \
108 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
109 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
110 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
113 #define NDR_TABLE_SIZE 128
114 #define NDR_TABLE_MASK 127
116 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
117 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
118 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
119 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
120 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
122 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
123 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
124 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
126 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
128 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
129 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
130 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
131 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
135 NdrPointerMarshall, NdrPointerMarshall,
136 NdrPointerMarshall, NdrPointerMarshall,
138 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
139 NdrConformantStructMarshall, NdrConformantStructMarshall,
140 NdrConformantVaryingStructMarshall,
141 NdrComplexStructMarshall,
143 NdrConformantArrayMarshall,
144 NdrConformantVaryingArrayMarshall,
145 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
146 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
147 NdrComplexArrayMarshall,
149 NdrConformantStringMarshall, 0, 0,
150 NdrConformantStringMarshall,
151 NdrNonConformantStringMarshall, 0, 0, 0,
153 NdrEncapsulatedUnionMarshall,
154 NdrNonEncapsulatedUnionMarshall,
155 NdrByteCountPointerMarshall,
156 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
158 NdrInterfacePointerMarshall,
160 NdrContextHandleMarshall,
163 NdrUserMarshalMarshall,
168 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
170 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
171 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
172 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
173 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
175 NdrBaseTypeUnmarshall,
177 NdrPointerUnmarshall, NdrPointerUnmarshall,
178 NdrPointerUnmarshall, NdrPointerUnmarshall,
180 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
181 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
182 NdrConformantVaryingStructUnmarshall,
183 NdrComplexStructUnmarshall,
185 NdrConformantArrayUnmarshall,
186 NdrConformantVaryingArrayUnmarshall,
187 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
188 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
189 NdrComplexArrayUnmarshall,
191 NdrConformantStringUnmarshall, 0, 0,
192 NdrConformantStringUnmarshall,
193 NdrNonConformantStringUnmarshall, 0, 0, 0,
195 NdrEncapsulatedUnionUnmarshall,
196 NdrNonEncapsulatedUnionUnmarshall,
197 NdrByteCountPointerUnmarshall,
198 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
200 NdrInterfacePointerUnmarshall,
202 NdrContextHandleUnmarshall,
205 NdrUserMarshalUnmarshall,
210 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
212 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
213 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
214 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
215 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
217 NdrBaseTypeBufferSize,
219 NdrPointerBufferSize, NdrPointerBufferSize,
220 NdrPointerBufferSize, NdrPointerBufferSize,
222 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
223 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
224 NdrConformantVaryingStructBufferSize,
225 NdrComplexStructBufferSize,
227 NdrConformantArrayBufferSize,
228 NdrConformantVaryingArrayBufferSize,
229 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
230 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
231 NdrComplexArrayBufferSize,
233 NdrConformantStringBufferSize, 0, 0,
234 NdrConformantStringBufferSize,
235 NdrNonConformantStringBufferSize, 0, 0, 0,
237 NdrEncapsulatedUnionBufferSize,
238 NdrNonEncapsulatedUnionBufferSize,
239 NdrByteCountPointerBufferSize,
240 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
242 NdrInterfacePointerBufferSize,
244 NdrContextHandleBufferSize,
247 NdrUserMarshalBufferSize,
252 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
254 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
255 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
256 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
257 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
259 NdrBaseTypeMemorySize,
261 NdrPointerMemorySize, NdrPointerMemorySize,
262 NdrPointerMemorySize, NdrPointerMemorySize,
264 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
265 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
266 NdrConformantVaryingStructMemorySize,
267 NdrComplexStructMemorySize,
269 NdrConformantArrayMemorySize,
270 NdrConformantVaryingArrayMemorySize,
271 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
272 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
273 NdrComplexArrayMemorySize,
275 NdrConformantStringMemorySize, 0, 0,
276 NdrConformantStringMemorySize,
277 NdrNonConformantStringMemorySize, 0, 0, 0,
279 NdrEncapsulatedUnionMemorySize,
280 NdrNonEncapsulatedUnionMemorySize,
281 NdrByteCountPointerMemorySize,
282 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
284 NdrInterfacePointerMemorySize,
289 NdrUserMarshalMemorySize,
294 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
296 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
297 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
298 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
299 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
303 NdrPointerFree, NdrPointerFree,
304 NdrPointerFree, NdrPointerFree,
306 NdrSimpleStructFree, NdrSimpleStructFree,
307 NdrConformantStructFree, NdrConformantStructFree,
308 NdrConformantVaryingStructFree,
309 NdrComplexStructFree,
311 NdrConformantArrayFree,
312 NdrConformantVaryingArrayFree,
313 NdrFixedArrayFree, NdrFixedArrayFree,
314 NdrVaryingArrayFree, NdrVaryingArrayFree,
320 NdrEncapsulatedUnionFree,
321 NdrNonEncapsulatedUnionFree,
323 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
325 NdrInterfacePointerFree,
336 typedef struct _NDR_MEMORY_LIST
341 struct _NDR_MEMORY_LIST *next;
344 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
346 /***********************************************************************
347 * NdrAllocate [RPCRT4.@]
349 * Allocates a block of memory using pStubMsg->pfnAllocate.
352 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
353 * len [I] Size of memory block to allocate.
356 * The memory block of size len that was allocated.
359 * The memory block is always 8-byte aligned.
360 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
361 * exception is raised.
363 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
368 NDR_MEMORY_LIST *mem_list;
370 aligned_len = ALIGNED_LENGTH(len, 8);
371 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
372 /* check for overflow */
373 if (adjusted_len < len)
375 ERR("overflow of adjusted_len %d, len %d\n", adjusted_len, len);
376 RpcRaiseException(RPC_X_BAD_STUB_DATA);
379 p = pStubMsg->pfnAllocate(adjusted_len);
380 if (!p) RpcRaiseException(ERROR_OUTOFMEMORY);
382 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
383 mem_list->magic = MEML_MAGIC;
384 mem_list->size = aligned_len;
385 mem_list->reserved = 0;
386 mem_list->next = pStubMsg->pMemoryList;
387 pStubMsg->pMemoryList = mem_list;
393 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
395 TRACE("(%p, %p)\n", pStubMsg, Pointer);
397 pStubMsg->pfnFree(Pointer);
400 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
402 return (*(const ULONG *)pFormat != -1);
405 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
407 ALIGN_POINTER(pStubMsg->Buffer, 4);
408 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
409 RpcRaiseException(RPC_X_BAD_STUB_DATA);
410 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
411 pStubMsg->Buffer += 4;
412 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
413 if (pStubMsg->fHasNewCorrDesc)
419 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
421 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
423 pStubMsg->Offset = 0;
424 pStubMsg->ActualCount = pStubMsg->MaxCount;
428 ALIGN_POINTER(pStubMsg->Buffer, 4);
429 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
430 RpcRaiseException(RPC_X_BAD_STUB_DATA);
431 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
432 pStubMsg->Buffer += 4;
433 TRACE("offset is %d\n", pStubMsg->Offset);
434 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
435 pStubMsg->Buffer += 4;
436 TRACE("variance is %d\n", pStubMsg->ActualCount);
438 if ((pStubMsg->ActualCount > MaxValue) ||
439 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
441 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
442 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
443 RpcRaiseException(RPC_S_INVALID_BOUND);
448 if (pStubMsg->fHasNewCorrDesc)
454 /* writes the conformance value to the buffer */
455 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
457 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
458 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
459 RpcRaiseException(RPC_X_BAD_STUB_DATA);
460 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
461 pStubMsg->Buffer += 4;
464 /* writes the variance values to the buffer */
465 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
467 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
468 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
469 RpcRaiseException(RPC_X_BAD_STUB_DATA);
470 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
471 pStubMsg->Buffer += 4;
472 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
473 pStubMsg->Buffer += 4;
476 /* requests buffer space for the conformance value */
477 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
479 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
480 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
481 RpcRaiseException(RPC_X_BAD_STUB_DATA);
482 pStubMsg->BufferLength += 4;
485 /* requests buffer space for the variance values */
486 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
488 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
489 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
490 RpcRaiseException(RPC_X_BAD_STUB_DATA);
491 pStubMsg->BufferLength += 8;
494 PFORMAT_STRING ComputeConformanceOrVariance(
495 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
496 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
498 BYTE dtype = pFormat[0] & 0xf;
499 short ofs = *(const short *)&pFormat[2];
503 if (!IsConformanceOrVariancePresent(pFormat)) {
504 /* null descriptor */
509 switch (pFormat[0] & 0xf0) {
510 case RPC_FC_NORMAL_CONFORMANCE:
511 TRACE("normal conformance, ofs=%d\n", ofs);
514 case RPC_FC_POINTER_CONFORMANCE:
515 TRACE("pointer conformance, ofs=%d\n", ofs);
516 ptr = pStubMsg->Memory;
518 case RPC_FC_TOP_LEVEL_CONFORMANCE:
519 TRACE("toplevel conformance, ofs=%d\n", ofs);
520 if (pStubMsg->StackTop) {
521 ptr = pStubMsg->StackTop;
524 /* -Os mode, *pCount is already set */
528 case RPC_FC_CONSTANT_CONFORMANCE:
529 data = ofs | ((DWORD)pFormat[1] << 16);
530 TRACE("constant conformance, val=%d\n", data);
533 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
534 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
535 if (pStubMsg->StackTop) {
536 ptr = pStubMsg->StackTop;
544 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
547 switch (pFormat[1]) {
548 case RPC_FC_DEREFERENCE:
549 ptr = *(LPVOID*)((char *)ptr + ofs);
551 case RPC_FC_CALLBACK:
553 unsigned char *old_stack_top = pStubMsg->StackTop;
554 pStubMsg->StackTop = ptr;
556 /* ofs is index into StubDesc->apfnExprEval */
557 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
558 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
560 pStubMsg->StackTop = old_stack_top;
562 /* the callback function always stores the computed value in MaxCount */
563 *pCount = pStubMsg->MaxCount;
567 ptr = (char *)ptr + ofs;
580 data = *(USHORT*)ptr;
591 FIXME("unknown conformance data type %x\n", dtype);
594 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
597 switch (pFormat[1]) {
598 case RPC_FC_DEREFERENCE: /* already handled */
615 FIXME("unknown conformance op %d\n", pFormat[1]);
620 TRACE("resulting conformance is %ld\n", *pCount);
621 if (pStubMsg->fHasNewCorrDesc)
627 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
628 * the result overflows 32-bits */
629 static inline ULONG safe_multiply(ULONG a, ULONG b)
631 ULONGLONG ret = (ULONGLONG)a * b;
632 if (ret > 0xffffffff)
634 RpcRaiseException(RPC_S_INVALID_BOUND);
640 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
642 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
643 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
644 RpcRaiseException(RPC_X_BAD_STUB_DATA);
645 pStubMsg->Buffer += size;
648 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
650 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
652 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
653 pStubMsg->BufferLength, size);
654 RpcRaiseException(RPC_X_BAD_STUB_DATA);
656 pStubMsg->BufferLength += size;
659 /* copies data from the buffer, checking that there is enough data in the buffer
661 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
663 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
664 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
666 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
667 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
668 RpcRaiseException(RPC_X_BAD_STUB_DATA);
670 if (p == pStubMsg->Buffer)
671 ERR("pointer is the same as the buffer\n");
672 memcpy(p, pStubMsg->Buffer, size);
673 pStubMsg->Buffer += size;
676 /* copies data to the buffer, checking that there is enough space to do so */
677 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
679 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
680 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
682 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
683 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
685 RpcRaiseException(RPC_X_BAD_STUB_DATA);
687 memcpy(pStubMsg->Buffer, p, size);
688 pStubMsg->Buffer += size;
692 * NdrConformantString:
694 * What MS calls a ConformantString is, in DCE terminology,
695 * a Varying-Conformant String.
697 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
698 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
699 * into unmarshalled string)
700 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
702 * data: CHARTYPE[maxlen]
704 * ], where CHARTYPE is the appropriate character type (specified externally)
708 /***********************************************************************
709 * NdrConformantStringMarshall [RPCRT4.@]
711 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
712 unsigned char *pszMessage, PFORMAT_STRING pFormat)
716 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
718 if (*pFormat == RPC_FC_C_CSTRING) {
719 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
720 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
723 else if (*pFormat == RPC_FC_C_WSTRING) {
724 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
725 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
729 ERR("Unhandled string type: %#x\n", *pFormat);
730 /* FIXME: raise an exception. */
734 if (pFormat[1] == RPC_FC_STRING_SIZED)
735 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
737 pStubMsg->MaxCount = pStubMsg->ActualCount;
738 pStubMsg->Offset = 0;
739 WriteConformance(pStubMsg);
740 WriteVariance(pStubMsg);
742 size = safe_multiply(esize, pStubMsg->ActualCount);
743 safe_copy_to_buffer(pStubMsg, pszMessage, size); /* the string itself */
746 return NULL; /* is this always right? */
749 /***********************************************************************
750 * NdrConformantStringBufferSize [RPCRT4.@]
752 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
753 unsigned char* pMemory, PFORMAT_STRING pFormat)
757 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
759 SizeConformance(pStubMsg);
760 SizeVariance(pStubMsg);
762 if (*pFormat == RPC_FC_C_CSTRING) {
763 TRACE("string=%s\n", debugstr_a((char*)pMemory));
764 pStubMsg->ActualCount = strlen((char*)pMemory)+1;
767 else if (*pFormat == RPC_FC_C_WSTRING) {
768 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
769 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;
773 ERR("Unhandled string type: %#x\n", *pFormat);
774 /* FIXME: raise an exception */
778 if (pFormat[1] == RPC_FC_STRING_SIZED)
779 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
781 pStubMsg->MaxCount = pStubMsg->ActualCount;
783 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
786 /************************************************************************
787 * NdrConformantStringMemorySize [RPCRT4.@]
789 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
790 PFORMAT_STRING pFormat )
792 ULONG bufsize, memsize, esize, i;
794 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
796 ReadConformance(pStubMsg, NULL);
797 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
799 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
801 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
802 pStubMsg->ActualCount, pStubMsg->MaxCount);
803 RpcRaiseException(RPC_S_INVALID_BOUND);
805 if (pStubMsg->Offset)
807 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
808 RpcRaiseException(RPC_S_INVALID_BOUND);
811 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
812 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
814 ERR("Unhandled string type: %#x\n", *pFormat);
815 /* FIXME: raise an exception */
819 memsize = safe_multiply(esize, pStubMsg->MaxCount);
820 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
822 /* strings must always have null terminating bytes */
825 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
826 RpcRaiseException(RPC_S_INVALID_BOUND);
829 /* verify the buffer is safe to access */
830 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
831 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
833 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
834 pStubMsg->BufferEnd, pStubMsg->Buffer);
835 RpcRaiseException(RPC_X_BAD_STUB_DATA);
838 for (i = bufsize - esize; i < bufsize; i++)
839 if (pStubMsg->Buffer[i] != 0)
841 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
842 i, pStubMsg->Buffer[i]);
843 RpcRaiseException(RPC_S_INVALID_BOUND);
846 safe_buffer_increment(pStubMsg, bufsize);
847 pStubMsg->MemorySize += memsize;
849 return pStubMsg->MemorySize;
852 /************************************************************************
853 * NdrConformantStringUnmarshall [RPCRT4.@]
855 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
856 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
858 ULONG bufsize, memsize, esize, i;
860 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
861 pStubMsg, *ppMemory, pFormat, fMustAlloc);
863 assert(pFormat && ppMemory && pStubMsg);
865 ReadConformance(pStubMsg, NULL);
866 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
868 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
870 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
871 pStubMsg->ActualCount, pStubMsg->MaxCount);
872 RpcRaiseException(RPC_S_INVALID_BOUND);
875 if (pStubMsg->Offset)
877 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
878 RpcRaiseException(RPC_S_INVALID_BOUND);
882 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
883 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
885 ERR("Unhandled string type: %#x\n", *pFormat);
886 /* FIXME: raise an exception */
890 memsize = safe_multiply(esize, pStubMsg->MaxCount);
891 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
893 /* strings must always have null terminating bytes */
896 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
897 RpcRaiseException(RPC_S_INVALID_BOUND);
901 /* verify the buffer is safe to access */
902 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
903 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
905 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
906 pStubMsg->BufferEnd, pStubMsg->Buffer);
907 RpcRaiseException(RPC_X_BAD_STUB_DATA);
911 for (i = bufsize - esize; i < bufsize; i++)
912 if (pStubMsg->Buffer[i] != 0)
914 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
915 i, pStubMsg->Buffer[i]);
916 RpcRaiseException(RPC_S_INVALID_BOUND);
921 *ppMemory = NdrAllocate(pStubMsg, memsize);
924 if (!pStubMsg->IsClient && !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
925 /* if the data in the RPC buffer is big enough, we just point straight
927 *ppMemory = pStubMsg->Buffer;
929 *ppMemory = NdrAllocate(pStubMsg, memsize);
932 if (*ppMemory == pStubMsg->Buffer)
933 safe_buffer_increment(pStubMsg, bufsize);
935 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
937 if (*pFormat == RPC_FC_C_CSTRING) {
938 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
940 else if (*pFormat == RPC_FC_C_WSTRING) {
941 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
944 return NULL; /* FIXME: is this always right? */
947 /***********************************************************************
948 * NdrNonConformantStringMarshall [RPCRT4.@]
950 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
951 unsigned char *pMemory,
952 PFORMAT_STRING pFormat)
954 ULONG esize, size, maxsize;
956 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
958 maxsize = *(USHORT *)&pFormat[2];
960 if (*pFormat == RPC_FC_CSTRING)
963 const char *str = (const char *)pMemory;
964 for (i = 0; i < maxsize && *str; i++, str++)
966 TRACE("string=%s\n", debugstr_an(str, i));
967 pStubMsg->ActualCount = i + 1;
970 else if (*pFormat == RPC_FC_WSTRING)
973 const WCHAR *str = (const WCHAR *)pMemory;
974 for (i = 0; i < maxsize && *str; i++, str++)
976 TRACE("string=%s\n", debugstr_wn(str, i));
977 pStubMsg->ActualCount = i + 1;
982 ERR("Unhandled string type: %#x\n", *pFormat);
983 RpcRaiseException(RPC_X_BAD_STUB_DATA);
986 pStubMsg->Offset = 0;
987 WriteVariance(pStubMsg);
989 size = safe_multiply(esize, pStubMsg->ActualCount);
990 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
995 /***********************************************************************
996 * NdrNonConformantStringUnmarshall [RPCRT4.@]
998 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
999 unsigned char **ppMemory,
1000 PFORMAT_STRING pFormat,
1001 unsigned char fMustAlloc)
1003 ULONG bufsize, memsize, esize, i, maxsize;
1005 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
1006 pStubMsg, *ppMemory, pFormat, fMustAlloc);
1008 maxsize = *(USHORT *)&pFormat[2];
1010 ReadVariance(pStubMsg, NULL, maxsize);
1011 if (pStubMsg->Offset)
1013 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
1014 RpcRaiseException(RPC_S_INVALID_BOUND);
1017 if (*pFormat == RPC_FC_CSTRING) esize = 1;
1018 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
1021 ERR("Unhandled string type: %#x\n", *pFormat);
1022 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1025 memsize = esize * maxsize;
1026 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
1028 if (bufsize < esize)
1030 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
1031 RpcRaiseException(RPC_S_INVALID_BOUND);
1035 /* verify the buffer is safe to access */
1036 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
1037 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
1039 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
1040 pStubMsg->BufferEnd, pStubMsg->Buffer);
1041 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1045 /* strings must always have null terminating bytes */
1046 for (i = bufsize - esize; i < bufsize; i++)
1047 if (pStubMsg->Buffer[i] != 0)
1049 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
1050 i, pStubMsg->Buffer[i]);
1051 RpcRaiseException(RPC_S_INVALID_BOUND);
1054 if (fMustAlloc || !*ppMemory)
1055 *ppMemory = NdrAllocate(pStubMsg, memsize);
1057 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
1059 if (*pFormat == RPC_FC_CSTRING) {
1060 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
1062 else if (*pFormat == RPC_FC_WSTRING) {
1063 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
1069 /***********************************************************************
1070 * NdrNonConformantStringBufferSize [RPCRT4.@]
1072 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1073 unsigned char *pMemory,
1074 PFORMAT_STRING pFormat)
1076 ULONG esize, maxsize;
1078 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
1080 maxsize = *(USHORT *)&pFormat[2];
1082 SizeVariance(pStubMsg);
1084 if (*pFormat == RPC_FC_CSTRING)
1087 const char *str = (const char *)pMemory;
1088 for (i = 0; i < maxsize && *str; i++, str++)
1090 TRACE("string=%s\n", debugstr_an(str, i));
1091 pStubMsg->ActualCount = i + 1;
1094 else if (*pFormat == RPC_FC_WSTRING)
1097 const WCHAR *str = (const WCHAR *)pMemory;
1098 for (i = 0; i < maxsize && *str; i++, str++)
1100 TRACE("string=%s\n", debugstr_wn(str, i));
1101 pStubMsg->ActualCount = i + 1;
1106 ERR("Unhandled string type: %#x\n", *pFormat);
1107 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1110 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
1113 /***********************************************************************
1114 * NdrNonConformantStringMemorySize [RPCRT4.@]
1116 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1117 PFORMAT_STRING pFormat)
1119 ULONG bufsize, memsize, esize, i, maxsize;
1121 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
1123 maxsize = *(USHORT *)&pFormat[2];
1125 ReadVariance(pStubMsg, NULL, maxsize);
1127 if (pStubMsg->Offset)
1129 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
1130 RpcRaiseException(RPC_S_INVALID_BOUND);
1133 if (*pFormat == RPC_FC_CSTRING) esize = 1;
1134 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
1137 ERR("Unhandled string type: %#x\n", *pFormat);
1138 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1141 memsize = esize * maxsize;
1142 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
1144 /* strings must always have null terminating bytes */
1145 if (bufsize < esize)
1147 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
1148 RpcRaiseException(RPC_S_INVALID_BOUND);
1151 /* verify the buffer is safe to access */
1152 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
1153 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
1155 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
1156 pStubMsg->BufferEnd, pStubMsg->Buffer);
1157 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1160 for (i = bufsize - esize; i < bufsize; i++)
1161 if (pStubMsg->Buffer[i] != 0)
1163 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
1164 i, pStubMsg->Buffer[i]);
1165 RpcRaiseException(RPC_S_INVALID_BOUND);
1168 safe_buffer_increment(pStubMsg, bufsize);
1169 pStubMsg->MemorySize += memsize;
1171 return pStubMsg->MemorySize;
1174 static inline void dump_pointer_attr(unsigned char attr)
1176 if (attr & RPC_FC_P_ALLOCALLNODES)
1177 TRACE(" RPC_FC_P_ALLOCALLNODES");
1178 if (attr & RPC_FC_P_DONTFREE)
1179 TRACE(" RPC_FC_P_DONTFREE");
1180 if (attr & RPC_FC_P_ONSTACK)
1181 TRACE(" RPC_FC_P_ONSTACK");
1182 if (attr & RPC_FC_P_SIMPLEPOINTER)
1183 TRACE(" RPC_FC_P_SIMPLEPOINTER");
1184 if (attr & RPC_FC_P_DEREF)
1185 TRACE(" RPC_FC_P_DEREF");
1189 /***********************************************************************
1190 * PointerMarshall [internal]
1192 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1193 unsigned char *Buffer,
1194 unsigned char *Pointer,
1195 PFORMAT_STRING pFormat)
1197 unsigned type = pFormat[0], attr = pFormat[1];
1198 PFORMAT_STRING desc;
1201 int pointer_needs_marshaling;
1203 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
1204 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1206 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1207 else desc = pFormat + *(const SHORT*)pFormat;
1210 case RPC_FC_RP: /* ref pointer (always non-null) */
1213 ERR("NULL ref pointer is not allowed\n");
1214 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1216 pointer_needs_marshaling = 1;
1218 case RPC_FC_UP: /* unique pointer */
1219 case RPC_FC_OP: /* object pointer - same as unique here */
1221 pointer_needs_marshaling = 1;
1223 pointer_needs_marshaling = 0;
1224 pointer_id = (ULONG)Pointer;
1225 TRACE("writing 0x%08x to buffer\n", pointer_id);
1226 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
1229 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
1230 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
1231 TRACE("writing 0x%08x to buffer\n", pointer_id);
1232 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
1235 FIXME("unhandled ptr type=%02x\n", type);
1236 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1240 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
1242 if (pointer_needs_marshaling) {
1243 if (attr & RPC_FC_P_DEREF) {
1244 Pointer = *(unsigned char**)Pointer;
1245 TRACE("deref => %p\n", Pointer);
1247 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1248 if (m) m(pStubMsg, Pointer, desc);
1249 else FIXME("no marshaller for data type=%02x\n", *desc);
1252 STD_OVERFLOW_CHECK(pStubMsg);
1255 /***********************************************************************
1256 * PointerUnmarshall [internal]
1258 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1259 unsigned char *Buffer,
1260 unsigned char **pPointer,
1261 unsigned char *pSrcPointer,
1262 PFORMAT_STRING pFormat,
1263 unsigned char fMustAlloc)
1265 unsigned type = pFormat[0], attr = pFormat[1];
1266 PFORMAT_STRING desc;
1268 DWORD pointer_id = 0;
1269 int pointer_needs_unmarshaling;
1271 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
1272 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1274 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1275 else desc = pFormat + *(const SHORT*)pFormat;
1278 case RPC_FC_RP: /* ref pointer (always non-null) */
1279 pointer_needs_unmarshaling = 1;
1281 case RPC_FC_UP: /* unique pointer */
1282 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1283 TRACE("pointer_id is 0x%08x\n", pointer_id);
1285 pointer_needs_unmarshaling = 1;
1288 pointer_needs_unmarshaling = 0;
1291 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1292 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1293 TRACE("pointer_id is 0x%08x\n", pointer_id);
1294 if (!fMustAlloc && pSrcPointer)
1296 FIXME("free object pointer %p\n", pSrcPointer);
1300 pointer_needs_unmarshaling = 1;
1302 pointer_needs_unmarshaling = 0;
1305 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1306 TRACE("pointer_id is 0x%08x\n", pointer_id);
1307 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
1308 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
1311 FIXME("unhandled ptr type=%02x\n", type);
1312 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1316 if (pointer_needs_unmarshaling) {
1317 unsigned char *base_ptr_val = *pPointer;
1318 unsigned char **current_ptr = pPointer;
1319 if (pStubMsg->IsClient) {
1321 /* if we aren't forcing allocation of memory then try to use the existing
1322 * (source) pointer to unmarshall the data into so that [in,out]
1323 * parameters behave correctly. it doesn't matter if the parameter is
1324 * [out] only since in that case the pointer will be NULL. we force
1325 * allocation when the source pointer is NULL here instead of in the type
1326 * unmarshalling routine for the benefit of the deref code below */
1329 TRACE("setting *pPointer to %p\n", pSrcPointer);
1330 *pPointer = base_ptr_val = pSrcPointer;
1336 /* the memory in a stub is never initialised, so we have to work out here
1337 * whether we have to initialise it so we can use the optimisation of
1338 * setting the pointer to the buffer, if possible, or set fMustAlloc to
1340 if (attr & RPC_FC_P_DEREF) {
1343 base_ptr_val = NULL;
1344 *current_ptr = NULL;
1348 if (attr & RPC_FC_P_ALLOCALLNODES)
1349 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
1351 if (attr & RPC_FC_P_DEREF) {
1353 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
1354 *pPointer = base_ptr_val;
1355 current_ptr = (unsigned char **)base_ptr_val;
1357 current_ptr = *(unsigned char***)current_ptr;
1358 TRACE("deref => %p\n", current_ptr);
1359 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
1361 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1362 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
1363 else FIXME("no unmarshaller for data type=%02x\n", *desc);
1365 if (type == RPC_FC_FP)
1366 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
1370 TRACE("pointer=%p\n", *pPointer);
1373 /***********************************************************************
1374 * PointerBufferSize [internal]
1376 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1377 unsigned char *Pointer,
1378 PFORMAT_STRING pFormat)
1380 unsigned type = pFormat[0], attr = pFormat[1];
1381 PFORMAT_STRING desc;
1383 int pointer_needs_sizing;
1386 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1387 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1389 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1390 else desc = pFormat + *(const SHORT*)pFormat;
1393 case RPC_FC_RP: /* ref pointer (always non-null) */
1396 ERR("NULL ref pointer is not allowed\n");
1397 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1402 /* NULL pointer has no further representation */
1407 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1408 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1409 if (!pointer_needs_sizing)
1413 FIXME("unhandled ptr type=%02x\n", type);
1414 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1418 if (attr & RPC_FC_P_DEREF) {
1419 Pointer = *(unsigned char**)Pointer;
1420 TRACE("deref => %p\n", Pointer);
1423 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1424 if (m) m(pStubMsg, Pointer, desc);
1425 else FIXME("no buffersizer for data type=%02x\n", *desc);
1428 /***********************************************************************
1429 * PointerMemorySize [internal]
1431 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1432 unsigned char *Buffer,
1433 PFORMAT_STRING pFormat)
1435 unsigned type = pFormat[0], attr = pFormat[1];
1436 PFORMAT_STRING desc;
1438 DWORD pointer_id = 0;
1439 int pointer_needs_sizing;
1441 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1442 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1444 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1445 else desc = pFormat + *(const SHORT*)pFormat;
1448 case RPC_FC_RP: /* ref pointer (always non-null) */
1449 pointer_needs_sizing = 1;
1451 case RPC_FC_UP: /* unique pointer */
1452 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1453 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1454 TRACE("pointer_id is 0x%08x\n", pointer_id);
1456 pointer_needs_sizing = 1;
1458 pointer_needs_sizing = 0;
1463 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1464 TRACE("pointer_id is 0x%08x\n", pointer_id);
1465 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1466 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1470 FIXME("unhandled ptr type=%02x\n", type);
1471 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1475 if (attr & RPC_FC_P_DEREF) {
1479 if (pointer_needs_sizing) {
1480 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1481 if (m) m(pStubMsg, desc);
1482 else FIXME("no memorysizer for data type=%02x\n", *desc);
1485 return pStubMsg->MemorySize;
1488 /***********************************************************************
1489 * PointerFree [internal]
1491 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1492 unsigned char *Pointer,
1493 PFORMAT_STRING pFormat)
1495 unsigned type = pFormat[0], attr = pFormat[1];
1496 PFORMAT_STRING desc;
1498 unsigned char *current_pointer = Pointer;
1500 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1501 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1502 if (attr & RPC_FC_P_DONTFREE) return;
1504 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1505 else desc = pFormat + *(const SHORT*)pFormat;
1507 if (!Pointer) return;
1509 if (type == RPC_FC_FP) {
1510 int pointer_needs_freeing = NdrFullPointerFree(
1511 pStubMsg->FullPtrXlatTables, Pointer);
1512 if (!pointer_needs_freeing)
1516 if (attr & RPC_FC_P_DEREF) {
1517 current_pointer = *(unsigned char**)Pointer;
1518 TRACE("deref => %p\n", current_pointer);
1521 m = NdrFreer[*desc & NDR_TABLE_MASK];
1522 if (m) m(pStubMsg, current_pointer, desc);
1524 /* this check stops us from trying to free buffer memory. we don't have to
1525 * worry about clients, since they won't call this function.
1526 * we don't have to check for the buffer being reallocated because
1527 * BufferStart and BufferEnd won't be reset when allocating memory for
1528 * sending the response. we don't have to check for the new buffer here as
1529 * it won't be used a type memory, only for buffer memory */
1530 if (Pointer >= pStubMsg->BufferStart && Pointer < pStubMsg->BufferEnd)
1533 if (attr & RPC_FC_P_ONSTACK) {
1534 TRACE("not freeing stack ptr %p\n", Pointer);
1537 TRACE("freeing %p\n", Pointer);
1538 NdrFree(pStubMsg, Pointer);
1541 TRACE("not freeing %p\n", Pointer);
1544 /***********************************************************************
1545 * EmbeddedPointerMarshall
1547 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1548 unsigned char *pMemory,
1549 PFORMAT_STRING pFormat)
1551 unsigned char *Mark = pStubMsg->BufferMark;
1552 unsigned rep, count, stride;
1554 unsigned char *saved_buffer = NULL;
1556 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1558 if (*pFormat != RPC_FC_PP) return NULL;
1561 if (pStubMsg->PointerBufferMark)
1563 saved_buffer = pStubMsg->Buffer;
1564 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1565 pStubMsg->PointerBufferMark = NULL;
1568 while (pFormat[0] != RPC_FC_END) {
1569 switch (pFormat[0]) {
1571 FIXME("unknown repeat type %d\n", pFormat[0]);
1572 case RPC_FC_NO_REPEAT:
1578 case RPC_FC_FIXED_REPEAT:
1579 rep = *(const WORD*)&pFormat[2];
1580 stride = *(const WORD*)&pFormat[4];
1581 count = *(const WORD*)&pFormat[8];
1584 case RPC_FC_VARIABLE_REPEAT:
1585 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1586 stride = *(const WORD*)&pFormat[2];
1587 count = *(const WORD*)&pFormat[6];
1591 for (i = 0; i < rep; i++) {
1592 PFORMAT_STRING info = pFormat;
1593 unsigned char *membase = pMemory + (i * stride);
1594 unsigned char *bufbase = Mark + (i * stride);
1597 for (u=0; u<count; u++,info+=8) {
1598 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1599 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1600 unsigned char *saved_memory = pStubMsg->Memory;
1602 pStubMsg->Memory = pMemory;
1603 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1604 pStubMsg->Memory = saved_memory;
1607 pFormat += 8 * count;
1612 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1613 pStubMsg->Buffer = saved_buffer;
1616 STD_OVERFLOW_CHECK(pStubMsg);
1621 /***********************************************************************
1622 * EmbeddedPointerUnmarshall
1624 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1625 unsigned char *pDstMemoryPtrs,
1626 unsigned char *pSrcMemoryPtrs,
1627 PFORMAT_STRING pFormat,
1628 unsigned char fMustAlloc)
1630 unsigned char *Mark = pStubMsg->BufferMark;
1631 unsigned rep, count, stride;
1633 unsigned char *saved_buffer = NULL;
1635 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstMemoryPtrs, pSrcMemoryPtrs, pFormat, fMustAlloc);
1637 if (*pFormat != RPC_FC_PP) return NULL;
1640 if (pStubMsg->PointerBufferMark)
1642 saved_buffer = pStubMsg->Buffer;
1643 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1644 pStubMsg->PointerBufferMark = NULL;
1647 while (pFormat[0] != RPC_FC_END) {
1648 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1649 switch (pFormat[0]) {
1651 FIXME("unknown repeat type %d\n", pFormat[0]);
1652 case RPC_FC_NO_REPEAT:
1658 case RPC_FC_FIXED_REPEAT:
1659 rep = *(const WORD*)&pFormat[2];
1660 stride = *(const WORD*)&pFormat[4];
1661 count = *(const WORD*)&pFormat[8];
1664 case RPC_FC_VARIABLE_REPEAT:
1665 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1666 stride = *(const WORD*)&pFormat[2];
1667 count = *(const WORD*)&pFormat[6];
1671 for (i = 0; i < rep; i++) {
1672 PFORMAT_STRING info = pFormat;
1673 unsigned char *memdstbase = pDstMemoryPtrs + (i * stride);
1674 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1675 unsigned char *bufbase = Mark + (i * stride);
1678 for (u=0; u<count; u++,info+=8) {
1679 unsigned char **memdstptr = (unsigned char **)(memdstbase + *(const SHORT*)&info[0]);
1680 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1681 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1682 PointerUnmarshall(pStubMsg, bufptr, memdstptr, *memsrcptr, info+4, fMustAlloc);
1685 pFormat += 8 * count;
1690 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1691 pStubMsg->Buffer = saved_buffer;
1697 /***********************************************************************
1698 * EmbeddedPointerBufferSize
1700 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1701 unsigned char *pMemory,
1702 PFORMAT_STRING pFormat)
1704 unsigned rep, count, stride;
1706 ULONG saved_buffer_length = 0;
1708 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1710 if (pStubMsg->IgnoreEmbeddedPointers) return;
1712 if (*pFormat != RPC_FC_PP) return;
1715 if (pStubMsg->PointerLength)
1717 saved_buffer_length = pStubMsg->BufferLength;
1718 pStubMsg->BufferLength = pStubMsg->PointerLength;
1719 pStubMsg->PointerLength = 0;
1722 while (pFormat[0] != RPC_FC_END) {
1723 switch (pFormat[0]) {
1725 FIXME("unknown repeat type %d\n", pFormat[0]);
1726 case RPC_FC_NO_REPEAT:
1732 case RPC_FC_FIXED_REPEAT:
1733 rep = *(const WORD*)&pFormat[2];
1734 stride = *(const WORD*)&pFormat[4];
1735 count = *(const WORD*)&pFormat[8];
1738 case RPC_FC_VARIABLE_REPEAT:
1739 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1740 stride = *(const WORD*)&pFormat[2];
1741 count = *(const WORD*)&pFormat[6];
1745 for (i = 0; i < rep; i++) {
1746 PFORMAT_STRING info = pFormat;
1747 unsigned char *membase = pMemory + (i * stride);
1750 for (u=0; u<count; u++,info+=8) {
1751 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1752 unsigned char *saved_memory = pStubMsg->Memory;
1754 pStubMsg->Memory = pMemory;
1755 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1756 pStubMsg->Memory = saved_memory;
1759 pFormat += 8 * count;
1762 if (saved_buffer_length)
1764 pStubMsg->PointerLength = pStubMsg->BufferLength;
1765 pStubMsg->BufferLength = saved_buffer_length;
1769 /***********************************************************************
1770 * EmbeddedPointerMemorySize [internal]
1772 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1773 PFORMAT_STRING pFormat)
1775 unsigned char *Mark = pStubMsg->BufferMark;
1776 unsigned rep, count, stride;
1778 unsigned char *saved_buffer = NULL;
1780 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1782 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1784 if (pStubMsg->PointerBufferMark)
1786 saved_buffer = pStubMsg->Buffer;
1787 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1788 pStubMsg->PointerBufferMark = NULL;
1791 if (*pFormat != RPC_FC_PP) return 0;
1794 while (pFormat[0] != RPC_FC_END) {
1795 switch (pFormat[0]) {
1797 FIXME("unknown repeat type %d\n", pFormat[0]);
1798 case RPC_FC_NO_REPEAT:
1804 case RPC_FC_FIXED_REPEAT:
1805 rep = *(const WORD*)&pFormat[2];
1806 stride = *(const WORD*)&pFormat[4];
1807 count = *(const WORD*)&pFormat[8];
1810 case RPC_FC_VARIABLE_REPEAT:
1811 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1812 stride = *(const WORD*)&pFormat[2];
1813 count = *(const WORD*)&pFormat[6];
1817 for (i = 0; i < rep; i++) {
1818 PFORMAT_STRING info = pFormat;
1819 unsigned char *bufbase = Mark + (i * stride);
1821 for (u=0; u<count; u++,info+=8) {
1822 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1823 PointerMemorySize(pStubMsg, bufptr, info+4);
1826 pFormat += 8 * count;
1831 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1832 pStubMsg->Buffer = saved_buffer;
1838 /***********************************************************************
1839 * EmbeddedPointerFree [internal]
1841 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1842 unsigned char *pMemory,
1843 PFORMAT_STRING pFormat)
1845 unsigned rep, count, stride;
1848 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1849 if (*pFormat != RPC_FC_PP) return;
1852 while (pFormat[0] != RPC_FC_END) {
1853 switch (pFormat[0]) {
1855 FIXME("unknown repeat type %d\n", pFormat[0]);
1856 case RPC_FC_NO_REPEAT:
1862 case RPC_FC_FIXED_REPEAT:
1863 rep = *(const WORD*)&pFormat[2];
1864 stride = *(const WORD*)&pFormat[4];
1865 count = *(const WORD*)&pFormat[8];
1868 case RPC_FC_VARIABLE_REPEAT:
1869 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1870 stride = *(const WORD*)&pFormat[2];
1871 count = *(const WORD*)&pFormat[6];
1875 for (i = 0; i < rep; i++) {
1876 PFORMAT_STRING info = pFormat;
1877 unsigned char *membase = pMemory + (i * stride);
1880 for (u=0; u<count; u++,info+=8) {
1881 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1882 unsigned char *saved_memory = pStubMsg->Memory;
1884 pStubMsg->Memory = pMemory;
1885 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1886 pStubMsg->Memory = saved_memory;
1889 pFormat += 8 * count;
1893 /***********************************************************************
1894 * NdrPointerMarshall [RPCRT4.@]
1896 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1897 unsigned char *pMemory,
1898 PFORMAT_STRING pFormat)
1900 unsigned char *Buffer;
1902 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1904 /* incremement the buffer here instead of in PointerMarshall,
1905 * as that is used by embedded pointers which already handle the incrementing
1906 * the buffer, and shouldn't write any additional pointer data to the wire */
1907 if (*pFormat != RPC_FC_RP)
1909 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
1910 Buffer = pStubMsg->Buffer;
1911 safe_buffer_increment(pStubMsg, 4);
1914 Buffer = pStubMsg->Buffer;
1916 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1921 /***********************************************************************
1922 * NdrPointerUnmarshall [RPCRT4.@]
1924 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1925 unsigned char **ppMemory,
1926 PFORMAT_STRING pFormat,
1927 unsigned char fMustAlloc)
1929 unsigned char *Buffer;
1931 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1933 /* incremement the buffer here instead of in PointerUnmarshall,
1934 * as that is used by embedded pointers which already handle the incrementing
1935 * the buffer, and shouldn't read any additional pointer data from the
1937 if (*pFormat != RPC_FC_RP)
1939 ALIGN_POINTER(pStubMsg->Buffer, 4);
1940 Buffer = pStubMsg->Buffer;
1941 safe_buffer_increment(pStubMsg, 4);
1944 Buffer = pStubMsg->Buffer;
1946 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1951 /***********************************************************************
1952 * NdrPointerBufferSize [RPCRT4.@]
1954 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1955 unsigned char *pMemory,
1956 PFORMAT_STRING pFormat)
1958 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1960 /* incremement the buffer length here instead of in PointerBufferSize,
1961 * as that is used by embedded pointers which already handle the buffer
1962 * length, and shouldn't write anything more to the wire */
1963 if (*pFormat != RPC_FC_RP)
1965 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1966 safe_buffer_length_increment(pStubMsg, 4);
1969 PointerBufferSize(pStubMsg, pMemory, pFormat);
1972 /***********************************************************************
1973 * NdrPointerMemorySize [RPCRT4.@]
1975 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1976 PFORMAT_STRING pFormat)
1978 /* unsigned size = *(LPWORD)(pFormat+2); */
1979 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1980 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1984 /***********************************************************************
1985 * NdrPointerFree [RPCRT4.@]
1987 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1988 unsigned char *pMemory,
1989 PFORMAT_STRING pFormat)
1991 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1992 PointerFree(pStubMsg, pMemory, pFormat);
1995 /***********************************************************************
1996 * NdrSimpleTypeMarshall [RPCRT4.@]
1998 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1999 unsigned char FormatChar )
2001 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
2004 /***********************************************************************
2005 * NdrSimpleTypeUnmarshall [RPCRT4.@]
2007 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
2008 unsigned char FormatChar )
2010 NdrBaseTypeUnmarshall(pStubMsg, &pMemory, &FormatChar, 0);
2013 /***********************************************************************
2014 * NdrSimpleStructMarshall [RPCRT4.@]
2016 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2017 unsigned char *pMemory,
2018 PFORMAT_STRING pFormat)
2020 unsigned size = *(const WORD*)(pFormat+2);
2021 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2023 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
2025 pStubMsg->BufferMark = pStubMsg->Buffer;
2026 safe_copy_to_buffer(pStubMsg, pMemory, size);
2028 if (pFormat[0] != RPC_FC_STRUCT)
2029 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
2034 /***********************************************************************
2035 * NdrSimpleStructUnmarshall [RPCRT4.@]
2037 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2038 unsigned char **ppMemory,
2039 PFORMAT_STRING pFormat,
2040 unsigned char fMustAlloc)
2042 unsigned size = *(const WORD*)(pFormat+2);
2043 unsigned char *saved_buffer;
2044 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2046 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2049 *ppMemory = NdrAllocate(pStubMsg, size);
2052 if (!pStubMsg->IsClient && !*ppMemory)
2053 /* for servers, we just point straight into the RPC buffer */
2054 *ppMemory = pStubMsg->Buffer;
2057 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
2058 safe_buffer_increment(pStubMsg, size);
2059 if (pFormat[0] == RPC_FC_PSTRUCT)
2060 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
2062 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2063 if (*ppMemory != saved_buffer)
2064 memcpy(*ppMemory, saved_buffer, size);
2069 /***********************************************************************
2070 * NdrSimpleStructBufferSize [RPCRT4.@]
2072 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2073 unsigned char *pMemory,
2074 PFORMAT_STRING pFormat)
2076 unsigned size = *(const WORD*)(pFormat+2);
2077 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2079 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2081 safe_buffer_length_increment(pStubMsg, size);
2082 if (pFormat[0] != RPC_FC_STRUCT)
2083 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
2086 /***********************************************************************
2087 * NdrSimpleStructMemorySize [RPCRT4.@]
2089 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2090 PFORMAT_STRING pFormat)
2092 unsigned short size = *(const WORD *)(pFormat+2);
2094 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2096 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2097 pStubMsg->MemorySize += size;
2098 safe_buffer_increment(pStubMsg, size);
2100 if (pFormat[0] != RPC_FC_STRUCT)
2101 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
2102 return pStubMsg->MemorySize;
2105 /***********************************************************************
2106 * NdrSimpleStructFree [RPCRT4.@]
2108 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2109 unsigned char *pMemory,
2110 PFORMAT_STRING pFormat)
2112 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2113 if (pFormat[0] != RPC_FC_STRUCT)
2114 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
2118 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE *pStubMsg,
2119 PFORMAT_STRING pFormat)
2123 case RPC_FC_PSTRUCT:
2124 case RPC_FC_CSTRUCT:
2125 case RPC_FC_BOGUS_STRUCT:
2126 case RPC_FC_SMFARRAY:
2127 case RPC_FC_SMVARRAY:
2128 case RPC_FC_CSTRING:
2129 return *(const WORD*)&pFormat[2];
2130 case RPC_FC_USER_MARSHAL:
2131 return *(const WORD*)&pFormat[4];
2132 case RPC_FC_NON_ENCAPSULATED_UNION:
2134 if (pStubMsg->fHasNewCorrDesc)
2139 pFormat += *(const SHORT*)pFormat;
2140 return *(const SHORT*)pFormat;
2142 return sizeof(void *);
2143 case RPC_FC_WSTRING:
2144 return *(const WORD*)&pFormat[2] * 2;
2146 FIXME("unhandled embedded type %02x\n", *pFormat);
2152 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2153 PFORMAT_STRING pFormat)
2155 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2159 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2163 return m(pStubMsg, pFormat);
2167 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2168 unsigned char *pMemory,
2169 PFORMAT_STRING pFormat,
2170 PFORMAT_STRING pPointer)
2172 PFORMAT_STRING desc;
2176 while (*pFormat != RPC_FC_END) {
2182 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2183 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2189 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2190 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2194 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2195 if (32767 < *(DWORD*)pMemory)
2196 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2197 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2203 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2204 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2208 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2209 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2212 case RPC_FC_POINTER:
2214 unsigned char *saved_buffer;
2215 int pointer_buffer_mark_set = 0;
2216 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2217 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
2218 saved_buffer = pStubMsg->Buffer;
2219 if (pStubMsg->PointerBufferMark)
2221 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2222 pStubMsg->PointerBufferMark = NULL;
2223 pointer_buffer_mark_set = 1;
2226 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2227 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2228 if (pointer_buffer_mark_set)
2230 STD_OVERFLOW_CHECK(pStubMsg);
2231 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2232 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2234 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2235 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2236 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2238 pStubMsg->Buffer = saved_buffer + 4;
2244 case RPC_FC_ALIGNM4:
2245 ALIGN_POINTER(pMemory, 4);
2247 case RPC_FC_ALIGNM8:
2248 ALIGN_POINTER(pMemory, 8);
2250 case RPC_FC_STRUCTPAD1:
2251 case RPC_FC_STRUCTPAD2:
2252 case RPC_FC_STRUCTPAD3:
2253 case RPC_FC_STRUCTPAD4:
2254 case RPC_FC_STRUCTPAD5:
2255 case RPC_FC_STRUCTPAD6:
2256 case RPC_FC_STRUCTPAD7:
2257 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2259 case RPC_FC_EMBEDDED_COMPLEX:
2260 pMemory += pFormat[1];
2262 desc = pFormat + *(const SHORT*)pFormat;
2263 size = EmbeddedComplexSize(pStubMsg, desc);
2264 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
2265 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2268 /* for some reason interface pointers aren't generated as
2269 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2270 * they still need the derefencing treatment that pointers are
2272 if (*desc == RPC_FC_IP)
2273 m(pStubMsg, *(unsigned char **)pMemory, desc);
2275 m(pStubMsg, pMemory, desc);
2277 else FIXME("no marshaller for embedded type %02x\n", *desc);
2284 FIXME("unhandled format 0x%02x\n", *pFormat);
2292 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2293 unsigned char *pMemory,
2294 PFORMAT_STRING pFormat,
2295 PFORMAT_STRING pPointer)
2297 PFORMAT_STRING desc;
2301 while (*pFormat != RPC_FC_END) {
2307 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2308 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2314 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2315 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2319 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2320 *(DWORD*)pMemory &= 0xffff;
2321 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
2322 if (32767 < *(DWORD*)pMemory)
2323 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2329 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2330 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2334 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2335 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2338 case RPC_FC_POINTER:
2340 unsigned char *saved_buffer;
2341 int pointer_buffer_mark_set = 0;
2342 TRACE("pointer => %p\n", pMemory);
2343 ALIGN_POINTER(pStubMsg->Buffer, 4);
2344 saved_buffer = pStubMsg->Buffer;
2345 if (pStubMsg->PointerBufferMark)
2347 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2348 pStubMsg->PointerBufferMark = NULL;
2349 pointer_buffer_mark_set = 1;
2352 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2354 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, TRUE);
2355 if (pointer_buffer_mark_set)
2357 STD_OVERFLOW_CHECK(pStubMsg);
2358 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2359 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2361 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2362 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2363 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2365 pStubMsg->Buffer = saved_buffer + 4;
2371 case RPC_FC_ALIGNM4:
2372 ALIGN_POINTER_CLEAR(pMemory, 4);
2374 case RPC_FC_ALIGNM8:
2375 ALIGN_POINTER_CLEAR(pMemory, 8);
2377 case RPC_FC_STRUCTPAD1:
2378 case RPC_FC_STRUCTPAD2:
2379 case RPC_FC_STRUCTPAD3:
2380 case RPC_FC_STRUCTPAD4:
2381 case RPC_FC_STRUCTPAD5:
2382 case RPC_FC_STRUCTPAD6:
2383 case RPC_FC_STRUCTPAD7:
2384 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2385 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2387 case RPC_FC_EMBEDDED_COMPLEX:
2388 pMemory += pFormat[1];
2390 desc = pFormat + *(const SHORT*)pFormat;
2391 size = EmbeddedComplexSize(pStubMsg, desc);
2392 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2393 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2394 memset(pMemory, 0, size); /* just in case */
2397 /* for some reason interface pointers aren't generated as
2398 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2399 * they still need the derefencing treatment that pointers are
2401 if (*desc == RPC_FC_IP)
2402 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2404 m(pStubMsg, &pMemory, desc, FALSE);
2406 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2413 FIXME("unhandled format %d\n", *pFormat);
2421 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2422 unsigned char *pMemory,
2423 PFORMAT_STRING pFormat,
2424 PFORMAT_STRING pPointer)
2426 PFORMAT_STRING desc;
2430 while (*pFormat != RPC_FC_END) {
2436 safe_buffer_length_increment(pStubMsg, 1);
2442 safe_buffer_length_increment(pStubMsg, 2);
2446 safe_buffer_length_increment(pStubMsg, 2);
2452 safe_buffer_length_increment(pStubMsg, 4);
2456 safe_buffer_length_increment(pStubMsg, 8);
2459 case RPC_FC_POINTER:
2460 if (!pStubMsg->IgnoreEmbeddedPointers)
2462 int saved_buffer_length = pStubMsg->BufferLength;
2463 pStubMsg->BufferLength = pStubMsg->PointerLength;
2464 pStubMsg->PointerLength = 0;
2465 if(!pStubMsg->BufferLength)
2466 ERR("BufferLength == 0??\n");
2467 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2468 pStubMsg->PointerLength = pStubMsg->BufferLength;
2469 pStubMsg->BufferLength = saved_buffer_length;
2471 safe_buffer_length_increment(pStubMsg, 4);
2475 case RPC_FC_ALIGNM4:
2476 ALIGN_POINTER(pMemory, 4);
2478 case RPC_FC_ALIGNM8:
2479 ALIGN_POINTER(pMemory, 8);
2481 case RPC_FC_STRUCTPAD1:
2482 case RPC_FC_STRUCTPAD2:
2483 case RPC_FC_STRUCTPAD3:
2484 case RPC_FC_STRUCTPAD4:
2485 case RPC_FC_STRUCTPAD5:
2486 case RPC_FC_STRUCTPAD6:
2487 case RPC_FC_STRUCTPAD7:
2488 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2490 case RPC_FC_EMBEDDED_COMPLEX:
2491 pMemory += pFormat[1];
2493 desc = pFormat + *(const SHORT*)pFormat;
2494 size = EmbeddedComplexSize(pStubMsg, desc);
2495 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2498 /* for some reason interface pointers aren't generated as
2499 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2500 * they still need the derefencing treatment that pointers are
2502 if (*desc == RPC_FC_IP)
2503 m(pStubMsg, *(unsigned char **)pMemory, desc);
2505 m(pStubMsg, pMemory, desc);
2507 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2514 FIXME("unhandled format 0x%02x\n", *pFormat);
2522 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2523 unsigned char *pMemory,
2524 PFORMAT_STRING pFormat,
2525 PFORMAT_STRING pPointer)
2527 PFORMAT_STRING desc;
2531 while (*pFormat != RPC_FC_END) {
2553 case RPC_FC_POINTER:
2554 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
2558 case RPC_FC_ALIGNM4:
2559 ALIGN_POINTER(pMemory, 4);
2561 case RPC_FC_ALIGNM8:
2562 ALIGN_POINTER(pMemory, 8);
2564 case RPC_FC_STRUCTPAD1:
2565 case RPC_FC_STRUCTPAD2:
2566 case RPC_FC_STRUCTPAD3:
2567 case RPC_FC_STRUCTPAD4:
2568 case RPC_FC_STRUCTPAD5:
2569 case RPC_FC_STRUCTPAD6:
2570 case RPC_FC_STRUCTPAD7:
2571 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2573 case RPC_FC_EMBEDDED_COMPLEX:
2574 pMemory += pFormat[1];
2576 desc = pFormat + *(const SHORT*)pFormat;
2577 size = EmbeddedComplexSize(pStubMsg, desc);
2578 m = NdrFreer[*desc & NDR_TABLE_MASK];
2581 /* for some reason interface pointers aren't generated as
2582 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2583 * they still need the derefencing treatment that pointers are
2585 if (*desc == RPC_FC_IP)
2586 m(pStubMsg, *(unsigned char **)pMemory, desc);
2588 m(pStubMsg, pMemory, desc);
2596 FIXME("unhandled format 0x%02x\n", *pFormat);
2604 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2605 PFORMAT_STRING pFormat)
2607 PFORMAT_STRING desc;
2608 unsigned long size = 0;
2610 while (*pFormat != RPC_FC_END) {
2617 safe_buffer_increment(pStubMsg, 1);
2623 safe_buffer_increment(pStubMsg, 2);
2627 safe_buffer_increment(pStubMsg, 2);
2633 safe_buffer_increment(pStubMsg, 4);
2637 safe_buffer_increment(pStubMsg, 8);
2639 case RPC_FC_POINTER:
2641 safe_buffer_increment(pStubMsg, 4);
2642 if (!pStubMsg->IgnoreEmbeddedPointers)
2643 FIXME("embedded pointers\n");
2645 case RPC_FC_ALIGNM4:
2646 ALIGN_LENGTH(size, 4);
2647 ALIGN_POINTER(pStubMsg->Buffer, 4);
2649 case RPC_FC_ALIGNM8:
2650 ALIGN_LENGTH(size, 8);
2651 ALIGN_POINTER(pStubMsg->Buffer, 8);
2653 case RPC_FC_STRUCTPAD1:
2654 case RPC_FC_STRUCTPAD2:
2655 case RPC_FC_STRUCTPAD3:
2656 case RPC_FC_STRUCTPAD4:
2657 case RPC_FC_STRUCTPAD5:
2658 case RPC_FC_STRUCTPAD6:
2659 case RPC_FC_STRUCTPAD7:
2660 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2662 case RPC_FC_EMBEDDED_COMPLEX:
2665 desc = pFormat + *(const SHORT*)pFormat;
2666 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2672 FIXME("unhandled format 0x%02x\n", *pFormat);
2680 unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg,
2681 PFORMAT_STRING pFormat)
2683 PFORMAT_STRING desc;
2684 unsigned long size = 0;
2686 while (*pFormat != RPC_FC_END) {
2708 case RPC_FC_POINTER:
2709 size += sizeof(void *);
2711 case RPC_FC_ALIGNM4:
2712 ALIGN_LENGTH(size, 4);
2714 case RPC_FC_ALIGNM8:
2715 ALIGN_LENGTH(size, 8);
2717 case RPC_FC_STRUCTPAD1:
2718 case RPC_FC_STRUCTPAD2:
2719 case RPC_FC_STRUCTPAD3:
2720 case RPC_FC_STRUCTPAD4:
2721 case RPC_FC_STRUCTPAD5:
2722 case RPC_FC_STRUCTPAD6:
2723 case RPC_FC_STRUCTPAD7:
2724 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2726 case RPC_FC_EMBEDDED_COMPLEX:
2729 desc = pFormat + *(const SHORT*)pFormat;
2730 size += EmbeddedComplexSize(pStubMsg, desc);
2736 FIXME("unhandled format 0x%02x\n", *pFormat);
2744 /***********************************************************************
2745 * NdrComplexStructMarshall [RPCRT4.@]
2747 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2748 unsigned char *pMemory,
2749 PFORMAT_STRING pFormat)
2751 PFORMAT_STRING conf_array = NULL;
2752 PFORMAT_STRING pointer_desc = NULL;
2753 unsigned char *OldMemory = pStubMsg->Memory;
2754 int pointer_buffer_mark_set = 0;
2756 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2758 if (!pStubMsg->PointerBufferMark)
2760 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2761 /* save buffer length */
2762 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2764 /* get the buffer pointer after complex array data, but before
2766 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2767 pStubMsg->IgnoreEmbeddedPointers = 1;
2768 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2769 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2771 /* save it for use by embedded pointer code later */
2772 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2773 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
2774 pointer_buffer_mark_set = 1;
2776 /* restore the original buffer length */
2777 pStubMsg->BufferLength = saved_buffer_length;
2780 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
2783 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2785 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2788 pStubMsg->Memory = pMemory;
2790 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2793 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2795 pStubMsg->Memory = OldMemory;
2797 if (pointer_buffer_mark_set)
2799 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2800 pStubMsg->PointerBufferMark = NULL;
2803 STD_OVERFLOW_CHECK(pStubMsg);
2808 /***********************************************************************
2809 * NdrComplexStructUnmarshall [RPCRT4.@]
2811 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2812 unsigned char **ppMemory,
2813 PFORMAT_STRING pFormat,
2814 unsigned char fMustAlloc)
2816 unsigned size = *(const WORD*)(pFormat+2);
2817 PFORMAT_STRING conf_array = NULL;
2818 PFORMAT_STRING pointer_desc = NULL;
2819 unsigned char *pMemory;
2820 int pointer_buffer_mark_set = 0;
2822 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2824 if (!pStubMsg->PointerBufferMark)
2826 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2827 /* save buffer pointer */
2828 unsigned char *saved_buffer = pStubMsg->Buffer;
2830 /* get the buffer pointer after complex array data, but before
2832 pStubMsg->IgnoreEmbeddedPointers = 1;
2833 NdrComplexStructMemorySize(pStubMsg, pFormat);
2834 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2836 /* save it for use by embedded pointer code later */
2837 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2838 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
2839 pointer_buffer_mark_set = 1;
2841 /* restore the original buffer */
2842 pStubMsg->Buffer = saved_buffer;
2845 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2847 if (fMustAlloc || !*ppMemory)
2849 *ppMemory = NdrAllocate(pStubMsg, size);
2850 memset(*ppMemory, 0, size);
2854 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2856 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2859 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2862 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2864 if (pointer_buffer_mark_set)
2866 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2867 pStubMsg->PointerBufferMark = NULL;
2873 /***********************************************************************
2874 * NdrComplexStructBufferSize [RPCRT4.@]
2876 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2877 unsigned char *pMemory,
2878 PFORMAT_STRING pFormat)
2880 PFORMAT_STRING conf_array = NULL;
2881 PFORMAT_STRING pointer_desc = NULL;
2882 unsigned char *OldMemory = pStubMsg->Memory;
2883 int pointer_length_set = 0;
2885 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2887 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2889 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2891 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2892 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2894 /* get the buffer length after complex struct data, but before
2896 pStubMsg->IgnoreEmbeddedPointers = 1;
2897 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2898 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2900 /* save it for use by embedded pointer code later */
2901 pStubMsg->PointerLength = pStubMsg->BufferLength;
2902 pointer_length_set = 1;
2903 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
2905 /* restore the original buffer length */
2906 pStubMsg->BufferLength = saved_buffer_length;
2910 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2912 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2915 pStubMsg->Memory = pMemory;
2917 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2920 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2922 pStubMsg->Memory = OldMemory;
2924 if(pointer_length_set)
2926 pStubMsg->BufferLength = pStubMsg->PointerLength;
2927 pStubMsg->PointerLength = 0;
2932 /***********************************************************************
2933 * NdrComplexStructMemorySize [RPCRT4.@]
2935 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2936 PFORMAT_STRING pFormat)
2938 unsigned size = *(const WORD*)(pFormat+2);
2939 PFORMAT_STRING conf_array = NULL;
2940 PFORMAT_STRING pointer_desc = NULL;
2942 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2944 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2947 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2949 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2952 ComplexStructMemorySize(pStubMsg, pFormat);
2955 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2960 /***********************************************************************
2961 * NdrComplexStructFree [RPCRT4.@]
2963 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2964 unsigned char *pMemory,
2965 PFORMAT_STRING pFormat)
2967 PFORMAT_STRING conf_array = NULL;
2968 PFORMAT_STRING pointer_desc = NULL;
2969 unsigned char *OldMemory = pStubMsg->Memory;
2971 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2974 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2976 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2979 pStubMsg->Memory = pMemory;
2981 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2984 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2986 pStubMsg->Memory = OldMemory;
2989 /***********************************************************************
2990 * NdrConformantArrayMarshall [RPCRT4.@]
2992 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2993 unsigned char *pMemory,
2994 PFORMAT_STRING pFormat)
2996 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2997 unsigned char alignment = pFormat[1] + 1;
2999 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3000 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3002 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3004 WriteConformance(pStubMsg);
3006 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3008 size = safe_multiply(esize, pStubMsg->MaxCount);
3009 pStubMsg->BufferMark = pStubMsg->Buffer;
3010 safe_copy_to_buffer(pStubMsg, pMemory, size);
3012 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3017 /***********************************************************************
3018 * NdrConformantArrayUnmarshall [RPCRT4.@]
3020 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3021 unsigned char **ppMemory,
3022 PFORMAT_STRING pFormat,
3023 unsigned char fMustAlloc)
3025 DWORD size, esize = *(const WORD*)(pFormat+2);
3026 unsigned char alignment = pFormat[1] + 1;
3027 unsigned char *saved_buffer;
3029 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3030 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3032 pFormat = ReadConformance(pStubMsg, pFormat+4);
3034 size = safe_multiply(esize, pStubMsg->MaxCount);
3035 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3038 *ppMemory = NdrAllocate(pStubMsg, size);
3041 if (!pStubMsg->IsClient && !*ppMemory)
3042 /* for servers, we just point straight into the RPC buffer */
3043 *ppMemory = pStubMsg->Buffer;
3046 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3047 safe_buffer_increment(pStubMsg, size);
3048 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3050 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
3051 if (*ppMemory != saved_buffer)
3052 memcpy(*ppMemory, saved_buffer, size);
3057 /***********************************************************************
3058 * NdrConformantArrayBufferSize [RPCRT4.@]
3060 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3061 unsigned char *pMemory,
3062 PFORMAT_STRING pFormat)
3064 DWORD size, esize = *(const WORD*)(pFormat+2);
3065 unsigned char alignment = pFormat[1] + 1;
3067 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3068 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3070 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3072 SizeConformance(pStubMsg);
3074 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3076 size = safe_multiply(esize, pStubMsg->MaxCount);
3077 /* conformance value plus array */
3078 safe_buffer_length_increment(pStubMsg, size);
3080 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3083 /***********************************************************************
3084 * NdrConformantArrayMemorySize [RPCRT4.@]
3086 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3087 PFORMAT_STRING pFormat)
3089 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
3090 unsigned char alignment = pFormat[1] + 1;
3092 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3093 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3095 pFormat = ReadConformance(pStubMsg, pFormat+4);
3096 size = safe_multiply(esize, pStubMsg->MaxCount);
3097 pStubMsg->MemorySize += size;
3099 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3100 pStubMsg->BufferMark = pStubMsg->Buffer;
3101 safe_buffer_increment(pStubMsg, size);
3103 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3105 return pStubMsg->MemorySize;
3108 /***********************************************************************
3109 * NdrConformantArrayFree [RPCRT4.@]
3111 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3112 unsigned char *pMemory,
3113 PFORMAT_STRING pFormat)
3115 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3116 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3118 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3120 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3124 /***********************************************************************
3125 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3127 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
3128 unsigned char* pMemory,
3129 PFORMAT_STRING pFormat )
3132 unsigned char alignment = pFormat[1] + 1;
3133 DWORD esize = *(const WORD*)(pFormat+2);
3135 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3137 if (pFormat[0] != RPC_FC_CVARRAY)
3139 ERR("invalid format type %x\n", pFormat[0]);
3140 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3144 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3145 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3147 WriteConformance(pStubMsg);
3148 WriteVariance(pStubMsg);
3150 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3152 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3154 pStubMsg->BufferMark = pStubMsg->Buffer;
3155 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
3157 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3163 /***********************************************************************
3164 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3166 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
3167 unsigned char** ppMemory,
3168 PFORMAT_STRING pFormat,
3169 unsigned char fMustAlloc )
3171 ULONG bufsize, memsize;
3172 unsigned char alignment = pFormat[1] + 1;
3173 DWORD esize = *(const WORD*)(pFormat+2);
3174 unsigned char *saved_buffer;
3177 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3179 if (pFormat[0] != RPC_FC_CVARRAY)
3181 ERR("invalid format type %x\n", pFormat[0]);
3182 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3186 pFormat = ReadConformance(pStubMsg, pFormat+4);
3187 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3189 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3191 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3192 memsize = safe_multiply(esize, pStubMsg->MaxCount);
3193 offset = pStubMsg->Offset;
3195 if (!*ppMemory || fMustAlloc)
3196 *ppMemory = NdrAllocate(pStubMsg, memsize);
3197 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3198 safe_buffer_increment(pStubMsg, bufsize);
3200 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3202 memcpy(*ppMemory + offset, saved_buffer, bufsize);
3208 /***********************************************************************
3209 * NdrConformantVaryingArrayFree [RPCRT4.@]
3211 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
3212 unsigned char* pMemory,
3213 PFORMAT_STRING pFormat )
3215 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3217 if (pFormat[0] != RPC_FC_CVARRAY)
3219 ERR("invalid format type %x\n", pFormat[0]);
3220 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3224 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3225 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3227 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3231 /***********************************************************************
3232 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3234 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
3235 unsigned char* pMemory, PFORMAT_STRING pFormat )
3237 unsigned char alignment = pFormat[1] + 1;
3238 DWORD esize = *(const WORD*)(pFormat+2);
3240 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3242 if (pFormat[0] != RPC_FC_CVARRAY)
3244 ERR("invalid format type %x\n", pFormat[0]);
3245 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3250 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3251 /* compute length */
3252 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3254 SizeConformance(pStubMsg);
3255 SizeVariance(pStubMsg);
3257 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3259 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
3261 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3265 /***********************************************************************
3266 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3268 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
3269 PFORMAT_STRING pFormat )
3271 ULONG bufsize, memsize;
3272 unsigned char alignment = pFormat[1] + 1;
3273 DWORD esize = *(const WORD*)(pFormat+2);
3275 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3277 if (pFormat[0] != RPC_FC_CVARRAY)
3279 ERR("invalid format type %x\n", pFormat[0]);
3280 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3281 return pStubMsg->MemorySize;
3284 pFormat = ReadConformance(pStubMsg, pFormat+4);
3285 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3287 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3289 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3290 memsize = safe_multiply(esize, pStubMsg->MaxCount);
3292 safe_buffer_increment(pStubMsg, bufsize);
3293 pStubMsg->MemorySize += memsize;
3295 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3297 return pStubMsg->MemorySize;
3301 /***********************************************************************
3302 * NdrComplexArrayMarshall [RPCRT4.@]
3304 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3305 unsigned char *pMemory,
3306 PFORMAT_STRING pFormat)
3308 ULONG i, count, def;
3309 BOOL variance_present;
3310 unsigned char alignment;
3311 int pointer_buffer_mark_set = 0;
3313 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
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 if (!pStubMsg->PointerBufferMark)
3326 /* save buffer fields that may be changed by buffer sizer functions
3327 * and that may be needed later on */
3328 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3329 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3330 unsigned long saved_max_count = pStubMsg->MaxCount;
3331 unsigned long saved_offset = pStubMsg->Offset;
3332 unsigned long saved_actual_count = pStubMsg->ActualCount;
3334 /* get the buffer pointer after complex array data, but before
3336 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3337 pStubMsg->IgnoreEmbeddedPointers = 1;
3338 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3339 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3341 /* save it for use by embedded pointer code later */
3342 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3343 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
3344 pointer_buffer_mark_set = 1;
3346 /* restore fields */
3347 pStubMsg->ActualCount = saved_actual_count;
3348 pStubMsg->Offset = saved_offset;
3349 pStubMsg->MaxCount = saved_max_count;
3350 pStubMsg->BufferLength = saved_buffer_length;
3353 def = *(const WORD*)&pFormat[2];
3356 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3357 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3359 variance_present = IsConformanceOrVariancePresent(pFormat);
3360 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3361 TRACE("variance = %d\n", pStubMsg->ActualCount);
3363 WriteConformance(pStubMsg);
3364 if (variance_present)
3365 WriteVariance(pStubMsg);
3367 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3369 count = pStubMsg->ActualCount;
3370 for (i = 0; i < count; i++)
3371 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3373 STD_OVERFLOW_CHECK(pStubMsg);
3375 if (pointer_buffer_mark_set)
3377 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3378 pStubMsg->PointerBufferMark = NULL;
3384 /***********************************************************************
3385 * NdrComplexArrayUnmarshall [RPCRT4.@]
3387 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3388 unsigned char **ppMemory,
3389 PFORMAT_STRING pFormat,
3390 unsigned char fMustAlloc)
3392 ULONG i, count, size;
3393 unsigned char alignment;
3394 unsigned char *pMemory;
3395 unsigned char *saved_buffer;
3396 int pointer_buffer_mark_set = 0;
3397 int saved_ignore_embedded;
3399 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3401 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3403 ERR("invalid format type %x\n", pFormat[0]);
3404 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3408 alignment = pFormat[1] + 1;
3410 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3411 /* save buffer pointer */
3412 saved_buffer = pStubMsg->Buffer;
3413 /* get the buffer pointer after complex array data, but before
3415 pStubMsg->IgnoreEmbeddedPointers = 1;
3416 pStubMsg->MemorySize = 0;
3417 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3418 size = pStubMsg->MemorySize;
3419 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3421 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
3422 if (!pStubMsg->PointerBufferMark)
3424 /* save it for use by embedded pointer code later */
3425 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3426 pointer_buffer_mark_set = 1;
3428 /* restore the original buffer */
3429 pStubMsg->Buffer = saved_buffer;
3433 pFormat = ReadConformance(pStubMsg, pFormat);
3434 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3436 if (fMustAlloc || !*ppMemory)
3438 *ppMemory = NdrAllocate(pStubMsg, size);
3439 memset(*ppMemory, 0, size);
3442 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3444 pMemory = *ppMemory;
3445 count = pStubMsg->ActualCount;
3446 for (i = 0; i < count; i++)
3447 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
3449 if (pointer_buffer_mark_set)
3451 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3452 pStubMsg->PointerBufferMark = NULL;
3458 /***********************************************************************
3459 * NdrComplexArrayBufferSize [RPCRT4.@]
3461 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3462 unsigned char *pMemory,
3463 PFORMAT_STRING pFormat)
3465 ULONG i, count, def;
3466 unsigned char alignment;
3467 BOOL variance_present;
3468 int pointer_length_set = 0;
3470 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3472 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3474 ERR("invalid format type %x\n", pFormat[0]);
3475 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3479 alignment = pFormat[1] + 1;
3481 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3483 /* save buffer fields that may be changed by buffer sizer functions
3484 * and that may be needed later on */
3485 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3486 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3487 unsigned long saved_max_count = pStubMsg->MaxCount;
3488 unsigned long saved_offset = pStubMsg->Offset;
3489 unsigned long saved_actual_count = pStubMsg->ActualCount;
3491 /* get the buffer pointer after complex array data, but before
3493 pStubMsg->IgnoreEmbeddedPointers = 1;
3494 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3495 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3497 /* save it for use by embedded pointer code later */
3498 pStubMsg->PointerLength = pStubMsg->BufferLength;
3499 pointer_length_set = 1;
3501 /* restore fields */
3502 pStubMsg->ActualCount = saved_actual_count;
3503 pStubMsg->Offset = saved_offset;
3504 pStubMsg->MaxCount = saved_max_count;
3505 pStubMsg->BufferLength = saved_buffer_length;
3507 def = *(const WORD*)&pFormat[2];
3510 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3511 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3512 SizeConformance(pStubMsg);
3514 variance_present = IsConformanceOrVariancePresent(pFormat);
3515 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3516 TRACE("variance = %d\n", pStubMsg->ActualCount);
3518 if (variance_present)
3519 SizeVariance(pStubMsg);
3521 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3523 count = pStubMsg->ActualCount;
3524 for (i = 0; i < count; i++)
3525 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
3527 if(pointer_length_set)
3529 pStubMsg->BufferLength = pStubMsg->PointerLength;
3530 pStubMsg->PointerLength = 0;
3534 /***********************************************************************
3535 * NdrComplexArrayMemorySize [RPCRT4.@]
3537 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3538 PFORMAT_STRING pFormat)
3540 ULONG i, count, esize, SavedMemorySize, MemorySize;
3541 unsigned char alignment;
3543 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3545 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3547 ERR("invalid format type %x\n", pFormat[0]);
3548 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3552 alignment = pFormat[1] + 1;
3556 pFormat = ReadConformance(pStubMsg, pFormat);
3557 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3559 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3561 SavedMemorySize = pStubMsg->MemorySize;
3563 esize = ComplexStructSize(pStubMsg, pFormat);
3565 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
3567 count = pStubMsg->ActualCount;
3568 for (i = 0; i < count; i++)
3569 ComplexStructMemorySize(pStubMsg, pFormat);
3571 pStubMsg->MemorySize = SavedMemorySize;
3573 pStubMsg->MemorySize += MemorySize;
3577 /***********************************************************************
3578 * NdrComplexArrayFree [RPCRT4.@]
3580 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3581 unsigned char *pMemory,
3582 PFORMAT_STRING pFormat)
3584 ULONG i, count, def;
3586 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3588 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3590 ERR("invalid format type %x\n", pFormat[0]);
3591 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3595 def = *(const WORD*)&pFormat[2];
3598 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3599 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3601 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3602 TRACE("variance = %d\n", pStubMsg->ActualCount);
3604 count = pStubMsg->ActualCount;
3605 for (i = 0; i < count; i++)
3606 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
3609 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
3610 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
3611 USER_MARSHAL_CB *umcb)
3613 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
3614 pStubMsg->RpcMsg->DataRepresentation);
3615 umcb->pStubMsg = pStubMsg;
3616 umcb->pReserve = NULL;
3617 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
3618 umcb->CBType = cbtype;
3619 umcb->pFormat = pFormat;
3620 umcb->pTypeFormat = NULL /* FIXME */;
3623 #define USER_MARSHAL_PTR_PREFIX \
3624 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3625 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3627 /***********************************************************************
3628 * NdrUserMarshalMarshall [RPCRT4.@]
3630 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3631 unsigned char *pMemory,
3632 PFORMAT_STRING pFormat)
3634 unsigned flags = pFormat[1];
3635 unsigned index = *(const WORD*)&pFormat[2];
3636 unsigned char *saved_buffer = NULL;
3637 USER_MARSHAL_CB umcb;
3639 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3640 TRACE("index=%d\n", index);
3642 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
3644 if (flags & USER_MARSHAL_POINTER)
3646 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
3647 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
3648 pStubMsg->Buffer += 4;
3649 if (pStubMsg->PointerBufferMark)
3651 saved_buffer = pStubMsg->Buffer;
3652 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3653 pStubMsg->PointerBufferMark = NULL;
3655 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
3658 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
3661 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
3662 &umcb.Flags, pStubMsg->Buffer, pMemory);
3666 STD_OVERFLOW_CHECK(pStubMsg);
3667 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3668 pStubMsg->Buffer = saved_buffer;
3671 STD_OVERFLOW_CHECK(pStubMsg);
3676 /***********************************************************************
3677 * NdrUserMarshalUnmarshall [RPCRT4.@]
3679 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3680 unsigned char **ppMemory,
3681 PFORMAT_STRING pFormat,
3682 unsigned char fMustAlloc)
3684 unsigned flags = pFormat[1];
3685 unsigned index = *(const WORD*)&pFormat[2];
3686 DWORD memsize = *(const WORD*)&pFormat[4];
3687 unsigned char *saved_buffer = NULL;
3688 USER_MARSHAL_CB umcb;
3690 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3691 TRACE("index=%d\n", index);
3693 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
3695 if (flags & USER_MARSHAL_POINTER)
3697 ALIGN_POINTER(pStubMsg->Buffer, 4);
3698 /* skip pointer prefix */
3699 pStubMsg->Buffer += 4;
3700 if (pStubMsg->PointerBufferMark)
3702 saved_buffer = pStubMsg->Buffer;
3703 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3704 pStubMsg->PointerBufferMark = NULL;
3706 ALIGN_POINTER(pStubMsg->Buffer, 8);
3709 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3711 if (fMustAlloc || !*ppMemory)
3712 *ppMemory = NdrAllocate(pStubMsg, memsize);
3715 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
3716 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
3720 STD_OVERFLOW_CHECK(pStubMsg);
3721 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3722 pStubMsg->Buffer = saved_buffer;
3728 /***********************************************************************
3729 * NdrUserMarshalBufferSize [RPCRT4.@]
3731 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3732 unsigned char *pMemory,
3733 PFORMAT_STRING pFormat)
3735 unsigned flags = pFormat[1];
3736 unsigned index = *(const WORD*)&pFormat[2];
3737 DWORD bufsize = *(const WORD*)&pFormat[6];
3738 USER_MARSHAL_CB umcb;
3739 unsigned long saved_buffer_length = 0;
3741 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3742 TRACE("index=%d\n", index);
3744 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
3746 if (flags & USER_MARSHAL_POINTER)
3748 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3749 /* skip pointer prefix */
3750 safe_buffer_length_increment(pStubMsg, 4);
3751 if (pStubMsg->IgnoreEmbeddedPointers)
3753 if (pStubMsg->PointerLength)
3755 saved_buffer_length = pStubMsg->BufferLength;
3756 pStubMsg->BufferLength = pStubMsg->PointerLength;
3757 pStubMsg->PointerLength = 0;
3759 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
3762 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
3765 TRACE("size=%d\n", bufsize);
3766 safe_buffer_length_increment(pStubMsg, bufsize);
3769 pStubMsg->BufferLength =
3770 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
3771 &umcb.Flags, pStubMsg->BufferLength, pMemory);
3773 if (saved_buffer_length)
3775 pStubMsg->PointerLength = pStubMsg->BufferLength;
3776 pStubMsg->BufferLength = saved_buffer_length;
3781 /***********************************************************************
3782 * NdrUserMarshalMemorySize [RPCRT4.@]
3784 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3785 PFORMAT_STRING pFormat)
3787 unsigned flags = pFormat[1];
3788 unsigned index = *(const WORD*)&pFormat[2];
3789 DWORD memsize = *(const WORD*)&pFormat[4];
3790 DWORD bufsize = *(const WORD*)&pFormat[6];
3792 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3793 TRACE("index=%d\n", index);
3795 pStubMsg->MemorySize += memsize;
3797 if (flags & USER_MARSHAL_POINTER)
3799 ALIGN_POINTER(pStubMsg->Buffer, 4);
3800 /* skip pointer prefix */
3801 pStubMsg->Buffer += 4;
3802 if (pStubMsg->IgnoreEmbeddedPointers)
3803 return pStubMsg->MemorySize;
3804 ALIGN_POINTER(pStubMsg->Buffer, 8);
3807 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3810 FIXME("not implemented for varying buffer size\n");
3812 pStubMsg->Buffer += bufsize;
3814 return pStubMsg->MemorySize;
3817 /***********************************************************************
3818 * NdrUserMarshalFree [RPCRT4.@]
3820 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
3821 unsigned char *pMemory,
3822 PFORMAT_STRING pFormat)
3824 /* unsigned flags = pFormat[1]; */
3825 unsigned index = *(const WORD*)&pFormat[2];
3826 USER_MARSHAL_CB umcb;
3828 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3829 TRACE("index=%d\n", index);
3831 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
3833 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
3834 &umcb.Flags, pMemory);
3837 /***********************************************************************
3838 * NdrClearOutParameters [RPCRT4.@]
3840 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
3841 PFORMAT_STRING pFormat,
3844 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
3847 /***********************************************************************
3848 * NdrConvert [RPCRT4.@]
3850 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
3852 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
3853 /* FIXME: since this stub doesn't do any converting, the proper behavior
3854 is to raise an exception */
3857 /***********************************************************************
3858 * NdrConvert2 [RPCRT4.@]
3860 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
3862 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3863 pStubMsg, pFormat, NumberParams);
3864 /* FIXME: since this stub doesn't do any converting, the proper behavior
3865 is to raise an exception */
3868 #include "pshpack1.h"
3869 typedef struct _NDR_CSTRUCT_FORMAT
3872 unsigned char alignment;
3873 unsigned short memory_size;
3874 short offset_to_array_description;
3875 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
3876 #include "poppack.h"
3878 /***********************************************************************
3879 * NdrConformantStructMarshall [RPCRT4.@]
3881 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3882 unsigned char *pMemory,
3883 PFORMAT_STRING pFormat)
3885 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3886 PFORMAT_STRING pCArrayFormat;
3887 ULONG esize, bufsize;
3889 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3891 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3892 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3894 ERR("invalid format type %x\n", pCStructFormat->type);
3895 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3899 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3900 pCStructFormat->offset_to_array_description;
3901 if (*pCArrayFormat != RPC_FC_CARRAY)
3903 ERR("invalid array format type %x\n", pCStructFormat->type);
3904 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3907 esize = *(const WORD*)(pCArrayFormat+2);
3909 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3910 pCArrayFormat + 4, 0);
3912 WriteConformance(pStubMsg);
3914 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3916 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3918 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3919 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3921 ERR("integer overflow of memory_size %u with bufsize %u\n",
3922 pCStructFormat->memory_size, bufsize);
3923 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3925 /* copy constant sized part of struct */
3926 pStubMsg->BufferMark = pStubMsg->Buffer;
3927 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
3929 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3930 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3935 /***********************************************************************
3936 * NdrConformantStructUnmarshall [RPCRT4.@]
3938 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3939 unsigned char **ppMemory,
3940 PFORMAT_STRING pFormat,
3941 unsigned char fMustAlloc)
3943 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3944 PFORMAT_STRING pCArrayFormat;
3945 ULONG esize, bufsize;
3946 unsigned char *saved_buffer;
3948 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3950 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3951 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3953 ERR("invalid format type %x\n", pCStructFormat->type);
3954 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3957 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3958 pCStructFormat->offset_to_array_description;
3959 if (*pCArrayFormat != RPC_FC_CARRAY)
3961 ERR("invalid array format type %x\n", pCStructFormat->type);
3962 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3965 esize = *(const WORD*)(pCArrayFormat+2);
3967 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3969 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3971 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3973 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3974 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3976 ERR("integer overflow of memory_size %u with bufsize %u\n",
3977 pCStructFormat->memory_size, bufsize);
3978 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3983 SIZE_T size = pCStructFormat->memory_size + bufsize;
3984 *ppMemory = NdrAllocate(pStubMsg, size);
3988 if (!pStubMsg->IsClient && !*ppMemory)
3989 /* for servers, we just point straight into the RPC buffer */
3990 *ppMemory = pStubMsg->Buffer;
3993 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3994 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
3995 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3996 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3998 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
3999 if (*ppMemory != saved_buffer)
4000 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4005 /***********************************************************************
4006 * NdrConformantStructBufferSize [RPCRT4.@]
4008 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4009 unsigned char *pMemory,
4010 PFORMAT_STRING pFormat)
4012 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4013 PFORMAT_STRING pCArrayFormat;
4016 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4018 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4019 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4021 ERR("invalid format type %x\n", pCStructFormat->type);
4022 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4025 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4026 pCStructFormat->offset_to_array_description;
4027 if (*pCArrayFormat != RPC_FC_CARRAY)
4029 ERR("invalid array format type %x\n", pCStructFormat->type);
4030 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4033 esize = *(const WORD*)(pCArrayFormat+2);
4035 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4036 SizeConformance(pStubMsg);
4038 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4040 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4042 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4043 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4045 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4046 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4049 /***********************************************************************
4050 * NdrConformantStructMemorySize [RPCRT4.@]
4052 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4053 PFORMAT_STRING pFormat)
4059 /***********************************************************************
4060 * NdrConformantStructFree [RPCRT4.@]
4062 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4063 unsigned char *pMemory,
4064 PFORMAT_STRING pFormat)
4066 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4067 PFORMAT_STRING pCArrayFormat;
4070 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4072 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4073 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4075 ERR("invalid format type %x\n", pCStructFormat->type);
4076 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4080 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4081 pCStructFormat->offset_to_array_description;
4082 if (*pCArrayFormat != RPC_FC_CARRAY)
4084 ERR("invalid array format type %x\n", pCStructFormat->type);
4085 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4088 esize = *(const WORD*)(pCArrayFormat+2);
4090 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4091 pCArrayFormat + 4, 0);
4093 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4095 /* copy constant sized part of struct */
4096 pStubMsg->BufferMark = pStubMsg->Buffer;
4098 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4099 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4102 /***********************************************************************
4103 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4105 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4106 unsigned char *pMemory,
4107 PFORMAT_STRING pFormat)
4109 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4110 PFORMAT_STRING pCVArrayFormat;
4111 ULONG esize, bufsize;
4113 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4115 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4116 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4118 ERR("invalid format type %x\n", pCVStructFormat->type);
4119 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4123 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4124 pCVStructFormat->offset_to_array_description;
4125 switch (*pCVArrayFormat)
4127 case RPC_FC_CVARRAY:
4128 esize = *(const WORD*)(pCVArrayFormat+2);
4130 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4131 pCVArrayFormat + 4, 0);
4132 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4135 case RPC_FC_C_CSTRING:
4136 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4137 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4138 esize = sizeof(char);
4139 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4140 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4141 pCVArrayFormat + 2, 0);
4143 pStubMsg->MaxCount = pStubMsg->ActualCount;
4145 case RPC_FC_C_WSTRING:
4146 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4147 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4148 esize = sizeof(WCHAR);
4149 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4150 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4151 pCVArrayFormat + 2, 0);
4153 pStubMsg->MaxCount = pStubMsg->ActualCount;
4156 ERR("invalid array format type %x\n", *pCVArrayFormat);
4157 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4161 WriteConformance(pStubMsg);
4163 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4165 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4167 /* write constant sized part */
4168 pStubMsg->BufferMark = pStubMsg->Buffer;
4169 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4171 WriteVariance(pStubMsg);
4173 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4175 /* write array part */
4176 safe_copy_to_buffer(pStubMsg, pMemory + pCVStructFormat->memory_size, bufsize);
4178 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4183 /***********************************************************************
4184 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4186 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4187 unsigned char **ppMemory,
4188 PFORMAT_STRING pFormat,
4189 unsigned char fMustAlloc)
4191 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4192 PFORMAT_STRING pCVArrayFormat;
4193 ULONG esize, bufsize;
4194 unsigned char cvarray_type;
4196 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4198 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4199 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4201 ERR("invalid format type %x\n", pCVStructFormat->type);
4202 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4206 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4207 pCVStructFormat->offset_to_array_description;
4208 cvarray_type = *pCVArrayFormat;
4209 switch (cvarray_type)
4211 case RPC_FC_CVARRAY:
4212 esize = *(const WORD*)(pCVArrayFormat+2);
4213 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4215 case RPC_FC_C_CSTRING:
4216 esize = sizeof(char);
4217 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4218 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4220 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4222 case RPC_FC_C_WSTRING:
4223 esize = sizeof(WCHAR);
4224 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4225 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4227 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4230 ERR("invalid array format type %x\n", *pCVArrayFormat);
4231 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4235 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4237 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4239 /* work out how much memory to allocate if we need to do so */
4240 if (!*ppMemory || fMustAlloc)
4242 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4243 *ppMemory = NdrAllocate(pStubMsg, size);
4246 /* copy the constant data */
4247 pStubMsg->BufferMark = pStubMsg->Buffer;
4248 safe_copy_from_buffer(pStubMsg, *ppMemory, pCVStructFormat->memory_size);
4250 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4252 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4254 if ((cvarray_type == RPC_FC_C_CSTRING) ||
4255 (cvarray_type == RPC_FC_C_WSTRING))
4258 /* strings must always have null terminating bytes */
4259 if (bufsize < esize)
4261 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
4262 RpcRaiseException(RPC_S_INVALID_BOUND);
4265 for (i = bufsize - esize; i < bufsize; i++)
4266 if (pStubMsg->Buffer[i] != 0)
4268 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
4269 i, pStubMsg->Buffer[i]);
4270 RpcRaiseException(RPC_S_INVALID_BOUND);
4275 /* copy the array data */
4276 safe_copy_from_buffer(pStubMsg, *ppMemory + pCVStructFormat->memory_size, bufsize);
4278 if (cvarray_type == RPC_FC_C_CSTRING)
4279 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
4280 else if (cvarray_type == RPC_FC_C_WSTRING)
4281 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
4283 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
4288 /***********************************************************************
4289 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4291 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4292 unsigned char *pMemory,
4293 PFORMAT_STRING pFormat)
4295 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4296 PFORMAT_STRING pCVArrayFormat;
4299 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4301 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4302 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4304 ERR("invalid format type %x\n", pCVStructFormat->type);
4305 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4309 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4310 pCVStructFormat->offset_to_array_description;
4311 switch (*pCVArrayFormat)
4313 case RPC_FC_CVARRAY:
4314 esize = *(const WORD*)(pCVArrayFormat+2);
4316 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4317 pCVArrayFormat + 4, 0);
4318 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4321 case RPC_FC_C_CSTRING:
4322 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4323 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4324 esize = sizeof(char);
4325 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4326 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4327 pCVArrayFormat + 2, 0);
4329 pStubMsg->MaxCount = pStubMsg->ActualCount;
4331 case RPC_FC_C_WSTRING:
4332 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4333 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4334 esize = sizeof(WCHAR);
4335 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4336 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4337 pCVArrayFormat + 2, 0);
4339 pStubMsg->MaxCount = pStubMsg->ActualCount;
4342 ERR("invalid array format type %x\n", *pCVArrayFormat);
4343 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4347 SizeConformance(pStubMsg);
4349 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4351 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4353 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4354 SizeVariance(pStubMsg);
4355 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4357 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4360 /***********************************************************************
4361 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4363 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4364 PFORMAT_STRING pFormat)
4366 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4367 PFORMAT_STRING pCVArrayFormat;
4369 unsigned char cvarray_type;
4371 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4373 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4374 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4376 ERR("invalid format type %x\n", pCVStructFormat->type);
4377 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4381 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4382 pCVStructFormat->offset_to_array_description;
4383 cvarray_type = *pCVArrayFormat;
4384 switch (cvarray_type)
4386 case RPC_FC_CVARRAY:
4387 esize = *(const WORD*)(pCVArrayFormat+2);
4388 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4390 case RPC_FC_C_CSTRING:
4391 esize = sizeof(char);
4392 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4393 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4395 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4397 case RPC_FC_C_WSTRING:
4398 esize = sizeof(WCHAR);
4399 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4400 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4402 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4405 ERR("invalid array format type %x\n", *pCVArrayFormat);
4406 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4410 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4412 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4414 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4415 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4416 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4418 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4420 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4422 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
4425 /***********************************************************************
4426 * NdrConformantVaryingStructFree [RPCRT4.@]
4428 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4429 unsigned char *pMemory,
4430 PFORMAT_STRING pFormat)
4432 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4433 PFORMAT_STRING pCVArrayFormat;
4436 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4438 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4439 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4441 ERR("invalid format type %x\n", pCVStructFormat->type);
4442 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4446 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4447 pCVStructFormat->offset_to_array_description;
4448 switch (*pCVArrayFormat)
4450 case RPC_FC_CVARRAY:
4451 esize = *(const WORD*)(pCVArrayFormat+2);
4453 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4454 pCVArrayFormat + 4, 0);
4455 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4458 case RPC_FC_C_CSTRING:
4459 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4460 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4461 esize = sizeof(char);
4462 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4463 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4464 pCVArrayFormat + 2, 0);
4466 pStubMsg->MaxCount = pStubMsg->ActualCount;
4468 case RPC_FC_C_WSTRING:
4469 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4470 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4471 esize = sizeof(WCHAR);
4472 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4473 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4474 pCVArrayFormat + 2, 0);
4476 pStubMsg->MaxCount = pStubMsg->ActualCount;
4479 ERR("invalid array format type %x\n", *pCVArrayFormat);
4480 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4484 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4486 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4489 #include "pshpack1.h"
4493 unsigned char alignment;
4494 unsigned short total_size;
4495 } NDR_SMFARRAY_FORMAT;
4500 unsigned char alignment;
4501 unsigned long total_size;
4502 } NDR_LGFARRAY_FORMAT;
4503 #include "poppack.h"
4505 /***********************************************************************
4506 * NdrFixedArrayMarshall [RPCRT4.@]
4508 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4509 unsigned char *pMemory,
4510 PFORMAT_STRING pFormat)
4512 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4513 unsigned long total_size;
4515 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4517 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4518 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4520 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4521 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4525 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4527 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4529 total_size = pSmFArrayFormat->total_size;
4530 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4534 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4535 total_size = pLgFArrayFormat->total_size;
4536 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4539 pStubMsg->BufferMark = pStubMsg->Buffer;
4540 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4542 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4547 /***********************************************************************
4548 * NdrFixedArrayUnmarshall [RPCRT4.@]
4550 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4551 unsigned char **ppMemory,
4552 PFORMAT_STRING pFormat,
4553 unsigned char fMustAlloc)
4555 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4556 unsigned long total_size;
4557 unsigned char *saved_buffer;
4559 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4561 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4562 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4564 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4565 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4569 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4571 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4573 total_size = pSmFArrayFormat->total_size;
4574 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4578 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4579 total_size = pLgFArrayFormat->total_size;
4580 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4584 *ppMemory = NdrAllocate(pStubMsg, total_size);
4587 if (!pStubMsg->IsClient && !*ppMemory)
4588 /* for servers, we just point straight into the RPC buffer */
4589 *ppMemory = pStubMsg->Buffer;
4592 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4593 safe_buffer_increment(pStubMsg, total_size);
4594 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4596 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4597 if (*ppMemory != saved_buffer)
4598 memcpy(*ppMemory, saved_buffer, total_size);
4603 /***********************************************************************
4604 * NdrFixedArrayBufferSize [RPCRT4.@]
4606 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4607 unsigned char *pMemory,
4608 PFORMAT_STRING pFormat)
4610 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4611 unsigned long total_size;
4613 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4615 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4616 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4618 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4619 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4623 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4625 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4627 total_size = pSmFArrayFormat->total_size;
4628 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4632 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4633 total_size = pLgFArrayFormat->total_size;
4634 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4636 safe_buffer_length_increment(pStubMsg, total_size);
4638 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4641 /***********************************************************************
4642 * NdrFixedArrayMemorySize [RPCRT4.@]
4644 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4645 PFORMAT_STRING pFormat)
4647 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4650 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4652 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4653 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4655 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4656 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4660 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4662 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4664 total_size = pSmFArrayFormat->total_size;
4665 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4669 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4670 total_size = pLgFArrayFormat->total_size;
4671 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4673 pStubMsg->BufferMark = pStubMsg->Buffer;
4674 safe_buffer_increment(pStubMsg, total_size);
4675 pStubMsg->MemorySize += total_size;
4677 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4682 /***********************************************************************
4683 * NdrFixedArrayFree [RPCRT4.@]
4685 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4686 unsigned char *pMemory,
4687 PFORMAT_STRING pFormat)
4689 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4691 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4693 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4694 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4696 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4697 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4701 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4702 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4705 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4706 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4709 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4712 /***********************************************************************
4713 * NdrVaryingArrayMarshall [RPCRT4.@]
4715 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4716 unsigned char *pMemory,
4717 PFORMAT_STRING pFormat)
4719 unsigned char alignment;
4720 DWORD elements, esize;
4723 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4725 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4726 (pFormat[0] != RPC_FC_LGVARRAY))
4728 ERR("invalid format type %x\n", pFormat[0]);
4729 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4733 alignment = pFormat[1] + 1;
4735 if (pFormat[0] == RPC_FC_SMVARRAY)
4738 pFormat += sizeof(WORD);
4739 elements = *(const WORD*)pFormat;
4740 pFormat += sizeof(WORD);
4745 pFormat += sizeof(DWORD);
4746 elements = *(const DWORD*)pFormat;
4747 pFormat += sizeof(DWORD);
4750 esize = *(const WORD*)pFormat;
4751 pFormat += sizeof(WORD);
4753 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4754 if ((pStubMsg->ActualCount > elements) ||
4755 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4757 RpcRaiseException(RPC_S_INVALID_BOUND);
4761 WriteVariance(pStubMsg);
4763 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
4765 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4766 pStubMsg->BufferMark = pStubMsg->Buffer;
4767 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
4769 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4774 /***********************************************************************
4775 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4777 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4778 unsigned char **ppMemory,
4779 PFORMAT_STRING pFormat,
4780 unsigned char fMustAlloc)
4782 unsigned char alignment;
4783 DWORD size, elements, esize;
4785 unsigned char *saved_buffer;
4788 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4790 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4791 (pFormat[0] != RPC_FC_LGVARRAY))
4793 ERR("invalid format type %x\n", pFormat[0]);
4794 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4798 alignment = pFormat[1] + 1;
4800 if (pFormat[0] == RPC_FC_SMVARRAY)
4803 size = *(const WORD*)pFormat;
4804 pFormat += sizeof(WORD);
4805 elements = *(const WORD*)pFormat;
4806 pFormat += sizeof(WORD);
4811 size = *(const DWORD*)pFormat;
4812 pFormat += sizeof(DWORD);
4813 elements = *(const DWORD*)pFormat;
4814 pFormat += sizeof(DWORD);
4817 esize = *(const WORD*)pFormat;
4818 pFormat += sizeof(WORD);
4820 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4822 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4824 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4825 offset = pStubMsg->Offset;
4827 if (!*ppMemory || fMustAlloc)
4828 *ppMemory = NdrAllocate(pStubMsg, size);
4829 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4830 safe_buffer_increment(pStubMsg, bufsize);
4832 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4834 memcpy(*ppMemory + offset, saved_buffer, bufsize);
4839 /***********************************************************************
4840 * NdrVaryingArrayBufferSize [RPCRT4.@]
4842 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4843 unsigned char *pMemory,
4844 PFORMAT_STRING pFormat)
4846 unsigned char alignment;
4847 DWORD elements, esize;
4849 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4851 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4852 (pFormat[0] != RPC_FC_LGVARRAY))
4854 ERR("invalid format type %x\n", pFormat[0]);
4855 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4859 alignment = pFormat[1] + 1;
4861 if (pFormat[0] == RPC_FC_SMVARRAY)
4864 pFormat += sizeof(WORD);
4865 elements = *(const WORD*)pFormat;
4866 pFormat += sizeof(WORD);
4871 pFormat += sizeof(DWORD);
4872 elements = *(const DWORD*)pFormat;
4873 pFormat += sizeof(DWORD);
4876 esize = *(const WORD*)pFormat;
4877 pFormat += sizeof(WORD);
4879 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4880 if ((pStubMsg->ActualCount > elements) ||
4881 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4883 RpcRaiseException(RPC_S_INVALID_BOUND);
4887 SizeVariance(pStubMsg);
4889 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4891 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4893 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4896 /***********************************************************************
4897 * NdrVaryingArrayMemorySize [RPCRT4.@]
4899 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4900 PFORMAT_STRING pFormat)
4902 unsigned char alignment;
4903 DWORD size, elements, esize;
4905 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4907 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4908 (pFormat[0] != RPC_FC_LGVARRAY))
4910 ERR("invalid format type %x\n", pFormat[0]);
4911 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4915 alignment = pFormat[1] + 1;
4917 if (pFormat[0] == RPC_FC_SMVARRAY)
4920 size = *(const WORD*)pFormat;
4921 pFormat += sizeof(WORD);
4922 elements = *(const WORD*)pFormat;
4923 pFormat += sizeof(WORD);
4928 size = *(const DWORD*)pFormat;
4929 pFormat += sizeof(DWORD);
4930 elements = *(const DWORD*)pFormat;
4931 pFormat += sizeof(DWORD);
4934 esize = *(const WORD*)pFormat;
4935 pFormat += sizeof(WORD);
4937 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4939 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4941 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4942 pStubMsg->MemorySize += size;
4944 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4946 return pStubMsg->MemorySize;
4949 /***********************************************************************
4950 * NdrVaryingArrayFree [RPCRT4.@]
4952 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4953 unsigned char *pMemory,
4954 PFORMAT_STRING pFormat)
4956 unsigned char alignment;
4959 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4961 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4962 (pFormat[0] != RPC_FC_LGVARRAY))
4964 ERR("invalid format type %x\n", pFormat[0]);
4965 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4969 alignment = pFormat[1] + 1;
4971 if (pFormat[0] == RPC_FC_SMVARRAY)
4974 pFormat += sizeof(WORD);
4975 elements = *(const WORD*)pFormat;
4976 pFormat += sizeof(WORD);
4981 pFormat += sizeof(DWORD);
4982 elements = *(const DWORD*)pFormat;
4983 pFormat += sizeof(DWORD);
4986 pFormat += sizeof(WORD);
4988 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4989 if ((pStubMsg->ActualCount > elements) ||
4990 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4992 RpcRaiseException(RPC_S_INVALID_BOUND);
4996 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4999 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5012 return *(const USHORT *)pMemory;
5016 return *(const ULONG *)pMemory;
5018 FIXME("Unhandled base type: 0x%02x\n", fc);
5023 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5024 unsigned long discriminant,
5025 PFORMAT_STRING pFormat)
5027 unsigned short num_arms, arm, type;
5029 num_arms = *(const SHORT*)pFormat & 0x0fff;
5031 for(arm = 0; arm < num_arms; arm++)
5033 if(discriminant == *(const ULONG*)pFormat)
5041 type = *(const unsigned short*)pFormat;
5042 TRACE("type %04x\n", type);
5043 if(arm == num_arms) /* default arm extras */
5047 ERR("no arm for 0x%lx and no default case\n", discriminant);
5048 RpcRaiseException(RPC_S_INVALID_TAG);
5053 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
5060 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5062 unsigned short type;
5066 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5070 type = *(const unsigned short*)pFormat;
5071 if((type & 0xff00) == 0x8000)
5073 unsigned char basetype = LOBYTE(type);
5074 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5078 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5079 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5082 unsigned char *saved_buffer = NULL;
5083 int pointer_buffer_mark_set = 0;
5090 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5091 saved_buffer = pStubMsg->Buffer;
5092 if (pStubMsg->PointerBufferMark)
5094 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5095 pStubMsg->PointerBufferMark = NULL;
5096 pointer_buffer_mark_set = 1;
5099 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5101 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5102 if (pointer_buffer_mark_set)
5104 STD_OVERFLOW_CHECK(pStubMsg);
5105 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5106 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5108 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5109 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5110 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5112 pStubMsg->Buffer = saved_buffer + 4;
5116 m(pStubMsg, pMemory, desc);
5119 else FIXME("no marshaller for embedded type %02x\n", *desc);
5124 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5125 unsigned char **ppMemory,
5127 PFORMAT_STRING pFormat,
5128 unsigned char fMustAlloc)
5130 unsigned short type;
5134 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5138 type = *(const unsigned short*)pFormat;
5139 if((type & 0xff00) == 0x8000)
5141 unsigned char basetype = LOBYTE(type);
5142 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5146 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5147 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5150 unsigned char *saved_buffer = NULL;
5151 int pointer_buffer_mark_set = 0;
5158 **(void***)ppMemory = NULL;
5159 ALIGN_POINTER(pStubMsg->Buffer, 4);
5160 saved_buffer = pStubMsg->Buffer;
5161 if (pStubMsg->PointerBufferMark)
5163 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5164 pStubMsg->PointerBufferMark = NULL;
5165 pointer_buffer_mark_set = 1;
5168 pStubMsg->Buffer += 4; /* for pointer ID */
5170 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5172 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5173 saved_buffer, pStubMsg->BufferEnd);
5174 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5177 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5178 if (pointer_buffer_mark_set)
5180 STD_OVERFLOW_CHECK(pStubMsg);
5181 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5182 pStubMsg->Buffer = saved_buffer + 4;
5186 m(pStubMsg, ppMemory, desc, fMustAlloc);
5189 else FIXME("no marshaller for embedded type %02x\n", *desc);
5194 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5195 unsigned char *pMemory,
5197 PFORMAT_STRING pFormat)
5199 unsigned short type;
5203 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5207 type = *(const unsigned short*)pFormat;
5208 if((type & 0xff00) == 0x8000)
5210 unsigned char basetype = LOBYTE(type);
5211 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5215 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5216 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5225 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5226 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5227 if (!pStubMsg->IgnoreEmbeddedPointers)
5229 int saved_buffer_length = pStubMsg->BufferLength;
5230 pStubMsg->BufferLength = pStubMsg->PointerLength;
5231 pStubMsg->PointerLength = 0;
5232 if(!pStubMsg->BufferLength)
5233 ERR("BufferLength == 0??\n");
5234 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5235 pStubMsg->PointerLength = pStubMsg->BufferLength;
5236 pStubMsg->BufferLength = saved_buffer_length;
5240 m(pStubMsg, pMemory, desc);
5243 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5247 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5249 PFORMAT_STRING pFormat)
5251 unsigned short type, size;
5253 size = *(const unsigned short*)pFormat;
5254 pStubMsg->Memory += size;
5257 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5261 type = *(const unsigned short*)pFormat;
5262 if((type & 0xff00) == 0x8000)
5264 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5268 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5269 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5270 unsigned char *saved_buffer;
5279 ALIGN_POINTER(pStubMsg->Buffer, 4);
5280 saved_buffer = pStubMsg->Buffer;
5281 safe_buffer_increment(pStubMsg, 4);
5282 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
5283 pStubMsg->MemorySize += 4;
5284 if (!pStubMsg->IgnoreEmbeddedPointers)
5285 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5288 return m(pStubMsg, desc);
5291 else FIXME("no marshaller for embedded type %02x\n", *desc);
5294 TRACE("size %d\n", size);
5298 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5299 unsigned char *pMemory,
5301 PFORMAT_STRING pFormat)
5303 unsigned short type;
5307 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5311 type = *(const unsigned short*)pFormat;
5312 if((type & 0xff00) != 0x8000)
5314 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5315 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5324 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5327 m(pStubMsg, pMemory, desc);
5333 /***********************************************************************
5334 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5336 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5337 unsigned char *pMemory,
5338 PFORMAT_STRING pFormat)
5340 unsigned char switch_type;
5341 unsigned char increment;
5344 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5347 switch_type = *pFormat & 0xf;
5348 increment = (*pFormat & 0xf0) >> 4;
5351 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5353 switch_value = get_discriminant(switch_type, pMemory);
5354 TRACE("got switch value 0x%x\n", switch_value);
5356 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5357 pMemory += increment;
5359 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5362 /***********************************************************************
5363 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5365 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5366 unsigned char **ppMemory,
5367 PFORMAT_STRING pFormat,
5368 unsigned char fMustAlloc)
5370 unsigned char switch_type;
5371 unsigned char increment;
5373 unsigned short size;
5374 unsigned char *pMemoryArm;
5376 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5379 switch_type = *pFormat & 0xf;
5380 increment = (*pFormat & 0xf0) >> 4;
5383 ALIGN_POINTER(pStubMsg->Buffer, increment);
5384 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5385 TRACE("got switch value 0x%x\n", switch_value);
5387 size = *(const unsigned short*)pFormat + increment;
5388 if(!*ppMemory || fMustAlloc)
5389 *ppMemory = NdrAllocate(pStubMsg, size);
5391 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5392 pMemoryArm = *ppMemory + increment;
5394 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
5397 /***********************************************************************
5398 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5400 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5401 unsigned char *pMemory,
5402 PFORMAT_STRING pFormat)
5404 unsigned char switch_type;
5405 unsigned char increment;
5408 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5411 switch_type = *pFormat & 0xf;
5412 increment = (*pFormat & 0xf0) >> 4;
5415 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5416 switch_value = get_discriminant(switch_type, pMemory);
5417 TRACE("got switch value 0x%x\n", switch_value);
5419 /* Add discriminant size */
5420 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5421 pMemory += increment;
5423 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5426 /***********************************************************************
5427 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5429 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5430 PFORMAT_STRING pFormat)
5432 unsigned char switch_type;
5433 unsigned char increment;
5436 switch_type = *pFormat & 0xf;
5437 increment = (*pFormat & 0xf0) >> 4;
5440 ALIGN_POINTER(pStubMsg->Buffer, increment);
5441 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5442 TRACE("got switch value 0x%x\n", switch_value);
5444 pStubMsg->Memory += increment;
5446 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5449 /***********************************************************************
5450 * NdrEncapsulatedUnionFree [RPCRT4.@]
5452 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5453 unsigned char *pMemory,
5454 PFORMAT_STRING pFormat)
5456 unsigned char switch_type;
5457 unsigned char increment;
5460 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5463 switch_type = *pFormat & 0xf;
5464 increment = (*pFormat & 0xf0) >> 4;
5467 switch_value = get_discriminant(switch_type, pMemory);
5468 TRACE("got switch value 0x%x\n", switch_value);
5470 pMemory += increment;
5472 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5475 /***********************************************************************
5476 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5478 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5479 unsigned char *pMemory,
5480 PFORMAT_STRING pFormat)
5482 unsigned char switch_type;
5484 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5487 switch_type = *pFormat;
5490 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5491 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5492 /* Marshall discriminant */
5493 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5495 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5498 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5499 PFORMAT_STRING *ppFormat)
5501 long discriminant = 0;
5511 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5520 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5521 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5529 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5530 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5535 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5539 if (pStubMsg->fHasNewCorrDesc)
5543 return discriminant;
5546 /**********************************************************************
5547 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5549 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5550 unsigned char **ppMemory,
5551 PFORMAT_STRING pFormat,
5552 unsigned char fMustAlloc)
5555 unsigned short size;
5557 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5560 /* Unmarshall discriminant */
5561 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5562 TRACE("unmarshalled discriminant %lx\n", discriminant);
5564 pFormat += *(const SHORT*)pFormat;
5566 size = *(const unsigned short*)pFormat;
5568 if(!*ppMemory || fMustAlloc)
5569 *ppMemory = NdrAllocate(pStubMsg, size);
5571 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5574 /***********************************************************************
5575 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5577 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5578 unsigned char *pMemory,
5579 PFORMAT_STRING pFormat)
5581 unsigned char switch_type;
5583 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5586 switch_type = *pFormat;
5589 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5590 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5591 /* Add discriminant size */
5592 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5594 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5597 /***********************************************************************
5598 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5600 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5601 PFORMAT_STRING pFormat)
5606 /* Unmarshall discriminant */
5607 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5608 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
5610 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
5613 /***********************************************************************
5614 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5616 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5617 unsigned char *pMemory,
5618 PFORMAT_STRING pFormat)
5620 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5624 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5625 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5627 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5630 /***********************************************************************
5631 * NdrByteCountPointerMarshall [RPCRT4.@]
5633 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5634 unsigned char *pMemory,
5635 PFORMAT_STRING pFormat)
5641 /***********************************************************************
5642 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5644 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5645 unsigned char **ppMemory,
5646 PFORMAT_STRING pFormat,
5647 unsigned char fMustAlloc)
5653 /***********************************************************************
5654 * NdrByteCountPointerBufferSize [RPCRT4.@]
5656 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5657 unsigned char *pMemory,
5658 PFORMAT_STRING pFormat)
5663 /***********************************************************************
5664 * NdrByteCountPointerMemorySize [RPCRT4.@]
5666 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5667 PFORMAT_STRING pFormat)
5673 /***********************************************************************
5674 * NdrByteCountPointerFree [RPCRT4.@]
5676 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
5677 unsigned char *pMemory,
5678 PFORMAT_STRING pFormat)
5683 /***********************************************************************
5684 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5686 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5687 unsigned char *pMemory,
5688 PFORMAT_STRING pFormat)
5694 /***********************************************************************
5695 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5697 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5698 unsigned char **ppMemory,
5699 PFORMAT_STRING pFormat,
5700 unsigned char fMustAlloc)
5706 /***********************************************************************
5707 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5709 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5710 unsigned char *pMemory,
5711 PFORMAT_STRING pFormat)
5716 /***********************************************************************
5717 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5719 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5720 PFORMAT_STRING pFormat)
5726 /***********************************************************************
5727 * NdrXmitOrRepAsFree [RPCRT4.@]
5729 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
5730 unsigned char *pMemory,
5731 PFORMAT_STRING pFormat)
5736 #include "pshpack1.h"
5740 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
5744 #include "poppack.h"
5746 /***********************************************************************
5747 * NdrRangeMarshall [internal]
5749 unsigned char *WINAPI NdrRangeMarshall(
5750 PMIDL_STUB_MESSAGE pStubMsg,
5751 unsigned char *pMemory,
5752 PFORMAT_STRING pFormat)
5754 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5755 unsigned char base_type;
5757 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5759 if (pRange->type != RPC_FC_RANGE)
5761 ERR("invalid format type %x\n", pRange->type);
5762 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5766 base_type = pRange->flags_type & 0xf;
5768 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
5771 /***********************************************************************
5772 * NdrRangeUnmarshall
5774 unsigned char *WINAPI NdrRangeUnmarshall(
5775 PMIDL_STUB_MESSAGE pStubMsg,
5776 unsigned char **ppMemory,
5777 PFORMAT_STRING pFormat,
5778 unsigned char fMustAlloc)
5780 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5781 unsigned char base_type;
5783 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5785 if (pRange->type != RPC_FC_RANGE)
5787 ERR("invalid format type %x\n", pRange->type);
5788 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5791 base_type = pRange->flags_type & 0xf;
5793 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5794 base_type, pRange->low_value, pRange->high_value);
5796 #define RANGE_UNMARSHALL(type, format_spec) \
5799 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5800 if (fMustAlloc || !*ppMemory) \
5801 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5802 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5804 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5805 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5806 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5808 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5809 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5811 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5812 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5813 (type)pRange->high_value); \
5814 RpcRaiseException(RPC_S_INVALID_BOUND); \
5817 TRACE("*ppMemory: %p\n", *ppMemory); \
5818 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5819 pStubMsg->Buffer += sizeof(type); \
5826 RANGE_UNMARSHALL(UCHAR, "%d");
5827 TRACE("value: 0x%02x\n", **ppMemory);
5831 RANGE_UNMARSHALL(CHAR, "%u");
5832 TRACE("value: 0x%02x\n", **ppMemory);
5834 case RPC_FC_WCHAR: /* FIXME: valid? */
5836 RANGE_UNMARSHALL(USHORT, "%u");
5837 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5840 RANGE_UNMARSHALL(SHORT, "%d");
5841 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5844 RANGE_UNMARSHALL(LONG, "%d");
5845 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5848 RANGE_UNMARSHALL(ULONG, "%u");
5849 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5853 FIXME("Unhandled enum type\n");
5855 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
5860 ERR("invalid range base type: 0x%02x\n", base_type);
5861 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5867 /***********************************************************************
5868 * NdrRangeBufferSize [internal]
5870 void WINAPI NdrRangeBufferSize(
5871 PMIDL_STUB_MESSAGE pStubMsg,
5872 unsigned char *pMemory,
5873 PFORMAT_STRING pFormat)
5875 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5876 unsigned char base_type;
5878 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5880 if (pRange->type != RPC_FC_RANGE)
5882 ERR("invalid format type %x\n", pRange->type);
5883 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5885 base_type = pRange->flags_type & 0xf;
5887 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
5890 /***********************************************************************
5891 * NdrRangeMemorySize [internal]
5893 ULONG WINAPI NdrRangeMemorySize(
5894 PMIDL_STUB_MESSAGE pStubMsg,
5895 PFORMAT_STRING pFormat)
5897 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5898 unsigned char base_type;
5900 if (pRange->type != RPC_FC_RANGE)
5902 ERR("invalid format type %x\n", pRange->type);
5903 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5906 base_type = pRange->flags_type & 0xf;
5908 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
5911 /***********************************************************************
5912 * NdrRangeFree [internal]
5914 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
5915 unsigned char *pMemory,
5916 PFORMAT_STRING pFormat)
5918 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5923 /***********************************************************************
5924 * NdrBaseTypeMarshall [internal]
5926 static unsigned char *WINAPI NdrBaseTypeMarshall(
5927 PMIDL_STUB_MESSAGE pStubMsg,
5928 unsigned char *pMemory,
5929 PFORMAT_STRING pFormat)
5931 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5939 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
5940 TRACE("value: 0x%02x\n", *pMemory);
5945 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
5946 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
5947 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
5951 case RPC_FC_ERROR_STATUS_T:
5953 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
5954 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
5955 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
5958 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
5959 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
5962 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
5963 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
5966 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
5967 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
5968 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
5971 /* only 16-bits on the wire, so do a sanity check */
5972 if (*(UINT *)pMemory > SHRT_MAX)
5973 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
5974 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
5975 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5976 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5977 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
5978 pStubMsg->Buffer += sizeof(USHORT);
5979 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
5984 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5987 /* FIXME: what is the correct return value? */
5991 /***********************************************************************
5992 * NdrBaseTypeUnmarshall [internal]
5994 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
5995 PMIDL_STUB_MESSAGE pStubMsg,
5996 unsigned char **ppMemory,
5997 PFORMAT_STRING pFormat,
5998 unsigned char fMustAlloc)
6000 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6002 #define BASE_TYPE_UNMARSHALL(type) \
6003 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6004 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6006 *ppMemory = pStubMsg->Buffer; \
6007 TRACE("*ppMemory: %p\n", *ppMemory); \
6012 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6013 TRACE("*ppMemory: %p\n", *ppMemory); \
6014 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
6016 pStubMsg->Buffer += sizeof(type);
6024 BASE_TYPE_UNMARSHALL(UCHAR);
6025 TRACE("value: 0x%02x\n", **ppMemory);
6030 BASE_TYPE_UNMARSHALL(USHORT);
6031 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6035 case RPC_FC_ERROR_STATUS_T:
6037 BASE_TYPE_UNMARSHALL(ULONG);
6038 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6041 BASE_TYPE_UNMARSHALL(float);
6042 TRACE("value: %f\n", **(float **)ppMemory);
6045 BASE_TYPE_UNMARSHALL(double);
6046 TRACE("value: %f\n", **(double **)ppMemory);
6049 BASE_TYPE_UNMARSHALL(ULONGLONG);
6050 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6053 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6054 if (fMustAlloc || !*ppMemory)
6055 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6056 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
6057 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6058 TRACE("*ppMemory: %p\n", *ppMemory);
6059 /* 16-bits on the wire, but int in memory */
6060 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
6061 pStubMsg->Buffer += sizeof(USHORT);
6062 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6067 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6069 #undef BASE_TYPE_UNMARSHALL
6071 /* FIXME: what is the correct return value? */
6076 /***********************************************************************
6077 * NdrBaseTypeBufferSize [internal]
6079 static void WINAPI NdrBaseTypeBufferSize(
6080 PMIDL_STUB_MESSAGE pStubMsg,
6081 unsigned char *pMemory,
6082 PFORMAT_STRING pFormat)
6084 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6092 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6098 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
6099 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6104 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
6105 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6108 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
6109 safe_buffer_length_increment(pStubMsg, sizeof(float));
6112 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
6113 safe_buffer_length_increment(pStubMsg, sizeof(double));
6116 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
6117 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6119 case RPC_FC_ERROR_STATUS_T:
6120 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
6121 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6126 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6130 /***********************************************************************
6131 * NdrBaseTypeMemorySize [internal]
6133 static ULONG WINAPI NdrBaseTypeMemorySize(
6134 PMIDL_STUB_MESSAGE pStubMsg,
6135 PFORMAT_STRING pFormat)
6137 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6145 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6146 pStubMsg->MemorySize += sizeof(UCHAR);
6147 return sizeof(UCHAR);
6151 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6152 pStubMsg->MemorySize += sizeof(USHORT);
6153 return sizeof(USHORT);
6157 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6158 pStubMsg->MemorySize += sizeof(ULONG);
6159 return sizeof(ULONG);
6161 safe_buffer_increment(pStubMsg, sizeof(float));
6162 pStubMsg->MemorySize += sizeof(float);
6163 return sizeof(float);
6165 safe_buffer_increment(pStubMsg, sizeof(double));
6166 pStubMsg->MemorySize += sizeof(double);
6167 return sizeof(double);
6169 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6170 pStubMsg->MemorySize += sizeof(ULONGLONG);
6171 return sizeof(ULONGLONG);
6172 case RPC_FC_ERROR_STATUS_T:
6173 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6174 pStubMsg->MemorySize += sizeof(error_status_t);
6175 return sizeof(error_status_t);
6177 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6178 pStubMsg->MemorySize += sizeof(UINT);
6179 return sizeof(UINT);
6181 pStubMsg->MemorySize += sizeof(void *);
6182 return sizeof(void *);
6184 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6189 /***********************************************************************
6190 * NdrBaseTypeFree [internal]
6192 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6193 unsigned char *pMemory,
6194 PFORMAT_STRING pFormat)
6196 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6201 /***********************************************************************
6202 * NdrContextHandleBufferSize [internal]
6204 static void WINAPI NdrContextHandleBufferSize(
6205 PMIDL_STUB_MESSAGE pStubMsg,
6206 unsigned char *pMemory,
6207 PFORMAT_STRING pFormat)
6209 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6211 if (*pFormat != RPC_FC_BIND_CONTEXT)
6213 ERR("invalid format type %x\n", *pFormat);
6214 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6216 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
6217 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6220 /***********************************************************************
6221 * NdrContextHandleMarshall [internal]
6223 static unsigned char *WINAPI NdrContextHandleMarshall(
6224 PMIDL_STUB_MESSAGE pStubMsg,
6225 unsigned char *pMemory,
6226 PFORMAT_STRING pFormat)
6228 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6230 if (*pFormat != RPC_FC_BIND_CONTEXT)
6232 ERR("invalid format type %x\n", *pFormat);
6233 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6235 TRACE("flags: 0x%02x\n", pFormat[1]);
6237 if (pFormat[1] & 0x80)
6238 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6240 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
6245 /***********************************************************************
6246 * NdrContextHandleUnmarshall [internal]
6248 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6249 PMIDL_STUB_MESSAGE pStubMsg,
6250 unsigned char **ppMemory,
6251 PFORMAT_STRING pFormat,
6252 unsigned char fMustAlloc)
6254 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6255 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6257 if (*pFormat != RPC_FC_BIND_CONTEXT)
6259 ERR("invalid format type %x\n", *pFormat);
6260 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6262 TRACE("flags: 0x%02x\n", pFormat[1]);
6264 /* [out]-only or [ret] param */
6265 if ((pFormat[1] & 0x60) == 0x20)
6266 **(NDR_CCONTEXT **)ppMemory = NULL;
6267 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6272 /***********************************************************************
6273 * NdrClientContextMarshall [RPCRT4.@]
6275 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6276 NDR_CCONTEXT ContextHandle,
6279 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
6281 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
6283 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6285 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6286 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6287 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6290 /* FIXME: what does fCheck do? */
6291 NDRCContextMarshall(ContextHandle,
6294 pStubMsg->Buffer += cbNDRContext;
6297 /***********************************************************************
6298 * NdrClientContextUnmarshall [RPCRT4.@]
6300 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6301 NDR_CCONTEXT * pContextHandle,
6302 RPC_BINDING_HANDLE BindHandle)
6304 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
6306 ALIGN_POINTER(pStubMsg->Buffer, 4);
6308 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
6309 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6311 NDRCContextUnmarshall(pContextHandle,
6314 pStubMsg->RpcMsg->DataRepresentation);
6316 pStubMsg->Buffer += cbNDRContext;
6319 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6320 NDR_SCONTEXT ContextHandle,
6321 NDR_RUNDOWN RundownRoutine )
6323 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
6325 ALIGN_POINTER(pStubMsg->Buffer, 4);
6327 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6329 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6330 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6331 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6334 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6335 pStubMsg->Buffer, RundownRoutine, NULL,
6336 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6337 pStubMsg->Buffer += cbNDRContext;
6340 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6342 NDR_SCONTEXT ContextHandle;
6344 TRACE("(%p)\n", pStubMsg);
6346 ALIGN_POINTER(pStubMsg->Buffer, 4);
6348 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6350 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6351 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6352 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6355 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6357 pStubMsg->RpcMsg->DataRepresentation,
6358 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6359 pStubMsg->Buffer += cbNDRContext;
6361 return ContextHandle;
6364 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6365 unsigned char* pMemory,
6366 PFORMAT_STRING pFormat)
6368 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6371 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6372 PFORMAT_STRING pFormat)
6374 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6375 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6377 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6379 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6380 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6381 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6382 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6383 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6385 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6386 if_id = &sif->InterfaceId;
6389 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
6390 pStubMsg->RpcMsg->DataRepresentation, if_id,
6394 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6395 NDR_SCONTEXT ContextHandle,
6396 NDR_RUNDOWN RundownRoutine,
6397 PFORMAT_STRING pFormat)
6399 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6400 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6402 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6404 ALIGN_POINTER(pStubMsg->Buffer, 4);
6406 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6408 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6409 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6410 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6413 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6414 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6415 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6416 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6417 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6419 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6420 if_id = &sif->InterfaceId;
6423 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6424 pStubMsg->Buffer, RundownRoutine, if_id, flags);
6425 pStubMsg->Buffer += cbNDRContext;
6428 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6429 PFORMAT_STRING pFormat)
6431 NDR_SCONTEXT ContextHandle;
6432 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6433 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6435 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6437 ALIGN_POINTER(pStubMsg->Buffer, 4);
6439 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6441 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6442 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6443 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6446 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6447 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6448 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6449 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6450 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6452 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6453 if_id = &sif->InterfaceId;
6456 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6458 pStubMsg->RpcMsg->DataRepresentation,
6460 pStubMsg->Buffer += cbNDRContext;
6462 return ContextHandle;
6465 /***********************************************************************
6466 * NdrCorrelationInitialize [RPCRT4.@]
6468 * Initializes correlation validity checking.
6471 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6472 * pMemory [I] Pointer to memory to use as a cache.
6473 * CacheSize [I] Size of the memory pointed to by pMemory.
6474 * Flags [I] Reserved. Set to zero.
6479 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
6481 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
6482 pStubMsg->fHasNewCorrDesc = TRUE;
6485 /***********************************************************************
6486 * NdrCorrelationPass [RPCRT4.@]
6488 * Performs correlation validity checking.
6491 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6496 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
6498 FIXME("(%p): stub\n", pStubMsg);
6501 /***********************************************************************
6502 * NdrCorrelationFree [RPCRT4.@]
6504 * Frees any resources used while unmarshalling parameters that need
6505 * correlation validity checking.
6508 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6513 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
6515 FIXME("(%p): stub\n", pStubMsg);