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
44 #include "wine/unicode.h"
45 #include "wine/rpcfc.h"
47 #include "wine/debug.h"
49 WINE_DEFAULT_DEBUG_CHANNEL(ole);
52 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
53 (*((UINT32 *)(pchar)) = (uint32))
55 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
56 (*((UINT32 *)(pchar)))
58 /* these would work for i386 too, but less efficient */
59 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
60 (*(pchar) = LOBYTE(LOWORD(uint32)), \
61 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
62 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
63 *((pchar)+3) = HIBYTE(HIWORD(uint32)))
65 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
67 MAKEWORD(*(pchar), *((pchar)+1)), \
68 MAKEWORD(*((pchar)+2), *((pchar)+3))))
71 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
72 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
73 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
74 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
75 *(pchar) = HIBYTE(HIWORD(uint32)))
77 #define BIG_ENDIAN_UINT32_READ(pchar) \
79 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
80 MAKEWORD(*((pchar)+1), *(pchar))))
82 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
83 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
84 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
85 # define NDR_LOCAL_UINT32_READ(pchar) \
86 BIG_ENDIAN_UINT32_READ(pchar)
88 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
89 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
90 # define NDR_LOCAL_UINT32_READ(pchar) \
91 LITTLE_ENDIAN_UINT32_READ(pchar)
94 /* _Align must be the desired alignment,
95 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
96 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
97 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
98 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
99 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
100 #define ALIGN_POINTER_CLEAR(_Ptr, _Align) \
102 memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \
103 ALIGN_POINTER(_Ptr, _Align); \
106 #define STD_OVERFLOW_CHECK(_Msg) do { \
107 TRACE("buffer=%d/%d\n", (ULONG)(_Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer), _Msg->BufferLength); \
108 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
109 ERR("buffer overflow %d bytes\n", (ULONG)(_Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength))); \
112 #define NDR_POINTER_ID_BASE 0x20000
113 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
114 #define NDR_TABLE_SIZE 128
115 #define NDR_TABLE_MASK 127
117 #define NDRSContextFromValue(user_context) (NDR_SCONTEXT)((char *)(user_context) - (char *)NDRSContextValue((NDR_SCONTEXT)NULL))
119 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
120 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
121 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
122 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
123 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
125 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
126 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
127 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
129 static unsigned char *WINAPI NdrRangeMarshall(PMIDL_STUB_MESSAGE,unsigned char *, PFORMAT_STRING);
130 static void WINAPI NdrRangeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
131 static ULONG WINAPI NdrRangeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
132 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
134 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
136 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
138 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
139 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
140 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
141 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
145 NdrPointerMarshall, NdrPointerMarshall,
146 NdrPointerMarshall, NdrPointerMarshall,
148 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
149 NdrConformantStructMarshall, NdrConformantStructMarshall,
150 NdrConformantVaryingStructMarshall,
151 NdrComplexStructMarshall,
153 NdrConformantArrayMarshall,
154 NdrConformantVaryingArrayMarshall,
155 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
156 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
157 NdrComplexArrayMarshall,
159 NdrConformantStringMarshall, 0, 0,
160 NdrConformantStringMarshall,
161 NdrNonConformantStringMarshall, 0, 0, 0,
163 NdrEncapsulatedUnionMarshall,
164 NdrNonEncapsulatedUnionMarshall,
165 NdrByteCountPointerMarshall,
166 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
168 NdrInterfacePointerMarshall,
170 NdrContextHandleMarshall,
173 NdrUserMarshalMarshall,
178 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
180 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
181 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
182 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
183 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
185 NdrBaseTypeUnmarshall,
187 NdrPointerUnmarshall, NdrPointerUnmarshall,
188 NdrPointerUnmarshall, NdrPointerUnmarshall,
190 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
191 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
192 NdrConformantVaryingStructUnmarshall,
193 NdrComplexStructUnmarshall,
195 NdrConformantArrayUnmarshall,
196 NdrConformantVaryingArrayUnmarshall,
197 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
198 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
199 NdrComplexArrayUnmarshall,
201 NdrConformantStringUnmarshall, 0, 0,
202 NdrConformantStringUnmarshall,
203 NdrNonConformantStringUnmarshall, 0, 0, 0,
205 NdrEncapsulatedUnionUnmarshall,
206 NdrNonEncapsulatedUnionUnmarshall,
207 NdrByteCountPointerUnmarshall,
208 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
210 NdrInterfacePointerUnmarshall,
212 NdrContextHandleUnmarshall,
215 NdrUserMarshalUnmarshall,
220 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
222 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
223 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
224 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
225 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
227 NdrBaseTypeBufferSize,
229 NdrPointerBufferSize, NdrPointerBufferSize,
230 NdrPointerBufferSize, NdrPointerBufferSize,
232 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
233 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
234 NdrConformantVaryingStructBufferSize,
235 NdrComplexStructBufferSize,
237 NdrConformantArrayBufferSize,
238 NdrConformantVaryingArrayBufferSize,
239 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
240 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
241 NdrComplexArrayBufferSize,
243 NdrConformantStringBufferSize, 0, 0,
244 NdrConformantStringBufferSize,
245 NdrNonConformantStringBufferSize, 0, 0, 0,
247 NdrEncapsulatedUnionBufferSize,
248 NdrNonEncapsulatedUnionBufferSize,
249 NdrByteCountPointerBufferSize,
250 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
252 NdrInterfacePointerBufferSize,
254 NdrContextHandleBufferSize,
257 NdrUserMarshalBufferSize,
262 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
264 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
265 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
266 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
267 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
269 NdrBaseTypeMemorySize,
271 NdrPointerMemorySize, NdrPointerMemorySize,
272 NdrPointerMemorySize, NdrPointerMemorySize,
274 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
275 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
276 NdrConformantVaryingStructMemorySize,
277 NdrComplexStructMemorySize,
279 NdrConformantArrayMemorySize,
280 NdrConformantVaryingArrayMemorySize,
281 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
282 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
283 NdrComplexArrayMemorySize,
285 NdrConformantStringMemorySize, 0, 0,
286 NdrConformantStringMemorySize,
287 NdrNonConformantStringMemorySize, 0, 0, 0,
289 NdrEncapsulatedUnionMemorySize,
290 NdrNonEncapsulatedUnionMemorySize,
291 NdrByteCountPointerMemorySize,
292 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
294 NdrInterfacePointerMemorySize,
299 NdrUserMarshalMemorySize,
304 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
306 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
307 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
308 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
309 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
313 NdrPointerFree, NdrPointerFree,
314 NdrPointerFree, NdrPointerFree,
316 NdrSimpleStructFree, NdrSimpleStructFree,
317 NdrConformantStructFree, NdrConformantStructFree,
318 NdrConformantVaryingStructFree,
319 NdrComplexStructFree,
321 NdrConformantArrayFree,
322 NdrConformantVaryingArrayFree,
323 NdrFixedArrayFree, NdrFixedArrayFree,
324 NdrVaryingArrayFree, NdrVaryingArrayFree,
330 NdrEncapsulatedUnionFree,
331 NdrNonEncapsulatedUnionFree,
333 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
335 NdrInterfacePointerFree,
346 typedef struct _NDR_MEMORY_LIST
351 struct _NDR_MEMORY_LIST *next;
354 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
356 /***********************************************************************
357 * NdrAllocate [RPCRT4.@]
359 * Allocates a block of memory using pStubMsg->pfnAllocate.
362 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
363 * len [I] Size of memory block to allocate.
366 * The memory block of size len that was allocated.
369 * The memory block is always 8-byte aligned.
370 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
371 * exception is raised.
373 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, SIZE_T len)
378 NDR_MEMORY_LIST *mem_list;
380 aligned_len = ALIGNED_LENGTH(len, 8);
381 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
382 /* check for overflow */
383 if (adjusted_len < len)
385 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len, len);
386 RpcRaiseException(RPC_X_BAD_STUB_DATA);
389 p = pStubMsg->pfnAllocate(adjusted_len);
390 if (!p) RpcRaiseException(ERROR_OUTOFMEMORY);
392 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
393 mem_list->magic = MEML_MAGIC;
394 mem_list->size = aligned_len;
395 mem_list->reserved = 0;
396 mem_list->next = pStubMsg->pMemoryList;
397 pStubMsg->pMemoryList = mem_list;
403 static void NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
405 TRACE("(%p, %p)\n", pStubMsg, Pointer);
407 pStubMsg->pfnFree(Pointer);
410 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
412 return (*(const ULONG *)pFormat != -1);
415 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
417 ALIGN_POINTER(pStubMsg->Buffer, 4);
418 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
419 RpcRaiseException(RPC_X_BAD_STUB_DATA);
420 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
421 pStubMsg->Buffer += 4;
422 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
423 if (pStubMsg->fHasNewCorrDesc)
429 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
431 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
433 pStubMsg->Offset = 0;
434 pStubMsg->ActualCount = pStubMsg->MaxCount;
438 ALIGN_POINTER(pStubMsg->Buffer, 4);
439 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
440 RpcRaiseException(RPC_X_BAD_STUB_DATA);
441 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
442 pStubMsg->Buffer += 4;
443 TRACE("offset is %d\n", pStubMsg->Offset);
444 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
445 pStubMsg->Buffer += 4;
446 TRACE("variance is %d\n", pStubMsg->ActualCount);
448 if ((pStubMsg->ActualCount > MaxValue) ||
449 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
451 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
452 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
453 RpcRaiseException(RPC_S_INVALID_BOUND);
458 if (pStubMsg->fHasNewCorrDesc)
464 /* writes the conformance value to the buffer */
465 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
467 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
468 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
469 RpcRaiseException(RPC_X_BAD_STUB_DATA);
470 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
471 pStubMsg->Buffer += 4;
474 /* writes the variance values to the buffer */
475 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
477 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
478 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
479 RpcRaiseException(RPC_X_BAD_STUB_DATA);
480 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
481 pStubMsg->Buffer += 4;
482 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
483 pStubMsg->Buffer += 4;
486 /* requests buffer space for the conformance value */
487 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
489 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
490 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
491 RpcRaiseException(RPC_X_BAD_STUB_DATA);
492 pStubMsg->BufferLength += 4;
495 /* requests buffer space for the variance values */
496 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
498 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
499 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
500 RpcRaiseException(RPC_X_BAD_STUB_DATA);
501 pStubMsg->BufferLength += 8;
504 PFORMAT_STRING ComputeConformanceOrVariance(
505 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
506 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
508 BYTE dtype = pFormat[0] & 0xf;
509 short ofs = *(const short *)&pFormat[2];
513 if (!IsConformanceOrVariancePresent(pFormat)) {
514 /* null descriptor */
519 switch (pFormat[0] & 0xf0) {
520 case RPC_FC_NORMAL_CONFORMANCE:
521 TRACE("normal conformance, ofs=%d\n", ofs);
524 case RPC_FC_POINTER_CONFORMANCE:
525 TRACE("pointer conformance, ofs=%d\n", ofs);
526 ptr = pStubMsg->Memory;
528 case RPC_FC_TOP_LEVEL_CONFORMANCE:
529 TRACE("toplevel conformance, ofs=%d\n", ofs);
530 if (pStubMsg->StackTop) {
531 ptr = pStubMsg->StackTop;
534 /* -Os mode, *pCount is already set */
538 case RPC_FC_CONSTANT_CONFORMANCE:
539 data = ofs | ((DWORD)pFormat[1] << 16);
540 TRACE("constant conformance, val=%d\n", data);
543 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
544 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
545 if (pStubMsg->StackTop) {
546 ptr = pStubMsg->StackTop;
554 FIXME("unknown conformance type %x, expect crash.\n", pFormat[0] & 0xf0);
558 switch (pFormat[1]) {
559 case RPC_FC_DEREFERENCE:
560 ptr = *(LPVOID*)((char *)ptr + ofs);
562 case RPC_FC_CALLBACK:
564 unsigned char *old_stack_top = pStubMsg->StackTop;
565 pStubMsg->StackTop = ptr;
567 /* ofs is index into StubDesc->apfnExprEval */
568 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
569 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
571 pStubMsg->StackTop = old_stack_top;
573 /* the callback function always stores the computed value in MaxCount */
574 *pCount = pStubMsg->MaxCount;
578 ptr = (char *)ptr + ofs;
591 data = *(USHORT*)ptr;
602 FIXME("unknown conformance data type %x\n", dtype);
605 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
608 switch (pFormat[1]) {
609 case RPC_FC_DEREFERENCE: /* already handled */
626 FIXME("unknown conformance op %d\n", pFormat[1]);
631 TRACE("resulting conformance is %ld\n", *pCount);
632 if (pStubMsg->fHasNewCorrDesc)
638 static inline PFORMAT_STRING SkipConformance(PMIDL_STUB_MESSAGE pStubMsg,
639 PFORMAT_STRING pFormat)
641 if (IsConformanceOrVariancePresent(pFormat))
643 if (pStubMsg->fHasNewCorrDesc)
651 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
652 * the result overflows 32-bits */
653 static inline ULONG safe_multiply(ULONG a, ULONG b)
655 ULONGLONG ret = (ULONGLONG)a * b;
656 if (ret > 0xffffffff)
658 RpcRaiseException(RPC_S_INVALID_BOUND);
664 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
666 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
667 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
668 RpcRaiseException(RPC_X_BAD_STUB_DATA);
669 pStubMsg->Buffer += size;
672 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
674 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
676 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
677 pStubMsg->BufferLength, size);
678 RpcRaiseException(RPC_X_BAD_STUB_DATA);
680 pStubMsg->BufferLength += size;
683 /* copies data from the buffer, checking that there is enough data in the buffer
685 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
687 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
688 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
690 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
691 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
692 RpcRaiseException(RPC_X_BAD_STUB_DATA);
694 if (p == pStubMsg->Buffer)
695 ERR("pointer is the same as the buffer\n");
696 memcpy(p, pStubMsg->Buffer, size);
697 pStubMsg->Buffer += size;
700 /* copies data to the buffer, checking that there is enough space to do so */
701 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
703 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
704 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
706 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
707 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
709 RpcRaiseException(RPC_X_BAD_STUB_DATA);
711 memcpy(pStubMsg->Buffer, p, size);
712 pStubMsg->Buffer += size;
715 /* verify that string data sitting in the buffer is valid and safe to
717 static void validate_string_data(MIDL_STUB_MESSAGE *pStubMsg, ULONG bufsize, ULONG esize)
721 /* verify the buffer is safe to access */
722 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
723 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
725 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
726 pStubMsg->BufferEnd, pStubMsg->Buffer);
727 RpcRaiseException(RPC_X_BAD_STUB_DATA);
730 /* strings must always have null terminating bytes */
733 ERR("invalid string length of %d\n", bufsize / esize);
734 RpcRaiseException(RPC_S_INVALID_BOUND);
737 for (i = bufsize - esize; i < bufsize; i++)
738 if (pStubMsg->Buffer[i] != 0)
740 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
741 i, pStubMsg->Buffer[i]);
742 RpcRaiseException(RPC_S_INVALID_BOUND);
746 static inline void dump_pointer_attr(unsigned char attr)
748 if (attr & RPC_FC_P_ALLOCALLNODES)
749 TRACE(" RPC_FC_P_ALLOCALLNODES");
750 if (attr & RPC_FC_P_DONTFREE)
751 TRACE(" RPC_FC_P_DONTFREE");
752 if (attr & RPC_FC_P_ONSTACK)
753 TRACE(" RPC_FC_P_ONSTACK");
754 if (attr & RPC_FC_P_SIMPLEPOINTER)
755 TRACE(" RPC_FC_P_SIMPLEPOINTER");
756 if (attr & RPC_FC_P_DEREF)
757 TRACE(" RPC_FC_P_DEREF");
761 /***********************************************************************
762 * PointerMarshall [internal]
764 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
765 unsigned char *Buffer,
766 unsigned char *Pointer,
767 PFORMAT_STRING pFormat)
769 unsigned type = pFormat[0], attr = pFormat[1];
773 int pointer_needs_marshaling;
775 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
776 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
778 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
779 else desc = pFormat + *(const SHORT*)pFormat;
782 case RPC_FC_RP: /* ref pointer (always non-null) */
785 ERR("NULL ref pointer is not allowed\n");
786 RpcRaiseException(RPC_X_NULL_REF_POINTER);
788 pointer_needs_marshaling = 1;
790 case RPC_FC_UP: /* unique pointer */
791 case RPC_FC_OP: /* object pointer - same as unique here */
793 pointer_needs_marshaling = 1;
795 pointer_needs_marshaling = 0;
796 pointer_id = Pointer ? NDR_POINTER_ID(pStubMsg) : 0;
797 TRACE("writing 0x%08x to buffer\n", pointer_id);
798 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
801 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
802 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
803 TRACE("writing 0x%08x to buffer\n", pointer_id);
804 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
807 FIXME("unhandled ptr type=%02x\n", type);
808 RpcRaiseException(RPC_X_BAD_STUB_DATA);
812 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
814 if (pointer_needs_marshaling) {
815 if (attr & RPC_FC_P_DEREF) {
816 Pointer = *(unsigned char**)Pointer;
817 TRACE("deref => %p\n", Pointer);
819 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
820 if (m) m(pStubMsg, Pointer, desc);
821 else FIXME("no marshaller for data type=%02x\n", *desc);
824 STD_OVERFLOW_CHECK(pStubMsg);
827 /***********************************************************************
828 * PointerUnmarshall [internal]
830 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
831 unsigned char *Buffer,
832 unsigned char **pPointer,
833 unsigned char *pSrcPointer,
834 PFORMAT_STRING pFormat,
835 unsigned char fMustAlloc)
837 unsigned type = pFormat[0], attr = pFormat[1];
840 DWORD pointer_id = 0;
841 int pointer_needs_unmarshaling;
843 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
844 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
846 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
847 else desc = pFormat + *(const SHORT*)pFormat;
850 case RPC_FC_RP: /* ref pointer (always non-null) */
851 pointer_needs_unmarshaling = 1;
853 case RPC_FC_UP: /* unique pointer */
854 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
855 TRACE("pointer_id is 0x%08x\n", pointer_id);
857 pointer_needs_unmarshaling = 1;
860 pointer_needs_unmarshaling = 0;
863 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
864 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
865 TRACE("pointer_id is 0x%08x\n", pointer_id);
866 if (!fMustAlloc && pSrcPointer)
868 FIXME("free object pointer %p\n", pSrcPointer);
872 pointer_needs_unmarshaling = 1;
876 pointer_needs_unmarshaling = 0;
880 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
881 TRACE("pointer_id is 0x%08x\n", pointer_id);
882 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
883 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
886 FIXME("unhandled ptr type=%02x\n", type);
887 RpcRaiseException(RPC_X_BAD_STUB_DATA);
891 if (pointer_needs_unmarshaling) {
892 unsigned char *base_ptr_val = *pPointer;
893 unsigned char **current_ptr = pPointer;
894 if (pStubMsg->IsClient) {
896 /* if we aren't forcing allocation of memory then try to use the existing
897 * (source) pointer to unmarshall the data into so that [in,out]
898 * parameters behave correctly. it doesn't matter if the parameter is
899 * [out] only since in that case the pointer will be NULL. we force
900 * allocation when the source pointer is NULL here instead of in the type
901 * unmarshalling routine for the benefit of the deref code below */
904 TRACE("setting *pPointer to %p\n", pSrcPointer);
905 *pPointer = base_ptr_val = pSrcPointer;
911 /* the memory in a stub is never initialised, so we have to work out here
912 * whether we have to initialise it so we can use the optimisation of
913 * setting the pointer to the buffer, if possible, or set fMustAlloc to
915 if (attr & RPC_FC_P_DEREF) {
923 if (attr & RPC_FC_P_ALLOCALLNODES)
924 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
926 if (attr & RPC_FC_P_DEREF) {
928 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
929 *pPointer = base_ptr_val;
930 current_ptr = (unsigned char **)base_ptr_val;
932 current_ptr = *(unsigned char***)current_ptr;
933 TRACE("deref => %p\n", current_ptr);
934 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
936 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
937 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
938 else FIXME("no unmarshaller for data type=%02x\n", *desc);
940 if (type == RPC_FC_FP)
941 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
945 TRACE("pointer=%p\n", *pPointer);
948 /***********************************************************************
949 * PointerBufferSize [internal]
951 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
952 unsigned char *Pointer,
953 PFORMAT_STRING pFormat)
955 unsigned type = pFormat[0], attr = pFormat[1];
958 int pointer_needs_sizing;
961 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
962 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
964 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
965 else desc = pFormat + *(const SHORT*)pFormat;
968 case RPC_FC_RP: /* ref pointer (always non-null) */
971 ERR("NULL ref pointer is not allowed\n");
972 RpcRaiseException(RPC_X_NULL_REF_POINTER);
977 /* NULL pointer has no further representation */
982 pointer_needs_sizing = !NdrFullPointerQueryPointer(
983 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
984 if (!pointer_needs_sizing)
988 FIXME("unhandled ptr type=%02x\n", type);
989 RpcRaiseException(RPC_X_BAD_STUB_DATA);
993 if (attr & RPC_FC_P_DEREF) {
994 Pointer = *(unsigned char**)Pointer;
995 TRACE("deref => %p\n", Pointer);
998 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
999 if (m) m(pStubMsg, Pointer, desc);
1000 else FIXME("no buffersizer for data type=%02x\n", *desc);
1003 /***********************************************************************
1004 * PointerMemorySize [internal]
1006 static ULONG PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1007 unsigned char *Buffer, PFORMAT_STRING pFormat)
1009 unsigned type = pFormat[0], attr = pFormat[1];
1010 PFORMAT_STRING desc;
1012 DWORD pointer_id = 0;
1013 int pointer_needs_sizing;
1015 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1016 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1018 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1019 else desc = pFormat + *(const SHORT*)pFormat;
1022 case RPC_FC_RP: /* ref pointer (always non-null) */
1023 pointer_needs_sizing = 1;
1025 case RPC_FC_UP: /* unique pointer */
1026 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1027 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1028 TRACE("pointer_id is 0x%08x\n", pointer_id);
1030 pointer_needs_sizing = 1;
1032 pointer_needs_sizing = 0;
1037 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1038 TRACE("pointer_id is 0x%08x\n", pointer_id);
1039 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1040 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1044 FIXME("unhandled ptr type=%02x\n", type);
1045 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1049 if (attr & RPC_FC_P_DEREF) {
1050 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(void*));
1051 pStubMsg->MemorySize += sizeof(void*);
1055 if (pointer_needs_sizing) {
1056 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1057 if (m) m(pStubMsg, desc);
1058 else FIXME("no memorysizer for data type=%02x\n", *desc);
1061 return pStubMsg->MemorySize;
1064 /***********************************************************************
1065 * PointerFree [internal]
1067 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1068 unsigned char *Pointer,
1069 PFORMAT_STRING pFormat)
1071 unsigned type = pFormat[0], attr = pFormat[1];
1072 PFORMAT_STRING desc;
1074 unsigned char *current_pointer = Pointer;
1076 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1077 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1078 if (attr & RPC_FC_P_DONTFREE) return;
1080 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1081 else desc = pFormat + *(const SHORT*)pFormat;
1083 if (!Pointer) return;
1085 if (type == RPC_FC_FP) {
1086 int pointer_needs_freeing = NdrFullPointerFree(
1087 pStubMsg->FullPtrXlatTables, Pointer);
1088 if (!pointer_needs_freeing)
1092 if (attr & RPC_FC_P_DEREF) {
1093 current_pointer = *(unsigned char**)Pointer;
1094 TRACE("deref => %p\n", current_pointer);
1097 m = NdrFreer[*desc & NDR_TABLE_MASK];
1098 if (m) m(pStubMsg, current_pointer, desc);
1100 /* this check stops us from trying to free buffer memory. we don't have to
1101 * worry about clients, since they won't call this function.
1102 * we don't have to check for the buffer being reallocated because
1103 * BufferStart and BufferEnd won't be reset when allocating memory for
1104 * sending the response. we don't have to check for the new buffer here as
1105 * it won't be used a type memory, only for buffer memory */
1106 if (Pointer >= pStubMsg->BufferStart && Pointer < pStubMsg->BufferEnd)
1109 if (attr & RPC_FC_P_ONSTACK) {
1110 TRACE("not freeing stack ptr %p\n", Pointer);
1113 TRACE("freeing %p\n", Pointer);
1114 NdrFree(pStubMsg, Pointer);
1117 TRACE("not freeing %p\n", Pointer);
1120 /***********************************************************************
1121 * EmbeddedPointerMarshall
1123 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1124 unsigned char *pMemory,
1125 PFORMAT_STRING pFormat)
1127 unsigned char *Mark = pStubMsg->BufferMark;
1128 unsigned rep, count, stride;
1130 unsigned char *saved_buffer = NULL;
1132 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1134 if (*pFormat != RPC_FC_PP) return NULL;
1137 if (pStubMsg->PointerBufferMark)
1139 saved_buffer = pStubMsg->Buffer;
1140 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1141 pStubMsg->PointerBufferMark = NULL;
1144 while (pFormat[0] != RPC_FC_END) {
1145 switch (pFormat[0]) {
1147 FIXME("unknown repeat type %d\n", pFormat[0]);
1148 case RPC_FC_NO_REPEAT:
1154 case RPC_FC_FIXED_REPEAT:
1155 rep = *(const WORD*)&pFormat[2];
1156 stride = *(const WORD*)&pFormat[4];
1157 count = *(const WORD*)&pFormat[8];
1160 case RPC_FC_VARIABLE_REPEAT:
1161 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1162 stride = *(const WORD*)&pFormat[2];
1163 count = *(const WORD*)&pFormat[6];
1167 for (i = 0; i < rep; i++) {
1168 PFORMAT_STRING info = pFormat;
1169 unsigned char *membase = pMemory + (i * stride);
1170 unsigned char *bufbase = Mark + (i * stride);
1173 for (u=0; u<count; u++,info+=8) {
1174 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1175 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1176 unsigned char *saved_memory = pStubMsg->Memory;
1178 pStubMsg->Memory = pMemory;
1179 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1180 pStubMsg->Memory = saved_memory;
1183 pFormat += 8 * count;
1188 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1189 pStubMsg->Buffer = saved_buffer;
1192 STD_OVERFLOW_CHECK(pStubMsg);
1197 /***********************************************************************
1198 * EmbeddedPointerUnmarshall
1200 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1201 unsigned char *pDstBuffer,
1202 unsigned char *pSrcMemoryPtrs,
1203 PFORMAT_STRING pFormat,
1204 unsigned char fMustAlloc)
1206 unsigned char *Mark = pStubMsg->BufferMark;
1207 unsigned rep, count, stride;
1209 unsigned char *saved_buffer = NULL;
1211 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc);
1213 if (*pFormat != RPC_FC_PP) return NULL;
1216 if (pStubMsg->PointerBufferMark)
1218 saved_buffer = pStubMsg->Buffer;
1219 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1220 pStubMsg->PointerBufferMark = NULL;
1223 while (pFormat[0] != RPC_FC_END) {
1224 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1225 switch (pFormat[0]) {
1227 FIXME("unknown repeat type %d\n", pFormat[0]);
1228 case RPC_FC_NO_REPEAT:
1234 case RPC_FC_FIXED_REPEAT:
1235 rep = *(const WORD*)&pFormat[2];
1236 stride = *(const WORD*)&pFormat[4];
1237 count = *(const WORD*)&pFormat[8];
1240 case RPC_FC_VARIABLE_REPEAT:
1241 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1242 stride = *(const WORD*)&pFormat[2];
1243 count = *(const WORD*)&pFormat[6];
1247 for (i = 0; i < rep; i++) {
1248 PFORMAT_STRING info = pFormat;
1249 unsigned char *bufdstbase = pDstBuffer + (i * stride);
1250 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1251 unsigned char *bufbase = Mark + (i * stride);
1254 for (u=0; u<count; u++,info+=8) {
1255 unsigned char **bufdstptr = (unsigned char **)(bufdstbase + *(const SHORT*)&info[2]);
1256 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1257 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1258 PointerUnmarshall(pStubMsg, bufptr, bufdstptr, *memsrcptr, info+4, fMustAlloc);
1261 pFormat += 8 * count;
1266 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1267 pStubMsg->Buffer = saved_buffer;
1273 /***********************************************************************
1274 * EmbeddedPointerBufferSize
1276 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1277 unsigned char *pMemory,
1278 PFORMAT_STRING pFormat)
1280 unsigned rep, count, stride;
1282 ULONG saved_buffer_length = 0;
1284 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1286 if (pStubMsg->IgnoreEmbeddedPointers) return;
1288 if (*pFormat != RPC_FC_PP) return;
1291 if (pStubMsg->PointerLength)
1293 saved_buffer_length = pStubMsg->BufferLength;
1294 pStubMsg->BufferLength = pStubMsg->PointerLength;
1295 pStubMsg->PointerLength = 0;
1298 while (pFormat[0] != RPC_FC_END) {
1299 switch (pFormat[0]) {
1301 FIXME("unknown repeat type %d\n", pFormat[0]);
1302 case RPC_FC_NO_REPEAT:
1308 case RPC_FC_FIXED_REPEAT:
1309 rep = *(const WORD*)&pFormat[2];
1310 stride = *(const WORD*)&pFormat[4];
1311 count = *(const WORD*)&pFormat[8];
1314 case RPC_FC_VARIABLE_REPEAT:
1315 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1316 stride = *(const WORD*)&pFormat[2];
1317 count = *(const WORD*)&pFormat[6];
1321 for (i = 0; i < rep; i++) {
1322 PFORMAT_STRING info = pFormat;
1323 unsigned char *membase = pMemory + (i * stride);
1326 for (u=0; u<count; u++,info+=8) {
1327 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1328 unsigned char *saved_memory = pStubMsg->Memory;
1330 pStubMsg->Memory = pMemory;
1331 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1332 pStubMsg->Memory = saved_memory;
1335 pFormat += 8 * count;
1338 if (saved_buffer_length)
1340 pStubMsg->PointerLength = pStubMsg->BufferLength;
1341 pStubMsg->BufferLength = saved_buffer_length;
1345 /***********************************************************************
1346 * EmbeddedPointerMemorySize [internal]
1348 static ULONG EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1349 PFORMAT_STRING pFormat)
1351 unsigned char *Mark = pStubMsg->BufferMark;
1352 unsigned rep, count, stride;
1354 unsigned char *saved_buffer = NULL;
1356 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1358 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1360 if (pStubMsg->PointerBufferMark)
1362 saved_buffer = pStubMsg->Buffer;
1363 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1364 pStubMsg->PointerBufferMark = NULL;
1367 if (*pFormat != RPC_FC_PP) return 0;
1370 while (pFormat[0] != RPC_FC_END) {
1371 switch (pFormat[0]) {
1373 FIXME("unknown repeat type %d\n", pFormat[0]);
1374 case RPC_FC_NO_REPEAT:
1380 case RPC_FC_FIXED_REPEAT:
1381 rep = *(const WORD*)&pFormat[2];
1382 stride = *(const WORD*)&pFormat[4];
1383 count = *(const WORD*)&pFormat[8];
1386 case RPC_FC_VARIABLE_REPEAT:
1387 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1388 stride = *(const WORD*)&pFormat[2];
1389 count = *(const WORD*)&pFormat[6];
1393 for (i = 0; i < rep; i++) {
1394 PFORMAT_STRING info = pFormat;
1395 unsigned char *bufbase = Mark + (i * stride);
1397 for (u=0; u<count; u++,info+=8) {
1398 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1399 PointerMemorySize(pStubMsg, bufptr, info+4);
1402 pFormat += 8 * count;
1407 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1408 pStubMsg->Buffer = saved_buffer;
1414 /***********************************************************************
1415 * EmbeddedPointerFree [internal]
1417 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1418 unsigned char *pMemory,
1419 PFORMAT_STRING pFormat)
1421 unsigned rep, count, stride;
1424 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1425 if (*pFormat != RPC_FC_PP) return;
1428 while (pFormat[0] != RPC_FC_END) {
1429 switch (pFormat[0]) {
1431 FIXME("unknown repeat type %d\n", pFormat[0]);
1432 case RPC_FC_NO_REPEAT:
1438 case RPC_FC_FIXED_REPEAT:
1439 rep = *(const WORD*)&pFormat[2];
1440 stride = *(const WORD*)&pFormat[4];
1441 count = *(const WORD*)&pFormat[8];
1444 case RPC_FC_VARIABLE_REPEAT:
1445 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1446 stride = *(const WORD*)&pFormat[2];
1447 count = *(const WORD*)&pFormat[6];
1451 for (i = 0; i < rep; i++) {
1452 PFORMAT_STRING info = pFormat;
1453 unsigned char *membase = pMemory + (i * stride);
1456 for (u=0; u<count; u++,info+=8) {
1457 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1458 unsigned char *saved_memory = pStubMsg->Memory;
1460 pStubMsg->Memory = pMemory;
1461 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1462 pStubMsg->Memory = saved_memory;
1465 pFormat += 8 * count;
1469 /***********************************************************************
1470 * NdrPointerMarshall [RPCRT4.@]
1472 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1473 unsigned char *pMemory,
1474 PFORMAT_STRING pFormat)
1476 unsigned char *Buffer;
1478 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1480 /* Increment the buffer here instead of in PointerMarshall,
1481 * as that is used by embedded pointers which already handle the incrementing
1482 * the buffer, and shouldn't write any additional pointer data to the wire */
1483 if (*pFormat != RPC_FC_RP)
1485 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
1486 Buffer = pStubMsg->Buffer;
1487 safe_buffer_increment(pStubMsg, 4);
1490 Buffer = pStubMsg->Buffer;
1492 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1497 /***********************************************************************
1498 * NdrPointerUnmarshall [RPCRT4.@]
1500 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1501 unsigned char **ppMemory,
1502 PFORMAT_STRING pFormat,
1503 unsigned char fMustAlloc)
1505 unsigned char *Buffer;
1507 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1509 if (*pFormat == RPC_FC_RP)
1511 Buffer = pStubMsg->Buffer;
1512 /* Do the NULL ref pointer check here because embedded pointers can be
1513 * NULL if the type the pointer is embedded in was allocated rather than
1514 * being passed in by the client */
1515 if (pStubMsg->IsClient && !*ppMemory)
1517 ERR("NULL ref pointer is not allowed\n");
1518 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1523 /* Increment the buffer here instead of in PointerUnmarshall,
1524 * as that is used by embedded pointers which already handle the incrementing
1525 * the buffer, and shouldn't read any additional pointer data from the
1527 ALIGN_POINTER(pStubMsg->Buffer, 4);
1528 Buffer = pStubMsg->Buffer;
1529 safe_buffer_increment(pStubMsg, 4);
1532 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1537 /***********************************************************************
1538 * NdrPointerBufferSize [RPCRT4.@]
1540 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1541 unsigned char *pMemory,
1542 PFORMAT_STRING pFormat)
1544 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1546 /* Increment the buffer length here instead of in PointerBufferSize,
1547 * as that is used by embedded pointers which already handle the buffer
1548 * length, and shouldn't write anything more to the wire */
1549 if (*pFormat != RPC_FC_RP)
1551 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1552 safe_buffer_length_increment(pStubMsg, 4);
1555 PointerBufferSize(pStubMsg, pMemory, pFormat);
1558 /***********************************************************************
1559 * NdrPointerMemorySize [RPCRT4.@]
1561 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1562 PFORMAT_STRING pFormat)
1564 unsigned char *Buffer = pStubMsg->Buffer;
1565 if (*pFormat != RPC_FC_RP)
1567 ALIGN_POINTER(pStubMsg->Buffer, 4);
1568 safe_buffer_increment(pStubMsg, 4);
1570 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(void *));
1571 return PointerMemorySize(pStubMsg, Buffer, pFormat);
1574 /***********************************************************************
1575 * NdrPointerFree [RPCRT4.@]
1577 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1578 unsigned char *pMemory,
1579 PFORMAT_STRING pFormat)
1581 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1582 PointerFree(pStubMsg, pMemory, pFormat);
1585 /***********************************************************************
1586 * NdrSimpleTypeMarshall [RPCRT4.@]
1588 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1589 unsigned char FormatChar )
1591 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1594 /***********************************************************************
1595 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1597 * Unmarshall a base type.
1600 * Doesn't check that the buffer is long enough before copying, so the caller
1603 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1604 unsigned char FormatChar )
1606 #define BASE_TYPE_UNMARSHALL(type) \
1607 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
1608 TRACE("pMemory: %p\n", pMemory); \
1609 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1610 pStubMsg->Buffer += sizeof(type);
1618 BASE_TYPE_UNMARSHALL(UCHAR);
1619 TRACE("value: 0x%02x\n", *pMemory);
1624 BASE_TYPE_UNMARSHALL(USHORT);
1625 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
1629 case RPC_FC_ERROR_STATUS_T:
1631 BASE_TYPE_UNMARSHALL(ULONG);
1632 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
1635 BASE_TYPE_UNMARSHALL(float);
1636 TRACE("value: %f\n", *(float *)pMemory);
1639 BASE_TYPE_UNMARSHALL(double);
1640 TRACE("value: %f\n", *(double *)pMemory);
1643 BASE_TYPE_UNMARSHALL(ULONGLONG);
1644 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
1647 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
1648 TRACE("pMemory: %p\n", pMemory);
1649 /* 16-bits on the wire, but int in memory */
1650 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
1651 pStubMsg->Buffer += sizeof(USHORT);
1652 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
1657 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
1659 #undef BASE_TYPE_UNMARSHALL
1662 /***********************************************************************
1663 * NdrSimpleStructMarshall [RPCRT4.@]
1665 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1666 unsigned char *pMemory,
1667 PFORMAT_STRING pFormat)
1669 unsigned size = *(const WORD*)(pFormat+2);
1670 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1672 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
1674 pStubMsg->BufferMark = pStubMsg->Buffer;
1675 safe_copy_to_buffer(pStubMsg, pMemory, size);
1677 if (pFormat[0] != RPC_FC_STRUCT)
1678 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1683 /***********************************************************************
1684 * NdrSimpleStructUnmarshall [RPCRT4.@]
1686 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1687 unsigned char **ppMemory,
1688 PFORMAT_STRING pFormat,
1689 unsigned char fMustAlloc)
1691 unsigned size = *(const WORD*)(pFormat+2);
1692 unsigned char *saved_buffer;
1693 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1695 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1698 *ppMemory = NdrAllocate(pStubMsg, size);
1701 if (!pStubMsg->IsClient && !*ppMemory)
1702 /* for servers, we just point straight into the RPC buffer */
1703 *ppMemory = pStubMsg->Buffer;
1706 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1707 safe_buffer_increment(pStubMsg, size);
1708 if (pFormat[0] == RPC_FC_PSTRUCT)
1709 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1711 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1712 if (*ppMemory != saved_buffer)
1713 memcpy(*ppMemory, saved_buffer, size);
1718 /***********************************************************************
1719 * NdrSimpleStructBufferSize [RPCRT4.@]
1721 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1722 unsigned char *pMemory,
1723 PFORMAT_STRING pFormat)
1725 unsigned size = *(const WORD*)(pFormat+2);
1726 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1728 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1730 safe_buffer_length_increment(pStubMsg, size);
1731 if (pFormat[0] != RPC_FC_STRUCT)
1732 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1735 /***********************************************************************
1736 * NdrSimpleStructMemorySize [RPCRT4.@]
1738 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1739 PFORMAT_STRING pFormat)
1741 unsigned short size = *(const WORD *)(pFormat+2);
1743 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1745 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1746 pStubMsg->MemorySize += size;
1747 safe_buffer_increment(pStubMsg, size);
1749 if (pFormat[0] != RPC_FC_STRUCT)
1750 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1751 return pStubMsg->MemorySize;
1754 /***********************************************************************
1755 * NdrSimpleStructFree [RPCRT4.@]
1757 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1758 unsigned char *pMemory,
1759 PFORMAT_STRING pFormat)
1761 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1762 if (pFormat[0] != RPC_FC_STRUCT)
1763 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1768 static inline void array_compute_and_size_conformance(
1769 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1770 PFORMAT_STRING pFormat)
1775 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1776 SizeConformance(pStubMsg);
1778 case RPC_FC_CVARRAY:
1779 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1780 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1781 SizeConformance(pStubMsg);
1783 case RPC_FC_C_CSTRING:
1784 case RPC_FC_C_WSTRING:
1785 if (fc == RPC_FC_C_CSTRING)
1787 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1788 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1792 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1793 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1796 if (pFormat[1] == RPC_FC_STRING_SIZED)
1797 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1799 pStubMsg->MaxCount = pStubMsg->ActualCount;
1801 SizeConformance(pStubMsg);
1804 ERR("unknown array format 0x%x\n", fc);
1805 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1809 static inline void array_buffer_size(
1810 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1811 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1815 unsigned char alignment;
1820 esize = *(const WORD*)(pFormat+2);
1821 alignment = pFormat[1] + 1;
1823 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1825 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
1827 size = safe_multiply(esize, pStubMsg->MaxCount);
1828 /* conformance value plus array */
1829 safe_buffer_length_increment(pStubMsg, size);
1832 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1834 case RPC_FC_CVARRAY:
1835 esize = *(const WORD*)(pFormat+2);
1836 alignment = pFormat[1] + 1;
1838 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1839 pFormat = SkipConformance(pStubMsg, pFormat);
1841 SizeVariance(pStubMsg);
1843 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
1845 size = safe_multiply(esize, pStubMsg->ActualCount);
1846 safe_buffer_length_increment(pStubMsg, size);
1849 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1851 case RPC_FC_C_CSTRING:
1852 case RPC_FC_C_WSTRING:
1853 if (fc == RPC_FC_C_CSTRING)
1858 SizeVariance(pStubMsg);
1860 size = safe_multiply(esize, pStubMsg->ActualCount);
1861 safe_buffer_length_increment(pStubMsg, size);
1864 ERR("unknown array format 0x%x\n", fc);
1865 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1869 static inline void array_compute_and_write_conformance(
1870 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1871 PFORMAT_STRING pFormat)
1876 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1877 WriteConformance(pStubMsg);
1879 case RPC_FC_CVARRAY:
1880 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1881 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1882 WriteConformance(pStubMsg);
1884 case RPC_FC_C_CSTRING:
1885 case RPC_FC_C_WSTRING:
1886 if (fc == RPC_FC_C_CSTRING)
1888 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1889 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1893 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1894 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1896 if (pFormat[1] == RPC_FC_STRING_SIZED)
1897 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1899 pStubMsg->MaxCount = pStubMsg->ActualCount;
1900 pStubMsg->Offset = 0;
1901 WriteConformance(pStubMsg);
1904 ERR("unknown array format 0x%x\n", fc);
1905 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1909 static inline void array_write_variance_and_marshall(
1910 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1911 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1915 unsigned char alignment;
1920 esize = *(const WORD*)(pFormat+2);
1921 alignment = pFormat[1] + 1;
1923 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1925 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
1927 size = safe_multiply(esize, pStubMsg->MaxCount);
1929 pStubMsg->BufferMark = pStubMsg->Buffer;
1930 safe_copy_to_buffer(pStubMsg, pMemory, size);
1933 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1935 case RPC_FC_CVARRAY:
1936 esize = *(const WORD*)(pFormat+2);
1937 alignment = pFormat[1] + 1;
1940 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1942 pFormat = SkipConformance(pStubMsg, pFormat);
1944 WriteVariance(pStubMsg);
1946 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
1948 size = safe_multiply(esize, pStubMsg->ActualCount);
1951 pStubMsg->BufferMark = pStubMsg->Buffer;
1952 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size);
1955 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1957 case RPC_FC_C_CSTRING:
1958 case RPC_FC_C_WSTRING:
1959 if (fc == RPC_FC_C_CSTRING)
1964 WriteVariance(pStubMsg);
1966 size = safe_multiply(esize, pStubMsg->ActualCount);
1967 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
1970 ERR("unknown array format 0x%x\n", fc);
1971 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1975 static inline ULONG array_read_conformance(
1976 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
1983 esize = *(const WORD*)(pFormat+2);
1984 pFormat = ReadConformance(pStubMsg, pFormat+4);
1985 return safe_multiply(esize, pStubMsg->MaxCount);
1986 case RPC_FC_CVARRAY:
1987 esize = *(const WORD*)(pFormat+2);
1988 pFormat = ReadConformance(pStubMsg, pFormat+4);
1989 return safe_multiply(esize, pStubMsg->MaxCount);
1990 case RPC_FC_C_CSTRING:
1991 case RPC_FC_C_WSTRING:
1992 if (fc == RPC_FC_C_CSTRING)
1997 if (pFormat[1] == RPC_FC_STRING_SIZED)
1998 ReadConformance(pStubMsg, pFormat + 2);
2000 ReadConformance(pStubMsg, NULL);
2001 return safe_multiply(esize, pStubMsg->MaxCount);
2003 ERR("unknown array format 0x%x\n", fc);
2004 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2008 static inline ULONG array_read_variance_and_unmarshall(
2009 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory,
2010 PFORMAT_STRING pFormat, unsigned char fMustAlloc,
2011 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall)
2013 ULONG bufsize, memsize;
2015 unsigned char alignment;
2016 unsigned char *saved_buffer;
2022 esize = *(const WORD*)(pFormat+2);
2023 alignment = pFormat[1] + 1;
2025 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2027 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2029 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2034 *ppMemory = NdrAllocate(pStubMsg, memsize);
2037 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory)
2038 /* for servers, we just point straight into the RPC buffer */
2039 *ppMemory = pStubMsg->Buffer;
2042 saved_buffer = pStubMsg->Buffer;
2043 safe_buffer_increment(pStubMsg, bufsize);
2045 pStubMsg->BufferMark = saved_buffer;
2046 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2048 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2049 if (*ppMemory != saved_buffer)
2050 memcpy(*ppMemory, saved_buffer, bufsize);
2053 case RPC_FC_CVARRAY:
2054 esize = *(const WORD*)(pFormat+2);
2055 alignment = pFormat[1] + 1;
2057 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2059 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2061 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2063 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2064 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2068 offset = pStubMsg->Offset;
2070 if (!fMustAlloc && !*ppMemory)
2073 *ppMemory = NdrAllocate(pStubMsg, memsize);
2074 saved_buffer = pStubMsg->Buffer;
2075 safe_buffer_increment(pStubMsg, bufsize);
2077 pStubMsg->BufferMark = saved_buffer;
2078 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat,
2081 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2084 case RPC_FC_C_CSTRING:
2085 case RPC_FC_C_WSTRING:
2086 if (fc == RPC_FC_C_CSTRING)
2091 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2093 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2095 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2096 pStubMsg->ActualCount, pStubMsg->MaxCount);
2097 RpcRaiseException(RPC_S_INVALID_BOUND);
2099 if (pStubMsg->Offset)
2101 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2102 RpcRaiseException(RPC_S_INVALID_BOUND);
2105 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2106 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2108 validate_string_data(pStubMsg, bufsize, esize);
2113 *ppMemory = NdrAllocate(pStubMsg, memsize);
2116 if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
2117 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
2118 /* if the data in the RPC buffer is big enough, we just point
2119 * straight into it */
2120 *ppMemory = pStubMsg->Buffer;
2121 else if (!*ppMemory)
2122 *ppMemory = NdrAllocate(pStubMsg, memsize);
2125 if (*ppMemory == pStubMsg->Buffer)
2126 safe_buffer_increment(pStubMsg, bufsize);
2128 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2130 if (*pFormat == RPC_FC_C_CSTRING)
2131 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
2133 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
2137 ERR("unknown array format 0x%x\n", fc);
2138 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2142 static inline void array_memory_size(
2143 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
2144 unsigned char fHasPointers)
2146 ULONG bufsize, memsize;
2148 unsigned char alignment;
2153 esize = *(const WORD*)(pFormat+2);
2154 alignment = pFormat[1] + 1;
2156 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2158 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2159 pStubMsg->MemorySize += memsize;
2161 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2163 pStubMsg->BufferMark = pStubMsg->Buffer;
2164 safe_buffer_increment(pStubMsg, bufsize);
2167 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2169 case RPC_FC_CVARRAY:
2170 esize = *(const WORD*)(pFormat+2);
2171 alignment = pFormat[1] + 1;
2173 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2175 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2177 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2178 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2179 pStubMsg->MemorySize += memsize;
2181 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2183 pStubMsg->BufferMark = pStubMsg->Buffer;
2184 safe_buffer_increment(pStubMsg, bufsize);
2187 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2189 case RPC_FC_C_CSTRING:
2190 case RPC_FC_C_WSTRING:
2191 if (fc == RPC_FC_C_CSTRING)
2196 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2198 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2200 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2201 pStubMsg->ActualCount, pStubMsg->MaxCount);
2202 RpcRaiseException(RPC_S_INVALID_BOUND);
2204 if (pStubMsg->Offset)
2206 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2207 RpcRaiseException(RPC_S_INVALID_BOUND);
2210 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2211 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2213 validate_string_data(pStubMsg, bufsize, esize);
2215 safe_buffer_increment(pStubMsg, bufsize);
2216 pStubMsg->MemorySize += memsize;
2219 ERR("unknown array format 0x%x\n", fc);
2220 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2224 static inline void array_free(
2225 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
2226 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
2231 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2233 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2235 case RPC_FC_CVARRAY:
2236 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2237 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2239 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2241 case RPC_FC_C_CSTRING:
2242 case RPC_FC_C_WSTRING:
2243 /* No embedded pointers so nothing to do */
2246 ERR("unknown array format 0x%x\n", fc);
2247 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2252 * NdrConformantString:
2254 * What MS calls a ConformantString is, in DCE terminology,
2255 * a Varying-Conformant String.
2257 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2258 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2259 * into unmarshalled string)
2260 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2262 * data: CHARTYPE[maxlen]
2264 * ], where CHARTYPE is the appropriate character type (specified externally)
2268 /***********************************************************************
2269 * NdrConformantStringMarshall [RPCRT4.@]
2271 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
2272 unsigned char *pszMessage, PFORMAT_STRING pFormat)
2274 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
2276 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2277 ERR("Unhandled string type: %#x\n", pFormat[0]);
2278 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2281 /* allow compiler to optimise inline function by passing constant into
2282 * these functions */
2283 if (pFormat[0] == RPC_FC_C_CSTRING) {
2284 array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2286 array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2287 pFormat, TRUE /* fHasPointers */);
2289 array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2291 array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2292 pFormat, TRUE /* fHasPointers */);
2298 /***********************************************************************
2299 * NdrConformantStringBufferSize [RPCRT4.@]
2301 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2302 unsigned char* pMemory, PFORMAT_STRING pFormat)
2304 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2306 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2307 ERR("Unhandled string type: %#x\n", pFormat[0]);
2308 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2311 /* allow compiler to optimise inline function by passing constant into
2312 * these functions */
2313 if (pFormat[0] == RPC_FC_C_CSTRING) {
2314 array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory,
2316 array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat,
2317 TRUE /* fHasPointers */);
2319 array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory,
2321 array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat,
2322 TRUE /* fHasPointers */);
2326 /************************************************************************
2327 * NdrConformantStringMemorySize [RPCRT4.@]
2329 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2330 PFORMAT_STRING pFormat )
2332 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2334 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2335 ERR("Unhandled string type: %#x\n", pFormat[0]);
2336 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2339 /* allow compiler to optimise inline function by passing constant into
2340 * these functions */
2341 if (pFormat[0] == RPC_FC_C_CSTRING) {
2342 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2343 array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat,
2344 TRUE /* fHasPointers */);
2346 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2347 array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat,
2348 TRUE /* fHasPointers */);
2351 return pStubMsg->MemorySize;
2354 /************************************************************************
2355 * NdrConformantStringUnmarshall [RPCRT4.@]
2357 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2358 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
2360 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2361 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2363 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2364 ERR("Unhandled string type: %#x\n", *pFormat);
2365 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2368 /* allow compiler to optimise inline function by passing constant into
2369 * these functions */
2370 if (pFormat[0] == RPC_FC_C_CSTRING) {
2371 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2372 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory,
2373 pFormat, fMustAlloc,
2374 TRUE /* fUseBufferMemoryServer */,
2375 TRUE /* fUnmarshall */);
2377 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2378 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory,
2379 pFormat, fMustAlloc,
2380 TRUE /* fUseBufferMemoryServer */,
2381 TRUE /* fUnmarshall */);
2387 /***********************************************************************
2388 * NdrNonConformantStringMarshall [RPCRT4.@]
2390 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2391 unsigned char *pMemory,
2392 PFORMAT_STRING pFormat)
2394 ULONG esize, size, maxsize;
2396 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2398 maxsize = *(USHORT *)&pFormat[2];
2400 if (*pFormat == RPC_FC_CSTRING)
2403 const char *str = (const char *)pMemory;
2404 for (i = 0; i < maxsize && *str; i++, str++)
2406 TRACE("string=%s\n", debugstr_an(str, i));
2407 pStubMsg->ActualCount = i + 1;
2410 else if (*pFormat == RPC_FC_WSTRING)
2413 const WCHAR *str = (const WCHAR *)pMemory;
2414 for (i = 0; i < maxsize && *str; i++, str++)
2416 TRACE("string=%s\n", debugstr_wn(str, i));
2417 pStubMsg->ActualCount = i + 1;
2422 ERR("Unhandled string type: %#x\n", *pFormat);
2423 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2426 pStubMsg->Offset = 0;
2427 WriteVariance(pStubMsg);
2429 size = safe_multiply(esize, pStubMsg->ActualCount);
2430 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2435 /***********************************************************************
2436 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2438 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2439 unsigned char **ppMemory,
2440 PFORMAT_STRING pFormat,
2441 unsigned char fMustAlloc)
2443 ULONG bufsize, memsize, esize, maxsize;
2445 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2446 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2448 maxsize = *(USHORT *)&pFormat[2];
2450 ReadVariance(pStubMsg, NULL, maxsize);
2451 if (pStubMsg->Offset)
2453 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2454 RpcRaiseException(RPC_S_INVALID_BOUND);
2457 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2458 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2461 ERR("Unhandled string type: %#x\n", *pFormat);
2462 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2465 memsize = esize * maxsize;
2466 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2468 validate_string_data(pStubMsg, bufsize, esize);
2470 if (!fMustAlloc && !*ppMemory)
2473 *ppMemory = NdrAllocate(pStubMsg, memsize);
2475 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2477 if (*pFormat == RPC_FC_CSTRING) {
2478 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
2480 else if (*pFormat == RPC_FC_WSTRING) {
2481 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
2487 /***********************************************************************
2488 * NdrNonConformantStringBufferSize [RPCRT4.@]
2490 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2491 unsigned char *pMemory,
2492 PFORMAT_STRING pFormat)
2494 ULONG esize, maxsize;
2496 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2498 maxsize = *(USHORT *)&pFormat[2];
2500 SizeVariance(pStubMsg);
2502 if (*pFormat == RPC_FC_CSTRING)
2505 const char *str = (const char *)pMemory;
2506 for (i = 0; i < maxsize && *str; i++, str++)
2508 TRACE("string=%s\n", debugstr_an(str, i));
2509 pStubMsg->ActualCount = i + 1;
2512 else if (*pFormat == RPC_FC_WSTRING)
2515 const WCHAR *str = (const WCHAR *)pMemory;
2516 for (i = 0; i < maxsize && *str; i++, str++)
2518 TRACE("string=%s\n", debugstr_wn(str, i));
2519 pStubMsg->ActualCount = i + 1;
2524 ERR("Unhandled string type: %#x\n", *pFormat);
2525 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2528 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2531 /***********************************************************************
2532 * NdrNonConformantStringMemorySize [RPCRT4.@]
2534 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2535 PFORMAT_STRING pFormat)
2537 ULONG bufsize, memsize, esize, maxsize;
2539 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2541 maxsize = *(USHORT *)&pFormat[2];
2543 ReadVariance(pStubMsg, NULL, maxsize);
2545 if (pStubMsg->Offset)
2547 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2548 RpcRaiseException(RPC_S_INVALID_BOUND);
2551 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2552 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2555 ERR("Unhandled string type: %#x\n", *pFormat);
2556 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2559 memsize = esize * maxsize;
2560 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2562 validate_string_data(pStubMsg, bufsize, esize);
2564 safe_buffer_increment(pStubMsg, bufsize);
2565 pStubMsg->MemorySize += memsize;
2567 return pStubMsg->MemorySize;
2572 #include "pshpack1.h"
2576 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2580 #include "poppack.h"
2582 static ULONG EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2583 PFORMAT_STRING pFormat)
2587 case RPC_FC_PSTRUCT:
2588 case RPC_FC_CSTRUCT:
2589 case RPC_FC_BOGUS_STRUCT:
2590 case RPC_FC_SMFARRAY:
2591 case RPC_FC_SMVARRAY:
2592 case RPC_FC_CSTRING:
2593 return *(const WORD*)&pFormat[2];
2594 case RPC_FC_USER_MARSHAL:
2595 return *(const WORD*)&pFormat[4];
2596 case RPC_FC_RANGE: {
2597 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2602 return sizeof(UCHAR);
2606 return sizeof(USHORT);
2610 return sizeof(ULONG);
2612 return sizeof(float);
2614 return sizeof(double);
2616 return sizeof(ULONGLONG);
2618 return sizeof(UINT);
2620 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2621 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2624 case RPC_FC_NON_ENCAPSULATED_UNION:
2626 if (pStubMsg->fHasNewCorrDesc)
2631 pFormat += *(const SHORT*)pFormat;
2632 return *(const SHORT*)pFormat;
2634 return sizeof(void *);
2635 case RPC_FC_WSTRING:
2636 return *(const WORD*)&pFormat[2] * 2;
2638 FIXME("unhandled embedded type %02x\n", *pFormat);
2644 static ULONG EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2645 PFORMAT_STRING pFormat)
2647 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2651 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2655 return m(pStubMsg, pFormat);
2659 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2660 unsigned char *pMemory,
2661 PFORMAT_STRING pFormat,
2662 PFORMAT_STRING pPointer)
2664 PFORMAT_STRING desc;
2668 while (*pFormat != RPC_FC_END) {
2674 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2675 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2681 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2682 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2686 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2687 if (32767 < *(DWORD*)pMemory)
2688 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2689 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2695 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2696 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2700 TRACE("float=%f <= %p\n", *(float*)pMemory, pMemory);
2701 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
2702 pMemory += sizeof(float);
2705 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2706 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2710 TRACE("double=%f <= %p\n", *(double*)pMemory, pMemory);
2711 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
2712 pMemory += sizeof(double);
2718 case RPC_FC_POINTER:
2720 unsigned char *saved_buffer;
2721 int pointer_buffer_mark_set = 0;
2722 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2723 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2724 if (*pFormat != RPC_FC_POINTER)
2726 if (*pPointer != RPC_FC_RP)
2727 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
2728 saved_buffer = pStubMsg->Buffer;
2729 if (pStubMsg->PointerBufferMark)
2731 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2732 pStubMsg->PointerBufferMark = NULL;
2733 pointer_buffer_mark_set = 1;
2735 else if (*pPointer != RPC_FC_RP)
2736 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2737 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2738 if (pointer_buffer_mark_set)
2740 STD_OVERFLOW_CHECK(pStubMsg);
2741 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2742 pStubMsg->Buffer = saved_buffer;
2743 if (*pPointer != RPC_FC_RP)
2744 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2746 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2747 if (*pFormat == RPC_FC_POINTER)
2751 pMemory += sizeof(void *);
2754 case RPC_FC_ALIGNM2:
2755 ALIGN_POINTER(pMemory, 2);
2757 case RPC_FC_ALIGNM4:
2758 ALIGN_POINTER(pMemory, 4);
2760 case RPC_FC_ALIGNM8:
2761 ALIGN_POINTER(pMemory, 8);
2763 case RPC_FC_STRUCTPAD1:
2764 case RPC_FC_STRUCTPAD2:
2765 case RPC_FC_STRUCTPAD3:
2766 case RPC_FC_STRUCTPAD4:
2767 case RPC_FC_STRUCTPAD5:
2768 case RPC_FC_STRUCTPAD6:
2769 case RPC_FC_STRUCTPAD7:
2770 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2772 case RPC_FC_EMBEDDED_COMPLEX:
2773 pMemory += pFormat[1];
2775 desc = pFormat + *(const SHORT*)pFormat;
2776 size = EmbeddedComplexSize(pStubMsg, desc);
2777 TRACE("embedded complex (size=%d) <= %p\n", size, pMemory);
2778 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2781 /* for some reason interface pointers aren't generated as
2782 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2783 * they still need the derefencing treatment that pointers are
2785 if (*desc == RPC_FC_IP)
2786 m(pStubMsg, *(unsigned char **)pMemory, desc);
2788 m(pStubMsg, pMemory, desc);
2790 else FIXME("no marshaller for embedded type %02x\n", *desc);
2797 FIXME("unhandled format 0x%02x\n", *pFormat);
2805 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2806 unsigned char *pMemory,
2807 PFORMAT_STRING pFormat,
2808 PFORMAT_STRING pPointer,
2809 unsigned char fMustAlloc)
2811 PFORMAT_STRING desc;
2815 while (*pFormat != RPC_FC_END) {
2821 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2822 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2828 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2829 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2833 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2834 *(DWORD*)pMemory &= 0xffff;
2835 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
2836 if (32767 < *(DWORD*)pMemory)
2837 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2843 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2844 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2848 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(float));
2849 TRACE("float=%f => %p\n", *(float*)pMemory, pMemory);
2850 pMemory += sizeof(float);
2853 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2854 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2858 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(double));
2859 TRACE("double=%f => %p\n", *(double*)pMemory, pMemory);
2860 pMemory += sizeof(double);
2866 case RPC_FC_POINTER:
2868 unsigned char *saved_buffer;
2869 int pointer_buffer_mark_set = 0;
2870 TRACE("pointer => %p\n", pMemory);
2871 if (*pFormat != RPC_FC_POINTER)
2873 if (*pPointer != RPC_FC_RP)
2874 ALIGN_POINTER(pStubMsg->Buffer, 4);
2875 saved_buffer = pStubMsg->Buffer;
2876 if (pStubMsg->PointerBufferMark)
2878 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2879 pStubMsg->PointerBufferMark = NULL;
2880 pointer_buffer_mark_set = 1;
2882 else if (*pPointer != RPC_FC_RP)
2883 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2885 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
2886 if (pointer_buffer_mark_set)
2888 STD_OVERFLOW_CHECK(pStubMsg);
2889 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2890 pStubMsg->Buffer = saved_buffer;
2891 if (*pPointer != RPC_FC_RP)
2892 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2894 if (*pFormat == RPC_FC_POINTER)
2898 pMemory += sizeof(void *);
2901 case RPC_FC_ALIGNM2:
2902 ALIGN_POINTER_CLEAR(pMemory, 2);
2904 case RPC_FC_ALIGNM4:
2905 ALIGN_POINTER_CLEAR(pMemory, 4);
2907 case RPC_FC_ALIGNM8:
2908 ALIGN_POINTER_CLEAR(pMemory, 8);
2910 case RPC_FC_STRUCTPAD1:
2911 case RPC_FC_STRUCTPAD2:
2912 case RPC_FC_STRUCTPAD3:
2913 case RPC_FC_STRUCTPAD4:
2914 case RPC_FC_STRUCTPAD5:
2915 case RPC_FC_STRUCTPAD6:
2916 case RPC_FC_STRUCTPAD7:
2917 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2918 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2920 case RPC_FC_EMBEDDED_COMPLEX:
2921 pMemory += pFormat[1];
2923 desc = pFormat + *(const SHORT*)pFormat;
2924 size = EmbeddedComplexSize(pStubMsg, desc);
2925 TRACE("embedded complex (size=%d) => %p\n", size, pMemory);
2927 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
2928 * since the type is part of the memory block that is encompassed by
2929 * the whole complex type. Memory is forced to allocate when pointers
2930 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
2931 * clearing the memory we pass in to the unmarshaller */
2932 memset(pMemory, 0, size);
2933 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2936 /* for some reason interface pointers aren't generated as
2937 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2938 * they still need the derefencing treatment that pointers are
2940 if (*desc == RPC_FC_IP)
2941 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2943 m(pStubMsg, &pMemory, desc, FALSE);
2945 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2952 FIXME("unhandled format %d\n", *pFormat);
2960 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2961 unsigned char *pMemory,
2962 PFORMAT_STRING pFormat,
2963 PFORMAT_STRING pPointer)
2965 PFORMAT_STRING desc;
2969 while (*pFormat != RPC_FC_END) {
2975 safe_buffer_length_increment(pStubMsg, 1);
2981 safe_buffer_length_increment(pStubMsg, 2);
2985 safe_buffer_length_increment(pStubMsg, 2);
2992 safe_buffer_length_increment(pStubMsg, 4);
2997 safe_buffer_length_increment(pStubMsg, 8);
3004 case RPC_FC_POINTER:
3005 if (*pFormat != RPC_FC_POINTER)
3007 if (!pStubMsg->IgnoreEmbeddedPointers)
3009 int saved_buffer_length = pStubMsg->BufferLength;
3010 pStubMsg->BufferLength = pStubMsg->PointerLength;
3011 pStubMsg->PointerLength = 0;
3012 if(!pStubMsg->BufferLength)
3013 ERR("BufferLength == 0??\n");
3014 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
3015 pStubMsg->PointerLength = pStubMsg->BufferLength;
3016 pStubMsg->BufferLength = saved_buffer_length;
3018 if (*pPointer != RPC_FC_RP)
3020 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3021 safe_buffer_length_increment(pStubMsg, 4);
3023 if (*pFormat == RPC_FC_POINTER)
3027 pMemory += sizeof(void*);
3029 case RPC_FC_ALIGNM2:
3030 ALIGN_POINTER(pMemory, 2);
3032 case RPC_FC_ALIGNM4:
3033 ALIGN_POINTER(pMemory, 4);
3035 case RPC_FC_ALIGNM8:
3036 ALIGN_POINTER(pMemory, 8);
3038 case RPC_FC_STRUCTPAD1:
3039 case RPC_FC_STRUCTPAD2:
3040 case RPC_FC_STRUCTPAD3:
3041 case RPC_FC_STRUCTPAD4:
3042 case RPC_FC_STRUCTPAD5:
3043 case RPC_FC_STRUCTPAD6:
3044 case RPC_FC_STRUCTPAD7:
3045 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3047 case RPC_FC_EMBEDDED_COMPLEX:
3048 pMemory += pFormat[1];
3050 desc = pFormat + *(const SHORT*)pFormat;
3051 size = EmbeddedComplexSize(pStubMsg, desc);
3052 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
3055 /* for some reason interface pointers aren't generated as
3056 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3057 * they still need the derefencing treatment that pointers are
3059 if (*desc == RPC_FC_IP)
3060 m(pStubMsg, *(unsigned char **)pMemory, desc);
3062 m(pStubMsg, pMemory, desc);
3064 else FIXME("no buffersizer for embedded type %02x\n", *desc);
3071 FIXME("unhandled format 0x%02x\n", *pFormat);
3079 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
3080 unsigned char *pMemory,
3081 PFORMAT_STRING pFormat,
3082 PFORMAT_STRING pPointer)
3084 PFORMAT_STRING desc;
3088 while (*pFormat != RPC_FC_END) {
3116 case RPC_FC_POINTER:
3117 if (*pFormat != RPC_FC_POINTER)
3119 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3120 if (*pFormat == RPC_FC_POINTER)
3124 pMemory += sizeof(void *);
3126 case RPC_FC_ALIGNM2:
3127 ALIGN_POINTER(pMemory, 2);
3129 case RPC_FC_ALIGNM4:
3130 ALIGN_POINTER(pMemory, 4);
3132 case RPC_FC_ALIGNM8:
3133 ALIGN_POINTER(pMemory, 8);
3135 case RPC_FC_STRUCTPAD1:
3136 case RPC_FC_STRUCTPAD2:
3137 case RPC_FC_STRUCTPAD3:
3138 case RPC_FC_STRUCTPAD4:
3139 case RPC_FC_STRUCTPAD5:
3140 case RPC_FC_STRUCTPAD6:
3141 case RPC_FC_STRUCTPAD7:
3142 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3144 case RPC_FC_EMBEDDED_COMPLEX:
3145 pMemory += pFormat[1];
3147 desc = pFormat + *(const SHORT*)pFormat;
3148 size = EmbeddedComplexSize(pStubMsg, desc);
3149 m = NdrFreer[*desc & NDR_TABLE_MASK];
3152 /* for some reason interface pointers aren't generated as
3153 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3154 * they still need the derefencing treatment that pointers are
3156 if (*desc == RPC_FC_IP)
3157 m(pStubMsg, *(unsigned char **)pMemory, desc);
3159 m(pStubMsg, pMemory, desc);
3167 FIXME("unhandled format 0x%02x\n", *pFormat);
3175 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3176 PFORMAT_STRING pFormat,
3177 PFORMAT_STRING pPointer)
3179 PFORMAT_STRING desc;
3182 while (*pFormat != RPC_FC_END) {
3189 safe_buffer_increment(pStubMsg, 1);
3195 safe_buffer_increment(pStubMsg, 2);
3199 safe_buffer_increment(pStubMsg, 2);
3206 safe_buffer_increment(pStubMsg, 4);
3211 safe_buffer_increment(pStubMsg, 8);
3217 case RPC_FC_POINTER:
3219 unsigned char *saved_buffer;
3220 int pointer_buffer_mark_set = 0;
3221 if (*pFormat != RPC_FC_POINTER)
3223 if (*pPointer != RPC_FC_RP)
3224 ALIGN_POINTER(pStubMsg->Buffer, 4);
3225 saved_buffer = pStubMsg->Buffer;
3226 if (pStubMsg->PointerBufferMark)
3228 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3229 pStubMsg->PointerBufferMark = NULL;
3230 pointer_buffer_mark_set = 1;
3232 else if (*pPointer != RPC_FC_RP)
3233 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3235 if (!pStubMsg->IgnoreEmbeddedPointers)
3236 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3237 if (pointer_buffer_mark_set)
3239 STD_OVERFLOW_CHECK(pStubMsg);
3240 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3241 pStubMsg->Buffer = saved_buffer;
3242 if (*pPointer != RPC_FC_RP)
3243 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3245 if (*pFormat == RPC_FC_POINTER)
3249 size += sizeof(void *);
3252 case RPC_FC_ALIGNM2:
3253 ALIGN_LENGTH(size, 2);
3255 case RPC_FC_ALIGNM4:
3256 ALIGN_LENGTH(size, 4);
3258 case RPC_FC_ALIGNM8:
3259 ALIGN_LENGTH(size, 8);
3261 case RPC_FC_STRUCTPAD1:
3262 case RPC_FC_STRUCTPAD2:
3263 case RPC_FC_STRUCTPAD3:
3264 case RPC_FC_STRUCTPAD4:
3265 case RPC_FC_STRUCTPAD5:
3266 case RPC_FC_STRUCTPAD6:
3267 case RPC_FC_STRUCTPAD7:
3268 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3270 case RPC_FC_EMBEDDED_COMPLEX:
3273 desc = pFormat + *(const SHORT*)pFormat;
3274 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3280 FIXME("unhandled format 0x%02x\n", *pFormat);
3288 ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
3290 PFORMAT_STRING desc;
3293 while (*pFormat != RPC_FC_END) {
3321 case RPC_FC_POINTER:
3322 size += sizeof(void *);
3323 if (*pFormat != RPC_FC_POINTER)
3326 case RPC_FC_ALIGNM2:
3327 ALIGN_LENGTH(size, 2);
3329 case RPC_FC_ALIGNM4:
3330 ALIGN_LENGTH(size, 4);
3332 case RPC_FC_ALIGNM8:
3333 ALIGN_LENGTH(size, 8);
3335 case RPC_FC_STRUCTPAD1:
3336 case RPC_FC_STRUCTPAD2:
3337 case RPC_FC_STRUCTPAD3:
3338 case RPC_FC_STRUCTPAD4:
3339 case RPC_FC_STRUCTPAD5:
3340 case RPC_FC_STRUCTPAD6:
3341 case RPC_FC_STRUCTPAD7:
3342 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3344 case RPC_FC_EMBEDDED_COMPLEX:
3347 desc = pFormat + *(const SHORT*)pFormat;
3348 size += EmbeddedComplexSize(pStubMsg, desc);
3354 FIXME("unhandled format 0x%02x\n", *pFormat);
3362 /***********************************************************************
3363 * NdrComplexStructMarshall [RPCRT4.@]
3365 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3366 unsigned char *pMemory,
3367 PFORMAT_STRING pFormat)
3369 PFORMAT_STRING conf_array = NULL;
3370 PFORMAT_STRING pointer_desc = NULL;
3371 unsigned char *OldMemory = pStubMsg->Memory;
3372 int pointer_buffer_mark_set = 0;
3374 ULONG max_count = 0;
3377 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3379 if (!pStubMsg->PointerBufferMark)
3381 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3382 /* save buffer length */
3383 ULONG saved_buffer_length = pStubMsg->BufferLength;
3385 /* get the buffer pointer after complex array data, but before
3387 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3388 pStubMsg->IgnoreEmbeddedPointers = 1;
3389 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3390 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3392 /* save it for use by embedded pointer code later */
3393 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3394 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - pStubMsg->Buffer));
3395 pointer_buffer_mark_set = 1;
3397 /* restore the original buffer length */
3398 pStubMsg->BufferLength = saved_buffer_length;
3401 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
3404 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3406 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3409 pStubMsg->Memory = pMemory;
3413 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3414 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3415 pMemory + struct_size, conf_array);
3416 /* these could be changed in ComplexMarshall so save them for later */
3417 max_count = pStubMsg->MaxCount;
3418 count = pStubMsg->ActualCount;
3419 offset = pStubMsg->Offset;
3422 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3426 pStubMsg->MaxCount = max_count;
3427 pStubMsg->ActualCount = count;
3428 pStubMsg->Offset = offset;
3429 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3430 conf_array, TRUE /* fHasPointers */);
3433 pStubMsg->Memory = OldMemory;
3435 if (pointer_buffer_mark_set)
3437 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3438 pStubMsg->PointerBufferMark = NULL;
3441 STD_OVERFLOW_CHECK(pStubMsg);
3446 /***********************************************************************
3447 * NdrComplexStructUnmarshall [RPCRT4.@]
3449 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3450 unsigned char **ppMemory,
3451 PFORMAT_STRING pFormat,
3452 unsigned char fMustAlloc)
3454 unsigned size = *(const WORD*)(pFormat+2);
3455 PFORMAT_STRING conf_array = NULL;
3456 PFORMAT_STRING pointer_desc = NULL;
3457 unsigned char *pMemory;
3458 int pointer_buffer_mark_set = 0;
3460 ULONG max_count = 0;
3462 ULONG array_size = 0;
3464 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3466 if (!pStubMsg->PointerBufferMark)
3468 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3469 /* save buffer pointer */
3470 unsigned char *saved_buffer = pStubMsg->Buffer;
3472 /* get the buffer pointer after complex array data, but before
3474 pStubMsg->IgnoreEmbeddedPointers = 1;
3475 NdrComplexStructMemorySize(pStubMsg, pFormat);
3476 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3478 /* save it for use by embedded pointer code later */
3479 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3480 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - saved_buffer));
3481 pointer_buffer_mark_set = 1;
3483 /* restore the original buffer */
3484 pStubMsg->Buffer = saved_buffer;
3487 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3490 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3492 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3497 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3500 /* these could be changed in ComplexMarshall so save them for later */
3501 max_count = pStubMsg->MaxCount;
3502 count = pStubMsg->ActualCount;
3503 offset = pStubMsg->Offset;
3506 if (!fMustAlloc && !*ppMemory)
3509 *ppMemory = NdrAllocate(pStubMsg, size);
3511 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3515 pStubMsg->MaxCount = max_count;
3516 pStubMsg->ActualCount = count;
3517 pStubMsg->Offset = offset;
3519 memset(pMemory, 0, array_size);
3520 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3522 FALSE /* fUseBufferMemoryServer */,
3523 TRUE /* fUnmarshall */);
3526 if (pointer_buffer_mark_set)
3528 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3529 pStubMsg->PointerBufferMark = NULL;
3535 /***********************************************************************
3536 * NdrComplexStructBufferSize [RPCRT4.@]
3538 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3539 unsigned char *pMemory,
3540 PFORMAT_STRING pFormat)
3542 PFORMAT_STRING conf_array = NULL;
3543 PFORMAT_STRING pointer_desc = NULL;
3544 unsigned char *OldMemory = pStubMsg->Memory;
3545 int pointer_length_set = 0;
3547 ULONG max_count = 0;
3550 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3552 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
3554 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3556 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3557 ULONG saved_buffer_length = pStubMsg->BufferLength;
3559 /* get the buffer length after complex struct data, but before
3561 pStubMsg->IgnoreEmbeddedPointers = 1;
3562 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3563 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3565 /* save it for use by embedded pointer code later */
3566 pStubMsg->PointerLength = pStubMsg->BufferLength;
3567 pointer_length_set = 1;
3568 TRACE("difference = 0x%x\n", pStubMsg->PointerLength - saved_buffer_length);
3570 /* restore the original buffer length */
3571 pStubMsg->BufferLength = saved_buffer_length;
3575 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3577 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3580 pStubMsg->Memory = pMemory;
3584 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3585 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3588 /* these could be changed in ComplexMarshall so save them for later */
3589 max_count = pStubMsg->MaxCount;
3590 count = pStubMsg->ActualCount;
3591 offset = pStubMsg->Offset;
3594 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3598 pStubMsg->MaxCount = max_count;
3599 pStubMsg->ActualCount = count;
3600 pStubMsg->Offset = offset;
3601 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3602 TRUE /* fHasPointers */);
3605 pStubMsg->Memory = OldMemory;
3607 if(pointer_length_set)
3609 pStubMsg->BufferLength = pStubMsg->PointerLength;
3610 pStubMsg->PointerLength = 0;
3615 /***********************************************************************
3616 * NdrComplexStructMemorySize [RPCRT4.@]
3618 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3619 PFORMAT_STRING pFormat)
3621 unsigned size = *(const WORD*)(pFormat+2);
3622 PFORMAT_STRING conf_array = NULL;
3623 PFORMAT_STRING pointer_desc = NULL;
3625 ULONG max_count = 0;
3628 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3630 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3633 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3635 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3640 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3642 /* these could be changed in ComplexStructMemorySize so save them for
3644 max_count = pStubMsg->MaxCount;
3645 count = pStubMsg->ActualCount;
3646 offset = pStubMsg->Offset;
3649 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3653 pStubMsg->MaxCount = max_count;
3654 pStubMsg->ActualCount = count;
3655 pStubMsg->Offset = offset;
3656 array_memory_size(conf_array[0], pStubMsg, conf_array,
3657 TRUE /* fHasPointers */);
3663 /***********************************************************************
3664 * NdrComplexStructFree [RPCRT4.@]
3666 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3667 unsigned char *pMemory,
3668 PFORMAT_STRING pFormat)
3670 PFORMAT_STRING conf_array = NULL;
3671 PFORMAT_STRING pointer_desc = NULL;
3672 unsigned char *OldMemory = pStubMsg->Memory;
3674 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3677 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3679 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3682 pStubMsg->Memory = pMemory;
3684 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3687 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3688 TRUE /* fHasPointers */);
3690 pStubMsg->Memory = OldMemory;
3693 /***********************************************************************
3694 * NdrConformantArrayMarshall [RPCRT4.@]
3696 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3697 unsigned char *pMemory,
3698 PFORMAT_STRING pFormat)
3700 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3701 if (pFormat[0] != RPC_FC_CARRAY)
3703 ERR("invalid format = 0x%x\n", pFormat[0]);
3704 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3707 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory,
3709 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3710 TRUE /* fHasPointers */);
3715 /***********************************************************************
3716 * NdrConformantArrayUnmarshall [RPCRT4.@]
3718 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3719 unsigned char **ppMemory,
3720 PFORMAT_STRING pFormat,
3721 unsigned char fMustAlloc)
3723 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3724 if (pFormat[0] != RPC_FC_CARRAY)
3726 ERR("invalid format = 0x%x\n", pFormat[0]);
3727 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3730 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3731 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat,
3733 TRUE /* fUseBufferMemoryServer */,
3734 TRUE /* fUnmarshall */);
3739 /***********************************************************************
3740 * NdrConformantArrayBufferSize [RPCRT4.@]
3742 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3743 unsigned char *pMemory,
3744 PFORMAT_STRING pFormat)
3746 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3747 if (pFormat[0] != RPC_FC_CARRAY)
3749 ERR("invalid format = 0x%x\n", pFormat[0]);
3750 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3753 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat);
3754 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3755 TRUE /* fHasPointers */);
3758 /***********************************************************************
3759 * NdrConformantArrayMemorySize [RPCRT4.@]
3761 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3762 PFORMAT_STRING pFormat)
3764 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3765 if (pFormat[0] != RPC_FC_CARRAY)
3767 ERR("invalid format = 0x%x\n", pFormat[0]);
3768 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3771 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3772 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
3774 return pStubMsg->MemorySize;
3777 /***********************************************************************
3778 * NdrConformantArrayFree [RPCRT4.@]
3780 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3781 unsigned char *pMemory,
3782 PFORMAT_STRING pFormat)
3784 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3785 if (pFormat[0] != RPC_FC_CARRAY)
3787 ERR("invalid format = 0x%x\n", pFormat[0]);
3788 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3791 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3792 TRUE /* fHasPointers */);
3796 /***********************************************************************
3797 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3799 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
3800 unsigned char* pMemory,
3801 PFORMAT_STRING pFormat )
3803 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3805 if (pFormat[0] != RPC_FC_CVARRAY)
3807 ERR("invalid format type %x\n", pFormat[0]);
3808 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3812 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3814 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory,
3815 pFormat, TRUE /* fHasPointers */);
3821 /***********************************************************************
3822 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3824 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
3825 unsigned char** ppMemory,
3826 PFORMAT_STRING pFormat,
3827 unsigned char fMustAlloc )
3829 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3831 if (pFormat[0] != RPC_FC_CVARRAY)
3833 ERR("invalid format type %x\n", pFormat[0]);
3834 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3838 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3839 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory,
3840 pFormat, fMustAlloc,
3841 TRUE /* fUseBufferMemoryServer */,
3842 TRUE /* fUnmarshall */);
3848 /***********************************************************************
3849 * NdrConformantVaryingArrayFree [RPCRT4.@]
3851 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
3852 unsigned char* pMemory,
3853 PFORMAT_STRING pFormat )
3855 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3857 if (pFormat[0] != RPC_FC_CVARRAY)
3859 ERR("invalid format type %x\n", pFormat[0]);
3860 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3864 array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3865 TRUE /* fHasPointers */);
3869 /***********************************************************************
3870 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3872 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
3873 unsigned char* pMemory, PFORMAT_STRING pFormat )
3875 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3877 if (pFormat[0] != RPC_FC_CVARRAY)
3879 ERR("invalid format type %x\n", pFormat[0]);
3880 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3884 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3886 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3887 TRUE /* fHasPointers */);
3891 /***********************************************************************
3892 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3894 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
3895 PFORMAT_STRING pFormat )
3897 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3899 if (pFormat[0] != RPC_FC_CVARRAY)
3901 ERR("invalid format type %x\n", pFormat[0]);
3902 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3903 return pStubMsg->MemorySize;
3906 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3907 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat,
3908 TRUE /* fHasPointers */);
3910 return pStubMsg->MemorySize;
3914 /***********************************************************************
3915 * NdrComplexArrayMarshall [RPCRT4.@]
3917 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3918 unsigned char *pMemory,
3919 PFORMAT_STRING pFormat)
3921 ULONG i, count, def;
3922 BOOL variance_present;
3923 unsigned char alignment;
3924 int pointer_buffer_mark_set = 0;
3926 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3928 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3930 ERR("invalid format type %x\n", pFormat[0]);
3931 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3935 alignment = pFormat[1] + 1;
3937 if (!pStubMsg->PointerBufferMark)
3939 /* save buffer fields that may be changed by buffer sizer functions
3940 * and that may be needed later on */
3941 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3942 ULONG saved_buffer_length = pStubMsg->BufferLength;
3943 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
3944 ULONG saved_offset = pStubMsg->Offset;
3945 ULONG saved_actual_count = pStubMsg->ActualCount;
3947 /* get the buffer pointer after complex array data, but before
3949 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3950 pStubMsg->IgnoreEmbeddedPointers = 1;
3951 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3952 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3954 /* save it for use by embedded pointer code later */
3955 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3956 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer));
3957 pointer_buffer_mark_set = 1;
3959 /* restore fields */
3960 pStubMsg->ActualCount = saved_actual_count;
3961 pStubMsg->Offset = saved_offset;
3962 pStubMsg->MaxCount = saved_max_count;
3963 pStubMsg->BufferLength = saved_buffer_length;
3966 def = *(const WORD*)&pFormat[2];
3969 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3970 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3972 variance_present = IsConformanceOrVariancePresent(pFormat);
3973 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3974 TRACE("variance = %d\n", pStubMsg->ActualCount);
3976 WriteConformance(pStubMsg);
3977 if (variance_present)
3978 WriteVariance(pStubMsg);
3980 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3982 count = pStubMsg->ActualCount;
3983 for (i = 0; i < count; i++)
3984 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3986 STD_OVERFLOW_CHECK(pStubMsg);
3988 if (pointer_buffer_mark_set)
3990 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3991 pStubMsg->PointerBufferMark = NULL;
3997 /***********************************************************************
3998 * NdrComplexArrayUnmarshall [RPCRT4.@]
4000 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4001 unsigned char **ppMemory,
4002 PFORMAT_STRING pFormat,
4003 unsigned char fMustAlloc)
4005 ULONG i, count, size;
4006 unsigned char alignment;
4007 unsigned char *pMemory;
4008 unsigned char *saved_buffer;
4009 int pointer_buffer_mark_set = 0;
4010 int saved_ignore_embedded;
4012 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4014 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4016 ERR("invalid format type %x\n", pFormat[0]);
4017 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4021 alignment = pFormat[1] + 1;
4023 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4024 /* save buffer pointer */
4025 saved_buffer = pStubMsg->Buffer;
4026 /* get the buffer pointer after complex array data, but before
4028 pStubMsg->IgnoreEmbeddedPointers = 1;
4029 pStubMsg->MemorySize = 0;
4030 NdrComplexArrayMemorySize(pStubMsg, pFormat);
4031 size = pStubMsg->MemorySize;
4032 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4034 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - saved_buffer));
4035 if (!pStubMsg->PointerBufferMark)
4037 /* save it for use by embedded pointer code later */
4038 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4039 pointer_buffer_mark_set = 1;
4041 /* restore the original buffer */
4042 pStubMsg->Buffer = saved_buffer;
4046 pFormat = ReadConformance(pStubMsg, pFormat);
4047 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
4049 if (!fMustAlloc && !*ppMemory)
4052 *ppMemory = NdrAllocate(pStubMsg, size);
4054 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4056 pMemory = *ppMemory;
4057 count = pStubMsg->ActualCount;
4058 for (i = 0; i < count; i++)
4059 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
4061 if (pointer_buffer_mark_set)
4063 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4064 pStubMsg->PointerBufferMark = NULL;
4070 /***********************************************************************
4071 * NdrComplexArrayBufferSize [RPCRT4.@]
4073 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4074 unsigned char *pMemory,
4075 PFORMAT_STRING pFormat)
4077 ULONG i, count, def;
4078 unsigned char alignment;
4079 BOOL variance_present;
4080 int pointer_length_set = 0;
4082 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4084 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4086 ERR("invalid format type %x\n", pFormat[0]);
4087 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4091 alignment = pFormat[1] + 1;
4093 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
4095 /* save buffer fields that may be changed by buffer sizer functions
4096 * and that may be needed later on */
4097 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4098 ULONG saved_buffer_length = pStubMsg->BufferLength;
4099 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4100 ULONG saved_offset = pStubMsg->Offset;
4101 ULONG saved_actual_count = pStubMsg->ActualCount;
4103 /* get the buffer pointer after complex array data, but before
4105 pStubMsg->IgnoreEmbeddedPointers = 1;
4106 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4107 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4109 /* save it for use by embedded pointer code later */
4110 pStubMsg->PointerLength = pStubMsg->BufferLength;
4111 pointer_length_set = 1;
4113 /* restore fields */
4114 pStubMsg->ActualCount = saved_actual_count;
4115 pStubMsg->Offset = saved_offset;
4116 pStubMsg->MaxCount = saved_max_count;
4117 pStubMsg->BufferLength = saved_buffer_length;
4119 def = *(const WORD*)&pFormat[2];
4122 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4123 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4124 SizeConformance(pStubMsg);
4126 variance_present = IsConformanceOrVariancePresent(pFormat);
4127 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4128 TRACE("variance = %d\n", pStubMsg->ActualCount);
4130 if (variance_present)
4131 SizeVariance(pStubMsg);
4133 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4135 count = pStubMsg->ActualCount;
4136 for (i = 0; i < count; i++)
4137 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
4139 if(pointer_length_set)
4141 pStubMsg->BufferLength = pStubMsg->PointerLength;
4142 pStubMsg->PointerLength = 0;
4146 /***********************************************************************
4147 * NdrComplexArrayMemorySize [RPCRT4.@]
4149 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4150 PFORMAT_STRING pFormat)
4152 ULONG i, count, esize, SavedMemorySize, MemorySize;
4153 unsigned char alignment;
4155 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4157 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4159 ERR("invalid format type %x\n", pFormat[0]);
4160 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4164 alignment = pFormat[1] + 1;
4168 pFormat = ReadConformance(pStubMsg, pFormat);
4169 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
4171 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4173 SavedMemorySize = pStubMsg->MemorySize;
4175 esize = ComplexStructSize(pStubMsg, pFormat);
4177 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
4179 count = pStubMsg->ActualCount;
4180 for (i = 0; i < count; i++)
4181 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
4183 pStubMsg->MemorySize = SavedMemorySize;
4185 pStubMsg->MemorySize += MemorySize;
4189 /***********************************************************************
4190 * NdrComplexArrayFree [RPCRT4.@]
4192 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4193 unsigned char *pMemory,
4194 PFORMAT_STRING pFormat)
4196 ULONG i, count, def;
4198 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4200 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4202 ERR("invalid format type %x\n", pFormat[0]);
4203 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4207 def = *(const WORD*)&pFormat[2];
4210 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4211 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4213 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4214 TRACE("variance = %d\n", pStubMsg->ActualCount);
4216 count = pStubMsg->ActualCount;
4217 for (i = 0; i < count; i++)
4218 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4221 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4222 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4223 USER_MARSHAL_CB *umcb)
4225 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4226 pStubMsg->RpcMsg->DataRepresentation);
4227 umcb->pStubMsg = pStubMsg;
4228 umcb->pReserve = NULL;
4229 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4230 umcb->CBType = cbtype;
4231 umcb->pFormat = pFormat;
4232 umcb->pTypeFormat = NULL /* FIXME */;
4235 #define USER_MARSHAL_PTR_PREFIX \
4236 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4237 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4239 /***********************************************************************
4240 * NdrUserMarshalMarshall [RPCRT4.@]
4242 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4243 unsigned char *pMemory,
4244 PFORMAT_STRING pFormat)
4246 unsigned flags = pFormat[1];
4247 unsigned index = *(const WORD*)&pFormat[2];
4248 unsigned char *saved_buffer = NULL;
4249 USER_MARSHAL_CB umcb;
4251 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4252 TRACE("index=%d\n", index);
4254 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4256 if (flags & USER_MARSHAL_POINTER)
4258 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
4259 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4260 pStubMsg->Buffer += 4;
4261 if (pStubMsg->PointerBufferMark)
4263 saved_buffer = pStubMsg->Buffer;
4264 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4265 pStubMsg->PointerBufferMark = NULL;
4267 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
4270 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
4273 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4274 &umcb.Flags, pStubMsg->Buffer, pMemory);
4278 STD_OVERFLOW_CHECK(pStubMsg);
4279 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4280 pStubMsg->Buffer = saved_buffer;
4283 STD_OVERFLOW_CHECK(pStubMsg);
4288 /***********************************************************************
4289 * NdrUserMarshalUnmarshall [RPCRT4.@]
4291 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4292 unsigned char **ppMemory,
4293 PFORMAT_STRING pFormat,
4294 unsigned char fMustAlloc)
4296 unsigned flags = pFormat[1];
4297 unsigned index = *(const WORD*)&pFormat[2];
4298 DWORD memsize = *(const WORD*)&pFormat[4];
4299 unsigned char *saved_buffer = NULL;
4300 USER_MARSHAL_CB umcb;
4302 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4303 TRACE("index=%d\n", index);
4305 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4307 if (flags & USER_MARSHAL_POINTER)
4309 ALIGN_POINTER(pStubMsg->Buffer, 4);
4310 /* skip pointer prefix */
4311 pStubMsg->Buffer += 4;
4312 if (pStubMsg->PointerBufferMark)
4314 saved_buffer = pStubMsg->Buffer;
4315 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4316 pStubMsg->PointerBufferMark = NULL;
4318 ALIGN_POINTER(pStubMsg->Buffer, 8);
4321 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4323 if (!fMustAlloc && !*ppMemory)
4327 *ppMemory = NdrAllocate(pStubMsg, memsize);
4328 memset(*ppMemory, 0, memsize);
4332 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4333 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4337 STD_OVERFLOW_CHECK(pStubMsg);
4338 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4339 pStubMsg->Buffer = saved_buffer;
4345 /***********************************************************************
4346 * NdrUserMarshalBufferSize [RPCRT4.@]
4348 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4349 unsigned char *pMemory,
4350 PFORMAT_STRING pFormat)
4352 unsigned flags = pFormat[1];
4353 unsigned index = *(const WORD*)&pFormat[2];
4354 DWORD bufsize = *(const WORD*)&pFormat[6];
4355 USER_MARSHAL_CB umcb;
4356 ULONG saved_buffer_length = 0;
4358 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4359 TRACE("index=%d\n", index);
4361 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4363 if (flags & USER_MARSHAL_POINTER)
4365 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4366 /* skip pointer prefix */
4367 safe_buffer_length_increment(pStubMsg, 4);
4368 if (pStubMsg->IgnoreEmbeddedPointers)
4370 if (pStubMsg->PointerLength)
4372 saved_buffer_length = pStubMsg->BufferLength;
4373 pStubMsg->BufferLength = pStubMsg->PointerLength;
4374 pStubMsg->PointerLength = 0;
4376 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
4379 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
4382 TRACE("size=%d\n", bufsize);
4383 safe_buffer_length_increment(pStubMsg, bufsize);
4386 pStubMsg->BufferLength =
4387 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4388 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4390 if (saved_buffer_length)
4392 pStubMsg->PointerLength = pStubMsg->BufferLength;
4393 pStubMsg->BufferLength = saved_buffer_length;
4398 /***********************************************************************
4399 * NdrUserMarshalMemorySize [RPCRT4.@]
4401 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4402 PFORMAT_STRING pFormat)
4404 unsigned flags = pFormat[1];
4405 unsigned index = *(const WORD*)&pFormat[2];
4406 DWORD memsize = *(const WORD*)&pFormat[4];
4407 DWORD bufsize = *(const WORD*)&pFormat[6];
4409 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4410 TRACE("index=%d\n", index);
4412 pStubMsg->MemorySize += memsize;
4414 if (flags & USER_MARSHAL_POINTER)
4416 ALIGN_POINTER(pStubMsg->Buffer, 4);
4417 /* skip pointer prefix */
4418 pStubMsg->Buffer += 4;
4419 if (pStubMsg->IgnoreEmbeddedPointers)
4420 return pStubMsg->MemorySize;
4421 ALIGN_POINTER(pStubMsg->Buffer, 8);
4424 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4427 FIXME("not implemented for varying buffer size\n");
4429 pStubMsg->Buffer += bufsize;
4431 return pStubMsg->MemorySize;
4434 /***********************************************************************
4435 * NdrUserMarshalFree [RPCRT4.@]
4437 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4438 unsigned char *pMemory,
4439 PFORMAT_STRING pFormat)
4441 /* unsigned flags = pFormat[1]; */
4442 unsigned index = *(const WORD*)&pFormat[2];
4443 USER_MARSHAL_CB umcb;
4445 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4446 TRACE("index=%d\n", index);
4448 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4450 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4451 &umcb.Flags, pMemory);
4454 /***********************************************************************
4455 * NdrGetUserMarshalInfo [RPCRT4.@]
4457 RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi)
4459 USER_MARSHAL_CB *umcb = CONTAINING_RECORD(flags, USER_MARSHAL_CB, Flags);
4461 TRACE("(%p,%u,%p)\n", flags, level, umi);
4464 return RPC_S_INVALID_ARG;
4466 memset(&umi->u1.Level1, 0, sizeof(umi->u1.Level1));
4467 umi->InformationLevel = level;
4469 if (umcb->Signature != USER_MARSHAL_CB_SIGNATURE)
4470 return RPC_S_INVALID_ARG;
4472 umi->u1.Level1.pfnAllocate = umcb->pStubMsg->pfnAllocate;
4473 umi->u1.Level1.pfnFree = umcb->pStubMsg->pfnFree;
4474 umi->u1.Level1.pRpcChannelBuffer = umcb->pStubMsg->pRpcChannelBuffer;
4476 switch (umcb->CBType)
4478 case USER_MARSHAL_CB_MARSHALL:
4479 case USER_MARSHAL_CB_UNMARSHALL:
4481 RPC_MESSAGE *msg = umcb->pStubMsg->RpcMsg;
4482 unsigned char *buffer_start = msg->Buffer;
4483 unsigned char *buffer_end =
4484 (unsigned char *)msg->Buffer + msg->BufferLength;
4486 if (umcb->pStubMsg->Buffer < buffer_start ||
4487 umcb->pStubMsg->Buffer > buffer_end)
4488 return ERROR_INVALID_USER_BUFFER;
4490 umi->u1.Level1.Buffer = umcb->pStubMsg->Buffer;
4491 umi->u1.Level1.BufferSize = buffer_end - umcb->pStubMsg->Buffer;
4494 case USER_MARSHAL_CB_BUFFER_SIZE:
4495 case USER_MARSHAL_CB_FREE:
4498 WARN("unrecognised CBType %d\n", umcb->CBType);
4504 /***********************************************************************
4505 * NdrClearOutParameters [RPCRT4.@]
4507 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4508 PFORMAT_STRING pFormat,
4511 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4514 /***********************************************************************
4515 * NdrConvert [RPCRT4.@]
4517 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4519 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4520 /* FIXME: since this stub doesn't do any converting, the proper behavior
4521 is to raise an exception */
4524 /***********************************************************************
4525 * NdrConvert2 [RPCRT4.@]
4527 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4529 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4530 pStubMsg, pFormat, NumberParams);
4531 /* FIXME: since this stub doesn't do any converting, the proper behavior
4532 is to raise an exception */
4535 #include "pshpack1.h"
4536 typedef struct _NDR_CSTRUCT_FORMAT
4539 unsigned char alignment;
4540 unsigned short memory_size;
4541 short offset_to_array_description;
4542 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4543 #include "poppack.h"
4545 /***********************************************************************
4546 * NdrConformantStructMarshall [RPCRT4.@]
4548 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4549 unsigned char *pMemory,
4550 PFORMAT_STRING pFormat)
4552 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4553 PFORMAT_STRING pCArrayFormat;
4554 ULONG esize, bufsize;
4556 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4558 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4559 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4561 ERR("invalid format type %x\n", pCStructFormat->type);
4562 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4566 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4567 pCStructFormat->offset_to_array_description;
4568 if (*pCArrayFormat != RPC_FC_CARRAY)
4570 ERR("invalid array format type %x\n", pCStructFormat->type);
4571 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4574 esize = *(const WORD*)(pCArrayFormat+2);
4576 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4577 pCArrayFormat + 4, 0);
4579 WriteConformance(pStubMsg);
4581 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4583 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4585 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4586 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4588 ERR("integer overflow of memory_size %u with bufsize %u\n",
4589 pCStructFormat->memory_size, bufsize);
4590 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4592 /* copy constant sized part of struct */
4593 pStubMsg->BufferMark = pStubMsg->Buffer;
4594 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4596 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4597 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4602 /***********************************************************************
4603 * NdrConformantStructUnmarshall [RPCRT4.@]
4605 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4606 unsigned char **ppMemory,
4607 PFORMAT_STRING pFormat,
4608 unsigned char fMustAlloc)
4610 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4611 PFORMAT_STRING pCArrayFormat;
4612 ULONG esize, bufsize;
4613 unsigned char *saved_buffer;
4615 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4617 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4618 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4620 ERR("invalid format type %x\n", pCStructFormat->type);
4621 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4624 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4625 pCStructFormat->offset_to_array_description;
4626 if (*pCArrayFormat != RPC_FC_CARRAY)
4628 ERR("invalid array format type %x\n", pCStructFormat->type);
4629 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4632 esize = *(const WORD*)(pCArrayFormat+2);
4634 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4636 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4638 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4640 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4641 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4643 ERR("integer overflow of memory_size %u with bufsize %u\n",
4644 pCStructFormat->memory_size, bufsize);
4645 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4650 SIZE_T size = pCStructFormat->memory_size + bufsize;
4651 *ppMemory = NdrAllocate(pStubMsg, size);
4655 if (!pStubMsg->IsClient && !*ppMemory)
4656 /* for servers, we just point straight into the RPC buffer */
4657 *ppMemory = pStubMsg->Buffer;
4660 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4661 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4662 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4663 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4665 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4666 if (*ppMemory != saved_buffer)
4667 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4672 /***********************************************************************
4673 * NdrConformantStructBufferSize [RPCRT4.@]
4675 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4676 unsigned char *pMemory,
4677 PFORMAT_STRING pFormat)
4679 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4680 PFORMAT_STRING pCArrayFormat;
4683 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4685 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4686 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4688 ERR("invalid format type %x\n", pCStructFormat->type);
4689 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4692 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4693 pCStructFormat->offset_to_array_description;
4694 if (*pCArrayFormat != RPC_FC_CARRAY)
4696 ERR("invalid array format type %x\n", pCStructFormat->type);
4697 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4700 esize = *(const WORD*)(pCArrayFormat+2);
4702 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4703 SizeConformance(pStubMsg);
4705 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4707 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4709 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4710 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4712 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4713 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4716 /***********************************************************************
4717 * NdrConformantStructMemorySize [RPCRT4.@]
4719 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4720 PFORMAT_STRING pFormat)
4726 /***********************************************************************
4727 * NdrConformantStructFree [RPCRT4.@]
4729 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4730 unsigned char *pMemory,
4731 PFORMAT_STRING pFormat)
4733 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4734 PFORMAT_STRING pCArrayFormat;
4736 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4738 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4739 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4741 ERR("invalid format type %x\n", pCStructFormat->type);
4742 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4746 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4747 pCStructFormat->offset_to_array_description;
4748 if (*pCArrayFormat != RPC_FC_CARRAY)
4750 ERR("invalid array format type %x\n", pCStructFormat->type);
4751 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4755 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4756 pCArrayFormat + 4, 0);
4758 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4760 /* copy constant sized part of struct */
4761 pStubMsg->BufferMark = pStubMsg->Buffer;
4763 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4764 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4767 /***********************************************************************
4768 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4770 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4771 unsigned char *pMemory,
4772 PFORMAT_STRING pFormat)
4774 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4775 PFORMAT_STRING pCVArrayFormat;
4777 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4779 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4780 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4782 ERR("invalid format type %x\n", pCVStructFormat->type);
4783 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4787 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4788 pCVStructFormat->offset_to_array_description;
4790 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4791 pMemory + pCVStructFormat->memory_size,
4794 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4796 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4798 /* write constant sized part */
4799 pStubMsg->BufferMark = pStubMsg->Buffer;
4800 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4802 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4803 pMemory + pCVStructFormat->memory_size,
4804 pCVArrayFormat, FALSE /* fHasPointers */);
4806 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4811 /***********************************************************************
4812 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4814 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4815 unsigned char **ppMemory,
4816 PFORMAT_STRING pFormat,
4817 unsigned char fMustAlloc)
4819 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4820 PFORMAT_STRING pCVArrayFormat;
4821 ULONG memsize, bufsize;
4822 unsigned char *saved_buffer, *saved_array_buffer;
4824 unsigned char *array_memory;
4826 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4828 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4829 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4831 ERR("invalid format type %x\n", pCVStructFormat->type);
4832 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4836 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4837 pCVStructFormat->offset_to_array_description;
4839 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4842 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4844 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4846 /* work out how much memory to allocate if we need to do so */
4847 if (!fMustAlloc && !*ppMemory)
4851 SIZE_T size = pCVStructFormat->memory_size + memsize;
4852 *ppMemory = NdrAllocate(pStubMsg, size);
4855 /* mark the start of the constant data */
4856 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4857 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4859 array_memory = *ppMemory + pCVStructFormat->memory_size;
4860 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
4861 &array_memory, pCVArrayFormat,
4862 FALSE /* fMustAlloc */,
4863 FALSE /* fUseServerBufferMemory */,
4864 FALSE /* fUnmarshall */);
4866 /* save offset in case unmarshalling pointers changes it */
4867 offset = pStubMsg->Offset;
4869 /* mark the start of the array data */
4870 saved_array_buffer = pStubMsg->Buffer;
4871 safe_buffer_increment(pStubMsg, bufsize);
4873 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4875 /* copy the constant data */
4876 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
4877 /* copy the array data */
4878 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
4879 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
4880 saved_array_buffer, bufsize);
4882 if (*pCVArrayFormat == RPC_FC_C_CSTRING)
4883 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
4884 else if (*pCVArrayFormat == RPC_FC_C_WSTRING)
4885 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
4890 /***********************************************************************
4891 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4893 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4894 unsigned char *pMemory,
4895 PFORMAT_STRING pFormat)
4897 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4898 PFORMAT_STRING pCVArrayFormat;
4900 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4902 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4903 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4905 ERR("invalid format type %x\n", pCVStructFormat->type);
4906 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4910 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4911 pCVStructFormat->offset_to_array_description;
4912 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
4913 pMemory + pCVStructFormat->memory_size,
4916 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4918 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4920 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4922 array_buffer_size(*pCVArrayFormat, pStubMsg,
4923 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4924 FALSE /* fHasPointers */);
4926 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4929 /***********************************************************************
4930 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4932 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4933 PFORMAT_STRING pFormat)
4935 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4936 PFORMAT_STRING pCVArrayFormat;
4938 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4940 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4941 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4943 ERR("invalid format type %x\n", pCVStructFormat->type);
4944 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4948 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4949 pCVStructFormat->offset_to_array_description;
4950 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
4952 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4954 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4956 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4957 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
4958 FALSE /* fHasPointers */);
4960 pStubMsg->MemorySize += pCVStructFormat->memory_size;
4962 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4964 return pStubMsg->MemorySize;
4967 /***********************************************************************
4968 * NdrConformantVaryingStructFree [RPCRT4.@]
4970 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4971 unsigned char *pMemory,
4972 PFORMAT_STRING pFormat)
4974 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4975 PFORMAT_STRING pCVArrayFormat;
4977 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4979 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4980 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4982 ERR("invalid format type %x\n", pCVStructFormat->type);
4983 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4987 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4988 pCVStructFormat->offset_to_array_description;
4989 array_free(*pCVArrayFormat, pStubMsg,
4990 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4991 FALSE /* fHasPointers */);
4993 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4995 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4998 #include "pshpack1.h"
5002 unsigned char alignment;
5003 unsigned short total_size;
5004 } NDR_SMFARRAY_FORMAT;
5009 unsigned char alignment;
5011 } NDR_LGFARRAY_FORMAT;
5012 #include "poppack.h"
5014 /***********************************************************************
5015 * NdrFixedArrayMarshall [RPCRT4.@]
5017 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5018 unsigned char *pMemory,
5019 PFORMAT_STRING pFormat)
5021 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5024 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5026 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5027 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5029 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5030 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5034 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5036 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5038 total_size = pSmFArrayFormat->total_size;
5039 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5043 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5044 total_size = pLgFArrayFormat->total_size;
5045 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5048 pStubMsg->BufferMark = pStubMsg->Buffer;
5049 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
5051 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5056 /***********************************************************************
5057 * NdrFixedArrayUnmarshall [RPCRT4.@]
5059 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5060 unsigned char **ppMemory,
5061 PFORMAT_STRING pFormat,
5062 unsigned char fMustAlloc)
5064 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5066 unsigned char *saved_buffer;
5068 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5070 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5071 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5073 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5074 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5078 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5080 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5082 total_size = pSmFArrayFormat->total_size;
5083 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5087 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5088 total_size = pLgFArrayFormat->total_size;
5089 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5093 *ppMemory = NdrAllocate(pStubMsg, total_size);
5096 if (!pStubMsg->IsClient && !*ppMemory)
5097 /* for servers, we just point straight into the RPC buffer */
5098 *ppMemory = pStubMsg->Buffer;
5101 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5102 safe_buffer_increment(pStubMsg, total_size);
5103 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5105 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
5106 if (*ppMemory != saved_buffer)
5107 memcpy(*ppMemory, saved_buffer, total_size);
5112 /***********************************************************************
5113 * NdrFixedArrayBufferSize [RPCRT4.@]
5115 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5116 unsigned char *pMemory,
5117 PFORMAT_STRING pFormat)
5119 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5122 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5124 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5125 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5127 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5128 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5132 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
5134 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5136 total_size = pSmFArrayFormat->total_size;
5137 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5141 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5142 total_size = pLgFArrayFormat->total_size;
5143 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5145 safe_buffer_length_increment(pStubMsg, total_size);
5147 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5150 /***********************************************************************
5151 * NdrFixedArrayMemorySize [RPCRT4.@]
5153 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5154 PFORMAT_STRING pFormat)
5156 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5159 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5161 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5162 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5164 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5165 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5169 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5171 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5173 total_size = pSmFArrayFormat->total_size;
5174 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5178 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5179 total_size = pLgFArrayFormat->total_size;
5180 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5182 pStubMsg->BufferMark = pStubMsg->Buffer;
5183 safe_buffer_increment(pStubMsg, total_size);
5184 pStubMsg->MemorySize += total_size;
5186 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5191 /***********************************************************************
5192 * NdrFixedArrayFree [RPCRT4.@]
5194 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5195 unsigned char *pMemory,
5196 PFORMAT_STRING pFormat)
5198 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5200 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5202 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5203 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5205 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5206 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5210 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5211 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5214 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5215 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5218 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5221 /***********************************************************************
5222 * NdrVaryingArrayMarshall [RPCRT4.@]
5224 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5225 unsigned char *pMemory,
5226 PFORMAT_STRING pFormat)
5228 unsigned char alignment;
5229 DWORD elements, esize;
5232 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5234 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5235 (pFormat[0] != RPC_FC_LGVARRAY))
5237 ERR("invalid format type %x\n", pFormat[0]);
5238 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5242 alignment = pFormat[1] + 1;
5244 if (pFormat[0] == RPC_FC_SMVARRAY)
5247 pFormat += sizeof(WORD);
5248 elements = *(const WORD*)pFormat;
5249 pFormat += sizeof(WORD);
5254 pFormat += sizeof(DWORD);
5255 elements = *(const DWORD*)pFormat;
5256 pFormat += sizeof(DWORD);
5259 esize = *(const WORD*)pFormat;
5260 pFormat += sizeof(WORD);
5262 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5263 if ((pStubMsg->ActualCount > elements) ||
5264 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5266 RpcRaiseException(RPC_S_INVALID_BOUND);
5270 WriteVariance(pStubMsg);
5272 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
5274 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5275 pStubMsg->BufferMark = pStubMsg->Buffer;
5276 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5278 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5283 /***********************************************************************
5284 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5286 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5287 unsigned char **ppMemory,
5288 PFORMAT_STRING pFormat,
5289 unsigned char fMustAlloc)
5291 unsigned char alignment;
5292 DWORD size, elements, esize;
5294 unsigned char *saved_buffer;
5297 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5299 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5300 (pFormat[0] != RPC_FC_LGVARRAY))
5302 ERR("invalid format type %x\n", pFormat[0]);
5303 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5307 alignment = pFormat[1] + 1;
5309 if (pFormat[0] == RPC_FC_SMVARRAY)
5312 size = *(const WORD*)pFormat;
5313 pFormat += sizeof(WORD);
5314 elements = *(const WORD*)pFormat;
5315 pFormat += sizeof(WORD);
5320 size = *(const DWORD*)pFormat;
5321 pFormat += sizeof(DWORD);
5322 elements = *(const DWORD*)pFormat;
5323 pFormat += sizeof(DWORD);
5326 esize = *(const WORD*)pFormat;
5327 pFormat += sizeof(WORD);
5329 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5331 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5333 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5334 offset = pStubMsg->Offset;
5336 if (!fMustAlloc && !*ppMemory)
5339 *ppMemory = NdrAllocate(pStubMsg, size);
5340 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5341 safe_buffer_increment(pStubMsg, bufsize);
5343 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5345 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5350 /***********************************************************************
5351 * NdrVaryingArrayBufferSize [RPCRT4.@]
5353 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5354 unsigned char *pMemory,
5355 PFORMAT_STRING pFormat)
5357 unsigned char alignment;
5358 DWORD elements, esize;
5360 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5362 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5363 (pFormat[0] != RPC_FC_LGVARRAY))
5365 ERR("invalid format type %x\n", pFormat[0]);
5366 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5370 alignment = pFormat[1] + 1;
5372 if (pFormat[0] == RPC_FC_SMVARRAY)
5375 pFormat += sizeof(WORD);
5376 elements = *(const WORD*)pFormat;
5377 pFormat += sizeof(WORD);
5382 pFormat += sizeof(DWORD);
5383 elements = *(const DWORD*)pFormat;
5384 pFormat += sizeof(DWORD);
5387 esize = *(const WORD*)pFormat;
5388 pFormat += sizeof(WORD);
5390 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5391 if ((pStubMsg->ActualCount > elements) ||
5392 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5394 RpcRaiseException(RPC_S_INVALID_BOUND);
5398 SizeVariance(pStubMsg);
5400 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
5402 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5404 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5407 /***********************************************************************
5408 * NdrVaryingArrayMemorySize [RPCRT4.@]
5410 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5411 PFORMAT_STRING pFormat)
5413 unsigned char alignment;
5414 DWORD size, elements, esize;
5416 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5418 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5419 (pFormat[0] != RPC_FC_LGVARRAY))
5421 ERR("invalid format type %x\n", pFormat[0]);
5422 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5426 alignment = pFormat[1] + 1;
5428 if (pFormat[0] == RPC_FC_SMVARRAY)
5431 size = *(const WORD*)pFormat;
5432 pFormat += sizeof(WORD);
5433 elements = *(const WORD*)pFormat;
5434 pFormat += sizeof(WORD);
5439 size = *(const DWORD*)pFormat;
5440 pFormat += sizeof(DWORD);
5441 elements = *(const DWORD*)pFormat;
5442 pFormat += sizeof(DWORD);
5445 esize = *(const WORD*)pFormat;
5446 pFormat += sizeof(WORD);
5448 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5450 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5452 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5453 pStubMsg->MemorySize += size;
5455 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5457 return pStubMsg->MemorySize;
5460 /***********************************************************************
5461 * NdrVaryingArrayFree [RPCRT4.@]
5463 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5464 unsigned char *pMemory,
5465 PFORMAT_STRING pFormat)
5469 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5471 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5472 (pFormat[0] != RPC_FC_LGVARRAY))
5474 ERR("invalid format type %x\n", pFormat[0]);
5475 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5479 if (pFormat[0] == RPC_FC_SMVARRAY)
5482 pFormat += sizeof(WORD);
5483 elements = *(const WORD*)pFormat;
5484 pFormat += sizeof(WORD);
5489 pFormat += sizeof(DWORD);
5490 elements = *(const DWORD*)pFormat;
5491 pFormat += sizeof(DWORD);
5494 pFormat += sizeof(WORD);
5496 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5497 if ((pStubMsg->ActualCount > elements) ||
5498 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5500 RpcRaiseException(RPC_S_INVALID_BOUND);
5504 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5507 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5520 return *(const USHORT *)pMemory;
5524 return *(const ULONG *)pMemory;
5526 FIXME("Unhandled base type: 0x%02x\n", fc);
5531 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5533 PFORMAT_STRING pFormat)
5535 unsigned short num_arms, arm, type;
5537 num_arms = *(const SHORT*)pFormat & 0x0fff;
5539 for(arm = 0; arm < num_arms; arm++)
5541 if(discriminant == *(const ULONG*)pFormat)
5549 type = *(const unsigned short*)pFormat;
5550 TRACE("type %04x\n", type);
5551 if(arm == num_arms) /* default arm extras */
5555 ERR("no arm for 0x%x and no default case\n", discriminant);
5556 RpcRaiseException(RPC_S_INVALID_TAG);
5561 TRACE("falling back to empty default case for 0x%x\n", discriminant);
5568 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5570 unsigned short type;
5574 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5578 type = *(const unsigned short*)pFormat;
5579 if((type & 0xff00) == 0x8000)
5581 unsigned char basetype = LOBYTE(type);
5582 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5586 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5587 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5590 unsigned char *saved_buffer = NULL;
5591 int pointer_buffer_mark_set = 0;
5598 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5599 saved_buffer = pStubMsg->Buffer;
5600 if (pStubMsg->PointerBufferMark)
5602 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5603 pStubMsg->PointerBufferMark = NULL;
5604 pointer_buffer_mark_set = 1;
5607 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5609 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5610 if (pointer_buffer_mark_set)
5612 STD_OVERFLOW_CHECK(pStubMsg);
5613 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5614 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5616 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5617 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5618 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5620 pStubMsg->Buffer = saved_buffer + 4;
5624 m(pStubMsg, pMemory, desc);
5627 else FIXME("no marshaller for embedded type %02x\n", *desc);
5632 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5633 unsigned char **ppMemory,
5635 PFORMAT_STRING pFormat,
5636 unsigned char fMustAlloc)
5638 unsigned short type;
5642 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5646 type = *(const unsigned short*)pFormat;
5647 if((type & 0xff00) == 0x8000)
5649 unsigned char basetype = LOBYTE(type);
5650 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5654 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5655 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5658 unsigned char *saved_buffer = NULL;
5659 int pointer_buffer_mark_set = 0;
5666 ALIGN_POINTER(pStubMsg->Buffer, 4);
5667 saved_buffer = pStubMsg->Buffer;
5668 if (pStubMsg->PointerBufferMark)
5670 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5671 pStubMsg->PointerBufferMark = NULL;
5672 pointer_buffer_mark_set = 1;
5675 pStubMsg->Buffer += 4; /* for pointer ID */
5677 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5679 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5680 saved_buffer, pStubMsg->BufferEnd);
5681 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5684 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5685 if (pointer_buffer_mark_set)
5687 STD_OVERFLOW_CHECK(pStubMsg);
5688 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5689 pStubMsg->Buffer = saved_buffer + 4;
5693 m(pStubMsg, ppMemory, desc, fMustAlloc);
5696 else FIXME("no marshaller for embedded type %02x\n", *desc);
5701 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5702 unsigned char *pMemory,
5704 PFORMAT_STRING pFormat)
5706 unsigned short type;
5710 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5714 type = *(const unsigned short*)pFormat;
5715 if((type & 0xff00) == 0x8000)
5717 unsigned char basetype = LOBYTE(type);
5718 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5722 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5723 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5732 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5733 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5734 if (!pStubMsg->IgnoreEmbeddedPointers)
5736 int saved_buffer_length = pStubMsg->BufferLength;
5737 pStubMsg->BufferLength = pStubMsg->PointerLength;
5738 pStubMsg->PointerLength = 0;
5739 if(!pStubMsg->BufferLength)
5740 ERR("BufferLength == 0??\n");
5741 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5742 pStubMsg->PointerLength = pStubMsg->BufferLength;
5743 pStubMsg->BufferLength = saved_buffer_length;
5747 m(pStubMsg, pMemory, desc);
5750 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5754 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5756 PFORMAT_STRING pFormat)
5758 unsigned short type, size;
5760 size = *(const unsigned short*)pFormat;
5761 pStubMsg->Memory += size;
5764 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5768 type = *(const unsigned short*)pFormat;
5769 if((type & 0xff00) == 0x8000)
5771 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5775 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5776 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5777 unsigned char *saved_buffer;
5786 ALIGN_POINTER(pStubMsg->Buffer, 4);
5787 saved_buffer = pStubMsg->Buffer;
5788 safe_buffer_increment(pStubMsg, 4);
5789 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(void *));
5790 pStubMsg->MemorySize += sizeof(void *);
5791 if (!pStubMsg->IgnoreEmbeddedPointers)
5792 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5795 return m(pStubMsg, desc);
5798 else FIXME("no marshaller for embedded type %02x\n", *desc);
5801 TRACE("size %d\n", size);
5805 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5806 unsigned char *pMemory,
5808 PFORMAT_STRING pFormat)
5810 unsigned short type;
5814 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5818 type = *(const unsigned short*)pFormat;
5819 if((type & 0xff00) != 0x8000)
5821 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5822 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5831 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5834 m(pStubMsg, pMemory, desc);
5840 /***********************************************************************
5841 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5843 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5844 unsigned char *pMemory,
5845 PFORMAT_STRING pFormat)
5847 unsigned char switch_type;
5848 unsigned char increment;
5851 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5854 switch_type = *pFormat & 0xf;
5855 increment = (*pFormat & 0xf0) >> 4;
5858 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5860 switch_value = get_discriminant(switch_type, pMemory);
5861 TRACE("got switch value 0x%x\n", switch_value);
5863 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5864 pMemory += increment;
5866 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5869 /***********************************************************************
5870 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5872 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5873 unsigned char **ppMemory,
5874 PFORMAT_STRING pFormat,
5875 unsigned char fMustAlloc)
5877 unsigned char switch_type;
5878 unsigned char increment;
5880 unsigned short size;
5881 unsigned char *pMemoryArm;
5883 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5886 switch_type = *pFormat & 0xf;
5887 increment = (*pFormat & 0xf0) >> 4;
5890 ALIGN_POINTER(pStubMsg->Buffer, increment);
5891 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5892 TRACE("got switch value 0x%x\n", switch_value);
5894 size = *(const unsigned short*)pFormat + increment;
5895 if (!fMustAlloc && !*ppMemory)
5898 *ppMemory = NdrAllocate(pStubMsg, size);
5900 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
5901 * since the arm is part of the memory block that is encompassed by
5902 * the whole union. Memory is forced to allocate when pointers
5903 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
5904 * clearing the memory we pass in to the unmarshaller */
5906 memset(*ppMemory, 0, size);
5908 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5909 pMemoryArm = *ppMemory + increment;
5911 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, FALSE);
5914 /***********************************************************************
5915 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5917 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5918 unsigned char *pMemory,
5919 PFORMAT_STRING pFormat)
5921 unsigned char switch_type;
5922 unsigned char increment;
5925 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5928 switch_type = *pFormat & 0xf;
5929 increment = (*pFormat & 0xf0) >> 4;
5932 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5933 switch_value = get_discriminant(switch_type, pMemory);
5934 TRACE("got switch value 0x%x\n", switch_value);
5936 /* Add discriminant size */
5937 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5938 pMemory += increment;
5940 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5943 /***********************************************************************
5944 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5946 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5947 PFORMAT_STRING pFormat)
5949 unsigned char switch_type;
5950 unsigned char increment;
5953 switch_type = *pFormat & 0xf;
5954 increment = (*pFormat & 0xf0) >> 4;
5957 ALIGN_POINTER(pStubMsg->Buffer, increment);
5958 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5959 TRACE("got switch value 0x%x\n", switch_value);
5961 pStubMsg->Memory += increment;
5963 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5966 /***********************************************************************
5967 * NdrEncapsulatedUnionFree [RPCRT4.@]
5969 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5970 unsigned char *pMemory,
5971 PFORMAT_STRING pFormat)
5973 unsigned char switch_type;
5974 unsigned char increment;
5977 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5980 switch_type = *pFormat & 0xf;
5981 increment = (*pFormat & 0xf0) >> 4;
5984 switch_value = get_discriminant(switch_type, pMemory);
5985 TRACE("got switch value 0x%x\n", switch_value);
5987 pMemory += increment;
5989 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5992 /***********************************************************************
5993 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5995 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5996 unsigned char *pMemory,
5997 PFORMAT_STRING pFormat)
5999 unsigned char switch_type;
6001 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6004 switch_type = *pFormat;
6007 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6008 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6009 /* Marshall discriminant */
6010 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6012 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6015 static LONG unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
6016 PFORMAT_STRING *ppFormat)
6018 LONG discriminant = 0;
6028 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6037 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6038 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6046 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
6047 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6052 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
6056 if (pStubMsg->fHasNewCorrDesc)
6060 return discriminant;
6063 /**********************************************************************
6064 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6066 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6067 unsigned char **ppMemory,
6068 PFORMAT_STRING pFormat,
6069 unsigned char fMustAlloc)
6072 unsigned short size;
6074 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6077 /* Unmarshall discriminant */
6078 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6079 TRACE("unmarshalled discriminant %x\n", discriminant);
6081 pFormat += *(const SHORT*)pFormat;
6083 size = *(const unsigned short*)pFormat;
6085 if (!fMustAlloc && !*ppMemory)
6088 *ppMemory = NdrAllocate(pStubMsg, size);
6090 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6091 * since the arm is part of the memory block that is encompassed by
6092 * the whole union. Memory is forced to allocate when pointers
6093 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6094 * clearing the memory we pass in to the unmarshaller */
6096 memset(*ppMemory, 0, size);
6098 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, FALSE);
6101 /***********************************************************************
6102 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6104 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6105 unsigned char *pMemory,
6106 PFORMAT_STRING pFormat)
6108 unsigned char switch_type;
6110 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6113 switch_type = *pFormat;
6116 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6117 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6118 /* Add discriminant size */
6119 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6121 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6124 /***********************************************************************
6125 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6127 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6128 PFORMAT_STRING pFormat)
6133 /* Unmarshall discriminant */
6134 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6135 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
6137 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
6140 /***********************************************************************
6141 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6143 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6144 unsigned char *pMemory,
6145 PFORMAT_STRING pFormat)
6147 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6151 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6152 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6154 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6157 /***********************************************************************
6158 * NdrByteCountPointerMarshall [RPCRT4.@]
6160 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6161 unsigned char *pMemory,
6162 PFORMAT_STRING pFormat)
6168 /***********************************************************************
6169 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6171 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6172 unsigned char **ppMemory,
6173 PFORMAT_STRING pFormat,
6174 unsigned char fMustAlloc)
6180 /***********************************************************************
6181 * NdrByteCountPointerBufferSize [RPCRT4.@]
6183 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6184 unsigned char *pMemory,
6185 PFORMAT_STRING pFormat)
6190 /***********************************************************************
6191 * NdrByteCountPointerMemorySize [internal]
6193 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6194 PFORMAT_STRING pFormat)
6200 /***********************************************************************
6201 * NdrByteCountPointerFree [RPCRT4.@]
6203 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6204 unsigned char *pMemory,
6205 PFORMAT_STRING pFormat)
6210 /***********************************************************************
6211 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6213 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6214 unsigned char *pMemory,
6215 PFORMAT_STRING pFormat)
6221 /***********************************************************************
6222 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6224 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6225 unsigned char **ppMemory,
6226 PFORMAT_STRING pFormat,
6227 unsigned char fMustAlloc)
6233 /***********************************************************************
6234 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6236 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6237 unsigned char *pMemory,
6238 PFORMAT_STRING pFormat)
6243 /***********************************************************************
6244 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6246 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6247 PFORMAT_STRING pFormat)
6253 /***********************************************************************
6254 * NdrXmitOrRepAsFree [RPCRT4.@]
6256 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6257 unsigned char *pMemory,
6258 PFORMAT_STRING pFormat)
6263 /***********************************************************************
6264 * NdrRangeMarshall [internal]
6266 static unsigned char *WINAPI NdrRangeMarshall(
6267 PMIDL_STUB_MESSAGE pStubMsg,
6268 unsigned char *pMemory,
6269 PFORMAT_STRING pFormat)
6271 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6272 unsigned char base_type;
6274 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6276 if (pRange->type != RPC_FC_RANGE)
6278 ERR("invalid format type %x\n", pRange->type);
6279 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6283 base_type = pRange->flags_type & 0xf;
6285 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6288 /***********************************************************************
6289 * NdrRangeUnmarshall [RPCRT4.@]
6291 unsigned char *WINAPI NdrRangeUnmarshall(
6292 PMIDL_STUB_MESSAGE pStubMsg,
6293 unsigned char **ppMemory,
6294 PFORMAT_STRING pFormat,
6295 unsigned char fMustAlloc)
6297 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6298 unsigned char base_type;
6300 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6302 if (pRange->type != RPC_FC_RANGE)
6304 ERR("invalid format type %x\n", pRange->type);
6305 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6308 base_type = pRange->flags_type & 0xf;
6310 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6311 base_type, pRange->low_value, pRange->high_value);
6313 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6316 ALIGN_POINTER(pStubMsg->Buffer, sizeof(wire_type)); \
6317 if (!fMustAlloc && !*ppMemory) \
6318 fMustAlloc = TRUE; \
6320 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6321 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6323 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6324 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6325 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6327 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6328 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6330 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6331 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6332 (mem_type)pRange->high_value); \
6333 RpcRaiseException(RPC_S_INVALID_BOUND); \
6336 TRACE("*ppMemory: %p\n", *ppMemory); \
6337 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6338 pStubMsg->Buffer += sizeof(wire_type); \
6345 RANGE_UNMARSHALL(UCHAR, UCHAR, "%d");
6346 TRACE("value: 0x%02x\n", **ppMemory);
6350 RANGE_UNMARSHALL(CHAR, CHAR, "%u");
6351 TRACE("value: 0x%02x\n", **ppMemory);
6353 case RPC_FC_WCHAR: /* FIXME: valid? */
6355 RANGE_UNMARSHALL(USHORT, USHORT, "%u");
6356 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6359 RANGE_UNMARSHALL(SHORT, SHORT, "%d");
6360 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6364 RANGE_UNMARSHALL(LONG, LONG, "%d");
6365 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6368 RANGE_UNMARSHALL(ULONG, ULONG, "%u");
6369 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6372 RANGE_UNMARSHALL(UINT, USHORT, "%u");
6373 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6379 ERR("invalid range base type: 0x%02x\n", base_type);
6380 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6386 /***********************************************************************
6387 * NdrRangeBufferSize [internal]
6389 static void WINAPI NdrRangeBufferSize(
6390 PMIDL_STUB_MESSAGE pStubMsg,
6391 unsigned char *pMemory,
6392 PFORMAT_STRING pFormat)
6394 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6395 unsigned char base_type;
6397 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6399 if (pRange->type != RPC_FC_RANGE)
6401 ERR("invalid format type %x\n", pRange->type);
6402 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6404 base_type = pRange->flags_type & 0xf;
6406 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6409 /***********************************************************************
6410 * NdrRangeMemorySize [internal]
6412 static ULONG WINAPI NdrRangeMemorySize(
6413 PMIDL_STUB_MESSAGE pStubMsg,
6414 PFORMAT_STRING pFormat)
6416 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6417 unsigned char base_type;
6419 if (pRange->type != RPC_FC_RANGE)
6421 ERR("invalid format type %x\n", pRange->type);
6422 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6425 base_type = pRange->flags_type & 0xf;
6427 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6430 /***********************************************************************
6431 * NdrRangeFree [internal]
6433 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6434 unsigned char *pMemory,
6435 PFORMAT_STRING pFormat)
6437 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6442 /***********************************************************************
6443 * NdrBaseTypeMarshall [internal]
6445 static unsigned char *WINAPI NdrBaseTypeMarshall(
6446 PMIDL_STUB_MESSAGE pStubMsg,
6447 unsigned char *pMemory,
6448 PFORMAT_STRING pFormat)
6450 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6458 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6459 TRACE("value: 0x%02x\n", *pMemory);
6464 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6465 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6466 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6470 case RPC_FC_ERROR_STATUS_T:
6472 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
6473 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6474 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6477 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
6478 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6481 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
6482 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6485 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
6486 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6487 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6490 /* only 16-bits on the wire, so do a sanity check */
6491 if (*(UINT *)pMemory > SHRT_MAX)
6492 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6493 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6494 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6495 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6496 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
6497 pStubMsg->Buffer += sizeof(USHORT);
6498 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6503 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6506 /* FIXME: what is the correct return value? */
6510 /***********************************************************************
6511 * NdrBaseTypeUnmarshall [internal]
6513 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6514 PMIDL_STUB_MESSAGE pStubMsg,
6515 unsigned char **ppMemory,
6516 PFORMAT_STRING pFormat,
6517 unsigned char fMustAlloc)
6519 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6521 #define BASE_TYPE_UNMARSHALL(type) \
6522 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6523 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6525 *ppMemory = pStubMsg->Buffer; \
6526 TRACE("*ppMemory: %p\n", *ppMemory); \
6527 safe_buffer_increment(pStubMsg, sizeof(type)); \
6532 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6533 TRACE("*ppMemory: %p\n", *ppMemory); \
6534 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6543 BASE_TYPE_UNMARSHALL(UCHAR);
6544 TRACE("value: 0x%02x\n", **ppMemory);
6549 BASE_TYPE_UNMARSHALL(USHORT);
6550 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6554 case RPC_FC_ERROR_STATUS_T:
6556 BASE_TYPE_UNMARSHALL(ULONG);
6557 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6560 BASE_TYPE_UNMARSHALL(float);
6561 TRACE("value: %f\n", **(float **)ppMemory);
6564 BASE_TYPE_UNMARSHALL(double);
6565 TRACE("value: %f\n", **(double **)ppMemory);
6568 BASE_TYPE_UNMARSHALL(ULONGLONG);
6569 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6572 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6573 if (!fMustAlloc && !*ppMemory)
6576 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6577 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
6578 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6579 TRACE("*ppMemory: %p\n", *ppMemory);
6580 /* 16-bits on the wire, but int in memory */
6581 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
6582 pStubMsg->Buffer += sizeof(USHORT);
6583 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6588 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6590 #undef BASE_TYPE_UNMARSHALL
6592 /* FIXME: what is the correct return value? */
6597 /***********************************************************************
6598 * NdrBaseTypeBufferSize [internal]
6600 static void WINAPI NdrBaseTypeBufferSize(
6601 PMIDL_STUB_MESSAGE pStubMsg,
6602 unsigned char *pMemory,
6603 PFORMAT_STRING pFormat)
6605 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6613 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6619 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
6620 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6625 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
6626 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6629 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
6630 safe_buffer_length_increment(pStubMsg, sizeof(float));
6633 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
6634 safe_buffer_length_increment(pStubMsg, sizeof(double));
6637 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
6638 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6640 case RPC_FC_ERROR_STATUS_T:
6641 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
6642 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6647 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6651 /***********************************************************************
6652 * NdrBaseTypeMemorySize [internal]
6654 static ULONG WINAPI NdrBaseTypeMemorySize(
6655 PMIDL_STUB_MESSAGE pStubMsg,
6656 PFORMAT_STRING pFormat)
6658 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6666 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6667 pStubMsg->MemorySize += sizeof(UCHAR);
6668 return sizeof(UCHAR);
6672 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6673 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6674 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(USHORT));
6675 pStubMsg->MemorySize += sizeof(USHORT);
6676 return sizeof(USHORT);
6680 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
6681 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6682 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(ULONG));
6683 pStubMsg->MemorySize += sizeof(ULONG);
6684 return sizeof(ULONG);
6686 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
6687 safe_buffer_increment(pStubMsg, sizeof(float));
6688 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(float));
6689 pStubMsg->MemorySize += sizeof(float);
6690 return sizeof(float);
6692 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
6693 safe_buffer_increment(pStubMsg, sizeof(double));
6694 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(double));
6695 pStubMsg->MemorySize += sizeof(double);
6696 return sizeof(double);
6698 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
6699 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6700 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(ULONGLONG));
6701 pStubMsg->MemorySize += sizeof(ULONGLONG);
6702 return sizeof(ULONGLONG);
6703 case RPC_FC_ERROR_STATUS_T:
6704 ALIGN_POINTER(pStubMsg->Buffer, sizeof(error_status_t));
6705 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6706 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(error_status_t));
6707 pStubMsg->MemorySize += sizeof(error_status_t);
6708 return sizeof(error_status_t);
6710 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6711 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6712 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(UINT));
6713 pStubMsg->MemorySize += sizeof(UINT);
6714 return sizeof(UINT);
6716 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(void *));
6717 pStubMsg->MemorySize += sizeof(void *);
6718 return sizeof(void *);
6720 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6725 /***********************************************************************
6726 * NdrBaseTypeFree [internal]
6728 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6729 unsigned char *pMemory,
6730 PFORMAT_STRING pFormat)
6732 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6737 /***********************************************************************
6738 * NdrContextHandleBufferSize [internal]
6740 static void WINAPI NdrContextHandleBufferSize(
6741 PMIDL_STUB_MESSAGE pStubMsg,
6742 unsigned char *pMemory,
6743 PFORMAT_STRING pFormat)
6745 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6747 if (*pFormat != RPC_FC_BIND_CONTEXT)
6749 ERR("invalid format type %x\n", *pFormat);
6750 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6752 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
6753 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6756 /***********************************************************************
6757 * NdrContextHandleMarshall [internal]
6759 static unsigned char *WINAPI NdrContextHandleMarshall(
6760 PMIDL_STUB_MESSAGE pStubMsg,
6761 unsigned char *pMemory,
6762 PFORMAT_STRING pFormat)
6764 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6766 if (*pFormat != RPC_FC_BIND_CONTEXT)
6768 ERR("invalid format type %x\n", *pFormat);
6769 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6771 TRACE("flags: 0x%02x\n", pFormat[1]);
6773 if (pStubMsg->IsClient)
6775 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6776 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6778 NdrClientContextMarshall(pStubMsg, pMemory, FALSE);
6782 NDR_SCONTEXT ctxt = NDRSContextFromValue(pMemory);
6783 NDR_RUNDOWN rundown = pStubMsg->StubDesc->apfnNdrRundownRoutines[pFormat[2]];
6784 NdrServerContextNewMarshall(pStubMsg, ctxt, rundown, pFormat);
6790 /***********************************************************************
6791 * NdrContextHandleUnmarshall [internal]
6793 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6794 PMIDL_STUB_MESSAGE pStubMsg,
6795 unsigned char **ppMemory,
6796 PFORMAT_STRING pFormat,
6797 unsigned char fMustAlloc)
6799 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6800 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6802 if (*pFormat != RPC_FC_BIND_CONTEXT)
6804 ERR("invalid format type %x\n", *pFormat);
6805 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6807 TRACE("flags: 0x%02x\n", pFormat[1]);
6809 if (pStubMsg->IsClient)
6811 /* [out]-only or [ret] param */
6812 if ((pFormat[1] & (HANDLE_PARAM_IS_IN|HANDLE_PARAM_IS_OUT)) == HANDLE_PARAM_IS_OUT)
6813 **(NDR_CCONTEXT **)ppMemory = NULL;
6814 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6819 ctxt = NdrServerContextNewUnmarshall(pStubMsg, pFormat);
6820 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6821 *(void **)ppMemory = NDRSContextValue(ctxt);
6823 *(void **)ppMemory = *NDRSContextValue(ctxt);
6829 /***********************************************************************
6830 * NdrClientContextMarshall [RPCRT4.@]
6832 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6833 NDR_CCONTEXT ContextHandle,
6836 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
6838 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
6840 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6842 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6843 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6844 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6847 /* FIXME: what does fCheck do? */
6848 NDRCContextMarshall(ContextHandle,
6851 pStubMsg->Buffer += cbNDRContext;
6854 /***********************************************************************
6855 * NdrClientContextUnmarshall [RPCRT4.@]
6857 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6858 NDR_CCONTEXT * pContextHandle,
6859 RPC_BINDING_HANDLE BindHandle)
6861 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
6863 ALIGN_POINTER(pStubMsg->Buffer, 4);
6865 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
6866 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6868 NDRCContextUnmarshall(pContextHandle,
6871 pStubMsg->RpcMsg->DataRepresentation);
6873 pStubMsg->Buffer += cbNDRContext;
6876 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6877 NDR_SCONTEXT ContextHandle,
6878 NDR_RUNDOWN RundownRoutine )
6880 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
6882 ALIGN_POINTER(pStubMsg->Buffer, 4);
6884 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6886 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6887 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6888 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6891 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6892 pStubMsg->Buffer, RundownRoutine, NULL,
6893 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6894 pStubMsg->Buffer += cbNDRContext;
6897 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6899 NDR_SCONTEXT ContextHandle;
6901 TRACE("(%p)\n", pStubMsg);
6903 ALIGN_POINTER(pStubMsg->Buffer, 4);
6905 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6907 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6908 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6909 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6912 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6914 pStubMsg->RpcMsg->DataRepresentation,
6915 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6916 pStubMsg->Buffer += cbNDRContext;
6918 return ContextHandle;
6921 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6922 unsigned char* pMemory,
6923 PFORMAT_STRING pFormat)
6925 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6928 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6929 PFORMAT_STRING pFormat)
6931 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6932 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6934 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6936 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6937 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6938 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6939 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6940 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6942 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6943 if_id = &sif->InterfaceId;
6946 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
6947 pStubMsg->RpcMsg->DataRepresentation, if_id,
6951 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6952 NDR_SCONTEXT ContextHandle,
6953 NDR_RUNDOWN RundownRoutine,
6954 PFORMAT_STRING pFormat)
6956 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6957 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6959 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6961 ALIGN_POINTER(pStubMsg->Buffer, 4);
6963 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6965 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6966 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6967 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6970 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6971 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6972 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6973 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6974 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6976 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6977 if_id = &sif->InterfaceId;
6980 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6981 pStubMsg->Buffer, RundownRoutine, if_id, flags);
6982 pStubMsg->Buffer += cbNDRContext;
6985 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6986 PFORMAT_STRING pFormat)
6988 NDR_SCONTEXT ContextHandle;
6989 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6990 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6992 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6994 ALIGN_POINTER(pStubMsg->Buffer, 4);
6996 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6998 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6999 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7000 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7003 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7004 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7005 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7006 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7007 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7009 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7010 if_id = &sif->InterfaceId;
7013 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7015 pStubMsg->RpcMsg->DataRepresentation,
7017 pStubMsg->Buffer += cbNDRContext;
7019 return ContextHandle;
7022 /***********************************************************************
7023 * NdrCorrelationInitialize [RPCRT4.@]
7025 * Initializes correlation validity checking.
7028 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7029 * pMemory [I] Pointer to memory to use as a cache.
7030 * CacheSize [I] Size of the memory pointed to by pMemory.
7031 * Flags [I] Reserved. Set to zero.
7036 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
7038 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
7039 pStubMsg->fHasNewCorrDesc = TRUE;
7042 /***********************************************************************
7043 * NdrCorrelationPass [RPCRT4.@]
7045 * Performs correlation validity checking.
7048 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7053 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
7055 FIXME("(%p): stub\n", pStubMsg);
7058 /***********************************************************************
7059 * NdrCorrelationFree [RPCRT4.@]
7061 * Frees any resources used while unmarshalling parameters that need
7062 * correlation validity checking.
7065 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7070 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
7072 FIXME("(%p): stub\n", pStubMsg);