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;
864 pointer_needs_unmarshaling = 0;
867 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
868 TRACE("pointer_id is 0x%08x\n", pointer_id);
869 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
870 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
873 FIXME("unhandled ptr type=%02x\n", type);
874 RpcRaiseException(RPC_X_BAD_STUB_DATA);
878 if (pointer_needs_unmarshaling) {
879 unsigned char *base_ptr_val = *pPointer;
880 unsigned char **current_ptr = pPointer;
881 if (pStubMsg->IsClient) {
883 /* if we aren't forcing allocation of memory then try to use the existing
884 * (source) pointer to unmarshall the data into so that [in,out]
885 * parameters behave correctly. it doesn't matter if the parameter is
886 * [out] only since in that case the pointer will be NULL. we force
887 * allocation when the source pointer is NULL here instead of in the type
888 * unmarshalling routine for the benefit of the deref code below */
891 TRACE("setting *pPointer to %p\n", pSrcPointer);
892 *pPointer = base_ptr_val = pSrcPointer;
898 /* the memory in a stub is never initialised, so we have to work out here
899 * whether we have to initialise it so we can use the optimisation of
900 * setting the pointer to the buffer, if possible, or set fMustAlloc to
902 if (attr & RPC_FC_P_DEREF) {
910 if (attr & RPC_FC_P_ALLOCALLNODES)
911 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
913 if (attr & RPC_FC_P_DEREF) {
915 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
916 *pPointer = base_ptr_val;
917 current_ptr = (unsigned char **)base_ptr_val;
919 current_ptr = *(unsigned char***)current_ptr;
920 TRACE("deref => %p\n", current_ptr);
921 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
923 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
924 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
925 else FIXME("no unmarshaller for data type=%02x\n", *desc);
927 if (type == RPC_FC_FP)
928 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
932 TRACE("pointer=%p\n", *pPointer);
935 /***********************************************************************
936 * PointerBufferSize [internal]
938 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
939 unsigned char *Pointer,
940 PFORMAT_STRING pFormat)
942 unsigned type = pFormat[0], attr = pFormat[1];
945 int pointer_needs_sizing;
948 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
949 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
951 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
952 else desc = pFormat + *(const SHORT*)pFormat;
955 case RPC_FC_RP: /* ref pointer (always non-null) */
958 ERR("NULL ref pointer is not allowed\n");
959 RpcRaiseException(RPC_X_NULL_REF_POINTER);
964 /* NULL pointer has no further representation */
969 pointer_needs_sizing = !NdrFullPointerQueryPointer(
970 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
971 if (!pointer_needs_sizing)
975 FIXME("unhandled ptr type=%02x\n", type);
976 RpcRaiseException(RPC_X_BAD_STUB_DATA);
980 if (attr & RPC_FC_P_DEREF) {
981 Pointer = *(unsigned char**)Pointer;
982 TRACE("deref => %p\n", Pointer);
985 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
986 if (m) m(pStubMsg, Pointer, desc);
987 else FIXME("no buffersizer for data type=%02x\n", *desc);
990 /***********************************************************************
991 * PointerMemorySize [internal]
993 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
994 unsigned char *Buffer,
995 PFORMAT_STRING pFormat)
997 unsigned type = pFormat[0], attr = pFormat[1];
1000 DWORD pointer_id = 0;
1001 int pointer_needs_sizing;
1003 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1004 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1006 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1007 else desc = pFormat + *(const SHORT*)pFormat;
1010 case RPC_FC_RP: /* ref pointer (always non-null) */
1011 pointer_needs_sizing = 1;
1013 case RPC_FC_UP: /* unique pointer */
1014 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1015 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1016 TRACE("pointer_id is 0x%08x\n", pointer_id);
1018 pointer_needs_sizing = 1;
1020 pointer_needs_sizing = 0;
1025 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1026 TRACE("pointer_id is 0x%08x\n", pointer_id);
1027 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1028 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1032 FIXME("unhandled ptr type=%02x\n", type);
1033 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1037 if (attr & RPC_FC_P_DEREF) {
1041 if (pointer_needs_sizing) {
1042 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1043 if (m) m(pStubMsg, desc);
1044 else FIXME("no memorysizer for data type=%02x\n", *desc);
1047 return pStubMsg->MemorySize;
1050 /***********************************************************************
1051 * PointerFree [internal]
1053 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1054 unsigned char *Pointer,
1055 PFORMAT_STRING pFormat)
1057 unsigned type = pFormat[0], attr = pFormat[1];
1058 PFORMAT_STRING desc;
1060 unsigned char *current_pointer = Pointer;
1062 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1063 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1064 if (attr & RPC_FC_P_DONTFREE) return;
1066 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1067 else desc = pFormat + *(const SHORT*)pFormat;
1069 if (!Pointer) return;
1071 if (type == RPC_FC_FP) {
1072 int pointer_needs_freeing = NdrFullPointerFree(
1073 pStubMsg->FullPtrXlatTables, Pointer);
1074 if (!pointer_needs_freeing)
1078 if (attr & RPC_FC_P_DEREF) {
1079 current_pointer = *(unsigned char**)Pointer;
1080 TRACE("deref => %p\n", current_pointer);
1083 m = NdrFreer[*desc & NDR_TABLE_MASK];
1084 if (m) m(pStubMsg, current_pointer, desc);
1086 /* this check stops us from trying to free buffer memory. we don't have to
1087 * worry about clients, since they won't call this function.
1088 * we don't have to check for the buffer being reallocated because
1089 * BufferStart and BufferEnd won't be reset when allocating memory for
1090 * sending the response. we don't have to check for the new buffer here as
1091 * it won't be used a type memory, only for buffer memory */
1092 if (Pointer >= pStubMsg->BufferStart && Pointer < pStubMsg->BufferEnd)
1095 if (attr & RPC_FC_P_ONSTACK) {
1096 TRACE("not freeing stack ptr %p\n", Pointer);
1099 TRACE("freeing %p\n", Pointer);
1100 NdrFree(pStubMsg, Pointer);
1103 TRACE("not freeing %p\n", Pointer);
1106 /***********************************************************************
1107 * EmbeddedPointerMarshall
1109 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1110 unsigned char *pMemory,
1111 PFORMAT_STRING pFormat)
1113 unsigned char *Mark = pStubMsg->BufferMark;
1114 unsigned rep, count, stride;
1116 unsigned char *saved_buffer = NULL;
1118 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1120 if (*pFormat != RPC_FC_PP) return NULL;
1123 if (pStubMsg->PointerBufferMark)
1125 saved_buffer = pStubMsg->Buffer;
1126 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1127 pStubMsg->PointerBufferMark = NULL;
1130 while (pFormat[0] != RPC_FC_END) {
1131 switch (pFormat[0]) {
1133 FIXME("unknown repeat type %d\n", pFormat[0]);
1134 case RPC_FC_NO_REPEAT:
1140 case RPC_FC_FIXED_REPEAT:
1141 rep = *(const WORD*)&pFormat[2];
1142 stride = *(const WORD*)&pFormat[4];
1143 count = *(const WORD*)&pFormat[8];
1146 case RPC_FC_VARIABLE_REPEAT:
1147 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1148 stride = *(const WORD*)&pFormat[2];
1149 count = *(const WORD*)&pFormat[6];
1153 for (i = 0; i < rep; i++) {
1154 PFORMAT_STRING info = pFormat;
1155 unsigned char *membase = pMemory + (i * stride);
1156 unsigned char *bufbase = Mark + (i * stride);
1159 for (u=0; u<count; u++,info+=8) {
1160 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1161 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1162 unsigned char *saved_memory = pStubMsg->Memory;
1164 pStubMsg->Memory = pMemory;
1165 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1166 pStubMsg->Memory = saved_memory;
1169 pFormat += 8 * count;
1174 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1175 pStubMsg->Buffer = saved_buffer;
1178 STD_OVERFLOW_CHECK(pStubMsg);
1183 /***********************************************************************
1184 * EmbeddedPointerUnmarshall
1186 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1187 unsigned char *pDstBuffer,
1188 unsigned char *pSrcMemoryPtrs,
1189 PFORMAT_STRING pFormat,
1190 unsigned char fMustAlloc)
1192 unsigned char *Mark = pStubMsg->BufferMark;
1193 unsigned rep, count, stride;
1195 unsigned char *saved_buffer = NULL;
1197 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc);
1199 if (*pFormat != RPC_FC_PP) return NULL;
1202 if (pStubMsg->PointerBufferMark)
1204 saved_buffer = pStubMsg->Buffer;
1205 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1206 pStubMsg->PointerBufferMark = NULL;
1209 while (pFormat[0] != RPC_FC_END) {
1210 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1211 switch (pFormat[0]) {
1213 FIXME("unknown repeat type %d\n", pFormat[0]);
1214 case RPC_FC_NO_REPEAT:
1220 case RPC_FC_FIXED_REPEAT:
1221 rep = *(const WORD*)&pFormat[2];
1222 stride = *(const WORD*)&pFormat[4];
1223 count = *(const WORD*)&pFormat[8];
1226 case RPC_FC_VARIABLE_REPEAT:
1227 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1228 stride = *(const WORD*)&pFormat[2];
1229 count = *(const WORD*)&pFormat[6];
1233 for (i = 0; i < rep; i++) {
1234 PFORMAT_STRING info = pFormat;
1235 unsigned char *bufdstbase = pDstBuffer + (i * stride);
1236 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1237 unsigned char *bufbase = Mark + (i * stride);
1240 for (u=0; u<count; u++,info+=8) {
1241 unsigned char **bufdstptr = (unsigned char **)(bufdstbase + *(const SHORT*)&info[2]);
1242 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1243 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1244 PointerUnmarshall(pStubMsg, bufptr, bufdstptr, *memsrcptr, info+4, fMustAlloc);
1247 pFormat += 8 * count;
1252 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1253 pStubMsg->Buffer = saved_buffer;
1259 /***********************************************************************
1260 * EmbeddedPointerBufferSize
1262 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1263 unsigned char *pMemory,
1264 PFORMAT_STRING pFormat)
1266 unsigned rep, count, stride;
1268 ULONG saved_buffer_length = 0;
1270 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1272 if (pStubMsg->IgnoreEmbeddedPointers) return;
1274 if (*pFormat != RPC_FC_PP) return;
1277 if (pStubMsg->PointerLength)
1279 saved_buffer_length = pStubMsg->BufferLength;
1280 pStubMsg->BufferLength = pStubMsg->PointerLength;
1281 pStubMsg->PointerLength = 0;
1284 while (pFormat[0] != RPC_FC_END) {
1285 switch (pFormat[0]) {
1287 FIXME("unknown repeat type %d\n", pFormat[0]);
1288 case RPC_FC_NO_REPEAT:
1294 case RPC_FC_FIXED_REPEAT:
1295 rep = *(const WORD*)&pFormat[2];
1296 stride = *(const WORD*)&pFormat[4];
1297 count = *(const WORD*)&pFormat[8];
1300 case RPC_FC_VARIABLE_REPEAT:
1301 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1302 stride = *(const WORD*)&pFormat[2];
1303 count = *(const WORD*)&pFormat[6];
1307 for (i = 0; i < rep; i++) {
1308 PFORMAT_STRING info = pFormat;
1309 unsigned char *membase = pMemory + (i * stride);
1312 for (u=0; u<count; u++,info+=8) {
1313 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1314 unsigned char *saved_memory = pStubMsg->Memory;
1316 pStubMsg->Memory = pMemory;
1317 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1318 pStubMsg->Memory = saved_memory;
1321 pFormat += 8 * count;
1324 if (saved_buffer_length)
1326 pStubMsg->PointerLength = pStubMsg->BufferLength;
1327 pStubMsg->BufferLength = saved_buffer_length;
1331 /***********************************************************************
1332 * EmbeddedPointerMemorySize [internal]
1334 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1335 PFORMAT_STRING pFormat)
1337 unsigned char *Mark = pStubMsg->BufferMark;
1338 unsigned rep, count, stride;
1340 unsigned char *saved_buffer = NULL;
1342 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1344 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1346 if (pStubMsg->PointerBufferMark)
1348 saved_buffer = pStubMsg->Buffer;
1349 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1350 pStubMsg->PointerBufferMark = NULL;
1353 if (*pFormat != RPC_FC_PP) return 0;
1356 while (pFormat[0] != RPC_FC_END) {
1357 switch (pFormat[0]) {
1359 FIXME("unknown repeat type %d\n", pFormat[0]);
1360 case RPC_FC_NO_REPEAT:
1366 case RPC_FC_FIXED_REPEAT:
1367 rep = *(const WORD*)&pFormat[2];
1368 stride = *(const WORD*)&pFormat[4];
1369 count = *(const WORD*)&pFormat[8];
1372 case RPC_FC_VARIABLE_REPEAT:
1373 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1374 stride = *(const WORD*)&pFormat[2];
1375 count = *(const WORD*)&pFormat[6];
1379 for (i = 0; i < rep; i++) {
1380 PFORMAT_STRING info = pFormat;
1381 unsigned char *bufbase = Mark + (i * stride);
1383 for (u=0; u<count; u++,info+=8) {
1384 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1385 PointerMemorySize(pStubMsg, bufptr, info+4);
1388 pFormat += 8 * count;
1393 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1394 pStubMsg->Buffer = saved_buffer;
1400 /***********************************************************************
1401 * EmbeddedPointerFree [internal]
1403 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1404 unsigned char *pMemory,
1405 PFORMAT_STRING pFormat)
1407 unsigned rep, count, stride;
1410 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1411 if (*pFormat != RPC_FC_PP) return;
1414 while (pFormat[0] != RPC_FC_END) {
1415 switch (pFormat[0]) {
1417 FIXME("unknown repeat type %d\n", pFormat[0]);
1418 case RPC_FC_NO_REPEAT:
1424 case RPC_FC_FIXED_REPEAT:
1425 rep = *(const WORD*)&pFormat[2];
1426 stride = *(const WORD*)&pFormat[4];
1427 count = *(const WORD*)&pFormat[8];
1430 case RPC_FC_VARIABLE_REPEAT:
1431 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1432 stride = *(const WORD*)&pFormat[2];
1433 count = *(const WORD*)&pFormat[6];
1437 for (i = 0; i < rep; i++) {
1438 PFORMAT_STRING info = pFormat;
1439 unsigned char *membase = pMemory + (i * stride);
1442 for (u=0; u<count; u++,info+=8) {
1443 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1444 unsigned char *saved_memory = pStubMsg->Memory;
1446 pStubMsg->Memory = pMemory;
1447 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1448 pStubMsg->Memory = saved_memory;
1451 pFormat += 8 * count;
1455 /***********************************************************************
1456 * NdrPointerMarshall [RPCRT4.@]
1458 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1459 unsigned char *pMemory,
1460 PFORMAT_STRING pFormat)
1462 unsigned char *Buffer;
1464 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1466 /* Increment the buffer here instead of in PointerMarshall,
1467 * as that is used by embedded pointers which already handle the incrementing
1468 * the buffer, and shouldn't write any additional pointer data to the wire */
1469 if (*pFormat != RPC_FC_RP)
1471 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
1472 Buffer = pStubMsg->Buffer;
1473 safe_buffer_increment(pStubMsg, 4);
1476 Buffer = pStubMsg->Buffer;
1478 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1483 /***********************************************************************
1484 * NdrPointerUnmarshall [RPCRT4.@]
1486 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1487 unsigned char **ppMemory,
1488 PFORMAT_STRING pFormat,
1489 unsigned char fMustAlloc)
1491 unsigned char *Buffer;
1493 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1495 /* Increment the buffer here instead of in PointerUnmarshall,
1496 * as that is used by embedded pointers which already handle the incrementing
1497 * the buffer, and shouldn't read any additional pointer data from the
1499 if (*pFormat != RPC_FC_RP)
1501 ALIGN_POINTER(pStubMsg->Buffer, 4);
1502 Buffer = pStubMsg->Buffer;
1503 safe_buffer_increment(pStubMsg, 4);
1506 Buffer = pStubMsg->Buffer;
1508 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1513 /***********************************************************************
1514 * NdrPointerBufferSize [RPCRT4.@]
1516 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1517 unsigned char *pMemory,
1518 PFORMAT_STRING pFormat)
1520 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1522 /* Increment the buffer length here instead of in PointerBufferSize,
1523 * as that is used by embedded pointers which already handle the buffer
1524 * length, and shouldn't write anything more to the wire */
1525 if (*pFormat != RPC_FC_RP)
1527 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1528 safe_buffer_length_increment(pStubMsg, 4);
1531 PointerBufferSize(pStubMsg, pMemory, pFormat);
1534 /***********************************************************************
1535 * NdrPointerMemorySize [RPCRT4.@]
1537 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1538 PFORMAT_STRING pFormat)
1540 /* unsigned size = *(LPWORD)(pFormat+2); */
1541 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1542 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1546 /***********************************************************************
1547 * NdrPointerFree [RPCRT4.@]
1549 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1550 unsigned char *pMemory,
1551 PFORMAT_STRING pFormat)
1553 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1554 PointerFree(pStubMsg, pMemory, pFormat);
1557 /***********************************************************************
1558 * NdrSimpleTypeMarshall [RPCRT4.@]
1560 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1561 unsigned char FormatChar )
1563 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1566 /***********************************************************************
1567 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1569 * Unmarshall a base type.
1572 * Doesn't check that the buffer is long enough before copying, so the caller
1575 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1576 unsigned char FormatChar )
1578 #define BASE_TYPE_UNMARSHALL(type) \
1579 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
1580 TRACE("pMemory: %p\n", pMemory); \
1581 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1582 pStubMsg->Buffer += sizeof(type);
1590 BASE_TYPE_UNMARSHALL(UCHAR);
1591 TRACE("value: 0x%02x\n", *pMemory);
1596 BASE_TYPE_UNMARSHALL(USHORT);
1597 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
1601 case RPC_FC_ERROR_STATUS_T:
1603 BASE_TYPE_UNMARSHALL(ULONG);
1604 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
1607 BASE_TYPE_UNMARSHALL(float);
1608 TRACE("value: %f\n", *(float *)pMemory);
1611 BASE_TYPE_UNMARSHALL(double);
1612 TRACE("value: %f\n", *(double *)pMemory);
1615 BASE_TYPE_UNMARSHALL(ULONGLONG);
1616 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
1619 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
1620 TRACE("pMemory: %p\n", pMemory);
1621 /* 16-bits on the wire, but int in memory */
1622 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
1623 pStubMsg->Buffer += sizeof(USHORT);
1624 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
1629 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
1631 #undef BASE_TYPE_UNMARSHALL
1634 /***********************************************************************
1635 * NdrSimpleStructMarshall [RPCRT4.@]
1637 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1638 unsigned char *pMemory,
1639 PFORMAT_STRING pFormat)
1641 unsigned size = *(const WORD*)(pFormat+2);
1642 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1644 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
1646 pStubMsg->BufferMark = pStubMsg->Buffer;
1647 safe_copy_to_buffer(pStubMsg, pMemory, size);
1649 if (pFormat[0] != RPC_FC_STRUCT)
1650 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1655 /***********************************************************************
1656 * NdrSimpleStructUnmarshall [RPCRT4.@]
1658 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1659 unsigned char **ppMemory,
1660 PFORMAT_STRING pFormat,
1661 unsigned char fMustAlloc)
1663 unsigned size = *(const WORD*)(pFormat+2);
1664 unsigned char *saved_buffer;
1665 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1667 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1670 *ppMemory = NdrAllocate(pStubMsg, size);
1673 if (!pStubMsg->IsClient && !*ppMemory)
1674 /* for servers, we just point straight into the RPC buffer */
1675 *ppMemory = pStubMsg->Buffer;
1678 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1679 safe_buffer_increment(pStubMsg, size);
1680 if (pFormat[0] == RPC_FC_PSTRUCT)
1681 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1683 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1684 if (*ppMemory != saved_buffer)
1685 memcpy(*ppMemory, saved_buffer, size);
1690 /***********************************************************************
1691 * NdrSimpleStructBufferSize [RPCRT4.@]
1693 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1694 unsigned char *pMemory,
1695 PFORMAT_STRING pFormat)
1697 unsigned size = *(const WORD*)(pFormat+2);
1698 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1700 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1702 safe_buffer_length_increment(pStubMsg, size);
1703 if (pFormat[0] != RPC_FC_STRUCT)
1704 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1707 /***********************************************************************
1708 * NdrSimpleStructMemorySize [RPCRT4.@]
1710 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1711 PFORMAT_STRING pFormat)
1713 unsigned short size = *(const WORD *)(pFormat+2);
1715 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1717 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1718 pStubMsg->MemorySize += size;
1719 safe_buffer_increment(pStubMsg, size);
1721 if (pFormat[0] != RPC_FC_STRUCT)
1722 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1723 return pStubMsg->MemorySize;
1726 /***********************************************************************
1727 * NdrSimpleStructFree [RPCRT4.@]
1729 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1730 unsigned char *pMemory,
1731 PFORMAT_STRING pFormat)
1733 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1734 if (pFormat[0] != RPC_FC_STRUCT)
1735 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1740 static inline void array_compute_and_size_conformance(
1741 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1742 PFORMAT_STRING pFormat)
1747 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1748 SizeConformance(pStubMsg);
1750 case RPC_FC_CVARRAY:
1751 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1752 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1753 SizeConformance(pStubMsg);
1755 case RPC_FC_C_CSTRING:
1756 case RPC_FC_C_WSTRING:
1757 if (pFormat[0] == RPC_FC_C_CSTRING)
1759 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1760 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1764 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1765 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1768 if (fc == RPC_FC_STRING_SIZED)
1769 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1771 pStubMsg->MaxCount = pStubMsg->ActualCount;
1773 SizeConformance(pStubMsg);
1776 ERR("unknown array format 0x%x\n", fc);
1777 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1781 static inline void array_buffer_size(
1782 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1783 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1787 unsigned char alignment;
1792 esize = *(const WORD*)(pFormat+2);
1793 alignment = pFormat[1] + 1;
1795 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1797 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
1799 size = safe_multiply(esize, pStubMsg->MaxCount);
1800 /* conformance value plus array */
1801 safe_buffer_length_increment(pStubMsg, size);
1804 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1806 case RPC_FC_CVARRAY:
1807 esize = *(const WORD*)(pFormat+2);
1808 alignment = pFormat[1] + 1;
1810 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1811 pFormat = SkipConformance(pStubMsg, pFormat);
1813 SizeVariance(pStubMsg);
1815 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
1817 size = safe_multiply(esize, pStubMsg->ActualCount);
1818 safe_buffer_length_increment(pStubMsg, size);
1821 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1823 case RPC_FC_C_CSTRING:
1824 case RPC_FC_C_WSTRING:
1825 if (fc == RPC_FC_C_CSTRING)
1830 SizeVariance(pStubMsg);
1832 size = safe_multiply(esize, pStubMsg->ActualCount);
1833 safe_buffer_length_increment(pStubMsg, size);
1836 ERR("unknown array format 0x%x\n", fc);
1837 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1841 static inline void array_compute_and_write_conformance(
1842 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1843 PFORMAT_STRING pFormat)
1848 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1849 WriteConformance(pStubMsg);
1851 case RPC_FC_CVARRAY:
1852 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1853 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1854 WriteConformance(pStubMsg);
1856 case RPC_FC_C_CSTRING:
1857 case RPC_FC_C_WSTRING:
1858 if (fc == RPC_FC_C_CSTRING)
1860 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1861 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1865 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1866 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1868 if (pFormat[1] == RPC_FC_STRING_SIZED)
1869 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1871 pStubMsg->MaxCount = pStubMsg->ActualCount;
1872 pStubMsg->Offset = 0;
1873 WriteConformance(pStubMsg);
1876 ERR("unknown array format 0x%x\n", fc);
1877 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1881 static inline void array_write_variance_and_marshall(
1882 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1883 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1887 unsigned char alignment;
1892 esize = *(const WORD*)(pFormat+2);
1893 alignment = pFormat[1] + 1;
1895 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1897 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
1899 size = safe_multiply(esize, pStubMsg->MaxCount);
1901 pStubMsg->BufferMark = pStubMsg->Buffer;
1902 safe_copy_to_buffer(pStubMsg, pMemory, size);
1905 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1907 case RPC_FC_CVARRAY:
1908 esize = *(const WORD*)(pFormat+2);
1909 alignment = pFormat[1] + 1;
1912 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1914 pFormat = SkipConformance(pStubMsg, pFormat);
1916 WriteVariance(pStubMsg);
1918 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
1920 size = safe_multiply(esize, pStubMsg->ActualCount);
1923 pStubMsg->BufferMark = pStubMsg->Buffer;
1924 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size);
1927 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1929 case RPC_FC_C_CSTRING:
1930 case RPC_FC_C_WSTRING:
1931 if (fc == RPC_FC_C_CSTRING)
1936 WriteVariance(pStubMsg);
1938 size = safe_multiply(esize, pStubMsg->ActualCount);
1939 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
1942 ERR("unknown array format 0x%x\n", fc);
1943 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1947 static inline ULONG array_read_conformance(
1948 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
1955 esize = *(const WORD*)(pFormat+2);
1956 pFormat = ReadConformance(pStubMsg, pFormat+4);
1957 return safe_multiply(esize, pStubMsg->MaxCount);
1958 case RPC_FC_CVARRAY:
1959 esize = *(const WORD*)(pFormat+2);
1960 pFormat = ReadConformance(pStubMsg, pFormat+4);
1961 return safe_multiply(esize, pStubMsg->MaxCount);
1962 case RPC_FC_C_CSTRING:
1963 case RPC_FC_C_WSTRING:
1964 if (fc == RPC_FC_C_CSTRING)
1969 if (pFormat[1] == RPC_FC_STRING_SIZED)
1970 ReadConformance(pStubMsg, pFormat + 2);
1972 ReadConformance(pStubMsg, NULL);
1973 return safe_multiply(esize, pStubMsg->MaxCount);
1975 ERR("unknown array format 0x%x\n", fc);
1976 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1980 static inline ULONG array_read_variance_and_unmarshall(
1981 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory,
1982 PFORMAT_STRING pFormat, unsigned char fMustAlloc,
1983 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall)
1985 ULONG bufsize, memsize;
1987 unsigned char alignment;
1988 unsigned char *saved_buffer;
1994 esize = *(const WORD*)(pFormat+2);
1995 alignment = pFormat[1] + 1;
1997 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
1999 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2001 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2006 *ppMemory = NdrAllocate(pStubMsg, memsize);
2009 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory)
2010 /* for servers, we just point straight into the RPC buffer */
2011 *ppMemory = pStubMsg->Buffer;
2014 saved_buffer = pStubMsg->Buffer;
2015 safe_buffer_increment(pStubMsg, bufsize);
2017 pStubMsg->BufferMark = saved_buffer;
2018 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2020 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2021 if (*ppMemory != saved_buffer)
2022 memcpy(*ppMemory, saved_buffer, bufsize);
2025 case RPC_FC_CVARRAY:
2026 esize = *(const WORD*)(pFormat+2);
2027 alignment = pFormat[1] + 1;
2029 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2031 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2033 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2035 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2036 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2040 offset = pStubMsg->Offset;
2042 if (!fMustAlloc && !*ppMemory)
2045 *ppMemory = NdrAllocate(pStubMsg, memsize);
2046 saved_buffer = pStubMsg->Buffer;
2047 safe_buffer_increment(pStubMsg, bufsize);
2049 pStubMsg->BufferMark = saved_buffer;
2050 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat,
2053 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2056 case RPC_FC_C_CSTRING:
2057 case RPC_FC_C_WSTRING:
2058 if (fc == RPC_FC_C_CSTRING)
2063 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2065 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2067 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2068 pStubMsg->ActualCount, pStubMsg->MaxCount);
2069 RpcRaiseException(RPC_S_INVALID_BOUND);
2071 if (pStubMsg->Offset)
2073 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2074 RpcRaiseException(RPC_S_INVALID_BOUND);
2077 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2078 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2080 validate_string_data(pStubMsg, bufsize, esize);
2085 *ppMemory = NdrAllocate(pStubMsg, memsize);
2088 if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
2089 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
2090 /* if the data in the RPC buffer is big enough, we just point
2091 * straight into it */
2092 *ppMemory = pStubMsg->Buffer;
2093 else if (!*ppMemory)
2094 *ppMemory = NdrAllocate(pStubMsg, memsize);
2097 if (*ppMemory == pStubMsg->Buffer)
2098 safe_buffer_increment(pStubMsg, bufsize);
2100 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2102 if (*pFormat == RPC_FC_C_CSTRING)
2103 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
2105 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
2109 ERR("unknown array format 0x%x\n", fc);
2110 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2114 static inline void array_memory_size(
2115 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
2116 unsigned char fHasPointers)
2118 ULONG bufsize, memsize;
2120 unsigned char alignment;
2125 esize = *(const WORD*)(pFormat+2);
2126 alignment = pFormat[1] + 1;
2128 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2130 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2131 pStubMsg->MemorySize += memsize;
2133 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2135 pStubMsg->BufferMark = pStubMsg->Buffer;
2136 safe_buffer_increment(pStubMsg, bufsize);
2139 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2141 case RPC_FC_CVARRAY:
2142 esize = *(const WORD*)(pFormat+2);
2143 alignment = pFormat[1] + 1;
2145 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2147 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2149 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2150 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2151 pStubMsg->MemorySize += memsize;
2153 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2155 pStubMsg->BufferMark = pStubMsg->Buffer;
2156 safe_buffer_increment(pStubMsg, bufsize);
2159 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2161 case RPC_FC_C_CSTRING:
2162 case RPC_FC_C_WSTRING:
2163 if (fc == RPC_FC_C_CSTRING)
2168 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2170 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2172 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2173 pStubMsg->ActualCount, pStubMsg->MaxCount);
2174 RpcRaiseException(RPC_S_INVALID_BOUND);
2176 if (pStubMsg->Offset)
2178 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2179 RpcRaiseException(RPC_S_INVALID_BOUND);
2182 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2183 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2185 validate_string_data(pStubMsg, bufsize, esize);
2187 safe_buffer_increment(pStubMsg, bufsize);
2188 pStubMsg->MemorySize += memsize;
2191 ERR("unknown array format 0x%x\n", fc);
2192 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2196 static inline void array_free(
2197 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
2198 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
2203 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2205 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2207 case RPC_FC_CVARRAY:
2208 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2209 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2211 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2213 case RPC_FC_C_CSTRING:
2214 case RPC_FC_C_WSTRING:
2215 /* No embedded pointers so nothing to do */
2218 ERR("unknown array format 0x%x\n", fc);
2219 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2224 * NdrConformantString:
2226 * What MS calls a ConformantString is, in DCE terminology,
2227 * a Varying-Conformant String.
2229 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2230 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2231 * into unmarshalled string)
2232 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2234 * data: CHARTYPE[maxlen]
2236 * ], where CHARTYPE is the appropriate character type (specified externally)
2240 /***********************************************************************
2241 * NdrConformantStringMarshall [RPCRT4.@]
2243 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
2244 unsigned char *pszMessage, PFORMAT_STRING pFormat)
2246 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
2248 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2249 ERR("Unhandled string type: %#x\n", pFormat[0]);
2250 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2253 /* allow compiler to optimise inline function by passing constant into
2254 * these functions */
2255 if (pFormat[0] == RPC_FC_C_CSTRING) {
2256 array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2258 array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2259 pFormat, TRUE /* fHasPointers */);
2261 array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2263 array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2264 pFormat, TRUE /* fHasPointers */);
2270 /***********************************************************************
2271 * NdrConformantStringBufferSize [RPCRT4.@]
2273 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2274 unsigned char* pMemory, PFORMAT_STRING pFormat)
2276 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2278 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2279 ERR("Unhandled string type: %#x\n", pFormat[0]);
2280 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2283 /* allow compiler to optimise inline function by passing constant into
2284 * these functions */
2285 if (pFormat[0] == RPC_FC_C_CSTRING) {
2286 array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory,
2288 array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat,
2289 TRUE /* fHasPointers */);
2291 array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory,
2293 array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat,
2294 TRUE /* fHasPointers */);
2298 /************************************************************************
2299 * NdrConformantStringMemorySize [RPCRT4.@]
2301 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2302 PFORMAT_STRING pFormat )
2304 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2306 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2307 ERR("Unhandled string type: %#x\n", pFormat[0]);
2308 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2311 /* allow compiler to optimise inline function by passing constant into
2312 * these functions */
2313 if (pFormat[0] == RPC_FC_C_CSTRING) {
2314 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2315 array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat,
2316 TRUE /* fHasPointers */);
2318 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2319 array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat,
2320 TRUE /* fHasPointers */);
2323 return pStubMsg->MemorySize;
2326 /************************************************************************
2327 * NdrConformantStringUnmarshall [RPCRT4.@]
2329 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2330 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
2332 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2333 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2335 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2336 ERR("Unhandled string type: %#x\n", *pFormat);
2337 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2340 /* allow compiler to optimise inline function by passing constant into
2341 * these functions */
2342 if (pFormat[0] == RPC_FC_C_CSTRING) {
2343 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2344 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory,
2345 pFormat, fMustAlloc,
2346 TRUE /* fUseBufferMemoryServer */,
2347 TRUE /* fUnmarshall */);
2349 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2350 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory,
2351 pFormat, fMustAlloc,
2352 TRUE /* fUseBufferMemoryServer */,
2353 TRUE /* fUnmarshall */);
2359 /***********************************************************************
2360 * NdrNonConformantStringMarshall [RPCRT4.@]
2362 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2363 unsigned char *pMemory,
2364 PFORMAT_STRING pFormat)
2366 ULONG esize, size, maxsize;
2368 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2370 maxsize = *(USHORT *)&pFormat[2];
2372 if (*pFormat == RPC_FC_CSTRING)
2375 const char *str = (const char *)pMemory;
2376 for (i = 0; i < maxsize && *str; i++, str++)
2378 TRACE("string=%s\n", debugstr_an(str, i));
2379 pStubMsg->ActualCount = i + 1;
2382 else if (*pFormat == RPC_FC_WSTRING)
2385 const WCHAR *str = (const WCHAR *)pMemory;
2386 for (i = 0; i < maxsize && *str; i++, str++)
2388 TRACE("string=%s\n", debugstr_wn(str, i));
2389 pStubMsg->ActualCount = i + 1;
2394 ERR("Unhandled string type: %#x\n", *pFormat);
2395 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2398 pStubMsg->Offset = 0;
2399 WriteVariance(pStubMsg);
2401 size = safe_multiply(esize, pStubMsg->ActualCount);
2402 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2407 /***********************************************************************
2408 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2410 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2411 unsigned char **ppMemory,
2412 PFORMAT_STRING pFormat,
2413 unsigned char fMustAlloc)
2415 ULONG bufsize, memsize, esize, maxsize;
2417 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2418 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2420 maxsize = *(USHORT *)&pFormat[2];
2422 ReadVariance(pStubMsg, NULL, maxsize);
2423 if (pStubMsg->Offset)
2425 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2426 RpcRaiseException(RPC_S_INVALID_BOUND);
2429 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2430 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2433 ERR("Unhandled string type: %#x\n", *pFormat);
2434 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2437 memsize = esize * maxsize;
2438 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2440 validate_string_data(pStubMsg, bufsize, esize);
2442 if (fMustAlloc || !*ppMemory)
2443 *ppMemory = NdrAllocate(pStubMsg, memsize);
2445 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2447 if (*pFormat == RPC_FC_CSTRING) {
2448 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
2450 else if (*pFormat == RPC_FC_WSTRING) {
2451 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
2457 /***********************************************************************
2458 * NdrNonConformantStringBufferSize [RPCRT4.@]
2460 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2461 unsigned char *pMemory,
2462 PFORMAT_STRING pFormat)
2464 ULONG esize, maxsize;
2466 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2468 maxsize = *(USHORT *)&pFormat[2];
2470 SizeVariance(pStubMsg);
2472 if (*pFormat == RPC_FC_CSTRING)
2475 const char *str = (const char *)pMemory;
2476 for (i = 0; i < maxsize && *str; i++, str++)
2478 TRACE("string=%s\n", debugstr_an(str, i));
2479 pStubMsg->ActualCount = i + 1;
2482 else if (*pFormat == RPC_FC_WSTRING)
2485 const WCHAR *str = (const WCHAR *)pMemory;
2486 for (i = 0; i < maxsize && *str; i++, str++)
2488 TRACE("string=%s\n", debugstr_wn(str, i));
2489 pStubMsg->ActualCount = i + 1;
2494 ERR("Unhandled string type: %#x\n", *pFormat);
2495 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2498 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2501 /***********************************************************************
2502 * NdrNonConformantStringMemorySize [RPCRT4.@]
2504 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2505 PFORMAT_STRING pFormat)
2507 ULONG bufsize, memsize, esize, maxsize;
2509 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2511 maxsize = *(USHORT *)&pFormat[2];
2513 ReadVariance(pStubMsg, NULL, maxsize);
2515 if (pStubMsg->Offset)
2517 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2518 RpcRaiseException(RPC_S_INVALID_BOUND);
2521 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2522 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2525 ERR("Unhandled string type: %#x\n", *pFormat);
2526 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2529 memsize = esize * maxsize;
2530 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2532 validate_string_data(pStubMsg, bufsize, esize);
2534 safe_buffer_increment(pStubMsg, bufsize);
2535 pStubMsg->MemorySize += memsize;
2537 return pStubMsg->MemorySize;
2542 #include "pshpack1.h"
2546 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2550 #include "poppack.h"
2552 static unsigned long EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2553 PFORMAT_STRING pFormat)
2557 case RPC_FC_PSTRUCT:
2558 case RPC_FC_CSTRUCT:
2559 case RPC_FC_BOGUS_STRUCT:
2560 case RPC_FC_SMFARRAY:
2561 case RPC_FC_SMVARRAY:
2562 case RPC_FC_CSTRING:
2563 return *(const WORD*)&pFormat[2];
2564 case RPC_FC_USER_MARSHAL:
2565 return *(const WORD*)&pFormat[4];
2566 case RPC_FC_RANGE: {
2567 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2572 return sizeof(UCHAR);
2576 return sizeof(USHORT);
2580 return sizeof(ULONG);
2582 return sizeof(float);
2584 return sizeof(double);
2586 return sizeof(ULONGLONG);
2588 return sizeof(UINT);
2590 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2591 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2594 case RPC_FC_NON_ENCAPSULATED_UNION:
2596 if (pStubMsg->fHasNewCorrDesc)
2601 pFormat += *(const SHORT*)pFormat;
2602 return *(const SHORT*)pFormat;
2604 return sizeof(void *);
2605 case RPC_FC_WSTRING:
2606 return *(const WORD*)&pFormat[2] * 2;
2608 FIXME("unhandled embedded type %02x\n", *pFormat);
2614 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2615 PFORMAT_STRING pFormat)
2617 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2621 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2625 return m(pStubMsg, pFormat);
2629 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2630 unsigned char *pMemory,
2631 PFORMAT_STRING pFormat,
2632 PFORMAT_STRING pPointer)
2634 PFORMAT_STRING desc;
2638 while (*pFormat != RPC_FC_END) {
2644 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2645 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2651 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2652 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2656 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2657 if (32767 < *(DWORD*)pMemory)
2658 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2659 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2665 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2666 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2670 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2671 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2674 case RPC_FC_POINTER:
2676 unsigned char *saved_buffer;
2677 int pointer_buffer_mark_set = 0;
2678 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2679 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2680 if (*pPointer != RPC_FC_RP)
2681 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
2682 saved_buffer = pStubMsg->Buffer;
2683 if (pStubMsg->PointerBufferMark)
2685 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2686 pStubMsg->PointerBufferMark = NULL;
2687 pointer_buffer_mark_set = 1;
2689 else if (*pPointer != RPC_FC_RP)
2690 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2691 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2692 if (pointer_buffer_mark_set)
2694 STD_OVERFLOW_CHECK(pStubMsg);
2695 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2696 pStubMsg->Buffer = saved_buffer;
2697 if (*pPointer != RPC_FC_RP)
2698 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2700 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2705 case RPC_FC_ALIGNM4:
2706 ALIGN_POINTER(pMemory, 4);
2708 case RPC_FC_ALIGNM8:
2709 ALIGN_POINTER(pMemory, 8);
2711 case RPC_FC_STRUCTPAD1:
2712 case RPC_FC_STRUCTPAD2:
2713 case RPC_FC_STRUCTPAD3:
2714 case RPC_FC_STRUCTPAD4:
2715 case RPC_FC_STRUCTPAD5:
2716 case RPC_FC_STRUCTPAD6:
2717 case RPC_FC_STRUCTPAD7:
2718 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2720 case RPC_FC_EMBEDDED_COMPLEX:
2721 pMemory += pFormat[1];
2723 desc = pFormat + *(const SHORT*)pFormat;
2724 size = EmbeddedComplexSize(pStubMsg, desc);
2725 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
2726 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2729 /* for some reason interface pointers aren't generated as
2730 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2731 * they still need the derefencing treatment that pointers are
2733 if (*desc == RPC_FC_IP)
2734 m(pStubMsg, *(unsigned char **)pMemory, desc);
2736 m(pStubMsg, pMemory, desc);
2738 else FIXME("no marshaller for embedded type %02x\n", *desc);
2745 FIXME("unhandled format 0x%02x\n", *pFormat);
2753 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2754 unsigned char *pMemory,
2755 PFORMAT_STRING pFormat,
2756 PFORMAT_STRING pPointer,
2757 unsigned char fMustAlloc)
2759 PFORMAT_STRING desc;
2763 while (*pFormat != RPC_FC_END) {
2769 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2770 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2776 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2777 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2781 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2782 *(DWORD*)pMemory &= 0xffff;
2783 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
2784 if (32767 < *(DWORD*)pMemory)
2785 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2791 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2792 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2796 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2797 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2800 case RPC_FC_POINTER:
2802 unsigned char *saved_buffer;
2803 int pointer_buffer_mark_set = 0;
2804 TRACE("pointer => %p\n", pMemory);
2805 if (*pPointer != RPC_FC_RP)
2806 ALIGN_POINTER(pStubMsg->Buffer, 4);
2807 saved_buffer = pStubMsg->Buffer;
2808 if (pStubMsg->PointerBufferMark)
2810 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2811 pStubMsg->PointerBufferMark = NULL;
2812 pointer_buffer_mark_set = 1;
2814 else if (*pPointer != RPC_FC_RP)
2815 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2817 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
2818 if (pointer_buffer_mark_set)
2820 STD_OVERFLOW_CHECK(pStubMsg);
2821 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2822 pStubMsg->Buffer = saved_buffer;
2823 if (*pPointer != RPC_FC_RP)
2824 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2830 case RPC_FC_ALIGNM4:
2831 ALIGN_POINTER_CLEAR(pMemory, 4);
2833 case RPC_FC_ALIGNM8:
2834 ALIGN_POINTER_CLEAR(pMemory, 8);
2836 case RPC_FC_STRUCTPAD1:
2837 case RPC_FC_STRUCTPAD2:
2838 case RPC_FC_STRUCTPAD3:
2839 case RPC_FC_STRUCTPAD4:
2840 case RPC_FC_STRUCTPAD5:
2841 case RPC_FC_STRUCTPAD6:
2842 case RPC_FC_STRUCTPAD7:
2843 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2844 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2846 case RPC_FC_EMBEDDED_COMPLEX:
2847 pMemory += pFormat[1];
2849 desc = pFormat + *(const SHORT*)pFormat;
2850 size = EmbeddedComplexSize(pStubMsg, desc);
2851 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2853 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
2854 * since the type is part of the memory block that is encompassed by
2855 * the whole complex type. Memory is forced to allocate when pointers
2856 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
2857 * clearing the memory we pass in to the unmarshaller */
2858 memset(pMemory, 0, size);
2859 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2862 /* for some reason interface pointers aren't generated as
2863 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2864 * they still need the derefencing treatment that pointers are
2866 if (*desc == RPC_FC_IP)
2867 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2869 m(pStubMsg, &pMemory, desc, FALSE);
2871 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2878 FIXME("unhandled format %d\n", *pFormat);
2886 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2887 unsigned char *pMemory,
2888 PFORMAT_STRING pFormat,
2889 PFORMAT_STRING pPointer)
2891 PFORMAT_STRING desc;
2895 while (*pFormat != RPC_FC_END) {
2901 safe_buffer_length_increment(pStubMsg, 1);
2907 safe_buffer_length_increment(pStubMsg, 2);
2911 safe_buffer_length_increment(pStubMsg, 2);
2917 safe_buffer_length_increment(pStubMsg, 4);
2921 safe_buffer_length_increment(pStubMsg, 8);
2924 case RPC_FC_POINTER:
2925 if (!pStubMsg->IgnoreEmbeddedPointers)
2927 int saved_buffer_length = pStubMsg->BufferLength;
2928 pStubMsg->BufferLength = pStubMsg->PointerLength;
2929 pStubMsg->PointerLength = 0;
2930 if(!pStubMsg->BufferLength)
2931 ERR("BufferLength == 0??\n");
2932 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2933 pStubMsg->PointerLength = pStubMsg->BufferLength;
2934 pStubMsg->BufferLength = saved_buffer_length;
2936 if (*pPointer != RPC_FC_RP)
2938 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2939 safe_buffer_length_increment(pStubMsg, 4);
2944 case RPC_FC_ALIGNM4:
2945 ALIGN_POINTER(pMemory, 4);
2947 case RPC_FC_ALIGNM8:
2948 ALIGN_POINTER(pMemory, 8);
2950 case RPC_FC_STRUCTPAD1:
2951 case RPC_FC_STRUCTPAD2:
2952 case RPC_FC_STRUCTPAD3:
2953 case RPC_FC_STRUCTPAD4:
2954 case RPC_FC_STRUCTPAD5:
2955 case RPC_FC_STRUCTPAD6:
2956 case RPC_FC_STRUCTPAD7:
2957 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2959 case RPC_FC_EMBEDDED_COMPLEX:
2960 pMemory += pFormat[1];
2962 desc = pFormat + *(const SHORT*)pFormat;
2963 size = EmbeddedComplexSize(pStubMsg, desc);
2964 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2967 /* for some reason interface pointers aren't generated as
2968 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2969 * they still need the derefencing treatment that pointers are
2971 if (*desc == RPC_FC_IP)
2972 m(pStubMsg, *(unsigned char **)pMemory, desc);
2974 m(pStubMsg, pMemory, desc);
2976 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2983 FIXME("unhandled format 0x%02x\n", *pFormat);
2991 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2992 unsigned char *pMemory,
2993 PFORMAT_STRING pFormat,
2994 PFORMAT_STRING pPointer)
2996 PFORMAT_STRING desc;
3000 while (*pFormat != RPC_FC_END) {
3022 case RPC_FC_POINTER:
3023 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3027 case RPC_FC_ALIGNM4:
3028 ALIGN_POINTER(pMemory, 4);
3030 case RPC_FC_ALIGNM8:
3031 ALIGN_POINTER(pMemory, 8);
3033 case RPC_FC_STRUCTPAD1:
3034 case RPC_FC_STRUCTPAD2:
3035 case RPC_FC_STRUCTPAD3:
3036 case RPC_FC_STRUCTPAD4:
3037 case RPC_FC_STRUCTPAD5:
3038 case RPC_FC_STRUCTPAD6:
3039 case RPC_FC_STRUCTPAD7:
3040 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3042 case RPC_FC_EMBEDDED_COMPLEX:
3043 pMemory += pFormat[1];
3045 desc = pFormat + *(const SHORT*)pFormat;
3046 size = EmbeddedComplexSize(pStubMsg, desc);
3047 m = NdrFreer[*desc & NDR_TABLE_MASK];
3050 /* for some reason interface pointers aren't generated as
3051 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3052 * they still need the derefencing treatment that pointers are
3054 if (*desc == RPC_FC_IP)
3055 m(pStubMsg, *(unsigned char **)pMemory, desc);
3057 m(pStubMsg, pMemory, desc);
3065 FIXME("unhandled format 0x%02x\n", *pFormat);
3073 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3074 PFORMAT_STRING pFormat,
3075 PFORMAT_STRING pPointer)
3077 PFORMAT_STRING desc;
3078 unsigned long size = 0;
3080 while (*pFormat != RPC_FC_END) {
3087 safe_buffer_increment(pStubMsg, 1);
3093 safe_buffer_increment(pStubMsg, 2);
3097 safe_buffer_increment(pStubMsg, 2);
3103 safe_buffer_increment(pStubMsg, 4);
3107 safe_buffer_increment(pStubMsg, 8);
3109 case RPC_FC_POINTER:
3111 unsigned char *saved_buffer;
3112 int pointer_buffer_mark_set = 0;
3113 if (*pPointer != RPC_FC_RP)
3114 ALIGN_POINTER(pStubMsg->Buffer, 4);
3115 saved_buffer = pStubMsg->Buffer;
3116 if (pStubMsg->PointerBufferMark)
3118 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3119 pStubMsg->PointerBufferMark = NULL;
3120 pointer_buffer_mark_set = 1;
3122 else if (*pPointer != RPC_FC_RP)
3123 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3125 if (!pStubMsg->IgnoreEmbeddedPointers)
3126 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3127 if (pointer_buffer_mark_set)
3129 STD_OVERFLOW_CHECK(pStubMsg);
3130 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3131 pStubMsg->Buffer = saved_buffer;
3132 if (*pPointer != RPC_FC_RP)
3133 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3139 case RPC_FC_ALIGNM4:
3140 ALIGN_LENGTH(size, 4);
3141 ALIGN_POINTER(pStubMsg->Buffer, 4);
3143 case RPC_FC_ALIGNM8:
3144 ALIGN_LENGTH(size, 8);
3145 ALIGN_POINTER(pStubMsg->Buffer, 8);
3147 case RPC_FC_STRUCTPAD1:
3148 case RPC_FC_STRUCTPAD2:
3149 case RPC_FC_STRUCTPAD3:
3150 case RPC_FC_STRUCTPAD4:
3151 case RPC_FC_STRUCTPAD5:
3152 case RPC_FC_STRUCTPAD6:
3153 case RPC_FC_STRUCTPAD7:
3154 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3156 case RPC_FC_EMBEDDED_COMPLEX:
3159 desc = pFormat + *(const SHORT*)pFormat;
3160 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3166 FIXME("unhandled format 0x%02x\n", *pFormat);
3174 unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg,
3175 PFORMAT_STRING pFormat)
3177 PFORMAT_STRING desc;
3178 unsigned long size = 0;
3180 while (*pFormat != RPC_FC_END) {
3202 case RPC_FC_POINTER:
3203 size += sizeof(void *);
3205 case RPC_FC_ALIGNM4:
3206 ALIGN_LENGTH(size, 4);
3208 case RPC_FC_ALIGNM8:
3209 ALIGN_LENGTH(size, 8);
3211 case RPC_FC_STRUCTPAD1:
3212 case RPC_FC_STRUCTPAD2:
3213 case RPC_FC_STRUCTPAD3:
3214 case RPC_FC_STRUCTPAD4:
3215 case RPC_FC_STRUCTPAD5:
3216 case RPC_FC_STRUCTPAD6:
3217 case RPC_FC_STRUCTPAD7:
3218 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3220 case RPC_FC_EMBEDDED_COMPLEX:
3223 desc = pFormat + *(const SHORT*)pFormat;
3224 size += EmbeddedComplexSize(pStubMsg, desc);
3230 FIXME("unhandled format 0x%02x\n", *pFormat);
3238 /***********************************************************************
3239 * NdrComplexStructMarshall [RPCRT4.@]
3241 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3242 unsigned char *pMemory,
3243 PFORMAT_STRING pFormat)
3245 PFORMAT_STRING conf_array = NULL;
3246 PFORMAT_STRING pointer_desc = NULL;
3247 unsigned char *OldMemory = pStubMsg->Memory;
3248 int pointer_buffer_mark_set = 0;
3250 ULONG max_count = 0;
3253 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3255 if (!pStubMsg->PointerBufferMark)
3257 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3258 /* save buffer length */
3259 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3261 /* get the buffer pointer after complex array data, but before
3263 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3264 pStubMsg->IgnoreEmbeddedPointers = 1;
3265 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3266 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3268 /* save it for use by embedded pointer code later */
3269 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3270 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
3271 pointer_buffer_mark_set = 1;
3273 /* restore the original buffer length */
3274 pStubMsg->BufferLength = saved_buffer_length;
3277 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
3280 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3282 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3285 pStubMsg->Memory = pMemory;
3289 unsigned long struct_size = ComplexStructSize(pStubMsg, pFormat);
3290 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3291 pMemory + struct_size, conf_array);
3292 /* these could be changed in ComplexMarshall so save them for later */
3293 max_count = pStubMsg->MaxCount;
3294 count = pStubMsg->ActualCount;
3295 offset = pStubMsg->Offset;
3298 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3302 pStubMsg->MaxCount = max_count;
3303 pStubMsg->ActualCount = count;
3304 pStubMsg->Offset = offset;
3305 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3306 conf_array, TRUE /* fHasPointers */);
3309 pStubMsg->Memory = OldMemory;
3311 if (pointer_buffer_mark_set)
3313 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3314 pStubMsg->PointerBufferMark = NULL;
3317 STD_OVERFLOW_CHECK(pStubMsg);
3322 /***********************************************************************
3323 * NdrComplexStructUnmarshall [RPCRT4.@]
3325 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3326 unsigned char **ppMemory,
3327 PFORMAT_STRING pFormat,
3328 unsigned char fMustAlloc)
3330 unsigned size = *(const WORD*)(pFormat+2);
3331 PFORMAT_STRING conf_array = NULL;
3332 PFORMAT_STRING pointer_desc = NULL;
3333 unsigned char *pMemory;
3334 int pointer_buffer_mark_set = 0;
3336 ULONG max_count = 0;
3338 ULONG array_size = 0;
3340 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3342 if (!pStubMsg->PointerBufferMark)
3344 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3345 /* save buffer pointer */
3346 unsigned char *saved_buffer = pStubMsg->Buffer;
3348 /* get the buffer pointer after complex array data, but before
3350 pStubMsg->IgnoreEmbeddedPointers = 1;
3351 NdrComplexStructMemorySize(pStubMsg, pFormat);
3352 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3354 /* save it for use by embedded pointer code later */
3355 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3356 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
3357 pointer_buffer_mark_set = 1;
3359 /* restore the original buffer */
3360 pStubMsg->Buffer = saved_buffer;
3363 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3366 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3368 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3373 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3376 /* these could be changed in ComplexMarshall so save them for later */
3377 max_count = pStubMsg->MaxCount;
3378 count = pStubMsg->ActualCount;
3379 offset = pStubMsg->Offset;
3382 if (fMustAlloc || !*ppMemory)
3383 *ppMemory = NdrAllocate(pStubMsg, size);
3385 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3389 pStubMsg->MaxCount = max_count;
3390 pStubMsg->ActualCount = count;
3391 pStubMsg->Offset = offset;
3393 memset(pMemory, 0, array_size);
3394 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3396 FALSE /* fUseBufferMemoryServer */,
3397 TRUE /* fUnmarshall */);
3400 if (pointer_buffer_mark_set)
3402 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3403 pStubMsg->PointerBufferMark = NULL;
3409 /***********************************************************************
3410 * NdrComplexStructBufferSize [RPCRT4.@]
3412 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3413 unsigned char *pMemory,
3414 PFORMAT_STRING pFormat)
3416 PFORMAT_STRING conf_array = NULL;
3417 PFORMAT_STRING pointer_desc = NULL;
3418 unsigned char *OldMemory = pStubMsg->Memory;
3419 int pointer_length_set = 0;
3421 ULONG max_count = 0;
3424 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3426 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
3428 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3430 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3431 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3433 /* get the buffer length after complex struct data, but before
3435 pStubMsg->IgnoreEmbeddedPointers = 1;
3436 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3437 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3439 /* save it for use by embedded pointer code later */
3440 pStubMsg->PointerLength = pStubMsg->BufferLength;
3441 pointer_length_set = 1;
3442 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
3444 /* restore the original buffer length */
3445 pStubMsg->BufferLength = saved_buffer_length;
3449 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3451 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3454 pStubMsg->Memory = pMemory;
3458 unsigned long struct_size = ComplexStructSize(pStubMsg, pFormat);
3459 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3462 /* these could be changed in ComplexMarshall so save them for later */
3463 max_count = pStubMsg->MaxCount;
3464 count = pStubMsg->ActualCount;
3465 offset = pStubMsg->Offset;
3468 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3472 pStubMsg->MaxCount = max_count;
3473 pStubMsg->ActualCount = count;
3474 pStubMsg->Offset = offset;
3475 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3476 TRUE /* fHasPointers */);
3479 pStubMsg->Memory = OldMemory;
3481 if(pointer_length_set)
3483 pStubMsg->BufferLength = pStubMsg->PointerLength;
3484 pStubMsg->PointerLength = 0;
3489 /***********************************************************************
3490 * NdrComplexStructMemorySize [RPCRT4.@]
3492 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3493 PFORMAT_STRING pFormat)
3495 unsigned size = *(const WORD*)(pFormat+2);
3496 PFORMAT_STRING conf_array = NULL;
3497 PFORMAT_STRING pointer_desc = NULL;
3499 ULONG max_count = 0;
3502 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3504 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3507 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3509 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3514 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3516 /* these could be changed in ComplexStructMemorySize so save them for
3518 max_count = pStubMsg->MaxCount;
3519 count = pStubMsg->ActualCount;
3520 offset = pStubMsg->Offset;
3523 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3527 pStubMsg->MaxCount = max_count;
3528 pStubMsg->ActualCount = count;
3529 pStubMsg->Offset = offset;
3530 array_memory_size(conf_array[0], pStubMsg, conf_array,
3531 TRUE /* fHasPointers */);
3537 /***********************************************************************
3538 * NdrComplexStructFree [RPCRT4.@]
3540 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3541 unsigned char *pMemory,
3542 PFORMAT_STRING pFormat)
3544 PFORMAT_STRING conf_array = NULL;
3545 PFORMAT_STRING pointer_desc = NULL;
3546 unsigned char *OldMemory = pStubMsg->Memory;
3548 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3551 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3553 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3556 pStubMsg->Memory = pMemory;
3558 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3561 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3562 TRUE /* fHasPointers */);
3564 pStubMsg->Memory = OldMemory;
3567 /***********************************************************************
3568 * NdrConformantArrayMarshall [RPCRT4.@]
3570 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3571 unsigned char *pMemory,
3572 PFORMAT_STRING pFormat)
3574 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3575 if (pFormat[0] != RPC_FC_CARRAY)
3577 ERR("invalid format = 0x%x\n", pFormat[0]);
3578 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3581 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory,
3583 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3584 TRUE /* fHasPointers */);
3589 /***********************************************************************
3590 * NdrConformantArrayUnmarshall [RPCRT4.@]
3592 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3593 unsigned char **ppMemory,
3594 PFORMAT_STRING pFormat,
3595 unsigned char fMustAlloc)
3597 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3598 if (pFormat[0] != RPC_FC_CARRAY)
3600 ERR("invalid format = 0x%x\n", pFormat[0]);
3601 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3604 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3605 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat,
3607 TRUE /* fUseBufferMemoryServer */,
3608 TRUE /* fUnmarshall */);
3613 /***********************************************************************
3614 * NdrConformantArrayBufferSize [RPCRT4.@]
3616 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3617 unsigned char *pMemory,
3618 PFORMAT_STRING pFormat)
3620 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3621 if (pFormat[0] != RPC_FC_CARRAY)
3623 ERR("invalid format = 0x%x\n", pFormat[0]);
3624 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3627 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat);
3628 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3629 TRUE /* fHasPointers */);
3632 /***********************************************************************
3633 * NdrConformantArrayMemorySize [RPCRT4.@]
3635 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3636 PFORMAT_STRING pFormat)
3638 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3639 if (pFormat[0] != RPC_FC_CARRAY)
3641 ERR("invalid format = 0x%x\n", pFormat[0]);
3642 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3645 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3646 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
3648 return pStubMsg->MemorySize;
3651 /***********************************************************************
3652 * NdrConformantArrayFree [RPCRT4.@]
3654 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3655 unsigned char *pMemory,
3656 PFORMAT_STRING pFormat)
3658 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3659 if (pFormat[0] != RPC_FC_CARRAY)
3661 ERR("invalid format = 0x%x\n", pFormat[0]);
3662 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3665 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3666 TRUE /* fHasPointers */);
3670 /***********************************************************************
3671 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3673 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
3674 unsigned char* pMemory,
3675 PFORMAT_STRING pFormat )
3677 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3679 if (pFormat[0] != RPC_FC_CVARRAY)
3681 ERR("invalid format type %x\n", pFormat[0]);
3682 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3686 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3688 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory,
3689 pFormat, TRUE /* fHasPointers */);
3695 /***********************************************************************
3696 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3698 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
3699 unsigned char** ppMemory,
3700 PFORMAT_STRING pFormat,
3701 unsigned char fMustAlloc )
3703 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3705 if (pFormat[0] != RPC_FC_CVARRAY)
3707 ERR("invalid format type %x\n", pFormat[0]);
3708 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3712 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3713 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory,
3714 pFormat, fMustAlloc,
3715 TRUE /* fUseBufferMemoryServer */,
3716 TRUE /* fUnmarshall */);
3722 /***********************************************************************
3723 * NdrConformantVaryingArrayFree [RPCRT4.@]
3725 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
3726 unsigned char* pMemory,
3727 PFORMAT_STRING pFormat )
3729 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3731 if (pFormat[0] != RPC_FC_CVARRAY)
3733 ERR("invalid format type %x\n", pFormat[0]);
3734 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3738 array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3739 TRUE /* fHasPointers */);
3743 /***********************************************************************
3744 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3746 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
3747 unsigned char* pMemory, PFORMAT_STRING pFormat )
3749 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3751 if (pFormat[0] != RPC_FC_CVARRAY)
3753 ERR("invalid format type %x\n", pFormat[0]);
3754 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3758 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3760 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3761 TRUE /* fHasPointers */);
3765 /***********************************************************************
3766 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3768 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
3769 PFORMAT_STRING pFormat )
3771 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3773 if (pFormat[0] != RPC_FC_CVARRAY)
3775 ERR("invalid format type %x\n", pFormat[0]);
3776 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3777 return pStubMsg->MemorySize;
3780 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3781 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat,
3782 TRUE /* fHasPointers */);
3784 return pStubMsg->MemorySize;
3788 /***********************************************************************
3789 * NdrComplexArrayMarshall [RPCRT4.@]
3791 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3792 unsigned char *pMemory,
3793 PFORMAT_STRING pFormat)
3795 ULONG i, count, def;
3796 BOOL variance_present;
3797 unsigned char alignment;
3798 int pointer_buffer_mark_set = 0;
3800 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3802 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3804 ERR("invalid format type %x\n", pFormat[0]);
3805 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3809 alignment = pFormat[1] + 1;
3811 if (!pStubMsg->PointerBufferMark)
3813 /* save buffer fields that may be changed by buffer sizer functions
3814 * and that may be needed later on */
3815 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3816 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3817 unsigned long saved_max_count = pStubMsg->MaxCount;
3818 unsigned long saved_offset = pStubMsg->Offset;
3819 unsigned long saved_actual_count = pStubMsg->ActualCount;
3821 /* get the buffer pointer after complex array data, but before
3823 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3824 pStubMsg->IgnoreEmbeddedPointers = 1;
3825 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3826 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3828 /* save it for use by embedded pointer code later */
3829 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3830 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
3831 pointer_buffer_mark_set = 1;
3833 /* restore fields */
3834 pStubMsg->ActualCount = saved_actual_count;
3835 pStubMsg->Offset = saved_offset;
3836 pStubMsg->MaxCount = saved_max_count;
3837 pStubMsg->BufferLength = saved_buffer_length;
3840 def = *(const WORD*)&pFormat[2];
3843 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3844 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3846 variance_present = IsConformanceOrVariancePresent(pFormat);
3847 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3848 TRACE("variance = %d\n", pStubMsg->ActualCount);
3850 WriteConformance(pStubMsg);
3851 if (variance_present)
3852 WriteVariance(pStubMsg);
3854 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3856 count = pStubMsg->ActualCount;
3857 for (i = 0; i < count; i++)
3858 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3860 STD_OVERFLOW_CHECK(pStubMsg);
3862 if (pointer_buffer_mark_set)
3864 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3865 pStubMsg->PointerBufferMark = NULL;
3871 /***********************************************************************
3872 * NdrComplexArrayUnmarshall [RPCRT4.@]
3874 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3875 unsigned char **ppMemory,
3876 PFORMAT_STRING pFormat,
3877 unsigned char fMustAlloc)
3879 ULONG i, count, size;
3880 unsigned char alignment;
3881 unsigned char *pMemory;
3882 unsigned char *saved_buffer;
3883 int pointer_buffer_mark_set = 0;
3884 int saved_ignore_embedded;
3886 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3888 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3890 ERR("invalid format type %x\n", pFormat[0]);
3891 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3895 alignment = pFormat[1] + 1;
3897 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3898 /* save buffer pointer */
3899 saved_buffer = pStubMsg->Buffer;
3900 /* get the buffer pointer after complex array data, but before
3902 pStubMsg->IgnoreEmbeddedPointers = 1;
3903 pStubMsg->MemorySize = 0;
3904 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3905 size = pStubMsg->MemorySize;
3906 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3908 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
3909 if (!pStubMsg->PointerBufferMark)
3911 /* save it for use by embedded pointer code later */
3912 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3913 pointer_buffer_mark_set = 1;
3915 /* restore the original buffer */
3916 pStubMsg->Buffer = saved_buffer;
3920 pFormat = ReadConformance(pStubMsg, pFormat);
3921 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3923 if (fMustAlloc || !*ppMemory)
3924 *ppMemory = NdrAllocate(pStubMsg, size);
3926 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3928 pMemory = *ppMemory;
3929 count = pStubMsg->ActualCount;
3930 for (i = 0; i < count; i++)
3931 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
3933 if (pointer_buffer_mark_set)
3935 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3936 pStubMsg->PointerBufferMark = NULL;
3942 /***********************************************************************
3943 * NdrComplexArrayBufferSize [RPCRT4.@]
3945 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3946 unsigned char *pMemory,
3947 PFORMAT_STRING pFormat)
3949 ULONG i, count, def;
3950 unsigned char alignment;
3951 BOOL variance_present;
3952 int pointer_length_set = 0;
3954 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3956 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3958 ERR("invalid format type %x\n", pFormat[0]);
3959 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3963 alignment = pFormat[1] + 1;
3965 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3967 /* save buffer fields that may be changed by buffer sizer functions
3968 * and that may be needed later on */
3969 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3970 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3971 unsigned long saved_max_count = pStubMsg->MaxCount;
3972 unsigned long saved_offset = pStubMsg->Offset;
3973 unsigned long saved_actual_count = pStubMsg->ActualCount;
3975 /* get the buffer pointer after complex array data, but before
3977 pStubMsg->IgnoreEmbeddedPointers = 1;
3978 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3979 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3981 /* save it for use by embedded pointer code later */
3982 pStubMsg->PointerLength = pStubMsg->BufferLength;
3983 pointer_length_set = 1;
3985 /* restore fields */
3986 pStubMsg->ActualCount = saved_actual_count;
3987 pStubMsg->Offset = saved_offset;
3988 pStubMsg->MaxCount = saved_max_count;
3989 pStubMsg->BufferLength = saved_buffer_length;
3991 def = *(const WORD*)&pFormat[2];
3994 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3995 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3996 SizeConformance(pStubMsg);
3998 variance_present = IsConformanceOrVariancePresent(pFormat);
3999 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4000 TRACE("variance = %d\n", pStubMsg->ActualCount);
4002 if (variance_present)
4003 SizeVariance(pStubMsg);
4005 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4007 count = pStubMsg->ActualCount;
4008 for (i = 0; i < count; i++)
4009 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
4011 if(pointer_length_set)
4013 pStubMsg->BufferLength = pStubMsg->PointerLength;
4014 pStubMsg->PointerLength = 0;
4018 /***********************************************************************
4019 * NdrComplexArrayMemorySize [RPCRT4.@]
4021 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4022 PFORMAT_STRING pFormat)
4024 ULONG i, count, esize, SavedMemorySize, MemorySize;
4025 unsigned char alignment;
4027 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4029 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4031 ERR("invalid format type %x\n", pFormat[0]);
4032 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4036 alignment = pFormat[1] + 1;
4040 pFormat = ReadConformance(pStubMsg, pFormat);
4041 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
4043 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4045 SavedMemorySize = pStubMsg->MemorySize;
4047 esize = ComplexStructSize(pStubMsg, pFormat);
4049 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
4051 count = pStubMsg->ActualCount;
4052 for (i = 0; i < count; i++)
4053 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
4055 pStubMsg->MemorySize = SavedMemorySize;
4057 pStubMsg->MemorySize += MemorySize;
4061 /***********************************************************************
4062 * NdrComplexArrayFree [RPCRT4.@]
4064 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4065 unsigned char *pMemory,
4066 PFORMAT_STRING pFormat)
4068 ULONG i, count, def;
4070 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4072 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4074 ERR("invalid format type %x\n", pFormat[0]);
4075 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4079 def = *(const WORD*)&pFormat[2];
4082 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4083 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4085 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4086 TRACE("variance = %d\n", pStubMsg->ActualCount);
4088 count = pStubMsg->ActualCount;
4089 for (i = 0; i < count; i++)
4090 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4093 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4094 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4095 USER_MARSHAL_CB *umcb)
4097 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4098 pStubMsg->RpcMsg->DataRepresentation);
4099 umcb->pStubMsg = pStubMsg;
4100 umcb->pReserve = NULL;
4101 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4102 umcb->CBType = cbtype;
4103 umcb->pFormat = pFormat;
4104 umcb->pTypeFormat = NULL /* FIXME */;
4107 #define USER_MARSHAL_PTR_PREFIX \
4108 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4109 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4111 /***********************************************************************
4112 * NdrUserMarshalMarshall [RPCRT4.@]
4114 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4115 unsigned char *pMemory,
4116 PFORMAT_STRING pFormat)
4118 unsigned flags = pFormat[1];
4119 unsigned index = *(const WORD*)&pFormat[2];
4120 unsigned char *saved_buffer = NULL;
4121 USER_MARSHAL_CB umcb;
4123 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4124 TRACE("index=%d\n", index);
4126 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4128 if (flags & USER_MARSHAL_POINTER)
4130 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
4131 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4132 pStubMsg->Buffer += 4;
4133 if (pStubMsg->PointerBufferMark)
4135 saved_buffer = pStubMsg->Buffer;
4136 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4137 pStubMsg->PointerBufferMark = NULL;
4139 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
4142 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
4145 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4146 &umcb.Flags, pStubMsg->Buffer, pMemory);
4150 STD_OVERFLOW_CHECK(pStubMsg);
4151 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4152 pStubMsg->Buffer = saved_buffer;
4155 STD_OVERFLOW_CHECK(pStubMsg);
4160 /***********************************************************************
4161 * NdrUserMarshalUnmarshall [RPCRT4.@]
4163 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4164 unsigned char **ppMemory,
4165 PFORMAT_STRING pFormat,
4166 unsigned char fMustAlloc)
4168 unsigned flags = pFormat[1];
4169 unsigned index = *(const WORD*)&pFormat[2];
4170 DWORD memsize = *(const WORD*)&pFormat[4];
4171 unsigned char *saved_buffer = NULL;
4172 USER_MARSHAL_CB umcb;
4174 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4175 TRACE("index=%d\n", index);
4177 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4179 if (flags & USER_MARSHAL_POINTER)
4181 ALIGN_POINTER(pStubMsg->Buffer, 4);
4182 /* skip pointer prefix */
4183 pStubMsg->Buffer += 4;
4184 if (pStubMsg->PointerBufferMark)
4186 saved_buffer = pStubMsg->Buffer;
4187 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4188 pStubMsg->PointerBufferMark = NULL;
4190 ALIGN_POINTER(pStubMsg->Buffer, 8);
4193 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4195 if (fMustAlloc || !*ppMemory)
4196 *ppMemory = NdrAllocate(pStubMsg, memsize);
4199 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4200 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4204 STD_OVERFLOW_CHECK(pStubMsg);
4205 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4206 pStubMsg->Buffer = saved_buffer;
4212 /***********************************************************************
4213 * NdrUserMarshalBufferSize [RPCRT4.@]
4215 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4216 unsigned char *pMemory,
4217 PFORMAT_STRING pFormat)
4219 unsigned flags = pFormat[1];
4220 unsigned index = *(const WORD*)&pFormat[2];
4221 DWORD bufsize = *(const WORD*)&pFormat[6];
4222 USER_MARSHAL_CB umcb;
4223 unsigned long saved_buffer_length = 0;
4225 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4226 TRACE("index=%d\n", index);
4228 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4230 if (flags & USER_MARSHAL_POINTER)
4232 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4233 /* skip pointer prefix */
4234 safe_buffer_length_increment(pStubMsg, 4);
4235 if (pStubMsg->IgnoreEmbeddedPointers)
4237 if (pStubMsg->PointerLength)
4239 saved_buffer_length = pStubMsg->BufferLength;
4240 pStubMsg->BufferLength = pStubMsg->PointerLength;
4241 pStubMsg->PointerLength = 0;
4243 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
4246 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
4249 TRACE("size=%d\n", bufsize);
4250 safe_buffer_length_increment(pStubMsg, bufsize);
4253 pStubMsg->BufferLength =
4254 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4255 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4257 if (saved_buffer_length)
4259 pStubMsg->PointerLength = pStubMsg->BufferLength;
4260 pStubMsg->BufferLength = saved_buffer_length;
4265 /***********************************************************************
4266 * NdrUserMarshalMemorySize [RPCRT4.@]
4268 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4269 PFORMAT_STRING pFormat)
4271 unsigned flags = pFormat[1];
4272 unsigned index = *(const WORD*)&pFormat[2];
4273 DWORD memsize = *(const WORD*)&pFormat[4];
4274 DWORD bufsize = *(const WORD*)&pFormat[6];
4276 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4277 TRACE("index=%d\n", index);
4279 pStubMsg->MemorySize += memsize;
4281 if (flags & USER_MARSHAL_POINTER)
4283 ALIGN_POINTER(pStubMsg->Buffer, 4);
4284 /* skip pointer prefix */
4285 pStubMsg->Buffer += 4;
4286 if (pStubMsg->IgnoreEmbeddedPointers)
4287 return pStubMsg->MemorySize;
4288 ALIGN_POINTER(pStubMsg->Buffer, 8);
4291 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4294 FIXME("not implemented for varying buffer size\n");
4296 pStubMsg->Buffer += bufsize;
4298 return pStubMsg->MemorySize;
4301 /***********************************************************************
4302 * NdrUserMarshalFree [RPCRT4.@]
4304 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4305 unsigned char *pMemory,
4306 PFORMAT_STRING pFormat)
4308 /* unsigned flags = pFormat[1]; */
4309 unsigned index = *(const WORD*)&pFormat[2];
4310 USER_MARSHAL_CB umcb;
4312 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4313 TRACE("index=%d\n", index);
4315 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4317 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4318 &umcb.Flags, pMemory);
4321 /***********************************************************************
4322 * NdrClearOutParameters [RPCRT4.@]
4324 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4325 PFORMAT_STRING pFormat,
4328 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4331 /***********************************************************************
4332 * NdrConvert [RPCRT4.@]
4334 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4336 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4337 /* FIXME: since this stub doesn't do any converting, the proper behavior
4338 is to raise an exception */
4341 /***********************************************************************
4342 * NdrConvert2 [RPCRT4.@]
4344 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4346 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4347 pStubMsg, pFormat, NumberParams);
4348 /* FIXME: since this stub doesn't do any converting, the proper behavior
4349 is to raise an exception */
4352 #include "pshpack1.h"
4353 typedef struct _NDR_CSTRUCT_FORMAT
4356 unsigned char alignment;
4357 unsigned short memory_size;
4358 short offset_to_array_description;
4359 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4360 #include "poppack.h"
4362 /***********************************************************************
4363 * NdrConformantStructMarshall [RPCRT4.@]
4365 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4366 unsigned char *pMemory,
4367 PFORMAT_STRING pFormat)
4369 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4370 PFORMAT_STRING pCArrayFormat;
4371 ULONG esize, bufsize;
4373 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4375 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4376 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4378 ERR("invalid format type %x\n", pCStructFormat->type);
4379 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4383 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4384 pCStructFormat->offset_to_array_description;
4385 if (*pCArrayFormat != RPC_FC_CARRAY)
4387 ERR("invalid array format type %x\n", pCStructFormat->type);
4388 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4391 esize = *(const WORD*)(pCArrayFormat+2);
4393 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4394 pCArrayFormat + 4, 0);
4396 WriteConformance(pStubMsg);
4398 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4400 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4402 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4403 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4405 ERR("integer overflow of memory_size %u with bufsize %u\n",
4406 pCStructFormat->memory_size, bufsize);
4407 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4409 /* copy constant sized part of struct */
4410 pStubMsg->BufferMark = pStubMsg->Buffer;
4411 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4413 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4414 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4419 /***********************************************************************
4420 * NdrConformantStructUnmarshall [RPCRT4.@]
4422 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4423 unsigned char **ppMemory,
4424 PFORMAT_STRING pFormat,
4425 unsigned char fMustAlloc)
4427 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4428 PFORMAT_STRING pCArrayFormat;
4429 ULONG esize, bufsize;
4430 unsigned char *saved_buffer;
4432 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4434 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4435 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4437 ERR("invalid format type %x\n", pCStructFormat->type);
4438 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4441 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4442 pCStructFormat->offset_to_array_description;
4443 if (*pCArrayFormat != RPC_FC_CARRAY)
4445 ERR("invalid array format type %x\n", pCStructFormat->type);
4446 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4449 esize = *(const WORD*)(pCArrayFormat+2);
4451 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4453 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4455 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4457 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4458 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4460 ERR("integer overflow of memory_size %u with bufsize %u\n",
4461 pCStructFormat->memory_size, bufsize);
4462 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4467 SIZE_T size = pCStructFormat->memory_size + bufsize;
4468 *ppMemory = NdrAllocate(pStubMsg, size);
4472 if (!pStubMsg->IsClient && !*ppMemory)
4473 /* for servers, we just point straight into the RPC buffer */
4474 *ppMemory = pStubMsg->Buffer;
4477 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4478 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4479 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4480 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4482 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4483 if (*ppMemory != saved_buffer)
4484 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4489 /***********************************************************************
4490 * NdrConformantStructBufferSize [RPCRT4.@]
4492 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4493 unsigned char *pMemory,
4494 PFORMAT_STRING pFormat)
4496 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4497 PFORMAT_STRING pCArrayFormat;
4500 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4502 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4503 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4505 ERR("invalid format type %x\n", pCStructFormat->type);
4506 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4509 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4510 pCStructFormat->offset_to_array_description;
4511 if (*pCArrayFormat != RPC_FC_CARRAY)
4513 ERR("invalid array format type %x\n", pCStructFormat->type);
4514 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4517 esize = *(const WORD*)(pCArrayFormat+2);
4519 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4520 SizeConformance(pStubMsg);
4522 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4524 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4526 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4527 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4529 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4530 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4533 /***********************************************************************
4534 * NdrConformantStructMemorySize [RPCRT4.@]
4536 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4537 PFORMAT_STRING pFormat)
4543 /***********************************************************************
4544 * NdrConformantStructFree [RPCRT4.@]
4546 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4547 unsigned char *pMemory,
4548 PFORMAT_STRING pFormat)
4550 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4551 PFORMAT_STRING pCArrayFormat;
4553 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4555 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4556 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4558 ERR("invalid format type %x\n", pCStructFormat->type);
4559 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4563 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4564 pCStructFormat->offset_to_array_description;
4565 if (*pCArrayFormat != RPC_FC_CARRAY)
4567 ERR("invalid array format type %x\n", pCStructFormat->type);
4568 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4572 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4573 pCArrayFormat + 4, 0);
4575 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4577 /* copy constant sized part of struct */
4578 pStubMsg->BufferMark = pStubMsg->Buffer;
4580 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4581 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4584 /***********************************************************************
4585 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4587 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4588 unsigned char *pMemory,
4589 PFORMAT_STRING pFormat)
4591 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4592 PFORMAT_STRING pCVArrayFormat;
4594 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4596 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4597 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4599 ERR("invalid format type %x\n", pCVStructFormat->type);
4600 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4604 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4605 pCVStructFormat->offset_to_array_description;
4607 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4608 pMemory + pCVStructFormat->memory_size,
4611 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4613 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4615 /* write constant sized part */
4616 pStubMsg->BufferMark = pStubMsg->Buffer;
4617 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4619 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4620 pMemory + pCVStructFormat->memory_size,
4621 pCVArrayFormat, FALSE /* fHasPointers */);
4623 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4628 /***********************************************************************
4629 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4631 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4632 unsigned char **ppMemory,
4633 PFORMAT_STRING pFormat,
4634 unsigned char fMustAlloc)
4636 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4637 PFORMAT_STRING pCVArrayFormat;
4638 ULONG memsize, bufsize;
4639 unsigned char *saved_buffer, *saved_array_buffer;
4641 unsigned char *array_memory;
4643 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4645 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4646 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4648 ERR("invalid format type %x\n", pCVStructFormat->type);
4649 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4653 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4654 pCVStructFormat->offset_to_array_description;
4656 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4659 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4661 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4663 /* work out how much memory to allocate if we need to do so */
4664 if (!*ppMemory || fMustAlloc)
4666 SIZE_T size = pCVStructFormat->memory_size + memsize;
4667 *ppMemory = NdrAllocate(pStubMsg, size);
4670 /* mark the start of the constant data */
4671 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4672 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4674 array_memory = *ppMemory + pCVStructFormat->memory_size;
4675 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
4676 &array_memory, pCVArrayFormat,
4677 FALSE /* fMustAlloc */,
4678 FALSE /* fUseServerBufferMemory */,
4679 FALSE /* fUnmarshall */);
4681 /* save offset in case unmarshalling pointers changes it */
4682 offset = pStubMsg->Offset;
4684 /* mark the start of the array data */
4685 saved_array_buffer = pStubMsg->Buffer;
4686 safe_buffer_increment(pStubMsg, bufsize);
4688 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4690 /* copy the constant data */
4691 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
4692 /* copy the array data */
4693 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
4694 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
4695 saved_array_buffer, bufsize);
4697 if (*pCVArrayFormat == RPC_FC_C_CSTRING)
4698 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
4699 else if (*pCVArrayFormat == RPC_FC_C_WSTRING)
4700 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
4705 /***********************************************************************
4706 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4708 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4709 unsigned char *pMemory,
4710 PFORMAT_STRING pFormat)
4712 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4713 PFORMAT_STRING pCVArrayFormat;
4715 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4717 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4718 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4720 ERR("invalid format type %x\n", pCVStructFormat->type);
4721 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4725 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4726 pCVStructFormat->offset_to_array_description;
4727 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
4728 pMemory + pCVStructFormat->memory_size,
4731 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4733 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4735 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4737 array_buffer_size(*pCVArrayFormat, pStubMsg,
4738 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4739 FALSE /* fHasPointers */);
4741 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4744 /***********************************************************************
4745 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4747 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4748 PFORMAT_STRING pFormat)
4750 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4751 PFORMAT_STRING pCVArrayFormat;
4753 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4755 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4756 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4758 ERR("invalid format type %x\n", pCVStructFormat->type);
4759 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4763 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4764 pCVStructFormat->offset_to_array_description;
4765 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
4767 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4769 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4771 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4772 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
4773 FALSE /* fHasPointers */);
4775 pStubMsg->MemorySize += pCVStructFormat->memory_size;
4777 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4779 return pStubMsg->MemorySize;
4782 /***********************************************************************
4783 * NdrConformantVaryingStructFree [RPCRT4.@]
4785 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4786 unsigned char *pMemory,
4787 PFORMAT_STRING pFormat)
4789 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4790 PFORMAT_STRING pCVArrayFormat;
4792 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4794 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4795 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4797 ERR("invalid format type %x\n", pCVStructFormat->type);
4798 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4802 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4803 pCVStructFormat->offset_to_array_description;
4804 array_free(*pCVArrayFormat, pStubMsg,
4805 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4806 FALSE /* fHasPointers */);
4808 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4810 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4813 #include "pshpack1.h"
4817 unsigned char alignment;
4818 unsigned short total_size;
4819 } NDR_SMFARRAY_FORMAT;
4824 unsigned char alignment;
4825 unsigned long total_size;
4826 } NDR_LGFARRAY_FORMAT;
4827 #include "poppack.h"
4829 /***********************************************************************
4830 * NdrFixedArrayMarshall [RPCRT4.@]
4832 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4833 unsigned char *pMemory,
4834 PFORMAT_STRING pFormat)
4836 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4837 unsigned long total_size;
4839 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4841 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4842 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4844 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4845 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4849 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4851 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4853 total_size = pSmFArrayFormat->total_size;
4854 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4858 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4859 total_size = pLgFArrayFormat->total_size;
4860 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4863 pStubMsg->BufferMark = pStubMsg->Buffer;
4864 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4866 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4871 /***********************************************************************
4872 * NdrFixedArrayUnmarshall [RPCRT4.@]
4874 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4875 unsigned char **ppMemory,
4876 PFORMAT_STRING pFormat,
4877 unsigned char fMustAlloc)
4879 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4880 unsigned long total_size;
4881 unsigned char *saved_buffer;
4883 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4885 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4886 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4888 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4889 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4893 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4895 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4897 total_size = pSmFArrayFormat->total_size;
4898 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4902 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4903 total_size = pLgFArrayFormat->total_size;
4904 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4908 *ppMemory = NdrAllocate(pStubMsg, total_size);
4911 if (!pStubMsg->IsClient && !*ppMemory)
4912 /* for servers, we just point straight into the RPC buffer */
4913 *ppMemory = pStubMsg->Buffer;
4916 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4917 safe_buffer_increment(pStubMsg, total_size);
4918 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4920 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4921 if (*ppMemory != saved_buffer)
4922 memcpy(*ppMemory, saved_buffer, total_size);
4927 /***********************************************************************
4928 * NdrFixedArrayBufferSize [RPCRT4.@]
4930 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4931 unsigned char *pMemory,
4932 PFORMAT_STRING pFormat)
4934 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4935 unsigned long total_size;
4937 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4939 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4940 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4942 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4943 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4947 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4949 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4951 total_size = pSmFArrayFormat->total_size;
4952 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4956 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4957 total_size = pLgFArrayFormat->total_size;
4958 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4960 safe_buffer_length_increment(pStubMsg, total_size);
4962 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4965 /***********************************************************************
4966 * NdrFixedArrayMemorySize [RPCRT4.@]
4968 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4969 PFORMAT_STRING pFormat)
4971 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4974 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4976 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4977 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4979 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4980 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4984 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4986 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4988 total_size = pSmFArrayFormat->total_size;
4989 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4993 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4994 total_size = pLgFArrayFormat->total_size;
4995 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4997 pStubMsg->BufferMark = pStubMsg->Buffer;
4998 safe_buffer_increment(pStubMsg, total_size);
4999 pStubMsg->MemorySize += total_size;
5001 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5006 /***********************************************************************
5007 * NdrFixedArrayFree [RPCRT4.@]
5009 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5010 unsigned char *pMemory,
5011 PFORMAT_STRING pFormat)
5013 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5015 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5017 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5018 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5020 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5021 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5025 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5026 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5029 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5030 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5033 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5036 /***********************************************************************
5037 * NdrVaryingArrayMarshall [RPCRT4.@]
5039 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5040 unsigned char *pMemory,
5041 PFORMAT_STRING pFormat)
5043 unsigned char alignment;
5044 DWORD elements, esize;
5047 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5049 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5050 (pFormat[0] != RPC_FC_LGVARRAY))
5052 ERR("invalid format type %x\n", pFormat[0]);
5053 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5057 alignment = pFormat[1] + 1;
5059 if (pFormat[0] == RPC_FC_SMVARRAY)
5062 pFormat += sizeof(WORD);
5063 elements = *(const WORD*)pFormat;
5064 pFormat += sizeof(WORD);
5069 pFormat += sizeof(DWORD);
5070 elements = *(const DWORD*)pFormat;
5071 pFormat += sizeof(DWORD);
5074 esize = *(const WORD*)pFormat;
5075 pFormat += sizeof(WORD);
5077 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5078 if ((pStubMsg->ActualCount > elements) ||
5079 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5081 RpcRaiseException(RPC_S_INVALID_BOUND);
5085 WriteVariance(pStubMsg);
5087 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
5089 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5090 pStubMsg->BufferMark = pStubMsg->Buffer;
5091 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5093 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5098 /***********************************************************************
5099 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5101 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5102 unsigned char **ppMemory,
5103 PFORMAT_STRING pFormat,
5104 unsigned char fMustAlloc)
5106 unsigned char alignment;
5107 DWORD size, elements, esize;
5109 unsigned char *saved_buffer;
5112 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5114 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5115 (pFormat[0] != RPC_FC_LGVARRAY))
5117 ERR("invalid format type %x\n", pFormat[0]);
5118 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5122 alignment = pFormat[1] + 1;
5124 if (pFormat[0] == RPC_FC_SMVARRAY)
5127 size = *(const WORD*)pFormat;
5128 pFormat += sizeof(WORD);
5129 elements = *(const WORD*)pFormat;
5130 pFormat += sizeof(WORD);
5135 size = *(const DWORD*)pFormat;
5136 pFormat += sizeof(DWORD);
5137 elements = *(const DWORD*)pFormat;
5138 pFormat += sizeof(DWORD);
5141 esize = *(const WORD*)pFormat;
5142 pFormat += sizeof(WORD);
5144 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5146 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5148 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5149 offset = pStubMsg->Offset;
5151 if (!*ppMemory || fMustAlloc)
5152 *ppMemory = NdrAllocate(pStubMsg, size);
5153 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5154 safe_buffer_increment(pStubMsg, bufsize);
5156 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5158 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5163 /***********************************************************************
5164 * NdrVaryingArrayBufferSize [RPCRT4.@]
5166 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5167 unsigned char *pMemory,
5168 PFORMAT_STRING pFormat)
5170 unsigned char alignment;
5171 DWORD elements, esize;
5173 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5175 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5176 (pFormat[0] != RPC_FC_LGVARRAY))
5178 ERR("invalid format type %x\n", pFormat[0]);
5179 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5183 alignment = pFormat[1] + 1;
5185 if (pFormat[0] == RPC_FC_SMVARRAY)
5188 pFormat += sizeof(WORD);
5189 elements = *(const WORD*)pFormat;
5190 pFormat += sizeof(WORD);
5195 pFormat += sizeof(DWORD);
5196 elements = *(const DWORD*)pFormat;
5197 pFormat += sizeof(DWORD);
5200 esize = *(const WORD*)pFormat;
5201 pFormat += sizeof(WORD);
5203 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5204 if ((pStubMsg->ActualCount > elements) ||
5205 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5207 RpcRaiseException(RPC_S_INVALID_BOUND);
5211 SizeVariance(pStubMsg);
5213 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
5215 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5217 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5220 /***********************************************************************
5221 * NdrVaryingArrayMemorySize [RPCRT4.@]
5223 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5224 PFORMAT_STRING pFormat)
5226 unsigned char alignment;
5227 DWORD size, elements, esize;
5229 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5231 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5232 (pFormat[0] != RPC_FC_LGVARRAY))
5234 ERR("invalid format type %x\n", pFormat[0]);
5235 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5239 alignment = pFormat[1] + 1;
5241 if (pFormat[0] == RPC_FC_SMVARRAY)
5244 size = *(const WORD*)pFormat;
5245 pFormat += sizeof(WORD);
5246 elements = *(const WORD*)pFormat;
5247 pFormat += sizeof(WORD);
5252 size = *(const DWORD*)pFormat;
5253 pFormat += sizeof(DWORD);
5254 elements = *(const DWORD*)pFormat;
5255 pFormat += sizeof(DWORD);
5258 esize = *(const WORD*)pFormat;
5259 pFormat += sizeof(WORD);
5261 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5263 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5265 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5266 pStubMsg->MemorySize += size;
5268 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5270 return pStubMsg->MemorySize;
5273 /***********************************************************************
5274 * NdrVaryingArrayFree [RPCRT4.@]
5276 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5277 unsigned char *pMemory,
5278 PFORMAT_STRING pFormat)
5282 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5284 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5285 (pFormat[0] != RPC_FC_LGVARRAY))
5287 ERR("invalid format type %x\n", pFormat[0]);
5288 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5292 if (pFormat[0] == RPC_FC_SMVARRAY)
5295 pFormat += sizeof(WORD);
5296 elements = *(const WORD*)pFormat;
5297 pFormat += sizeof(WORD);
5302 pFormat += sizeof(DWORD);
5303 elements = *(const DWORD*)pFormat;
5304 pFormat += sizeof(DWORD);
5307 pFormat += sizeof(WORD);
5309 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5310 if ((pStubMsg->ActualCount > elements) ||
5311 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5313 RpcRaiseException(RPC_S_INVALID_BOUND);
5317 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5320 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5333 return *(const USHORT *)pMemory;
5337 return *(const ULONG *)pMemory;
5339 FIXME("Unhandled base type: 0x%02x\n", fc);
5344 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5345 unsigned long discriminant,
5346 PFORMAT_STRING pFormat)
5348 unsigned short num_arms, arm, type;
5350 num_arms = *(const SHORT*)pFormat & 0x0fff;
5352 for(arm = 0; arm < num_arms; arm++)
5354 if(discriminant == *(const ULONG*)pFormat)
5362 type = *(const unsigned short*)pFormat;
5363 TRACE("type %04x\n", type);
5364 if(arm == num_arms) /* default arm extras */
5368 ERR("no arm for 0x%lx and no default case\n", discriminant);
5369 RpcRaiseException(RPC_S_INVALID_TAG);
5374 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
5381 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5383 unsigned short type;
5387 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5391 type = *(const unsigned short*)pFormat;
5392 if((type & 0xff00) == 0x8000)
5394 unsigned char basetype = LOBYTE(type);
5395 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5399 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5400 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5403 unsigned char *saved_buffer = NULL;
5404 int pointer_buffer_mark_set = 0;
5411 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5412 saved_buffer = pStubMsg->Buffer;
5413 if (pStubMsg->PointerBufferMark)
5415 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5416 pStubMsg->PointerBufferMark = NULL;
5417 pointer_buffer_mark_set = 1;
5420 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5422 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5423 if (pointer_buffer_mark_set)
5425 STD_OVERFLOW_CHECK(pStubMsg);
5426 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5427 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5429 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5430 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5431 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5433 pStubMsg->Buffer = saved_buffer + 4;
5437 m(pStubMsg, pMemory, desc);
5440 else FIXME("no marshaller for embedded type %02x\n", *desc);
5445 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5446 unsigned char **ppMemory,
5448 PFORMAT_STRING pFormat,
5449 unsigned char fMustAlloc)
5451 unsigned short type;
5455 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5459 type = *(const unsigned short*)pFormat;
5460 if((type & 0xff00) == 0x8000)
5462 unsigned char basetype = LOBYTE(type);
5463 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5467 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5468 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5471 unsigned char *saved_buffer = NULL;
5472 int pointer_buffer_mark_set = 0;
5479 **(void***)ppMemory = NULL;
5480 ALIGN_POINTER(pStubMsg->Buffer, 4);
5481 saved_buffer = pStubMsg->Buffer;
5482 if (pStubMsg->PointerBufferMark)
5484 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5485 pStubMsg->PointerBufferMark = NULL;
5486 pointer_buffer_mark_set = 1;
5489 pStubMsg->Buffer += 4; /* for pointer ID */
5491 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5493 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5494 saved_buffer, pStubMsg->BufferEnd);
5495 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5498 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5499 if (pointer_buffer_mark_set)
5501 STD_OVERFLOW_CHECK(pStubMsg);
5502 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5503 pStubMsg->Buffer = saved_buffer + 4;
5507 m(pStubMsg, ppMemory, desc, fMustAlloc);
5510 else FIXME("no marshaller for embedded type %02x\n", *desc);
5515 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5516 unsigned char *pMemory,
5518 PFORMAT_STRING pFormat)
5520 unsigned short type;
5524 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5528 type = *(const unsigned short*)pFormat;
5529 if((type & 0xff00) == 0x8000)
5531 unsigned char basetype = LOBYTE(type);
5532 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5536 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5537 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5546 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5547 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5548 if (!pStubMsg->IgnoreEmbeddedPointers)
5550 int saved_buffer_length = pStubMsg->BufferLength;
5551 pStubMsg->BufferLength = pStubMsg->PointerLength;
5552 pStubMsg->PointerLength = 0;
5553 if(!pStubMsg->BufferLength)
5554 ERR("BufferLength == 0??\n");
5555 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5556 pStubMsg->PointerLength = pStubMsg->BufferLength;
5557 pStubMsg->BufferLength = saved_buffer_length;
5561 m(pStubMsg, pMemory, desc);
5564 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5568 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5570 PFORMAT_STRING pFormat)
5572 unsigned short type, size;
5574 size = *(const unsigned short*)pFormat;
5575 pStubMsg->Memory += size;
5578 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5582 type = *(const unsigned short*)pFormat;
5583 if((type & 0xff00) == 0x8000)
5585 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5589 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5590 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5591 unsigned char *saved_buffer;
5600 ALIGN_POINTER(pStubMsg->Buffer, 4);
5601 saved_buffer = pStubMsg->Buffer;
5602 safe_buffer_increment(pStubMsg, 4);
5603 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
5604 pStubMsg->MemorySize += 4;
5605 if (!pStubMsg->IgnoreEmbeddedPointers)
5606 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5609 return m(pStubMsg, desc);
5612 else FIXME("no marshaller for embedded type %02x\n", *desc);
5615 TRACE("size %d\n", size);
5619 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5620 unsigned char *pMemory,
5622 PFORMAT_STRING pFormat)
5624 unsigned short type;
5628 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5632 type = *(const unsigned short*)pFormat;
5633 if((type & 0xff00) != 0x8000)
5635 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5636 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5645 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5648 m(pStubMsg, pMemory, desc);
5654 /***********************************************************************
5655 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5657 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5658 unsigned char *pMemory,
5659 PFORMAT_STRING pFormat)
5661 unsigned char switch_type;
5662 unsigned char increment;
5665 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5668 switch_type = *pFormat & 0xf;
5669 increment = (*pFormat & 0xf0) >> 4;
5672 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5674 switch_value = get_discriminant(switch_type, pMemory);
5675 TRACE("got switch value 0x%x\n", switch_value);
5677 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5678 pMemory += increment;
5680 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5683 /***********************************************************************
5684 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5686 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5687 unsigned char **ppMemory,
5688 PFORMAT_STRING pFormat,
5689 unsigned char fMustAlloc)
5691 unsigned char switch_type;
5692 unsigned char increment;
5694 unsigned short size;
5695 unsigned char *pMemoryArm;
5697 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5700 switch_type = *pFormat & 0xf;
5701 increment = (*pFormat & 0xf0) >> 4;
5704 ALIGN_POINTER(pStubMsg->Buffer, increment);
5705 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5706 TRACE("got switch value 0x%x\n", switch_value);
5708 size = *(const unsigned short*)pFormat + increment;
5709 if(!*ppMemory || fMustAlloc)
5710 *ppMemory = NdrAllocate(pStubMsg, size);
5712 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5713 pMemoryArm = *ppMemory + increment;
5715 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
5718 /***********************************************************************
5719 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5721 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5722 unsigned char *pMemory,
5723 PFORMAT_STRING pFormat)
5725 unsigned char switch_type;
5726 unsigned char increment;
5729 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5732 switch_type = *pFormat & 0xf;
5733 increment = (*pFormat & 0xf0) >> 4;
5736 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5737 switch_value = get_discriminant(switch_type, pMemory);
5738 TRACE("got switch value 0x%x\n", switch_value);
5740 /* Add discriminant size */
5741 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5742 pMemory += increment;
5744 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5747 /***********************************************************************
5748 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5750 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5751 PFORMAT_STRING pFormat)
5753 unsigned char switch_type;
5754 unsigned char increment;
5757 switch_type = *pFormat & 0xf;
5758 increment = (*pFormat & 0xf0) >> 4;
5761 ALIGN_POINTER(pStubMsg->Buffer, increment);
5762 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5763 TRACE("got switch value 0x%x\n", switch_value);
5765 pStubMsg->Memory += increment;
5767 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5770 /***********************************************************************
5771 * NdrEncapsulatedUnionFree [RPCRT4.@]
5773 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5774 unsigned char *pMemory,
5775 PFORMAT_STRING pFormat)
5777 unsigned char switch_type;
5778 unsigned char increment;
5781 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5784 switch_type = *pFormat & 0xf;
5785 increment = (*pFormat & 0xf0) >> 4;
5788 switch_value = get_discriminant(switch_type, pMemory);
5789 TRACE("got switch value 0x%x\n", switch_value);
5791 pMemory += increment;
5793 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5796 /***********************************************************************
5797 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5799 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5800 unsigned char *pMemory,
5801 PFORMAT_STRING pFormat)
5803 unsigned char switch_type;
5805 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5808 switch_type = *pFormat;
5811 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5812 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5813 /* Marshall discriminant */
5814 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5816 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5819 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5820 PFORMAT_STRING *ppFormat)
5822 long discriminant = 0;
5832 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5841 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5842 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5850 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5851 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5856 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5860 if (pStubMsg->fHasNewCorrDesc)
5864 return discriminant;
5867 /**********************************************************************
5868 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5870 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5871 unsigned char **ppMemory,
5872 PFORMAT_STRING pFormat,
5873 unsigned char fMustAlloc)
5876 unsigned short size;
5878 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5881 /* Unmarshall discriminant */
5882 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5883 TRACE("unmarshalled discriminant %lx\n", discriminant);
5885 pFormat += *(const SHORT*)pFormat;
5887 size = *(const unsigned short*)pFormat;
5889 if(!*ppMemory || fMustAlloc)
5890 *ppMemory = NdrAllocate(pStubMsg, size);
5892 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5895 /***********************************************************************
5896 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5898 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5899 unsigned char *pMemory,
5900 PFORMAT_STRING pFormat)
5902 unsigned char switch_type;
5904 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5907 switch_type = *pFormat;
5910 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5911 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5912 /* Add discriminant size */
5913 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5915 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5918 /***********************************************************************
5919 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5921 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5922 PFORMAT_STRING pFormat)
5927 /* Unmarshall discriminant */
5928 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5929 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
5931 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
5934 /***********************************************************************
5935 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5937 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5938 unsigned char *pMemory,
5939 PFORMAT_STRING pFormat)
5941 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5945 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5946 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5948 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5951 /***********************************************************************
5952 * NdrByteCountPointerMarshall [RPCRT4.@]
5954 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5955 unsigned char *pMemory,
5956 PFORMAT_STRING pFormat)
5962 /***********************************************************************
5963 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5965 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5966 unsigned char **ppMemory,
5967 PFORMAT_STRING pFormat,
5968 unsigned char fMustAlloc)
5974 /***********************************************************************
5975 * NdrByteCountPointerBufferSize [RPCRT4.@]
5977 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5978 unsigned char *pMemory,
5979 PFORMAT_STRING pFormat)
5984 /***********************************************************************
5985 * NdrByteCountPointerMemorySize [RPCRT4.@]
5987 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5988 PFORMAT_STRING pFormat)
5994 /***********************************************************************
5995 * NdrByteCountPointerFree [RPCRT4.@]
5997 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
5998 unsigned char *pMemory,
5999 PFORMAT_STRING pFormat)
6004 /***********************************************************************
6005 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6007 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6008 unsigned char *pMemory,
6009 PFORMAT_STRING pFormat)
6015 /***********************************************************************
6016 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6018 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6019 unsigned char **ppMemory,
6020 PFORMAT_STRING pFormat,
6021 unsigned char fMustAlloc)
6027 /***********************************************************************
6028 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6030 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6031 unsigned char *pMemory,
6032 PFORMAT_STRING pFormat)
6037 /***********************************************************************
6038 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6040 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6041 PFORMAT_STRING pFormat)
6047 /***********************************************************************
6048 * NdrXmitOrRepAsFree [RPCRT4.@]
6050 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6051 unsigned char *pMemory,
6052 PFORMAT_STRING pFormat)
6057 /***********************************************************************
6058 * NdrRangeMarshall [internal]
6060 unsigned char *WINAPI NdrRangeMarshall(
6061 PMIDL_STUB_MESSAGE pStubMsg,
6062 unsigned char *pMemory,
6063 PFORMAT_STRING pFormat)
6065 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6066 unsigned char base_type;
6068 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6070 if (pRange->type != RPC_FC_RANGE)
6072 ERR("invalid format type %x\n", pRange->type);
6073 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6077 base_type = pRange->flags_type & 0xf;
6079 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6082 /***********************************************************************
6083 * NdrRangeUnmarshall
6085 unsigned char *WINAPI NdrRangeUnmarshall(
6086 PMIDL_STUB_MESSAGE pStubMsg,
6087 unsigned char **ppMemory,
6088 PFORMAT_STRING pFormat,
6089 unsigned char fMustAlloc)
6091 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6092 unsigned char base_type;
6094 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6096 if (pRange->type != RPC_FC_RANGE)
6098 ERR("invalid format type %x\n", pRange->type);
6099 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6102 base_type = pRange->flags_type & 0xf;
6104 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6105 base_type, pRange->low_value, pRange->high_value);
6107 #define RANGE_UNMARSHALL(type, format_spec) \
6110 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6111 if (fMustAlloc || !*ppMemory) \
6112 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6113 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
6115 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6116 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6117 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6119 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
6120 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
6122 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6123 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
6124 (type)pRange->high_value); \
6125 RpcRaiseException(RPC_S_INVALID_BOUND); \
6128 TRACE("*ppMemory: %p\n", *ppMemory); \
6129 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
6130 pStubMsg->Buffer += sizeof(type); \
6137 RANGE_UNMARSHALL(UCHAR, "%d");
6138 TRACE("value: 0x%02x\n", **ppMemory);
6142 RANGE_UNMARSHALL(CHAR, "%u");
6143 TRACE("value: 0x%02x\n", **ppMemory);
6145 case RPC_FC_WCHAR: /* FIXME: valid? */
6147 RANGE_UNMARSHALL(USHORT, "%u");
6148 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6151 RANGE_UNMARSHALL(SHORT, "%d");
6152 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6155 RANGE_UNMARSHALL(LONG, "%d");
6156 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6159 RANGE_UNMARSHALL(ULONG, "%u");
6160 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6164 FIXME("Unhandled enum type\n");
6166 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
6171 ERR("invalid range base type: 0x%02x\n", base_type);
6172 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6178 /***********************************************************************
6179 * NdrRangeBufferSize [internal]
6181 void WINAPI NdrRangeBufferSize(
6182 PMIDL_STUB_MESSAGE pStubMsg,
6183 unsigned char *pMemory,
6184 PFORMAT_STRING pFormat)
6186 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6187 unsigned char base_type;
6189 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6191 if (pRange->type != RPC_FC_RANGE)
6193 ERR("invalid format type %x\n", pRange->type);
6194 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6196 base_type = pRange->flags_type & 0xf;
6198 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6201 /***********************************************************************
6202 * NdrRangeMemorySize [internal]
6204 ULONG WINAPI NdrRangeMemorySize(
6205 PMIDL_STUB_MESSAGE pStubMsg,
6206 PFORMAT_STRING pFormat)
6208 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6209 unsigned char base_type;
6211 if (pRange->type != RPC_FC_RANGE)
6213 ERR("invalid format type %x\n", pRange->type);
6214 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6217 base_type = pRange->flags_type & 0xf;
6219 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6222 /***********************************************************************
6223 * NdrRangeFree [internal]
6225 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6226 unsigned char *pMemory,
6227 PFORMAT_STRING pFormat)
6229 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6234 /***********************************************************************
6235 * NdrBaseTypeMarshall [internal]
6237 static unsigned char *WINAPI NdrBaseTypeMarshall(
6238 PMIDL_STUB_MESSAGE pStubMsg,
6239 unsigned char *pMemory,
6240 PFORMAT_STRING pFormat)
6242 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6250 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6251 TRACE("value: 0x%02x\n", *pMemory);
6256 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6257 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6258 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6262 case RPC_FC_ERROR_STATUS_T:
6264 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
6265 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6266 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6269 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
6270 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6273 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
6274 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6277 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
6278 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6279 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6282 /* only 16-bits on the wire, so do a sanity check */
6283 if (*(UINT *)pMemory > SHRT_MAX)
6284 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6285 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6286 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6287 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6288 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
6289 pStubMsg->Buffer += sizeof(USHORT);
6290 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6295 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6298 /* FIXME: what is the correct return value? */
6302 /***********************************************************************
6303 * NdrBaseTypeUnmarshall [internal]
6305 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6306 PMIDL_STUB_MESSAGE pStubMsg,
6307 unsigned char **ppMemory,
6308 PFORMAT_STRING pFormat,
6309 unsigned char fMustAlloc)
6311 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6313 #define BASE_TYPE_UNMARSHALL(type) \
6314 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6315 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6317 *ppMemory = pStubMsg->Buffer; \
6318 TRACE("*ppMemory: %p\n", *ppMemory); \
6319 safe_buffer_increment(pStubMsg, sizeof(type)); \
6324 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6325 TRACE("*ppMemory: %p\n", *ppMemory); \
6326 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6335 BASE_TYPE_UNMARSHALL(UCHAR);
6336 TRACE("value: 0x%02x\n", **ppMemory);
6341 BASE_TYPE_UNMARSHALL(USHORT);
6342 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6346 case RPC_FC_ERROR_STATUS_T:
6348 BASE_TYPE_UNMARSHALL(ULONG);
6349 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6352 BASE_TYPE_UNMARSHALL(float);
6353 TRACE("value: %f\n", **(float **)ppMemory);
6356 BASE_TYPE_UNMARSHALL(double);
6357 TRACE("value: %f\n", **(double **)ppMemory);
6360 BASE_TYPE_UNMARSHALL(ULONGLONG);
6361 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6364 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6365 if (fMustAlloc || !*ppMemory)
6366 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6367 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
6368 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6369 TRACE("*ppMemory: %p\n", *ppMemory);
6370 /* 16-bits on the wire, but int in memory */
6371 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
6372 pStubMsg->Buffer += sizeof(USHORT);
6373 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6378 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6380 #undef BASE_TYPE_UNMARSHALL
6382 /* FIXME: what is the correct return value? */
6387 /***********************************************************************
6388 * NdrBaseTypeBufferSize [internal]
6390 static void WINAPI NdrBaseTypeBufferSize(
6391 PMIDL_STUB_MESSAGE pStubMsg,
6392 unsigned char *pMemory,
6393 PFORMAT_STRING pFormat)
6395 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6403 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6409 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
6410 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6415 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
6416 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6419 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
6420 safe_buffer_length_increment(pStubMsg, sizeof(float));
6423 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
6424 safe_buffer_length_increment(pStubMsg, sizeof(double));
6427 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
6428 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6430 case RPC_FC_ERROR_STATUS_T:
6431 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
6432 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6437 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6441 /***********************************************************************
6442 * NdrBaseTypeMemorySize [internal]
6444 static ULONG WINAPI NdrBaseTypeMemorySize(
6445 PMIDL_STUB_MESSAGE pStubMsg,
6446 PFORMAT_STRING pFormat)
6448 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6456 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6457 pStubMsg->MemorySize += sizeof(UCHAR);
6458 return sizeof(UCHAR);
6462 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6463 pStubMsg->MemorySize += sizeof(USHORT);
6464 return sizeof(USHORT);
6468 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6469 pStubMsg->MemorySize += sizeof(ULONG);
6470 return sizeof(ULONG);
6472 safe_buffer_increment(pStubMsg, sizeof(float));
6473 pStubMsg->MemorySize += sizeof(float);
6474 return sizeof(float);
6476 safe_buffer_increment(pStubMsg, sizeof(double));
6477 pStubMsg->MemorySize += sizeof(double);
6478 return sizeof(double);
6480 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6481 pStubMsg->MemorySize += sizeof(ULONGLONG);
6482 return sizeof(ULONGLONG);
6483 case RPC_FC_ERROR_STATUS_T:
6484 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6485 pStubMsg->MemorySize += sizeof(error_status_t);
6486 return sizeof(error_status_t);
6488 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6489 pStubMsg->MemorySize += sizeof(UINT);
6490 return sizeof(UINT);
6492 pStubMsg->MemorySize += sizeof(void *);
6493 return sizeof(void *);
6495 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6500 /***********************************************************************
6501 * NdrBaseTypeFree [internal]
6503 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6504 unsigned char *pMemory,
6505 PFORMAT_STRING pFormat)
6507 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6512 /***********************************************************************
6513 * NdrContextHandleBufferSize [internal]
6515 static void WINAPI NdrContextHandleBufferSize(
6516 PMIDL_STUB_MESSAGE pStubMsg,
6517 unsigned char *pMemory,
6518 PFORMAT_STRING pFormat)
6520 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6522 if (*pFormat != RPC_FC_BIND_CONTEXT)
6524 ERR("invalid format type %x\n", *pFormat);
6525 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6527 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
6528 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6531 /***********************************************************************
6532 * NdrContextHandleMarshall [internal]
6534 static unsigned char *WINAPI NdrContextHandleMarshall(
6535 PMIDL_STUB_MESSAGE pStubMsg,
6536 unsigned char *pMemory,
6537 PFORMAT_STRING pFormat)
6539 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6541 if (*pFormat != RPC_FC_BIND_CONTEXT)
6543 ERR("invalid format type %x\n", *pFormat);
6544 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6546 TRACE("flags: 0x%02x\n", pFormat[1]);
6548 if (pFormat[1] & 0x80)
6549 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6551 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
6556 /***********************************************************************
6557 * NdrContextHandleUnmarshall [internal]
6559 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6560 PMIDL_STUB_MESSAGE pStubMsg,
6561 unsigned char **ppMemory,
6562 PFORMAT_STRING pFormat,
6563 unsigned char fMustAlloc)
6565 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6566 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6568 if (*pFormat != RPC_FC_BIND_CONTEXT)
6570 ERR("invalid format type %x\n", *pFormat);
6571 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6573 TRACE("flags: 0x%02x\n", pFormat[1]);
6575 /* [out]-only or [ret] param */
6576 if ((pFormat[1] & 0x60) == 0x20)
6577 **(NDR_CCONTEXT **)ppMemory = NULL;
6578 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6583 /***********************************************************************
6584 * NdrClientContextMarshall [RPCRT4.@]
6586 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6587 NDR_CCONTEXT ContextHandle,
6590 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
6592 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
6594 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6596 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6597 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6598 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6601 /* FIXME: what does fCheck do? */
6602 NDRCContextMarshall(ContextHandle,
6605 pStubMsg->Buffer += cbNDRContext;
6608 /***********************************************************************
6609 * NdrClientContextUnmarshall [RPCRT4.@]
6611 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6612 NDR_CCONTEXT * pContextHandle,
6613 RPC_BINDING_HANDLE BindHandle)
6615 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
6617 ALIGN_POINTER(pStubMsg->Buffer, 4);
6619 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
6620 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6622 NDRCContextUnmarshall(pContextHandle,
6625 pStubMsg->RpcMsg->DataRepresentation);
6627 pStubMsg->Buffer += cbNDRContext;
6630 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6631 NDR_SCONTEXT ContextHandle,
6632 NDR_RUNDOWN RundownRoutine )
6634 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
6636 ALIGN_POINTER(pStubMsg->Buffer, 4);
6638 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6640 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6641 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6642 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6645 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6646 pStubMsg->Buffer, RundownRoutine, NULL,
6647 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6648 pStubMsg->Buffer += cbNDRContext;
6651 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6653 NDR_SCONTEXT ContextHandle;
6655 TRACE("(%p)\n", pStubMsg);
6657 ALIGN_POINTER(pStubMsg->Buffer, 4);
6659 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6661 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6662 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6663 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6666 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6668 pStubMsg->RpcMsg->DataRepresentation,
6669 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6670 pStubMsg->Buffer += cbNDRContext;
6672 return ContextHandle;
6675 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6676 unsigned char* pMemory,
6677 PFORMAT_STRING pFormat)
6679 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6682 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6683 PFORMAT_STRING pFormat)
6685 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6686 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6688 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6690 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6691 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6692 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6693 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6694 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6696 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6697 if_id = &sif->InterfaceId;
6700 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
6701 pStubMsg->RpcMsg->DataRepresentation, if_id,
6705 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6706 NDR_SCONTEXT ContextHandle,
6707 NDR_RUNDOWN RundownRoutine,
6708 PFORMAT_STRING pFormat)
6710 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6711 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6713 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6715 ALIGN_POINTER(pStubMsg->Buffer, 4);
6717 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6719 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6720 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6721 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6724 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6725 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6726 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6727 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6728 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6730 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6731 if_id = &sif->InterfaceId;
6734 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6735 pStubMsg->Buffer, RundownRoutine, if_id, flags);
6736 pStubMsg->Buffer += cbNDRContext;
6739 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6740 PFORMAT_STRING pFormat)
6742 NDR_SCONTEXT ContextHandle;
6743 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6744 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6746 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6748 ALIGN_POINTER(pStubMsg->Buffer, 4);
6750 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6752 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6753 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6754 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6757 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6758 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6759 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6760 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6761 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6763 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6764 if_id = &sif->InterfaceId;
6767 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6769 pStubMsg->RpcMsg->DataRepresentation,
6771 pStubMsg->Buffer += cbNDRContext;
6773 return ContextHandle;
6776 /***********************************************************************
6777 * NdrCorrelationInitialize [RPCRT4.@]
6779 * Initializes correlation validity checking.
6782 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6783 * pMemory [I] Pointer to memory to use as a cache.
6784 * CacheSize [I] Size of the memory pointed to by pMemory.
6785 * Flags [I] Reserved. Set to zero.
6790 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
6792 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
6793 pStubMsg->fHasNewCorrDesc = TRUE;
6796 /***********************************************************************
6797 * NdrCorrelationPass [RPCRT4.@]
6799 * Performs correlation validity checking.
6802 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6807 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
6809 FIXME("(%p): stub\n", pStubMsg);
6812 /***********************************************************************
6813 * NdrCorrelationFree [RPCRT4.@]
6815 * Frees any resources used while unmarshalling parameters that need
6816 * correlation validity checking.
6819 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6824 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
6826 FIXME("(%p): stub\n", pStubMsg);