4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * - Byte count pointers
24 * - transmit_as/represent as
25 * - Multi-dimensional arrays
26 * - Conversion functions (NdrConvert)
27 * - Checks for integer addition overflow in user marshall functions
35 #define NONAMELESSUNION
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)))
64 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
66 MAKEWORD(*(pchar), *((pchar)+1)), \
67 MAKEWORD(*((pchar)+2), *((pchar)+3))))
70 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
71 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
72 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
73 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
74 *(pchar) = HIBYTE(HIWORD(uint32)))
76 #define BIG_ENDIAN_UINT32_READ(pchar) \
78 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
79 MAKEWORD(*((pchar)+1), *(pchar))))
81 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
82 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
83 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
84 # define NDR_LOCAL_UINT32_READ(pchar) \
85 BIG_ENDIAN_UINT32_READ(pchar)
87 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
88 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
89 # define NDR_LOCAL_UINT32_READ(pchar) \
90 LITTLE_ENDIAN_UINT32_READ(pchar)
93 /* _Align must be the desired alignment,
94 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
95 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
96 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
97 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
98 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
99 #define ALIGN_POINTER_CLEAR(_Ptr, _Align) \
101 memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \
102 ALIGN_POINTER(_Ptr, _Align); \
105 #define STD_OVERFLOW_CHECK(_Msg) do { \
106 TRACE("buffer=%d/%d\n", (ULONG)(_Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer), _Msg->BufferLength); \
107 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
108 ERR("buffer overflow %d bytes\n", (ULONG)(_Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength))); \
111 #define NDR_POINTER_ID_BASE 0x20000
112 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
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 static unsigned char *WINAPI NdrRangeMarshall(PMIDL_STUB_MESSAGE,unsigned char *, PFORMAT_STRING);
127 static void WINAPI NdrRangeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
128 static ULONG WINAPI NdrRangeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
129 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
131 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
133 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
135 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
136 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
137 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
138 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
142 NdrPointerMarshall, NdrPointerMarshall,
143 NdrPointerMarshall, NdrPointerMarshall,
145 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
146 NdrConformantStructMarshall, NdrConformantStructMarshall,
147 NdrConformantVaryingStructMarshall,
148 NdrComplexStructMarshall,
150 NdrConformantArrayMarshall,
151 NdrConformantVaryingArrayMarshall,
152 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
153 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
154 NdrComplexArrayMarshall,
156 NdrConformantStringMarshall, 0, 0,
157 NdrConformantStringMarshall,
158 NdrNonConformantStringMarshall, 0, 0, 0,
160 NdrEncapsulatedUnionMarshall,
161 NdrNonEncapsulatedUnionMarshall,
162 NdrByteCountPointerMarshall,
163 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
165 NdrInterfacePointerMarshall,
167 NdrContextHandleMarshall,
170 NdrUserMarshalMarshall,
175 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
177 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
178 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
179 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
180 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
182 NdrBaseTypeUnmarshall,
184 NdrPointerUnmarshall, NdrPointerUnmarshall,
185 NdrPointerUnmarshall, NdrPointerUnmarshall,
187 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
188 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
189 NdrConformantVaryingStructUnmarshall,
190 NdrComplexStructUnmarshall,
192 NdrConformantArrayUnmarshall,
193 NdrConformantVaryingArrayUnmarshall,
194 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
195 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
196 NdrComplexArrayUnmarshall,
198 NdrConformantStringUnmarshall, 0, 0,
199 NdrConformantStringUnmarshall,
200 NdrNonConformantStringUnmarshall, 0, 0, 0,
202 NdrEncapsulatedUnionUnmarshall,
203 NdrNonEncapsulatedUnionUnmarshall,
204 NdrByteCountPointerUnmarshall,
205 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
207 NdrInterfacePointerUnmarshall,
209 NdrContextHandleUnmarshall,
212 NdrUserMarshalUnmarshall,
217 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
219 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
220 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
221 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
222 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
224 NdrBaseTypeBufferSize,
226 NdrPointerBufferSize, NdrPointerBufferSize,
227 NdrPointerBufferSize, NdrPointerBufferSize,
229 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
230 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
231 NdrConformantVaryingStructBufferSize,
232 NdrComplexStructBufferSize,
234 NdrConformantArrayBufferSize,
235 NdrConformantVaryingArrayBufferSize,
236 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
237 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
238 NdrComplexArrayBufferSize,
240 NdrConformantStringBufferSize, 0, 0,
241 NdrConformantStringBufferSize,
242 NdrNonConformantStringBufferSize, 0, 0, 0,
244 NdrEncapsulatedUnionBufferSize,
245 NdrNonEncapsulatedUnionBufferSize,
246 NdrByteCountPointerBufferSize,
247 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
249 NdrInterfacePointerBufferSize,
251 NdrContextHandleBufferSize,
254 NdrUserMarshalBufferSize,
259 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
261 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
262 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
263 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
264 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
266 NdrBaseTypeMemorySize,
268 NdrPointerMemorySize, NdrPointerMemorySize,
269 NdrPointerMemorySize, NdrPointerMemorySize,
271 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
272 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
273 NdrConformantVaryingStructMemorySize,
274 NdrComplexStructMemorySize,
276 NdrConformantArrayMemorySize,
277 NdrConformantVaryingArrayMemorySize,
278 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
279 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
280 NdrComplexArrayMemorySize,
282 NdrConformantStringMemorySize, 0, 0,
283 NdrConformantStringMemorySize,
284 NdrNonConformantStringMemorySize, 0, 0, 0,
286 NdrEncapsulatedUnionMemorySize,
287 NdrNonEncapsulatedUnionMemorySize,
288 NdrByteCountPointerMemorySize,
289 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
291 NdrInterfacePointerMemorySize,
296 NdrUserMarshalMemorySize,
301 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
303 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
304 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
305 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
306 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
310 NdrPointerFree, NdrPointerFree,
311 NdrPointerFree, NdrPointerFree,
313 NdrSimpleStructFree, NdrSimpleStructFree,
314 NdrConformantStructFree, NdrConformantStructFree,
315 NdrConformantVaryingStructFree,
316 NdrComplexStructFree,
318 NdrConformantArrayFree,
319 NdrConformantVaryingArrayFree,
320 NdrFixedArrayFree, NdrFixedArrayFree,
321 NdrVaryingArrayFree, NdrVaryingArrayFree,
327 NdrEncapsulatedUnionFree,
328 NdrNonEncapsulatedUnionFree,
330 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
332 NdrInterfacePointerFree,
343 typedef struct _NDR_MEMORY_LIST
348 struct _NDR_MEMORY_LIST *next;
351 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
353 /***********************************************************************
354 * NdrAllocate [RPCRT4.@]
356 * Allocates a block of memory using pStubMsg->pfnAllocate.
359 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
360 * len [I] Size of memory block to allocate.
363 * The memory block of size len that was allocated.
366 * The memory block is always 8-byte aligned.
367 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
368 * exception is raised.
370 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, SIZE_T len)
375 NDR_MEMORY_LIST *mem_list;
377 aligned_len = ALIGNED_LENGTH(len, 8);
378 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
379 /* check for overflow */
380 if (adjusted_len < len)
382 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len, len);
383 RpcRaiseException(RPC_X_BAD_STUB_DATA);
386 p = pStubMsg->pfnAllocate(adjusted_len);
387 if (!p) RpcRaiseException(ERROR_OUTOFMEMORY);
389 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
390 mem_list->magic = MEML_MAGIC;
391 mem_list->size = aligned_len;
392 mem_list->reserved = 0;
393 mem_list->next = pStubMsg->pMemoryList;
394 pStubMsg->pMemoryList = mem_list;
400 static void NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
402 TRACE("(%p, %p)\n", pStubMsg, Pointer);
404 pStubMsg->pfnFree(Pointer);
407 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
409 return (*(const ULONG *)pFormat != -1);
412 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
414 ALIGN_POINTER(pStubMsg->Buffer, 4);
415 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
416 RpcRaiseException(RPC_X_BAD_STUB_DATA);
417 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
418 pStubMsg->Buffer += 4;
419 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
420 if (pStubMsg->fHasNewCorrDesc)
426 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
428 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
430 pStubMsg->Offset = 0;
431 pStubMsg->ActualCount = pStubMsg->MaxCount;
435 ALIGN_POINTER(pStubMsg->Buffer, 4);
436 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
437 RpcRaiseException(RPC_X_BAD_STUB_DATA);
438 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
439 pStubMsg->Buffer += 4;
440 TRACE("offset is %d\n", pStubMsg->Offset);
441 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
442 pStubMsg->Buffer += 4;
443 TRACE("variance is %d\n", pStubMsg->ActualCount);
445 if ((pStubMsg->ActualCount > MaxValue) ||
446 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
448 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
449 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
450 RpcRaiseException(RPC_S_INVALID_BOUND);
455 if (pStubMsg->fHasNewCorrDesc)
461 /* writes the conformance value to the buffer */
462 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
464 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
465 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
466 RpcRaiseException(RPC_X_BAD_STUB_DATA);
467 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
468 pStubMsg->Buffer += 4;
471 /* writes the variance values to the buffer */
472 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
474 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
475 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
476 RpcRaiseException(RPC_X_BAD_STUB_DATA);
477 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
478 pStubMsg->Buffer += 4;
479 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
480 pStubMsg->Buffer += 4;
483 /* requests buffer space for the conformance value */
484 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
486 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
487 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
488 RpcRaiseException(RPC_X_BAD_STUB_DATA);
489 pStubMsg->BufferLength += 4;
492 /* requests buffer space for the variance values */
493 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
495 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
496 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
497 RpcRaiseException(RPC_X_BAD_STUB_DATA);
498 pStubMsg->BufferLength += 8;
501 PFORMAT_STRING ComputeConformanceOrVariance(
502 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
503 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
505 BYTE dtype = pFormat[0] & 0xf;
506 short ofs = *(const short *)&pFormat[2];
510 if (!IsConformanceOrVariancePresent(pFormat)) {
511 /* null descriptor */
516 switch (pFormat[0] & 0xf0) {
517 case RPC_FC_NORMAL_CONFORMANCE:
518 TRACE("normal conformance, ofs=%d\n", ofs);
521 case RPC_FC_POINTER_CONFORMANCE:
522 TRACE("pointer conformance, ofs=%d\n", ofs);
523 ptr = pStubMsg->Memory;
525 case RPC_FC_TOP_LEVEL_CONFORMANCE:
526 TRACE("toplevel conformance, ofs=%d\n", ofs);
527 if (pStubMsg->StackTop) {
528 ptr = pStubMsg->StackTop;
531 /* -Os mode, *pCount is already set */
535 case RPC_FC_CONSTANT_CONFORMANCE:
536 data = ofs | ((DWORD)pFormat[1] << 16);
537 TRACE("constant conformance, val=%d\n", data);
540 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
541 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
542 if (pStubMsg->StackTop) {
543 ptr = pStubMsg->StackTop;
551 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
554 switch (pFormat[1]) {
555 case RPC_FC_DEREFERENCE:
556 ptr = *(LPVOID*)((char *)ptr + ofs);
558 case RPC_FC_CALLBACK:
560 unsigned char *old_stack_top = pStubMsg->StackTop;
561 pStubMsg->StackTop = ptr;
563 /* ofs is index into StubDesc->apfnExprEval */
564 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
565 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
567 pStubMsg->StackTop = old_stack_top;
569 /* the callback function always stores the computed value in MaxCount */
570 *pCount = pStubMsg->MaxCount;
574 ptr = (char *)ptr + ofs;
587 data = *(USHORT*)ptr;
598 FIXME("unknown conformance data type %x\n", dtype);
601 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
604 switch (pFormat[1]) {
605 case RPC_FC_DEREFERENCE: /* already handled */
622 FIXME("unknown conformance op %d\n", pFormat[1]);
627 TRACE("resulting conformance is %ld\n", *pCount);
628 if (pStubMsg->fHasNewCorrDesc)
634 static inline PFORMAT_STRING SkipConformance(PMIDL_STUB_MESSAGE pStubMsg,
635 PFORMAT_STRING pFormat)
637 if (IsConformanceOrVariancePresent(pFormat))
639 if (pStubMsg->fHasNewCorrDesc)
647 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
648 * the result overflows 32-bits */
649 static inline ULONG safe_multiply(ULONG a, ULONG b)
651 ULONGLONG ret = (ULONGLONG)a * b;
652 if (ret > 0xffffffff)
654 RpcRaiseException(RPC_S_INVALID_BOUND);
660 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
662 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
663 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
664 RpcRaiseException(RPC_X_BAD_STUB_DATA);
665 pStubMsg->Buffer += size;
668 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
670 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
672 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
673 pStubMsg->BufferLength, size);
674 RpcRaiseException(RPC_X_BAD_STUB_DATA);
676 pStubMsg->BufferLength += size;
679 /* copies data from the buffer, checking that there is enough data in the buffer
681 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
683 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
684 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
686 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
687 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
688 RpcRaiseException(RPC_X_BAD_STUB_DATA);
690 if (p == pStubMsg->Buffer)
691 ERR("pointer is the same as the buffer\n");
692 memcpy(p, pStubMsg->Buffer, size);
693 pStubMsg->Buffer += size;
696 /* copies data to the buffer, checking that there is enough space to do so */
697 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
699 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
700 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
702 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
703 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
705 RpcRaiseException(RPC_X_BAD_STUB_DATA);
707 memcpy(pStubMsg->Buffer, p, size);
708 pStubMsg->Buffer += size;
711 /* verify that string data sitting in the buffer is valid and safe to
713 static void validate_string_data(MIDL_STUB_MESSAGE *pStubMsg, ULONG bufsize, ULONG esize)
717 /* verify the buffer is safe to access */
718 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
719 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
721 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
722 pStubMsg->BufferEnd, pStubMsg->Buffer);
723 RpcRaiseException(RPC_X_BAD_STUB_DATA);
726 /* strings must always have null terminating bytes */
729 ERR("invalid string length of %d\n", bufsize / esize);
730 RpcRaiseException(RPC_S_INVALID_BOUND);
733 for (i = bufsize - esize; i < bufsize; i++)
734 if (pStubMsg->Buffer[i] != 0)
736 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
737 i, pStubMsg->Buffer[i]);
738 RpcRaiseException(RPC_S_INVALID_BOUND);
742 static inline void dump_pointer_attr(unsigned char attr)
744 if (attr & RPC_FC_P_ALLOCALLNODES)
745 TRACE(" RPC_FC_P_ALLOCALLNODES");
746 if (attr & RPC_FC_P_DONTFREE)
747 TRACE(" RPC_FC_P_DONTFREE");
748 if (attr & RPC_FC_P_ONSTACK)
749 TRACE(" RPC_FC_P_ONSTACK");
750 if (attr & RPC_FC_P_SIMPLEPOINTER)
751 TRACE(" RPC_FC_P_SIMPLEPOINTER");
752 if (attr & RPC_FC_P_DEREF)
753 TRACE(" RPC_FC_P_DEREF");
757 /***********************************************************************
758 * PointerMarshall [internal]
760 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
761 unsigned char *Buffer,
762 unsigned char *Pointer,
763 PFORMAT_STRING pFormat)
765 unsigned type = pFormat[0], attr = pFormat[1];
769 int pointer_needs_marshaling;
771 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
772 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
774 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
775 else desc = pFormat + *(const SHORT*)pFormat;
778 case RPC_FC_RP: /* ref pointer (always non-null) */
781 ERR("NULL ref pointer is not allowed\n");
782 RpcRaiseException(RPC_X_NULL_REF_POINTER);
784 pointer_needs_marshaling = 1;
786 case RPC_FC_UP: /* unique pointer */
787 case RPC_FC_OP: /* object pointer - same as unique here */
789 pointer_needs_marshaling = 1;
791 pointer_needs_marshaling = 0;
792 pointer_id = Pointer ? NDR_POINTER_ID(pStubMsg) : 0;
793 TRACE("writing 0x%08x to buffer\n", pointer_id);
794 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
797 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
798 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
799 TRACE("writing 0x%08x to buffer\n", pointer_id);
800 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
803 FIXME("unhandled ptr type=%02x\n", type);
804 RpcRaiseException(RPC_X_BAD_STUB_DATA);
808 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
810 if (pointer_needs_marshaling) {
811 if (attr & RPC_FC_P_DEREF) {
812 Pointer = *(unsigned char**)Pointer;
813 TRACE("deref => %p\n", Pointer);
815 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
816 if (m) m(pStubMsg, Pointer, desc);
817 else FIXME("no marshaller for data type=%02x\n", *desc);
820 STD_OVERFLOW_CHECK(pStubMsg);
823 /***********************************************************************
824 * PointerUnmarshall [internal]
826 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
827 unsigned char *Buffer,
828 unsigned char **pPointer,
829 unsigned char *pSrcPointer,
830 PFORMAT_STRING pFormat,
831 unsigned char fMustAlloc)
833 unsigned type = pFormat[0], attr = pFormat[1];
836 DWORD pointer_id = 0;
837 int pointer_needs_unmarshaling;
839 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
840 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
842 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
843 else desc = pFormat + *(const SHORT*)pFormat;
846 case RPC_FC_RP: /* ref pointer (always non-null) */
847 pointer_needs_unmarshaling = 1;
849 case RPC_FC_UP: /* unique pointer */
850 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
851 TRACE("pointer_id is 0x%08x\n", pointer_id);
853 pointer_needs_unmarshaling = 1;
856 pointer_needs_unmarshaling = 0;
859 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
860 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
861 TRACE("pointer_id is 0x%08x\n", pointer_id);
862 if (!fMustAlloc && pSrcPointer)
864 FIXME("free object pointer %p\n", pSrcPointer);
868 pointer_needs_unmarshaling = 1;
872 pointer_needs_unmarshaling = 0;
876 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
877 TRACE("pointer_id is 0x%08x\n", pointer_id);
878 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
879 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
882 FIXME("unhandled ptr type=%02x\n", type);
883 RpcRaiseException(RPC_X_BAD_STUB_DATA);
887 if (pointer_needs_unmarshaling) {
888 unsigned char *base_ptr_val = *pPointer;
889 unsigned char **current_ptr = pPointer;
890 if (pStubMsg->IsClient) {
892 /* if we aren't forcing allocation of memory then try to use the existing
893 * (source) pointer to unmarshall the data into so that [in,out]
894 * parameters behave correctly. it doesn't matter if the parameter is
895 * [out] only since in that case the pointer will be NULL. we force
896 * allocation when the source pointer is NULL here instead of in the type
897 * unmarshalling routine for the benefit of the deref code below */
900 TRACE("setting *pPointer to %p\n", pSrcPointer);
901 *pPointer = base_ptr_val = pSrcPointer;
907 /* the memory in a stub is never initialised, so we have to work out here
908 * whether we have to initialise it so we can use the optimisation of
909 * setting the pointer to the buffer, if possible, or set fMustAlloc to
911 if (attr & RPC_FC_P_DEREF) {
919 if (attr & RPC_FC_P_ALLOCALLNODES)
920 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
922 if (attr & RPC_FC_P_DEREF) {
924 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
925 *pPointer = base_ptr_val;
926 current_ptr = (unsigned char **)base_ptr_val;
928 current_ptr = *(unsigned char***)current_ptr;
929 TRACE("deref => %p\n", current_ptr);
930 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
932 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
933 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
934 else FIXME("no unmarshaller for data type=%02x\n", *desc);
936 if (type == RPC_FC_FP)
937 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
941 TRACE("pointer=%p\n", *pPointer);
944 /***********************************************************************
945 * PointerBufferSize [internal]
947 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
948 unsigned char *Pointer,
949 PFORMAT_STRING pFormat)
951 unsigned type = pFormat[0], attr = pFormat[1];
954 int pointer_needs_sizing;
957 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
958 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
960 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
961 else desc = pFormat + *(const SHORT*)pFormat;
964 case RPC_FC_RP: /* ref pointer (always non-null) */
967 ERR("NULL ref pointer is not allowed\n");
968 RpcRaiseException(RPC_X_NULL_REF_POINTER);
973 /* NULL pointer has no further representation */
978 pointer_needs_sizing = !NdrFullPointerQueryPointer(
979 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
980 if (!pointer_needs_sizing)
984 FIXME("unhandled ptr type=%02x\n", type);
985 RpcRaiseException(RPC_X_BAD_STUB_DATA);
989 if (attr & RPC_FC_P_DEREF) {
990 Pointer = *(unsigned char**)Pointer;
991 TRACE("deref => %p\n", Pointer);
994 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
995 if (m) m(pStubMsg, Pointer, desc);
996 else FIXME("no buffersizer for data type=%02x\n", *desc);
999 /***********************************************************************
1000 * PointerMemorySize [internal]
1002 static ULONG PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1003 unsigned char *Buffer, PFORMAT_STRING pFormat)
1005 unsigned type = pFormat[0], attr = pFormat[1];
1006 PFORMAT_STRING desc;
1008 DWORD pointer_id = 0;
1009 int pointer_needs_sizing;
1011 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1012 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1014 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1015 else desc = pFormat + *(const SHORT*)pFormat;
1018 case RPC_FC_RP: /* ref pointer (always non-null) */
1019 pointer_needs_sizing = 1;
1021 case RPC_FC_UP: /* unique pointer */
1022 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1023 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1024 TRACE("pointer_id is 0x%08x\n", pointer_id);
1026 pointer_needs_sizing = 1;
1028 pointer_needs_sizing = 0;
1033 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1034 TRACE("pointer_id is 0x%08x\n", pointer_id);
1035 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1036 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1040 FIXME("unhandled ptr type=%02x\n", type);
1041 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1045 if (attr & RPC_FC_P_DEREF) {
1046 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(void*));
1047 pStubMsg->MemorySize += sizeof(void*);
1051 if (pointer_needs_sizing) {
1052 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1053 if (m) m(pStubMsg, desc);
1054 else FIXME("no memorysizer for data type=%02x\n", *desc);
1057 return pStubMsg->MemorySize;
1060 /***********************************************************************
1061 * PointerFree [internal]
1063 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1064 unsigned char *Pointer,
1065 PFORMAT_STRING pFormat)
1067 unsigned type = pFormat[0], attr = pFormat[1];
1068 PFORMAT_STRING desc;
1070 unsigned char *current_pointer = Pointer;
1072 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1073 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1074 if (attr & RPC_FC_P_DONTFREE) return;
1076 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1077 else desc = pFormat + *(const SHORT*)pFormat;
1079 if (!Pointer) return;
1081 if (type == RPC_FC_FP) {
1082 int pointer_needs_freeing = NdrFullPointerFree(
1083 pStubMsg->FullPtrXlatTables, Pointer);
1084 if (!pointer_needs_freeing)
1088 if (attr & RPC_FC_P_DEREF) {
1089 current_pointer = *(unsigned char**)Pointer;
1090 TRACE("deref => %p\n", current_pointer);
1093 m = NdrFreer[*desc & NDR_TABLE_MASK];
1094 if (m) m(pStubMsg, current_pointer, desc);
1096 /* this check stops us from trying to free buffer memory. we don't have to
1097 * worry about clients, since they won't call this function.
1098 * we don't have to check for the buffer being reallocated because
1099 * BufferStart and BufferEnd won't be reset when allocating memory for
1100 * sending the response. we don't have to check for the new buffer here as
1101 * it won't be used a type memory, only for buffer memory */
1102 if (Pointer >= pStubMsg->BufferStart && Pointer < pStubMsg->BufferEnd)
1105 if (attr & RPC_FC_P_ONSTACK) {
1106 TRACE("not freeing stack ptr %p\n", Pointer);
1109 TRACE("freeing %p\n", Pointer);
1110 NdrFree(pStubMsg, Pointer);
1113 TRACE("not freeing %p\n", Pointer);
1116 /***********************************************************************
1117 * EmbeddedPointerMarshall
1119 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1120 unsigned char *pMemory,
1121 PFORMAT_STRING pFormat)
1123 unsigned char *Mark = pStubMsg->BufferMark;
1124 unsigned rep, count, stride;
1126 unsigned char *saved_buffer = NULL;
1128 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1130 if (*pFormat != RPC_FC_PP) return NULL;
1133 if (pStubMsg->PointerBufferMark)
1135 saved_buffer = pStubMsg->Buffer;
1136 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1137 pStubMsg->PointerBufferMark = NULL;
1140 while (pFormat[0] != RPC_FC_END) {
1141 switch (pFormat[0]) {
1143 FIXME("unknown repeat type %d\n", pFormat[0]);
1144 case RPC_FC_NO_REPEAT:
1150 case RPC_FC_FIXED_REPEAT:
1151 rep = *(const WORD*)&pFormat[2];
1152 stride = *(const WORD*)&pFormat[4];
1153 count = *(const WORD*)&pFormat[8];
1156 case RPC_FC_VARIABLE_REPEAT:
1157 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1158 stride = *(const WORD*)&pFormat[2];
1159 count = *(const WORD*)&pFormat[6];
1163 for (i = 0; i < rep; i++) {
1164 PFORMAT_STRING info = pFormat;
1165 unsigned char *membase = pMemory + (i * stride);
1166 unsigned char *bufbase = Mark + (i * stride);
1169 for (u=0; u<count; u++,info+=8) {
1170 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1171 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1172 unsigned char *saved_memory = pStubMsg->Memory;
1174 pStubMsg->Memory = pMemory;
1175 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1176 pStubMsg->Memory = saved_memory;
1179 pFormat += 8 * count;
1184 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1185 pStubMsg->Buffer = saved_buffer;
1188 STD_OVERFLOW_CHECK(pStubMsg);
1193 /***********************************************************************
1194 * EmbeddedPointerUnmarshall
1196 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1197 unsigned char *pDstBuffer,
1198 unsigned char *pSrcMemoryPtrs,
1199 PFORMAT_STRING pFormat,
1200 unsigned char fMustAlloc)
1202 unsigned char *Mark = pStubMsg->BufferMark;
1203 unsigned rep, count, stride;
1205 unsigned char *saved_buffer = NULL;
1207 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc);
1209 if (*pFormat != RPC_FC_PP) return NULL;
1212 if (pStubMsg->PointerBufferMark)
1214 saved_buffer = pStubMsg->Buffer;
1215 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1216 pStubMsg->PointerBufferMark = NULL;
1219 while (pFormat[0] != RPC_FC_END) {
1220 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1221 switch (pFormat[0]) {
1223 FIXME("unknown repeat type %d\n", pFormat[0]);
1224 case RPC_FC_NO_REPEAT:
1230 case RPC_FC_FIXED_REPEAT:
1231 rep = *(const WORD*)&pFormat[2];
1232 stride = *(const WORD*)&pFormat[4];
1233 count = *(const WORD*)&pFormat[8];
1236 case RPC_FC_VARIABLE_REPEAT:
1237 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1238 stride = *(const WORD*)&pFormat[2];
1239 count = *(const WORD*)&pFormat[6];
1243 for (i = 0; i < rep; i++) {
1244 PFORMAT_STRING info = pFormat;
1245 unsigned char *bufdstbase = pDstBuffer + (i * stride);
1246 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1247 unsigned char *bufbase = Mark + (i * stride);
1250 for (u=0; u<count; u++,info+=8) {
1251 unsigned char **bufdstptr = (unsigned char **)(bufdstbase + *(const SHORT*)&info[2]);
1252 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1253 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1254 PointerUnmarshall(pStubMsg, bufptr, bufdstptr, *memsrcptr, info+4, fMustAlloc);
1257 pFormat += 8 * count;
1262 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1263 pStubMsg->Buffer = saved_buffer;
1269 /***********************************************************************
1270 * EmbeddedPointerBufferSize
1272 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1273 unsigned char *pMemory,
1274 PFORMAT_STRING pFormat)
1276 unsigned rep, count, stride;
1278 ULONG saved_buffer_length = 0;
1280 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1282 if (pStubMsg->IgnoreEmbeddedPointers) return;
1284 if (*pFormat != RPC_FC_PP) return;
1287 if (pStubMsg->PointerLength)
1289 saved_buffer_length = pStubMsg->BufferLength;
1290 pStubMsg->BufferLength = pStubMsg->PointerLength;
1291 pStubMsg->PointerLength = 0;
1294 while (pFormat[0] != RPC_FC_END) {
1295 switch (pFormat[0]) {
1297 FIXME("unknown repeat type %d\n", pFormat[0]);
1298 case RPC_FC_NO_REPEAT:
1304 case RPC_FC_FIXED_REPEAT:
1305 rep = *(const WORD*)&pFormat[2];
1306 stride = *(const WORD*)&pFormat[4];
1307 count = *(const WORD*)&pFormat[8];
1310 case RPC_FC_VARIABLE_REPEAT:
1311 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1312 stride = *(const WORD*)&pFormat[2];
1313 count = *(const WORD*)&pFormat[6];
1317 for (i = 0; i < rep; i++) {
1318 PFORMAT_STRING info = pFormat;
1319 unsigned char *membase = pMemory + (i * stride);
1322 for (u=0; u<count; u++,info+=8) {
1323 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1324 unsigned char *saved_memory = pStubMsg->Memory;
1326 pStubMsg->Memory = pMemory;
1327 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1328 pStubMsg->Memory = saved_memory;
1331 pFormat += 8 * count;
1334 if (saved_buffer_length)
1336 pStubMsg->PointerLength = pStubMsg->BufferLength;
1337 pStubMsg->BufferLength = saved_buffer_length;
1341 /***********************************************************************
1342 * EmbeddedPointerMemorySize [internal]
1344 static ULONG EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1345 PFORMAT_STRING pFormat)
1347 unsigned char *Mark = pStubMsg->BufferMark;
1348 unsigned rep, count, stride;
1350 unsigned char *saved_buffer = NULL;
1352 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1354 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1356 if (pStubMsg->PointerBufferMark)
1358 saved_buffer = pStubMsg->Buffer;
1359 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1360 pStubMsg->PointerBufferMark = NULL;
1363 if (*pFormat != RPC_FC_PP) return 0;
1366 while (pFormat[0] != RPC_FC_END) {
1367 switch (pFormat[0]) {
1369 FIXME("unknown repeat type %d\n", pFormat[0]);
1370 case RPC_FC_NO_REPEAT:
1376 case RPC_FC_FIXED_REPEAT:
1377 rep = *(const WORD*)&pFormat[2];
1378 stride = *(const WORD*)&pFormat[4];
1379 count = *(const WORD*)&pFormat[8];
1382 case RPC_FC_VARIABLE_REPEAT:
1383 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1384 stride = *(const WORD*)&pFormat[2];
1385 count = *(const WORD*)&pFormat[6];
1389 for (i = 0; i < rep; i++) {
1390 PFORMAT_STRING info = pFormat;
1391 unsigned char *bufbase = Mark + (i * stride);
1393 for (u=0; u<count; u++,info+=8) {
1394 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1395 PointerMemorySize(pStubMsg, bufptr, info+4);
1398 pFormat += 8 * count;
1403 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1404 pStubMsg->Buffer = saved_buffer;
1410 /***********************************************************************
1411 * EmbeddedPointerFree [internal]
1413 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1414 unsigned char *pMemory,
1415 PFORMAT_STRING pFormat)
1417 unsigned rep, count, stride;
1420 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1421 if (*pFormat != RPC_FC_PP) return;
1424 while (pFormat[0] != RPC_FC_END) {
1425 switch (pFormat[0]) {
1427 FIXME("unknown repeat type %d\n", pFormat[0]);
1428 case RPC_FC_NO_REPEAT:
1434 case RPC_FC_FIXED_REPEAT:
1435 rep = *(const WORD*)&pFormat[2];
1436 stride = *(const WORD*)&pFormat[4];
1437 count = *(const WORD*)&pFormat[8];
1440 case RPC_FC_VARIABLE_REPEAT:
1441 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1442 stride = *(const WORD*)&pFormat[2];
1443 count = *(const WORD*)&pFormat[6];
1447 for (i = 0; i < rep; i++) {
1448 PFORMAT_STRING info = pFormat;
1449 unsigned char *membase = pMemory + (i * stride);
1452 for (u=0; u<count; u++,info+=8) {
1453 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1454 unsigned char *saved_memory = pStubMsg->Memory;
1456 pStubMsg->Memory = pMemory;
1457 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1458 pStubMsg->Memory = saved_memory;
1461 pFormat += 8 * count;
1465 /***********************************************************************
1466 * NdrPointerMarshall [RPCRT4.@]
1468 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1469 unsigned char *pMemory,
1470 PFORMAT_STRING pFormat)
1472 unsigned char *Buffer;
1474 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1476 /* Increment the buffer here instead of in PointerMarshall,
1477 * as that is used by embedded pointers which already handle the incrementing
1478 * the buffer, and shouldn't write any additional pointer data to the wire */
1479 if (*pFormat != RPC_FC_RP)
1481 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
1482 Buffer = pStubMsg->Buffer;
1483 safe_buffer_increment(pStubMsg, 4);
1486 Buffer = pStubMsg->Buffer;
1488 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1493 /***********************************************************************
1494 * NdrPointerUnmarshall [RPCRT4.@]
1496 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1497 unsigned char **ppMemory,
1498 PFORMAT_STRING pFormat,
1499 unsigned char fMustAlloc)
1501 unsigned char *Buffer;
1503 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1505 if (*pFormat == RPC_FC_RP)
1507 Buffer = pStubMsg->Buffer;
1508 /* Do the NULL ref pointer check here because embedded pointers can be
1509 * NULL if the type the pointer is embedded in was allocated rather than
1510 * being passed in by the client */
1511 if (pStubMsg->IsClient && !*ppMemory)
1513 ERR("NULL ref pointer is not allowed\n");
1514 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1519 /* Increment the buffer here instead of in PointerUnmarshall,
1520 * as that is used by embedded pointers which already handle the incrementing
1521 * the buffer, and shouldn't read any additional pointer data from the
1523 ALIGN_POINTER(pStubMsg->Buffer, 4);
1524 Buffer = pStubMsg->Buffer;
1525 safe_buffer_increment(pStubMsg, 4);
1528 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1533 /***********************************************************************
1534 * NdrPointerBufferSize [RPCRT4.@]
1536 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1537 unsigned char *pMemory,
1538 PFORMAT_STRING pFormat)
1540 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1542 /* Increment the buffer length here instead of in PointerBufferSize,
1543 * as that is used by embedded pointers which already handle the buffer
1544 * length, and shouldn't write anything more to the wire */
1545 if (*pFormat != RPC_FC_RP)
1547 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1548 safe_buffer_length_increment(pStubMsg, 4);
1551 PointerBufferSize(pStubMsg, pMemory, pFormat);
1554 /***********************************************************************
1555 * NdrPointerMemorySize [RPCRT4.@]
1557 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1558 PFORMAT_STRING pFormat)
1560 unsigned char *Buffer = pStubMsg->Buffer;
1561 if (*pFormat != RPC_FC_RP)
1563 ALIGN_POINTER(pStubMsg->Buffer, 4);
1564 safe_buffer_increment(pStubMsg, 4);
1566 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(void *));
1567 return PointerMemorySize(pStubMsg, Buffer, pFormat);
1570 /***********************************************************************
1571 * NdrPointerFree [RPCRT4.@]
1573 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1574 unsigned char *pMemory,
1575 PFORMAT_STRING pFormat)
1577 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1578 PointerFree(pStubMsg, pMemory, pFormat);
1581 /***********************************************************************
1582 * NdrSimpleTypeMarshall [RPCRT4.@]
1584 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1585 unsigned char FormatChar )
1587 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1590 /***********************************************************************
1591 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1593 * Unmarshall a base type.
1596 * Doesn't check that the buffer is long enough before copying, so the caller
1599 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1600 unsigned char FormatChar )
1602 #define BASE_TYPE_UNMARSHALL(type) \
1603 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
1604 TRACE("pMemory: %p\n", pMemory); \
1605 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1606 pStubMsg->Buffer += sizeof(type);
1614 BASE_TYPE_UNMARSHALL(UCHAR);
1615 TRACE("value: 0x%02x\n", *pMemory);
1620 BASE_TYPE_UNMARSHALL(USHORT);
1621 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
1625 case RPC_FC_ERROR_STATUS_T:
1627 BASE_TYPE_UNMARSHALL(ULONG);
1628 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
1631 BASE_TYPE_UNMARSHALL(float);
1632 TRACE("value: %f\n", *(float *)pMemory);
1635 BASE_TYPE_UNMARSHALL(double);
1636 TRACE("value: %f\n", *(double *)pMemory);
1639 BASE_TYPE_UNMARSHALL(ULONGLONG);
1640 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
1643 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
1644 TRACE("pMemory: %p\n", pMemory);
1645 /* 16-bits on the wire, but int in memory */
1646 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
1647 pStubMsg->Buffer += sizeof(USHORT);
1648 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
1653 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
1655 #undef BASE_TYPE_UNMARSHALL
1658 /***********************************************************************
1659 * NdrSimpleStructMarshall [RPCRT4.@]
1661 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1662 unsigned char *pMemory,
1663 PFORMAT_STRING pFormat)
1665 unsigned size = *(const WORD*)(pFormat+2);
1666 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1668 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
1670 pStubMsg->BufferMark = pStubMsg->Buffer;
1671 safe_copy_to_buffer(pStubMsg, pMemory, size);
1673 if (pFormat[0] != RPC_FC_STRUCT)
1674 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1679 /***********************************************************************
1680 * NdrSimpleStructUnmarshall [RPCRT4.@]
1682 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1683 unsigned char **ppMemory,
1684 PFORMAT_STRING pFormat,
1685 unsigned char fMustAlloc)
1687 unsigned size = *(const WORD*)(pFormat+2);
1688 unsigned char *saved_buffer;
1689 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1691 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1694 *ppMemory = NdrAllocate(pStubMsg, size);
1697 if (!pStubMsg->IsClient && !*ppMemory)
1698 /* for servers, we just point straight into the RPC buffer */
1699 *ppMemory = pStubMsg->Buffer;
1702 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1703 safe_buffer_increment(pStubMsg, size);
1704 if (pFormat[0] == RPC_FC_PSTRUCT)
1705 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1707 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1708 if (*ppMemory != saved_buffer)
1709 memcpy(*ppMemory, saved_buffer, size);
1714 /***********************************************************************
1715 * NdrSimpleStructBufferSize [RPCRT4.@]
1717 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1718 unsigned char *pMemory,
1719 PFORMAT_STRING pFormat)
1721 unsigned size = *(const WORD*)(pFormat+2);
1722 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1724 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1726 safe_buffer_length_increment(pStubMsg, size);
1727 if (pFormat[0] != RPC_FC_STRUCT)
1728 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1731 /***********************************************************************
1732 * NdrSimpleStructMemorySize [RPCRT4.@]
1734 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1735 PFORMAT_STRING pFormat)
1737 unsigned short size = *(const WORD *)(pFormat+2);
1739 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1741 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1742 pStubMsg->MemorySize += size;
1743 safe_buffer_increment(pStubMsg, size);
1745 if (pFormat[0] != RPC_FC_STRUCT)
1746 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1747 return pStubMsg->MemorySize;
1750 /***********************************************************************
1751 * NdrSimpleStructFree [RPCRT4.@]
1753 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1754 unsigned char *pMemory,
1755 PFORMAT_STRING pFormat)
1757 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1758 if (pFormat[0] != RPC_FC_STRUCT)
1759 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1764 static inline void array_compute_and_size_conformance(
1765 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1766 PFORMAT_STRING pFormat)
1771 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1772 SizeConformance(pStubMsg);
1774 case RPC_FC_CVARRAY:
1775 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1776 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1777 SizeConformance(pStubMsg);
1779 case RPC_FC_C_CSTRING:
1780 case RPC_FC_C_WSTRING:
1781 if (fc == RPC_FC_C_CSTRING)
1783 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1784 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1788 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1789 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1792 if (pFormat[1] == RPC_FC_STRING_SIZED)
1793 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1795 pStubMsg->MaxCount = pStubMsg->ActualCount;
1797 SizeConformance(pStubMsg);
1800 ERR("unknown array format 0x%x\n", fc);
1801 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1805 static inline void array_buffer_size(
1806 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1807 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1811 unsigned char alignment;
1816 esize = *(const WORD*)(pFormat+2);
1817 alignment = pFormat[1] + 1;
1819 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1821 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
1823 size = safe_multiply(esize, pStubMsg->MaxCount);
1824 /* conformance value plus array */
1825 safe_buffer_length_increment(pStubMsg, size);
1828 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1830 case RPC_FC_CVARRAY:
1831 esize = *(const WORD*)(pFormat+2);
1832 alignment = pFormat[1] + 1;
1834 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1835 pFormat = SkipConformance(pStubMsg, pFormat);
1837 SizeVariance(pStubMsg);
1839 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
1841 size = safe_multiply(esize, pStubMsg->ActualCount);
1842 safe_buffer_length_increment(pStubMsg, size);
1845 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1847 case RPC_FC_C_CSTRING:
1848 case RPC_FC_C_WSTRING:
1849 if (fc == RPC_FC_C_CSTRING)
1854 SizeVariance(pStubMsg);
1856 size = safe_multiply(esize, pStubMsg->ActualCount);
1857 safe_buffer_length_increment(pStubMsg, size);
1860 ERR("unknown array format 0x%x\n", fc);
1861 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1865 static inline void array_compute_and_write_conformance(
1866 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1867 PFORMAT_STRING pFormat)
1872 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1873 WriteConformance(pStubMsg);
1875 case RPC_FC_CVARRAY:
1876 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1877 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1878 WriteConformance(pStubMsg);
1880 case RPC_FC_C_CSTRING:
1881 case RPC_FC_C_WSTRING:
1882 if (fc == RPC_FC_C_CSTRING)
1884 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1885 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1889 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1890 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1892 if (pFormat[1] == RPC_FC_STRING_SIZED)
1893 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1895 pStubMsg->MaxCount = pStubMsg->ActualCount;
1896 pStubMsg->Offset = 0;
1897 WriteConformance(pStubMsg);
1900 ERR("unknown array format 0x%x\n", fc);
1901 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1905 static inline void array_write_variance_and_marshall(
1906 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1907 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1911 unsigned char alignment;
1916 esize = *(const WORD*)(pFormat+2);
1917 alignment = pFormat[1] + 1;
1919 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1921 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
1923 size = safe_multiply(esize, pStubMsg->MaxCount);
1925 pStubMsg->BufferMark = pStubMsg->Buffer;
1926 safe_copy_to_buffer(pStubMsg, pMemory, size);
1929 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1931 case RPC_FC_CVARRAY:
1932 esize = *(const WORD*)(pFormat+2);
1933 alignment = pFormat[1] + 1;
1936 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1938 pFormat = SkipConformance(pStubMsg, pFormat);
1940 WriteVariance(pStubMsg);
1942 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
1944 size = safe_multiply(esize, pStubMsg->ActualCount);
1947 pStubMsg->BufferMark = pStubMsg->Buffer;
1948 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size);
1951 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1953 case RPC_FC_C_CSTRING:
1954 case RPC_FC_C_WSTRING:
1955 if (fc == RPC_FC_C_CSTRING)
1960 WriteVariance(pStubMsg);
1962 size = safe_multiply(esize, pStubMsg->ActualCount);
1963 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
1966 ERR("unknown array format 0x%x\n", fc);
1967 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1971 static inline ULONG array_read_conformance(
1972 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
1979 esize = *(const WORD*)(pFormat+2);
1980 pFormat = ReadConformance(pStubMsg, pFormat+4);
1981 return safe_multiply(esize, pStubMsg->MaxCount);
1982 case RPC_FC_CVARRAY:
1983 esize = *(const WORD*)(pFormat+2);
1984 pFormat = ReadConformance(pStubMsg, pFormat+4);
1985 return safe_multiply(esize, pStubMsg->MaxCount);
1986 case RPC_FC_C_CSTRING:
1987 case RPC_FC_C_WSTRING:
1988 if (fc == RPC_FC_C_CSTRING)
1993 if (pFormat[1] == RPC_FC_STRING_SIZED)
1994 ReadConformance(pStubMsg, pFormat + 2);
1996 ReadConformance(pStubMsg, NULL);
1997 return safe_multiply(esize, pStubMsg->MaxCount);
1999 ERR("unknown array format 0x%x\n", fc);
2000 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2004 static inline ULONG array_read_variance_and_unmarshall(
2005 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory,
2006 PFORMAT_STRING pFormat, unsigned char fMustAlloc,
2007 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall)
2009 ULONG bufsize, memsize;
2011 unsigned char alignment;
2012 unsigned char *saved_buffer;
2018 esize = *(const WORD*)(pFormat+2);
2019 alignment = pFormat[1] + 1;
2021 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2023 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2025 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2030 *ppMemory = NdrAllocate(pStubMsg, memsize);
2033 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory)
2034 /* for servers, we just point straight into the RPC buffer */
2035 *ppMemory = pStubMsg->Buffer;
2038 saved_buffer = pStubMsg->Buffer;
2039 safe_buffer_increment(pStubMsg, bufsize);
2041 pStubMsg->BufferMark = saved_buffer;
2042 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2044 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2045 if (*ppMemory != saved_buffer)
2046 memcpy(*ppMemory, saved_buffer, bufsize);
2049 case RPC_FC_CVARRAY:
2050 esize = *(const WORD*)(pFormat+2);
2051 alignment = pFormat[1] + 1;
2053 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2055 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2057 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2059 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2060 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2064 offset = pStubMsg->Offset;
2066 if (!fMustAlloc && !*ppMemory)
2069 *ppMemory = NdrAllocate(pStubMsg, memsize);
2070 saved_buffer = pStubMsg->Buffer;
2071 safe_buffer_increment(pStubMsg, bufsize);
2073 pStubMsg->BufferMark = saved_buffer;
2074 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat,
2077 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2080 case RPC_FC_C_CSTRING:
2081 case RPC_FC_C_WSTRING:
2082 if (fc == RPC_FC_C_CSTRING)
2087 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2089 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2091 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2092 pStubMsg->ActualCount, pStubMsg->MaxCount);
2093 RpcRaiseException(RPC_S_INVALID_BOUND);
2095 if (pStubMsg->Offset)
2097 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2098 RpcRaiseException(RPC_S_INVALID_BOUND);
2101 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2102 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2104 validate_string_data(pStubMsg, bufsize, esize);
2109 *ppMemory = NdrAllocate(pStubMsg, memsize);
2112 if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
2113 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
2114 /* if the data in the RPC buffer is big enough, we just point
2115 * straight into it */
2116 *ppMemory = pStubMsg->Buffer;
2117 else if (!*ppMemory)
2118 *ppMemory = NdrAllocate(pStubMsg, memsize);
2121 if (*ppMemory == pStubMsg->Buffer)
2122 safe_buffer_increment(pStubMsg, bufsize);
2124 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2126 if (*pFormat == RPC_FC_C_CSTRING)
2127 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
2129 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
2133 ERR("unknown array format 0x%x\n", fc);
2134 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2138 static inline void array_memory_size(
2139 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
2140 unsigned char fHasPointers)
2142 ULONG bufsize, memsize;
2144 unsigned char alignment;
2149 esize = *(const WORD*)(pFormat+2);
2150 alignment = pFormat[1] + 1;
2152 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2154 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2155 pStubMsg->MemorySize += memsize;
2157 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2159 pStubMsg->BufferMark = pStubMsg->Buffer;
2160 safe_buffer_increment(pStubMsg, bufsize);
2163 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2165 case RPC_FC_CVARRAY:
2166 esize = *(const WORD*)(pFormat+2);
2167 alignment = pFormat[1] + 1;
2169 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2171 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2173 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2174 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2175 pStubMsg->MemorySize += memsize;
2177 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2179 pStubMsg->BufferMark = pStubMsg->Buffer;
2180 safe_buffer_increment(pStubMsg, bufsize);
2183 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2185 case RPC_FC_C_CSTRING:
2186 case RPC_FC_C_WSTRING:
2187 if (fc == RPC_FC_C_CSTRING)
2192 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2194 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2196 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2197 pStubMsg->ActualCount, pStubMsg->MaxCount);
2198 RpcRaiseException(RPC_S_INVALID_BOUND);
2200 if (pStubMsg->Offset)
2202 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2203 RpcRaiseException(RPC_S_INVALID_BOUND);
2206 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2207 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2209 validate_string_data(pStubMsg, bufsize, esize);
2211 safe_buffer_increment(pStubMsg, bufsize);
2212 pStubMsg->MemorySize += memsize;
2215 ERR("unknown array format 0x%x\n", fc);
2216 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2220 static inline void array_free(
2221 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
2222 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
2227 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2229 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2231 case RPC_FC_CVARRAY:
2232 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2233 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2235 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2237 case RPC_FC_C_CSTRING:
2238 case RPC_FC_C_WSTRING:
2239 /* No embedded pointers so nothing to do */
2242 ERR("unknown array format 0x%x\n", fc);
2243 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2248 * NdrConformantString:
2250 * What MS calls a ConformantString is, in DCE terminology,
2251 * a Varying-Conformant String.
2253 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2254 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2255 * into unmarshalled string)
2256 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2258 * data: CHARTYPE[maxlen]
2260 * ], where CHARTYPE is the appropriate character type (specified externally)
2264 /***********************************************************************
2265 * NdrConformantStringMarshall [RPCRT4.@]
2267 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
2268 unsigned char *pszMessage, PFORMAT_STRING pFormat)
2270 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
2272 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2273 ERR("Unhandled string type: %#x\n", pFormat[0]);
2274 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2277 /* allow compiler to optimise inline function by passing constant into
2278 * these functions */
2279 if (pFormat[0] == RPC_FC_C_CSTRING) {
2280 array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2282 array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2283 pFormat, TRUE /* fHasPointers */);
2285 array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2287 array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2288 pFormat, TRUE /* fHasPointers */);
2294 /***********************************************************************
2295 * NdrConformantStringBufferSize [RPCRT4.@]
2297 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2298 unsigned char* pMemory, PFORMAT_STRING pFormat)
2300 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2302 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2303 ERR("Unhandled string type: %#x\n", pFormat[0]);
2304 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2307 /* allow compiler to optimise inline function by passing constant into
2308 * these functions */
2309 if (pFormat[0] == RPC_FC_C_CSTRING) {
2310 array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory,
2312 array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat,
2313 TRUE /* fHasPointers */);
2315 array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory,
2317 array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat,
2318 TRUE /* fHasPointers */);
2322 /************************************************************************
2323 * NdrConformantStringMemorySize [RPCRT4.@]
2325 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2326 PFORMAT_STRING pFormat )
2328 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2330 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2331 ERR("Unhandled string type: %#x\n", pFormat[0]);
2332 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2335 /* allow compiler to optimise inline function by passing constant into
2336 * these functions */
2337 if (pFormat[0] == RPC_FC_C_CSTRING) {
2338 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2339 array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat,
2340 TRUE /* fHasPointers */);
2342 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2343 array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat,
2344 TRUE /* fHasPointers */);
2347 return pStubMsg->MemorySize;
2350 /************************************************************************
2351 * NdrConformantStringUnmarshall [RPCRT4.@]
2353 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2354 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
2356 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2357 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2359 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2360 ERR("Unhandled string type: %#x\n", *pFormat);
2361 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2364 /* allow compiler to optimise inline function by passing constant into
2365 * these functions */
2366 if (pFormat[0] == RPC_FC_C_CSTRING) {
2367 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2368 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory,
2369 pFormat, fMustAlloc,
2370 TRUE /* fUseBufferMemoryServer */,
2371 TRUE /* fUnmarshall */);
2373 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2374 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory,
2375 pFormat, fMustAlloc,
2376 TRUE /* fUseBufferMemoryServer */,
2377 TRUE /* fUnmarshall */);
2383 /***********************************************************************
2384 * NdrNonConformantStringMarshall [RPCRT4.@]
2386 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2387 unsigned char *pMemory,
2388 PFORMAT_STRING pFormat)
2390 ULONG esize, size, maxsize;
2392 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2394 maxsize = *(USHORT *)&pFormat[2];
2396 if (*pFormat == RPC_FC_CSTRING)
2399 const char *str = (const char *)pMemory;
2400 for (i = 0; i < maxsize && *str; i++, str++)
2402 TRACE("string=%s\n", debugstr_an(str, i));
2403 pStubMsg->ActualCount = i + 1;
2406 else if (*pFormat == RPC_FC_WSTRING)
2409 const WCHAR *str = (const WCHAR *)pMemory;
2410 for (i = 0; i < maxsize && *str; i++, str++)
2412 TRACE("string=%s\n", debugstr_wn(str, i));
2413 pStubMsg->ActualCount = i + 1;
2418 ERR("Unhandled string type: %#x\n", *pFormat);
2419 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2422 pStubMsg->Offset = 0;
2423 WriteVariance(pStubMsg);
2425 size = safe_multiply(esize, pStubMsg->ActualCount);
2426 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2431 /***********************************************************************
2432 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2434 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2435 unsigned char **ppMemory,
2436 PFORMAT_STRING pFormat,
2437 unsigned char fMustAlloc)
2439 ULONG bufsize, memsize, esize, maxsize;
2441 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2442 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2444 maxsize = *(USHORT *)&pFormat[2];
2446 ReadVariance(pStubMsg, NULL, maxsize);
2447 if (pStubMsg->Offset)
2449 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2450 RpcRaiseException(RPC_S_INVALID_BOUND);
2453 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2454 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2457 ERR("Unhandled string type: %#x\n", *pFormat);
2458 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2461 memsize = esize * maxsize;
2462 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2464 validate_string_data(pStubMsg, bufsize, esize);
2466 if (!fMustAlloc && !*ppMemory)
2469 *ppMemory = NdrAllocate(pStubMsg, memsize);
2471 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2473 if (*pFormat == RPC_FC_CSTRING) {
2474 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
2476 else if (*pFormat == RPC_FC_WSTRING) {
2477 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
2483 /***********************************************************************
2484 * NdrNonConformantStringBufferSize [RPCRT4.@]
2486 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2487 unsigned char *pMemory,
2488 PFORMAT_STRING pFormat)
2490 ULONG esize, maxsize;
2492 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2494 maxsize = *(USHORT *)&pFormat[2];
2496 SizeVariance(pStubMsg);
2498 if (*pFormat == RPC_FC_CSTRING)
2501 const char *str = (const char *)pMemory;
2502 for (i = 0; i < maxsize && *str; i++, str++)
2504 TRACE("string=%s\n", debugstr_an(str, i));
2505 pStubMsg->ActualCount = i + 1;
2508 else if (*pFormat == RPC_FC_WSTRING)
2511 const WCHAR *str = (const WCHAR *)pMemory;
2512 for (i = 0; i < maxsize && *str; i++, str++)
2514 TRACE("string=%s\n", debugstr_wn(str, i));
2515 pStubMsg->ActualCount = i + 1;
2520 ERR("Unhandled string type: %#x\n", *pFormat);
2521 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2524 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2527 /***********************************************************************
2528 * NdrNonConformantStringMemorySize [RPCRT4.@]
2530 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2531 PFORMAT_STRING pFormat)
2533 ULONG bufsize, memsize, esize, maxsize;
2535 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2537 maxsize = *(USHORT *)&pFormat[2];
2539 ReadVariance(pStubMsg, NULL, maxsize);
2541 if (pStubMsg->Offset)
2543 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2544 RpcRaiseException(RPC_S_INVALID_BOUND);
2547 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2548 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2551 ERR("Unhandled string type: %#x\n", *pFormat);
2552 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2555 memsize = esize * maxsize;
2556 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2558 validate_string_data(pStubMsg, bufsize, esize);
2560 safe_buffer_increment(pStubMsg, bufsize);
2561 pStubMsg->MemorySize += memsize;
2563 return pStubMsg->MemorySize;
2568 #include "pshpack1.h"
2572 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2576 #include "poppack.h"
2578 static ULONG EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2579 PFORMAT_STRING pFormat)
2583 case RPC_FC_PSTRUCT:
2584 case RPC_FC_CSTRUCT:
2585 case RPC_FC_BOGUS_STRUCT:
2586 case RPC_FC_SMFARRAY:
2587 case RPC_FC_SMVARRAY:
2588 case RPC_FC_CSTRING:
2589 return *(const WORD*)&pFormat[2];
2590 case RPC_FC_USER_MARSHAL:
2591 return *(const WORD*)&pFormat[4];
2592 case RPC_FC_RANGE: {
2593 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2598 return sizeof(UCHAR);
2602 return sizeof(USHORT);
2606 return sizeof(ULONG);
2608 return sizeof(float);
2610 return sizeof(double);
2612 return sizeof(ULONGLONG);
2614 return sizeof(UINT);
2616 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2617 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2620 case RPC_FC_NON_ENCAPSULATED_UNION:
2622 if (pStubMsg->fHasNewCorrDesc)
2627 pFormat += *(const SHORT*)pFormat;
2628 return *(const SHORT*)pFormat;
2630 return sizeof(void *);
2631 case RPC_FC_WSTRING:
2632 return *(const WORD*)&pFormat[2] * 2;
2634 FIXME("unhandled embedded type %02x\n", *pFormat);
2640 static ULONG EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2641 PFORMAT_STRING pFormat)
2643 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2647 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2651 return m(pStubMsg, pFormat);
2655 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2656 unsigned char *pMemory,
2657 PFORMAT_STRING pFormat,
2658 PFORMAT_STRING pPointer)
2660 PFORMAT_STRING desc;
2664 while (*pFormat != RPC_FC_END) {
2670 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2671 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2677 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2678 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2682 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2683 if (32767 < *(DWORD*)pMemory)
2684 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2685 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2691 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2692 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2696 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2697 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2700 case RPC_FC_POINTER:
2702 unsigned char *saved_buffer;
2703 int pointer_buffer_mark_set = 0;
2704 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2705 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2706 if (*pPointer != RPC_FC_RP)
2707 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
2708 saved_buffer = pStubMsg->Buffer;
2709 if (pStubMsg->PointerBufferMark)
2711 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2712 pStubMsg->PointerBufferMark = NULL;
2713 pointer_buffer_mark_set = 1;
2715 else if (*pPointer != RPC_FC_RP)
2716 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2717 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2718 if (pointer_buffer_mark_set)
2720 STD_OVERFLOW_CHECK(pStubMsg);
2721 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2722 pStubMsg->Buffer = saved_buffer;
2723 if (*pPointer != RPC_FC_RP)
2724 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2726 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2728 pMemory += sizeof(void *);
2731 case RPC_FC_ALIGNM2:
2732 ALIGN_POINTER(pMemory, 2);
2734 case RPC_FC_ALIGNM4:
2735 ALIGN_POINTER(pMemory, 4);
2737 case RPC_FC_ALIGNM8:
2738 ALIGN_POINTER(pMemory, 8);
2740 case RPC_FC_STRUCTPAD1:
2741 case RPC_FC_STRUCTPAD2:
2742 case RPC_FC_STRUCTPAD3:
2743 case RPC_FC_STRUCTPAD4:
2744 case RPC_FC_STRUCTPAD5:
2745 case RPC_FC_STRUCTPAD6:
2746 case RPC_FC_STRUCTPAD7:
2747 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2749 case RPC_FC_EMBEDDED_COMPLEX:
2750 pMemory += pFormat[1];
2752 desc = pFormat + *(const SHORT*)pFormat;
2753 size = EmbeddedComplexSize(pStubMsg, desc);
2754 TRACE("embedded complex (size=%d) <= %p\n", size, pMemory);
2755 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2758 /* for some reason interface pointers aren't generated as
2759 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2760 * they still need the derefencing treatment that pointers are
2762 if (*desc == RPC_FC_IP)
2763 m(pStubMsg, *(unsigned char **)pMemory, desc);
2765 m(pStubMsg, pMemory, desc);
2767 else FIXME("no marshaller for embedded type %02x\n", *desc);
2774 FIXME("unhandled format 0x%02x\n", *pFormat);
2782 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2783 unsigned char *pMemory,
2784 PFORMAT_STRING pFormat,
2785 PFORMAT_STRING pPointer,
2786 unsigned char fMustAlloc)
2788 PFORMAT_STRING desc;
2792 while (*pFormat != RPC_FC_END) {
2798 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2799 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2805 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2806 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2810 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2811 *(DWORD*)pMemory &= 0xffff;
2812 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
2813 if (32767 < *(DWORD*)pMemory)
2814 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2820 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2821 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2825 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2826 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2829 case RPC_FC_POINTER:
2831 unsigned char *saved_buffer;
2832 int pointer_buffer_mark_set = 0;
2833 TRACE("pointer => %p\n", pMemory);
2834 if (*pPointer != RPC_FC_RP)
2835 ALIGN_POINTER(pStubMsg->Buffer, 4);
2836 saved_buffer = pStubMsg->Buffer;
2837 if (pStubMsg->PointerBufferMark)
2839 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2840 pStubMsg->PointerBufferMark = NULL;
2841 pointer_buffer_mark_set = 1;
2843 else if (*pPointer != RPC_FC_RP)
2844 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2846 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
2847 if (pointer_buffer_mark_set)
2849 STD_OVERFLOW_CHECK(pStubMsg);
2850 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2851 pStubMsg->Buffer = saved_buffer;
2852 if (*pPointer != RPC_FC_RP)
2853 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2856 pMemory += sizeof(void *);
2859 case RPC_FC_ALIGNM2:
2860 ALIGN_POINTER_CLEAR(pMemory, 2);
2862 case RPC_FC_ALIGNM4:
2863 ALIGN_POINTER_CLEAR(pMemory, 4);
2865 case RPC_FC_ALIGNM8:
2866 ALIGN_POINTER_CLEAR(pMemory, 8);
2868 case RPC_FC_STRUCTPAD1:
2869 case RPC_FC_STRUCTPAD2:
2870 case RPC_FC_STRUCTPAD3:
2871 case RPC_FC_STRUCTPAD4:
2872 case RPC_FC_STRUCTPAD5:
2873 case RPC_FC_STRUCTPAD6:
2874 case RPC_FC_STRUCTPAD7:
2875 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2876 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2878 case RPC_FC_EMBEDDED_COMPLEX:
2879 pMemory += pFormat[1];
2881 desc = pFormat + *(const SHORT*)pFormat;
2882 size = EmbeddedComplexSize(pStubMsg, desc);
2883 TRACE("embedded complex (size=%d) => %p\n", size, pMemory);
2885 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
2886 * since the type is part of the memory block that is encompassed by
2887 * the whole complex type. Memory is forced to allocate when pointers
2888 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
2889 * clearing the memory we pass in to the unmarshaller */
2890 memset(pMemory, 0, size);
2891 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2894 /* for some reason interface pointers aren't generated as
2895 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2896 * they still need the derefencing treatment that pointers are
2898 if (*desc == RPC_FC_IP)
2899 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2901 m(pStubMsg, &pMemory, desc, FALSE);
2903 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2910 FIXME("unhandled format %d\n", *pFormat);
2918 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2919 unsigned char *pMemory,
2920 PFORMAT_STRING pFormat,
2921 PFORMAT_STRING pPointer)
2923 PFORMAT_STRING desc;
2927 while (*pFormat != RPC_FC_END) {
2933 safe_buffer_length_increment(pStubMsg, 1);
2939 safe_buffer_length_increment(pStubMsg, 2);
2943 safe_buffer_length_increment(pStubMsg, 2);
2949 safe_buffer_length_increment(pStubMsg, 4);
2953 safe_buffer_length_increment(pStubMsg, 8);
2956 case RPC_FC_POINTER:
2957 if (!pStubMsg->IgnoreEmbeddedPointers)
2959 int saved_buffer_length = pStubMsg->BufferLength;
2960 pStubMsg->BufferLength = pStubMsg->PointerLength;
2961 pStubMsg->PointerLength = 0;
2962 if(!pStubMsg->BufferLength)
2963 ERR("BufferLength == 0??\n");
2964 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2965 pStubMsg->PointerLength = pStubMsg->BufferLength;
2966 pStubMsg->BufferLength = saved_buffer_length;
2968 if (*pPointer != RPC_FC_RP)
2970 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2971 safe_buffer_length_increment(pStubMsg, 4);
2974 pMemory += sizeof(void*);
2976 case RPC_FC_ALIGNM2:
2977 ALIGN_POINTER(pMemory, 2);
2979 case RPC_FC_ALIGNM4:
2980 ALIGN_POINTER(pMemory, 4);
2982 case RPC_FC_ALIGNM8:
2983 ALIGN_POINTER(pMemory, 8);
2985 case RPC_FC_STRUCTPAD1:
2986 case RPC_FC_STRUCTPAD2:
2987 case RPC_FC_STRUCTPAD3:
2988 case RPC_FC_STRUCTPAD4:
2989 case RPC_FC_STRUCTPAD5:
2990 case RPC_FC_STRUCTPAD6:
2991 case RPC_FC_STRUCTPAD7:
2992 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2994 case RPC_FC_EMBEDDED_COMPLEX:
2995 pMemory += pFormat[1];
2997 desc = pFormat + *(const SHORT*)pFormat;
2998 size = EmbeddedComplexSize(pStubMsg, desc);
2999 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
3002 /* for some reason interface pointers aren't generated as
3003 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3004 * they still need the derefencing treatment that pointers are
3006 if (*desc == RPC_FC_IP)
3007 m(pStubMsg, *(unsigned char **)pMemory, desc);
3009 m(pStubMsg, pMemory, desc);
3011 else FIXME("no buffersizer for embedded type %02x\n", *desc);
3018 FIXME("unhandled format 0x%02x\n", *pFormat);
3026 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
3027 unsigned char *pMemory,
3028 PFORMAT_STRING pFormat,
3029 PFORMAT_STRING pPointer)
3031 PFORMAT_STRING desc;
3035 while (*pFormat != RPC_FC_END) {
3057 case RPC_FC_POINTER:
3058 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3060 pMemory += sizeof(void *);
3062 case RPC_FC_ALIGNM2:
3063 ALIGN_POINTER(pMemory, 2);
3065 case RPC_FC_ALIGNM4:
3066 ALIGN_POINTER(pMemory, 4);
3068 case RPC_FC_ALIGNM8:
3069 ALIGN_POINTER(pMemory, 8);
3071 case RPC_FC_STRUCTPAD1:
3072 case RPC_FC_STRUCTPAD2:
3073 case RPC_FC_STRUCTPAD3:
3074 case RPC_FC_STRUCTPAD4:
3075 case RPC_FC_STRUCTPAD5:
3076 case RPC_FC_STRUCTPAD6:
3077 case RPC_FC_STRUCTPAD7:
3078 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3080 case RPC_FC_EMBEDDED_COMPLEX:
3081 pMemory += pFormat[1];
3083 desc = pFormat + *(const SHORT*)pFormat;
3084 size = EmbeddedComplexSize(pStubMsg, desc);
3085 m = NdrFreer[*desc & NDR_TABLE_MASK];
3088 /* for some reason interface pointers aren't generated as
3089 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3090 * they still need the derefencing treatment that pointers are
3092 if (*desc == RPC_FC_IP)
3093 m(pStubMsg, *(unsigned char **)pMemory, desc);
3095 m(pStubMsg, pMemory, desc);
3103 FIXME("unhandled format 0x%02x\n", *pFormat);
3111 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3112 PFORMAT_STRING pFormat,
3113 PFORMAT_STRING pPointer)
3115 PFORMAT_STRING desc;
3118 while (*pFormat != RPC_FC_END) {
3125 safe_buffer_increment(pStubMsg, 1);
3131 safe_buffer_increment(pStubMsg, 2);
3135 safe_buffer_increment(pStubMsg, 2);
3141 safe_buffer_increment(pStubMsg, 4);
3145 safe_buffer_increment(pStubMsg, 8);
3147 case RPC_FC_POINTER:
3149 unsigned char *saved_buffer;
3150 int pointer_buffer_mark_set = 0;
3151 if (*pPointer != RPC_FC_RP)
3152 ALIGN_POINTER(pStubMsg->Buffer, 4);
3153 saved_buffer = pStubMsg->Buffer;
3154 if (pStubMsg->PointerBufferMark)
3156 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3157 pStubMsg->PointerBufferMark = NULL;
3158 pointer_buffer_mark_set = 1;
3160 else if (*pPointer != RPC_FC_RP)
3161 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3163 if (!pStubMsg->IgnoreEmbeddedPointers)
3164 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3165 if (pointer_buffer_mark_set)
3167 STD_OVERFLOW_CHECK(pStubMsg);
3168 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3169 pStubMsg->Buffer = saved_buffer;
3170 if (*pPointer != RPC_FC_RP)
3171 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3174 size += sizeof(void *);
3177 case RPC_FC_ALIGNM2:
3178 ALIGN_LENGTH(size, 2);
3180 case RPC_FC_ALIGNM4:
3181 ALIGN_LENGTH(size, 4);
3183 case RPC_FC_ALIGNM8:
3184 ALIGN_LENGTH(size, 8);
3186 case RPC_FC_STRUCTPAD1:
3187 case RPC_FC_STRUCTPAD2:
3188 case RPC_FC_STRUCTPAD3:
3189 case RPC_FC_STRUCTPAD4:
3190 case RPC_FC_STRUCTPAD5:
3191 case RPC_FC_STRUCTPAD6:
3192 case RPC_FC_STRUCTPAD7:
3193 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3195 case RPC_FC_EMBEDDED_COMPLEX:
3198 desc = pFormat + *(const SHORT*)pFormat;
3199 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3205 FIXME("unhandled format 0x%02x\n", *pFormat);
3213 ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
3215 PFORMAT_STRING desc;
3218 while (*pFormat != RPC_FC_END) {
3240 case RPC_FC_POINTER:
3241 size += sizeof(void *);
3243 case RPC_FC_ALIGNM2:
3244 ALIGN_LENGTH(size, 2);
3246 case RPC_FC_ALIGNM4:
3247 ALIGN_LENGTH(size, 4);
3249 case RPC_FC_ALIGNM8:
3250 ALIGN_LENGTH(size, 8);
3252 case RPC_FC_STRUCTPAD1:
3253 case RPC_FC_STRUCTPAD2:
3254 case RPC_FC_STRUCTPAD3:
3255 case RPC_FC_STRUCTPAD4:
3256 case RPC_FC_STRUCTPAD5:
3257 case RPC_FC_STRUCTPAD6:
3258 case RPC_FC_STRUCTPAD7:
3259 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3261 case RPC_FC_EMBEDDED_COMPLEX:
3264 desc = pFormat + *(const SHORT*)pFormat;
3265 size += EmbeddedComplexSize(pStubMsg, desc);
3271 FIXME("unhandled format 0x%02x\n", *pFormat);
3279 /***********************************************************************
3280 * NdrComplexStructMarshall [RPCRT4.@]
3282 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3283 unsigned char *pMemory,
3284 PFORMAT_STRING pFormat)
3286 PFORMAT_STRING conf_array = NULL;
3287 PFORMAT_STRING pointer_desc = NULL;
3288 unsigned char *OldMemory = pStubMsg->Memory;
3289 int pointer_buffer_mark_set = 0;
3291 ULONG max_count = 0;
3294 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3296 if (!pStubMsg->PointerBufferMark)
3298 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3299 /* save buffer length */
3300 ULONG saved_buffer_length = pStubMsg->BufferLength;
3302 /* get the buffer pointer after complex array data, but before
3304 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3305 pStubMsg->IgnoreEmbeddedPointers = 1;
3306 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3307 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3309 /* save it for use by embedded pointer code later */
3310 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3311 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - pStubMsg->Buffer));
3312 pointer_buffer_mark_set = 1;
3314 /* restore the original buffer length */
3315 pStubMsg->BufferLength = saved_buffer_length;
3318 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
3321 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3323 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3326 pStubMsg->Memory = pMemory;
3330 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3331 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3332 pMemory + struct_size, conf_array);
3333 /* these could be changed in ComplexMarshall so save them for later */
3334 max_count = pStubMsg->MaxCount;
3335 count = pStubMsg->ActualCount;
3336 offset = pStubMsg->Offset;
3339 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3343 pStubMsg->MaxCount = max_count;
3344 pStubMsg->ActualCount = count;
3345 pStubMsg->Offset = offset;
3346 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3347 conf_array, TRUE /* fHasPointers */);
3350 pStubMsg->Memory = OldMemory;
3352 if (pointer_buffer_mark_set)
3354 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3355 pStubMsg->PointerBufferMark = NULL;
3358 STD_OVERFLOW_CHECK(pStubMsg);
3363 /***********************************************************************
3364 * NdrComplexStructUnmarshall [RPCRT4.@]
3366 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3367 unsigned char **ppMemory,
3368 PFORMAT_STRING pFormat,
3369 unsigned char fMustAlloc)
3371 unsigned size = *(const WORD*)(pFormat+2);
3372 PFORMAT_STRING conf_array = NULL;
3373 PFORMAT_STRING pointer_desc = NULL;
3374 unsigned char *pMemory;
3375 int pointer_buffer_mark_set = 0;
3377 ULONG max_count = 0;
3379 ULONG array_size = 0;
3381 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3383 if (!pStubMsg->PointerBufferMark)
3385 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3386 /* save buffer pointer */
3387 unsigned char *saved_buffer = pStubMsg->Buffer;
3389 /* get the buffer pointer after complex array data, but before
3391 pStubMsg->IgnoreEmbeddedPointers = 1;
3392 NdrComplexStructMemorySize(pStubMsg, pFormat);
3393 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3395 /* save it for use by embedded pointer code later */
3396 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3397 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - saved_buffer));
3398 pointer_buffer_mark_set = 1;
3400 /* restore the original buffer */
3401 pStubMsg->Buffer = saved_buffer;
3404 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3407 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3409 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3414 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3417 /* these could be changed in ComplexMarshall so save them for later */
3418 max_count = pStubMsg->MaxCount;
3419 count = pStubMsg->ActualCount;
3420 offset = pStubMsg->Offset;
3423 if (!fMustAlloc && !*ppMemory)
3426 *ppMemory = NdrAllocate(pStubMsg, size);
3428 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3432 pStubMsg->MaxCount = max_count;
3433 pStubMsg->ActualCount = count;
3434 pStubMsg->Offset = offset;
3436 memset(pMemory, 0, array_size);
3437 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3439 FALSE /* fUseBufferMemoryServer */,
3440 TRUE /* fUnmarshall */);
3443 if (pointer_buffer_mark_set)
3445 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3446 pStubMsg->PointerBufferMark = NULL;
3452 /***********************************************************************
3453 * NdrComplexStructBufferSize [RPCRT4.@]
3455 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3456 unsigned char *pMemory,
3457 PFORMAT_STRING pFormat)
3459 PFORMAT_STRING conf_array = NULL;
3460 PFORMAT_STRING pointer_desc = NULL;
3461 unsigned char *OldMemory = pStubMsg->Memory;
3462 int pointer_length_set = 0;
3464 ULONG max_count = 0;
3467 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3469 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
3471 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3473 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3474 ULONG saved_buffer_length = pStubMsg->BufferLength;
3476 /* get the buffer length after complex struct data, but before
3478 pStubMsg->IgnoreEmbeddedPointers = 1;
3479 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3480 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3482 /* save it for use by embedded pointer code later */
3483 pStubMsg->PointerLength = pStubMsg->BufferLength;
3484 pointer_length_set = 1;
3485 TRACE("difference = 0x%x\n", pStubMsg->PointerLength - saved_buffer_length);
3487 /* restore the original buffer length */
3488 pStubMsg->BufferLength = saved_buffer_length;
3492 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3494 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3497 pStubMsg->Memory = pMemory;
3501 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3502 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3505 /* these could be changed in ComplexMarshall so save them for later */
3506 max_count = pStubMsg->MaxCount;
3507 count = pStubMsg->ActualCount;
3508 offset = pStubMsg->Offset;
3511 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3515 pStubMsg->MaxCount = max_count;
3516 pStubMsg->ActualCount = count;
3517 pStubMsg->Offset = offset;
3518 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3519 TRUE /* fHasPointers */);
3522 pStubMsg->Memory = OldMemory;
3524 if(pointer_length_set)
3526 pStubMsg->BufferLength = pStubMsg->PointerLength;
3527 pStubMsg->PointerLength = 0;
3532 /***********************************************************************
3533 * NdrComplexStructMemorySize [RPCRT4.@]
3535 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3536 PFORMAT_STRING pFormat)
3538 unsigned size = *(const WORD*)(pFormat+2);
3539 PFORMAT_STRING conf_array = NULL;
3540 PFORMAT_STRING pointer_desc = NULL;
3542 ULONG max_count = 0;
3545 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3547 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3550 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3552 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3557 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3559 /* these could be changed in ComplexStructMemorySize so save them for
3561 max_count = pStubMsg->MaxCount;
3562 count = pStubMsg->ActualCount;
3563 offset = pStubMsg->Offset;
3566 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3570 pStubMsg->MaxCount = max_count;
3571 pStubMsg->ActualCount = count;
3572 pStubMsg->Offset = offset;
3573 array_memory_size(conf_array[0], pStubMsg, conf_array,
3574 TRUE /* fHasPointers */);
3580 /***********************************************************************
3581 * NdrComplexStructFree [RPCRT4.@]
3583 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3584 unsigned char *pMemory,
3585 PFORMAT_STRING pFormat)
3587 PFORMAT_STRING conf_array = NULL;
3588 PFORMAT_STRING pointer_desc = NULL;
3589 unsigned char *OldMemory = pStubMsg->Memory;
3591 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3594 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3596 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3599 pStubMsg->Memory = pMemory;
3601 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3604 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3605 TRUE /* fHasPointers */);
3607 pStubMsg->Memory = OldMemory;
3610 /***********************************************************************
3611 * NdrConformantArrayMarshall [RPCRT4.@]
3613 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3614 unsigned char *pMemory,
3615 PFORMAT_STRING pFormat)
3617 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3618 if (pFormat[0] != RPC_FC_CARRAY)
3620 ERR("invalid format = 0x%x\n", pFormat[0]);
3621 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3624 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory,
3626 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3627 TRUE /* fHasPointers */);
3632 /***********************************************************************
3633 * NdrConformantArrayUnmarshall [RPCRT4.@]
3635 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3636 unsigned char **ppMemory,
3637 PFORMAT_STRING pFormat,
3638 unsigned char fMustAlloc)
3640 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3641 if (pFormat[0] != RPC_FC_CARRAY)
3643 ERR("invalid format = 0x%x\n", pFormat[0]);
3644 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3647 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3648 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat,
3650 TRUE /* fUseBufferMemoryServer */,
3651 TRUE /* fUnmarshall */);
3656 /***********************************************************************
3657 * NdrConformantArrayBufferSize [RPCRT4.@]
3659 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3660 unsigned char *pMemory,
3661 PFORMAT_STRING pFormat)
3663 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3664 if (pFormat[0] != RPC_FC_CARRAY)
3666 ERR("invalid format = 0x%x\n", pFormat[0]);
3667 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3670 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat);
3671 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3672 TRUE /* fHasPointers */);
3675 /***********************************************************************
3676 * NdrConformantArrayMemorySize [RPCRT4.@]
3678 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3679 PFORMAT_STRING pFormat)
3681 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3682 if (pFormat[0] != RPC_FC_CARRAY)
3684 ERR("invalid format = 0x%x\n", pFormat[0]);
3685 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3688 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3689 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
3691 return pStubMsg->MemorySize;
3694 /***********************************************************************
3695 * NdrConformantArrayFree [RPCRT4.@]
3697 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3698 unsigned char *pMemory,
3699 PFORMAT_STRING pFormat)
3701 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3702 if (pFormat[0] != RPC_FC_CARRAY)
3704 ERR("invalid format = 0x%x\n", pFormat[0]);
3705 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3708 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3709 TRUE /* fHasPointers */);
3713 /***********************************************************************
3714 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3716 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
3717 unsigned char* pMemory,
3718 PFORMAT_STRING pFormat )
3720 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3722 if (pFormat[0] != RPC_FC_CVARRAY)
3724 ERR("invalid format type %x\n", pFormat[0]);
3725 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3729 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3731 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory,
3732 pFormat, TRUE /* fHasPointers */);
3738 /***********************************************************************
3739 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3741 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
3742 unsigned char** ppMemory,
3743 PFORMAT_STRING pFormat,
3744 unsigned char fMustAlloc )
3746 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3748 if (pFormat[0] != RPC_FC_CVARRAY)
3750 ERR("invalid format type %x\n", pFormat[0]);
3751 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3755 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3756 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory,
3757 pFormat, fMustAlloc,
3758 TRUE /* fUseBufferMemoryServer */,
3759 TRUE /* fUnmarshall */);
3765 /***********************************************************************
3766 * NdrConformantVaryingArrayFree [RPCRT4.@]
3768 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
3769 unsigned char* pMemory,
3770 PFORMAT_STRING pFormat )
3772 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3774 if (pFormat[0] != RPC_FC_CVARRAY)
3776 ERR("invalid format type %x\n", pFormat[0]);
3777 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3781 array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3782 TRUE /* fHasPointers */);
3786 /***********************************************************************
3787 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3789 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
3790 unsigned char* pMemory, PFORMAT_STRING pFormat )
3792 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3794 if (pFormat[0] != RPC_FC_CVARRAY)
3796 ERR("invalid format type %x\n", pFormat[0]);
3797 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3801 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3803 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3804 TRUE /* fHasPointers */);
3808 /***********************************************************************
3809 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3811 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
3812 PFORMAT_STRING pFormat )
3814 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3816 if (pFormat[0] != RPC_FC_CVARRAY)
3818 ERR("invalid format type %x\n", pFormat[0]);
3819 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3820 return pStubMsg->MemorySize;
3823 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3824 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat,
3825 TRUE /* fHasPointers */);
3827 return pStubMsg->MemorySize;
3831 /***********************************************************************
3832 * NdrComplexArrayMarshall [RPCRT4.@]
3834 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3835 unsigned char *pMemory,
3836 PFORMAT_STRING pFormat)
3838 ULONG i, count, def;
3839 BOOL variance_present;
3840 unsigned char alignment;
3841 int pointer_buffer_mark_set = 0;
3843 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3845 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3847 ERR("invalid format type %x\n", pFormat[0]);
3848 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3852 alignment = pFormat[1] + 1;
3854 if (!pStubMsg->PointerBufferMark)
3856 /* save buffer fields that may be changed by buffer sizer functions
3857 * and that may be needed later on */
3858 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3859 ULONG saved_buffer_length = pStubMsg->BufferLength;
3860 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
3861 ULONG saved_offset = pStubMsg->Offset;
3862 ULONG saved_actual_count = pStubMsg->ActualCount;
3864 /* get the buffer pointer after complex array data, but before
3866 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3867 pStubMsg->IgnoreEmbeddedPointers = 1;
3868 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3869 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3871 /* save it for use by embedded pointer code later */
3872 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3873 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer));
3874 pointer_buffer_mark_set = 1;
3876 /* restore fields */
3877 pStubMsg->ActualCount = saved_actual_count;
3878 pStubMsg->Offset = saved_offset;
3879 pStubMsg->MaxCount = saved_max_count;
3880 pStubMsg->BufferLength = saved_buffer_length;
3883 def = *(const WORD*)&pFormat[2];
3886 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3887 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3889 variance_present = IsConformanceOrVariancePresent(pFormat);
3890 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3891 TRACE("variance = %d\n", pStubMsg->ActualCount);
3893 WriteConformance(pStubMsg);
3894 if (variance_present)
3895 WriteVariance(pStubMsg);
3897 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3899 count = pStubMsg->ActualCount;
3900 for (i = 0; i < count; i++)
3901 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3903 STD_OVERFLOW_CHECK(pStubMsg);
3905 if (pointer_buffer_mark_set)
3907 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3908 pStubMsg->PointerBufferMark = NULL;
3914 /***********************************************************************
3915 * NdrComplexArrayUnmarshall [RPCRT4.@]
3917 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3918 unsigned char **ppMemory,
3919 PFORMAT_STRING pFormat,
3920 unsigned char fMustAlloc)
3922 ULONG i, count, size;
3923 unsigned char alignment;
3924 unsigned char *pMemory;
3925 unsigned char *saved_buffer;
3926 int pointer_buffer_mark_set = 0;
3927 int saved_ignore_embedded;
3929 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3931 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3933 ERR("invalid format type %x\n", pFormat[0]);
3934 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3938 alignment = pFormat[1] + 1;
3940 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3941 /* save buffer pointer */
3942 saved_buffer = pStubMsg->Buffer;
3943 /* get the buffer pointer after complex array data, but before
3945 pStubMsg->IgnoreEmbeddedPointers = 1;
3946 pStubMsg->MemorySize = 0;
3947 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3948 size = pStubMsg->MemorySize;
3949 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3951 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - saved_buffer));
3952 if (!pStubMsg->PointerBufferMark)
3954 /* save it for use by embedded pointer code later */
3955 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3956 pointer_buffer_mark_set = 1;
3958 /* restore the original buffer */
3959 pStubMsg->Buffer = saved_buffer;
3963 pFormat = ReadConformance(pStubMsg, pFormat);
3964 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3966 if (!fMustAlloc && !*ppMemory)
3969 *ppMemory = NdrAllocate(pStubMsg, size);
3971 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3973 pMemory = *ppMemory;
3974 count = pStubMsg->ActualCount;
3975 for (i = 0; i < count; i++)
3976 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
3978 if (pointer_buffer_mark_set)
3980 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3981 pStubMsg->PointerBufferMark = NULL;
3987 /***********************************************************************
3988 * NdrComplexArrayBufferSize [RPCRT4.@]
3990 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3991 unsigned char *pMemory,
3992 PFORMAT_STRING pFormat)
3994 ULONG i, count, def;
3995 unsigned char alignment;
3996 BOOL variance_present;
3997 int pointer_length_set = 0;
3999 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4001 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4003 ERR("invalid format type %x\n", pFormat[0]);
4004 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4008 alignment = pFormat[1] + 1;
4010 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
4012 /* save buffer fields that may be changed by buffer sizer functions
4013 * and that may be needed later on */
4014 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4015 ULONG saved_buffer_length = pStubMsg->BufferLength;
4016 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4017 ULONG saved_offset = pStubMsg->Offset;
4018 ULONG saved_actual_count = pStubMsg->ActualCount;
4020 /* get the buffer pointer after complex array data, but before
4022 pStubMsg->IgnoreEmbeddedPointers = 1;
4023 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4024 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4026 /* save it for use by embedded pointer code later */
4027 pStubMsg->PointerLength = pStubMsg->BufferLength;
4028 pointer_length_set = 1;
4030 /* restore fields */
4031 pStubMsg->ActualCount = saved_actual_count;
4032 pStubMsg->Offset = saved_offset;
4033 pStubMsg->MaxCount = saved_max_count;
4034 pStubMsg->BufferLength = saved_buffer_length;
4036 def = *(const WORD*)&pFormat[2];
4039 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4040 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4041 SizeConformance(pStubMsg);
4043 variance_present = IsConformanceOrVariancePresent(pFormat);
4044 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4045 TRACE("variance = %d\n", pStubMsg->ActualCount);
4047 if (variance_present)
4048 SizeVariance(pStubMsg);
4050 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4052 count = pStubMsg->ActualCount;
4053 for (i = 0; i < count; i++)
4054 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
4056 if(pointer_length_set)
4058 pStubMsg->BufferLength = pStubMsg->PointerLength;
4059 pStubMsg->PointerLength = 0;
4063 /***********************************************************************
4064 * NdrComplexArrayMemorySize [RPCRT4.@]
4066 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4067 PFORMAT_STRING pFormat)
4069 ULONG i, count, esize, SavedMemorySize, MemorySize;
4070 unsigned char alignment;
4072 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4074 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4076 ERR("invalid format type %x\n", pFormat[0]);
4077 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4081 alignment = pFormat[1] + 1;
4085 pFormat = ReadConformance(pStubMsg, pFormat);
4086 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
4088 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4090 SavedMemorySize = pStubMsg->MemorySize;
4092 esize = ComplexStructSize(pStubMsg, pFormat);
4094 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
4096 count = pStubMsg->ActualCount;
4097 for (i = 0; i < count; i++)
4098 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
4100 pStubMsg->MemorySize = SavedMemorySize;
4102 pStubMsg->MemorySize += MemorySize;
4106 /***********************************************************************
4107 * NdrComplexArrayFree [RPCRT4.@]
4109 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4110 unsigned char *pMemory,
4111 PFORMAT_STRING pFormat)
4113 ULONG i, count, def;
4115 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4117 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4119 ERR("invalid format type %x\n", pFormat[0]);
4120 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4124 def = *(const WORD*)&pFormat[2];
4127 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4128 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4130 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4131 TRACE("variance = %d\n", pStubMsg->ActualCount);
4133 count = pStubMsg->ActualCount;
4134 for (i = 0; i < count; i++)
4135 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4138 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4139 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4140 USER_MARSHAL_CB *umcb)
4142 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4143 pStubMsg->RpcMsg->DataRepresentation);
4144 umcb->pStubMsg = pStubMsg;
4145 umcb->pReserve = NULL;
4146 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4147 umcb->CBType = cbtype;
4148 umcb->pFormat = pFormat;
4149 umcb->pTypeFormat = NULL /* FIXME */;
4152 #define USER_MARSHAL_PTR_PREFIX \
4153 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4154 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4156 /***********************************************************************
4157 * NdrUserMarshalMarshall [RPCRT4.@]
4159 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4160 unsigned char *pMemory,
4161 PFORMAT_STRING pFormat)
4163 unsigned flags = pFormat[1];
4164 unsigned index = *(const WORD*)&pFormat[2];
4165 unsigned char *saved_buffer = NULL;
4166 USER_MARSHAL_CB umcb;
4168 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4169 TRACE("index=%d\n", index);
4171 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4173 if (flags & USER_MARSHAL_POINTER)
4175 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
4176 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4177 pStubMsg->Buffer += 4;
4178 if (pStubMsg->PointerBufferMark)
4180 saved_buffer = pStubMsg->Buffer;
4181 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4182 pStubMsg->PointerBufferMark = NULL;
4184 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
4187 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
4190 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4191 &umcb.Flags, pStubMsg->Buffer, pMemory);
4195 STD_OVERFLOW_CHECK(pStubMsg);
4196 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4197 pStubMsg->Buffer = saved_buffer;
4200 STD_OVERFLOW_CHECK(pStubMsg);
4205 /***********************************************************************
4206 * NdrUserMarshalUnmarshall [RPCRT4.@]
4208 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4209 unsigned char **ppMemory,
4210 PFORMAT_STRING pFormat,
4211 unsigned char fMustAlloc)
4213 unsigned flags = pFormat[1];
4214 unsigned index = *(const WORD*)&pFormat[2];
4215 DWORD memsize = *(const WORD*)&pFormat[4];
4216 unsigned char *saved_buffer = NULL;
4217 USER_MARSHAL_CB umcb;
4219 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4220 TRACE("index=%d\n", index);
4222 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4224 if (flags & USER_MARSHAL_POINTER)
4226 ALIGN_POINTER(pStubMsg->Buffer, 4);
4227 /* skip pointer prefix */
4228 pStubMsg->Buffer += 4;
4229 if (pStubMsg->PointerBufferMark)
4231 saved_buffer = pStubMsg->Buffer;
4232 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4233 pStubMsg->PointerBufferMark = NULL;
4235 ALIGN_POINTER(pStubMsg->Buffer, 8);
4238 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4240 if (!fMustAlloc && !*ppMemory)
4244 *ppMemory = NdrAllocate(pStubMsg, memsize);
4245 memset(*ppMemory, 0, memsize);
4249 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4250 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4254 STD_OVERFLOW_CHECK(pStubMsg);
4255 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4256 pStubMsg->Buffer = saved_buffer;
4262 /***********************************************************************
4263 * NdrUserMarshalBufferSize [RPCRT4.@]
4265 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4266 unsigned char *pMemory,
4267 PFORMAT_STRING pFormat)
4269 unsigned flags = pFormat[1];
4270 unsigned index = *(const WORD*)&pFormat[2];
4271 DWORD bufsize = *(const WORD*)&pFormat[6];
4272 USER_MARSHAL_CB umcb;
4273 ULONG saved_buffer_length = 0;
4275 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4276 TRACE("index=%d\n", index);
4278 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4280 if (flags & USER_MARSHAL_POINTER)
4282 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4283 /* skip pointer prefix */
4284 safe_buffer_length_increment(pStubMsg, 4);
4285 if (pStubMsg->IgnoreEmbeddedPointers)
4287 if (pStubMsg->PointerLength)
4289 saved_buffer_length = pStubMsg->BufferLength;
4290 pStubMsg->BufferLength = pStubMsg->PointerLength;
4291 pStubMsg->PointerLength = 0;
4293 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
4296 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
4299 TRACE("size=%d\n", bufsize);
4300 safe_buffer_length_increment(pStubMsg, bufsize);
4303 pStubMsg->BufferLength =
4304 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4305 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4307 if (saved_buffer_length)
4309 pStubMsg->PointerLength = pStubMsg->BufferLength;
4310 pStubMsg->BufferLength = saved_buffer_length;
4315 /***********************************************************************
4316 * NdrUserMarshalMemorySize [RPCRT4.@]
4318 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4319 PFORMAT_STRING pFormat)
4321 unsigned flags = pFormat[1];
4322 unsigned index = *(const WORD*)&pFormat[2];
4323 DWORD memsize = *(const WORD*)&pFormat[4];
4324 DWORD bufsize = *(const WORD*)&pFormat[6];
4326 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4327 TRACE("index=%d\n", index);
4329 pStubMsg->MemorySize += memsize;
4331 if (flags & USER_MARSHAL_POINTER)
4333 ALIGN_POINTER(pStubMsg->Buffer, 4);
4334 /* skip pointer prefix */
4335 pStubMsg->Buffer += 4;
4336 if (pStubMsg->IgnoreEmbeddedPointers)
4337 return pStubMsg->MemorySize;
4338 ALIGN_POINTER(pStubMsg->Buffer, 8);
4341 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4344 FIXME("not implemented for varying buffer size\n");
4346 pStubMsg->Buffer += bufsize;
4348 return pStubMsg->MemorySize;
4351 /***********************************************************************
4352 * NdrUserMarshalFree [RPCRT4.@]
4354 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4355 unsigned char *pMemory,
4356 PFORMAT_STRING pFormat)
4358 /* unsigned flags = pFormat[1]; */
4359 unsigned index = *(const WORD*)&pFormat[2];
4360 USER_MARSHAL_CB umcb;
4362 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4363 TRACE("index=%d\n", index);
4365 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4367 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4368 &umcb.Flags, pMemory);
4371 /***********************************************************************
4372 * NdrGetUserMarshalInfo [RPCRT4.@]
4374 RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi)
4376 USER_MARSHAL_CB *umcb = CONTAINING_RECORD(flags, USER_MARSHAL_CB, Flags);
4378 TRACE("(%p,%u,%p)\n", flags, level, umi);
4381 return RPC_S_INVALID_ARG;
4383 memset(&umi->u1.Level1, 0, sizeof(umi->u1.Level1));
4384 umi->InformationLevel = level;
4386 if (umcb->Signature != USER_MARSHAL_CB_SIGNATURE)
4387 return RPC_S_INVALID_ARG;
4389 umi->u1.Level1.pfnAllocate = umcb->pStubMsg->pfnAllocate;
4390 umi->u1.Level1.pfnFree = umcb->pStubMsg->pfnFree;
4391 umi->u1.Level1.pRpcChannelBuffer = umcb->pStubMsg->pRpcChannelBuffer;
4393 switch (umcb->CBType)
4395 case USER_MARSHAL_CB_MARSHALL:
4396 case USER_MARSHAL_CB_UNMARSHALL:
4398 RPC_MESSAGE *msg = umcb->pStubMsg->RpcMsg;
4399 unsigned char *buffer_start = msg->Buffer;
4400 unsigned char *buffer_end =
4401 (unsigned char *)msg->Buffer + msg->BufferLength;
4403 if (umcb->pStubMsg->Buffer < buffer_start ||
4404 umcb->pStubMsg->Buffer > buffer_end)
4405 return ERROR_INVALID_USER_BUFFER;
4407 umi->u1.Level1.Buffer = umcb->pStubMsg->Buffer;
4408 umi->u1.Level1.BufferSize = buffer_end - umcb->pStubMsg->Buffer;
4411 case USER_MARSHAL_CB_BUFFER_SIZE:
4412 case USER_MARSHAL_CB_FREE:
4415 WARN("unrecognised CBType %d\n", umcb->CBType);
4421 /***********************************************************************
4422 * NdrClearOutParameters [RPCRT4.@]
4424 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4425 PFORMAT_STRING pFormat,
4428 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4431 /***********************************************************************
4432 * NdrConvert [RPCRT4.@]
4434 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4436 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4437 /* FIXME: since this stub doesn't do any converting, the proper behavior
4438 is to raise an exception */
4441 /***********************************************************************
4442 * NdrConvert2 [RPCRT4.@]
4444 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4446 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4447 pStubMsg, pFormat, NumberParams);
4448 /* FIXME: since this stub doesn't do any converting, the proper behavior
4449 is to raise an exception */
4452 #include "pshpack1.h"
4453 typedef struct _NDR_CSTRUCT_FORMAT
4456 unsigned char alignment;
4457 unsigned short memory_size;
4458 short offset_to_array_description;
4459 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4460 #include "poppack.h"
4462 /***********************************************************************
4463 * NdrConformantStructMarshall [RPCRT4.@]
4465 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4466 unsigned char *pMemory,
4467 PFORMAT_STRING pFormat)
4469 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4470 PFORMAT_STRING pCArrayFormat;
4471 ULONG esize, bufsize;
4473 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4475 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4476 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4478 ERR("invalid format type %x\n", pCStructFormat->type);
4479 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4483 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4484 pCStructFormat->offset_to_array_description;
4485 if (*pCArrayFormat != RPC_FC_CARRAY)
4487 ERR("invalid array format type %x\n", pCStructFormat->type);
4488 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4491 esize = *(const WORD*)(pCArrayFormat+2);
4493 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4494 pCArrayFormat + 4, 0);
4496 WriteConformance(pStubMsg);
4498 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4500 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4502 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4503 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4505 ERR("integer overflow of memory_size %u with bufsize %u\n",
4506 pCStructFormat->memory_size, bufsize);
4507 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4509 /* copy constant sized part of struct */
4510 pStubMsg->BufferMark = pStubMsg->Buffer;
4511 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4513 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4514 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4519 /***********************************************************************
4520 * NdrConformantStructUnmarshall [RPCRT4.@]
4522 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4523 unsigned char **ppMemory,
4524 PFORMAT_STRING pFormat,
4525 unsigned char fMustAlloc)
4527 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4528 PFORMAT_STRING pCArrayFormat;
4529 ULONG esize, bufsize;
4530 unsigned char *saved_buffer;
4532 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4534 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4535 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4537 ERR("invalid format type %x\n", pCStructFormat->type);
4538 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4541 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4542 pCStructFormat->offset_to_array_description;
4543 if (*pCArrayFormat != RPC_FC_CARRAY)
4545 ERR("invalid array format type %x\n", pCStructFormat->type);
4546 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4549 esize = *(const WORD*)(pCArrayFormat+2);
4551 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4553 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4555 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4557 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4558 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4560 ERR("integer overflow of memory_size %u with bufsize %u\n",
4561 pCStructFormat->memory_size, bufsize);
4562 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4567 SIZE_T size = pCStructFormat->memory_size + bufsize;
4568 *ppMemory = NdrAllocate(pStubMsg, size);
4572 if (!pStubMsg->IsClient && !*ppMemory)
4573 /* for servers, we just point straight into the RPC buffer */
4574 *ppMemory = pStubMsg->Buffer;
4577 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4578 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4579 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4580 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4582 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4583 if (*ppMemory != saved_buffer)
4584 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4589 /***********************************************************************
4590 * NdrConformantStructBufferSize [RPCRT4.@]
4592 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4593 unsigned char *pMemory,
4594 PFORMAT_STRING pFormat)
4596 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4597 PFORMAT_STRING pCArrayFormat;
4600 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4602 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4603 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4605 ERR("invalid format type %x\n", pCStructFormat->type);
4606 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4609 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4610 pCStructFormat->offset_to_array_description;
4611 if (*pCArrayFormat != RPC_FC_CARRAY)
4613 ERR("invalid array format type %x\n", pCStructFormat->type);
4614 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4617 esize = *(const WORD*)(pCArrayFormat+2);
4619 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4620 SizeConformance(pStubMsg);
4622 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4624 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4626 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4627 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4629 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4630 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4633 /***********************************************************************
4634 * NdrConformantStructMemorySize [RPCRT4.@]
4636 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4637 PFORMAT_STRING pFormat)
4643 /***********************************************************************
4644 * NdrConformantStructFree [RPCRT4.@]
4646 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4647 unsigned char *pMemory,
4648 PFORMAT_STRING pFormat)
4650 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4651 PFORMAT_STRING pCArrayFormat;
4653 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4655 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4656 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4658 ERR("invalid format type %x\n", pCStructFormat->type);
4659 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4663 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4664 pCStructFormat->offset_to_array_description;
4665 if (*pCArrayFormat != RPC_FC_CARRAY)
4667 ERR("invalid array format type %x\n", pCStructFormat->type);
4668 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4672 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4673 pCArrayFormat + 4, 0);
4675 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4677 /* copy constant sized part of struct */
4678 pStubMsg->BufferMark = pStubMsg->Buffer;
4680 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4681 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4684 /***********************************************************************
4685 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4687 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4688 unsigned char *pMemory,
4689 PFORMAT_STRING pFormat)
4691 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4692 PFORMAT_STRING pCVArrayFormat;
4694 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4696 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4697 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4699 ERR("invalid format type %x\n", pCVStructFormat->type);
4700 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4704 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4705 pCVStructFormat->offset_to_array_description;
4707 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4708 pMemory + pCVStructFormat->memory_size,
4711 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4713 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4715 /* write constant sized part */
4716 pStubMsg->BufferMark = pStubMsg->Buffer;
4717 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4719 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4720 pMemory + pCVStructFormat->memory_size,
4721 pCVArrayFormat, FALSE /* fHasPointers */);
4723 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4728 /***********************************************************************
4729 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4731 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4732 unsigned char **ppMemory,
4733 PFORMAT_STRING pFormat,
4734 unsigned char fMustAlloc)
4736 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4737 PFORMAT_STRING pCVArrayFormat;
4738 ULONG memsize, bufsize;
4739 unsigned char *saved_buffer, *saved_array_buffer;
4741 unsigned char *array_memory;
4743 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4745 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4746 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4748 ERR("invalid format type %x\n", pCVStructFormat->type);
4749 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4753 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4754 pCVStructFormat->offset_to_array_description;
4756 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4759 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4761 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4763 /* work out how much memory to allocate if we need to do so */
4764 if (!fMustAlloc && !*ppMemory)
4768 SIZE_T size = pCVStructFormat->memory_size + memsize;
4769 *ppMemory = NdrAllocate(pStubMsg, size);
4772 /* mark the start of the constant data */
4773 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4774 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4776 array_memory = *ppMemory + pCVStructFormat->memory_size;
4777 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
4778 &array_memory, pCVArrayFormat,
4779 FALSE /* fMustAlloc */,
4780 FALSE /* fUseServerBufferMemory */,
4781 FALSE /* fUnmarshall */);
4783 /* save offset in case unmarshalling pointers changes it */
4784 offset = pStubMsg->Offset;
4786 /* mark the start of the array data */
4787 saved_array_buffer = pStubMsg->Buffer;
4788 safe_buffer_increment(pStubMsg, bufsize);
4790 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4792 /* copy the constant data */
4793 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
4794 /* copy the array data */
4795 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
4796 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
4797 saved_array_buffer, bufsize);
4799 if (*pCVArrayFormat == RPC_FC_C_CSTRING)
4800 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
4801 else if (*pCVArrayFormat == RPC_FC_C_WSTRING)
4802 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
4807 /***********************************************************************
4808 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4810 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4811 unsigned char *pMemory,
4812 PFORMAT_STRING pFormat)
4814 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4815 PFORMAT_STRING pCVArrayFormat;
4817 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4819 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4820 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4822 ERR("invalid format type %x\n", pCVStructFormat->type);
4823 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4827 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4828 pCVStructFormat->offset_to_array_description;
4829 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
4830 pMemory + pCVStructFormat->memory_size,
4833 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4835 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4837 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4839 array_buffer_size(*pCVArrayFormat, pStubMsg,
4840 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4841 FALSE /* fHasPointers */);
4843 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4846 /***********************************************************************
4847 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4849 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4850 PFORMAT_STRING pFormat)
4852 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4853 PFORMAT_STRING pCVArrayFormat;
4855 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4857 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4858 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4860 ERR("invalid format type %x\n", pCVStructFormat->type);
4861 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4865 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4866 pCVStructFormat->offset_to_array_description;
4867 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
4869 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4871 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4873 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4874 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
4875 FALSE /* fHasPointers */);
4877 pStubMsg->MemorySize += pCVStructFormat->memory_size;
4879 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4881 return pStubMsg->MemorySize;
4884 /***********************************************************************
4885 * NdrConformantVaryingStructFree [RPCRT4.@]
4887 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4888 unsigned char *pMemory,
4889 PFORMAT_STRING pFormat)
4891 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4892 PFORMAT_STRING pCVArrayFormat;
4894 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4896 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4897 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4899 ERR("invalid format type %x\n", pCVStructFormat->type);
4900 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4904 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4905 pCVStructFormat->offset_to_array_description;
4906 array_free(*pCVArrayFormat, pStubMsg,
4907 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4908 FALSE /* fHasPointers */);
4910 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4912 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4915 #include "pshpack1.h"
4919 unsigned char alignment;
4920 unsigned short total_size;
4921 } NDR_SMFARRAY_FORMAT;
4926 unsigned char alignment;
4928 } NDR_LGFARRAY_FORMAT;
4929 #include "poppack.h"
4931 /***********************************************************************
4932 * NdrFixedArrayMarshall [RPCRT4.@]
4934 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4935 unsigned char *pMemory,
4936 PFORMAT_STRING pFormat)
4938 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4941 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4943 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4944 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4946 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4947 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4951 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4953 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4955 total_size = pSmFArrayFormat->total_size;
4956 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4960 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4961 total_size = pLgFArrayFormat->total_size;
4962 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4965 pStubMsg->BufferMark = pStubMsg->Buffer;
4966 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4968 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4973 /***********************************************************************
4974 * NdrFixedArrayUnmarshall [RPCRT4.@]
4976 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4977 unsigned char **ppMemory,
4978 PFORMAT_STRING pFormat,
4979 unsigned char fMustAlloc)
4981 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4983 unsigned char *saved_buffer;
4985 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4987 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4988 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4990 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4991 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4995 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4997 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4999 total_size = pSmFArrayFormat->total_size;
5000 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5004 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5005 total_size = pLgFArrayFormat->total_size;
5006 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5010 *ppMemory = NdrAllocate(pStubMsg, total_size);
5013 if (!pStubMsg->IsClient && !*ppMemory)
5014 /* for servers, we just point straight into the RPC buffer */
5015 *ppMemory = pStubMsg->Buffer;
5018 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5019 safe_buffer_increment(pStubMsg, total_size);
5020 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5022 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
5023 if (*ppMemory != saved_buffer)
5024 memcpy(*ppMemory, saved_buffer, total_size);
5029 /***********************************************************************
5030 * NdrFixedArrayBufferSize [RPCRT4.@]
5032 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5033 unsigned char *pMemory,
5034 PFORMAT_STRING pFormat)
5036 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5039 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5041 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5042 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5044 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5045 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5049 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
5051 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5053 total_size = pSmFArrayFormat->total_size;
5054 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5058 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5059 total_size = pLgFArrayFormat->total_size;
5060 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5062 safe_buffer_length_increment(pStubMsg, total_size);
5064 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5067 /***********************************************************************
5068 * NdrFixedArrayMemorySize [RPCRT4.@]
5070 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5071 PFORMAT_STRING pFormat)
5073 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5076 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5078 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5079 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5081 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5082 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5086 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5088 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5090 total_size = pSmFArrayFormat->total_size;
5091 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5095 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5096 total_size = pLgFArrayFormat->total_size;
5097 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5099 pStubMsg->BufferMark = pStubMsg->Buffer;
5100 safe_buffer_increment(pStubMsg, total_size);
5101 pStubMsg->MemorySize += total_size;
5103 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5108 /***********************************************************************
5109 * NdrFixedArrayFree [RPCRT4.@]
5111 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5112 unsigned char *pMemory,
5113 PFORMAT_STRING pFormat)
5115 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5117 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5119 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5120 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5122 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5123 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5127 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5128 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5131 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5132 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5135 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5138 /***********************************************************************
5139 * NdrVaryingArrayMarshall [RPCRT4.@]
5141 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5142 unsigned char *pMemory,
5143 PFORMAT_STRING pFormat)
5145 unsigned char alignment;
5146 DWORD elements, esize;
5149 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5151 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5152 (pFormat[0] != RPC_FC_LGVARRAY))
5154 ERR("invalid format type %x\n", pFormat[0]);
5155 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5159 alignment = pFormat[1] + 1;
5161 if (pFormat[0] == RPC_FC_SMVARRAY)
5164 pFormat += sizeof(WORD);
5165 elements = *(const WORD*)pFormat;
5166 pFormat += sizeof(WORD);
5171 pFormat += sizeof(DWORD);
5172 elements = *(const DWORD*)pFormat;
5173 pFormat += sizeof(DWORD);
5176 esize = *(const WORD*)pFormat;
5177 pFormat += sizeof(WORD);
5179 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5180 if ((pStubMsg->ActualCount > elements) ||
5181 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5183 RpcRaiseException(RPC_S_INVALID_BOUND);
5187 WriteVariance(pStubMsg);
5189 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
5191 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5192 pStubMsg->BufferMark = pStubMsg->Buffer;
5193 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5195 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5200 /***********************************************************************
5201 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5203 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5204 unsigned char **ppMemory,
5205 PFORMAT_STRING pFormat,
5206 unsigned char fMustAlloc)
5208 unsigned char alignment;
5209 DWORD size, elements, esize;
5211 unsigned char *saved_buffer;
5214 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5216 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5217 (pFormat[0] != RPC_FC_LGVARRAY))
5219 ERR("invalid format type %x\n", pFormat[0]);
5220 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5224 alignment = pFormat[1] + 1;
5226 if (pFormat[0] == RPC_FC_SMVARRAY)
5229 size = *(const WORD*)pFormat;
5230 pFormat += sizeof(WORD);
5231 elements = *(const WORD*)pFormat;
5232 pFormat += sizeof(WORD);
5237 size = *(const DWORD*)pFormat;
5238 pFormat += sizeof(DWORD);
5239 elements = *(const DWORD*)pFormat;
5240 pFormat += sizeof(DWORD);
5243 esize = *(const WORD*)pFormat;
5244 pFormat += sizeof(WORD);
5246 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5248 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5250 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5251 offset = pStubMsg->Offset;
5253 if (!fMustAlloc && !*ppMemory)
5256 *ppMemory = NdrAllocate(pStubMsg, size);
5257 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5258 safe_buffer_increment(pStubMsg, bufsize);
5260 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5262 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5267 /***********************************************************************
5268 * NdrVaryingArrayBufferSize [RPCRT4.@]
5270 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5271 unsigned char *pMemory,
5272 PFORMAT_STRING pFormat)
5274 unsigned char alignment;
5275 DWORD elements, esize;
5277 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5279 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5280 (pFormat[0] != RPC_FC_LGVARRAY))
5282 ERR("invalid format type %x\n", pFormat[0]);
5283 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5287 alignment = pFormat[1] + 1;
5289 if (pFormat[0] == RPC_FC_SMVARRAY)
5292 pFormat += sizeof(WORD);
5293 elements = *(const WORD*)pFormat;
5294 pFormat += sizeof(WORD);
5299 pFormat += sizeof(DWORD);
5300 elements = *(const DWORD*)pFormat;
5301 pFormat += sizeof(DWORD);
5304 esize = *(const WORD*)pFormat;
5305 pFormat += sizeof(WORD);
5307 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5308 if ((pStubMsg->ActualCount > elements) ||
5309 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5311 RpcRaiseException(RPC_S_INVALID_BOUND);
5315 SizeVariance(pStubMsg);
5317 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
5319 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5321 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5324 /***********************************************************************
5325 * NdrVaryingArrayMemorySize [RPCRT4.@]
5327 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5328 PFORMAT_STRING pFormat)
5330 unsigned char alignment;
5331 DWORD size, elements, esize;
5333 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5335 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5336 (pFormat[0] != RPC_FC_LGVARRAY))
5338 ERR("invalid format type %x\n", pFormat[0]);
5339 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5343 alignment = pFormat[1] + 1;
5345 if (pFormat[0] == RPC_FC_SMVARRAY)
5348 size = *(const WORD*)pFormat;
5349 pFormat += sizeof(WORD);
5350 elements = *(const WORD*)pFormat;
5351 pFormat += sizeof(WORD);
5356 size = *(const DWORD*)pFormat;
5357 pFormat += sizeof(DWORD);
5358 elements = *(const DWORD*)pFormat;
5359 pFormat += sizeof(DWORD);
5362 esize = *(const WORD*)pFormat;
5363 pFormat += sizeof(WORD);
5365 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5367 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5369 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5370 pStubMsg->MemorySize += size;
5372 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5374 return pStubMsg->MemorySize;
5377 /***********************************************************************
5378 * NdrVaryingArrayFree [RPCRT4.@]
5380 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5381 unsigned char *pMemory,
5382 PFORMAT_STRING pFormat)
5386 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5388 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5389 (pFormat[0] != RPC_FC_LGVARRAY))
5391 ERR("invalid format type %x\n", pFormat[0]);
5392 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5396 if (pFormat[0] == RPC_FC_SMVARRAY)
5399 pFormat += sizeof(WORD);
5400 elements = *(const WORD*)pFormat;
5401 pFormat += sizeof(WORD);
5406 pFormat += sizeof(DWORD);
5407 elements = *(const DWORD*)pFormat;
5408 pFormat += sizeof(DWORD);
5411 pFormat += sizeof(WORD);
5413 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5414 if ((pStubMsg->ActualCount > elements) ||
5415 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5417 RpcRaiseException(RPC_S_INVALID_BOUND);
5421 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5424 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5437 return *(const USHORT *)pMemory;
5441 return *(const ULONG *)pMemory;
5443 FIXME("Unhandled base type: 0x%02x\n", fc);
5448 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5450 PFORMAT_STRING pFormat)
5452 unsigned short num_arms, arm, type;
5454 num_arms = *(const SHORT*)pFormat & 0x0fff;
5456 for(arm = 0; arm < num_arms; arm++)
5458 if(discriminant == *(const ULONG*)pFormat)
5466 type = *(const unsigned short*)pFormat;
5467 TRACE("type %04x\n", type);
5468 if(arm == num_arms) /* default arm extras */
5472 ERR("no arm for 0x%x and no default case\n", discriminant);
5473 RpcRaiseException(RPC_S_INVALID_TAG);
5478 TRACE("falling back to empty default case for 0x%x\n", discriminant);
5485 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5487 unsigned short type;
5491 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5495 type = *(const unsigned short*)pFormat;
5496 if((type & 0xff00) == 0x8000)
5498 unsigned char basetype = LOBYTE(type);
5499 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5503 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5504 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5507 unsigned char *saved_buffer = NULL;
5508 int pointer_buffer_mark_set = 0;
5515 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5516 saved_buffer = pStubMsg->Buffer;
5517 if (pStubMsg->PointerBufferMark)
5519 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5520 pStubMsg->PointerBufferMark = NULL;
5521 pointer_buffer_mark_set = 1;
5524 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5526 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5527 if (pointer_buffer_mark_set)
5529 STD_OVERFLOW_CHECK(pStubMsg);
5530 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5531 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5533 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5534 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5535 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5537 pStubMsg->Buffer = saved_buffer + 4;
5541 m(pStubMsg, pMemory, desc);
5544 else FIXME("no marshaller for embedded type %02x\n", *desc);
5549 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5550 unsigned char **ppMemory,
5552 PFORMAT_STRING pFormat,
5553 unsigned char fMustAlloc)
5555 unsigned short type;
5559 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5563 type = *(const unsigned short*)pFormat;
5564 if((type & 0xff00) == 0x8000)
5566 unsigned char basetype = LOBYTE(type);
5567 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5571 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5572 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5575 unsigned char *saved_buffer = NULL;
5576 int pointer_buffer_mark_set = 0;
5583 ALIGN_POINTER(pStubMsg->Buffer, 4);
5584 saved_buffer = pStubMsg->Buffer;
5585 if (pStubMsg->PointerBufferMark)
5587 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5588 pStubMsg->PointerBufferMark = NULL;
5589 pointer_buffer_mark_set = 1;
5592 pStubMsg->Buffer += 4; /* for pointer ID */
5594 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5596 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5597 saved_buffer, pStubMsg->BufferEnd);
5598 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5601 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5602 if (pointer_buffer_mark_set)
5604 STD_OVERFLOW_CHECK(pStubMsg);
5605 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5606 pStubMsg->Buffer = saved_buffer + 4;
5610 m(pStubMsg, ppMemory, desc, fMustAlloc);
5613 else FIXME("no marshaller for embedded type %02x\n", *desc);
5618 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5619 unsigned char *pMemory,
5621 PFORMAT_STRING pFormat)
5623 unsigned short type;
5627 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5631 type = *(const unsigned short*)pFormat;
5632 if((type & 0xff00) == 0x8000)
5634 unsigned char basetype = LOBYTE(type);
5635 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5639 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5640 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5649 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5650 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5651 if (!pStubMsg->IgnoreEmbeddedPointers)
5653 int saved_buffer_length = pStubMsg->BufferLength;
5654 pStubMsg->BufferLength = pStubMsg->PointerLength;
5655 pStubMsg->PointerLength = 0;
5656 if(!pStubMsg->BufferLength)
5657 ERR("BufferLength == 0??\n");
5658 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5659 pStubMsg->PointerLength = pStubMsg->BufferLength;
5660 pStubMsg->BufferLength = saved_buffer_length;
5664 m(pStubMsg, pMemory, desc);
5667 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5671 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5673 PFORMAT_STRING pFormat)
5675 unsigned short type, size;
5677 size = *(const unsigned short*)pFormat;
5678 pStubMsg->Memory += size;
5681 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5685 type = *(const unsigned short*)pFormat;
5686 if((type & 0xff00) == 0x8000)
5688 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5692 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5693 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5694 unsigned char *saved_buffer;
5703 ALIGN_POINTER(pStubMsg->Buffer, 4);
5704 saved_buffer = pStubMsg->Buffer;
5705 safe_buffer_increment(pStubMsg, 4);
5706 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(void *));
5707 pStubMsg->MemorySize += sizeof(void *);
5708 if (!pStubMsg->IgnoreEmbeddedPointers)
5709 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5712 return m(pStubMsg, desc);
5715 else FIXME("no marshaller for embedded type %02x\n", *desc);
5718 TRACE("size %d\n", size);
5722 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5723 unsigned char *pMemory,
5725 PFORMAT_STRING pFormat)
5727 unsigned short type;
5731 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5735 type = *(const unsigned short*)pFormat;
5736 if((type & 0xff00) != 0x8000)
5738 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5739 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5748 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5751 m(pStubMsg, pMemory, desc);
5757 /***********************************************************************
5758 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5760 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5761 unsigned char *pMemory,
5762 PFORMAT_STRING pFormat)
5764 unsigned char switch_type;
5765 unsigned char increment;
5768 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5771 switch_type = *pFormat & 0xf;
5772 increment = (*pFormat & 0xf0) >> 4;
5775 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5777 switch_value = get_discriminant(switch_type, pMemory);
5778 TRACE("got switch value 0x%x\n", switch_value);
5780 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5781 pMemory += increment;
5783 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5786 /***********************************************************************
5787 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5789 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5790 unsigned char **ppMemory,
5791 PFORMAT_STRING pFormat,
5792 unsigned char fMustAlloc)
5794 unsigned char switch_type;
5795 unsigned char increment;
5797 unsigned short size;
5798 unsigned char *pMemoryArm;
5800 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5803 switch_type = *pFormat & 0xf;
5804 increment = (*pFormat & 0xf0) >> 4;
5807 ALIGN_POINTER(pStubMsg->Buffer, increment);
5808 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5809 TRACE("got switch value 0x%x\n", switch_value);
5811 size = *(const unsigned short*)pFormat + increment;
5812 if (!fMustAlloc && !*ppMemory)
5815 *ppMemory = NdrAllocate(pStubMsg, size);
5817 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
5818 * since the arm is part of the memory block that is encompassed by
5819 * the whole union. Memory is forced to allocate when pointers
5820 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
5821 * clearing the memory we pass in to the unmarshaller */
5823 memset(*ppMemory, 0, size);
5825 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5826 pMemoryArm = *ppMemory + increment;
5828 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, FALSE);
5831 /***********************************************************************
5832 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5834 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5835 unsigned char *pMemory,
5836 PFORMAT_STRING pFormat)
5838 unsigned char switch_type;
5839 unsigned char increment;
5842 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5845 switch_type = *pFormat & 0xf;
5846 increment = (*pFormat & 0xf0) >> 4;
5849 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5850 switch_value = get_discriminant(switch_type, pMemory);
5851 TRACE("got switch value 0x%x\n", switch_value);
5853 /* Add discriminant size */
5854 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5855 pMemory += increment;
5857 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5860 /***********************************************************************
5861 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5863 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5864 PFORMAT_STRING pFormat)
5866 unsigned char switch_type;
5867 unsigned char increment;
5870 switch_type = *pFormat & 0xf;
5871 increment = (*pFormat & 0xf0) >> 4;
5874 ALIGN_POINTER(pStubMsg->Buffer, increment);
5875 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5876 TRACE("got switch value 0x%x\n", switch_value);
5878 pStubMsg->Memory += increment;
5880 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5883 /***********************************************************************
5884 * NdrEncapsulatedUnionFree [RPCRT4.@]
5886 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5887 unsigned char *pMemory,
5888 PFORMAT_STRING pFormat)
5890 unsigned char switch_type;
5891 unsigned char increment;
5894 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5897 switch_type = *pFormat & 0xf;
5898 increment = (*pFormat & 0xf0) >> 4;
5901 switch_value = get_discriminant(switch_type, pMemory);
5902 TRACE("got switch value 0x%x\n", switch_value);
5904 pMemory += increment;
5906 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5909 /***********************************************************************
5910 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5912 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5913 unsigned char *pMemory,
5914 PFORMAT_STRING pFormat)
5916 unsigned char switch_type;
5918 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5921 switch_type = *pFormat;
5924 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5925 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5926 /* Marshall discriminant */
5927 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5929 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5932 static LONG unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5933 PFORMAT_STRING *ppFormat)
5935 LONG discriminant = 0;
5945 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5954 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5955 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5963 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5964 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5969 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5973 if (pStubMsg->fHasNewCorrDesc)
5977 return discriminant;
5980 /**********************************************************************
5981 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5983 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5984 unsigned char **ppMemory,
5985 PFORMAT_STRING pFormat,
5986 unsigned char fMustAlloc)
5989 unsigned short size;
5991 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5994 /* Unmarshall discriminant */
5995 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5996 TRACE("unmarshalled discriminant %x\n", discriminant);
5998 pFormat += *(const SHORT*)pFormat;
6000 size = *(const unsigned short*)pFormat;
6002 if (!fMustAlloc && !*ppMemory)
6005 *ppMemory = NdrAllocate(pStubMsg, size);
6007 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6008 * since the arm is part of the memory block that is encompassed by
6009 * the whole union. Memory is forced to allocate when pointers
6010 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6011 * clearing the memory we pass in to the unmarshaller */
6013 memset(*ppMemory, 0, size);
6015 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, FALSE);
6018 /***********************************************************************
6019 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6021 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6022 unsigned char *pMemory,
6023 PFORMAT_STRING pFormat)
6025 unsigned char switch_type;
6027 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6030 switch_type = *pFormat;
6033 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6034 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6035 /* Add discriminant size */
6036 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6038 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6041 /***********************************************************************
6042 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6044 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6045 PFORMAT_STRING pFormat)
6050 /* Unmarshall discriminant */
6051 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6052 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
6054 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
6057 /***********************************************************************
6058 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6060 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6061 unsigned char *pMemory,
6062 PFORMAT_STRING pFormat)
6064 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6068 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6069 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6071 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6074 /***********************************************************************
6075 * NdrByteCountPointerMarshall [RPCRT4.@]
6077 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6078 unsigned char *pMemory,
6079 PFORMAT_STRING pFormat)
6085 /***********************************************************************
6086 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6088 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6089 unsigned char **ppMemory,
6090 PFORMAT_STRING pFormat,
6091 unsigned char fMustAlloc)
6097 /***********************************************************************
6098 * NdrByteCountPointerBufferSize [RPCRT4.@]
6100 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6101 unsigned char *pMemory,
6102 PFORMAT_STRING pFormat)
6107 /***********************************************************************
6108 * NdrByteCountPointerMemorySize [internal]
6110 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6111 PFORMAT_STRING pFormat)
6117 /***********************************************************************
6118 * NdrByteCountPointerFree [RPCRT4.@]
6120 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6121 unsigned char *pMemory,
6122 PFORMAT_STRING pFormat)
6127 /***********************************************************************
6128 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6130 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6131 unsigned char *pMemory,
6132 PFORMAT_STRING pFormat)
6138 /***********************************************************************
6139 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6141 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6142 unsigned char **ppMemory,
6143 PFORMAT_STRING pFormat,
6144 unsigned char fMustAlloc)
6150 /***********************************************************************
6151 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6153 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6154 unsigned char *pMemory,
6155 PFORMAT_STRING pFormat)
6160 /***********************************************************************
6161 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6163 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6164 PFORMAT_STRING pFormat)
6170 /***********************************************************************
6171 * NdrXmitOrRepAsFree [RPCRT4.@]
6173 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6174 unsigned char *pMemory,
6175 PFORMAT_STRING pFormat)
6180 /***********************************************************************
6181 * NdrRangeMarshall [internal]
6183 static unsigned char *WINAPI NdrRangeMarshall(
6184 PMIDL_STUB_MESSAGE pStubMsg,
6185 unsigned char *pMemory,
6186 PFORMAT_STRING pFormat)
6188 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6189 unsigned char base_type;
6191 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6193 if (pRange->type != RPC_FC_RANGE)
6195 ERR("invalid format type %x\n", pRange->type);
6196 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6200 base_type = pRange->flags_type & 0xf;
6202 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6205 /***********************************************************************
6206 * NdrRangeUnmarshall [RPCRT4.@]
6208 unsigned char *WINAPI NdrRangeUnmarshall(
6209 PMIDL_STUB_MESSAGE pStubMsg,
6210 unsigned char **ppMemory,
6211 PFORMAT_STRING pFormat,
6212 unsigned char fMustAlloc)
6214 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6215 unsigned char base_type;
6217 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6219 if (pRange->type != RPC_FC_RANGE)
6221 ERR("invalid format type %x\n", pRange->type);
6222 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6225 base_type = pRange->flags_type & 0xf;
6227 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6228 base_type, pRange->low_value, pRange->high_value);
6230 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6233 ALIGN_POINTER(pStubMsg->Buffer, sizeof(wire_type)); \
6234 if (!fMustAlloc && !*ppMemory) \
6235 fMustAlloc = TRUE; \
6237 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6238 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6240 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6241 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6242 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6244 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6245 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6247 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6248 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6249 (mem_type)pRange->high_value); \
6250 RpcRaiseException(RPC_S_INVALID_BOUND); \
6253 TRACE("*ppMemory: %p\n", *ppMemory); \
6254 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6255 pStubMsg->Buffer += sizeof(wire_type); \
6262 RANGE_UNMARSHALL(UCHAR, UCHAR, "%d");
6263 TRACE("value: 0x%02x\n", **ppMemory);
6267 RANGE_UNMARSHALL(CHAR, CHAR, "%u");
6268 TRACE("value: 0x%02x\n", **ppMemory);
6270 case RPC_FC_WCHAR: /* FIXME: valid? */
6272 RANGE_UNMARSHALL(USHORT, USHORT, "%u");
6273 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6276 RANGE_UNMARSHALL(SHORT, SHORT, "%d");
6277 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6281 RANGE_UNMARSHALL(LONG, LONG, "%d");
6282 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6285 RANGE_UNMARSHALL(ULONG, ULONG, "%u");
6286 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6289 RANGE_UNMARSHALL(UINT, USHORT, "%u");
6290 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6296 ERR("invalid range base type: 0x%02x\n", base_type);
6297 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6303 /***********************************************************************
6304 * NdrRangeBufferSize [internal]
6306 static void WINAPI NdrRangeBufferSize(
6307 PMIDL_STUB_MESSAGE pStubMsg,
6308 unsigned char *pMemory,
6309 PFORMAT_STRING pFormat)
6311 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6312 unsigned char base_type;
6314 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6316 if (pRange->type != RPC_FC_RANGE)
6318 ERR("invalid format type %x\n", pRange->type);
6319 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6321 base_type = pRange->flags_type & 0xf;
6323 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6326 /***********************************************************************
6327 * NdrRangeMemorySize [internal]
6329 static ULONG WINAPI NdrRangeMemorySize(
6330 PMIDL_STUB_MESSAGE pStubMsg,
6331 PFORMAT_STRING pFormat)
6333 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6334 unsigned char base_type;
6336 if (pRange->type != RPC_FC_RANGE)
6338 ERR("invalid format type %x\n", pRange->type);
6339 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6342 base_type = pRange->flags_type & 0xf;
6344 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6347 /***********************************************************************
6348 * NdrRangeFree [internal]
6350 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6351 unsigned char *pMemory,
6352 PFORMAT_STRING pFormat)
6354 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6359 /***********************************************************************
6360 * NdrBaseTypeMarshall [internal]
6362 static unsigned char *WINAPI NdrBaseTypeMarshall(
6363 PMIDL_STUB_MESSAGE pStubMsg,
6364 unsigned char *pMemory,
6365 PFORMAT_STRING pFormat)
6367 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6375 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6376 TRACE("value: 0x%02x\n", *pMemory);
6381 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6382 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6383 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6387 case RPC_FC_ERROR_STATUS_T:
6389 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
6390 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6391 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6394 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
6395 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6398 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
6399 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6402 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
6403 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6404 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6407 /* only 16-bits on the wire, so do a sanity check */
6408 if (*(UINT *)pMemory > SHRT_MAX)
6409 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6410 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6411 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6412 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6413 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
6414 pStubMsg->Buffer += sizeof(USHORT);
6415 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6420 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6423 /* FIXME: what is the correct return value? */
6427 /***********************************************************************
6428 * NdrBaseTypeUnmarshall [internal]
6430 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6431 PMIDL_STUB_MESSAGE pStubMsg,
6432 unsigned char **ppMemory,
6433 PFORMAT_STRING pFormat,
6434 unsigned char fMustAlloc)
6436 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6438 #define BASE_TYPE_UNMARSHALL(type) \
6439 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6440 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6442 *ppMemory = pStubMsg->Buffer; \
6443 TRACE("*ppMemory: %p\n", *ppMemory); \
6444 safe_buffer_increment(pStubMsg, sizeof(type)); \
6449 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6450 TRACE("*ppMemory: %p\n", *ppMemory); \
6451 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6460 BASE_TYPE_UNMARSHALL(UCHAR);
6461 TRACE("value: 0x%02x\n", **ppMemory);
6466 BASE_TYPE_UNMARSHALL(USHORT);
6467 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6471 case RPC_FC_ERROR_STATUS_T:
6473 BASE_TYPE_UNMARSHALL(ULONG);
6474 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6477 BASE_TYPE_UNMARSHALL(float);
6478 TRACE("value: %f\n", **(float **)ppMemory);
6481 BASE_TYPE_UNMARSHALL(double);
6482 TRACE("value: %f\n", **(double **)ppMemory);
6485 BASE_TYPE_UNMARSHALL(ULONGLONG);
6486 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6489 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6490 if (!fMustAlloc && !*ppMemory)
6493 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6494 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
6495 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6496 TRACE("*ppMemory: %p\n", *ppMemory);
6497 /* 16-bits on the wire, but int in memory */
6498 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
6499 pStubMsg->Buffer += sizeof(USHORT);
6500 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6505 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6507 #undef BASE_TYPE_UNMARSHALL
6509 /* FIXME: what is the correct return value? */
6514 /***********************************************************************
6515 * NdrBaseTypeBufferSize [internal]
6517 static void WINAPI NdrBaseTypeBufferSize(
6518 PMIDL_STUB_MESSAGE pStubMsg,
6519 unsigned char *pMemory,
6520 PFORMAT_STRING pFormat)
6522 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6530 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6536 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
6537 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6542 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
6543 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6546 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
6547 safe_buffer_length_increment(pStubMsg, sizeof(float));
6550 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
6551 safe_buffer_length_increment(pStubMsg, sizeof(double));
6554 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
6555 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6557 case RPC_FC_ERROR_STATUS_T:
6558 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
6559 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6564 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6568 /***********************************************************************
6569 * NdrBaseTypeMemorySize [internal]
6571 static ULONG WINAPI NdrBaseTypeMemorySize(
6572 PMIDL_STUB_MESSAGE pStubMsg,
6573 PFORMAT_STRING pFormat)
6575 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6583 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6584 pStubMsg->MemorySize += sizeof(UCHAR);
6585 return sizeof(UCHAR);
6589 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6590 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6591 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(USHORT));
6592 pStubMsg->MemorySize += sizeof(USHORT);
6593 return sizeof(USHORT);
6597 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
6598 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6599 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(ULONG));
6600 pStubMsg->MemorySize += sizeof(ULONG);
6601 return sizeof(ULONG);
6603 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
6604 safe_buffer_increment(pStubMsg, sizeof(float));
6605 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(float));
6606 pStubMsg->MemorySize += sizeof(float);
6607 return sizeof(float);
6609 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
6610 safe_buffer_increment(pStubMsg, sizeof(double));
6611 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(double));
6612 pStubMsg->MemorySize += sizeof(double);
6613 return sizeof(double);
6615 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
6616 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6617 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(ULONGLONG));
6618 pStubMsg->MemorySize += sizeof(ULONGLONG);
6619 return sizeof(ULONGLONG);
6620 case RPC_FC_ERROR_STATUS_T:
6621 ALIGN_POINTER(pStubMsg->Buffer, sizeof(error_status_t));
6622 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6623 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(error_status_t));
6624 pStubMsg->MemorySize += sizeof(error_status_t);
6625 return sizeof(error_status_t);
6627 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6628 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6629 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(UINT));
6630 pStubMsg->MemorySize += sizeof(UINT);
6631 return sizeof(UINT);
6633 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(void *));
6634 pStubMsg->MemorySize += sizeof(void *);
6635 return sizeof(void *);
6637 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6642 /***********************************************************************
6643 * NdrBaseTypeFree [internal]
6645 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6646 unsigned char *pMemory,
6647 PFORMAT_STRING pFormat)
6649 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6654 /***********************************************************************
6655 * NdrContextHandleBufferSize [internal]
6657 static void WINAPI NdrContextHandleBufferSize(
6658 PMIDL_STUB_MESSAGE pStubMsg,
6659 unsigned char *pMemory,
6660 PFORMAT_STRING pFormat)
6662 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6664 if (*pFormat != RPC_FC_BIND_CONTEXT)
6666 ERR("invalid format type %x\n", *pFormat);
6667 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6669 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
6670 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6673 /***********************************************************************
6674 * NdrContextHandleMarshall [internal]
6676 static unsigned char *WINAPI NdrContextHandleMarshall(
6677 PMIDL_STUB_MESSAGE pStubMsg,
6678 unsigned char *pMemory,
6679 PFORMAT_STRING pFormat)
6681 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6683 if (*pFormat != RPC_FC_BIND_CONTEXT)
6685 ERR("invalid format type %x\n", *pFormat);
6686 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6688 TRACE("flags: 0x%02x\n", pFormat[1]);
6690 if (pFormat[1] & 0x80)
6691 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6693 NdrClientContextMarshall(pStubMsg, pMemory, FALSE);
6698 /***********************************************************************
6699 * NdrContextHandleUnmarshall [internal]
6701 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6702 PMIDL_STUB_MESSAGE pStubMsg,
6703 unsigned char **ppMemory,
6704 PFORMAT_STRING pFormat,
6705 unsigned char fMustAlloc)
6707 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6708 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6710 if (*pFormat != RPC_FC_BIND_CONTEXT)
6712 ERR("invalid format type %x\n", *pFormat);
6713 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6715 TRACE("flags: 0x%02x\n", pFormat[1]);
6717 /* [out]-only or [ret] param */
6718 if ((pFormat[1] & 0x60) == 0x20)
6719 **(NDR_CCONTEXT **)ppMemory = NULL;
6720 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6725 /***********************************************************************
6726 * NdrClientContextMarshall [RPCRT4.@]
6728 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6729 NDR_CCONTEXT ContextHandle,
6732 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
6734 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
6736 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6738 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6739 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6740 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6743 /* FIXME: what does fCheck do? */
6744 NDRCContextMarshall(ContextHandle,
6747 pStubMsg->Buffer += cbNDRContext;
6750 /***********************************************************************
6751 * NdrClientContextUnmarshall [RPCRT4.@]
6753 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6754 NDR_CCONTEXT * pContextHandle,
6755 RPC_BINDING_HANDLE BindHandle)
6757 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
6759 ALIGN_POINTER(pStubMsg->Buffer, 4);
6761 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
6762 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6764 NDRCContextUnmarshall(pContextHandle,
6767 pStubMsg->RpcMsg->DataRepresentation);
6769 pStubMsg->Buffer += cbNDRContext;
6772 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6773 NDR_SCONTEXT ContextHandle,
6774 NDR_RUNDOWN RundownRoutine )
6776 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
6778 ALIGN_POINTER(pStubMsg->Buffer, 4);
6780 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6782 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6783 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6784 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6787 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6788 pStubMsg->Buffer, RundownRoutine, NULL,
6789 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6790 pStubMsg->Buffer += cbNDRContext;
6793 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6795 NDR_SCONTEXT ContextHandle;
6797 TRACE("(%p)\n", pStubMsg);
6799 ALIGN_POINTER(pStubMsg->Buffer, 4);
6801 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6803 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6804 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6805 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6808 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6810 pStubMsg->RpcMsg->DataRepresentation,
6811 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6812 pStubMsg->Buffer += cbNDRContext;
6814 return ContextHandle;
6817 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6818 unsigned char* pMemory,
6819 PFORMAT_STRING pFormat)
6821 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6824 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6825 PFORMAT_STRING pFormat)
6827 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6828 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6830 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6832 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6833 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6834 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6835 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6836 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6838 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6839 if_id = &sif->InterfaceId;
6842 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
6843 pStubMsg->RpcMsg->DataRepresentation, if_id,
6847 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6848 NDR_SCONTEXT ContextHandle,
6849 NDR_RUNDOWN RundownRoutine,
6850 PFORMAT_STRING pFormat)
6852 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6853 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6855 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6857 ALIGN_POINTER(pStubMsg->Buffer, 4);
6859 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6861 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6862 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6863 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6866 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6867 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6868 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6869 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6870 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6872 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6873 if_id = &sif->InterfaceId;
6876 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6877 pStubMsg->Buffer, RundownRoutine, if_id, flags);
6878 pStubMsg->Buffer += cbNDRContext;
6881 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6882 PFORMAT_STRING pFormat)
6884 NDR_SCONTEXT ContextHandle;
6885 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6886 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6888 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6890 ALIGN_POINTER(pStubMsg->Buffer, 4);
6892 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6894 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6895 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6896 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6899 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6900 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6901 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6902 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6903 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6905 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6906 if_id = &sif->InterfaceId;
6909 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6911 pStubMsg->RpcMsg->DataRepresentation,
6913 pStubMsg->Buffer += cbNDRContext;
6915 return ContextHandle;
6918 /***********************************************************************
6919 * NdrCorrelationInitialize [RPCRT4.@]
6921 * Initializes correlation validity checking.
6924 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6925 * pMemory [I] Pointer to memory to use as a cache.
6926 * CacheSize [I] Size of the memory pointed to by pMemory.
6927 * Flags [I] Reserved. Set to zero.
6932 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
6934 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
6935 pStubMsg->fHasNewCorrDesc = TRUE;
6938 /***********************************************************************
6939 * NdrCorrelationPass [RPCRT4.@]
6941 * Performs correlation validity checking.
6944 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6949 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
6951 FIXME("(%p): stub\n", pStubMsg);
6954 /***********************************************************************
6955 * NdrCorrelationFree [RPCRT4.@]
6957 * Frees any resources used while unmarshalling parameters that need
6958 * correlation validity checking.
6961 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6966 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
6968 FIXME("(%p): stub\n", pStubMsg);