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
42 #include "wine/unicode.h"
43 #include "wine/rpcfc.h"
45 #include "wine/debug.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(ole);
50 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
51 (*((UINT32 *)(pchar)) = (uint32))
53 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
54 (*((UINT32 *)(pchar)))
56 /* these would work for i386 too, but less efficient */
57 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
58 (*(pchar) = LOBYTE(LOWORD(uint32)), \
59 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
60 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
61 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
62 (uint32)) /* allow as r-value */
64 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
66 MAKEWORD(*(pchar), *((pchar)+1)), \
67 MAKEWORD(*((pchar)+2), *((pchar)+3))))
70 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
71 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
72 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
73 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
74 *(pchar) = HIBYTE(HIWORD(uint32)), \
75 (uint32)) /* allow as r-value */
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", _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", _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 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
118 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
119 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
120 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
121 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
123 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
124 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
125 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
127 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
129 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
130 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
131 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
132 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
136 NdrPointerMarshall, NdrPointerMarshall,
137 NdrPointerMarshall, NdrPointerMarshall,
139 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
140 NdrConformantStructMarshall, NdrConformantStructMarshall,
141 NdrConformantVaryingStructMarshall,
142 NdrComplexStructMarshall,
144 NdrConformantArrayMarshall,
145 NdrConformantVaryingArrayMarshall,
146 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
147 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
148 NdrComplexArrayMarshall,
150 NdrConformantStringMarshall, 0, 0,
151 NdrConformantStringMarshall,
152 NdrNonConformantStringMarshall, 0, 0, 0,
154 NdrEncapsulatedUnionMarshall,
155 NdrNonEncapsulatedUnionMarshall,
156 NdrByteCountPointerMarshall,
157 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
159 NdrInterfacePointerMarshall,
161 NdrContextHandleMarshall,
164 NdrUserMarshalMarshall,
169 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
171 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
172 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
173 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
174 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
176 NdrBaseTypeUnmarshall,
178 NdrPointerUnmarshall, NdrPointerUnmarshall,
179 NdrPointerUnmarshall, NdrPointerUnmarshall,
181 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
182 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
183 NdrConformantVaryingStructUnmarshall,
184 NdrComplexStructUnmarshall,
186 NdrConformantArrayUnmarshall,
187 NdrConformantVaryingArrayUnmarshall,
188 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
189 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
190 NdrComplexArrayUnmarshall,
192 NdrConformantStringUnmarshall, 0, 0,
193 NdrConformantStringUnmarshall,
194 NdrNonConformantStringUnmarshall, 0, 0, 0,
196 NdrEncapsulatedUnionUnmarshall,
197 NdrNonEncapsulatedUnionUnmarshall,
198 NdrByteCountPointerUnmarshall,
199 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
201 NdrInterfacePointerUnmarshall,
203 NdrContextHandleUnmarshall,
206 NdrUserMarshalUnmarshall,
211 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
213 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
214 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
215 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
216 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
218 NdrBaseTypeBufferSize,
220 NdrPointerBufferSize, NdrPointerBufferSize,
221 NdrPointerBufferSize, NdrPointerBufferSize,
223 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
224 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
225 NdrConformantVaryingStructBufferSize,
226 NdrComplexStructBufferSize,
228 NdrConformantArrayBufferSize,
229 NdrConformantVaryingArrayBufferSize,
230 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
231 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
232 NdrComplexArrayBufferSize,
234 NdrConformantStringBufferSize, 0, 0,
235 NdrConformantStringBufferSize,
236 NdrNonConformantStringBufferSize, 0, 0, 0,
238 NdrEncapsulatedUnionBufferSize,
239 NdrNonEncapsulatedUnionBufferSize,
240 NdrByteCountPointerBufferSize,
241 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
243 NdrInterfacePointerBufferSize,
245 NdrContextHandleBufferSize,
248 NdrUserMarshalBufferSize,
253 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
255 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
256 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
257 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
258 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
260 NdrBaseTypeMemorySize,
262 NdrPointerMemorySize, NdrPointerMemorySize,
263 NdrPointerMemorySize, NdrPointerMemorySize,
265 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
266 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
267 NdrConformantVaryingStructMemorySize,
268 NdrComplexStructMemorySize,
270 NdrConformantArrayMemorySize,
271 NdrConformantVaryingArrayMemorySize,
272 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
273 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
274 NdrComplexArrayMemorySize,
276 NdrConformantStringMemorySize, 0, 0,
277 NdrConformantStringMemorySize,
278 NdrNonConformantStringMemorySize, 0, 0, 0,
280 NdrEncapsulatedUnionMemorySize,
281 NdrNonEncapsulatedUnionMemorySize,
282 NdrByteCountPointerMemorySize,
283 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
285 NdrInterfacePointerMemorySize,
290 NdrUserMarshalMemorySize,
295 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
297 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
298 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
299 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
300 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
304 NdrPointerFree, NdrPointerFree,
305 NdrPointerFree, NdrPointerFree,
307 NdrSimpleStructFree, NdrSimpleStructFree,
308 NdrConformantStructFree, NdrConformantStructFree,
309 NdrConformantVaryingStructFree,
310 NdrComplexStructFree,
312 NdrConformantArrayFree,
313 NdrConformantVaryingArrayFree,
314 NdrFixedArrayFree, NdrFixedArrayFree,
315 NdrVaryingArrayFree, NdrVaryingArrayFree,
321 NdrEncapsulatedUnionFree,
322 NdrNonEncapsulatedUnionFree,
324 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
326 NdrInterfacePointerFree,
337 typedef struct _NDR_MEMORY_LIST
342 struct _NDR_MEMORY_LIST *next;
345 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
347 /***********************************************************************
348 * NdrAllocate [RPCRT4.@]
350 * Allocates a block of memory using pStubMsg->pfnAllocate.
353 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
354 * len [I] Size of memory block to allocate.
357 * The memory block of size len that was allocated.
360 * The memory block is always 8-byte aligned.
361 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
362 * exception is raised.
364 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, SIZE_T len)
369 NDR_MEMORY_LIST *mem_list;
371 aligned_len = ALIGNED_LENGTH(len, 8);
372 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
373 /* check for overflow */
374 if (adjusted_len < len)
376 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len, len);
377 RpcRaiseException(RPC_X_BAD_STUB_DATA);
380 p = pStubMsg->pfnAllocate(adjusted_len);
381 if (!p) RpcRaiseException(ERROR_OUTOFMEMORY);
383 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
384 mem_list->magic = MEML_MAGIC;
385 mem_list->size = aligned_len;
386 mem_list->reserved = 0;
387 mem_list->next = pStubMsg->pMemoryList;
388 pStubMsg->pMemoryList = mem_list;
394 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
396 TRACE("(%p, %p)\n", pStubMsg, Pointer);
398 pStubMsg->pfnFree(Pointer);
401 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
403 return (*(const ULONG *)pFormat != -1);
406 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
408 ALIGN_POINTER(pStubMsg->Buffer, 4);
409 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
410 RpcRaiseException(RPC_X_BAD_STUB_DATA);
411 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
412 pStubMsg->Buffer += 4;
413 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
414 if (pStubMsg->fHasNewCorrDesc)
420 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
422 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
424 pStubMsg->Offset = 0;
425 pStubMsg->ActualCount = pStubMsg->MaxCount;
429 ALIGN_POINTER(pStubMsg->Buffer, 4);
430 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
431 RpcRaiseException(RPC_X_BAD_STUB_DATA);
432 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
433 pStubMsg->Buffer += 4;
434 TRACE("offset is %d\n", pStubMsg->Offset);
435 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
436 pStubMsg->Buffer += 4;
437 TRACE("variance is %d\n", pStubMsg->ActualCount);
439 if ((pStubMsg->ActualCount > MaxValue) ||
440 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
442 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
443 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
444 RpcRaiseException(RPC_S_INVALID_BOUND);
449 if (pStubMsg->fHasNewCorrDesc)
455 /* writes the conformance value to the buffer */
456 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
458 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
459 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
460 RpcRaiseException(RPC_X_BAD_STUB_DATA);
461 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
462 pStubMsg->Buffer += 4;
465 /* writes the variance values to the buffer */
466 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
468 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
469 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
470 RpcRaiseException(RPC_X_BAD_STUB_DATA);
471 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
472 pStubMsg->Buffer += 4;
473 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
474 pStubMsg->Buffer += 4;
477 /* requests buffer space for the conformance value */
478 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
480 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
481 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
482 RpcRaiseException(RPC_X_BAD_STUB_DATA);
483 pStubMsg->BufferLength += 4;
486 /* requests buffer space for the variance values */
487 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
489 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
490 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
491 RpcRaiseException(RPC_X_BAD_STUB_DATA);
492 pStubMsg->BufferLength += 8;
495 PFORMAT_STRING ComputeConformanceOrVariance(
496 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
497 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
499 BYTE dtype = pFormat[0] & 0xf;
500 short ofs = *(const short *)&pFormat[2];
504 if (!IsConformanceOrVariancePresent(pFormat)) {
505 /* null descriptor */
510 switch (pFormat[0] & 0xf0) {
511 case RPC_FC_NORMAL_CONFORMANCE:
512 TRACE("normal conformance, ofs=%d\n", ofs);
515 case RPC_FC_POINTER_CONFORMANCE:
516 TRACE("pointer conformance, ofs=%d\n", ofs);
517 ptr = pStubMsg->Memory;
519 case RPC_FC_TOP_LEVEL_CONFORMANCE:
520 TRACE("toplevel conformance, ofs=%d\n", ofs);
521 if (pStubMsg->StackTop) {
522 ptr = pStubMsg->StackTop;
525 /* -Os mode, *pCount is already set */
529 case RPC_FC_CONSTANT_CONFORMANCE:
530 data = ofs | ((DWORD)pFormat[1] << 16);
531 TRACE("constant conformance, val=%d\n", data);
534 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
535 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
536 if (pStubMsg->StackTop) {
537 ptr = pStubMsg->StackTop;
545 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
548 switch (pFormat[1]) {
549 case RPC_FC_DEREFERENCE:
550 ptr = *(LPVOID*)((char *)ptr + ofs);
552 case RPC_FC_CALLBACK:
554 unsigned char *old_stack_top = pStubMsg->StackTop;
555 pStubMsg->StackTop = ptr;
557 /* ofs is index into StubDesc->apfnExprEval */
558 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
559 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
561 pStubMsg->StackTop = old_stack_top;
563 /* the callback function always stores the computed value in MaxCount */
564 *pCount = pStubMsg->MaxCount;
568 ptr = (char *)ptr + ofs;
581 data = *(USHORT*)ptr;
592 FIXME("unknown conformance data type %x\n", dtype);
595 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
598 switch (pFormat[1]) {
599 case RPC_FC_DEREFERENCE: /* already handled */
616 FIXME("unknown conformance op %d\n", pFormat[1]);
621 TRACE("resulting conformance is %ld\n", *pCount);
622 if (pStubMsg->fHasNewCorrDesc)
628 static inline PFORMAT_STRING SkipConformance(PMIDL_STUB_MESSAGE pStubMsg,
629 PFORMAT_STRING pFormat)
631 if (IsConformanceOrVariancePresent(pFormat))
633 if (pStubMsg->fHasNewCorrDesc)
641 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
642 * the result overflows 32-bits */
643 static inline ULONG safe_multiply(ULONG a, ULONG b)
645 ULONGLONG ret = (ULONGLONG)a * b;
646 if (ret > 0xffffffff)
648 RpcRaiseException(RPC_S_INVALID_BOUND);
654 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
656 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
657 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
658 RpcRaiseException(RPC_X_BAD_STUB_DATA);
659 pStubMsg->Buffer += size;
662 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
664 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
666 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
667 pStubMsg->BufferLength, size);
668 RpcRaiseException(RPC_X_BAD_STUB_DATA);
670 pStubMsg->BufferLength += size;
673 /* copies data from the buffer, checking that there is enough data in the buffer
675 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
677 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
678 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
680 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
681 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
682 RpcRaiseException(RPC_X_BAD_STUB_DATA);
684 if (p == pStubMsg->Buffer)
685 ERR("pointer is the same as the buffer\n");
686 memcpy(p, pStubMsg->Buffer, size);
687 pStubMsg->Buffer += size;
690 /* copies data to the buffer, checking that there is enough space to do so */
691 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
693 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
694 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
696 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
697 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
699 RpcRaiseException(RPC_X_BAD_STUB_DATA);
701 memcpy(pStubMsg->Buffer, p, size);
702 pStubMsg->Buffer += size;
705 /* verify that string data sitting in the buffer is valid and safe to
707 static void validate_string_data(MIDL_STUB_MESSAGE *pStubMsg, ULONG bufsize, ULONG esize)
711 /* verify the buffer is safe to access */
712 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
713 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
715 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
716 pStubMsg->BufferEnd, pStubMsg->Buffer);
717 RpcRaiseException(RPC_X_BAD_STUB_DATA);
720 /* strings must always have null terminating bytes */
723 ERR("invalid string length of %d\n", bufsize / esize);
724 RpcRaiseException(RPC_S_INVALID_BOUND);
727 for (i = bufsize - esize; i < bufsize; i++)
728 if (pStubMsg->Buffer[i] != 0)
730 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
731 i, pStubMsg->Buffer[i]);
732 RpcRaiseException(RPC_S_INVALID_BOUND);
736 static inline void dump_pointer_attr(unsigned char attr)
738 if (attr & RPC_FC_P_ALLOCALLNODES)
739 TRACE(" RPC_FC_P_ALLOCALLNODES");
740 if (attr & RPC_FC_P_DONTFREE)
741 TRACE(" RPC_FC_P_DONTFREE");
742 if (attr & RPC_FC_P_ONSTACK)
743 TRACE(" RPC_FC_P_ONSTACK");
744 if (attr & RPC_FC_P_SIMPLEPOINTER)
745 TRACE(" RPC_FC_P_SIMPLEPOINTER");
746 if (attr & RPC_FC_P_DEREF)
747 TRACE(" RPC_FC_P_DEREF");
751 /***********************************************************************
752 * PointerMarshall [internal]
754 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
755 unsigned char *Buffer,
756 unsigned char *Pointer,
757 PFORMAT_STRING pFormat)
759 unsigned type = pFormat[0], attr = pFormat[1];
763 int pointer_needs_marshaling;
765 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
766 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
768 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
769 else desc = pFormat + *(const SHORT*)pFormat;
772 case RPC_FC_RP: /* ref pointer (always non-null) */
775 ERR("NULL ref pointer is not allowed\n");
776 RpcRaiseException(RPC_X_NULL_REF_POINTER);
778 pointer_needs_marshaling = 1;
780 case RPC_FC_UP: /* unique pointer */
781 case RPC_FC_OP: /* object pointer - same as unique here */
783 pointer_needs_marshaling = 1;
785 pointer_needs_marshaling = 0;
786 pointer_id = Pointer ? NDR_POINTER_ID(pStubMsg) : 0;
787 TRACE("writing 0x%08x to buffer\n", pointer_id);
788 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
791 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
792 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
793 TRACE("writing 0x%08x to buffer\n", pointer_id);
794 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
797 FIXME("unhandled ptr type=%02x\n", type);
798 RpcRaiseException(RPC_X_BAD_STUB_DATA);
802 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
804 if (pointer_needs_marshaling) {
805 if (attr & RPC_FC_P_DEREF) {
806 Pointer = *(unsigned char**)Pointer;
807 TRACE("deref => %p\n", Pointer);
809 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
810 if (m) m(pStubMsg, Pointer, desc);
811 else FIXME("no marshaller for data type=%02x\n", *desc);
814 STD_OVERFLOW_CHECK(pStubMsg);
817 /***********************************************************************
818 * PointerUnmarshall [internal]
820 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
821 unsigned char *Buffer,
822 unsigned char **pPointer,
823 unsigned char *pSrcPointer,
824 PFORMAT_STRING pFormat,
825 unsigned char fMustAlloc)
827 unsigned type = pFormat[0], attr = pFormat[1];
830 DWORD pointer_id = 0;
831 int pointer_needs_unmarshaling;
833 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
834 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
836 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
837 else desc = pFormat + *(const SHORT*)pFormat;
840 case RPC_FC_RP: /* ref pointer (always non-null) */
841 pointer_needs_unmarshaling = 1;
843 case RPC_FC_UP: /* unique pointer */
844 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
845 TRACE("pointer_id is 0x%08x\n", pointer_id);
847 pointer_needs_unmarshaling = 1;
850 pointer_needs_unmarshaling = 0;
853 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
854 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
855 TRACE("pointer_id is 0x%08x\n", pointer_id);
856 if (!fMustAlloc && pSrcPointer)
858 FIXME("free object pointer %p\n", pSrcPointer);
862 pointer_needs_unmarshaling = 1;
866 pointer_needs_unmarshaling = 0;
870 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
871 TRACE("pointer_id is 0x%08x\n", pointer_id);
872 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
873 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
876 FIXME("unhandled ptr type=%02x\n", type);
877 RpcRaiseException(RPC_X_BAD_STUB_DATA);
881 if (pointer_needs_unmarshaling) {
882 unsigned char *base_ptr_val = *pPointer;
883 unsigned char **current_ptr = pPointer;
884 if (pStubMsg->IsClient) {
886 /* if we aren't forcing allocation of memory then try to use the existing
887 * (source) pointer to unmarshall the data into so that [in,out]
888 * parameters behave correctly. it doesn't matter if the parameter is
889 * [out] only since in that case the pointer will be NULL. we force
890 * allocation when the source pointer is NULL here instead of in the type
891 * unmarshalling routine for the benefit of the deref code below */
894 TRACE("setting *pPointer to %p\n", pSrcPointer);
895 *pPointer = base_ptr_val = pSrcPointer;
901 /* the memory in a stub is never initialised, so we have to work out here
902 * whether we have to initialise it so we can use the optimisation of
903 * setting the pointer to the buffer, if possible, or set fMustAlloc to
905 if (attr & RPC_FC_P_DEREF) {
913 if (attr & RPC_FC_P_ALLOCALLNODES)
914 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
916 if (attr & RPC_FC_P_DEREF) {
918 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
919 *pPointer = base_ptr_val;
920 current_ptr = (unsigned char **)base_ptr_val;
922 current_ptr = *(unsigned char***)current_ptr;
923 TRACE("deref => %p\n", current_ptr);
924 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
926 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
927 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
928 else FIXME("no unmarshaller for data type=%02x\n", *desc);
930 if (type == RPC_FC_FP)
931 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
935 TRACE("pointer=%p\n", *pPointer);
938 /***********************************************************************
939 * PointerBufferSize [internal]
941 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
942 unsigned char *Pointer,
943 PFORMAT_STRING pFormat)
945 unsigned type = pFormat[0], attr = pFormat[1];
948 int pointer_needs_sizing;
951 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
952 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
954 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
955 else desc = pFormat + *(const SHORT*)pFormat;
958 case RPC_FC_RP: /* ref pointer (always non-null) */
961 ERR("NULL ref pointer is not allowed\n");
962 RpcRaiseException(RPC_X_NULL_REF_POINTER);
967 /* NULL pointer has no further representation */
972 pointer_needs_sizing = !NdrFullPointerQueryPointer(
973 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
974 if (!pointer_needs_sizing)
978 FIXME("unhandled ptr type=%02x\n", type);
979 RpcRaiseException(RPC_X_BAD_STUB_DATA);
983 if (attr & RPC_FC_P_DEREF) {
984 Pointer = *(unsigned char**)Pointer;
985 TRACE("deref => %p\n", Pointer);
988 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
989 if (m) m(pStubMsg, Pointer, desc);
990 else FIXME("no buffersizer for data type=%02x\n", *desc);
993 /***********************************************************************
994 * PointerMemorySize [internal]
996 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
997 unsigned char *Buffer,
998 PFORMAT_STRING pFormat)
1000 unsigned type = pFormat[0], attr = pFormat[1];
1001 PFORMAT_STRING desc;
1003 DWORD pointer_id = 0;
1004 int pointer_needs_sizing;
1006 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1007 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1009 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1010 else desc = pFormat + *(const SHORT*)pFormat;
1013 case RPC_FC_RP: /* ref pointer (always non-null) */
1014 pointer_needs_sizing = 1;
1016 case RPC_FC_UP: /* unique pointer */
1017 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1018 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1019 TRACE("pointer_id is 0x%08x\n", pointer_id);
1021 pointer_needs_sizing = 1;
1023 pointer_needs_sizing = 0;
1028 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1029 TRACE("pointer_id is 0x%08x\n", pointer_id);
1030 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1031 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1035 FIXME("unhandled ptr type=%02x\n", type);
1036 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1040 if (attr & RPC_FC_P_DEREF) {
1044 if (pointer_needs_sizing) {
1045 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1046 if (m) m(pStubMsg, desc);
1047 else FIXME("no memorysizer for data type=%02x\n", *desc);
1050 return pStubMsg->MemorySize;
1053 /***********************************************************************
1054 * PointerFree [internal]
1056 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1057 unsigned char *Pointer,
1058 PFORMAT_STRING pFormat)
1060 unsigned type = pFormat[0], attr = pFormat[1];
1061 PFORMAT_STRING desc;
1063 unsigned char *current_pointer = Pointer;
1065 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1066 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1067 if (attr & RPC_FC_P_DONTFREE) return;
1069 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1070 else desc = pFormat + *(const SHORT*)pFormat;
1072 if (!Pointer) return;
1074 if (type == RPC_FC_FP) {
1075 int pointer_needs_freeing = NdrFullPointerFree(
1076 pStubMsg->FullPtrXlatTables, Pointer);
1077 if (!pointer_needs_freeing)
1081 if (attr & RPC_FC_P_DEREF) {
1082 current_pointer = *(unsigned char**)Pointer;
1083 TRACE("deref => %p\n", current_pointer);
1086 m = NdrFreer[*desc & NDR_TABLE_MASK];
1087 if (m) m(pStubMsg, current_pointer, desc);
1089 /* this check stops us from trying to free buffer memory. we don't have to
1090 * worry about clients, since they won't call this function.
1091 * we don't have to check for the buffer being reallocated because
1092 * BufferStart and BufferEnd won't be reset when allocating memory for
1093 * sending the response. we don't have to check for the new buffer here as
1094 * it won't be used a type memory, only for buffer memory */
1095 if (Pointer >= pStubMsg->BufferStart && Pointer < pStubMsg->BufferEnd)
1098 if (attr & RPC_FC_P_ONSTACK) {
1099 TRACE("not freeing stack ptr %p\n", Pointer);
1102 TRACE("freeing %p\n", Pointer);
1103 NdrFree(pStubMsg, Pointer);
1106 TRACE("not freeing %p\n", Pointer);
1109 /***********************************************************************
1110 * EmbeddedPointerMarshall
1112 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1113 unsigned char *pMemory,
1114 PFORMAT_STRING pFormat)
1116 unsigned char *Mark = pStubMsg->BufferMark;
1117 unsigned rep, count, stride;
1119 unsigned char *saved_buffer = NULL;
1121 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1123 if (*pFormat != RPC_FC_PP) return NULL;
1126 if (pStubMsg->PointerBufferMark)
1128 saved_buffer = pStubMsg->Buffer;
1129 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1130 pStubMsg->PointerBufferMark = NULL;
1133 while (pFormat[0] != RPC_FC_END) {
1134 switch (pFormat[0]) {
1136 FIXME("unknown repeat type %d\n", pFormat[0]);
1137 case RPC_FC_NO_REPEAT:
1143 case RPC_FC_FIXED_REPEAT:
1144 rep = *(const WORD*)&pFormat[2];
1145 stride = *(const WORD*)&pFormat[4];
1146 count = *(const WORD*)&pFormat[8];
1149 case RPC_FC_VARIABLE_REPEAT:
1150 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1151 stride = *(const WORD*)&pFormat[2];
1152 count = *(const WORD*)&pFormat[6];
1156 for (i = 0; i < rep; i++) {
1157 PFORMAT_STRING info = pFormat;
1158 unsigned char *membase = pMemory + (i * stride);
1159 unsigned char *bufbase = Mark + (i * stride);
1162 for (u=0; u<count; u++,info+=8) {
1163 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1164 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1165 unsigned char *saved_memory = pStubMsg->Memory;
1167 pStubMsg->Memory = pMemory;
1168 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1169 pStubMsg->Memory = saved_memory;
1172 pFormat += 8 * count;
1177 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1178 pStubMsg->Buffer = saved_buffer;
1181 STD_OVERFLOW_CHECK(pStubMsg);
1186 /***********************************************************************
1187 * EmbeddedPointerUnmarshall
1189 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1190 unsigned char *pDstBuffer,
1191 unsigned char *pSrcMemoryPtrs,
1192 PFORMAT_STRING pFormat,
1193 unsigned char fMustAlloc)
1195 unsigned char *Mark = pStubMsg->BufferMark;
1196 unsigned rep, count, stride;
1198 unsigned char *saved_buffer = NULL;
1200 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc);
1202 if (*pFormat != RPC_FC_PP) return NULL;
1205 if (pStubMsg->PointerBufferMark)
1207 saved_buffer = pStubMsg->Buffer;
1208 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1209 pStubMsg->PointerBufferMark = NULL;
1212 while (pFormat[0] != RPC_FC_END) {
1213 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1214 switch (pFormat[0]) {
1216 FIXME("unknown repeat type %d\n", pFormat[0]);
1217 case RPC_FC_NO_REPEAT:
1223 case RPC_FC_FIXED_REPEAT:
1224 rep = *(const WORD*)&pFormat[2];
1225 stride = *(const WORD*)&pFormat[4];
1226 count = *(const WORD*)&pFormat[8];
1229 case RPC_FC_VARIABLE_REPEAT:
1230 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1231 stride = *(const WORD*)&pFormat[2];
1232 count = *(const WORD*)&pFormat[6];
1236 for (i = 0; i < rep; i++) {
1237 PFORMAT_STRING info = pFormat;
1238 unsigned char *bufdstbase = pDstBuffer + (i * stride);
1239 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1240 unsigned char *bufbase = Mark + (i * stride);
1243 for (u=0; u<count; u++,info+=8) {
1244 unsigned char **bufdstptr = (unsigned char **)(bufdstbase + *(const SHORT*)&info[2]);
1245 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1246 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1247 PointerUnmarshall(pStubMsg, bufptr, bufdstptr, *memsrcptr, info+4, fMustAlloc);
1250 pFormat += 8 * count;
1255 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1256 pStubMsg->Buffer = saved_buffer;
1262 /***********************************************************************
1263 * EmbeddedPointerBufferSize
1265 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1266 unsigned char *pMemory,
1267 PFORMAT_STRING pFormat)
1269 unsigned rep, count, stride;
1271 ULONG saved_buffer_length = 0;
1273 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1275 if (pStubMsg->IgnoreEmbeddedPointers) return;
1277 if (*pFormat != RPC_FC_PP) return;
1280 if (pStubMsg->PointerLength)
1282 saved_buffer_length = pStubMsg->BufferLength;
1283 pStubMsg->BufferLength = pStubMsg->PointerLength;
1284 pStubMsg->PointerLength = 0;
1287 while (pFormat[0] != RPC_FC_END) {
1288 switch (pFormat[0]) {
1290 FIXME("unknown repeat type %d\n", pFormat[0]);
1291 case RPC_FC_NO_REPEAT:
1297 case RPC_FC_FIXED_REPEAT:
1298 rep = *(const WORD*)&pFormat[2];
1299 stride = *(const WORD*)&pFormat[4];
1300 count = *(const WORD*)&pFormat[8];
1303 case RPC_FC_VARIABLE_REPEAT:
1304 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1305 stride = *(const WORD*)&pFormat[2];
1306 count = *(const WORD*)&pFormat[6];
1310 for (i = 0; i < rep; i++) {
1311 PFORMAT_STRING info = pFormat;
1312 unsigned char *membase = pMemory + (i * stride);
1315 for (u=0; u<count; u++,info+=8) {
1316 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1317 unsigned char *saved_memory = pStubMsg->Memory;
1319 pStubMsg->Memory = pMemory;
1320 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1321 pStubMsg->Memory = saved_memory;
1324 pFormat += 8 * count;
1327 if (saved_buffer_length)
1329 pStubMsg->PointerLength = pStubMsg->BufferLength;
1330 pStubMsg->BufferLength = saved_buffer_length;
1334 /***********************************************************************
1335 * EmbeddedPointerMemorySize [internal]
1337 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1338 PFORMAT_STRING pFormat)
1340 unsigned char *Mark = pStubMsg->BufferMark;
1341 unsigned rep, count, stride;
1343 unsigned char *saved_buffer = NULL;
1345 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1347 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1349 if (pStubMsg->PointerBufferMark)
1351 saved_buffer = pStubMsg->Buffer;
1352 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1353 pStubMsg->PointerBufferMark = NULL;
1356 if (*pFormat != RPC_FC_PP) return 0;
1359 while (pFormat[0] != RPC_FC_END) {
1360 switch (pFormat[0]) {
1362 FIXME("unknown repeat type %d\n", pFormat[0]);
1363 case RPC_FC_NO_REPEAT:
1369 case RPC_FC_FIXED_REPEAT:
1370 rep = *(const WORD*)&pFormat[2];
1371 stride = *(const WORD*)&pFormat[4];
1372 count = *(const WORD*)&pFormat[8];
1375 case RPC_FC_VARIABLE_REPEAT:
1376 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1377 stride = *(const WORD*)&pFormat[2];
1378 count = *(const WORD*)&pFormat[6];
1382 for (i = 0; i < rep; i++) {
1383 PFORMAT_STRING info = pFormat;
1384 unsigned char *bufbase = Mark + (i * stride);
1386 for (u=0; u<count; u++,info+=8) {
1387 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1388 PointerMemorySize(pStubMsg, bufptr, info+4);
1391 pFormat += 8 * count;
1396 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1397 pStubMsg->Buffer = saved_buffer;
1403 /***********************************************************************
1404 * EmbeddedPointerFree [internal]
1406 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1407 unsigned char *pMemory,
1408 PFORMAT_STRING pFormat)
1410 unsigned rep, count, stride;
1413 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1414 if (*pFormat != RPC_FC_PP) return;
1417 while (pFormat[0] != RPC_FC_END) {
1418 switch (pFormat[0]) {
1420 FIXME("unknown repeat type %d\n", pFormat[0]);
1421 case RPC_FC_NO_REPEAT:
1427 case RPC_FC_FIXED_REPEAT:
1428 rep = *(const WORD*)&pFormat[2];
1429 stride = *(const WORD*)&pFormat[4];
1430 count = *(const WORD*)&pFormat[8];
1433 case RPC_FC_VARIABLE_REPEAT:
1434 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1435 stride = *(const WORD*)&pFormat[2];
1436 count = *(const WORD*)&pFormat[6];
1440 for (i = 0; i < rep; i++) {
1441 PFORMAT_STRING info = pFormat;
1442 unsigned char *membase = pMemory + (i * stride);
1445 for (u=0; u<count; u++,info+=8) {
1446 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1447 unsigned char *saved_memory = pStubMsg->Memory;
1449 pStubMsg->Memory = pMemory;
1450 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1451 pStubMsg->Memory = saved_memory;
1454 pFormat += 8 * count;
1458 /***********************************************************************
1459 * NdrPointerMarshall [RPCRT4.@]
1461 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1462 unsigned char *pMemory,
1463 PFORMAT_STRING pFormat)
1465 unsigned char *Buffer;
1467 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1469 /* Increment the buffer here instead of in PointerMarshall,
1470 * as that is used by embedded pointers which already handle the incrementing
1471 * the buffer, and shouldn't write any additional pointer data to the wire */
1472 if (*pFormat != RPC_FC_RP)
1474 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
1475 Buffer = pStubMsg->Buffer;
1476 safe_buffer_increment(pStubMsg, 4);
1479 Buffer = pStubMsg->Buffer;
1481 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1486 /***********************************************************************
1487 * NdrPointerUnmarshall [RPCRT4.@]
1489 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1490 unsigned char **ppMemory,
1491 PFORMAT_STRING pFormat,
1492 unsigned char fMustAlloc)
1494 unsigned char *Buffer;
1496 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1498 /* Increment the buffer here instead of in PointerUnmarshall,
1499 * as that is used by embedded pointers which already handle the incrementing
1500 * the buffer, and shouldn't read any additional pointer data from the
1502 if (*pFormat != RPC_FC_RP)
1504 ALIGN_POINTER(pStubMsg->Buffer, 4);
1505 Buffer = pStubMsg->Buffer;
1506 safe_buffer_increment(pStubMsg, 4);
1509 Buffer = pStubMsg->Buffer;
1511 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1516 /***********************************************************************
1517 * NdrPointerBufferSize [RPCRT4.@]
1519 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1520 unsigned char *pMemory,
1521 PFORMAT_STRING pFormat)
1523 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1525 /* Increment the buffer length here instead of in PointerBufferSize,
1526 * as that is used by embedded pointers which already handle the buffer
1527 * length, and shouldn't write anything more to the wire */
1528 if (*pFormat != RPC_FC_RP)
1530 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1531 safe_buffer_length_increment(pStubMsg, 4);
1534 PointerBufferSize(pStubMsg, pMemory, pFormat);
1537 /***********************************************************************
1538 * NdrPointerMemorySize [RPCRT4.@]
1540 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1541 PFORMAT_STRING pFormat)
1543 /* unsigned size = *(LPWORD)(pFormat+2); */
1544 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1545 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1549 /***********************************************************************
1550 * NdrPointerFree [RPCRT4.@]
1552 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1553 unsigned char *pMemory,
1554 PFORMAT_STRING pFormat)
1556 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1557 PointerFree(pStubMsg, pMemory, pFormat);
1560 /***********************************************************************
1561 * NdrSimpleTypeMarshall [RPCRT4.@]
1563 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1564 unsigned char FormatChar )
1566 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1569 /***********************************************************************
1570 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1572 * Unmarshall a base type.
1575 * Doesn't check that the buffer is long enough before copying, so the caller
1578 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1579 unsigned char FormatChar )
1581 #define BASE_TYPE_UNMARSHALL(type) \
1582 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
1583 TRACE("pMemory: %p\n", pMemory); \
1584 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1585 pStubMsg->Buffer += sizeof(type);
1593 BASE_TYPE_UNMARSHALL(UCHAR);
1594 TRACE("value: 0x%02x\n", *pMemory);
1599 BASE_TYPE_UNMARSHALL(USHORT);
1600 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
1604 case RPC_FC_ERROR_STATUS_T:
1606 BASE_TYPE_UNMARSHALL(ULONG);
1607 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
1610 BASE_TYPE_UNMARSHALL(float);
1611 TRACE("value: %f\n", *(float *)pMemory);
1614 BASE_TYPE_UNMARSHALL(double);
1615 TRACE("value: %f\n", *(double *)pMemory);
1618 BASE_TYPE_UNMARSHALL(ULONGLONG);
1619 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
1622 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
1623 TRACE("pMemory: %p\n", pMemory);
1624 /* 16-bits on the wire, but int in memory */
1625 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
1626 pStubMsg->Buffer += sizeof(USHORT);
1627 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
1632 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
1634 #undef BASE_TYPE_UNMARSHALL
1637 /***********************************************************************
1638 * NdrSimpleStructMarshall [RPCRT4.@]
1640 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1641 unsigned char *pMemory,
1642 PFORMAT_STRING pFormat)
1644 unsigned size = *(const WORD*)(pFormat+2);
1645 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1647 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
1649 pStubMsg->BufferMark = pStubMsg->Buffer;
1650 safe_copy_to_buffer(pStubMsg, pMemory, size);
1652 if (pFormat[0] != RPC_FC_STRUCT)
1653 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1658 /***********************************************************************
1659 * NdrSimpleStructUnmarshall [RPCRT4.@]
1661 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1662 unsigned char **ppMemory,
1663 PFORMAT_STRING pFormat,
1664 unsigned char fMustAlloc)
1666 unsigned size = *(const WORD*)(pFormat+2);
1667 unsigned char *saved_buffer;
1668 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1670 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1673 *ppMemory = NdrAllocate(pStubMsg, size);
1676 if (!pStubMsg->IsClient && !*ppMemory)
1677 /* for servers, we just point straight into the RPC buffer */
1678 *ppMemory = pStubMsg->Buffer;
1681 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1682 safe_buffer_increment(pStubMsg, size);
1683 if (pFormat[0] == RPC_FC_PSTRUCT)
1684 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1686 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1687 if (*ppMemory != saved_buffer)
1688 memcpy(*ppMemory, saved_buffer, size);
1693 /***********************************************************************
1694 * NdrSimpleStructBufferSize [RPCRT4.@]
1696 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1697 unsigned char *pMemory,
1698 PFORMAT_STRING pFormat)
1700 unsigned size = *(const WORD*)(pFormat+2);
1701 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1703 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1705 safe_buffer_length_increment(pStubMsg, size);
1706 if (pFormat[0] != RPC_FC_STRUCT)
1707 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1710 /***********************************************************************
1711 * NdrSimpleStructMemorySize [RPCRT4.@]
1713 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1714 PFORMAT_STRING pFormat)
1716 unsigned short size = *(const WORD *)(pFormat+2);
1718 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1720 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1721 pStubMsg->MemorySize += size;
1722 safe_buffer_increment(pStubMsg, size);
1724 if (pFormat[0] != RPC_FC_STRUCT)
1725 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1726 return pStubMsg->MemorySize;
1729 /***********************************************************************
1730 * NdrSimpleStructFree [RPCRT4.@]
1732 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1733 unsigned char *pMemory,
1734 PFORMAT_STRING pFormat)
1736 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1737 if (pFormat[0] != RPC_FC_STRUCT)
1738 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1743 static inline void array_compute_and_size_conformance(
1744 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1745 PFORMAT_STRING pFormat)
1750 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1751 SizeConformance(pStubMsg);
1753 case RPC_FC_CVARRAY:
1754 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1755 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1756 SizeConformance(pStubMsg);
1758 case RPC_FC_C_CSTRING:
1759 case RPC_FC_C_WSTRING:
1760 if (pFormat[0] == RPC_FC_C_CSTRING)
1762 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1763 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1767 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1768 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1771 if (fc == RPC_FC_STRING_SIZED)
1772 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1774 pStubMsg->MaxCount = pStubMsg->ActualCount;
1776 SizeConformance(pStubMsg);
1779 ERR("unknown array format 0x%x\n", fc);
1780 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1784 static inline void array_buffer_size(
1785 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1786 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1790 unsigned char alignment;
1795 esize = *(const WORD*)(pFormat+2);
1796 alignment = pFormat[1] + 1;
1798 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1800 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
1802 size = safe_multiply(esize, pStubMsg->MaxCount);
1803 /* conformance value plus array */
1804 safe_buffer_length_increment(pStubMsg, size);
1807 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1809 case RPC_FC_CVARRAY:
1810 esize = *(const WORD*)(pFormat+2);
1811 alignment = pFormat[1] + 1;
1813 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1814 pFormat = SkipConformance(pStubMsg, pFormat);
1816 SizeVariance(pStubMsg);
1818 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
1820 size = safe_multiply(esize, pStubMsg->ActualCount);
1821 safe_buffer_length_increment(pStubMsg, size);
1824 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1826 case RPC_FC_C_CSTRING:
1827 case RPC_FC_C_WSTRING:
1828 if (fc == RPC_FC_C_CSTRING)
1833 SizeVariance(pStubMsg);
1835 size = safe_multiply(esize, pStubMsg->ActualCount);
1836 safe_buffer_length_increment(pStubMsg, size);
1839 ERR("unknown array format 0x%x\n", fc);
1840 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1844 static inline void array_compute_and_write_conformance(
1845 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1846 PFORMAT_STRING pFormat)
1851 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1852 WriteConformance(pStubMsg);
1854 case RPC_FC_CVARRAY:
1855 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1856 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1857 WriteConformance(pStubMsg);
1859 case RPC_FC_C_CSTRING:
1860 case RPC_FC_C_WSTRING:
1861 if (fc == RPC_FC_C_CSTRING)
1863 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1864 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1868 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1869 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1871 if (pFormat[1] == RPC_FC_STRING_SIZED)
1872 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1874 pStubMsg->MaxCount = pStubMsg->ActualCount;
1875 pStubMsg->Offset = 0;
1876 WriteConformance(pStubMsg);
1879 ERR("unknown array format 0x%x\n", fc);
1880 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1884 static inline void array_write_variance_and_marshall(
1885 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1886 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1890 unsigned char alignment;
1895 esize = *(const WORD*)(pFormat+2);
1896 alignment = pFormat[1] + 1;
1898 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1900 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
1902 size = safe_multiply(esize, pStubMsg->MaxCount);
1904 pStubMsg->BufferMark = pStubMsg->Buffer;
1905 safe_copy_to_buffer(pStubMsg, pMemory, size);
1908 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1910 case RPC_FC_CVARRAY:
1911 esize = *(const WORD*)(pFormat+2);
1912 alignment = pFormat[1] + 1;
1915 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1917 pFormat = SkipConformance(pStubMsg, pFormat);
1919 WriteVariance(pStubMsg);
1921 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
1923 size = safe_multiply(esize, pStubMsg->ActualCount);
1926 pStubMsg->BufferMark = pStubMsg->Buffer;
1927 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size);
1930 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1932 case RPC_FC_C_CSTRING:
1933 case RPC_FC_C_WSTRING:
1934 if (fc == RPC_FC_C_CSTRING)
1939 WriteVariance(pStubMsg);
1941 size = safe_multiply(esize, pStubMsg->ActualCount);
1942 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
1945 ERR("unknown array format 0x%x\n", fc);
1946 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1950 static inline ULONG array_read_conformance(
1951 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
1958 esize = *(const WORD*)(pFormat+2);
1959 pFormat = ReadConformance(pStubMsg, pFormat+4);
1960 return safe_multiply(esize, pStubMsg->MaxCount);
1961 case RPC_FC_CVARRAY:
1962 esize = *(const WORD*)(pFormat+2);
1963 pFormat = ReadConformance(pStubMsg, pFormat+4);
1964 return safe_multiply(esize, pStubMsg->MaxCount);
1965 case RPC_FC_C_CSTRING:
1966 case RPC_FC_C_WSTRING:
1967 if (fc == RPC_FC_C_CSTRING)
1972 if (pFormat[1] == RPC_FC_STRING_SIZED)
1973 ReadConformance(pStubMsg, pFormat + 2);
1975 ReadConformance(pStubMsg, NULL);
1976 return safe_multiply(esize, pStubMsg->MaxCount);
1978 ERR("unknown array format 0x%x\n", fc);
1979 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1983 static inline ULONG array_read_variance_and_unmarshall(
1984 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory,
1985 PFORMAT_STRING pFormat, unsigned char fMustAlloc,
1986 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall)
1988 ULONG bufsize, memsize;
1990 unsigned char alignment;
1991 unsigned char *saved_buffer;
1997 esize = *(const WORD*)(pFormat+2);
1998 alignment = pFormat[1] + 1;
2000 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2002 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2004 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2009 *ppMemory = NdrAllocate(pStubMsg, memsize);
2012 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory)
2013 /* for servers, we just point straight into the RPC buffer */
2014 *ppMemory = pStubMsg->Buffer;
2017 saved_buffer = pStubMsg->Buffer;
2018 safe_buffer_increment(pStubMsg, bufsize);
2020 pStubMsg->BufferMark = saved_buffer;
2021 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2023 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2024 if (*ppMemory != saved_buffer)
2025 memcpy(*ppMemory, saved_buffer, bufsize);
2028 case RPC_FC_CVARRAY:
2029 esize = *(const WORD*)(pFormat+2);
2030 alignment = pFormat[1] + 1;
2032 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2034 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2036 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2038 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2039 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2043 offset = pStubMsg->Offset;
2045 if (!fMustAlloc && !*ppMemory)
2048 *ppMemory = NdrAllocate(pStubMsg, memsize);
2049 saved_buffer = pStubMsg->Buffer;
2050 safe_buffer_increment(pStubMsg, bufsize);
2052 pStubMsg->BufferMark = saved_buffer;
2053 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat,
2056 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2059 case RPC_FC_C_CSTRING:
2060 case RPC_FC_C_WSTRING:
2061 if (fc == RPC_FC_C_CSTRING)
2066 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2068 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2070 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2071 pStubMsg->ActualCount, pStubMsg->MaxCount);
2072 RpcRaiseException(RPC_S_INVALID_BOUND);
2074 if (pStubMsg->Offset)
2076 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2077 RpcRaiseException(RPC_S_INVALID_BOUND);
2080 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2081 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2083 validate_string_data(pStubMsg, bufsize, esize);
2088 *ppMemory = NdrAllocate(pStubMsg, memsize);
2091 if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
2092 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
2093 /* if the data in the RPC buffer is big enough, we just point
2094 * straight into it */
2095 *ppMemory = pStubMsg->Buffer;
2096 else if (!*ppMemory)
2097 *ppMemory = NdrAllocate(pStubMsg, memsize);
2100 if (*ppMemory == pStubMsg->Buffer)
2101 safe_buffer_increment(pStubMsg, bufsize);
2103 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2105 if (*pFormat == RPC_FC_C_CSTRING)
2106 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
2108 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
2112 ERR("unknown array format 0x%x\n", fc);
2113 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2117 static inline void array_memory_size(
2118 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
2119 unsigned char fHasPointers)
2121 ULONG bufsize, memsize;
2123 unsigned char alignment;
2128 esize = *(const WORD*)(pFormat+2);
2129 alignment = pFormat[1] + 1;
2131 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2133 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2134 pStubMsg->MemorySize += memsize;
2136 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2138 pStubMsg->BufferMark = pStubMsg->Buffer;
2139 safe_buffer_increment(pStubMsg, bufsize);
2142 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2144 case RPC_FC_CVARRAY:
2145 esize = *(const WORD*)(pFormat+2);
2146 alignment = pFormat[1] + 1;
2148 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2150 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2152 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2153 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2154 pStubMsg->MemorySize += memsize;
2156 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2158 pStubMsg->BufferMark = pStubMsg->Buffer;
2159 safe_buffer_increment(pStubMsg, bufsize);
2162 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2164 case RPC_FC_C_CSTRING:
2165 case RPC_FC_C_WSTRING:
2166 if (fc == RPC_FC_C_CSTRING)
2171 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2173 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2175 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2176 pStubMsg->ActualCount, pStubMsg->MaxCount);
2177 RpcRaiseException(RPC_S_INVALID_BOUND);
2179 if (pStubMsg->Offset)
2181 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2182 RpcRaiseException(RPC_S_INVALID_BOUND);
2185 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2186 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2188 validate_string_data(pStubMsg, bufsize, esize);
2190 safe_buffer_increment(pStubMsg, bufsize);
2191 pStubMsg->MemorySize += memsize;
2194 ERR("unknown array format 0x%x\n", fc);
2195 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2199 static inline void array_free(
2200 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
2201 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
2206 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2208 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2210 case RPC_FC_CVARRAY:
2211 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2212 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2214 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2216 case RPC_FC_C_CSTRING:
2217 case RPC_FC_C_WSTRING:
2218 /* No embedded pointers so nothing to do */
2221 ERR("unknown array format 0x%x\n", fc);
2222 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2227 * NdrConformantString:
2229 * What MS calls a ConformantString is, in DCE terminology,
2230 * a Varying-Conformant String.
2232 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2233 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2234 * into unmarshalled string)
2235 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2237 * data: CHARTYPE[maxlen]
2239 * ], where CHARTYPE is the appropriate character type (specified externally)
2243 /***********************************************************************
2244 * NdrConformantStringMarshall [RPCRT4.@]
2246 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
2247 unsigned char *pszMessage, PFORMAT_STRING pFormat)
2249 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
2251 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2252 ERR("Unhandled string type: %#x\n", pFormat[0]);
2253 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2256 /* allow compiler to optimise inline function by passing constant into
2257 * these functions */
2258 if (pFormat[0] == RPC_FC_C_CSTRING) {
2259 array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2261 array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2262 pFormat, TRUE /* fHasPointers */);
2264 array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2266 array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2267 pFormat, TRUE /* fHasPointers */);
2273 /***********************************************************************
2274 * NdrConformantStringBufferSize [RPCRT4.@]
2276 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2277 unsigned char* pMemory, PFORMAT_STRING pFormat)
2279 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2281 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2282 ERR("Unhandled string type: %#x\n", pFormat[0]);
2283 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2286 /* allow compiler to optimise inline function by passing constant into
2287 * these functions */
2288 if (pFormat[0] == RPC_FC_C_CSTRING) {
2289 array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory,
2291 array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat,
2292 TRUE /* fHasPointers */);
2294 array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory,
2296 array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat,
2297 TRUE /* fHasPointers */);
2301 /************************************************************************
2302 * NdrConformantStringMemorySize [RPCRT4.@]
2304 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2305 PFORMAT_STRING pFormat )
2307 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2309 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2310 ERR("Unhandled string type: %#x\n", pFormat[0]);
2311 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2314 /* allow compiler to optimise inline function by passing constant into
2315 * these functions */
2316 if (pFormat[0] == RPC_FC_C_CSTRING) {
2317 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2318 array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat,
2319 TRUE /* fHasPointers */);
2321 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2322 array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat,
2323 TRUE /* fHasPointers */);
2326 return pStubMsg->MemorySize;
2329 /************************************************************************
2330 * NdrConformantStringUnmarshall [RPCRT4.@]
2332 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2333 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
2335 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2336 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2338 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2339 ERR("Unhandled string type: %#x\n", *pFormat);
2340 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2343 /* allow compiler to optimise inline function by passing constant into
2344 * these functions */
2345 if (pFormat[0] == RPC_FC_C_CSTRING) {
2346 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2347 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory,
2348 pFormat, fMustAlloc,
2349 TRUE /* fUseBufferMemoryServer */,
2350 TRUE /* fUnmarshall */);
2352 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2353 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory,
2354 pFormat, fMustAlloc,
2355 TRUE /* fUseBufferMemoryServer */,
2356 TRUE /* fUnmarshall */);
2362 /***********************************************************************
2363 * NdrNonConformantStringMarshall [RPCRT4.@]
2365 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2366 unsigned char *pMemory,
2367 PFORMAT_STRING pFormat)
2369 ULONG esize, size, maxsize;
2371 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2373 maxsize = *(USHORT *)&pFormat[2];
2375 if (*pFormat == RPC_FC_CSTRING)
2378 const char *str = (const char *)pMemory;
2379 for (i = 0; i < maxsize && *str; i++, str++)
2381 TRACE("string=%s\n", debugstr_an(str, i));
2382 pStubMsg->ActualCount = i + 1;
2385 else if (*pFormat == RPC_FC_WSTRING)
2388 const WCHAR *str = (const WCHAR *)pMemory;
2389 for (i = 0; i < maxsize && *str; i++, str++)
2391 TRACE("string=%s\n", debugstr_wn(str, i));
2392 pStubMsg->ActualCount = i + 1;
2397 ERR("Unhandled string type: %#x\n", *pFormat);
2398 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2401 pStubMsg->Offset = 0;
2402 WriteVariance(pStubMsg);
2404 size = safe_multiply(esize, pStubMsg->ActualCount);
2405 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2410 /***********************************************************************
2411 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2413 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2414 unsigned char **ppMemory,
2415 PFORMAT_STRING pFormat,
2416 unsigned char fMustAlloc)
2418 ULONG bufsize, memsize, esize, maxsize;
2420 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2421 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2423 maxsize = *(USHORT *)&pFormat[2];
2425 ReadVariance(pStubMsg, NULL, maxsize);
2426 if (pStubMsg->Offset)
2428 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2429 RpcRaiseException(RPC_S_INVALID_BOUND);
2432 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2433 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2436 ERR("Unhandled string type: %#x\n", *pFormat);
2437 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2440 memsize = esize * maxsize;
2441 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2443 validate_string_data(pStubMsg, bufsize, esize);
2445 if (fMustAlloc || !*ppMemory)
2446 *ppMemory = NdrAllocate(pStubMsg, memsize);
2448 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2450 if (*pFormat == RPC_FC_CSTRING) {
2451 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
2453 else if (*pFormat == RPC_FC_WSTRING) {
2454 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
2460 /***********************************************************************
2461 * NdrNonConformantStringBufferSize [RPCRT4.@]
2463 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2464 unsigned char *pMemory,
2465 PFORMAT_STRING pFormat)
2467 ULONG esize, maxsize;
2469 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2471 maxsize = *(USHORT *)&pFormat[2];
2473 SizeVariance(pStubMsg);
2475 if (*pFormat == RPC_FC_CSTRING)
2478 const char *str = (const char *)pMemory;
2479 for (i = 0; i < maxsize && *str; i++, str++)
2481 TRACE("string=%s\n", debugstr_an(str, i));
2482 pStubMsg->ActualCount = i + 1;
2485 else if (*pFormat == RPC_FC_WSTRING)
2488 const WCHAR *str = (const WCHAR *)pMemory;
2489 for (i = 0; i < maxsize && *str; i++, str++)
2491 TRACE("string=%s\n", debugstr_wn(str, i));
2492 pStubMsg->ActualCount = i + 1;
2497 ERR("Unhandled string type: %#x\n", *pFormat);
2498 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2501 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2504 /***********************************************************************
2505 * NdrNonConformantStringMemorySize [RPCRT4.@]
2507 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2508 PFORMAT_STRING pFormat)
2510 ULONG bufsize, memsize, esize, maxsize;
2512 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2514 maxsize = *(USHORT *)&pFormat[2];
2516 ReadVariance(pStubMsg, NULL, maxsize);
2518 if (pStubMsg->Offset)
2520 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2521 RpcRaiseException(RPC_S_INVALID_BOUND);
2524 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2525 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2528 ERR("Unhandled string type: %#x\n", *pFormat);
2529 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2532 memsize = esize * maxsize;
2533 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2535 validate_string_data(pStubMsg, bufsize, esize);
2537 safe_buffer_increment(pStubMsg, bufsize);
2538 pStubMsg->MemorySize += memsize;
2540 return pStubMsg->MemorySize;
2545 #include "pshpack1.h"
2549 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2553 #include "poppack.h"
2555 static unsigned long EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2556 PFORMAT_STRING pFormat)
2560 case RPC_FC_PSTRUCT:
2561 case RPC_FC_CSTRUCT:
2562 case RPC_FC_BOGUS_STRUCT:
2563 case RPC_FC_SMFARRAY:
2564 case RPC_FC_SMVARRAY:
2565 case RPC_FC_CSTRING:
2566 return *(const WORD*)&pFormat[2];
2567 case RPC_FC_USER_MARSHAL:
2568 return *(const WORD*)&pFormat[4];
2569 case RPC_FC_RANGE: {
2570 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2575 return sizeof(UCHAR);
2579 return sizeof(USHORT);
2583 return sizeof(ULONG);
2585 return sizeof(float);
2587 return sizeof(double);
2589 return sizeof(ULONGLONG);
2591 return sizeof(UINT);
2593 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2594 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2597 case RPC_FC_NON_ENCAPSULATED_UNION:
2599 if (pStubMsg->fHasNewCorrDesc)
2604 pFormat += *(const SHORT*)pFormat;
2605 return *(const SHORT*)pFormat;
2607 return sizeof(void *);
2608 case RPC_FC_WSTRING:
2609 return *(const WORD*)&pFormat[2] * 2;
2611 FIXME("unhandled embedded type %02x\n", *pFormat);
2617 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2618 PFORMAT_STRING pFormat)
2620 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2624 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2628 return m(pStubMsg, pFormat);
2632 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2633 unsigned char *pMemory,
2634 PFORMAT_STRING pFormat,
2635 PFORMAT_STRING pPointer)
2637 PFORMAT_STRING desc;
2641 while (*pFormat != RPC_FC_END) {
2647 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2648 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2654 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2655 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2659 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2660 if (32767 < *(DWORD*)pMemory)
2661 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2662 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2668 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2669 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2673 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2674 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2677 case RPC_FC_POINTER:
2679 unsigned char *saved_buffer;
2680 int pointer_buffer_mark_set = 0;
2681 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2682 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2683 if (*pPointer != RPC_FC_RP)
2684 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
2685 saved_buffer = pStubMsg->Buffer;
2686 if (pStubMsg->PointerBufferMark)
2688 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2689 pStubMsg->PointerBufferMark = NULL;
2690 pointer_buffer_mark_set = 1;
2692 else if (*pPointer != RPC_FC_RP)
2693 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2694 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2695 if (pointer_buffer_mark_set)
2697 STD_OVERFLOW_CHECK(pStubMsg);
2698 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2699 pStubMsg->Buffer = saved_buffer;
2700 if (*pPointer != RPC_FC_RP)
2701 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2703 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2708 case RPC_FC_ALIGNM4:
2709 ALIGN_POINTER(pMemory, 4);
2711 case RPC_FC_ALIGNM8:
2712 ALIGN_POINTER(pMemory, 8);
2714 case RPC_FC_STRUCTPAD1:
2715 case RPC_FC_STRUCTPAD2:
2716 case RPC_FC_STRUCTPAD3:
2717 case RPC_FC_STRUCTPAD4:
2718 case RPC_FC_STRUCTPAD5:
2719 case RPC_FC_STRUCTPAD6:
2720 case RPC_FC_STRUCTPAD7:
2721 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2723 case RPC_FC_EMBEDDED_COMPLEX:
2724 pMemory += pFormat[1];
2726 desc = pFormat + *(const SHORT*)pFormat;
2727 size = EmbeddedComplexSize(pStubMsg, desc);
2728 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
2729 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2732 /* for some reason interface pointers aren't generated as
2733 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2734 * they still need the derefencing treatment that pointers are
2736 if (*desc == RPC_FC_IP)
2737 m(pStubMsg, *(unsigned char **)pMemory, desc);
2739 m(pStubMsg, pMemory, desc);
2741 else FIXME("no marshaller for embedded type %02x\n", *desc);
2748 FIXME("unhandled format 0x%02x\n", *pFormat);
2756 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2757 unsigned char *pMemory,
2758 PFORMAT_STRING pFormat,
2759 PFORMAT_STRING pPointer,
2760 unsigned char fMustAlloc)
2762 PFORMAT_STRING desc;
2766 while (*pFormat != RPC_FC_END) {
2772 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2773 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2779 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2780 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2784 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2785 *(DWORD*)pMemory &= 0xffff;
2786 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
2787 if (32767 < *(DWORD*)pMemory)
2788 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2794 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2795 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2799 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2800 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2803 case RPC_FC_POINTER:
2805 unsigned char *saved_buffer;
2806 int pointer_buffer_mark_set = 0;
2807 TRACE("pointer => %p\n", pMemory);
2808 if (*pPointer != RPC_FC_RP)
2809 ALIGN_POINTER(pStubMsg->Buffer, 4);
2810 saved_buffer = pStubMsg->Buffer;
2811 if (pStubMsg->PointerBufferMark)
2813 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2814 pStubMsg->PointerBufferMark = NULL;
2815 pointer_buffer_mark_set = 1;
2817 else if (*pPointer != RPC_FC_RP)
2818 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2820 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
2821 if (pointer_buffer_mark_set)
2823 STD_OVERFLOW_CHECK(pStubMsg);
2824 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2825 pStubMsg->Buffer = saved_buffer;
2826 if (*pPointer != RPC_FC_RP)
2827 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2833 case RPC_FC_ALIGNM4:
2834 ALIGN_POINTER_CLEAR(pMemory, 4);
2836 case RPC_FC_ALIGNM8:
2837 ALIGN_POINTER_CLEAR(pMemory, 8);
2839 case RPC_FC_STRUCTPAD1:
2840 case RPC_FC_STRUCTPAD2:
2841 case RPC_FC_STRUCTPAD3:
2842 case RPC_FC_STRUCTPAD4:
2843 case RPC_FC_STRUCTPAD5:
2844 case RPC_FC_STRUCTPAD6:
2845 case RPC_FC_STRUCTPAD7:
2846 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2847 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2849 case RPC_FC_EMBEDDED_COMPLEX:
2850 pMemory += pFormat[1];
2852 desc = pFormat + *(const SHORT*)pFormat;
2853 size = EmbeddedComplexSize(pStubMsg, desc);
2854 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2856 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
2857 * since the type is part of the memory block that is encompassed by
2858 * the whole complex type. Memory is forced to allocate when pointers
2859 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
2860 * clearing the memory we pass in to the unmarshaller */
2861 memset(pMemory, 0, size);
2862 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2865 /* for some reason interface pointers aren't generated as
2866 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2867 * they still need the derefencing treatment that pointers are
2869 if (*desc == RPC_FC_IP)
2870 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2872 m(pStubMsg, &pMemory, desc, FALSE);
2874 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2881 FIXME("unhandled format %d\n", *pFormat);
2889 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2890 unsigned char *pMemory,
2891 PFORMAT_STRING pFormat,
2892 PFORMAT_STRING pPointer)
2894 PFORMAT_STRING desc;
2898 while (*pFormat != RPC_FC_END) {
2904 safe_buffer_length_increment(pStubMsg, 1);
2910 safe_buffer_length_increment(pStubMsg, 2);
2914 safe_buffer_length_increment(pStubMsg, 2);
2920 safe_buffer_length_increment(pStubMsg, 4);
2924 safe_buffer_length_increment(pStubMsg, 8);
2927 case RPC_FC_POINTER:
2928 if (!pStubMsg->IgnoreEmbeddedPointers)
2930 int saved_buffer_length = pStubMsg->BufferLength;
2931 pStubMsg->BufferLength = pStubMsg->PointerLength;
2932 pStubMsg->PointerLength = 0;
2933 if(!pStubMsg->BufferLength)
2934 ERR("BufferLength == 0??\n");
2935 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2936 pStubMsg->PointerLength = pStubMsg->BufferLength;
2937 pStubMsg->BufferLength = saved_buffer_length;
2939 if (*pPointer != RPC_FC_RP)
2941 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2942 safe_buffer_length_increment(pStubMsg, 4);
2947 case RPC_FC_ALIGNM4:
2948 ALIGN_POINTER(pMemory, 4);
2950 case RPC_FC_ALIGNM8:
2951 ALIGN_POINTER(pMemory, 8);
2953 case RPC_FC_STRUCTPAD1:
2954 case RPC_FC_STRUCTPAD2:
2955 case RPC_FC_STRUCTPAD3:
2956 case RPC_FC_STRUCTPAD4:
2957 case RPC_FC_STRUCTPAD5:
2958 case RPC_FC_STRUCTPAD6:
2959 case RPC_FC_STRUCTPAD7:
2960 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2962 case RPC_FC_EMBEDDED_COMPLEX:
2963 pMemory += pFormat[1];
2965 desc = pFormat + *(const SHORT*)pFormat;
2966 size = EmbeddedComplexSize(pStubMsg, desc);
2967 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2970 /* for some reason interface pointers aren't generated as
2971 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2972 * they still need the derefencing treatment that pointers are
2974 if (*desc == RPC_FC_IP)
2975 m(pStubMsg, *(unsigned char **)pMemory, desc);
2977 m(pStubMsg, pMemory, desc);
2979 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2986 FIXME("unhandled format 0x%02x\n", *pFormat);
2994 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2995 unsigned char *pMemory,
2996 PFORMAT_STRING pFormat,
2997 PFORMAT_STRING pPointer)
2999 PFORMAT_STRING desc;
3003 while (*pFormat != RPC_FC_END) {
3025 case RPC_FC_POINTER:
3026 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3030 case RPC_FC_ALIGNM4:
3031 ALIGN_POINTER(pMemory, 4);
3033 case RPC_FC_ALIGNM8:
3034 ALIGN_POINTER(pMemory, 8);
3036 case RPC_FC_STRUCTPAD1:
3037 case RPC_FC_STRUCTPAD2:
3038 case RPC_FC_STRUCTPAD3:
3039 case RPC_FC_STRUCTPAD4:
3040 case RPC_FC_STRUCTPAD5:
3041 case RPC_FC_STRUCTPAD6:
3042 case RPC_FC_STRUCTPAD7:
3043 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3045 case RPC_FC_EMBEDDED_COMPLEX:
3046 pMemory += pFormat[1];
3048 desc = pFormat + *(const SHORT*)pFormat;
3049 size = EmbeddedComplexSize(pStubMsg, desc);
3050 m = NdrFreer[*desc & NDR_TABLE_MASK];
3053 /* for some reason interface pointers aren't generated as
3054 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3055 * they still need the derefencing treatment that pointers are
3057 if (*desc == RPC_FC_IP)
3058 m(pStubMsg, *(unsigned char **)pMemory, desc);
3060 m(pStubMsg, pMemory, desc);
3068 FIXME("unhandled format 0x%02x\n", *pFormat);
3076 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3077 PFORMAT_STRING pFormat,
3078 PFORMAT_STRING pPointer)
3080 PFORMAT_STRING desc;
3081 unsigned long size = 0;
3083 while (*pFormat != RPC_FC_END) {
3090 safe_buffer_increment(pStubMsg, 1);
3096 safe_buffer_increment(pStubMsg, 2);
3100 safe_buffer_increment(pStubMsg, 2);
3106 safe_buffer_increment(pStubMsg, 4);
3110 safe_buffer_increment(pStubMsg, 8);
3112 case RPC_FC_POINTER:
3114 unsigned char *saved_buffer;
3115 int pointer_buffer_mark_set = 0;
3116 if (*pPointer != RPC_FC_RP)
3117 ALIGN_POINTER(pStubMsg->Buffer, 4);
3118 saved_buffer = pStubMsg->Buffer;
3119 if (pStubMsg->PointerBufferMark)
3121 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3122 pStubMsg->PointerBufferMark = NULL;
3123 pointer_buffer_mark_set = 1;
3125 else if (*pPointer != RPC_FC_RP)
3126 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3128 if (!pStubMsg->IgnoreEmbeddedPointers)
3129 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3130 if (pointer_buffer_mark_set)
3132 STD_OVERFLOW_CHECK(pStubMsg);
3133 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3134 pStubMsg->Buffer = saved_buffer;
3135 if (*pPointer != RPC_FC_RP)
3136 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3142 case RPC_FC_ALIGNM4:
3143 ALIGN_LENGTH(size, 4);
3144 ALIGN_POINTER(pStubMsg->Buffer, 4);
3146 case RPC_FC_ALIGNM8:
3147 ALIGN_LENGTH(size, 8);
3148 ALIGN_POINTER(pStubMsg->Buffer, 8);
3150 case RPC_FC_STRUCTPAD1:
3151 case RPC_FC_STRUCTPAD2:
3152 case RPC_FC_STRUCTPAD3:
3153 case RPC_FC_STRUCTPAD4:
3154 case RPC_FC_STRUCTPAD5:
3155 case RPC_FC_STRUCTPAD6:
3156 case RPC_FC_STRUCTPAD7:
3157 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3159 case RPC_FC_EMBEDDED_COMPLEX:
3162 desc = pFormat + *(const SHORT*)pFormat;
3163 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3169 FIXME("unhandled format 0x%02x\n", *pFormat);
3177 unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg,
3178 PFORMAT_STRING pFormat)
3180 PFORMAT_STRING desc;
3181 unsigned long size = 0;
3183 while (*pFormat != RPC_FC_END) {
3205 case RPC_FC_POINTER:
3206 size += sizeof(void *);
3208 case RPC_FC_ALIGNM4:
3209 ALIGN_LENGTH(size, 4);
3211 case RPC_FC_ALIGNM8:
3212 ALIGN_LENGTH(size, 8);
3214 case RPC_FC_STRUCTPAD1:
3215 case RPC_FC_STRUCTPAD2:
3216 case RPC_FC_STRUCTPAD3:
3217 case RPC_FC_STRUCTPAD4:
3218 case RPC_FC_STRUCTPAD5:
3219 case RPC_FC_STRUCTPAD6:
3220 case RPC_FC_STRUCTPAD7:
3221 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3223 case RPC_FC_EMBEDDED_COMPLEX:
3226 desc = pFormat + *(const SHORT*)pFormat;
3227 size += EmbeddedComplexSize(pStubMsg, desc);
3233 FIXME("unhandled format 0x%02x\n", *pFormat);
3241 /***********************************************************************
3242 * NdrComplexStructMarshall [RPCRT4.@]
3244 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3245 unsigned char *pMemory,
3246 PFORMAT_STRING pFormat)
3248 PFORMAT_STRING conf_array = NULL;
3249 PFORMAT_STRING pointer_desc = NULL;
3250 unsigned char *OldMemory = pStubMsg->Memory;
3251 int pointer_buffer_mark_set = 0;
3253 ULONG max_count = 0;
3256 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3258 if (!pStubMsg->PointerBufferMark)
3260 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3261 /* save buffer length */
3262 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3264 /* get the buffer pointer after complex array data, but before
3266 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3267 pStubMsg->IgnoreEmbeddedPointers = 1;
3268 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3269 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3271 /* save it for use by embedded pointer code later */
3272 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3273 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
3274 pointer_buffer_mark_set = 1;
3276 /* restore the original buffer length */
3277 pStubMsg->BufferLength = saved_buffer_length;
3280 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
3283 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3285 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3288 pStubMsg->Memory = pMemory;
3292 unsigned long struct_size = ComplexStructSize(pStubMsg, pFormat);
3293 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3294 pMemory + struct_size, conf_array);
3295 /* these could be changed in ComplexMarshall so save them for later */
3296 max_count = pStubMsg->MaxCount;
3297 count = pStubMsg->ActualCount;
3298 offset = pStubMsg->Offset;
3301 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3305 pStubMsg->MaxCount = max_count;
3306 pStubMsg->ActualCount = count;
3307 pStubMsg->Offset = offset;
3308 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3309 conf_array, TRUE /* fHasPointers */);
3312 pStubMsg->Memory = OldMemory;
3314 if (pointer_buffer_mark_set)
3316 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3317 pStubMsg->PointerBufferMark = NULL;
3320 STD_OVERFLOW_CHECK(pStubMsg);
3325 /***********************************************************************
3326 * NdrComplexStructUnmarshall [RPCRT4.@]
3328 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3329 unsigned char **ppMemory,
3330 PFORMAT_STRING pFormat,
3331 unsigned char fMustAlloc)
3333 unsigned size = *(const WORD*)(pFormat+2);
3334 PFORMAT_STRING conf_array = NULL;
3335 PFORMAT_STRING pointer_desc = NULL;
3336 unsigned char *pMemory;
3337 int pointer_buffer_mark_set = 0;
3339 ULONG max_count = 0;
3341 ULONG array_size = 0;
3343 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3345 if (!pStubMsg->PointerBufferMark)
3347 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3348 /* save buffer pointer */
3349 unsigned char *saved_buffer = pStubMsg->Buffer;
3351 /* get the buffer pointer after complex array data, but before
3353 pStubMsg->IgnoreEmbeddedPointers = 1;
3354 NdrComplexStructMemorySize(pStubMsg, pFormat);
3355 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3357 /* save it for use by embedded pointer code later */
3358 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3359 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
3360 pointer_buffer_mark_set = 1;
3362 /* restore the original buffer */
3363 pStubMsg->Buffer = saved_buffer;
3366 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3369 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3371 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3376 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3379 /* these could be changed in ComplexMarshall so save them for later */
3380 max_count = pStubMsg->MaxCount;
3381 count = pStubMsg->ActualCount;
3382 offset = pStubMsg->Offset;
3385 if (fMustAlloc || !*ppMemory)
3386 *ppMemory = NdrAllocate(pStubMsg, size);
3388 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3392 pStubMsg->MaxCount = max_count;
3393 pStubMsg->ActualCount = count;
3394 pStubMsg->Offset = offset;
3396 memset(pMemory, 0, array_size);
3397 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3399 FALSE /* fUseBufferMemoryServer */,
3400 TRUE /* fUnmarshall */);
3403 if (pointer_buffer_mark_set)
3405 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3406 pStubMsg->PointerBufferMark = NULL;
3412 /***********************************************************************
3413 * NdrComplexStructBufferSize [RPCRT4.@]
3415 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3416 unsigned char *pMemory,
3417 PFORMAT_STRING pFormat)
3419 PFORMAT_STRING conf_array = NULL;
3420 PFORMAT_STRING pointer_desc = NULL;
3421 unsigned char *OldMemory = pStubMsg->Memory;
3422 int pointer_length_set = 0;
3424 ULONG max_count = 0;
3427 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3429 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
3431 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3433 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3434 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3436 /* get the buffer length after complex struct data, but before
3438 pStubMsg->IgnoreEmbeddedPointers = 1;
3439 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3440 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3442 /* save it for use by embedded pointer code later */
3443 pStubMsg->PointerLength = pStubMsg->BufferLength;
3444 pointer_length_set = 1;
3445 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
3447 /* restore the original buffer length */
3448 pStubMsg->BufferLength = saved_buffer_length;
3452 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3454 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3457 pStubMsg->Memory = pMemory;
3461 unsigned long struct_size = ComplexStructSize(pStubMsg, pFormat);
3462 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3465 /* these could be changed in ComplexMarshall so save them for later */
3466 max_count = pStubMsg->MaxCount;
3467 count = pStubMsg->ActualCount;
3468 offset = pStubMsg->Offset;
3471 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3475 pStubMsg->MaxCount = max_count;
3476 pStubMsg->ActualCount = count;
3477 pStubMsg->Offset = offset;
3478 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3479 TRUE /* fHasPointers */);
3482 pStubMsg->Memory = OldMemory;
3484 if(pointer_length_set)
3486 pStubMsg->BufferLength = pStubMsg->PointerLength;
3487 pStubMsg->PointerLength = 0;
3492 /***********************************************************************
3493 * NdrComplexStructMemorySize [RPCRT4.@]
3495 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3496 PFORMAT_STRING pFormat)
3498 unsigned size = *(const WORD*)(pFormat+2);
3499 PFORMAT_STRING conf_array = NULL;
3500 PFORMAT_STRING pointer_desc = NULL;
3502 ULONG max_count = 0;
3505 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3507 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3510 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3512 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3517 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3519 /* these could be changed in ComplexStructMemorySize so save them for
3521 max_count = pStubMsg->MaxCount;
3522 count = pStubMsg->ActualCount;
3523 offset = pStubMsg->Offset;
3526 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3530 pStubMsg->MaxCount = max_count;
3531 pStubMsg->ActualCount = count;
3532 pStubMsg->Offset = offset;
3533 array_memory_size(conf_array[0], pStubMsg, conf_array,
3534 TRUE /* fHasPointers */);
3540 /***********************************************************************
3541 * NdrComplexStructFree [RPCRT4.@]
3543 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3544 unsigned char *pMemory,
3545 PFORMAT_STRING pFormat)
3547 PFORMAT_STRING conf_array = NULL;
3548 PFORMAT_STRING pointer_desc = NULL;
3549 unsigned char *OldMemory = pStubMsg->Memory;
3551 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3554 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3556 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3559 pStubMsg->Memory = pMemory;
3561 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3564 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3565 TRUE /* fHasPointers */);
3567 pStubMsg->Memory = OldMemory;
3570 /***********************************************************************
3571 * NdrConformantArrayMarshall [RPCRT4.@]
3573 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3574 unsigned char *pMemory,
3575 PFORMAT_STRING pFormat)
3577 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3578 if (pFormat[0] != RPC_FC_CARRAY)
3580 ERR("invalid format = 0x%x\n", pFormat[0]);
3581 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3584 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory,
3586 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3587 TRUE /* fHasPointers */);
3592 /***********************************************************************
3593 * NdrConformantArrayUnmarshall [RPCRT4.@]
3595 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3596 unsigned char **ppMemory,
3597 PFORMAT_STRING pFormat,
3598 unsigned char fMustAlloc)
3600 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3601 if (pFormat[0] != RPC_FC_CARRAY)
3603 ERR("invalid format = 0x%x\n", pFormat[0]);
3604 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3607 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3608 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat,
3610 TRUE /* fUseBufferMemoryServer */,
3611 TRUE /* fUnmarshall */);
3616 /***********************************************************************
3617 * NdrConformantArrayBufferSize [RPCRT4.@]
3619 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3620 unsigned char *pMemory,
3621 PFORMAT_STRING pFormat)
3623 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3624 if (pFormat[0] != RPC_FC_CARRAY)
3626 ERR("invalid format = 0x%x\n", pFormat[0]);
3627 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3630 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat);
3631 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3632 TRUE /* fHasPointers */);
3635 /***********************************************************************
3636 * NdrConformantArrayMemorySize [RPCRT4.@]
3638 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3639 PFORMAT_STRING pFormat)
3641 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3642 if (pFormat[0] != RPC_FC_CARRAY)
3644 ERR("invalid format = 0x%x\n", pFormat[0]);
3645 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3648 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3649 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
3651 return pStubMsg->MemorySize;
3654 /***********************************************************************
3655 * NdrConformantArrayFree [RPCRT4.@]
3657 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3658 unsigned char *pMemory,
3659 PFORMAT_STRING pFormat)
3661 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3662 if (pFormat[0] != RPC_FC_CARRAY)
3664 ERR("invalid format = 0x%x\n", pFormat[0]);
3665 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3668 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3669 TRUE /* fHasPointers */);
3673 /***********************************************************************
3674 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3676 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
3677 unsigned char* pMemory,
3678 PFORMAT_STRING pFormat )
3680 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3682 if (pFormat[0] != RPC_FC_CVARRAY)
3684 ERR("invalid format type %x\n", pFormat[0]);
3685 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3689 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3691 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory,
3692 pFormat, TRUE /* fHasPointers */);
3698 /***********************************************************************
3699 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3701 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
3702 unsigned char** ppMemory,
3703 PFORMAT_STRING pFormat,
3704 unsigned char fMustAlloc )
3706 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3708 if (pFormat[0] != RPC_FC_CVARRAY)
3710 ERR("invalid format type %x\n", pFormat[0]);
3711 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3715 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3716 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory,
3717 pFormat, fMustAlloc,
3718 TRUE /* fUseBufferMemoryServer */,
3719 TRUE /* fUnmarshall */);
3725 /***********************************************************************
3726 * NdrConformantVaryingArrayFree [RPCRT4.@]
3728 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
3729 unsigned char* pMemory,
3730 PFORMAT_STRING pFormat )
3732 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3734 if (pFormat[0] != RPC_FC_CVARRAY)
3736 ERR("invalid format type %x\n", pFormat[0]);
3737 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3741 array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3742 TRUE /* fHasPointers */);
3746 /***********************************************************************
3747 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3749 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
3750 unsigned char* pMemory, PFORMAT_STRING pFormat )
3752 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3754 if (pFormat[0] != RPC_FC_CVARRAY)
3756 ERR("invalid format type %x\n", pFormat[0]);
3757 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3761 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3763 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3764 TRUE /* fHasPointers */);
3768 /***********************************************************************
3769 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3771 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
3772 PFORMAT_STRING pFormat )
3774 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3776 if (pFormat[0] != RPC_FC_CVARRAY)
3778 ERR("invalid format type %x\n", pFormat[0]);
3779 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3780 return pStubMsg->MemorySize;
3783 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3784 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat,
3785 TRUE /* fHasPointers */);
3787 return pStubMsg->MemorySize;
3791 /***********************************************************************
3792 * NdrComplexArrayMarshall [RPCRT4.@]
3794 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3795 unsigned char *pMemory,
3796 PFORMAT_STRING pFormat)
3798 ULONG i, count, def;
3799 BOOL variance_present;
3800 unsigned char alignment;
3801 int pointer_buffer_mark_set = 0;
3803 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3805 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3807 ERR("invalid format type %x\n", pFormat[0]);
3808 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3812 alignment = pFormat[1] + 1;
3814 if (!pStubMsg->PointerBufferMark)
3816 /* save buffer fields that may be changed by buffer sizer functions
3817 * and that may be needed later on */
3818 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3819 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3820 unsigned long saved_max_count = pStubMsg->MaxCount;
3821 unsigned long saved_offset = pStubMsg->Offset;
3822 unsigned long saved_actual_count = pStubMsg->ActualCount;
3824 /* get the buffer pointer after complex array data, but before
3826 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3827 pStubMsg->IgnoreEmbeddedPointers = 1;
3828 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3829 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3831 /* save it for use by embedded pointer code later */
3832 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3833 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
3834 pointer_buffer_mark_set = 1;
3836 /* restore fields */
3837 pStubMsg->ActualCount = saved_actual_count;
3838 pStubMsg->Offset = saved_offset;
3839 pStubMsg->MaxCount = saved_max_count;
3840 pStubMsg->BufferLength = saved_buffer_length;
3843 def = *(const WORD*)&pFormat[2];
3846 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3847 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3849 variance_present = IsConformanceOrVariancePresent(pFormat);
3850 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3851 TRACE("variance = %d\n", pStubMsg->ActualCount);
3853 WriteConformance(pStubMsg);
3854 if (variance_present)
3855 WriteVariance(pStubMsg);
3857 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3859 count = pStubMsg->ActualCount;
3860 for (i = 0; i < count; i++)
3861 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3863 STD_OVERFLOW_CHECK(pStubMsg);
3865 if (pointer_buffer_mark_set)
3867 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3868 pStubMsg->PointerBufferMark = NULL;
3874 /***********************************************************************
3875 * NdrComplexArrayUnmarshall [RPCRT4.@]
3877 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3878 unsigned char **ppMemory,
3879 PFORMAT_STRING pFormat,
3880 unsigned char fMustAlloc)
3882 ULONG i, count, size;
3883 unsigned char alignment;
3884 unsigned char *pMemory;
3885 unsigned char *saved_buffer;
3886 int pointer_buffer_mark_set = 0;
3887 int saved_ignore_embedded;
3889 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3891 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3893 ERR("invalid format type %x\n", pFormat[0]);
3894 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3898 alignment = pFormat[1] + 1;
3900 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3901 /* save buffer pointer */
3902 saved_buffer = pStubMsg->Buffer;
3903 /* get the buffer pointer after complex array data, but before
3905 pStubMsg->IgnoreEmbeddedPointers = 1;
3906 pStubMsg->MemorySize = 0;
3907 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3908 size = pStubMsg->MemorySize;
3909 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3911 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
3912 if (!pStubMsg->PointerBufferMark)
3914 /* save it for use by embedded pointer code later */
3915 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3916 pointer_buffer_mark_set = 1;
3918 /* restore the original buffer */
3919 pStubMsg->Buffer = saved_buffer;
3923 pFormat = ReadConformance(pStubMsg, pFormat);
3924 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3926 if (fMustAlloc || !*ppMemory)
3927 *ppMemory = NdrAllocate(pStubMsg, size);
3929 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3931 pMemory = *ppMemory;
3932 count = pStubMsg->ActualCount;
3933 for (i = 0; i < count; i++)
3934 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
3936 if (pointer_buffer_mark_set)
3938 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3939 pStubMsg->PointerBufferMark = NULL;
3945 /***********************************************************************
3946 * NdrComplexArrayBufferSize [RPCRT4.@]
3948 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3949 unsigned char *pMemory,
3950 PFORMAT_STRING pFormat)
3952 ULONG i, count, def;
3953 unsigned char alignment;
3954 BOOL variance_present;
3955 int pointer_length_set = 0;
3957 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3959 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3961 ERR("invalid format type %x\n", pFormat[0]);
3962 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3966 alignment = pFormat[1] + 1;
3968 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3970 /* save buffer fields that may be changed by buffer sizer functions
3971 * and that may be needed later on */
3972 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3973 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3974 unsigned long saved_max_count = pStubMsg->MaxCount;
3975 unsigned long saved_offset = pStubMsg->Offset;
3976 unsigned long saved_actual_count = pStubMsg->ActualCount;
3978 /* get the buffer pointer after complex array data, but before
3980 pStubMsg->IgnoreEmbeddedPointers = 1;
3981 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3982 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3984 /* save it for use by embedded pointer code later */
3985 pStubMsg->PointerLength = pStubMsg->BufferLength;
3986 pointer_length_set = 1;
3988 /* restore fields */
3989 pStubMsg->ActualCount = saved_actual_count;
3990 pStubMsg->Offset = saved_offset;
3991 pStubMsg->MaxCount = saved_max_count;
3992 pStubMsg->BufferLength = saved_buffer_length;
3994 def = *(const WORD*)&pFormat[2];
3997 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3998 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3999 SizeConformance(pStubMsg);
4001 variance_present = IsConformanceOrVariancePresent(pFormat);
4002 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4003 TRACE("variance = %d\n", pStubMsg->ActualCount);
4005 if (variance_present)
4006 SizeVariance(pStubMsg);
4008 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4010 count = pStubMsg->ActualCount;
4011 for (i = 0; i < count; i++)
4012 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
4014 if(pointer_length_set)
4016 pStubMsg->BufferLength = pStubMsg->PointerLength;
4017 pStubMsg->PointerLength = 0;
4021 /***********************************************************************
4022 * NdrComplexArrayMemorySize [RPCRT4.@]
4024 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4025 PFORMAT_STRING pFormat)
4027 ULONG i, count, esize, SavedMemorySize, MemorySize;
4028 unsigned char alignment;
4030 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4032 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4034 ERR("invalid format type %x\n", pFormat[0]);
4035 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4039 alignment = pFormat[1] + 1;
4043 pFormat = ReadConformance(pStubMsg, pFormat);
4044 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
4046 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4048 SavedMemorySize = pStubMsg->MemorySize;
4050 esize = ComplexStructSize(pStubMsg, pFormat);
4052 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
4054 count = pStubMsg->ActualCount;
4055 for (i = 0; i < count; i++)
4056 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
4058 pStubMsg->MemorySize = SavedMemorySize;
4060 pStubMsg->MemorySize += MemorySize;
4064 /***********************************************************************
4065 * NdrComplexArrayFree [RPCRT4.@]
4067 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4068 unsigned char *pMemory,
4069 PFORMAT_STRING pFormat)
4071 ULONG i, count, def;
4073 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4075 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4077 ERR("invalid format type %x\n", pFormat[0]);
4078 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4082 def = *(const WORD*)&pFormat[2];
4085 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4086 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4088 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4089 TRACE("variance = %d\n", pStubMsg->ActualCount);
4091 count = pStubMsg->ActualCount;
4092 for (i = 0; i < count; i++)
4093 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4096 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4097 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4098 USER_MARSHAL_CB *umcb)
4100 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4101 pStubMsg->RpcMsg->DataRepresentation);
4102 umcb->pStubMsg = pStubMsg;
4103 umcb->pReserve = NULL;
4104 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4105 umcb->CBType = cbtype;
4106 umcb->pFormat = pFormat;
4107 umcb->pTypeFormat = NULL /* FIXME */;
4110 #define USER_MARSHAL_PTR_PREFIX \
4111 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4112 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4114 /***********************************************************************
4115 * NdrUserMarshalMarshall [RPCRT4.@]
4117 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4118 unsigned char *pMemory,
4119 PFORMAT_STRING pFormat)
4121 unsigned flags = pFormat[1];
4122 unsigned index = *(const WORD*)&pFormat[2];
4123 unsigned char *saved_buffer = NULL;
4124 USER_MARSHAL_CB umcb;
4126 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4127 TRACE("index=%d\n", index);
4129 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4131 if (flags & USER_MARSHAL_POINTER)
4133 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
4134 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4135 pStubMsg->Buffer += 4;
4136 if (pStubMsg->PointerBufferMark)
4138 saved_buffer = pStubMsg->Buffer;
4139 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4140 pStubMsg->PointerBufferMark = NULL;
4142 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
4145 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
4148 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4149 &umcb.Flags, pStubMsg->Buffer, pMemory);
4153 STD_OVERFLOW_CHECK(pStubMsg);
4154 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4155 pStubMsg->Buffer = saved_buffer;
4158 STD_OVERFLOW_CHECK(pStubMsg);
4163 /***********************************************************************
4164 * NdrUserMarshalUnmarshall [RPCRT4.@]
4166 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4167 unsigned char **ppMemory,
4168 PFORMAT_STRING pFormat,
4169 unsigned char fMustAlloc)
4171 unsigned flags = pFormat[1];
4172 unsigned index = *(const WORD*)&pFormat[2];
4173 DWORD memsize = *(const WORD*)&pFormat[4];
4174 unsigned char *saved_buffer = NULL;
4175 USER_MARSHAL_CB umcb;
4177 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4178 TRACE("index=%d\n", index);
4180 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4182 if (flags & USER_MARSHAL_POINTER)
4184 ALIGN_POINTER(pStubMsg->Buffer, 4);
4185 /* skip pointer prefix */
4186 pStubMsg->Buffer += 4;
4187 if (pStubMsg->PointerBufferMark)
4189 saved_buffer = pStubMsg->Buffer;
4190 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4191 pStubMsg->PointerBufferMark = NULL;
4193 ALIGN_POINTER(pStubMsg->Buffer, 8);
4196 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4198 if (fMustAlloc || !*ppMemory)
4199 *ppMemory = NdrAllocate(pStubMsg, memsize);
4202 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4203 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4207 STD_OVERFLOW_CHECK(pStubMsg);
4208 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4209 pStubMsg->Buffer = saved_buffer;
4215 /***********************************************************************
4216 * NdrUserMarshalBufferSize [RPCRT4.@]
4218 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4219 unsigned char *pMemory,
4220 PFORMAT_STRING pFormat)
4222 unsigned flags = pFormat[1];
4223 unsigned index = *(const WORD*)&pFormat[2];
4224 DWORD bufsize = *(const WORD*)&pFormat[6];
4225 USER_MARSHAL_CB umcb;
4226 unsigned long saved_buffer_length = 0;
4228 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4229 TRACE("index=%d\n", index);
4231 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4233 if (flags & USER_MARSHAL_POINTER)
4235 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4236 /* skip pointer prefix */
4237 safe_buffer_length_increment(pStubMsg, 4);
4238 if (pStubMsg->IgnoreEmbeddedPointers)
4240 if (pStubMsg->PointerLength)
4242 saved_buffer_length = pStubMsg->BufferLength;
4243 pStubMsg->BufferLength = pStubMsg->PointerLength;
4244 pStubMsg->PointerLength = 0;
4246 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
4249 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
4252 TRACE("size=%d\n", bufsize);
4253 safe_buffer_length_increment(pStubMsg, bufsize);
4256 pStubMsg->BufferLength =
4257 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4258 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4260 if (saved_buffer_length)
4262 pStubMsg->PointerLength = pStubMsg->BufferLength;
4263 pStubMsg->BufferLength = saved_buffer_length;
4268 /***********************************************************************
4269 * NdrUserMarshalMemorySize [RPCRT4.@]
4271 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4272 PFORMAT_STRING pFormat)
4274 unsigned flags = pFormat[1];
4275 unsigned index = *(const WORD*)&pFormat[2];
4276 DWORD memsize = *(const WORD*)&pFormat[4];
4277 DWORD bufsize = *(const WORD*)&pFormat[6];
4279 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4280 TRACE("index=%d\n", index);
4282 pStubMsg->MemorySize += memsize;
4284 if (flags & USER_MARSHAL_POINTER)
4286 ALIGN_POINTER(pStubMsg->Buffer, 4);
4287 /* skip pointer prefix */
4288 pStubMsg->Buffer += 4;
4289 if (pStubMsg->IgnoreEmbeddedPointers)
4290 return pStubMsg->MemorySize;
4291 ALIGN_POINTER(pStubMsg->Buffer, 8);
4294 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4297 FIXME("not implemented for varying buffer size\n");
4299 pStubMsg->Buffer += bufsize;
4301 return pStubMsg->MemorySize;
4304 /***********************************************************************
4305 * NdrUserMarshalFree [RPCRT4.@]
4307 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4308 unsigned char *pMemory,
4309 PFORMAT_STRING pFormat)
4311 /* unsigned flags = pFormat[1]; */
4312 unsigned index = *(const WORD*)&pFormat[2];
4313 USER_MARSHAL_CB umcb;
4315 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4316 TRACE("index=%d\n", index);
4318 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4320 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4321 &umcb.Flags, pMemory);
4324 /***********************************************************************
4325 * NdrClearOutParameters [RPCRT4.@]
4327 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4328 PFORMAT_STRING pFormat,
4331 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4334 /***********************************************************************
4335 * NdrConvert [RPCRT4.@]
4337 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4339 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4340 /* FIXME: since this stub doesn't do any converting, the proper behavior
4341 is to raise an exception */
4344 /***********************************************************************
4345 * NdrConvert2 [RPCRT4.@]
4347 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4349 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4350 pStubMsg, pFormat, NumberParams);
4351 /* FIXME: since this stub doesn't do any converting, the proper behavior
4352 is to raise an exception */
4355 #include "pshpack1.h"
4356 typedef struct _NDR_CSTRUCT_FORMAT
4359 unsigned char alignment;
4360 unsigned short memory_size;
4361 short offset_to_array_description;
4362 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4363 #include "poppack.h"
4365 /***********************************************************************
4366 * NdrConformantStructMarshall [RPCRT4.@]
4368 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4369 unsigned char *pMemory,
4370 PFORMAT_STRING pFormat)
4372 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4373 PFORMAT_STRING pCArrayFormat;
4374 ULONG esize, bufsize;
4376 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4378 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4379 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4381 ERR("invalid format type %x\n", pCStructFormat->type);
4382 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4386 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4387 pCStructFormat->offset_to_array_description;
4388 if (*pCArrayFormat != RPC_FC_CARRAY)
4390 ERR("invalid array format type %x\n", pCStructFormat->type);
4391 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4394 esize = *(const WORD*)(pCArrayFormat+2);
4396 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4397 pCArrayFormat + 4, 0);
4399 WriteConformance(pStubMsg);
4401 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4403 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4405 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4406 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4408 ERR("integer overflow of memory_size %u with bufsize %u\n",
4409 pCStructFormat->memory_size, bufsize);
4410 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4412 /* copy constant sized part of struct */
4413 pStubMsg->BufferMark = pStubMsg->Buffer;
4414 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4416 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4417 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4422 /***********************************************************************
4423 * NdrConformantStructUnmarshall [RPCRT4.@]
4425 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4426 unsigned char **ppMemory,
4427 PFORMAT_STRING pFormat,
4428 unsigned char fMustAlloc)
4430 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4431 PFORMAT_STRING pCArrayFormat;
4432 ULONG esize, bufsize;
4433 unsigned char *saved_buffer;
4435 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4437 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4438 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4440 ERR("invalid format type %x\n", pCStructFormat->type);
4441 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4444 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4445 pCStructFormat->offset_to_array_description;
4446 if (*pCArrayFormat != RPC_FC_CARRAY)
4448 ERR("invalid array format type %x\n", pCStructFormat->type);
4449 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4452 esize = *(const WORD*)(pCArrayFormat+2);
4454 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4456 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4458 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4460 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4461 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4463 ERR("integer overflow of memory_size %u with bufsize %u\n",
4464 pCStructFormat->memory_size, bufsize);
4465 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4470 SIZE_T size = pCStructFormat->memory_size + bufsize;
4471 *ppMemory = NdrAllocate(pStubMsg, size);
4475 if (!pStubMsg->IsClient && !*ppMemory)
4476 /* for servers, we just point straight into the RPC buffer */
4477 *ppMemory = pStubMsg->Buffer;
4480 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4481 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4482 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4483 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4485 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4486 if (*ppMemory != saved_buffer)
4487 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4492 /***********************************************************************
4493 * NdrConformantStructBufferSize [RPCRT4.@]
4495 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4496 unsigned char *pMemory,
4497 PFORMAT_STRING pFormat)
4499 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4500 PFORMAT_STRING pCArrayFormat;
4503 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4505 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4506 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4508 ERR("invalid format type %x\n", pCStructFormat->type);
4509 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4512 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4513 pCStructFormat->offset_to_array_description;
4514 if (*pCArrayFormat != RPC_FC_CARRAY)
4516 ERR("invalid array format type %x\n", pCStructFormat->type);
4517 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4520 esize = *(const WORD*)(pCArrayFormat+2);
4522 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4523 SizeConformance(pStubMsg);
4525 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4527 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4529 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4530 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4532 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4533 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4536 /***********************************************************************
4537 * NdrConformantStructMemorySize [RPCRT4.@]
4539 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4540 PFORMAT_STRING pFormat)
4546 /***********************************************************************
4547 * NdrConformantStructFree [RPCRT4.@]
4549 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4550 unsigned char *pMemory,
4551 PFORMAT_STRING pFormat)
4553 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4554 PFORMAT_STRING pCArrayFormat;
4556 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4558 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4559 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4561 ERR("invalid format type %x\n", pCStructFormat->type);
4562 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4566 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4567 pCStructFormat->offset_to_array_description;
4568 if (*pCArrayFormat != RPC_FC_CARRAY)
4570 ERR("invalid array format type %x\n", pCStructFormat->type);
4571 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4575 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4576 pCArrayFormat + 4, 0);
4578 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4580 /* copy constant sized part of struct */
4581 pStubMsg->BufferMark = pStubMsg->Buffer;
4583 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4584 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4587 /***********************************************************************
4588 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4590 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4591 unsigned char *pMemory,
4592 PFORMAT_STRING pFormat)
4594 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4595 PFORMAT_STRING pCVArrayFormat;
4597 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4599 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4600 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4602 ERR("invalid format type %x\n", pCVStructFormat->type);
4603 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4607 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4608 pCVStructFormat->offset_to_array_description;
4610 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4611 pMemory + pCVStructFormat->memory_size,
4614 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4616 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4618 /* write constant sized part */
4619 pStubMsg->BufferMark = pStubMsg->Buffer;
4620 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4622 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4623 pMemory + pCVStructFormat->memory_size,
4624 pCVArrayFormat, FALSE /* fHasPointers */);
4626 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4631 /***********************************************************************
4632 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4634 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4635 unsigned char **ppMemory,
4636 PFORMAT_STRING pFormat,
4637 unsigned char fMustAlloc)
4639 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4640 PFORMAT_STRING pCVArrayFormat;
4641 ULONG memsize, bufsize;
4642 unsigned char *saved_buffer, *saved_array_buffer;
4644 unsigned char *array_memory;
4646 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4648 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4649 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4651 ERR("invalid format type %x\n", pCVStructFormat->type);
4652 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4656 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4657 pCVStructFormat->offset_to_array_description;
4659 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4662 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4664 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4666 /* work out how much memory to allocate if we need to do so */
4667 if (!*ppMemory || fMustAlloc)
4669 SIZE_T size = pCVStructFormat->memory_size + memsize;
4670 *ppMemory = NdrAllocate(pStubMsg, size);
4673 /* mark the start of the constant data */
4674 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4675 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4677 array_memory = *ppMemory + pCVStructFormat->memory_size;
4678 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
4679 &array_memory, pCVArrayFormat,
4680 FALSE /* fMustAlloc */,
4681 FALSE /* fUseServerBufferMemory */,
4682 FALSE /* fUnmarshall */);
4684 /* save offset in case unmarshalling pointers changes it */
4685 offset = pStubMsg->Offset;
4687 /* mark the start of the array data */
4688 saved_array_buffer = pStubMsg->Buffer;
4689 safe_buffer_increment(pStubMsg, bufsize);
4691 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4693 /* copy the constant data */
4694 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
4695 /* copy the array data */
4696 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
4697 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
4698 saved_array_buffer, bufsize);
4700 if (*pCVArrayFormat == RPC_FC_C_CSTRING)
4701 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
4702 else if (*pCVArrayFormat == RPC_FC_C_WSTRING)
4703 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
4708 /***********************************************************************
4709 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4711 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4712 unsigned char *pMemory,
4713 PFORMAT_STRING pFormat)
4715 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4716 PFORMAT_STRING pCVArrayFormat;
4718 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4720 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4721 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4723 ERR("invalid format type %x\n", pCVStructFormat->type);
4724 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4728 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4729 pCVStructFormat->offset_to_array_description;
4730 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
4731 pMemory + pCVStructFormat->memory_size,
4734 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4736 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4738 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4740 array_buffer_size(*pCVArrayFormat, pStubMsg,
4741 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4742 FALSE /* fHasPointers */);
4744 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4747 /***********************************************************************
4748 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4750 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4751 PFORMAT_STRING pFormat)
4753 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4754 PFORMAT_STRING pCVArrayFormat;
4756 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4758 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4759 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4761 ERR("invalid format type %x\n", pCVStructFormat->type);
4762 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4766 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4767 pCVStructFormat->offset_to_array_description;
4768 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
4770 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4772 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4774 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4775 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
4776 FALSE /* fHasPointers */);
4778 pStubMsg->MemorySize += pCVStructFormat->memory_size;
4780 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4782 return pStubMsg->MemorySize;
4785 /***********************************************************************
4786 * NdrConformantVaryingStructFree [RPCRT4.@]
4788 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4789 unsigned char *pMemory,
4790 PFORMAT_STRING pFormat)
4792 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4793 PFORMAT_STRING pCVArrayFormat;
4795 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4797 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4798 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4800 ERR("invalid format type %x\n", pCVStructFormat->type);
4801 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4805 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4806 pCVStructFormat->offset_to_array_description;
4807 array_free(*pCVArrayFormat, pStubMsg,
4808 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4809 FALSE /* fHasPointers */);
4811 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4813 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4816 #include "pshpack1.h"
4820 unsigned char alignment;
4821 unsigned short total_size;
4822 } NDR_SMFARRAY_FORMAT;
4827 unsigned char alignment;
4828 unsigned long total_size;
4829 } NDR_LGFARRAY_FORMAT;
4830 #include "poppack.h"
4832 /***********************************************************************
4833 * NdrFixedArrayMarshall [RPCRT4.@]
4835 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4836 unsigned char *pMemory,
4837 PFORMAT_STRING pFormat)
4839 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4840 unsigned long total_size;
4842 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4844 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4845 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4847 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4848 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4852 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4854 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4856 total_size = pSmFArrayFormat->total_size;
4857 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4861 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4862 total_size = pLgFArrayFormat->total_size;
4863 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4866 pStubMsg->BufferMark = pStubMsg->Buffer;
4867 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4869 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4874 /***********************************************************************
4875 * NdrFixedArrayUnmarshall [RPCRT4.@]
4877 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4878 unsigned char **ppMemory,
4879 PFORMAT_STRING pFormat,
4880 unsigned char fMustAlloc)
4882 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4883 unsigned long total_size;
4884 unsigned char *saved_buffer;
4886 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4888 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4889 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4891 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4892 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4896 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4898 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4900 total_size = pSmFArrayFormat->total_size;
4901 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4905 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4906 total_size = pLgFArrayFormat->total_size;
4907 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4911 *ppMemory = NdrAllocate(pStubMsg, total_size);
4914 if (!pStubMsg->IsClient && !*ppMemory)
4915 /* for servers, we just point straight into the RPC buffer */
4916 *ppMemory = pStubMsg->Buffer;
4919 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4920 safe_buffer_increment(pStubMsg, total_size);
4921 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4923 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4924 if (*ppMemory != saved_buffer)
4925 memcpy(*ppMemory, saved_buffer, total_size);
4930 /***********************************************************************
4931 * NdrFixedArrayBufferSize [RPCRT4.@]
4933 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4934 unsigned char *pMemory,
4935 PFORMAT_STRING pFormat)
4937 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4938 unsigned long total_size;
4940 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4942 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4943 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4945 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4946 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4950 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4952 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4954 total_size = pSmFArrayFormat->total_size;
4955 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4959 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4960 total_size = pLgFArrayFormat->total_size;
4961 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4963 safe_buffer_length_increment(pStubMsg, total_size);
4965 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4968 /***********************************************************************
4969 * NdrFixedArrayMemorySize [RPCRT4.@]
4971 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4972 PFORMAT_STRING pFormat)
4974 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4977 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4979 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4980 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4982 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4983 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4987 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4989 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4991 total_size = pSmFArrayFormat->total_size;
4992 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4996 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4997 total_size = pLgFArrayFormat->total_size;
4998 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5000 pStubMsg->BufferMark = pStubMsg->Buffer;
5001 safe_buffer_increment(pStubMsg, total_size);
5002 pStubMsg->MemorySize += total_size;
5004 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5009 /***********************************************************************
5010 * NdrFixedArrayFree [RPCRT4.@]
5012 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5013 unsigned char *pMemory,
5014 PFORMAT_STRING pFormat)
5016 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5018 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5020 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5021 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5023 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5024 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5028 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5029 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5032 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5033 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5036 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5039 /***********************************************************************
5040 * NdrVaryingArrayMarshall [RPCRT4.@]
5042 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5043 unsigned char *pMemory,
5044 PFORMAT_STRING pFormat)
5046 unsigned char alignment;
5047 DWORD elements, esize;
5050 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5052 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5053 (pFormat[0] != RPC_FC_LGVARRAY))
5055 ERR("invalid format type %x\n", pFormat[0]);
5056 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5060 alignment = pFormat[1] + 1;
5062 if (pFormat[0] == RPC_FC_SMVARRAY)
5065 pFormat += sizeof(WORD);
5066 elements = *(const WORD*)pFormat;
5067 pFormat += sizeof(WORD);
5072 pFormat += sizeof(DWORD);
5073 elements = *(const DWORD*)pFormat;
5074 pFormat += sizeof(DWORD);
5077 esize = *(const WORD*)pFormat;
5078 pFormat += sizeof(WORD);
5080 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5081 if ((pStubMsg->ActualCount > elements) ||
5082 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5084 RpcRaiseException(RPC_S_INVALID_BOUND);
5088 WriteVariance(pStubMsg);
5090 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
5092 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5093 pStubMsg->BufferMark = pStubMsg->Buffer;
5094 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5096 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5101 /***********************************************************************
5102 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5104 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5105 unsigned char **ppMemory,
5106 PFORMAT_STRING pFormat,
5107 unsigned char fMustAlloc)
5109 unsigned char alignment;
5110 DWORD size, elements, esize;
5112 unsigned char *saved_buffer;
5115 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5117 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5118 (pFormat[0] != RPC_FC_LGVARRAY))
5120 ERR("invalid format type %x\n", pFormat[0]);
5121 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5125 alignment = pFormat[1] + 1;
5127 if (pFormat[0] == RPC_FC_SMVARRAY)
5130 size = *(const WORD*)pFormat;
5131 pFormat += sizeof(WORD);
5132 elements = *(const WORD*)pFormat;
5133 pFormat += sizeof(WORD);
5138 size = *(const DWORD*)pFormat;
5139 pFormat += sizeof(DWORD);
5140 elements = *(const DWORD*)pFormat;
5141 pFormat += sizeof(DWORD);
5144 esize = *(const WORD*)pFormat;
5145 pFormat += sizeof(WORD);
5147 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5149 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5151 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5152 offset = pStubMsg->Offset;
5154 if (!*ppMemory || fMustAlloc)
5155 *ppMemory = NdrAllocate(pStubMsg, size);
5156 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5157 safe_buffer_increment(pStubMsg, bufsize);
5159 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5161 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5166 /***********************************************************************
5167 * NdrVaryingArrayBufferSize [RPCRT4.@]
5169 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5170 unsigned char *pMemory,
5171 PFORMAT_STRING pFormat)
5173 unsigned char alignment;
5174 DWORD elements, esize;
5176 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5178 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5179 (pFormat[0] != RPC_FC_LGVARRAY))
5181 ERR("invalid format type %x\n", pFormat[0]);
5182 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5186 alignment = pFormat[1] + 1;
5188 if (pFormat[0] == RPC_FC_SMVARRAY)
5191 pFormat += sizeof(WORD);
5192 elements = *(const WORD*)pFormat;
5193 pFormat += sizeof(WORD);
5198 pFormat += sizeof(DWORD);
5199 elements = *(const DWORD*)pFormat;
5200 pFormat += sizeof(DWORD);
5203 esize = *(const WORD*)pFormat;
5204 pFormat += sizeof(WORD);
5206 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5207 if ((pStubMsg->ActualCount > elements) ||
5208 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5210 RpcRaiseException(RPC_S_INVALID_BOUND);
5214 SizeVariance(pStubMsg);
5216 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
5218 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5220 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5223 /***********************************************************************
5224 * NdrVaryingArrayMemorySize [RPCRT4.@]
5226 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5227 PFORMAT_STRING pFormat)
5229 unsigned char alignment;
5230 DWORD size, elements, esize;
5232 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5234 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5235 (pFormat[0] != RPC_FC_LGVARRAY))
5237 ERR("invalid format type %x\n", pFormat[0]);
5238 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5242 alignment = pFormat[1] + 1;
5244 if (pFormat[0] == RPC_FC_SMVARRAY)
5247 size = *(const WORD*)pFormat;
5248 pFormat += sizeof(WORD);
5249 elements = *(const WORD*)pFormat;
5250 pFormat += sizeof(WORD);
5255 size = *(const DWORD*)pFormat;
5256 pFormat += sizeof(DWORD);
5257 elements = *(const DWORD*)pFormat;
5258 pFormat += sizeof(DWORD);
5261 esize = *(const WORD*)pFormat;
5262 pFormat += sizeof(WORD);
5264 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5266 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5268 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5269 pStubMsg->MemorySize += size;
5271 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5273 return pStubMsg->MemorySize;
5276 /***********************************************************************
5277 * NdrVaryingArrayFree [RPCRT4.@]
5279 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5280 unsigned char *pMemory,
5281 PFORMAT_STRING pFormat)
5285 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5287 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5288 (pFormat[0] != RPC_FC_LGVARRAY))
5290 ERR("invalid format type %x\n", pFormat[0]);
5291 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5295 if (pFormat[0] == RPC_FC_SMVARRAY)
5298 pFormat += sizeof(WORD);
5299 elements = *(const WORD*)pFormat;
5300 pFormat += sizeof(WORD);
5305 pFormat += sizeof(DWORD);
5306 elements = *(const DWORD*)pFormat;
5307 pFormat += sizeof(DWORD);
5310 pFormat += sizeof(WORD);
5312 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5313 if ((pStubMsg->ActualCount > elements) ||
5314 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5316 RpcRaiseException(RPC_S_INVALID_BOUND);
5320 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5323 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5336 return *(const USHORT *)pMemory;
5340 return *(const ULONG *)pMemory;
5342 FIXME("Unhandled base type: 0x%02x\n", fc);
5347 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5348 unsigned long discriminant,
5349 PFORMAT_STRING pFormat)
5351 unsigned short num_arms, arm, type;
5353 num_arms = *(const SHORT*)pFormat & 0x0fff;
5355 for(arm = 0; arm < num_arms; arm++)
5357 if(discriminant == *(const ULONG*)pFormat)
5365 type = *(const unsigned short*)pFormat;
5366 TRACE("type %04x\n", type);
5367 if(arm == num_arms) /* default arm extras */
5371 ERR("no arm for 0x%lx and no default case\n", discriminant);
5372 RpcRaiseException(RPC_S_INVALID_TAG);
5377 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
5384 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5386 unsigned short type;
5390 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5394 type = *(const unsigned short*)pFormat;
5395 if((type & 0xff00) == 0x8000)
5397 unsigned char basetype = LOBYTE(type);
5398 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5402 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5403 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5406 unsigned char *saved_buffer = NULL;
5407 int pointer_buffer_mark_set = 0;
5414 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5415 saved_buffer = pStubMsg->Buffer;
5416 if (pStubMsg->PointerBufferMark)
5418 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5419 pStubMsg->PointerBufferMark = NULL;
5420 pointer_buffer_mark_set = 1;
5423 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5425 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5426 if (pointer_buffer_mark_set)
5428 STD_OVERFLOW_CHECK(pStubMsg);
5429 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5430 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5432 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5433 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5434 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5436 pStubMsg->Buffer = saved_buffer + 4;
5440 m(pStubMsg, pMemory, desc);
5443 else FIXME("no marshaller for embedded type %02x\n", *desc);
5448 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5449 unsigned char **ppMemory,
5451 PFORMAT_STRING pFormat,
5452 unsigned char fMustAlloc)
5454 unsigned short type;
5458 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5462 type = *(const unsigned short*)pFormat;
5463 if((type & 0xff00) == 0x8000)
5465 unsigned char basetype = LOBYTE(type);
5466 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5470 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5471 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5474 unsigned char *saved_buffer = NULL;
5475 int pointer_buffer_mark_set = 0;
5482 **(void***)ppMemory = NULL;
5483 ALIGN_POINTER(pStubMsg->Buffer, 4);
5484 saved_buffer = pStubMsg->Buffer;
5485 if (pStubMsg->PointerBufferMark)
5487 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5488 pStubMsg->PointerBufferMark = NULL;
5489 pointer_buffer_mark_set = 1;
5492 pStubMsg->Buffer += 4; /* for pointer ID */
5494 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5496 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5497 saved_buffer, pStubMsg->BufferEnd);
5498 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5501 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5502 if (pointer_buffer_mark_set)
5504 STD_OVERFLOW_CHECK(pStubMsg);
5505 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5506 pStubMsg->Buffer = saved_buffer + 4;
5510 m(pStubMsg, ppMemory, desc, fMustAlloc);
5513 else FIXME("no marshaller for embedded type %02x\n", *desc);
5518 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5519 unsigned char *pMemory,
5521 PFORMAT_STRING pFormat)
5523 unsigned short type;
5527 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5531 type = *(const unsigned short*)pFormat;
5532 if((type & 0xff00) == 0x8000)
5534 unsigned char basetype = LOBYTE(type);
5535 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5539 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5540 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5549 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5550 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5551 if (!pStubMsg->IgnoreEmbeddedPointers)
5553 int saved_buffer_length = pStubMsg->BufferLength;
5554 pStubMsg->BufferLength = pStubMsg->PointerLength;
5555 pStubMsg->PointerLength = 0;
5556 if(!pStubMsg->BufferLength)
5557 ERR("BufferLength == 0??\n");
5558 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5559 pStubMsg->PointerLength = pStubMsg->BufferLength;
5560 pStubMsg->BufferLength = saved_buffer_length;
5564 m(pStubMsg, pMemory, desc);
5567 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5571 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5573 PFORMAT_STRING pFormat)
5575 unsigned short type, size;
5577 size = *(const unsigned short*)pFormat;
5578 pStubMsg->Memory += size;
5581 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5585 type = *(const unsigned short*)pFormat;
5586 if((type & 0xff00) == 0x8000)
5588 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5592 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5593 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5594 unsigned char *saved_buffer;
5603 ALIGN_POINTER(pStubMsg->Buffer, 4);
5604 saved_buffer = pStubMsg->Buffer;
5605 safe_buffer_increment(pStubMsg, 4);
5606 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
5607 pStubMsg->MemorySize += 4;
5608 if (!pStubMsg->IgnoreEmbeddedPointers)
5609 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5612 return m(pStubMsg, desc);
5615 else FIXME("no marshaller for embedded type %02x\n", *desc);
5618 TRACE("size %d\n", size);
5622 static void union_arm_free(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 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5639 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5648 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5651 m(pStubMsg, pMemory, desc);
5657 /***********************************************************************
5658 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5660 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5661 unsigned char *pMemory,
5662 PFORMAT_STRING pFormat)
5664 unsigned char switch_type;
5665 unsigned char increment;
5668 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5671 switch_type = *pFormat & 0xf;
5672 increment = (*pFormat & 0xf0) >> 4;
5675 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5677 switch_value = get_discriminant(switch_type, pMemory);
5678 TRACE("got switch value 0x%x\n", switch_value);
5680 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5681 pMemory += increment;
5683 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5686 /***********************************************************************
5687 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5689 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5690 unsigned char **ppMemory,
5691 PFORMAT_STRING pFormat,
5692 unsigned char fMustAlloc)
5694 unsigned char switch_type;
5695 unsigned char increment;
5697 unsigned short size;
5698 unsigned char *pMemoryArm;
5700 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5703 switch_type = *pFormat & 0xf;
5704 increment = (*pFormat & 0xf0) >> 4;
5707 ALIGN_POINTER(pStubMsg->Buffer, increment);
5708 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5709 TRACE("got switch value 0x%x\n", switch_value);
5711 size = *(const unsigned short*)pFormat + increment;
5712 if(!*ppMemory || fMustAlloc)
5713 *ppMemory = NdrAllocate(pStubMsg, size);
5715 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5716 pMemoryArm = *ppMemory + increment;
5718 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
5721 /***********************************************************************
5722 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5724 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5725 unsigned char *pMemory,
5726 PFORMAT_STRING pFormat)
5728 unsigned char switch_type;
5729 unsigned char increment;
5732 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5735 switch_type = *pFormat & 0xf;
5736 increment = (*pFormat & 0xf0) >> 4;
5739 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5740 switch_value = get_discriminant(switch_type, pMemory);
5741 TRACE("got switch value 0x%x\n", switch_value);
5743 /* Add discriminant size */
5744 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5745 pMemory += increment;
5747 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5750 /***********************************************************************
5751 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5753 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5754 PFORMAT_STRING pFormat)
5756 unsigned char switch_type;
5757 unsigned char increment;
5760 switch_type = *pFormat & 0xf;
5761 increment = (*pFormat & 0xf0) >> 4;
5764 ALIGN_POINTER(pStubMsg->Buffer, increment);
5765 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5766 TRACE("got switch value 0x%x\n", switch_value);
5768 pStubMsg->Memory += increment;
5770 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5773 /***********************************************************************
5774 * NdrEncapsulatedUnionFree [RPCRT4.@]
5776 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5777 unsigned char *pMemory,
5778 PFORMAT_STRING pFormat)
5780 unsigned char switch_type;
5781 unsigned char increment;
5784 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5787 switch_type = *pFormat & 0xf;
5788 increment = (*pFormat & 0xf0) >> 4;
5791 switch_value = get_discriminant(switch_type, pMemory);
5792 TRACE("got switch value 0x%x\n", switch_value);
5794 pMemory += increment;
5796 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5799 /***********************************************************************
5800 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5802 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5803 unsigned char *pMemory,
5804 PFORMAT_STRING pFormat)
5806 unsigned char switch_type;
5808 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5811 switch_type = *pFormat;
5814 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5815 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5816 /* Marshall discriminant */
5817 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5819 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5822 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5823 PFORMAT_STRING *ppFormat)
5825 long discriminant = 0;
5835 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5844 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5845 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5853 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5854 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5859 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5863 if (pStubMsg->fHasNewCorrDesc)
5867 return discriminant;
5870 /**********************************************************************
5871 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5873 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5874 unsigned char **ppMemory,
5875 PFORMAT_STRING pFormat,
5876 unsigned char fMustAlloc)
5879 unsigned short size;
5881 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5884 /* Unmarshall discriminant */
5885 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5886 TRACE("unmarshalled discriminant %lx\n", discriminant);
5888 pFormat += *(const SHORT*)pFormat;
5890 size = *(const unsigned short*)pFormat;
5892 if(!*ppMemory || fMustAlloc)
5893 *ppMemory = NdrAllocate(pStubMsg, size);
5895 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5898 /***********************************************************************
5899 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5901 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5902 unsigned char *pMemory,
5903 PFORMAT_STRING pFormat)
5905 unsigned char switch_type;
5907 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5910 switch_type = *pFormat;
5913 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5914 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5915 /* Add discriminant size */
5916 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5918 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5921 /***********************************************************************
5922 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5924 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5925 PFORMAT_STRING pFormat)
5930 /* Unmarshall discriminant */
5931 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5932 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
5934 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
5937 /***********************************************************************
5938 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5940 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5941 unsigned char *pMemory,
5942 PFORMAT_STRING pFormat)
5944 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5948 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5949 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5951 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5954 /***********************************************************************
5955 * NdrByteCountPointerMarshall [RPCRT4.@]
5957 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5958 unsigned char *pMemory,
5959 PFORMAT_STRING pFormat)
5965 /***********************************************************************
5966 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5968 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5969 unsigned char **ppMemory,
5970 PFORMAT_STRING pFormat,
5971 unsigned char fMustAlloc)
5977 /***********************************************************************
5978 * NdrByteCountPointerBufferSize [RPCRT4.@]
5980 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5981 unsigned char *pMemory,
5982 PFORMAT_STRING pFormat)
5987 /***********************************************************************
5988 * NdrByteCountPointerMemorySize [RPCRT4.@]
5990 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5991 PFORMAT_STRING pFormat)
5997 /***********************************************************************
5998 * NdrByteCountPointerFree [RPCRT4.@]
6000 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6001 unsigned char *pMemory,
6002 PFORMAT_STRING pFormat)
6007 /***********************************************************************
6008 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6010 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6011 unsigned char *pMemory,
6012 PFORMAT_STRING pFormat)
6018 /***********************************************************************
6019 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6021 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6022 unsigned char **ppMemory,
6023 PFORMAT_STRING pFormat,
6024 unsigned char fMustAlloc)
6030 /***********************************************************************
6031 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6033 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6034 unsigned char *pMemory,
6035 PFORMAT_STRING pFormat)
6040 /***********************************************************************
6041 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6043 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6044 PFORMAT_STRING pFormat)
6050 /***********************************************************************
6051 * NdrXmitOrRepAsFree [RPCRT4.@]
6053 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6054 unsigned char *pMemory,
6055 PFORMAT_STRING pFormat)
6060 /***********************************************************************
6061 * NdrRangeMarshall [internal]
6063 unsigned char *WINAPI NdrRangeMarshall(
6064 PMIDL_STUB_MESSAGE pStubMsg,
6065 unsigned char *pMemory,
6066 PFORMAT_STRING pFormat)
6068 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6069 unsigned char base_type;
6071 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6073 if (pRange->type != RPC_FC_RANGE)
6075 ERR("invalid format type %x\n", pRange->type);
6076 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6080 base_type = pRange->flags_type & 0xf;
6082 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6085 /***********************************************************************
6086 * NdrRangeUnmarshall
6088 unsigned char *WINAPI NdrRangeUnmarshall(
6089 PMIDL_STUB_MESSAGE pStubMsg,
6090 unsigned char **ppMemory,
6091 PFORMAT_STRING pFormat,
6092 unsigned char fMustAlloc)
6094 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6095 unsigned char base_type;
6097 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6099 if (pRange->type != RPC_FC_RANGE)
6101 ERR("invalid format type %x\n", pRange->type);
6102 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6105 base_type = pRange->flags_type & 0xf;
6107 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6108 base_type, pRange->low_value, pRange->high_value);
6110 #define RANGE_UNMARSHALL(type, format_spec) \
6113 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6114 if (fMustAlloc || !*ppMemory) \
6115 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6116 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
6118 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6119 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6120 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6122 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
6123 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
6125 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6126 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
6127 (type)pRange->high_value); \
6128 RpcRaiseException(RPC_S_INVALID_BOUND); \
6131 TRACE("*ppMemory: %p\n", *ppMemory); \
6132 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
6133 pStubMsg->Buffer += sizeof(type); \
6140 RANGE_UNMARSHALL(UCHAR, "%d");
6141 TRACE("value: 0x%02x\n", **ppMemory);
6145 RANGE_UNMARSHALL(CHAR, "%u");
6146 TRACE("value: 0x%02x\n", **ppMemory);
6148 case RPC_FC_WCHAR: /* FIXME: valid? */
6150 RANGE_UNMARSHALL(USHORT, "%u");
6151 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6154 RANGE_UNMARSHALL(SHORT, "%d");
6155 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6158 RANGE_UNMARSHALL(LONG, "%d");
6159 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6162 RANGE_UNMARSHALL(ULONG, "%u");
6163 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6167 FIXME("Unhandled enum type\n");
6169 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
6174 ERR("invalid range base type: 0x%02x\n", base_type);
6175 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6181 /***********************************************************************
6182 * NdrRangeBufferSize [internal]
6184 void WINAPI NdrRangeBufferSize(
6185 PMIDL_STUB_MESSAGE pStubMsg,
6186 unsigned char *pMemory,
6187 PFORMAT_STRING pFormat)
6189 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6190 unsigned char base_type;
6192 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6194 if (pRange->type != RPC_FC_RANGE)
6196 ERR("invalid format type %x\n", pRange->type);
6197 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6199 base_type = pRange->flags_type & 0xf;
6201 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6204 /***********************************************************************
6205 * NdrRangeMemorySize [internal]
6207 ULONG WINAPI NdrRangeMemorySize(
6208 PMIDL_STUB_MESSAGE pStubMsg,
6209 PFORMAT_STRING pFormat)
6211 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6212 unsigned char base_type;
6214 if (pRange->type != RPC_FC_RANGE)
6216 ERR("invalid format type %x\n", pRange->type);
6217 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6220 base_type = pRange->flags_type & 0xf;
6222 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6225 /***********************************************************************
6226 * NdrRangeFree [internal]
6228 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6229 unsigned char *pMemory,
6230 PFORMAT_STRING pFormat)
6232 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6237 /***********************************************************************
6238 * NdrBaseTypeMarshall [internal]
6240 static unsigned char *WINAPI NdrBaseTypeMarshall(
6241 PMIDL_STUB_MESSAGE pStubMsg,
6242 unsigned char *pMemory,
6243 PFORMAT_STRING pFormat)
6245 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6253 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6254 TRACE("value: 0x%02x\n", *pMemory);
6259 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6260 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6261 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6265 case RPC_FC_ERROR_STATUS_T:
6267 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
6268 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6269 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6272 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
6273 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6276 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
6277 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6280 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
6281 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6282 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6285 /* only 16-bits on the wire, so do a sanity check */
6286 if (*(UINT *)pMemory > SHRT_MAX)
6287 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6288 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6289 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6290 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6291 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
6292 pStubMsg->Buffer += sizeof(USHORT);
6293 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6298 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6301 /* FIXME: what is the correct return value? */
6305 /***********************************************************************
6306 * NdrBaseTypeUnmarshall [internal]
6308 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6309 PMIDL_STUB_MESSAGE pStubMsg,
6310 unsigned char **ppMemory,
6311 PFORMAT_STRING pFormat,
6312 unsigned char fMustAlloc)
6314 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6316 #define BASE_TYPE_UNMARSHALL(type) \
6317 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6318 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6320 *ppMemory = pStubMsg->Buffer; \
6321 TRACE("*ppMemory: %p\n", *ppMemory); \
6322 safe_buffer_increment(pStubMsg, sizeof(type)); \
6327 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6328 TRACE("*ppMemory: %p\n", *ppMemory); \
6329 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6338 BASE_TYPE_UNMARSHALL(UCHAR);
6339 TRACE("value: 0x%02x\n", **ppMemory);
6344 BASE_TYPE_UNMARSHALL(USHORT);
6345 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6349 case RPC_FC_ERROR_STATUS_T:
6351 BASE_TYPE_UNMARSHALL(ULONG);
6352 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6355 BASE_TYPE_UNMARSHALL(float);
6356 TRACE("value: %f\n", **(float **)ppMemory);
6359 BASE_TYPE_UNMARSHALL(double);
6360 TRACE("value: %f\n", **(double **)ppMemory);
6363 BASE_TYPE_UNMARSHALL(ULONGLONG);
6364 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6367 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6368 if (fMustAlloc || !*ppMemory)
6369 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6370 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
6371 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6372 TRACE("*ppMemory: %p\n", *ppMemory);
6373 /* 16-bits on the wire, but int in memory */
6374 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
6375 pStubMsg->Buffer += sizeof(USHORT);
6376 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6381 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6383 #undef BASE_TYPE_UNMARSHALL
6385 /* FIXME: what is the correct return value? */
6390 /***********************************************************************
6391 * NdrBaseTypeBufferSize [internal]
6393 static void WINAPI NdrBaseTypeBufferSize(
6394 PMIDL_STUB_MESSAGE pStubMsg,
6395 unsigned char *pMemory,
6396 PFORMAT_STRING pFormat)
6398 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6406 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6412 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
6413 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6418 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
6419 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6422 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
6423 safe_buffer_length_increment(pStubMsg, sizeof(float));
6426 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
6427 safe_buffer_length_increment(pStubMsg, sizeof(double));
6430 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
6431 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6433 case RPC_FC_ERROR_STATUS_T:
6434 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
6435 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6440 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6444 /***********************************************************************
6445 * NdrBaseTypeMemorySize [internal]
6447 static ULONG WINAPI NdrBaseTypeMemorySize(
6448 PMIDL_STUB_MESSAGE pStubMsg,
6449 PFORMAT_STRING pFormat)
6451 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6459 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6460 pStubMsg->MemorySize += sizeof(UCHAR);
6461 return sizeof(UCHAR);
6465 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6466 pStubMsg->MemorySize += sizeof(USHORT);
6467 return sizeof(USHORT);
6471 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6472 pStubMsg->MemorySize += sizeof(ULONG);
6473 return sizeof(ULONG);
6475 safe_buffer_increment(pStubMsg, sizeof(float));
6476 pStubMsg->MemorySize += sizeof(float);
6477 return sizeof(float);
6479 safe_buffer_increment(pStubMsg, sizeof(double));
6480 pStubMsg->MemorySize += sizeof(double);
6481 return sizeof(double);
6483 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6484 pStubMsg->MemorySize += sizeof(ULONGLONG);
6485 return sizeof(ULONGLONG);
6486 case RPC_FC_ERROR_STATUS_T:
6487 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6488 pStubMsg->MemorySize += sizeof(error_status_t);
6489 return sizeof(error_status_t);
6491 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6492 pStubMsg->MemorySize += sizeof(UINT);
6493 return sizeof(UINT);
6495 pStubMsg->MemorySize += sizeof(void *);
6496 return sizeof(void *);
6498 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6503 /***********************************************************************
6504 * NdrBaseTypeFree [internal]
6506 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6507 unsigned char *pMemory,
6508 PFORMAT_STRING pFormat)
6510 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6515 /***********************************************************************
6516 * NdrContextHandleBufferSize [internal]
6518 static void WINAPI NdrContextHandleBufferSize(
6519 PMIDL_STUB_MESSAGE pStubMsg,
6520 unsigned char *pMemory,
6521 PFORMAT_STRING pFormat)
6523 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6525 if (*pFormat != RPC_FC_BIND_CONTEXT)
6527 ERR("invalid format type %x\n", *pFormat);
6528 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6530 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
6531 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6534 /***********************************************************************
6535 * NdrContextHandleMarshall [internal]
6537 static unsigned char *WINAPI NdrContextHandleMarshall(
6538 PMIDL_STUB_MESSAGE pStubMsg,
6539 unsigned char *pMemory,
6540 PFORMAT_STRING pFormat)
6542 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6544 if (*pFormat != RPC_FC_BIND_CONTEXT)
6546 ERR("invalid format type %x\n", *pFormat);
6547 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6549 TRACE("flags: 0x%02x\n", pFormat[1]);
6551 if (pFormat[1] & 0x80)
6552 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6554 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
6559 /***********************************************************************
6560 * NdrContextHandleUnmarshall [internal]
6562 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6563 PMIDL_STUB_MESSAGE pStubMsg,
6564 unsigned char **ppMemory,
6565 PFORMAT_STRING pFormat,
6566 unsigned char fMustAlloc)
6568 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6569 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6571 if (*pFormat != RPC_FC_BIND_CONTEXT)
6573 ERR("invalid format type %x\n", *pFormat);
6574 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6576 TRACE("flags: 0x%02x\n", pFormat[1]);
6578 /* [out]-only or [ret] param */
6579 if ((pFormat[1] & 0x60) == 0x20)
6580 **(NDR_CCONTEXT **)ppMemory = NULL;
6581 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6586 /***********************************************************************
6587 * NdrClientContextMarshall [RPCRT4.@]
6589 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6590 NDR_CCONTEXT ContextHandle,
6593 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
6595 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
6597 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6599 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6600 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6601 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6604 /* FIXME: what does fCheck do? */
6605 NDRCContextMarshall(ContextHandle,
6608 pStubMsg->Buffer += cbNDRContext;
6611 /***********************************************************************
6612 * NdrClientContextUnmarshall [RPCRT4.@]
6614 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6615 NDR_CCONTEXT * pContextHandle,
6616 RPC_BINDING_HANDLE BindHandle)
6618 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
6620 ALIGN_POINTER(pStubMsg->Buffer, 4);
6622 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
6623 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6625 NDRCContextUnmarshall(pContextHandle,
6628 pStubMsg->RpcMsg->DataRepresentation);
6630 pStubMsg->Buffer += cbNDRContext;
6633 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6634 NDR_SCONTEXT ContextHandle,
6635 NDR_RUNDOWN RundownRoutine )
6637 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
6639 ALIGN_POINTER(pStubMsg->Buffer, 4);
6641 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6643 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6644 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6645 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6648 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6649 pStubMsg->Buffer, RundownRoutine, NULL,
6650 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6651 pStubMsg->Buffer += cbNDRContext;
6654 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6656 NDR_SCONTEXT ContextHandle;
6658 TRACE("(%p)\n", pStubMsg);
6660 ALIGN_POINTER(pStubMsg->Buffer, 4);
6662 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6664 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6665 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6666 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6669 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6671 pStubMsg->RpcMsg->DataRepresentation,
6672 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6673 pStubMsg->Buffer += cbNDRContext;
6675 return ContextHandle;
6678 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6679 unsigned char* pMemory,
6680 PFORMAT_STRING pFormat)
6682 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6685 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6686 PFORMAT_STRING pFormat)
6688 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6689 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6691 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6693 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6694 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6695 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6696 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6697 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6699 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6700 if_id = &sif->InterfaceId;
6703 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
6704 pStubMsg->RpcMsg->DataRepresentation, if_id,
6708 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6709 NDR_SCONTEXT ContextHandle,
6710 NDR_RUNDOWN RundownRoutine,
6711 PFORMAT_STRING pFormat)
6713 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6714 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6716 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6718 ALIGN_POINTER(pStubMsg->Buffer, 4);
6720 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6722 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6723 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6724 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6727 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6728 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6729 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6730 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6731 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6733 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6734 if_id = &sif->InterfaceId;
6737 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6738 pStubMsg->Buffer, RundownRoutine, if_id, flags);
6739 pStubMsg->Buffer += cbNDRContext;
6742 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6743 PFORMAT_STRING pFormat)
6745 NDR_SCONTEXT ContextHandle;
6746 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6747 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6749 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6751 ALIGN_POINTER(pStubMsg->Buffer, 4);
6753 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6755 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6756 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6757 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6760 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6761 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6762 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6763 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6764 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6766 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6767 if_id = &sif->InterfaceId;
6770 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6772 pStubMsg->RpcMsg->DataRepresentation,
6774 pStubMsg->Buffer += cbNDRContext;
6776 return ContextHandle;
6779 /***********************************************************************
6780 * NdrCorrelationInitialize [RPCRT4.@]
6782 * Initializes correlation validity checking.
6785 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6786 * pMemory [I] Pointer to memory to use as a cache.
6787 * CacheSize [I] Size of the memory pointed to by pMemory.
6788 * Flags [I] Reserved. Set to zero.
6793 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
6795 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
6796 pStubMsg->fHasNewCorrDesc = TRUE;
6799 /***********************************************************************
6800 * NdrCorrelationPass [RPCRT4.@]
6802 * Performs correlation validity checking.
6805 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6810 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
6812 FIXME("(%p): stub\n", pStubMsg);
6815 /***********************************************************************
6816 * NdrCorrelationFree [RPCRT4.@]
6818 * Frees any resources used while unmarshalling parameters that need
6819 * correlation validity checking.
6822 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6827 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
6829 FIXME("(%p): stub\n", pStubMsg);