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("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2701 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2704 case RPC_FC_POINTER:
2706 unsigned char *saved_buffer;
2707 int pointer_buffer_mark_set = 0;
2708 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2709 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2710 if (*pPointer != RPC_FC_RP)
2711 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
2712 saved_buffer = pStubMsg->Buffer;
2713 if (pStubMsg->PointerBufferMark)
2715 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2716 pStubMsg->PointerBufferMark = NULL;
2717 pointer_buffer_mark_set = 1;
2719 else if (*pPointer != RPC_FC_RP)
2720 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2721 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2722 if (pointer_buffer_mark_set)
2724 STD_OVERFLOW_CHECK(pStubMsg);
2725 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2726 pStubMsg->Buffer = saved_buffer;
2727 if (*pPointer != RPC_FC_RP)
2728 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2730 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2732 pMemory += sizeof(void *);
2735 case RPC_FC_ALIGNM2:
2736 ALIGN_POINTER(pMemory, 2);
2738 case RPC_FC_ALIGNM4:
2739 ALIGN_POINTER(pMemory, 4);
2741 case RPC_FC_ALIGNM8:
2742 ALIGN_POINTER(pMemory, 8);
2744 case RPC_FC_STRUCTPAD1:
2745 case RPC_FC_STRUCTPAD2:
2746 case RPC_FC_STRUCTPAD3:
2747 case RPC_FC_STRUCTPAD4:
2748 case RPC_FC_STRUCTPAD5:
2749 case RPC_FC_STRUCTPAD6:
2750 case RPC_FC_STRUCTPAD7:
2751 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2753 case RPC_FC_EMBEDDED_COMPLEX:
2754 pMemory += pFormat[1];
2756 desc = pFormat + *(const SHORT*)pFormat;
2757 size = EmbeddedComplexSize(pStubMsg, desc);
2758 TRACE("embedded complex (size=%d) <= %p\n", size, pMemory);
2759 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2762 /* for some reason interface pointers aren't generated as
2763 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2764 * they still need the derefencing treatment that pointers are
2766 if (*desc == RPC_FC_IP)
2767 m(pStubMsg, *(unsigned char **)pMemory, desc);
2769 m(pStubMsg, pMemory, desc);
2771 else FIXME("no marshaller for embedded type %02x\n", *desc);
2778 FIXME("unhandled format 0x%02x\n", *pFormat);
2786 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2787 unsigned char *pMemory,
2788 PFORMAT_STRING pFormat,
2789 PFORMAT_STRING pPointer,
2790 unsigned char fMustAlloc)
2792 PFORMAT_STRING desc;
2796 while (*pFormat != RPC_FC_END) {
2802 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2803 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2809 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2810 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2814 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2815 *(DWORD*)pMemory &= 0xffff;
2816 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
2817 if (32767 < *(DWORD*)pMemory)
2818 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2824 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2825 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2829 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2830 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2833 case RPC_FC_POINTER:
2835 unsigned char *saved_buffer;
2836 int pointer_buffer_mark_set = 0;
2837 TRACE("pointer => %p\n", pMemory);
2838 if (*pPointer != RPC_FC_RP)
2839 ALIGN_POINTER(pStubMsg->Buffer, 4);
2840 saved_buffer = pStubMsg->Buffer;
2841 if (pStubMsg->PointerBufferMark)
2843 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2844 pStubMsg->PointerBufferMark = NULL;
2845 pointer_buffer_mark_set = 1;
2847 else if (*pPointer != RPC_FC_RP)
2848 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2850 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
2851 if (pointer_buffer_mark_set)
2853 STD_OVERFLOW_CHECK(pStubMsg);
2854 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2855 pStubMsg->Buffer = saved_buffer;
2856 if (*pPointer != RPC_FC_RP)
2857 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2860 pMemory += sizeof(void *);
2863 case RPC_FC_ALIGNM2:
2864 ALIGN_POINTER_CLEAR(pMemory, 2);
2866 case RPC_FC_ALIGNM4:
2867 ALIGN_POINTER_CLEAR(pMemory, 4);
2869 case RPC_FC_ALIGNM8:
2870 ALIGN_POINTER_CLEAR(pMemory, 8);
2872 case RPC_FC_STRUCTPAD1:
2873 case RPC_FC_STRUCTPAD2:
2874 case RPC_FC_STRUCTPAD3:
2875 case RPC_FC_STRUCTPAD4:
2876 case RPC_FC_STRUCTPAD5:
2877 case RPC_FC_STRUCTPAD6:
2878 case RPC_FC_STRUCTPAD7:
2879 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2880 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2882 case RPC_FC_EMBEDDED_COMPLEX:
2883 pMemory += pFormat[1];
2885 desc = pFormat + *(const SHORT*)pFormat;
2886 size = EmbeddedComplexSize(pStubMsg, desc);
2887 TRACE("embedded complex (size=%d) => %p\n", size, pMemory);
2889 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
2890 * since the type is part of the memory block that is encompassed by
2891 * the whole complex type. Memory is forced to allocate when pointers
2892 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
2893 * clearing the memory we pass in to the unmarshaller */
2894 memset(pMemory, 0, size);
2895 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2898 /* for some reason interface pointers aren't generated as
2899 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2900 * they still need the derefencing treatment that pointers are
2902 if (*desc == RPC_FC_IP)
2903 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2905 m(pStubMsg, &pMemory, desc, FALSE);
2907 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2914 FIXME("unhandled format %d\n", *pFormat);
2922 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2923 unsigned char *pMemory,
2924 PFORMAT_STRING pFormat,
2925 PFORMAT_STRING pPointer)
2927 PFORMAT_STRING desc;
2931 while (*pFormat != RPC_FC_END) {
2937 safe_buffer_length_increment(pStubMsg, 1);
2943 safe_buffer_length_increment(pStubMsg, 2);
2947 safe_buffer_length_increment(pStubMsg, 2);
2953 safe_buffer_length_increment(pStubMsg, 4);
2957 safe_buffer_length_increment(pStubMsg, 8);
2960 case RPC_FC_POINTER:
2961 if (!pStubMsg->IgnoreEmbeddedPointers)
2963 int saved_buffer_length = pStubMsg->BufferLength;
2964 pStubMsg->BufferLength = pStubMsg->PointerLength;
2965 pStubMsg->PointerLength = 0;
2966 if(!pStubMsg->BufferLength)
2967 ERR("BufferLength == 0??\n");
2968 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2969 pStubMsg->PointerLength = pStubMsg->BufferLength;
2970 pStubMsg->BufferLength = saved_buffer_length;
2972 if (*pPointer != RPC_FC_RP)
2974 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2975 safe_buffer_length_increment(pStubMsg, 4);
2978 pMemory += sizeof(void*);
2980 case RPC_FC_ALIGNM2:
2981 ALIGN_POINTER(pMemory, 2);
2983 case RPC_FC_ALIGNM4:
2984 ALIGN_POINTER(pMemory, 4);
2986 case RPC_FC_ALIGNM8:
2987 ALIGN_POINTER(pMemory, 8);
2989 case RPC_FC_STRUCTPAD1:
2990 case RPC_FC_STRUCTPAD2:
2991 case RPC_FC_STRUCTPAD3:
2992 case RPC_FC_STRUCTPAD4:
2993 case RPC_FC_STRUCTPAD5:
2994 case RPC_FC_STRUCTPAD6:
2995 case RPC_FC_STRUCTPAD7:
2996 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2998 case RPC_FC_EMBEDDED_COMPLEX:
2999 pMemory += pFormat[1];
3001 desc = pFormat + *(const SHORT*)pFormat;
3002 size = EmbeddedComplexSize(pStubMsg, desc);
3003 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
3006 /* for some reason interface pointers aren't generated as
3007 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3008 * they still need the derefencing treatment that pointers are
3010 if (*desc == RPC_FC_IP)
3011 m(pStubMsg, *(unsigned char **)pMemory, desc);
3013 m(pStubMsg, pMemory, desc);
3015 else FIXME("no buffersizer for embedded type %02x\n", *desc);
3022 FIXME("unhandled format 0x%02x\n", *pFormat);
3030 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
3031 unsigned char *pMemory,
3032 PFORMAT_STRING pFormat,
3033 PFORMAT_STRING pPointer)
3035 PFORMAT_STRING desc;
3039 while (*pFormat != RPC_FC_END) {
3061 case RPC_FC_POINTER:
3062 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3064 pMemory += sizeof(void *);
3066 case RPC_FC_ALIGNM2:
3067 ALIGN_POINTER(pMemory, 2);
3069 case RPC_FC_ALIGNM4:
3070 ALIGN_POINTER(pMemory, 4);
3072 case RPC_FC_ALIGNM8:
3073 ALIGN_POINTER(pMemory, 8);
3075 case RPC_FC_STRUCTPAD1:
3076 case RPC_FC_STRUCTPAD2:
3077 case RPC_FC_STRUCTPAD3:
3078 case RPC_FC_STRUCTPAD4:
3079 case RPC_FC_STRUCTPAD5:
3080 case RPC_FC_STRUCTPAD6:
3081 case RPC_FC_STRUCTPAD7:
3082 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3084 case RPC_FC_EMBEDDED_COMPLEX:
3085 pMemory += pFormat[1];
3087 desc = pFormat + *(const SHORT*)pFormat;
3088 size = EmbeddedComplexSize(pStubMsg, desc);
3089 m = NdrFreer[*desc & NDR_TABLE_MASK];
3092 /* for some reason interface pointers aren't generated as
3093 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3094 * they still need the derefencing treatment that pointers are
3096 if (*desc == RPC_FC_IP)
3097 m(pStubMsg, *(unsigned char **)pMemory, desc);
3099 m(pStubMsg, pMemory, desc);
3107 FIXME("unhandled format 0x%02x\n", *pFormat);
3115 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3116 PFORMAT_STRING pFormat,
3117 PFORMAT_STRING pPointer)
3119 PFORMAT_STRING desc;
3122 while (*pFormat != RPC_FC_END) {
3129 safe_buffer_increment(pStubMsg, 1);
3135 safe_buffer_increment(pStubMsg, 2);
3139 safe_buffer_increment(pStubMsg, 2);
3145 safe_buffer_increment(pStubMsg, 4);
3149 safe_buffer_increment(pStubMsg, 8);
3151 case RPC_FC_POINTER:
3153 unsigned char *saved_buffer;
3154 int pointer_buffer_mark_set = 0;
3155 if (*pPointer != RPC_FC_RP)
3156 ALIGN_POINTER(pStubMsg->Buffer, 4);
3157 saved_buffer = pStubMsg->Buffer;
3158 if (pStubMsg->PointerBufferMark)
3160 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3161 pStubMsg->PointerBufferMark = NULL;
3162 pointer_buffer_mark_set = 1;
3164 else if (*pPointer != RPC_FC_RP)
3165 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3167 if (!pStubMsg->IgnoreEmbeddedPointers)
3168 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3169 if (pointer_buffer_mark_set)
3171 STD_OVERFLOW_CHECK(pStubMsg);
3172 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3173 pStubMsg->Buffer = saved_buffer;
3174 if (*pPointer != RPC_FC_RP)
3175 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3178 size += sizeof(void *);
3181 case RPC_FC_ALIGNM2:
3182 ALIGN_LENGTH(size, 2);
3184 case RPC_FC_ALIGNM4:
3185 ALIGN_LENGTH(size, 4);
3187 case RPC_FC_ALIGNM8:
3188 ALIGN_LENGTH(size, 8);
3190 case RPC_FC_STRUCTPAD1:
3191 case RPC_FC_STRUCTPAD2:
3192 case RPC_FC_STRUCTPAD3:
3193 case RPC_FC_STRUCTPAD4:
3194 case RPC_FC_STRUCTPAD5:
3195 case RPC_FC_STRUCTPAD6:
3196 case RPC_FC_STRUCTPAD7:
3197 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3199 case RPC_FC_EMBEDDED_COMPLEX:
3202 desc = pFormat + *(const SHORT*)pFormat;
3203 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3209 FIXME("unhandled format 0x%02x\n", *pFormat);
3217 ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
3219 PFORMAT_STRING desc;
3222 while (*pFormat != RPC_FC_END) {
3244 case RPC_FC_POINTER:
3245 size += sizeof(void *);
3247 case RPC_FC_ALIGNM2:
3248 ALIGN_LENGTH(size, 2);
3250 case RPC_FC_ALIGNM4:
3251 ALIGN_LENGTH(size, 4);
3253 case RPC_FC_ALIGNM8:
3254 ALIGN_LENGTH(size, 8);
3256 case RPC_FC_STRUCTPAD1:
3257 case RPC_FC_STRUCTPAD2:
3258 case RPC_FC_STRUCTPAD3:
3259 case RPC_FC_STRUCTPAD4:
3260 case RPC_FC_STRUCTPAD5:
3261 case RPC_FC_STRUCTPAD6:
3262 case RPC_FC_STRUCTPAD7:
3263 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3265 case RPC_FC_EMBEDDED_COMPLEX:
3268 desc = pFormat + *(const SHORT*)pFormat;
3269 size += EmbeddedComplexSize(pStubMsg, desc);
3275 FIXME("unhandled format 0x%02x\n", *pFormat);
3283 /***********************************************************************
3284 * NdrComplexStructMarshall [RPCRT4.@]
3286 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3287 unsigned char *pMemory,
3288 PFORMAT_STRING pFormat)
3290 PFORMAT_STRING conf_array = NULL;
3291 PFORMAT_STRING pointer_desc = NULL;
3292 unsigned char *OldMemory = pStubMsg->Memory;
3293 int pointer_buffer_mark_set = 0;
3295 ULONG max_count = 0;
3298 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3300 if (!pStubMsg->PointerBufferMark)
3302 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3303 /* save buffer length */
3304 ULONG saved_buffer_length = pStubMsg->BufferLength;
3306 /* get the buffer pointer after complex array data, but before
3308 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3309 pStubMsg->IgnoreEmbeddedPointers = 1;
3310 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3311 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3313 /* save it for use by embedded pointer code later */
3314 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3315 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - pStubMsg->Buffer));
3316 pointer_buffer_mark_set = 1;
3318 /* restore the original buffer length */
3319 pStubMsg->BufferLength = saved_buffer_length;
3322 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
3325 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3327 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3330 pStubMsg->Memory = pMemory;
3334 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3335 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3336 pMemory + struct_size, conf_array);
3337 /* these could be changed in ComplexMarshall so save them for later */
3338 max_count = pStubMsg->MaxCount;
3339 count = pStubMsg->ActualCount;
3340 offset = pStubMsg->Offset;
3343 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3347 pStubMsg->MaxCount = max_count;
3348 pStubMsg->ActualCount = count;
3349 pStubMsg->Offset = offset;
3350 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3351 conf_array, TRUE /* fHasPointers */);
3354 pStubMsg->Memory = OldMemory;
3356 if (pointer_buffer_mark_set)
3358 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3359 pStubMsg->PointerBufferMark = NULL;
3362 STD_OVERFLOW_CHECK(pStubMsg);
3367 /***********************************************************************
3368 * NdrComplexStructUnmarshall [RPCRT4.@]
3370 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3371 unsigned char **ppMemory,
3372 PFORMAT_STRING pFormat,
3373 unsigned char fMustAlloc)
3375 unsigned size = *(const WORD*)(pFormat+2);
3376 PFORMAT_STRING conf_array = NULL;
3377 PFORMAT_STRING pointer_desc = NULL;
3378 unsigned char *pMemory;
3379 int pointer_buffer_mark_set = 0;
3381 ULONG max_count = 0;
3383 ULONG array_size = 0;
3385 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3387 if (!pStubMsg->PointerBufferMark)
3389 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3390 /* save buffer pointer */
3391 unsigned char *saved_buffer = pStubMsg->Buffer;
3393 /* get the buffer pointer after complex array data, but before
3395 pStubMsg->IgnoreEmbeddedPointers = 1;
3396 NdrComplexStructMemorySize(pStubMsg, pFormat);
3397 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3399 /* save it for use by embedded pointer code later */
3400 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3401 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - saved_buffer));
3402 pointer_buffer_mark_set = 1;
3404 /* restore the original buffer */
3405 pStubMsg->Buffer = saved_buffer;
3408 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3411 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3413 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3418 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3421 /* these could be changed in ComplexMarshall so save them for later */
3422 max_count = pStubMsg->MaxCount;
3423 count = pStubMsg->ActualCount;
3424 offset = pStubMsg->Offset;
3427 if (!fMustAlloc && !*ppMemory)
3430 *ppMemory = NdrAllocate(pStubMsg, size);
3432 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3436 pStubMsg->MaxCount = max_count;
3437 pStubMsg->ActualCount = count;
3438 pStubMsg->Offset = offset;
3440 memset(pMemory, 0, array_size);
3441 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3443 FALSE /* fUseBufferMemoryServer */,
3444 TRUE /* fUnmarshall */);
3447 if (pointer_buffer_mark_set)
3449 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3450 pStubMsg->PointerBufferMark = NULL;
3456 /***********************************************************************
3457 * NdrComplexStructBufferSize [RPCRT4.@]
3459 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3460 unsigned char *pMemory,
3461 PFORMAT_STRING pFormat)
3463 PFORMAT_STRING conf_array = NULL;
3464 PFORMAT_STRING pointer_desc = NULL;
3465 unsigned char *OldMemory = pStubMsg->Memory;
3466 int pointer_length_set = 0;
3468 ULONG max_count = 0;
3471 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3473 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
3475 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3477 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3478 ULONG saved_buffer_length = pStubMsg->BufferLength;
3480 /* get the buffer length after complex struct data, but before
3482 pStubMsg->IgnoreEmbeddedPointers = 1;
3483 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3484 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3486 /* save it for use by embedded pointer code later */
3487 pStubMsg->PointerLength = pStubMsg->BufferLength;
3488 pointer_length_set = 1;
3489 TRACE("difference = 0x%x\n", pStubMsg->PointerLength - saved_buffer_length);
3491 /* restore the original buffer length */
3492 pStubMsg->BufferLength = saved_buffer_length;
3496 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3498 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3501 pStubMsg->Memory = pMemory;
3505 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3506 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3509 /* these could be changed in ComplexMarshall so save them for later */
3510 max_count = pStubMsg->MaxCount;
3511 count = pStubMsg->ActualCount;
3512 offset = pStubMsg->Offset;
3515 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3519 pStubMsg->MaxCount = max_count;
3520 pStubMsg->ActualCount = count;
3521 pStubMsg->Offset = offset;
3522 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3523 TRUE /* fHasPointers */);
3526 pStubMsg->Memory = OldMemory;
3528 if(pointer_length_set)
3530 pStubMsg->BufferLength = pStubMsg->PointerLength;
3531 pStubMsg->PointerLength = 0;
3536 /***********************************************************************
3537 * NdrComplexStructMemorySize [RPCRT4.@]
3539 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3540 PFORMAT_STRING pFormat)
3542 unsigned size = *(const WORD*)(pFormat+2);
3543 PFORMAT_STRING conf_array = NULL;
3544 PFORMAT_STRING pointer_desc = NULL;
3546 ULONG max_count = 0;
3549 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3551 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3554 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3556 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3561 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3563 /* these could be changed in ComplexStructMemorySize so save them for
3565 max_count = pStubMsg->MaxCount;
3566 count = pStubMsg->ActualCount;
3567 offset = pStubMsg->Offset;
3570 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3574 pStubMsg->MaxCount = max_count;
3575 pStubMsg->ActualCount = count;
3576 pStubMsg->Offset = offset;
3577 array_memory_size(conf_array[0], pStubMsg, conf_array,
3578 TRUE /* fHasPointers */);
3584 /***********************************************************************
3585 * NdrComplexStructFree [RPCRT4.@]
3587 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3588 unsigned char *pMemory,
3589 PFORMAT_STRING pFormat)
3591 PFORMAT_STRING conf_array = NULL;
3592 PFORMAT_STRING pointer_desc = NULL;
3593 unsigned char *OldMemory = pStubMsg->Memory;
3595 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3598 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3600 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3603 pStubMsg->Memory = pMemory;
3605 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3608 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3609 TRUE /* fHasPointers */);
3611 pStubMsg->Memory = OldMemory;
3614 /***********************************************************************
3615 * NdrConformantArrayMarshall [RPCRT4.@]
3617 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3618 unsigned char *pMemory,
3619 PFORMAT_STRING pFormat)
3621 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3622 if (pFormat[0] != RPC_FC_CARRAY)
3624 ERR("invalid format = 0x%x\n", pFormat[0]);
3625 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3628 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory,
3630 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3631 TRUE /* fHasPointers */);
3636 /***********************************************************************
3637 * NdrConformantArrayUnmarshall [RPCRT4.@]
3639 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3640 unsigned char **ppMemory,
3641 PFORMAT_STRING pFormat,
3642 unsigned char fMustAlloc)
3644 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3645 if (pFormat[0] != RPC_FC_CARRAY)
3647 ERR("invalid format = 0x%x\n", pFormat[0]);
3648 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3651 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3652 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat,
3654 TRUE /* fUseBufferMemoryServer */,
3655 TRUE /* fUnmarshall */);
3660 /***********************************************************************
3661 * NdrConformantArrayBufferSize [RPCRT4.@]
3663 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3664 unsigned char *pMemory,
3665 PFORMAT_STRING pFormat)
3667 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3668 if (pFormat[0] != RPC_FC_CARRAY)
3670 ERR("invalid format = 0x%x\n", pFormat[0]);
3671 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3674 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat);
3675 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3676 TRUE /* fHasPointers */);
3679 /***********************************************************************
3680 * NdrConformantArrayMemorySize [RPCRT4.@]
3682 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3683 PFORMAT_STRING pFormat)
3685 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3686 if (pFormat[0] != RPC_FC_CARRAY)
3688 ERR("invalid format = 0x%x\n", pFormat[0]);
3689 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3692 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3693 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
3695 return pStubMsg->MemorySize;
3698 /***********************************************************************
3699 * NdrConformantArrayFree [RPCRT4.@]
3701 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3702 unsigned char *pMemory,
3703 PFORMAT_STRING pFormat)
3705 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3706 if (pFormat[0] != RPC_FC_CARRAY)
3708 ERR("invalid format = 0x%x\n", pFormat[0]);
3709 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3712 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3713 TRUE /* fHasPointers */);
3717 /***********************************************************************
3718 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3720 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
3721 unsigned char* pMemory,
3722 PFORMAT_STRING pFormat )
3724 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3726 if (pFormat[0] != RPC_FC_CVARRAY)
3728 ERR("invalid format type %x\n", pFormat[0]);
3729 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3733 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3735 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory,
3736 pFormat, TRUE /* fHasPointers */);
3742 /***********************************************************************
3743 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3745 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
3746 unsigned char** ppMemory,
3747 PFORMAT_STRING pFormat,
3748 unsigned char fMustAlloc )
3750 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3752 if (pFormat[0] != RPC_FC_CVARRAY)
3754 ERR("invalid format type %x\n", pFormat[0]);
3755 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3759 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3760 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory,
3761 pFormat, fMustAlloc,
3762 TRUE /* fUseBufferMemoryServer */,
3763 TRUE /* fUnmarshall */);
3769 /***********************************************************************
3770 * NdrConformantVaryingArrayFree [RPCRT4.@]
3772 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
3773 unsigned char* pMemory,
3774 PFORMAT_STRING pFormat )
3776 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3778 if (pFormat[0] != RPC_FC_CVARRAY)
3780 ERR("invalid format type %x\n", pFormat[0]);
3781 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3785 array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3786 TRUE /* fHasPointers */);
3790 /***********************************************************************
3791 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3793 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
3794 unsigned char* pMemory, PFORMAT_STRING pFormat )
3796 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3798 if (pFormat[0] != RPC_FC_CVARRAY)
3800 ERR("invalid format type %x\n", pFormat[0]);
3801 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3805 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3807 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3808 TRUE /* fHasPointers */);
3812 /***********************************************************************
3813 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3815 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
3816 PFORMAT_STRING pFormat )
3818 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3820 if (pFormat[0] != RPC_FC_CVARRAY)
3822 ERR("invalid format type %x\n", pFormat[0]);
3823 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3824 return pStubMsg->MemorySize;
3827 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3828 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat,
3829 TRUE /* fHasPointers */);
3831 return pStubMsg->MemorySize;
3835 /***********************************************************************
3836 * NdrComplexArrayMarshall [RPCRT4.@]
3838 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3839 unsigned char *pMemory,
3840 PFORMAT_STRING pFormat)
3842 ULONG i, count, def;
3843 BOOL variance_present;
3844 unsigned char alignment;
3845 int pointer_buffer_mark_set = 0;
3847 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3849 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3851 ERR("invalid format type %x\n", pFormat[0]);
3852 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3856 alignment = pFormat[1] + 1;
3858 if (!pStubMsg->PointerBufferMark)
3860 /* save buffer fields that may be changed by buffer sizer functions
3861 * and that may be needed later on */
3862 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3863 ULONG saved_buffer_length = pStubMsg->BufferLength;
3864 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
3865 ULONG saved_offset = pStubMsg->Offset;
3866 ULONG saved_actual_count = pStubMsg->ActualCount;
3868 /* get the buffer pointer after complex array data, but before
3870 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3871 pStubMsg->IgnoreEmbeddedPointers = 1;
3872 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3873 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3875 /* save it for use by embedded pointer code later */
3876 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3877 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer));
3878 pointer_buffer_mark_set = 1;
3880 /* restore fields */
3881 pStubMsg->ActualCount = saved_actual_count;
3882 pStubMsg->Offset = saved_offset;
3883 pStubMsg->MaxCount = saved_max_count;
3884 pStubMsg->BufferLength = saved_buffer_length;
3887 def = *(const WORD*)&pFormat[2];
3890 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3891 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3893 variance_present = IsConformanceOrVariancePresent(pFormat);
3894 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3895 TRACE("variance = %d\n", pStubMsg->ActualCount);
3897 WriteConformance(pStubMsg);
3898 if (variance_present)
3899 WriteVariance(pStubMsg);
3901 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3903 count = pStubMsg->ActualCount;
3904 for (i = 0; i < count; i++)
3905 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3907 STD_OVERFLOW_CHECK(pStubMsg);
3909 if (pointer_buffer_mark_set)
3911 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3912 pStubMsg->PointerBufferMark = NULL;
3918 /***********************************************************************
3919 * NdrComplexArrayUnmarshall [RPCRT4.@]
3921 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3922 unsigned char **ppMemory,
3923 PFORMAT_STRING pFormat,
3924 unsigned char fMustAlloc)
3926 ULONG i, count, size;
3927 unsigned char alignment;
3928 unsigned char *pMemory;
3929 unsigned char *saved_buffer;
3930 int pointer_buffer_mark_set = 0;
3931 int saved_ignore_embedded;
3933 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3935 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3937 ERR("invalid format type %x\n", pFormat[0]);
3938 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3942 alignment = pFormat[1] + 1;
3944 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3945 /* save buffer pointer */
3946 saved_buffer = pStubMsg->Buffer;
3947 /* get the buffer pointer after complex array data, but before
3949 pStubMsg->IgnoreEmbeddedPointers = 1;
3950 pStubMsg->MemorySize = 0;
3951 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3952 size = pStubMsg->MemorySize;
3953 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3955 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - saved_buffer));
3956 if (!pStubMsg->PointerBufferMark)
3958 /* save it for use by embedded pointer code later */
3959 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3960 pointer_buffer_mark_set = 1;
3962 /* restore the original buffer */
3963 pStubMsg->Buffer = saved_buffer;
3967 pFormat = ReadConformance(pStubMsg, pFormat);
3968 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3970 if (!fMustAlloc && !*ppMemory)
3973 *ppMemory = NdrAllocate(pStubMsg, size);
3975 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3977 pMemory = *ppMemory;
3978 count = pStubMsg->ActualCount;
3979 for (i = 0; i < count; i++)
3980 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
3982 if (pointer_buffer_mark_set)
3984 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3985 pStubMsg->PointerBufferMark = NULL;
3991 /***********************************************************************
3992 * NdrComplexArrayBufferSize [RPCRT4.@]
3994 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3995 unsigned char *pMemory,
3996 PFORMAT_STRING pFormat)
3998 ULONG i, count, def;
3999 unsigned char alignment;
4000 BOOL variance_present;
4001 int pointer_length_set = 0;
4003 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4005 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4007 ERR("invalid format type %x\n", pFormat[0]);
4008 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4012 alignment = pFormat[1] + 1;
4014 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
4016 /* save buffer fields that may be changed by buffer sizer functions
4017 * and that may be needed later on */
4018 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4019 ULONG saved_buffer_length = pStubMsg->BufferLength;
4020 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4021 ULONG saved_offset = pStubMsg->Offset;
4022 ULONG saved_actual_count = pStubMsg->ActualCount;
4024 /* get the buffer pointer after complex array data, but before
4026 pStubMsg->IgnoreEmbeddedPointers = 1;
4027 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4028 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4030 /* save it for use by embedded pointer code later */
4031 pStubMsg->PointerLength = pStubMsg->BufferLength;
4032 pointer_length_set = 1;
4034 /* restore fields */
4035 pStubMsg->ActualCount = saved_actual_count;
4036 pStubMsg->Offset = saved_offset;
4037 pStubMsg->MaxCount = saved_max_count;
4038 pStubMsg->BufferLength = saved_buffer_length;
4040 def = *(const WORD*)&pFormat[2];
4043 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4044 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4045 SizeConformance(pStubMsg);
4047 variance_present = IsConformanceOrVariancePresent(pFormat);
4048 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4049 TRACE("variance = %d\n", pStubMsg->ActualCount);
4051 if (variance_present)
4052 SizeVariance(pStubMsg);
4054 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4056 count = pStubMsg->ActualCount;
4057 for (i = 0; i < count; i++)
4058 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
4060 if(pointer_length_set)
4062 pStubMsg->BufferLength = pStubMsg->PointerLength;
4063 pStubMsg->PointerLength = 0;
4067 /***********************************************************************
4068 * NdrComplexArrayMemorySize [RPCRT4.@]
4070 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4071 PFORMAT_STRING pFormat)
4073 ULONG i, count, esize, SavedMemorySize, MemorySize;
4074 unsigned char alignment;
4076 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4078 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4080 ERR("invalid format type %x\n", pFormat[0]);
4081 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4085 alignment = pFormat[1] + 1;
4089 pFormat = ReadConformance(pStubMsg, pFormat);
4090 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
4092 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4094 SavedMemorySize = pStubMsg->MemorySize;
4096 esize = ComplexStructSize(pStubMsg, pFormat);
4098 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
4100 count = pStubMsg->ActualCount;
4101 for (i = 0; i < count; i++)
4102 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
4104 pStubMsg->MemorySize = SavedMemorySize;
4106 pStubMsg->MemorySize += MemorySize;
4110 /***********************************************************************
4111 * NdrComplexArrayFree [RPCRT4.@]
4113 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4114 unsigned char *pMemory,
4115 PFORMAT_STRING pFormat)
4117 ULONG i, count, def;
4119 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4121 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4123 ERR("invalid format type %x\n", pFormat[0]);
4124 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4128 def = *(const WORD*)&pFormat[2];
4131 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4132 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4134 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4135 TRACE("variance = %d\n", pStubMsg->ActualCount);
4137 count = pStubMsg->ActualCount;
4138 for (i = 0; i < count; i++)
4139 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4142 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4143 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4144 USER_MARSHAL_CB *umcb)
4146 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4147 pStubMsg->RpcMsg->DataRepresentation);
4148 umcb->pStubMsg = pStubMsg;
4149 umcb->pReserve = NULL;
4150 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4151 umcb->CBType = cbtype;
4152 umcb->pFormat = pFormat;
4153 umcb->pTypeFormat = NULL /* FIXME */;
4156 #define USER_MARSHAL_PTR_PREFIX \
4157 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4158 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4160 /***********************************************************************
4161 * NdrUserMarshalMarshall [RPCRT4.@]
4163 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4164 unsigned char *pMemory,
4165 PFORMAT_STRING pFormat)
4167 unsigned flags = pFormat[1];
4168 unsigned index = *(const WORD*)&pFormat[2];
4169 unsigned char *saved_buffer = NULL;
4170 USER_MARSHAL_CB umcb;
4172 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4173 TRACE("index=%d\n", index);
4175 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4177 if (flags & USER_MARSHAL_POINTER)
4179 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
4180 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4181 pStubMsg->Buffer += 4;
4182 if (pStubMsg->PointerBufferMark)
4184 saved_buffer = pStubMsg->Buffer;
4185 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4186 pStubMsg->PointerBufferMark = NULL;
4188 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
4191 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
4194 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4195 &umcb.Flags, pStubMsg->Buffer, pMemory);
4199 STD_OVERFLOW_CHECK(pStubMsg);
4200 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4201 pStubMsg->Buffer = saved_buffer;
4204 STD_OVERFLOW_CHECK(pStubMsg);
4209 /***********************************************************************
4210 * NdrUserMarshalUnmarshall [RPCRT4.@]
4212 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4213 unsigned char **ppMemory,
4214 PFORMAT_STRING pFormat,
4215 unsigned char fMustAlloc)
4217 unsigned flags = pFormat[1];
4218 unsigned index = *(const WORD*)&pFormat[2];
4219 DWORD memsize = *(const WORD*)&pFormat[4];
4220 unsigned char *saved_buffer = NULL;
4221 USER_MARSHAL_CB umcb;
4223 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4224 TRACE("index=%d\n", index);
4226 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4228 if (flags & USER_MARSHAL_POINTER)
4230 ALIGN_POINTER(pStubMsg->Buffer, 4);
4231 /* skip pointer prefix */
4232 pStubMsg->Buffer += 4;
4233 if (pStubMsg->PointerBufferMark)
4235 saved_buffer = pStubMsg->Buffer;
4236 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4237 pStubMsg->PointerBufferMark = NULL;
4239 ALIGN_POINTER(pStubMsg->Buffer, 8);
4242 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4244 if (!fMustAlloc && !*ppMemory)
4248 *ppMemory = NdrAllocate(pStubMsg, memsize);
4249 memset(*ppMemory, 0, memsize);
4253 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4254 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4258 STD_OVERFLOW_CHECK(pStubMsg);
4259 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4260 pStubMsg->Buffer = saved_buffer;
4266 /***********************************************************************
4267 * NdrUserMarshalBufferSize [RPCRT4.@]
4269 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4270 unsigned char *pMemory,
4271 PFORMAT_STRING pFormat)
4273 unsigned flags = pFormat[1];
4274 unsigned index = *(const WORD*)&pFormat[2];
4275 DWORD bufsize = *(const WORD*)&pFormat[6];
4276 USER_MARSHAL_CB umcb;
4277 ULONG saved_buffer_length = 0;
4279 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4280 TRACE("index=%d\n", index);
4282 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4284 if (flags & USER_MARSHAL_POINTER)
4286 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4287 /* skip pointer prefix */
4288 safe_buffer_length_increment(pStubMsg, 4);
4289 if (pStubMsg->IgnoreEmbeddedPointers)
4291 if (pStubMsg->PointerLength)
4293 saved_buffer_length = pStubMsg->BufferLength;
4294 pStubMsg->BufferLength = pStubMsg->PointerLength;
4295 pStubMsg->PointerLength = 0;
4297 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
4300 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
4303 TRACE("size=%d\n", bufsize);
4304 safe_buffer_length_increment(pStubMsg, bufsize);
4307 pStubMsg->BufferLength =
4308 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4309 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4311 if (saved_buffer_length)
4313 pStubMsg->PointerLength = pStubMsg->BufferLength;
4314 pStubMsg->BufferLength = saved_buffer_length;
4319 /***********************************************************************
4320 * NdrUserMarshalMemorySize [RPCRT4.@]
4322 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4323 PFORMAT_STRING pFormat)
4325 unsigned flags = pFormat[1];
4326 unsigned index = *(const WORD*)&pFormat[2];
4327 DWORD memsize = *(const WORD*)&pFormat[4];
4328 DWORD bufsize = *(const WORD*)&pFormat[6];
4330 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4331 TRACE("index=%d\n", index);
4333 pStubMsg->MemorySize += memsize;
4335 if (flags & USER_MARSHAL_POINTER)
4337 ALIGN_POINTER(pStubMsg->Buffer, 4);
4338 /* skip pointer prefix */
4339 pStubMsg->Buffer += 4;
4340 if (pStubMsg->IgnoreEmbeddedPointers)
4341 return pStubMsg->MemorySize;
4342 ALIGN_POINTER(pStubMsg->Buffer, 8);
4345 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4348 FIXME("not implemented for varying buffer size\n");
4350 pStubMsg->Buffer += bufsize;
4352 return pStubMsg->MemorySize;
4355 /***********************************************************************
4356 * NdrUserMarshalFree [RPCRT4.@]
4358 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4359 unsigned char *pMemory,
4360 PFORMAT_STRING pFormat)
4362 /* unsigned flags = pFormat[1]; */
4363 unsigned index = *(const WORD*)&pFormat[2];
4364 USER_MARSHAL_CB umcb;
4366 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4367 TRACE("index=%d\n", index);
4369 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4371 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4372 &umcb.Flags, pMemory);
4375 /***********************************************************************
4376 * NdrGetUserMarshalInfo [RPCRT4.@]
4378 RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi)
4380 USER_MARSHAL_CB *umcb = CONTAINING_RECORD(flags, USER_MARSHAL_CB, Flags);
4382 TRACE("(%p,%u,%p)\n", flags, level, umi);
4385 return RPC_S_INVALID_ARG;
4387 memset(&umi->u1.Level1, 0, sizeof(umi->u1.Level1));
4388 umi->InformationLevel = level;
4390 if (umcb->Signature != USER_MARSHAL_CB_SIGNATURE)
4391 return RPC_S_INVALID_ARG;
4393 umi->u1.Level1.pfnAllocate = umcb->pStubMsg->pfnAllocate;
4394 umi->u1.Level1.pfnFree = umcb->pStubMsg->pfnFree;
4395 umi->u1.Level1.pRpcChannelBuffer = umcb->pStubMsg->pRpcChannelBuffer;
4397 switch (umcb->CBType)
4399 case USER_MARSHAL_CB_MARSHALL:
4400 case USER_MARSHAL_CB_UNMARSHALL:
4402 RPC_MESSAGE *msg = umcb->pStubMsg->RpcMsg;
4403 unsigned char *buffer_start = msg->Buffer;
4404 unsigned char *buffer_end =
4405 (unsigned char *)msg->Buffer + msg->BufferLength;
4407 if (umcb->pStubMsg->Buffer < buffer_start ||
4408 umcb->pStubMsg->Buffer > buffer_end)
4409 return ERROR_INVALID_USER_BUFFER;
4411 umi->u1.Level1.Buffer = umcb->pStubMsg->Buffer;
4412 umi->u1.Level1.BufferSize = buffer_end - umcb->pStubMsg->Buffer;
4415 case USER_MARSHAL_CB_BUFFER_SIZE:
4416 case USER_MARSHAL_CB_FREE:
4419 WARN("unrecognised CBType %d\n", umcb->CBType);
4425 /***********************************************************************
4426 * NdrClearOutParameters [RPCRT4.@]
4428 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4429 PFORMAT_STRING pFormat,
4432 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4435 /***********************************************************************
4436 * NdrConvert [RPCRT4.@]
4438 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4440 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4441 /* FIXME: since this stub doesn't do any converting, the proper behavior
4442 is to raise an exception */
4445 /***********************************************************************
4446 * NdrConvert2 [RPCRT4.@]
4448 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4450 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4451 pStubMsg, pFormat, NumberParams);
4452 /* FIXME: since this stub doesn't do any converting, the proper behavior
4453 is to raise an exception */
4456 #include "pshpack1.h"
4457 typedef struct _NDR_CSTRUCT_FORMAT
4460 unsigned char alignment;
4461 unsigned short memory_size;
4462 short offset_to_array_description;
4463 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4464 #include "poppack.h"
4466 /***********************************************************************
4467 * NdrConformantStructMarshall [RPCRT4.@]
4469 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4470 unsigned char *pMemory,
4471 PFORMAT_STRING pFormat)
4473 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4474 PFORMAT_STRING pCArrayFormat;
4475 ULONG esize, bufsize;
4477 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4479 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4480 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4482 ERR("invalid format type %x\n", pCStructFormat->type);
4483 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4487 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4488 pCStructFormat->offset_to_array_description;
4489 if (*pCArrayFormat != RPC_FC_CARRAY)
4491 ERR("invalid array format type %x\n", pCStructFormat->type);
4492 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4495 esize = *(const WORD*)(pCArrayFormat+2);
4497 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4498 pCArrayFormat + 4, 0);
4500 WriteConformance(pStubMsg);
4502 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4504 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4506 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4507 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4509 ERR("integer overflow of memory_size %u with bufsize %u\n",
4510 pCStructFormat->memory_size, bufsize);
4511 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4513 /* copy constant sized part of struct */
4514 pStubMsg->BufferMark = pStubMsg->Buffer;
4515 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4517 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4518 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4523 /***********************************************************************
4524 * NdrConformantStructUnmarshall [RPCRT4.@]
4526 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4527 unsigned char **ppMemory,
4528 PFORMAT_STRING pFormat,
4529 unsigned char fMustAlloc)
4531 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4532 PFORMAT_STRING pCArrayFormat;
4533 ULONG esize, bufsize;
4534 unsigned char *saved_buffer;
4536 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4538 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4539 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4541 ERR("invalid format type %x\n", pCStructFormat->type);
4542 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4545 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4546 pCStructFormat->offset_to_array_description;
4547 if (*pCArrayFormat != RPC_FC_CARRAY)
4549 ERR("invalid array format type %x\n", pCStructFormat->type);
4550 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4553 esize = *(const WORD*)(pCArrayFormat+2);
4555 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4557 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4559 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4561 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4562 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4564 ERR("integer overflow of memory_size %u with bufsize %u\n",
4565 pCStructFormat->memory_size, bufsize);
4566 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4571 SIZE_T size = pCStructFormat->memory_size + bufsize;
4572 *ppMemory = NdrAllocate(pStubMsg, size);
4576 if (!pStubMsg->IsClient && !*ppMemory)
4577 /* for servers, we just point straight into the RPC buffer */
4578 *ppMemory = pStubMsg->Buffer;
4581 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4582 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4583 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4584 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4586 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4587 if (*ppMemory != saved_buffer)
4588 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4593 /***********************************************************************
4594 * NdrConformantStructBufferSize [RPCRT4.@]
4596 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4597 unsigned char *pMemory,
4598 PFORMAT_STRING pFormat)
4600 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4601 PFORMAT_STRING pCArrayFormat;
4604 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4606 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4607 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4609 ERR("invalid format type %x\n", pCStructFormat->type);
4610 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4613 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4614 pCStructFormat->offset_to_array_description;
4615 if (*pCArrayFormat != RPC_FC_CARRAY)
4617 ERR("invalid array format type %x\n", pCStructFormat->type);
4618 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4621 esize = *(const WORD*)(pCArrayFormat+2);
4623 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4624 SizeConformance(pStubMsg);
4626 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4628 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4630 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4631 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4633 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4634 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4637 /***********************************************************************
4638 * NdrConformantStructMemorySize [RPCRT4.@]
4640 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4641 PFORMAT_STRING pFormat)
4647 /***********************************************************************
4648 * NdrConformantStructFree [RPCRT4.@]
4650 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4651 unsigned char *pMemory,
4652 PFORMAT_STRING pFormat)
4654 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4655 PFORMAT_STRING pCArrayFormat;
4657 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4659 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4660 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4662 ERR("invalid format type %x\n", pCStructFormat->type);
4663 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4667 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4668 pCStructFormat->offset_to_array_description;
4669 if (*pCArrayFormat != RPC_FC_CARRAY)
4671 ERR("invalid array format type %x\n", pCStructFormat->type);
4672 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4676 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4677 pCArrayFormat + 4, 0);
4679 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4681 /* copy constant sized part of struct */
4682 pStubMsg->BufferMark = pStubMsg->Buffer;
4684 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4685 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4688 /***********************************************************************
4689 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4691 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4692 unsigned char *pMemory,
4693 PFORMAT_STRING pFormat)
4695 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4696 PFORMAT_STRING pCVArrayFormat;
4698 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4700 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4701 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4703 ERR("invalid format type %x\n", pCVStructFormat->type);
4704 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4708 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4709 pCVStructFormat->offset_to_array_description;
4711 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4712 pMemory + pCVStructFormat->memory_size,
4715 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4717 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4719 /* write constant sized part */
4720 pStubMsg->BufferMark = pStubMsg->Buffer;
4721 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4723 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4724 pMemory + pCVStructFormat->memory_size,
4725 pCVArrayFormat, FALSE /* fHasPointers */);
4727 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4732 /***********************************************************************
4733 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4735 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4736 unsigned char **ppMemory,
4737 PFORMAT_STRING pFormat,
4738 unsigned char fMustAlloc)
4740 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4741 PFORMAT_STRING pCVArrayFormat;
4742 ULONG memsize, bufsize;
4743 unsigned char *saved_buffer, *saved_array_buffer;
4745 unsigned char *array_memory;
4747 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4749 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4750 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4752 ERR("invalid format type %x\n", pCVStructFormat->type);
4753 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4757 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4758 pCVStructFormat->offset_to_array_description;
4760 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4763 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4765 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4767 /* work out how much memory to allocate if we need to do so */
4768 if (!fMustAlloc && !*ppMemory)
4772 SIZE_T size = pCVStructFormat->memory_size + memsize;
4773 *ppMemory = NdrAllocate(pStubMsg, size);
4776 /* mark the start of the constant data */
4777 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4778 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4780 array_memory = *ppMemory + pCVStructFormat->memory_size;
4781 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
4782 &array_memory, pCVArrayFormat,
4783 FALSE /* fMustAlloc */,
4784 FALSE /* fUseServerBufferMemory */,
4785 FALSE /* fUnmarshall */);
4787 /* save offset in case unmarshalling pointers changes it */
4788 offset = pStubMsg->Offset;
4790 /* mark the start of the array data */
4791 saved_array_buffer = pStubMsg->Buffer;
4792 safe_buffer_increment(pStubMsg, bufsize);
4794 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4796 /* copy the constant data */
4797 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
4798 /* copy the array data */
4799 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
4800 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
4801 saved_array_buffer, bufsize);
4803 if (*pCVArrayFormat == RPC_FC_C_CSTRING)
4804 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
4805 else if (*pCVArrayFormat == RPC_FC_C_WSTRING)
4806 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
4811 /***********************************************************************
4812 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4814 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4815 unsigned char *pMemory,
4816 PFORMAT_STRING pFormat)
4818 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4819 PFORMAT_STRING pCVArrayFormat;
4821 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4823 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4824 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4826 ERR("invalid format type %x\n", pCVStructFormat->type);
4827 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4831 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4832 pCVStructFormat->offset_to_array_description;
4833 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
4834 pMemory + pCVStructFormat->memory_size,
4837 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4839 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4841 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4843 array_buffer_size(*pCVArrayFormat, pStubMsg,
4844 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4845 FALSE /* fHasPointers */);
4847 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4850 /***********************************************************************
4851 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4853 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4854 PFORMAT_STRING pFormat)
4856 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4857 PFORMAT_STRING pCVArrayFormat;
4859 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4861 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4862 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4864 ERR("invalid format type %x\n", pCVStructFormat->type);
4865 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4869 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4870 pCVStructFormat->offset_to_array_description;
4871 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
4873 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4875 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4877 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4878 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
4879 FALSE /* fHasPointers */);
4881 pStubMsg->MemorySize += pCVStructFormat->memory_size;
4883 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4885 return pStubMsg->MemorySize;
4888 /***********************************************************************
4889 * NdrConformantVaryingStructFree [RPCRT4.@]
4891 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4892 unsigned char *pMemory,
4893 PFORMAT_STRING pFormat)
4895 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4896 PFORMAT_STRING pCVArrayFormat;
4898 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4900 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4901 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4903 ERR("invalid format type %x\n", pCVStructFormat->type);
4904 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4908 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4909 pCVStructFormat->offset_to_array_description;
4910 array_free(*pCVArrayFormat, pStubMsg,
4911 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4912 FALSE /* fHasPointers */);
4914 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4916 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4919 #include "pshpack1.h"
4923 unsigned char alignment;
4924 unsigned short total_size;
4925 } NDR_SMFARRAY_FORMAT;
4930 unsigned char alignment;
4932 } NDR_LGFARRAY_FORMAT;
4933 #include "poppack.h"
4935 /***********************************************************************
4936 * NdrFixedArrayMarshall [RPCRT4.@]
4938 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4939 unsigned char *pMemory,
4940 PFORMAT_STRING pFormat)
4942 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4945 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4947 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4948 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4950 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4951 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4955 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4957 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4959 total_size = pSmFArrayFormat->total_size;
4960 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4964 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4965 total_size = pLgFArrayFormat->total_size;
4966 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4969 pStubMsg->BufferMark = pStubMsg->Buffer;
4970 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4972 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4977 /***********************************************************************
4978 * NdrFixedArrayUnmarshall [RPCRT4.@]
4980 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4981 unsigned char **ppMemory,
4982 PFORMAT_STRING pFormat,
4983 unsigned char fMustAlloc)
4985 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4987 unsigned char *saved_buffer;
4989 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4991 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4992 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4994 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4995 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4999 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5001 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5003 total_size = pSmFArrayFormat->total_size;
5004 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5008 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5009 total_size = pLgFArrayFormat->total_size;
5010 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5014 *ppMemory = NdrAllocate(pStubMsg, total_size);
5017 if (!pStubMsg->IsClient && !*ppMemory)
5018 /* for servers, we just point straight into the RPC buffer */
5019 *ppMemory = pStubMsg->Buffer;
5022 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5023 safe_buffer_increment(pStubMsg, total_size);
5024 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5026 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
5027 if (*ppMemory != saved_buffer)
5028 memcpy(*ppMemory, saved_buffer, total_size);
5033 /***********************************************************************
5034 * NdrFixedArrayBufferSize [RPCRT4.@]
5036 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5037 unsigned char *pMemory,
5038 PFORMAT_STRING pFormat)
5040 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5043 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5045 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5046 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5048 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5049 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5053 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
5055 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5057 total_size = pSmFArrayFormat->total_size;
5058 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5062 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5063 total_size = pLgFArrayFormat->total_size;
5064 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5066 safe_buffer_length_increment(pStubMsg, total_size);
5068 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5071 /***********************************************************************
5072 * NdrFixedArrayMemorySize [RPCRT4.@]
5074 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5075 PFORMAT_STRING pFormat)
5077 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5080 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5082 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5083 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5085 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5086 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5090 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5092 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5094 total_size = pSmFArrayFormat->total_size;
5095 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5099 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5100 total_size = pLgFArrayFormat->total_size;
5101 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5103 pStubMsg->BufferMark = pStubMsg->Buffer;
5104 safe_buffer_increment(pStubMsg, total_size);
5105 pStubMsg->MemorySize += total_size;
5107 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5112 /***********************************************************************
5113 * NdrFixedArrayFree [RPCRT4.@]
5115 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5116 unsigned char *pMemory,
5117 PFORMAT_STRING pFormat)
5119 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5121 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5123 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5124 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5126 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5127 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5131 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5132 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5135 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5136 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5139 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5142 /***********************************************************************
5143 * NdrVaryingArrayMarshall [RPCRT4.@]
5145 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5146 unsigned char *pMemory,
5147 PFORMAT_STRING pFormat)
5149 unsigned char alignment;
5150 DWORD elements, esize;
5153 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5155 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5156 (pFormat[0] != RPC_FC_LGVARRAY))
5158 ERR("invalid format type %x\n", pFormat[0]);
5159 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5163 alignment = pFormat[1] + 1;
5165 if (pFormat[0] == RPC_FC_SMVARRAY)
5168 pFormat += sizeof(WORD);
5169 elements = *(const WORD*)pFormat;
5170 pFormat += sizeof(WORD);
5175 pFormat += sizeof(DWORD);
5176 elements = *(const DWORD*)pFormat;
5177 pFormat += sizeof(DWORD);
5180 esize = *(const WORD*)pFormat;
5181 pFormat += sizeof(WORD);
5183 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5184 if ((pStubMsg->ActualCount > elements) ||
5185 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5187 RpcRaiseException(RPC_S_INVALID_BOUND);
5191 WriteVariance(pStubMsg);
5193 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
5195 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5196 pStubMsg->BufferMark = pStubMsg->Buffer;
5197 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5199 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5204 /***********************************************************************
5205 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5207 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5208 unsigned char **ppMemory,
5209 PFORMAT_STRING pFormat,
5210 unsigned char fMustAlloc)
5212 unsigned char alignment;
5213 DWORD size, elements, esize;
5215 unsigned char *saved_buffer;
5218 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5220 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5221 (pFormat[0] != RPC_FC_LGVARRAY))
5223 ERR("invalid format type %x\n", pFormat[0]);
5224 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5228 alignment = pFormat[1] + 1;
5230 if (pFormat[0] == RPC_FC_SMVARRAY)
5233 size = *(const WORD*)pFormat;
5234 pFormat += sizeof(WORD);
5235 elements = *(const WORD*)pFormat;
5236 pFormat += sizeof(WORD);
5241 size = *(const DWORD*)pFormat;
5242 pFormat += sizeof(DWORD);
5243 elements = *(const DWORD*)pFormat;
5244 pFormat += sizeof(DWORD);
5247 esize = *(const WORD*)pFormat;
5248 pFormat += sizeof(WORD);
5250 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5252 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5254 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5255 offset = pStubMsg->Offset;
5257 if (!fMustAlloc && !*ppMemory)
5260 *ppMemory = NdrAllocate(pStubMsg, size);
5261 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5262 safe_buffer_increment(pStubMsg, bufsize);
5264 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5266 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5271 /***********************************************************************
5272 * NdrVaryingArrayBufferSize [RPCRT4.@]
5274 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5275 unsigned char *pMemory,
5276 PFORMAT_STRING pFormat)
5278 unsigned char alignment;
5279 DWORD elements, esize;
5281 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5283 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5284 (pFormat[0] != RPC_FC_LGVARRAY))
5286 ERR("invalid format type %x\n", pFormat[0]);
5287 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5291 alignment = pFormat[1] + 1;
5293 if (pFormat[0] == RPC_FC_SMVARRAY)
5296 pFormat += sizeof(WORD);
5297 elements = *(const WORD*)pFormat;
5298 pFormat += sizeof(WORD);
5303 pFormat += sizeof(DWORD);
5304 elements = *(const DWORD*)pFormat;
5305 pFormat += sizeof(DWORD);
5308 esize = *(const WORD*)pFormat;
5309 pFormat += sizeof(WORD);
5311 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5312 if ((pStubMsg->ActualCount > elements) ||
5313 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5315 RpcRaiseException(RPC_S_INVALID_BOUND);
5319 SizeVariance(pStubMsg);
5321 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
5323 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5325 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5328 /***********************************************************************
5329 * NdrVaryingArrayMemorySize [RPCRT4.@]
5331 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5332 PFORMAT_STRING pFormat)
5334 unsigned char alignment;
5335 DWORD size, elements, esize;
5337 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5339 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5340 (pFormat[0] != RPC_FC_LGVARRAY))
5342 ERR("invalid format type %x\n", pFormat[0]);
5343 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5347 alignment = pFormat[1] + 1;
5349 if (pFormat[0] == RPC_FC_SMVARRAY)
5352 size = *(const WORD*)pFormat;
5353 pFormat += sizeof(WORD);
5354 elements = *(const WORD*)pFormat;
5355 pFormat += sizeof(WORD);
5360 size = *(const DWORD*)pFormat;
5361 pFormat += sizeof(DWORD);
5362 elements = *(const DWORD*)pFormat;
5363 pFormat += sizeof(DWORD);
5366 esize = *(const WORD*)pFormat;
5367 pFormat += sizeof(WORD);
5369 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5371 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5373 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5374 pStubMsg->MemorySize += size;
5376 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5378 return pStubMsg->MemorySize;
5381 /***********************************************************************
5382 * NdrVaryingArrayFree [RPCRT4.@]
5384 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5385 unsigned char *pMemory,
5386 PFORMAT_STRING pFormat)
5390 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5392 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5393 (pFormat[0] != RPC_FC_LGVARRAY))
5395 ERR("invalid format type %x\n", pFormat[0]);
5396 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5400 if (pFormat[0] == RPC_FC_SMVARRAY)
5403 pFormat += sizeof(WORD);
5404 elements = *(const WORD*)pFormat;
5405 pFormat += sizeof(WORD);
5410 pFormat += sizeof(DWORD);
5411 elements = *(const DWORD*)pFormat;
5412 pFormat += sizeof(DWORD);
5415 pFormat += sizeof(WORD);
5417 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5418 if ((pStubMsg->ActualCount > elements) ||
5419 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5421 RpcRaiseException(RPC_S_INVALID_BOUND);
5425 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5428 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5441 return *(const USHORT *)pMemory;
5445 return *(const ULONG *)pMemory;
5447 FIXME("Unhandled base type: 0x%02x\n", fc);
5452 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5454 PFORMAT_STRING pFormat)
5456 unsigned short num_arms, arm, type;
5458 num_arms = *(const SHORT*)pFormat & 0x0fff;
5460 for(arm = 0; arm < num_arms; arm++)
5462 if(discriminant == *(const ULONG*)pFormat)
5470 type = *(const unsigned short*)pFormat;
5471 TRACE("type %04x\n", type);
5472 if(arm == num_arms) /* default arm extras */
5476 ERR("no arm for 0x%x and no default case\n", discriminant);
5477 RpcRaiseException(RPC_S_INVALID_TAG);
5482 TRACE("falling back to empty default case for 0x%x\n", discriminant);
5489 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5491 unsigned short type;
5495 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5499 type = *(const unsigned short*)pFormat;
5500 if((type & 0xff00) == 0x8000)
5502 unsigned char basetype = LOBYTE(type);
5503 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5507 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5508 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5511 unsigned char *saved_buffer = NULL;
5512 int pointer_buffer_mark_set = 0;
5519 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5520 saved_buffer = pStubMsg->Buffer;
5521 if (pStubMsg->PointerBufferMark)
5523 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5524 pStubMsg->PointerBufferMark = NULL;
5525 pointer_buffer_mark_set = 1;
5528 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5530 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5531 if (pointer_buffer_mark_set)
5533 STD_OVERFLOW_CHECK(pStubMsg);
5534 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5535 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5537 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5538 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5539 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5541 pStubMsg->Buffer = saved_buffer + 4;
5545 m(pStubMsg, pMemory, desc);
5548 else FIXME("no marshaller for embedded type %02x\n", *desc);
5553 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5554 unsigned char **ppMemory,
5556 PFORMAT_STRING pFormat,
5557 unsigned char fMustAlloc)
5559 unsigned short type;
5563 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5567 type = *(const unsigned short*)pFormat;
5568 if((type & 0xff00) == 0x8000)
5570 unsigned char basetype = LOBYTE(type);
5571 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5575 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5576 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5579 unsigned char *saved_buffer = NULL;
5580 int pointer_buffer_mark_set = 0;
5587 ALIGN_POINTER(pStubMsg->Buffer, 4);
5588 saved_buffer = pStubMsg->Buffer;
5589 if (pStubMsg->PointerBufferMark)
5591 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5592 pStubMsg->PointerBufferMark = NULL;
5593 pointer_buffer_mark_set = 1;
5596 pStubMsg->Buffer += 4; /* for pointer ID */
5598 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5600 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5601 saved_buffer, pStubMsg->BufferEnd);
5602 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5605 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5606 if (pointer_buffer_mark_set)
5608 STD_OVERFLOW_CHECK(pStubMsg);
5609 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5610 pStubMsg->Buffer = saved_buffer + 4;
5614 m(pStubMsg, ppMemory, desc, fMustAlloc);
5617 else FIXME("no marshaller for embedded type %02x\n", *desc);
5622 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5623 unsigned char *pMemory,
5625 PFORMAT_STRING pFormat)
5627 unsigned short type;
5631 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5635 type = *(const unsigned short*)pFormat;
5636 if((type & 0xff00) == 0x8000)
5638 unsigned char basetype = LOBYTE(type);
5639 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5643 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5644 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5653 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5654 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5655 if (!pStubMsg->IgnoreEmbeddedPointers)
5657 int saved_buffer_length = pStubMsg->BufferLength;
5658 pStubMsg->BufferLength = pStubMsg->PointerLength;
5659 pStubMsg->PointerLength = 0;
5660 if(!pStubMsg->BufferLength)
5661 ERR("BufferLength == 0??\n");
5662 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5663 pStubMsg->PointerLength = pStubMsg->BufferLength;
5664 pStubMsg->BufferLength = saved_buffer_length;
5668 m(pStubMsg, pMemory, desc);
5671 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5675 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5677 PFORMAT_STRING pFormat)
5679 unsigned short type, size;
5681 size = *(const unsigned short*)pFormat;
5682 pStubMsg->Memory += size;
5685 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5689 type = *(const unsigned short*)pFormat;
5690 if((type & 0xff00) == 0x8000)
5692 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5696 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5697 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5698 unsigned char *saved_buffer;
5707 ALIGN_POINTER(pStubMsg->Buffer, 4);
5708 saved_buffer = pStubMsg->Buffer;
5709 safe_buffer_increment(pStubMsg, 4);
5710 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(void *));
5711 pStubMsg->MemorySize += sizeof(void *);
5712 if (!pStubMsg->IgnoreEmbeddedPointers)
5713 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5716 return m(pStubMsg, desc);
5719 else FIXME("no marshaller for embedded type %02x\n", *desc);
5722 TRACE("size %d\n", size);
5726 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5727 unsigned char *pMemory,
5729 PFORMAT_STRING pFormat)
5731 unsigned short type;
5735 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5739 type = *(const unsigned short*)pFormat;
5740 if((type & 0xff00) != 0x8000)
5742 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5743 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5752 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5755 m(pStubMsg, pMemory, desc);
5761 /***********************************************************************
5762 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5764 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5765 unsigned char *pMemory,
5766 PFORMAT_STRING pFormat)
5768 unsigned char switch_type;
5769 unsigned char increment;
5772 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5775 switch_type = *pFormat & 0xf;
5776 increment = (*pFormat & 0xf0) >> 4;
5779 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5781 switch_value = get_discriminant(switch_type, pMemory);
5782 TRACE("got switch value 0x%x\n", switch_value);
5784 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5785 pMemory += increment;
5787 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5790 /***********************************************************************
5791 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5793 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5794 unsigned char **ppMemory,
5795 PFORMAT_STRING pFormat,
5796 unsigned char fMustAlloc)
5798 unsigned char switch_type;
5799 unsigned char increment;
5801 unsigned short size;
5802 unsigned char *pMemoryArm;
5804 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5807 switch_type = *pFormat & 0xf;
5808 increment = (*pFormat & 0xf0) >> 4;
5811 ALIGN_POINTER(pStubMsg->Buffer, increment);
5812 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5813 TRACE("got switch value 0x%x\n", switch_value);
5815 size = *(const unsigned short*)pFormat + increment;
5816 if (!fMustAlloc && !*ppMemory)
5819 *ppMemory = NdrAllocate(pStubMsg, size);
5821 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
5822 * since the arm is part of the memory block that is encompassed by
5823 * the whole union. Memory is forced to allocate when pointers
5824 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
5825 * clearing the memory we pass in to the unmarshaller */
5827 memset(*ppMemory, 0, size);
5829 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5830 pMemoryArm = *ppMemory + increment;
5832 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, FALSE);
5835 /***********************************************************************
5836 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5838 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5839 unsigned char *pMemory,
5840 PFORMAT_STRING pFormat)
5842 unsigned char switch_type;
5843 unsigned char increment;
5846 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5849 switch_type = *pFormat & 0xf;
5850 increment = (*pFormat & 0xf0) >> 4;
5853 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5854 switch_value = get_discriminant(switch_type, pMemory);
5855 TRACE("got switch value 0x%x\n", switch_value);
5857 /* Add discriminant size */
5858 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5859 pMemory += increment;
5861 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5864 /***********************************************************************
5865 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5867 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5868 PFORMAT_STRING pFormat)
5870 unsigned char switch_type;
5871 unsigned char increment;
5874 switch_type = *pFormat & 0xf;
5875 increment = (*pFormat & 0xf0) >> 4;
5878 ALIGN_POINTER(pStubMsg->Buffer, increment);
5879 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5880 TRACE("got switch value 0x%x\n", switch_value);
5882 pStubMsg->Memory += increment;
5884 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5887 /***********************************************************************
5888 * NdrEncapsulatedUnionFree [RPCRT4.@]
5890 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5891 unsigned char *pMemory,
5892 PFORMAT_STRING pFormat)
5894 unsigned char switch_type;
5895 unsigned char increment;
5898 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5901 switch_type = *pFormat & 0xf;
5902 increment = (*pFormat & 0xf0) >> 4;
5905 switch_value = get_discriminant(switch_type, pMemory);
5906 TRACE("got switch value 0x%x\n", switch_value);
5908 pMemory += increment;
5910 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5913 /***********************************************************************
5914 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5916 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5917 unsigned char *pMemory,
5918 PFORMAT_STRING pFormat)
5920 unsigned char switch_type;
5922 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5925 switch_type = *pFormat;
5928 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5929 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5930 /* Marshall discriminant */
5931 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5933 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5936 static LONG unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5937 PFORMAT_STRING *ppFormat)
5939 LONG discriminant = 0;
5949 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5958 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5959 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5967 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5968 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5973 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5977 if (pStubMsg->fHasNewCorrDesc)
5981 return discriminant;
5984 /**********************************************************************
5985 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5987 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5988 unsigned char **ppMemory,
5989 PFORMAT_STRING pFormat,
5990 unsigned char fMustAlloc)
5993 unsigned short size;
5995 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5998 /* Unmarshall discriminant */
5999 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6000 TRACE("unmarshalled discriminant %x\n", discriminant);
6002 pFormat += *(const SHORT*)pFormat;
6004 size = *(const unsigned short*)pFormat;
6006 if (!fMustAlloc && !*ppMemory)
6009 *ppMemory = NdrAllocate(pStubMsg, size);
6011 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6012 * since the arm is part of the memory block that is encompassed by
6013 * the whole union. Memory is forced to allocate when pointers
6014 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6015 * clearing the memory we pass in to the unmarshaller */
6017 memset(*ppMemory, 0, size);
6019 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, FALSE);
6022 /***********************************************************************
6023 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6025 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6026 unsigned char *pMemory,
6027 PFORMAT_STRING pFormat)
6029 unsigned char switch_type;
6031 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6034 switch_type = *pFormat;
6037 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6038 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6039 /* Add discriminant size */
6040 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6042 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6045 /***********************************************************************
6046 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6048 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6049 PFORMAT_STRING pFormat)
6054 /* Unmarshall discriminant */
6055 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6056 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
6058 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
6061 /***********************************************************************
6062 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6064 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6065 unsigned char *pMemory,
6066 PFORMAT_STRING pFormat)
6068 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6072 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6073 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6075 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6078 /***********************************************************************
6079 * NdrByteCountPointerMarshall [RPCRT4.@]
6081 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6082 unsigned char *pMemory,
6083 PFORMAT_STRING pFormat)
6089 /***********************************************************************
6090 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6092 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6093 unsigned char **ppMemory,
6094 PFORMAT_STRING pFormat,
6095 unsigned char fMustAlloc)
6101 /***********************************************************************
6102 * NdrByteCountPointerBufferSize [RPCRT4.@]
6104 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6105 unsigned char *pMemory,
6106 PFORMAT_STRING pFormat)
6111 /***********************************************************************
6112 * NdrByteCountPointerMemorySize [internal]
6114 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6115 PFORMAT_STRING pFormat)
6121 /***********************************************************************
6122 * NdrByteCountPointerFree [RPCRT4.@]
6124 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6125 unsigned char *pMemory,
6126 PFORMAT_STRING pFormat)
6131 /***********************************************************************
6132 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6134 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6135 unsigned char *pMemory,
6136 PFORMAT_STRING pFormat)
6142 /***********************************************************************
6143 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6145 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6146 unsigned char **ppMemory,
6147 PFORMAT_STRING pFormat,
6148 unsigned char fMustAlloc)
6154 /***********************************************************************
6155 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6157 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6158 unsigned char *pMemory,
6159 PFORMAT_STRING pFormat)
6164 /***********************************************************************
6165 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6167 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6168 PFORMAT_STRING pFormat)
6174 /***********************************************************************
6175 * NdrXmitOrRepAsFree [RPCRT4.@]
6177 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6178 unsigned char *pMemory,
6179 PFORMAT_STRING pFormat)
6184 /***********************************************************************
6185 * NdrRangeMarshall [internal]
6187 static unsigned char *WINAPI NdrRangeMarshall(
6188 PMIDL_STUB_MESSAGE pStubMsg,
6189 unsigned char *pMemory,
6190 PFORMAT_STRING pFormat)
6192 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6193 unsigned char base_type;
6195 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6197 if (pRange->type != RPC_FC_RANGE)
6199 ERR("invalid format type %x\n", pRange->type);
6200 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6204 base_type = pRange->flags_type & 0xf;
6206 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6209 /***********************************************************************
6210 * NdrRangeUnmarshall [RPCRT4.@]
6212 unsigned char *WINAPI NdrRangeUnmarshall(
6213 PMIDL_STUB_MESSAGE pStubMsg,
6214 unsigned char **ppMemory,
6215 PFORMAT_STRING pFormat,
6216 unsigned char fMustAlloc)
6218 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6219 unsigned char base_type;
6221 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6223 if (pRange->type != RPC_FC_RANGE)
6225 ERR("invalid format type %x\n", pRange->type);
6226 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6229 base_type = pRange->flags_type & 0xf;
6231 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6232 base_type, pRange->low_value, pRange->high_value);
6234 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6237 ALIGN_POINTER(pStubMsg->Buffer, sizeof(wire_type)); \
6238 if (!fMustAlloc && !*ppMemory) \
6239 fMustAlloc = TRUE; \
6241 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6242 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6244 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6245 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6246 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6248 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6249 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6251 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6252 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6253 (mem_type)pRange->high_value); \
6254 RpcRaiseException(RPC_S_INVALID_BOUND); \
6257 TRACE("*ppMemory: %p\n", *ppMemory); \
6258 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6259 pStubMsg->Buffer += sizeof(wire_type); \
6266 RANGE_UNMARSHALL(UCHAR, UCHAR, "%d");
6267 TRACE("value: 0x%02x\n", **ppMemory);
6271 RANGE_UNMARSHALL(CHAR, CHAR, "%u");
6272 TRACE("value: 0x%02x\n", **ppMemory);
6274 case RPC_FC_WCHAR: /* FIXME: valid? */
6276 RANGE_UNMARSHALL(USHORT, USHORT, "%u");
6277 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6280 RANGE_UNMARSHALL(SHORT, SHORT, "%d");
6281 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6285 RANGE_UNMARSHALL(LONG, LONG, "%d");
6286 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6289 RANGE_UNMARSHALL(ULONG, ULONG, "%u");
6290 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6293 RANGE_UNMARSHALL(UINT, USHORT, "%u");
6294 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6300 ERR("invalid range base type: 0x%02x\n", base_type);
6301 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6307 /***********************************************************************
6308 * NdrRangeBufferSize [internal]
6310 static void WINAPI NdrRangeBufferSize(
6311 PMIDL_STUB_MESSAGE pStubMsg,
6312 unsigned char *pMemory,
6313 PFORMAT_STRING pFormat)
6315 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6316 unsigned char base_type;
6318 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6320 if (pRange->type != RPC_FC_RANGE)
6322 ERR("invalid format type %x\n", pRange->type);
6323 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6325 base_type = pRange->flags_type & 0xf;
6327 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6330 /***********************************************************************
6331 * NdrRangeMemorySize [internal]
6333 static ULONG WINAPI NdrRangeMemorySize(
6334 PMIDL_STUB_MESSAGE pStubMsg,
6335 PFORMAT_STRING pFormat)
6337 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6338 unsigned char base_type;
6340 if (pRange->type != RPC_FC_RANGE)
6342 ERR("invalid format type %x\n", pRange->type);
6343 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6346 base_type = pRange->flags_type & 0xf;
6348 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6351 /***********************************************************************
6352 * NdrRangeFree [internal]
6354 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6355 unsigned char *pMemory,
6356 PFORMAT_STRING pFormat)
6358 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6363 /***********************************************************************
6364 * NdrBaseTypeMarshall [internal]
6366 static unsigned char *WINAPI NdrBaseTypeMarshall(
6367 PMIDL_STUB_MESSAGE pStubMsg,
6368 unsigned char *pMemory,
6369 PFORMAT_STRING pFormat)
6371 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6379 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6380 TRACE("value: 0x%02x\n", *pMemory);
6385 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6386 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6387 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6391 case RPC_FC_ERROR_STATUS_T:
6393 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
6394 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6395 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6398 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
6399 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6402 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
6403 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6406 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
6407 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6408 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6411 /* only 16-bits on the wire, so do a sanity check */
6412 if (*(UINT *)pMemory > SHRT_MAX)
6413 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6414 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6415 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6416 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6417 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
6418 pStubMsg->Buffer += sizeof(USHORT);
6419 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6424 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6427 /* FIXME: what is the correct return value? */
6431 /***********************************************************************
6432 * NdrBaseTypeUnmarshall [internal]
6434 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6435 PMIDL_STUB_MESSAGE pStubMsg,
6436 unsigned char **ppMemory,
6437 PFORMAT_STRING pFormat,
6438 unsigned char fMustAlloc)
6440 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6442 #define BASE_TYPE_UNMARSHALL(type) \
6443 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6444 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6446 *ppMemory = pStubMsg->Buffer; \
6447 TRACE("*ppMemory: %p\n", *ppMemory); \
6448 safe_buffer_increment(pStubMsg, sizeof(type)); \
6453 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6454 TRACE("*ppMemory: %p\n", *ppMemory); \
6455 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6464 BASE_TYPE_UNMARSHALL(UCHAR);
6465 TRACE("value: 0x%02x\n", **ppMemory);
6470 BASE_TYPE_UNMARSHALL(USHORT);
6471 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6475 case RPC_FC_ERROR_STATUS_T:
6477 BASE_TYPE_UNMARSHALL(ULONG);
6478 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6481 BASE_TYPE_UNMARSHALL(float);
6482 TRACE("value: %f\n", **(float **)ppMemory);
6485 BASE_TYPE_UNMARSHALL(double);
6486 TRACE("value: %f\n", **(double **)ppMemory);
6489 BASE_TYPE_UNMARSHALL(ULONGLONG);
6490 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6493 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6494 if (!fMustAlloc && !*ppMemory)
6497 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6498 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
6499 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6500 TRACE("*ppMemory: %p\n", *ppMemory);
6501 /* 16-bits on the wire, but int in memory */
6502 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
6503 pStubMsg->Buffer += sizeof(USHORT);
6504 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6509 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6511 #undef BASE_TYPE_UNMARSHALL
6513 /* FIXME: what is the correct return value? */
6518 /***********************************************************************
6519 * NdrBaseTypeBufferSize [internal]
6521 static void WINAPI NdrBaseTypeBufferSize(
6522 PMIDL_STUB_MESSAGE pStubMsg,
6523 unsigned char *pMemory,
6524 PFORMAT_STRING pFormat)
6526 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6534 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6540 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
6541 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6546 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
6547 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6550 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
6551 safe_buffer_length_increment(pStubMsg, sizeof(float));
6554 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
6555 safe_buffer_length_increment(pStubMsg, sizeof(double));
6558 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
6559 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6561 case RPC_FC_ERROR_STATUS_T:
6562 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
6563 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6568 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6572 /***********************************************************************
6573 * NdrBaseTypeMemorySize [internal]
6575 static ULONG WINAPI NdrBaseTypeMemorySize(
6576 PMIDL_STUB_MESSAGE pStubMsg,
6577 PFORMAT_STRING pFormat)
6579 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6587 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6588 pStubMsg->MemorySize += sizeof(UCHAR);
6589 return sizeof(UCHAR);
6593 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6594 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6595 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(USHORT));
6596 pStubMsg->MemorySize += sizeof(USHORT);
6597 return sizeof(USHORT);
6601 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
6602 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6603 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(ULONG));
6604 pStubMsg->MemorySize += sizeof(ULONG);
6605 return sizeof(ULONG);
6607 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
6608 safe_buffer_increment(pStubMsg, sizeof(float));
6609 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(float));
6610 pStubMsg->MemorySize += sizeof(float);
6611 return sizeof(float);
6613 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
6614 safe_buffer_increment(pStubMsg, sizeof(double));
6615 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(double));
6616 pStubMsg->MemorySize += sizeof(double);
6617 return sizeof(double);
6619 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
6620 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6621 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(ULONGLONG));
6622 pStubMsg->MemorySize += sizeof(ULONGLONG);
6623 return sizeof(ULONGLONG);
6624 case RPC_FC_ERROR_STATUS_T:
6625 ALIGN_POINTER(pStubMsg->Buffer, sizeof(error_status_t));
6626 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6627 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(error_status_t));
6628 pStubMsg->MemorySize += sizeof(error_status_t);
6629 return sizeof(error_status_t);
6631 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6632 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6633 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(UINT));
6634 pStubMsg->MemorySize += sizeof(UINT);
6635 return sizeof(UINT);
6637 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(void *));
6638 pStubMsg->MemorySize += sizeof(void *);
6639 return sizeof(void *);
6641 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6646 /***********************************************************************
6647 * NdrBaseTypeFree [internal]
6649 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6650 unsigned char *pMemory,
6651 PFORMAT_STRING pFormat)
6653 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6658 /***********************************************************************
6659 * NdrContextHandleBufferSize [internal]
6661 static void WINAPI NdrContextHandleBufferSize(
6662 PMIDL_STUB_MESSAGE pStubMsg,
6663 unsigned char *pMemory,
6664 PFORMAT_STRING pFormat)
6666 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6668 if (*pFormat != RPC_FC_BIND_CONTEXT)
6670 ERR("invalid format type %x\n", *pFormat);
6671 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6673 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
6674 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6677 /***********************************************************************
6678 * NdrContextHandleMarshall [internal]
6680 static unsigned char *WINAPI NdrContextHandleMarshall(
6681 PMIDL_STUB_MESSAGE pStubMsg,
6682 unsigned char *pMemory,
6683 PFORMAT_STRING pFormat)
6685 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6687 if (*pFormat != RPC_FC_BIND_CONTEXT)
6689 ERR("invalid format type %x\n", *pFormat);
6690 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6692 TRACE("flags: 0x%02x\n", pFormat[1]);
6694 if (pStubMsg->IsClient)
6696 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6697 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6699 NdrClientContextMarshall(pStubMsg, pMemory, FALSE);
6703 NDR_SCONTEXT ctxt = NDRSContextFromValue(pMemory);
6704 NDR_RUNDOWN rundown = pStubMsg->StubDesc->apfnNdrRundownRoutines[pFormat[2]];
6705 NdrServerContextNewMarshall(pStubMsg, ctxt, rundown, pFormat);
6711 /***********************************************************************
6712 * NdrContextHandleUnmarshall [internal]
6714 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6715 PMIDL_STUB_MESSAGE pStubMsg,
6716 unsigned char **ppMemory,
6717 PFORMAT_STRING pFormat,
6718 unsigned char fMustAlloc)
6720 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6721 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6723 if (*pFormat != RPC_FC_BIND_CONTEXT)
6725 ERR("invalid format type %x\n", *pFormat);
6726 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6728 TRACE("flags: 0x%02x\n", pFormat[1]);
6730 if (pStubMsg->IsClient)
6732 /* [out]-only or [ret] param */
6733 if ((pFormat[1] & (HANDLE_PARAM_IS_IN|HANDLE_PARAM_IS_OUT)) == HANDLE_PARAM_IS_OUT)
6734 **(NDR_CCONTEXT **)ppMemory = NULL;
6735 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6740 ctxt = NdrServerContextNewUnmarshall(pStubMsg, pFormat);
6741 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6742 *(void **)ppMemory = NDRSContextValue(ctxt);
6744 *(void **)ppMemory = *NDRSContextValue(ctxt);
6750 /***********************************************************************
6751 * NdrClientContextMarshall [RPCRT4.@]
6753 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6754 NDR_CCONTEXT ContextHandle,
6757 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
6759 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
6761 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6763 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6764 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6765 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6768 /* FIXME: what does fCheck do? */
6769 NDRCContextMarshall(ContextHandle,
6772 pStubMsg->Buffer += cbNDRContext;
6775 /***********************************************************************
6776 * NdrClientContextUnmarshall [RPCRT4.@]
6778 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6779 NDR_CCONTEXT * pContextHandle,
6780 RPC_BINDING_HANDLE BindHandle)
6782 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
6784 ALIGN_POINTER(pStubMsg->Buffer, 4);
6786 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
6787 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6789 NDRCContextUnmarshall(pContextHandle,
6792 pStubMsg->RpcMsg->DataRepresentation);
6794 pStubMsg->Buffer += cbNDRContext;
6797 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6798 NDR_SCONTEXT ContextHandle,
6799 NDR_RUNDOWN RundownRoutine )
6801 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
6803 ALIGN_POINTER(pStubMsg->Buffer, 4);
6805 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6807 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6808 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6809 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6812 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6813 pStubMsg->Buffer, RundownRoutine, NULL,
6814 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6815 pStubMsg->Buffer += cbNDRContext;
6818 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6820 NDR_SCONTEXT ContextHandle;
6822 TRACE("(%p)\n", pStubMsg);
6824 ALIGN_POINTER(pStubMsg->Buffer, 4);
6826 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6828 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6829 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6830 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6833 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6835 pStubMsg->RpcMsg->DataRepresentation,
6836 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6837 pStubMsg->Buffer += cbNDRContext;
6839 return ContextHandle;
6842 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6843 unsigned char* pMemory,
6844 PFORMAT_STRING pFormat)
6846 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6849 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6850 PFORMAT_STRING pFormat)
6852 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6853 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6855 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6857 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6858 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6859 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6860 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6861 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6863 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6864 if_id = &sif->InterfaceId;
6867 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
6868 pStubMsg->RpcMsg->DataRepresentation, if_id,
6872 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6873 NDR_SCONTEXT ContextHandle,
6874 NDR_RUNDOWN RundownRoutine,
6875 PFORMAT_STRING pFormat)
6877 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6878 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6880 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
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 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6892 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6893 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6894 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6895 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6897 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6898 if_id = &sif->InterfaceId;
6901 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6902 pStubMsg->Buffer, RundownRoutine, if_id, flags);
6903 pStubMsg->Buffer += cbNDRContext;
6906 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6907 PFORMAT_STRING pFormat)
6909 NDR_SCONTEXT ContextHandle;
6910 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6911 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6913 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6915 ALIGN_POINTER(pStubMsg->Buffer, 4);
6917 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6919 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6920 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6921 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6924 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6925 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6926 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6927 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6928 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6930 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6931 if_id = &sif->InterfaceId;
6934 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6936 pStubMsg->RpcMsg->DataRepresentation,
6938 pStubMsg->Buffer += cbNDRContext;
6940 return ContextHandle;
6943 /***********************************************************************
6944 * NdrCorrelationInitialize [RPCRT4.@]
6946 * Initializes correlation validity checking.
6949 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6950 * pMemory [I] Pointer to memory to use as a cache.
6951 * CacheSize [I] Size of the memory pointed to by pMemory.
6952 * Flags [I] Reserved. Set to zero.
6957 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
6959 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
6960 pStubMsg->fHasNewCorrDesc = TRUE;
6963 /***********************************************************************
6964 * NdrCorrelationPass [RPCRT4.@]
6966 * Performs correlation validity checking.
6969 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6974 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
6976 FIXME("(%p): stub\n", pStubMsg);
6979 /***********************************************************************
6980 * NdrCorrelationFree [RPCRT4.@]
6982 * Frees any resources used while unmarshalling parameters that need
6983 * correlation validity checking.
6986 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6991 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
6993 FIXME("(%p): stub\n", pStubMsg);