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)))
63 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
65 MAKEWORD(*(pchar), *((pchar)+1)), \
66 MAKEWORD(*((pchar)+2), *((pchar)+3))))
69 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
70 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
71 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
72 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
73 *(pchar) = HIBYTE(HIWORD(uint32)))
75 #define BIG_ENDIAN_UINT32_READ(pchar) \
77 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
78 MAKEWORD(*((pchar)+1), *(pchar))))
80 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
81 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
82 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
83 # define NDR_LOCAL_UINT32_READ(pchar) \
84 BIG_ENDIAN_UINT32_READ(pchar)
86 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
87 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
88 # define NDR_LOCAL_UINT32_READ(pchar) \
89 LITTLE_ENDIAN_UINT32_READ(pchar)
92 /* _Align must be the desired alignment,
93 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
94 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
95 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
96 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
97 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
98 #define ALIGN_POINTER_CLEAR(_Ptr, _Align) \
100 memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \
101 ALIGN_POINTER(_Ptr, _Align); \
104 #define STD_OVERFLOW_CHECK(_Msg) do { \
105 TRACE("buffer=%d/%d\n", (ULONG)(_Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer), _Msg->BufferLength); \
106 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
107 ERR("buffer overflow %d bytes\n", (ULONG)(_Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength))); \
110 #define NDR_POINTER_ID_BASE 0x20000
111 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
112 #define NDR_TABLE_SIZE 128
113 #define NDR_TABLE_MASK 127
115 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
116 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
117 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
118 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
119 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
121 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
122 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
123 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
125 static unsigned char *WINAPI NdrRangeMarshall(PMIDL_STUB_MESSAGE,unsigned char *, PFORMAT_STRING);
126 static void WINAPI NdrRangeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
127 static ULONG WINAPI NdrRangeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
128 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
130 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
132 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
134 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
135 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
136 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
137 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
141 NdrPointerMarshall, NdrPointerMarshall,
142 NdrPointerMarshall, NdrPointerMarshall,
144 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
145 NdrConformantStructMarshall, NdrConformantStructMarshall,
146 NdrConformantVaryingStructMarshall,
147 NdrComplexStructMarshall,
149 NdrConformantArrayMarshall,
150 NdrConformantVaryingArrayMarshall,
151 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
152 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
153 NdrComplexArrayMarshall,
155 NdrConformantStringMarshall, 0, 0,
156 NdrConformantStringMarshall,
157 NdrNonConformantStringMarshall, 0, 0, 0,
159 NdrEncapsulatedUnionMarshall,
160 NdrNonEncapsulatedUnionMarshall,
161 NdrByteCountPointerMarshall,
162 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
164 NdrInterfacePointerMarshall,
166 NdrContextHandleMarshall,
169 NdrUserMarshalMarshall,
174 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
176 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
177 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
178 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
179 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
181 NdrBaseTypeUnmarshall,
183 NdrPointerUnmarshall, NdrPointerUnmarshall,
184 NdrPointerUnmarshall, NdrPointerUnmarshall,
186 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
187 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
188 NdrConformantVaryingStructUnmarshall,
189 NdrComplexStructUnmarshall,
191 NdrConformantArrayUnmarshall,
192 NdrConformantVaryingArrayUnmarshall,
193 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
194 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
195 NdrComplexArrayUnmarshall,
197 NdrConformantStringUnmarshall, 0, 0,
198 NdrConformantStringUnmarshall,
199 NdrNonConformantStringUnmarshall, 0, 0, 0,
201 NdrEncapsulatedUnionUnmarshall,
202 NdrNonEncapsulatedUnionUnmarshall,
203 NdrByteCountPointerUnmarshall,
204 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
206 NdrInterfacePointerUnmarshall,
208 NdrContextHandleUnmarshall,
211 NdrUserMarshalUnmarshall,
216 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
218 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
219 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
220 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
221 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
223 NdrBaseTypeBufferSize,
225 NdrPointerBufferSize, NdrPointerBufferSize,
226 NdrPointerBufferSize, NdrPointerBufferSize,
228 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
229 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
230 NdrConformantVaryingStructBufferSize,
231 NdrComplexStructBufferSize,
233 NdrConformantArrayBufferSize,
234 NdrConformantVaryingArrayBufferSize,
235 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
236 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
237 NdrComplexArrayBufferSize,
239 NdrConformantStringBufferSize, 0, 0,
240 NdrConformantStringBufferSize,
241 NdrNonConformantStringBufferSize, 0, 0, 0,
243 NdrEncapsulatedUnionBufferSize,
244 NdrNonEncapsulatedUnionBufferSize,
245 NdrByteCountPointerBufferSize,
246 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
248 NdrInterfacePointerBufferSize,
250 NdrContextHandleBufferSize,
253 NdrUserMarshalBufferSize,
258 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
260 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
261 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
262 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
263 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
265 NdrBaseTypeMemorySize,
267 NdrPointerMemorySize, NdrPointerMemorySize,
268 NdrPointerMemorySize, NdrPointerMemorySize,
270 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
271 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
272 NdrConformantVaryingStructMemorySize,
273 NdrComplexStructMemorySize,
275 NdrConformantArrayMemorySize,
276 NdrConformantVaryingArrayMemorySize,
277 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
278 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
279 NdrComplexArrayMemorySize,
281 NdrConformantStringMemorySize, 0, 0,
282 NdrConformantStringMemorySize,
283 NdrNonConformantStringMemorySize, 0, 0, 0,
285 NdrEncapsulatedUnionMemorySize,
286 NdrNonEncapsulatedUnionMemorySize,
287 NdrByteCountPointerMemorySize,
288 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
290 NdrInterfacePointerMemorySize,
295 NdrUserMarshalMemorySize,
300 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
302 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
303 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
304 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
305 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
309 NdrPointerFree, NdrPointerFree,
310 NdrPointerFree, NdrPointerFree,
312 NdrSimpleStructFree, NdrSimpleStructFree,
313 NdrConformantStructFree, NdrConformantStructFree,
314 NdrConformantVaryingStructFree,
315 NdrComplexStructFree,
317 NdrConformantArrayFree,
318 NdrConformantVaryingArrayFree,
319 NdrFixedArrayFree, NdrFixedArrayFree,
320 NdrVaryingArrayFree, NdrVaryingArrayFree,
326 NdrEncapsulatedUnionFree,
327 NdrNonEncapsulatedUnionFree,
329 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
331 NdrInterfacePointerFree,
342 typedef struct _NDR_MEMORY_LIST
347 struct _NDR_MEMORY_LIST *next;
350 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
352 /***********************************************************************
353 * NdrAllocate [RPCRT4.@]
355 * Allocates a block of memory using pStubMsg->pfnAllocate.
358 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
359 * len [I] Size of memory block to allocate.
362 * The memory block of size len that was allocated.
365 * The memory block is always 8-byte aligned.
366 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
367 * exception is raised.
369 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, SIZE_T len)
374 NDR_MEMORY_LIST *mem_list;
376 aligned_len = ALIGNED_LENGTH(len, 8);
377 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
378 /* check for overflow */
379 if (adjusted_len < len)
381 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len, len);
382 RpcRaiseException(RPC_X_BAD_STUB_DATA);
385 p = pStubMsg->pfnAllocate(adjusted_len);
386 if (!p) RpcRaiseException(ERROR_OUTOFMEMORY);
388 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
389 mem_list->magic = MEML_MAGIC;
390 mem_list->size = aligned_len;
391 mem_list->reserved = 0;
392 mem_list->next = pStubMsg->pMemoryList;
393 pStubMsg->pMemoryList = mem_list;
399 static void NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
401 TRACE("(%p, %p)\n", pStubMsg, Pointer);
403 pStubMsg->pfnFree(Pointer);
406 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
408 return (*(const ULONG *)pFormat != -1);
411 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
413 ALIGN_POINTER(pStubMsg->Buffer, 4);
414 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
415 RpcRaiseException(RPC_X_BAD_STUB_DATA);
416 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
417 pStubMsg->Buffer += 4;
418 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
419 if (pStubMsg->fHasNewCorrDesc)
425 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
427 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
429 pStubMsg->Offset = 0;
430 pStubMsg->ActualCount = pStubMsg->MaxCount;
434 ALIGN_POINTER(pStubMsg->Buffer, 4);
435 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
436 RpcRaiseException(RPC_X_BAD_STUB_DATA);
437 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
438 pStubMsg->Buffer += 4;
439 TRACE("offset is %d\n", pStubMsg->Offset);
440 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
441 pStubMsg->Buffer += 4;
442 TRACE("variance is %d\n", pStubMsg->ActualCount);
444 if ((pStubMsg->ActualCount > MaxValue) ||
445 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
447 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
448 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
449 RpcRaiseException(RPC_S_INVALID_BOUND);
454 if (pStubMsg->fHasNewCorrDesc)
460 /* writes the conformance value to the buffer */
461 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
463 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
464 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
465 RpcRaiseException(RPC_X_BAD_STUB_DATA);
466 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
467 pStubMsg->Buffer += 4;
470 /* writes the variance values to the buffer */
471 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
473 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
474 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
475 RpcRaiseException(RPC_X_BAD_STUB_DATA);
476 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
477 pStubMsg->Buffer += 4;
478 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
479 pStubMsg->Buffer += 4;
482 /* requests buffer space for the conformance value */
483 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
485 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
486 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
487 RpcRaiseException(RPC_X_BAD_STUB_DATA);
488 pStubMsg->BufferLength += 4;
491 /* requests buffer space for the variance values */
492 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
494 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
495 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
496 RpcRaiseException(RPC_X_BAD_STUB_DATA);
497 pStubMsg->BufferLength += 8;
500 PFORMAT_STRING ComputeConformanceOrVariance(
501 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
502 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
504 BYTE dtype = pFormat[0] & 0xf;
505 short ofs = *(const short *)&pFormat[2];
509 if (!IsConformanceOrVariancePresent(pFormat)) {
510 /* null descriptor */
515 switch (pFormat[0] & 0xf0) {
516 case RPC_FC_NORMAL_CONFORMANCE:
517 TRACE("normal conformance, ofs=%d\n", ofs);
520 case RPC_FC_POINTER_CONFORMANCE:
521 TRACE("pointer conformance, ofs=%d\n", ofs);
522 ptr = pStubMsg->Memory;
524 case RPC_FC_TOP_LEVEL_CONFORMANCE:
525 TRACE("toplevel conformance, ofs=%d\n", ofs);
526 if (pStubMsg->StackTop) {
527 ptr = pStubMsg->StackTop;
530 /* -Os mode, *pCount is already set */
534 case RPC_FC_CONSTANT_CONFORMANCE:
535 data = ofs | ((DWORD)pFormat[1] << 16);
536 TRACE("constant conformance, val=%d\n", data);
539 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
540 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
541 if (pStubMsg->StackTop) {
542 ptr = pStubMsg->StackTop;
550 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
553 switch (pFormat[1]) {
554 case RPC_FC_DEREFERENCE:
555 ptr = *(LPVOID*)((char *)ptr + ofs);
557 case RPC_FC_CALLBACK:
559 unsigned char *old_stack_top = pStubMsg->StackTop;
560 pStubMsg->StackTop = ptr;
562 /* ofs is index into StubDesc->apfnExprEval */
563 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
564 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
566 pStubMsg->StackTop = old_stack_top;
568 /* the callback function always stores the computed value in MaxCount */
569 *pCount = pStubMsg->MaxCount;
573 ptr = (char *)ptr + ofs;
586 data = *(USHORT*)ptr;
597 FIXME("unknown conformance data type %x\n", dtype);
600 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
603 switch (pFormat[1]) {
604 case RPC_FC_DEREFERENCE: /* already handled */
621 FIXME("unknown conformance op %d\n", pFormat[1]);
626 TRACE("resulting conformance is %ld\n", *pCount);
627 if (pStubMsg->fHasNewCorrDesc)
633 static inline PFORMAT_STRING SkipConformance(PMIDL_STUB_MESSAGE pStubMsg,
634 PFORMAT_STRING pFormat)
636 if (IsConformanceOrVariancePresent(pFormat))
638 if (pStubMsg->fHasNewCorrDesc)
646 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
647 * the result overflows 32-bits */
648 static inline ULONG safe_multiply(ULONG a, ULONG b)
650 ULONGLONG ret = (ULONGLONG)a * b;
651 if (ret > 0xffffffff)
653 RpcRaiseException(RPC_S_INVALID_BOUND);
659 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
661 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
662 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
663 RpcRaiseException(RPC_X_BAD_STUB_DATA);
664 pStubMsg->Buffer += size;
667 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
669 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
671 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
672 pStubMsg->BufferLength, size);
673 RpcRaiseException(RPC_X_BAD_STUB_DATA);
675 pStubMsg->BufferLength += size;
678 /* copies data from the buffer, checking that there is enough data in the buffer
680 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
682 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
683 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
685 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
686 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
687 RpcRaiseException(RPC_X_BAD_STUB_DATA);
689 if (p == pStubMsg->Buffer)
690 ERR("pointer is the same as the buffer\n");
691 memcpy(p, pStubMsg->Buffer, size);
692 pStubMsg->Buffer += size;
695 /* copies data to the buffer, checking that there is enough space to do so */
696 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
698 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
699 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
701 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
702 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
704 RpcRaiseException(RPC_X_BAD_STUB_DATA);
706 memcpy(pStubMsg->Buffer, p, size);
707 pStubMsg->Buffer += size;
710 /* verify that string data sitting in the buffer is valid and safe to
712 static void validate_string_data(MIDL_STUB_MESSAGE *pStubMsg, ULONG bufsize, ULONG esize)
716 /* verify the buffer is safe to access */
717 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
718 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
720 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
721 pStubMsg->BufferEnd, pStubMsg->Buffer);
722 RpcRaiseException(RPC_X_BAD_STUB_DATA);
725 /* strings must always have null terminating bytes */
728 ERR("invalid string length of %d\n", bufsize / esize);
729 RpcRaiseException(RPC_S_INVALID_BOUND);
732 for (i = bufsize - esize; i < bufsize; i++)
733 if (pStubMsg->Buffer[i] != 0)
735 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
736 i, pStubMsg->Buffer[i]);
737 RpcRaiseException(RPC_S_INVALID_BOUND);
741 static inline void dump_pointer_attr(unsigned char attr)
743 if (attr & RPC_FC_P_ALLOCALLNODES)
744 TRACE(" RPC_FC_P_ALLOCALLNODES");
745 if (attr & RPC_FC_P_DONTFREE)
746 TRACE(" RPC_FC_P_DONTFREE");
747 if (attr & RPC_FC_P_ONSTACK)
748 TRACE(" RPC_FC_P_ONSTACK");
749 if (attr & RPC_FC_P_SIMPLEPOINTER)
750 TRACE(" RPC_FC_P_SIMPLEPOINTER");
751 if (attr & RPC_FC_P_DEREF)
752 TRACE(" RPC_FC_P_DEREF");
756 /***********************************************************************
757 * PointerMarshall [internal]
759 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
760 unsigned char *Buffer,
761 unsigned char *Pointer,
762 PFORMAT_STRING pFormat)
764 unsigned type = pFormat[0], attr = pFormat[1];
768 int pointer_needs_marshaling;
770 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
771 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
773 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
774 else desc = pFormat + *(const SHORT*)pFormat;
777 case RPC_FC_RP: /* ref pointer (always non-null) */
780 ERR("NULL ref pointer is not allowed\n");
781 RpcRaiseException(RPC_X_NULL_REF_POINTER);
783 pointer_needs_marshaling = 1;
785 case RPC_FC_UP: /* unique pointer */
786 case RPC_FC_OP: /* object pointer - same as unique here */
788 pointer_needs_marshaling = 1;
790 pointer_needs_marshaling = 0;
791 pointer_id = Pointer ? NDR_POINTER_ID(pStubMsg) : 0;
792 TRACE("writing 0x%08x to buffer\n", pointer_id);
793 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
796 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
797 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
798 TRACE("writing 0x%08x to buffer\n", pointer_id);
799 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
802 FIXME("unhandled ptr type=%02x\n", type);
803 RpcRaiseException(RPC_X_BAD_STUB_DATA);
807 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
809 if (pointer_needs_marshaling) {
810 if (attr & RPC_FC_P_DEREF) {
811 Pointer = *(unsigned char**)Pointer;
812 TRACE("deref => %p\n", Pointer);
814 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
815 if (m) m(pStubMsg, Pointer, desc);
816 else FIXME("no marshaller for data type=%02x\n", *desc);
819 STD_OVERFLOW_CHECK(pStubMsg);
822 /***********************************************************************
823 * PointerUnmarshall [internal]
825 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
826 unsigned char *Buffer,
827 unsigned char **pPointer,
828 unsigned char *pSrcPointer,
829 PFORMAT_STRING pFormat,
830 unsigned char fMustAlloc)
832 unsigned type = pFormat[0], attr = pFormat[1];
835 DWORD pointer_id = 0;
836 int pointer_needs_unmarshaling;
838 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
839 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
841 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
842 else desc = pFormat + *(const SHORT*)pFormat;
845 case RPC_FC_RP: /* ref pointer (always non-null) */
846 pointer_needs_unmarshaling = 1;
848 case RPC_FC_UP: /* unique pointer */
849 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
850 TRACE("pointer_id is 0x%08x\n", pointer_id);
852 pointer_needs_unmarshaling = 1;
855 pointer_needs_unmarshaling = 0;
858 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
859 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
860 TRACE("pointer_id is 0x%08x\n", pointer_id);
861 if (!fMustAlloc && pSrcPointer)
863 FIXME("free object pointer %p\n", pSrcPointer);
867 pointer_needs_unmarshaling = 1;
871 pointer_needs_unmarshaling = 0;
875 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
876 TRACE("pointer_id is 0x%08x\n", pointer_id);
877 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
878 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
881 FIXME("unhandled ptr type=%02x\n", type);
882 RpcRaiseException(RPC_X_BAD_STUB_DATA);
886 if (pointer_needs_unmarshaling) {
887 unsigned char *base_ptr_val = *pPointer;
888 unsigned char **current_ptr = pPointer;
889 if (pStubMsg->IsClient) {
891 /* if we aren't forcing allocation of memory then try to use the existing
892 * (source) pointer to unmarshall the data into so that [in,out]
893 * parameters behave correctly. it doesn't matter if the parameter is
894 * [out] only since in that case the pointer will be NULL. we force
895 * allocation when the source pointer is NULL here instead of in the type
896 * unmarshalling routine for the benefit of the deref code below */
899 TRACE("setting *pPointer to %p\n", pSrcPointer);
900 *pPointer = base_ptr_val = pSrcPointer;
906 /* the memory in a stub is never initialised, so we have to work out here
907 * whether we have to initialise it so we can use the optimisation of
908 * setting the pointer to the buffer, if possible, or set fMustAlloc to
910 if (attr & RPC_FC_P_DEREF) {
918 if (attr & RPC_FC_P_ALLOCALLNODES)
919 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
921 if (attr & RPC_FC_P_DEREF) {
923 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
924 *pPointer = base_ptr_val;
925 current_ptr = (unsigned char **)base_ptr_val;
927 current_ptr = *(unsigned char***)current_ptr;
928 TRACE("deref => %p\n", current_ptr);
929 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
931 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
932 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
933 else FIXME("no unmarshaller for data type=%02x\n", *desc);
935 if (type == RPC_FC_FP)
936 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
940 TRACE("pointer=%p\n", *pPointer);
943 /***********************************************************************
944 * PointerBufferSize [internal]
946 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
947 unsigned char *Pointer,
948 PFORMAT_STRING pFormat)
950 unsigned type = pFormat[0], attr = pFormat[1];
953 int pointer_needs_sizing;
956 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
957 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
959 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
960 else desc = pFormat + *(const SHORT*)pFormat;
963 case RPC_FC_RP: /* ref pointer (always non-null) */
966 ERR("NULL ref pointer is not allowed\n");
967 RpcRaiseException(RPC_X_NULL_REF_POINTER);
972 /* NULL pointer has no further representation */
977 pointer_needs_sizing = !NdrFullPointerQueryPointer(
978 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
979 if (!pointer_needs_sizing)
983 FIXME("unhandled ptr type=%02x\n", type);
984 RpcRaiseException(RPC_X_BAD_STUB_DATA);
988 if (attr & RPC_FC_P_DEREF) {
989 Pointer = *(unsigned char**)Pointer;
990 TRACE("deref => %p\n", Pointer);
993 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
994 if (m) m(pStubMsg, Pointer, desc);
995 else FIXME("no buffersizer for data type=%02x\n", *desc);
998 /***********************************************************************
999 * PointerMemorySize [internal]
1001 static ULONG PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1002 unsigned char *Buffer, PFORMAT_STRING pFormat)
1004 unsigned type = pFormat[0], attr = pFormat[1];
1005 PFORMAT_STRING desc;
1007 DWORD pointer_id = 0;
1008 int pointer_needs_sizing;
1010 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1011 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1013 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1014 else desc = pFormat + *(const SHORT*)pFormat;
1017 case RPC_FC_RP: /* ref pointer (always non-null) */
1018 pointer_needs_sizing = 1;
1020 case RPC_FC_UP: /* unique pointer */
1021 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1022 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1023 TRACE("pointer_id is 0x%08x\n", pointer_id);
1025 pointer_needs_sizing = 1;
1027 pointer_needs_sizing = 0;
1032 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1033 TRACE("pointer_id is 0x%08x\n", pointer_id);
1034 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1035 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1039 FIXME("unhandled ptr type=%02x\n", type);
1040 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1044 if (attr & RPC_FC_P_DEREF) {
1045 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(void*));
1046 pStubMsg->MemorySize += sizeof(void*);
1050 if (pointer_needs_sizing) {
1051 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1052 if (m) m(pStubMsg, desc);
1053 else FIXME("no memorysizer for data type=%02x\n", *desc);
1056 return pStubMsg->MemorySize;
1059 /***********************************************************************
1060 * PointerFree [internal]
1062 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1063 unsigned char *Pointer,
1064 PFORMAT_STRING pFormat)
1066 unsigned type = pFormat[0], attr = pFormat[1];
1067 PFORMAT_STRING desc;
1069 unsigned char *current_pointer = Pointer;
1071 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1072 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1073 if (attr & RPC_FC_P_DONTFREE) return;
1075 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1076 else desc = pFormat + *(const SHORT*)pFormat;
1078 if (!Pointer) return;
1080 if (type == RPC_FC_FP) {
1081 int pointer_needs_freeing = NdrFullPointerFree(
1082 pStubMsg->FullPtrXlatTables, Pointer);
1083 if (!pointer_needs_freeing)
1087 if (attr & RPC_FC_P_DEREF) {
1088 current_pointer = *(unsigned char**)Pointer;
1089 TRACE("deref => %p\n", current_pointer);
1092 m = NdrFreer[*desc & NDR_TABLE_MASK];
1093 if (m) m(pStubMsg, current_pointer, desc);
1095 /* this check stops us from trying to free buffer memory. we don't have to
1096 * worry about clients, since they won't call this function.
1097 * we don't have to check for the buffer being reallocated because
1098 * BufferStart and BufferEnd won't be reset when allocating memory for
1099 * sending the response. we don't have to check for the new buffer here as
1100 * it won't be used a type memory, only for buffer memory */
1101 if (Pointer >= pStubMsg->BufferStart && Pointer < pStubMsg->BufferEnd)
1104 if (attr & RPC_FC_P_ONSTACK) {
1105 TRACE("not freeing stack ptr %p\n", Pointer);
1108 TRACE("freeing %p\n", Pointer);
1109 NdrFree(pStubMsg, Pointer);
1112 TRACE("not freeing %p\n", Pointer);
1115 /***********************************************************************
1116 * EmbeddedPointerMarshall
1118 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1119 unsigned char *pMemory,
1120 PFORMAT_STRING pFormat)
1122 unsigned char *Mark = pStubMsg->BufferMark;
1123 unsigned rep, count, stride;
1125 unsigned char *saved_buffer = NULL;
1127 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1129 if (*pFormat != RPC_FC_PP) return NULL;
1132 if (pStubMsg->PointerBufferMark)
1134 saved_buffer = pStubMsg->Buffer;
1135 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1136 pStubMsg->PointerBufferMark = NULL;
1139 while (pFormat[0] != RPC_FC_END) {
1140 switch (pFormat[0]) {
1142 FIXME("unknown repeat type %d\n", pFormat[0]);
1143 case RPC_FC_NO_REPEAT:
1149 case RPC_FC_FIXED_REPEAT:
1150 rep = *(const WORD*)&pFormat[2];
1151 stride = *(const WORD*)&pFormat[4];
1152 count = *(const WORD*)&pFormat[8];
1155 case RPC_FC_VARIABLE_REPEAT:
1156 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1157 stride = *(const WORD*)&pFormat[2];
1158 count = *(const WORD*)&pFormat[6];
1162 for (i = 0; i < rep; i++) {
1163 PFORMAT_STRING info = pFormat;
1164 unsigned char *membase = pMemory + (i * stride);
1165 unsigned char *bufbase = Mark + (i * stride);
1168 for (u=0; u<count; u++,info+=8) {
1169 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1170 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1171 unsigned char *saved_memory = pStubMsg->Memory;
1173 pStubMsg->Memory = pMemory;
1174 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1175 pStubMsg->Memory = saved_memory;
1178 pFormat += 8 * count;
1183 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1184 pStubMsg->Buffer = saved_buffer;
1187 STD_OVERFLOW_CHECK(pStubMsg);
1192 /***********************************************************************
1193 * EmbeddedPointerUnmarshall
1195 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1196 unsigned char *pDstBuffer,
1197 unsigned char *pSrcMemoryPtrs,
1198 PFORMAT_STRING pFormat,
1199 unsigned char fMustAlloc)
1201 unsigned char *Mark = pStubMsg->BufferMark;
1202 unsigned rep, count, stride;
1204 unsigned char *saved_buffer = NULL;
1206 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc);
1208 if (*pFormat != RPC_FC_PP) return NULL;
1211 if (pStubMsg->PointerBufferMark)
1213 saved_buffer = pStubMsg->Buffer;
1214 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1215 pStubMsg->PointerBufferMark = NULL;
1218 while (pFormat[0] != RPC_FC_END) {
1219 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1220 switch (pFormat[0]) {
1222 FIXME("unknown repeat type %d\n", pFormat[0]);
1223 case RPC_FC_NO_REPEAT:
1229 case RPC_FC_FIXED_REPEAT:
1230 rep = *(const WORD*)&pFormat[2];
1231 stride = *(const WORD*)&pFormat[4];
1232 count = *(const WORD*)&pFormat[8];
1235 case RPC_FC_VARIABLE_REPEAT:
1236 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1237 stride = *(const WORD*)&pFormat[2];
1238 count = *(const WORD*)&pFormat[6];
1242 for (i = 0; i < rep; i++) {
1243 PFORMAT_STRING info = pFormat;
1244 unsigned char *bufdstbase = pDstBuffer + (i * stride);
1245 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1246 unsigned char *bufbase = Mark + (i * stride);
1249 for (u=0; u<count; u++,info+=8) {
1250 unsigned char **bufdstptr = (unsigned char **)(bufdstbase + *(const SHORT*)&info[2]);
1251 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1252 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1253 PointerUnmarshall(pStubMsg, bufptr, bufdstptr, *memsrcptr, info+4, fMustAlloc);
1256 pFormat += 8 * count;
1261 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1262 pStubMsg->Buffer = saved_buffer;
1268 /***********************************************************************
1269 * EmbeddedPointerBufferSize
1271 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1272 unsigned char *pMemory,
1273 PFORMAT_STRING pFormat)
1275 unsigned rep, count, stride;
1277 ULONG saved_buffer_length = 0;
1279 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1281 if (pStubMsg->IgnoreEmbeddedPointers) return;
1283 if (*pFormat != RPC_FC_PP) return;
1286 if (pStubMsg->PointerLength)
1288 saved_buffer_length = pStubMsg->BufferLength;
1289 pStubMsg->BufferLength = pStubMsg->PointerLength;
1290 pStubMsg->PointerLength = 0;
1293 while (pFormat[0] != RPC_FC_END) {
1294 switch (pFormat[0]) {
1296 FIXME("unknown repeat type %d\n", pFormat[0]);
1297 case RPC_FC_NO_REPEAT:
1303 case RPC_FC_FIXED_REPEAT:
1304 rep = *(const WORD*)&pFormat[2];
1305 stride = *(const WORD*)&pFormat[4];
1306 count = *(const WORD*)&pFormat[8];
1309 case RPC_FC_VARIABLE_REPEAT:
1310 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1311 stride = *(const WORD*)&pFormat[2];
1312 count = *(const WORD*)&pFormat[6];
1316 for (i = 0; i < rep; i++) {
1317 PFORMAT_STRING info = pFormat;
1318 unsigned char *membase = pMemory + (i * stride);
1321 for (u=0; u<count; u++,info+=8) {
1322 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1323 unsigned char *saved_memory = pStubMsg->Memory;
1325 pStubMsg->Memory = pMemory;
1326 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1327 pStubMsg->Memory = saved_memory;
1330 pFormat += 8 * count;
1333 if (saved_buffer_length)
1335 pStubMsg->PointerLength = pStubMsg->BufferLength;
1336 pStubMsg->BufferLength = saved_buffer_length;
1340 /***********************************************************************
1341 * EmbeddedPointerMemorySize [internal]
1343 static ULONG EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1344 PFORMAT_STRING pFormat)
1346 unsigned char *Mark = pStubMsg->BufferMark;
1347 unsigned rep, count, stride;
1349 unsigned char *saved_buffer = NULL;
1351 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1353 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1355 if (pStubMsg->PointerBufferMark)
1357 saved_buffer = pStubMsg->Buffer;
1358 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1359 pStubMsg->PointerBufferMark = NULL;
1362 if (*pFormat != RPC_FC_PP) return 0;
1365 while (pFormat[0] != RPC_FC_END) {
1366 switch (pFormat[0]) {
1368 FIXME("unknown repeat type %d\n", pFormat[0]);
1369 case RPC_FC_NO_REPEAT:
1375 case RPC_FC_FIXED_REPEAT:
1376 rep = *(const WORD*)&pFormat[2];
1377 stride = *(const WORD*)&pFormat[4];
1378 count = *(const WORD*)&pFormat[8];
1381 case RPC_FC_VARIABLE_REPEAT:
1382 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1383 stride = *(const WORD*)&pFormat[2];
1384 count = *(const WORD*)&pFormat[6];
1388 for (i = 0; i < rep; i++) {
1389 PFORMAT_STRING info = pFormat;
1390 unsigned char *bufbase = Mark + (i * stride);
1392 for (u=0; u<count; u++,info+=8) {
1393 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1394 PointerMemorySize(pStubMsg, bufptr, info+4);
1397 pFormat += 8 * count;
1402 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1403 pStubMsg->Buffer = saved_buffer;
1409 /***********************************************************************
1410 * EmbeddedPointerFree [internal]
1412 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1413 unsigned char *pMemory,
1414 PFORMAT_STRING pFormat)
1416 unsigned rep, count, stride;
1419 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1420 if (*pFormat != RPC_FC_PP) return;
1423 while (pFormat[0] != RPC_FC_END) {
1424 switch (pFormat[0]) {
1426 FIXME("unknown repeat type %d\n", pFormat[0]);
1427 case RPC_FC_NO_REPEAT:
1433 case RPC_FC_FIXED_REPEAT:
1434 rep = *(const WORD*)&pFormat[2];
1435 stride = *(const WORD*)&pFormat[4];
1436 count = *(const WORD*)&pFormat[8];
1439 case RPC_FC_VARIABLE_REPEAT:
1440 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1441 stride = *(const WORD*)&pFormat[2];
1442 count = *(const WORD*)&pFormat[6];
1446 for (i = 0; i < rep; i++) {
1447 PFORMAT_STRING info = pFormat;
1448 unsigned char *membase = pMemory + (i * stride);
1451 for (u=0; u<count; u++,info+=8) {
1452 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1453 unsigned char *saved_memory = pStubMsg->Memory;
1455 pStubMsg->Memory = pMemory;
1456 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1457 pStubMsg->Memory = saved_memory;
1460 pFormat += 8 * count;
1464 /***********************************************************************
1465 * NdrPointerMarshall [RPCRT4.@]
1467 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1468 unsigned char *pMemory,
1469 PFORMAT_STRING pFormat)
1471 unsigned char *Buffer;
1473 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1475 /* Increment the buffer here instead of in PointerMarshall,
1476 * as that is used by embedded pointers which already handle the incrementing
1477 * the buffer, and shouldn't write any additional pointer data to the wire */
1478 if (*pFormat != RPC_FC_RP)
1480 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
1481 Buffer = pStubMsg->Buffer;
1482 safe_buffer_increment(pStubMsg, 4);
1485 Buffer = pStubMsg->Buffer;
1487 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1492 /***********************************************************************
1493 * NdrPointerUnmarshall [RPCRT4.@]
1495 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1496 unsigned char **ppMemory,
1497 PFORMAT_STRING pFormat,
1498 unsigned char fMustAlloc)
1500 unsigned char *Buffer;
1502 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1504 if (*pFormat == RPC_FC_RP)
1506 Buffer = pStubMsg->Buffer;
1507 /* Do the NULL ref pointer check here because embedded pointers can be
1508 * NULL if the type the pointer is embedded in was allocated rather than
1509 * being passed in by the client */
1510 if (pStubMsg->IsClient && !*ppMemory)
1512 ERR("NULL ref pointer is not allowed\n");
1513 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1518 /* Increment the buffer here instead of in PointerUnmarshall,
1519 * as that is used by embedded pointers which already handle the incrementing
1520 * the buffer, and shouldn't read any additional pointer data from the
1522 ALIGN_POINTER(pStubMsg->Buffer, 4);
1523 Buffer = pStubMsg->Buffer;
1524 safe_buffer_increment(pStubMsg, 4);
1527 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1532 /***********************************************************************
1533 * NdrPointerBufferSize [RPCRT4.@]
1535 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1536 unsigned char *pMemory,
1537 PFORMAT_STRING pFormat)
1539 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1541 /* Increment the buffer length here instead of in PointerBufferSize,
1542 * as that is used by embedded pointers which already handle the buffer
1543 * length, and shouldn't write anything more to the wire */
1544 if (*pFormat != RPC_FC_RP)
1546 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1547 safe_buffer_length_increment(pStubMsg, 4);
1550 PointerBufferSize(pStubMsg, pMemory, pFormat);
1553 /***********************************************************************
1554 * NdrPointerMemorySize [RPCRT4.@]
1556 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1557 PFORMAT_STRING pFormat)
1559 unsigned char *Buffer = pStubMsg->Buffer;
1560 if (*pFormat != RPC_FC_RP)
1562 ALIGN_POINTER(pStubMsg->Buffer, 4);
1563 safe_buffer_increment(pStubMsg, 4);
1565 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(void *));
1566 return PointerMemorySize(pStubMsg, Buffer, pFormat);
1569 /***********************************************************************
1570 * NdrPointerFree [RPCRT4.@]
1572 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1573 unsigned char *pMemory,
1574 PFORMAT_STRING pFormat)
1576 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1577 PointerFree(pStubMsg, pMemory, pFormat);
1580 /***********************************************************************
1581 * NdrSimpleTypeMarshall [RPCRT4.@]
1583 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1584 unsigned char FormatChar )
1586 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1589 /***********************************************************************
1590 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1592 * Unmarshall a base type.
1595 * Doesn't check that the buffer is long enough before copying, so the caller
1598 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1599 unsigned char FormatChar )
1601 #define BASE_TYPE_UNMARSHALL(type) \
1602 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
1603 TRACE("pMemory: %p\n", pMemory); \
1604 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1605 pStubMsg->Buffer += sizeof(type);
1613 BASE_TYPE_UNMARSHALL(UCHAR);
1614 TRACE("value: 0x%02x\n", *pMemory);
1619 BASE_TYPE_UNMARSHALL(USHORT);
1620 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
1624 case RPC_FC_ERROR_STATUS_T:
1626 BASE_TYPE_UNMARSHALL(ULONG);
1627 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
1630 BASE_TYPE_UNMARSHALL(float);
1631 TRACE("value: %f\n", *(float *)pMemory);
1634 BASE_TYPE_UNMARSHALL(double);
1635 TRACE("value: %f\n", *(double *)pMemory);
1638 BASE_TYPE_UNMARSHALL(ULONGLONG);
1639 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
1642 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
1643 TRACE("pMemory: %p\n", pMemory);
1644 /* 16-bits on the wire, but int in memory */
1645 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
1646 pStubMsg->Buffer += sizeof(USHORT);
1647 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
1652 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
1654 #undef BASE_TYPE_UNMARSHALL
1657 /***********************************************************************
1658 * NdrSimpleStructMarshall [RPCRT4.@]
1660 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1661 unsigned char *pMemory,
1662 PFORMAT_STRING pFormat)
1664 unsigned size = *(const WORD*)(pFormat+2);
1665 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1667 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
1669 pStubMsg->BufferMark = pStubMsg->Buffer;
1670 safe_copy_to_buffer(pStubMsg, pMemory, size);
1672 if (pFormat[0] != RPC_FC_STRUCT)
1673 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1678 /***********************************************************************
1679 * NdrSimpleStructUnmarshall [RPCRT4.@]
1681 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1682 unsigned char **ppMemory,
1683 PFORMAT_STRING pFormat,
1684 unsigned char fMustAlloc)
1686 unsigned size = *(const WORD*)(pFormat+2);
1687 unsigned char *saved_buffer;
1688 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1690 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1693 *ppMemory = NdrAllocate(pStubMsg, size);
1696 if (!pStubMsg->IsClient && !*ppMemory)
1697 /* for servers, we just point straight into the RPC buffer */
1698 *ppMemory = pStubMsg->Buffer;
1701 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1702 safe_buffer_increment(pStubMsg, size);
1703 if (pFormat[0] == RPC_FC_PSTRUCT)
1704 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1706 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1707 if (*ppMemory != saved_buffer)
1708 memcpy(*ppMemory, saved_buffer, size);
1713 /***********************************************************************
1714 * NdrSimpleStructBufferSize [RPCRT4.@]
1716 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1717 unsigned char *pMemory,
1718 PFORMAT_STRING pFormat)
1720 unsigned size = *(const WORD*)(pFormat+2);
1721 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1723 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1725 safe_buffer_length_increment(pStubMsg, size);
1726 if (pFormat[0] != RPC_FC_STRUCT)
1727 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1730 /***********************************************************************
1731 * NdrSimpleStructMemorySize [RPCRT4.@]
1733 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1734 PFORMAT_STRING pFormat)
1736 unsigned short size = *(const WORD *)(pFormat+2);
1738 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1740 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1741 pStubMsg->MemorySize += size;
1742 safe_buffer_increment(pStubMsg, size);
1744 if (pFormat[0] != RPC_FC_STRUCT)
1745 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1746 return pStubMsg->MemorySize;
1749 /***********************************************************************
1750 * NdrSimpleStructFree [RPCRT4.@]
1752 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1753 unsigned char *pMemory,
1754 PFORMAT_STRING pFormat)
1756 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1757 if (pFormat[0] != RPC_FC_STRUCT)
1758 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1763 static inline void array_compute_and_size_conformance(
1764 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1765 PFORMAT_STRING pFormat)
1770 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1771 SizeConformance(pStubMsg);
1773 case RPC_FC_CVARRAY:
1774 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1775 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1776 SizeConformance(pStubMsg);
1778 case RPC_FC_C_CSTRING:
1779 case RPC_FC_C_WSTRING:
1780 if (pFormat[0] == RPC_FC_C_CSTRING)
1782 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1783 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1787 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1788 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1791 if (fc == RPC_FC_STRING_SIZED)
1792 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1794 pStubMsg->MaxCount = pStubMsg->ActualCount;
1796 SizeConformance(pStubMsg);
1799 ERR("unknown array format 0x%x\n", fc);
1800 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1804 static inline void array_buffer_size(
1805 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1806 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1810 unsigned char alignment;
1815 esize = *(const WORD*)(pFormat+2);
1816 alignment = pFormat[1] + 1;
1818 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1820 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
1822 size = safe_multiply(esize, pStubMsg->MaxCount);
1823 /* conformance value plus array */
1824 safe_buffer_length_increment(pStubMsg, size);
1827 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1829 case RPC_FC_CVARRAY:
1830 esize = *(const WORD*)(pFormat+2);
1831 alignment = pFormat[1] + 1;
1833 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1834 pFormat = SkipConformance(pStubMsg, pFormat);
1836 SizeVariance(pStubMsg);
1838 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
1840 size = safe_multiply(esize, pStubMsg->ActualCount);
1841 safe_buffer_length_increment(pStubMsg, size);
1844 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1846 case RPC_FC_C_CSTRING:
1847 case RPC_FC_C_WSTRING:
1848 if (fc == RPC_FC_C_CSTRING)
1853 SizeVariance(pStubMsg);
1855 size = safe_multiply(esize, pStubMsg->ActualCount);
1856 safe_buffer_length_increment(pStubMsg, size);
1859 ERR("unknown array format 0x%x\n", fc);
1860 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1864 static inline void array_compute_and_write_conformance(
1865 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1866 PFORMAT_STRING pFormat)
1871 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1872 WriteConformance(pStubMsg);
1874 case RPC_FC_CVARRAY:
1875 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1876 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1877 WriteConformance(pStubMsg);
1879 case RPC_FC_C_CSTRING:
1880 case RPC_FC_C_WSTRING:
1881 if (fc == RPC_FC_C_CSTRING)
1883 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1884 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1888 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1889 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1891 if (pFormat[1] == RPC_FC_STRING_SIZED)
1892 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1894 pStubMsg->MaxCount = pStubMsg->ActualCount;
1895 pStubMsg->Offset = 0;
1896 WriteConformance(pStubMsg);
1899 ERR("unknown array format 0x%x\n", fc);
1900 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1904 static inline void array_write_variance_and_marshall(
1905 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1906 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1910 unsigned char alignment;
1915 esize = *(const WORD*)(pFormat+2);
1916 alignment = pFormat[1] + 1;
1918 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1920 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
1922 size = safe_multiply(esize, pStubMsg->MaxCount);
1924 pStubMsg->BufferMark = pStubMsg->Buffer;
1925 safe_copy_to_buffer(pStubMsg, pMemory, size);
1928 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1930 case RPC_FC_CVARRAY:
1931 esize = *(const WORD*)(pFormat+2);
1932 alignment = pFormat[1] + 1;
1935 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1937 pFormat = SkipConformance(pStubMsg, pFormat);
1939 WriteVariance(pStubMsg);
1941 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
1943 size = safe_multiply(esize, pStubMsg->ActualCount);
1946 pStubMsg->BufferMark = pStubMsg->Buffer;
1947 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size);
1950 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1952 case RPC_FC_C_CSTRING:
1953 case RPC_FC_C_WSTRING:
1954 if (fc == RPC_FC_C_CSTRING)
1959 WriteVariance(pStubMsg);
1961 size = safe_multiply(esize, pStubMsg->ActualCount);
1962 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
1965 ERR("unknown array format 0x%x\n", fc);
1966 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1970 static inline ULONG array_read_conformance(
1971 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
1978 esize = *(const WORD*)(pFormat+2);
1979 pFormat = ReadConformance(pStubMsg, pFormat+4);
1980 return safe_multiply(esize, pStubMsg->MaxCount);
1981 case RPC_FC_CVARRAY:
1982 esize = *(const WORD*)(pFormat+2);
1983 pFormat = ReadConformance(pStubMsg, pFormat+4);
1984 return safe_multiply(esize, pStubMsg->MaxCount);
1985 case RPC_FC_C_CSTRING:
1986 case RPC_FC_C_WSTRING:
1987 if (fc == RPC_FC_C_CSTRING)
1992 if (pFormat[1] == RPC_FC_STRING_SIZED)
1993 ReadConformance(pStubMsg, pFormat + 2);
1995 ReadConformance(pStubMsg, NULL);
1996 return safe_multiply(esize, pStubMsg->MaxCount);
1998 ERR("unknown array format 0x%x\n", fc);
1999 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2003 static inline ULONG array_read_variance_and_unmarshall(
2004 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory,
2005 PFORMAT_STRING pFormat, unsigned char fMustAlloc,
2006 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall)
2008 ULONG bufsize, memsize;
2010 unsigned char alignment;
2011 unsigned char *saved_buffer;
2017 esize = *(const WORD*)(pFormat+2);
2018 alignment = pFormat[1] + 1;
2020 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2022 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2024 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2029 *ppMemory = NdrAllocate(pStubMsg, memsize);
2032 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory)
2033 /* for servers, we just point straight into the RPC buffer */
2034 *ppMemory = pStubMsg->Buffer;
2037 saved_buffer = pStubMsg->Buffer;
2038 safe_buffer_increment(pStubMsg, bufsize);
2040 pStubMsg->BufferMark = saved_buffer;
2041 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2043 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2044 if (*ppMemory != saved_buffer)
2045 memcpy(*ppMemory, saved_buffer, bufsize);
2048 case RPC_FC_CVARRAY:
2049 esize = *(const WORD*)(pFormat+2);
2050 alignment = pFormat[1] + 1;
2052 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2054 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2056 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2058 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2059 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2063 offset = pStubMsg->Offset;
2065 if (!fMustAlloc && !*ppMemory)
2068 *ppMemory = NdrAllocate(pStubMsg, memsize);
2069 saved_buffer = pStubMsg->Buffer;
2070 safe_buffer_increment(pStubMsg, bufsize);
2072 pStubMsg->BufferMark = saved_buffer;
2073 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat,
2076 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2079 case RPC_FC_C_CSTRING:
2080 case RPC_FC_C_WSTRING:
2081 if (fc == RPC_FC_C_CSTRING)
2086 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2088 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2090 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2091 pStubMsg->ActualCount, pStubMsg->MaxCount);
2092 RpcRaiseException(RPC_S_INVALID_BOUND);
2094 if (pStubMsg->Offset)
2096 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2097 RpcRaiseException(RPC_S_INVALID_BOUND);
2100 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2101 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2103 validate_string_data(pStubMsg, bufsize, esize);
2108 *ppMemory = NdrAllocate(pStubMsg, memsize);
2111 if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
2112 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
2113 /* if the data in the RPC buffer is big enough, we just point
2114 * straight into it */
2115 *ppMemory = pStubMsg->Buffer;
2116 else if (!*ppMemory)
2117 *ppMemory = NdrAllocate(pStubMsg, memsize);
2120 if (*ppMemory == pStubMsg->Buffer)
2121 safe_buffer_increment(pStubMsg, bufsize);
2123 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2125 if (*pFormat == RPC_FC_C_CSTRING)
2126 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
2128 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
2132 ERR("unknown array format 0x%x\n", fc);
2133 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2137 static inline void array_memory_size(
2138 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
2139 unsigned char fHasPointers)
2141 ULONG bufsize, memsize;
2143 unsigned char alignment;
2148 esize = *(const WORD*)(pFormat+2);
2149 alignment = pFormat[1] + 1;
2151 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2153 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2154 pStubMsg->MemorySize += memsize;
2156 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2158 pStubMsg->BufferMark = pStubMsg->Buffer;
2159 safe_buffer_increment(pStubMsg, bufsize);
2162 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2164 case RPC_FC_CVARRAY:
2165 esize = *(const WORD*)(pFormat+2);
2166 alignment = pFormat[1] + 1;
2168 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2170 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2172 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2173 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2174 pStubMsg->MemorySize += memsize;
2176 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2178 pStubMsg->BufferMark = pStubMsg->Buffer;
2179 safe_buffer_increment(pStubMsg, bufsize);
2182 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2184 case RPC_FC_C_CSTRING:
2185 case RPC_FC_C_WSTRING:
2186 if (fc == RPC_FC_C_CSTRING)
2191 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2193 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2195 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2196 pStubMsg->ActualCount, pStubMsg->MaxCount);
2197 RpcRaiseException(RPC_S_INVALID_BOUND);
2199 if (pStubMsg->Offset)
2201 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2202 RpcRaiseException(RPC_S_INVALID_BOUND);
2205 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2206 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2208 validate_string_data(pStubMsg, bufsize, esize);
2210 safe_buffer_increment(pStubMsg, bufsize);
2211 pStubMsg->MemorySize += memsize;
2214 ERR("unknown array format 0x%x\n", fc);
2215 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2219 static inline void array_free(
2220 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
2221 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
2226 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2228 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2230 case RPC_FC_CVARRAY:
2231 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2232 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2234 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2236 case RPC_FC_C_CSTRING:
2237 case RPC_FC_C_WSTRING:
2238 /* No embedded pointers so nothing to do */
2241 ERR("unknown array format 0x%x\n", fc);
2242 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2247 * NdrConformantString:
2249 * What MS calls a ConformantString is, in DCE terminology,
2250 * a Varying-Conformant String.
2252 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2253 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2254 * into unmarshalled string)
2255 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2257 * data: CHARTYPE[maxlen]
2259 * ], where CHARTYPE is the appropriate character type (specified externally)
2263 /***********************************************************************
2264 * NdrConformantStringMarshall [RPCRT4.@]
2266 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
2267 unsigned char *pszMessage, PFORMAT_STRING pFormat)
2269 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
2271 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2272 ERR("Unhandled string type: %#x\n", pFormat[0]);
2273 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2276 /* allow compiler to optimise inline function by passing constant into
2277 * these functions */
2278 if (pFormat[0] == RPC_FC_C_CSTRING) {
2279 array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2281 array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2282 pFormat, TRUE /* fHasPointers */);
2284 array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2286 array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2287 pFormat, TRUE /* fHasPointers */);
2293 /***********************************************************************
2294 * NdrConformantStringBufferSize [RPCRT4.@]
2296 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2297 unsigned char* pMemory, PFORMAT_STRING pFormat)
2299 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2301 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2302 ERR("Unhandled string type: %#x\n", pFormat[0]);
2303 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2306 /* allow compiler to optimise inline function by passing constant into
2307 * these functions */
2308 if (pFormat[0] == RPC_FC_C_CSTRING) {
2309 array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory,
2311 array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat,
2312 TRUE /* fHasPointers */);
2314 array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory,
2316 array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat,
2317 TRUE /* fHasPointers */);
2321 /************************************************************************
2322 * NdrConformantStringMemorySize [RPCRT4.@]
2324 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2325 PFORMAT_STRING pFormat )
2327 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2329 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2330 ERR("Unhandled string type: %#x\n", pFormat[0]);
2331 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2334 /* allow compiler to optimise inline function by passing constant into
2335 * these functions */
2336 if (pFormat[0] == RPC_FC_C_CSTRING) {
2337 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2338 array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat,
2339 TRUE /* fHasPointers */);
2341 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2342 array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat,
2343 TRUE /* fHasPointers */);
2346 return pStubMsg->MemorySize;
2349 /************************************************************************
2350 * NdrConformantStringUnmarshall [RPCRT4.@]
2352 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2353 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
2355 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2356 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2358 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2359 ERR("Unhandled string type: %#x\n", *pFormat);
2360 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2363 /* allow compiler to optimise inline function by passing constant into
2364 * these functions */
2365 if (pFormat[0] == RPC_FC_C_CSTRING) {
2366 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2367 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory,
2368 pFormat, fMustAlloc,
2369 TRUE /* fUseBufferMemoryServer */,
2370 TRUE /* fUnmarshall */);
2372 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2373 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory,
2374 pFormat, fMustAlloc,
2375 TRUE /* fUseBufferMemoryServer */,
2376 TRUE /* fUnmarshall */);
2382 /***********************************************************************
2383 * NdrNonConformantStringMarshall [RPCRT4.@]
2385 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2386 unsigned char *pMemory,
2387 PFORMAT_STRING pFormat)
2389 ULONG esize, size, maxsize;
2391 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2393 maxsize = *(USHORT *)&pFormat[2];
2395 if (*pFormat == RPC_FC_CSTRING)
2398 const char *str = (const char *)pMemory;
2399 for (i = 0; i < maxsize && *str; i++, str++)
2401 TRACE("string=%s\n", debugstr_an(str, i));
2402 pStubMsg->ActualCount = i + 1;
2405 else if (*pFormat == RPC_FC_WSTRING)
2408 const WCHAR *str = (const WCHAR *)pMemory;
2409 for (i = 0; i < maxsize && *str; i++, str++)
2411 TRACE("string=%s\n", debugstr_wn(str, i));
2412 pStubMsg->ActualCount = i + 1;
2417 ERR("Unhandled string type: %#x\n", *pFormat);
2418 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2421 pStubMsg->Offset = 0;
2422 WriteVariance(pStubMsg);
2424 size = safe_multiply(esize, pStubMsg->ActualCount);
2425 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2430 /***********************************************************************
2431 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2433 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2434 unsigned char **ppMemory,
2435 PFORMAT_STRING pFormat,
2436 unsigned char fMustAlloc)
2438 ULONG bufsize, memsize, esize, maxsize;
2440 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2441 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2443 maxsize = *(USHORT *)&pFormat[2];
2445 ReadVariance(pStubMsg, NULL, maxsize);
2446 if (pStubMsg->Offset)
2448 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2449 RpcRaiseException(RPC_S_INVALID_BOUND);
2452 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2453 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2456 ERR("Unhandled string type: %#x\n", *pFormat);
2457 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2460 memsize = esize * maxsize;
2461 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2463 validate_string_data(pStubMsg, bufsize, esize);
2465 if (!fMustAlloc && !*ppMemory)
2468 *ppMemory = NdrAllocate(pStubMsg, memsize);
2470 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2472 if (*pFormat == RPC_FC_CSTRING) {
2473 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
2475 else if (*pFormat == RPC_FC_WSTRING) {
2476 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
2482 /***********************************************************************
2483 * NdrNonConformantStringBufferSize [RPCRT4.@]
2485 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2486 unsigned char *pMemory,
2487 PFORMAT_STRING pFormat)
2489 ULONG esize, maxsize;
2491 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2493 maxsize = *(USHORT *)&pFormat[2];
2495 SizeVariance(pStubMsg);
2497 if (*pFormat == RPC_FC_CSTRING)
2500 const char *str = (const char *)pMemory;
2501 for (i = 0; i < maxsize && *str; i++, str++)
2503 TRACE("string=%s\n", debugstr_an(str, i));
2504 pStubMsg->ActualCount = i + 1;
2507 else if (*pFormat == RPC_FC_WSTRING)
2510 const WCHAR *str = (const WCHAR *)pMemory;
2511 for (i = 0; i < maxsize && *str; i++, str++)
2513 TRACE("string=%s\n", debugstr_wn(str, i));
2514 pStubMsg->ActualCount = i + 1;
2519 ERR("Unhandled string type: %#x\n", *pFormat);
2520 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2523 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2526 /***********************************************************************
2527 * NdrNonConformantStringMemorySize [RPCRT4.@]
2529 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2530 PFORMAT_STRING pFormat)
2532 ULONG bufsize, memsize, esize, maxsize;
2534 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2536 maxsize = *(USHORT *)&pFormat[2];
2538 ReadVariance(pStubMsg, NULL, maxsize);
2540 if (pStubMsg->Offset)
2542 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2543 RpcRaiseException(RPC_S_INVALID_BOUND);
2546 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2547 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2550 ERR("Unhandled string type: %#x\n", *pFormat);
2551 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2554 memsize = esize * maxsize;
2555 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2557 validate_string_data(pStubMsg, bufsize, esize);
2559 safe_buffer_increment(pStubMsg, bufsize);
2560 pStubMsg->MemorySize += memsize;
2562 return pStubMsg->MemorySize;
2567 #include "pshpack1.h"
2571 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2575 #include "poppack.h"
2577 static ULONG EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2578 PFORMAT_STRING pFormat)
2582 case RPC_FC_PSTRUCT:
2583 case RPC_FC_CSTRUCT:
2584 case RPC_FC_BOGUS_STRUCT:
2585 case RPC_FC_SMFARRAY:
2586 case RPC_FC_SMVARRAY:
2587 case RPC_FC_CSTRING:
2588 return *(const WORD*)&pFormat[2];
2589 case RPC_FC_USER_MARSHAL:
2590 return *(const WORD*)&pFormat[4];
2591 case RPC_FC_RANGE: {
2592 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2597 return sizeof(UCHAR);
2601 return sizeof(USHORT);
2605 return sizeof(ULONG);
2607 return sizeof(float);
2609 return sizeof(double);
2611 return sizeof(ULONGLONG);
2613 return sizeof(UINT);
2615 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2616 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2619 case RPC_FC_NON_ENCAPSULATED_UNION:
2621 if (pStubMsg->fHasNewCorrDesc)
2626 pFormat += *(const SHORT*)pFormat;
2627 return *(const SHORT*)pFormat;
2629 return sizeof(void *);
2630 case RPC_FC_WSTRING:
2631 return *(const WORD*)&pFormat[2] * 2;
2633 FIXME("unhandled embedded type %02x\n", *pFormat);
2639 static ULONG EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2640 PFORMAT_STRING pFormat)
2642 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2646 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2650 return m(pStubMsg, pFormat);
2654 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2655 unsigned char *pMemory,
2656 PFORMAT_STRING pFormat,
2657 PFORMAT_STRING pPointer)
2659 PFORMAT_STRING desc;
2663 while (*pFormat != RPC_FC_END) {
2669 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2670 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2676 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2677 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2681 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2682 if (32767 < *(DWORD*)pMemory)
2683 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2684 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2690 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2691 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2695 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2696 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2699 case RPC_FC_POINTER:
2701 unsigned char *saved_buffer;
2702 int pointer_buffer_mark_set = 0;
2703 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2704 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2705 if (*pPointer != RPC_FC_RP)
2706 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
2707 saved_buffer = pStubMsg->Buffer;
2708 if (pStubMsg->PointerBufferMark)
2710 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2711 pStubMsg->PointerBufferMark = NULL;
2712 pointer_buffer_mark_set = 1;
2714 else if (*pPointer != RPC_FC_RP)
2715 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2716 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2717 if (pointer_buffer_mark_set)
2719 STD_OVERFLOW_CHECK(pStubMsg);
2720 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2721 pStubMsg->Buffer = saved_buffer;
2722 if (*pPointer != RPC_FC_RP)
2723 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2725 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2727 pMemory += sizeof(void *);
2730 case RPC_FC_ALIGNM4:
2731 ALIGN_POINTER(pMemory, 4);
2733 case RPC_FC_ALIGNM8:
2734 ALIGN_POINTER(pMemory, 8);
2736 case RPC_FC_STRUCTPAD1:
2737 case RPC_FC_STRUCTPAD2:
2738 case RPC_FC_STRUCTPAD3:
2739 case RPC_FC_STRUCTPAD4:
2740 case RPC_FC_STRUCTPAD5:
2741 case RPC_FC_STRUCTPAD6:
2742 case RPC_FC_STRUCTPAD7:
2743 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2745 case RPC_FC_EMBEDDED_COMPLEX:
2746 pMemory += pFormat[1];
2748 desc = pFormat + *(const SHORT*)pFormat;
2749 size = EmbeddedComplexSize(pStubMsg, desc);
2750 TRACE("embedded complex (size=%d) <= %p\n", size, pMemory);
2751 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2754 /* for some reason interface pointers aren't generated as
2755 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2756 * they still need the derefencing treatment that pointers are
2758 if (*desc == RPC_FC_IP)
2759 m(pStubMsg, *(unsigned char **)pMemory, desc);
2761 m(pStubMsg, pMemory, desc);
2763 else FIXME("no marshaller for embedded type %02x\n", *desc);
2770 FIXME("unhandled format 0x%02x\n", *pFormat);
2778 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2779 unsigned char *pMemory,
2780 PFORMAT_STRING pFormat,
2781 PFORMAT_STRING pPointer,
2782 unsigned char fMustAlloc)
2784 PFORMAT_STRING desc;
2788 while (*pFormat != RPC_FC_END) {
2794 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2795 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2801 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2802 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2806 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2807 *(DWORD*)pMemory &= 0xffff;
2808 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
2809 if (32767 < *(DWORD*)pMemory)
2810 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2816 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2817 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2821 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2822 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2825 case RPC_FC_POINTER:
2827 unsigned char *saved_buffer;
2828 int pointer_buffer_mark_set = 0;
2829 TRACE("pointer => %p\n", pMemory);
2830 if (*pPointer != RPC_FC_RP)
2831 ALIGN_POINTER(pStubMsg->Buffer, 4);
2832 saved_buffer = pStubMsg->Buffer;
2833 if (pStubMsg->PointerBufferMark)
2835 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2836 pStubMsg->PointerBufferMark = NULL;
2837 pointer_buffer_mark_set = 1;
2839 else if (*pPointer != RPC_FC_RP)
2840 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2842 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
2843 if (pointer_buffer_mark_set)
2845 STD_OVERFLOW_CHECK(pStubMsg);
2846 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2847 pStubMsg->Buffer = saved_buffer;
2848 if (*pPointer != RPC_FC_RP)
2849 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2852 pMemory += sizeof(void *);
2855 case RPC_FC_ALIGNM4:
2856 ALIGN_POINTER_CLEAR(pMemory, 4);
2858 case RPC_FC_ALIGNM8:
2859 ALIGN_POINTER_CLEAR(pMemory, 8);
2861 case RPC_FC_STRUCTPAD1:
2862 case RPC_FC_STRUCTPAD2:
2863 case RPC_FC_STRUCTPAD3:
2864 case RPC_FC_STRUCTPAD4:
2865 case RPC_FC_STRUCTPAD5:
2866 case RPC_FC_STRUCTPAD6:
2867 case RPC_FC_STRUCTPAD7:
2868 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2869 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2871 case RPC_FC_EMBEDDED_COMPLEX:
2872 pMemory += pFormat[1];
2874 desc = pFormat + *(const SHORT*)pFormat;
2875 size = EmbeddedComplexSize(pStubMsg, desc);
2876 TRACE("embedded complex (size=%d) => %p\n", size, pMemory);
2878 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
2879 * since the type is part of the memory block that is encompassed by
2880 * the whole complex type. Memory is forced to allocate when pointers
2881 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
2882 * clearing the memory we pass in to the unmarshaller */
2883 memset(pMemory, 0, size);
2884 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2887 /* for some reason interface pointers aren't generated as
2888 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2889 * they still need the derefencing treatment that pointers are
2891 if (*desc == RPC_FC_IP)
2892 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2894 m(pStubMsg, &pMemory, desc, FALSE);
2896 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2903 FIXME("unhandled format %d\n", *pFormat);
2911 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2912 unsigned char *pMemory,
2913 PFORMAT_STRING pFormat,
2914 PFORMAT_STRING pPointer)
2916 PFORMAT_STRING desc;
2920 while (*pFormat != RPC_FC_END) {
2926 safe_buffer_length_increment(pStubMsg, 1);
2932 safe_buffer_length_increment(pStubMsg, 2);
2936 safe_buffer_length_increment(pStubMsg, 2);
2942 safe_buffer_length_increment(pStubMsg, 4);
2946 safe_buffer_length_increment(pStubMsg, 8);
2949 case RPC_FC_POINTER:
2950 if (!pStubMsg->IgnoreEmbeddedPointers)
2952 int saved_buffer_length = pStubMsg->BufferLength;
2953 pStubMsg->BufferLength = pStubMsg->PointerLength;
2954 pStubMsg->PointerLength = 0;
2955 if(!pStubMsg->BufferLength)
2956 ERR("BufferLength == 0??\n");
2957 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2958 pStubMsg->PointerLength = pStubMsg->BufferLength;
2959 pStubMsg->BufferLength = saved_buffer_length;
2961 if (*pPointer != RPC_FC_RP)
2963 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2964 safe_buffer_length_increment(pStubMsg, 4);
2967 pMemory += sizeof(void*);
2969 case RPC_FC_ALIGNM4:
2970 ALIGN_POINTER(pMemory, 4);
2972 case RPC_FC_ALIGNM8:
2973 ALIGN_POINTER(pMemory, 8);
2975 case RPC_FC_STRUCTPAD1:
2976 case RPC_FC_STRUCTPAD2:
2977 case RPC_FC_STRUCTPAD3:
2978 case RPC_FC_STRUCTPAD4:
2979 case RPC_FC_STRUCTPAD5:
2980 case RPC_FC_STRUCTPAD6:
2981 case RPC_FC_STRUCTPAD7:
2982 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2984 case RPC_FC_EMBEDDED_COMPLEX:
2985 pMemory += pFormat[1];
2987 desc = pFormat + *(const SHORT*)pFormat;
2988 size = EmbeddedComplexSize(pStubMsg, desc);
2989 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2992 /* for some reason interface pointers aren't generated as
2993 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2994 * they still need the derefencing treatment that pointers are
2996 if (*desc == RPC_FC_IP)
2997 m(pStubMsg, *(unsigned char **)pMemory, desc);
2999 m(pStubMsg, pMemory, desc);
3001 else FIXME("no buffersizer for embedded type %02x\n", *desc);
3008 FIXME("unhandled format 0x%02x\n", *pFormat);
3016 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
3017 unsigned char *pMemory,
3018 PFORMAT_STRING pFormat,
3019 PFORMAT_STRING pPointer)
3021 PFORMAT_STRING desc;
3025 while (*pFormat != RPC_FC_END) {
3047 case RPC_FC_POINTER:
3048 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3050 pMemory += sizeof(void *);
3052 case RPC_FC_ALIGNM4:
3053 ALIGN_POINTER(pMemory, 4);
3055 case RPC_FC_ALIGNM8:
3056 ALIGN_POINTER(pMemory, 8);
3058 case RPC_FC_STRUCTPAD1:
3059 case RPC_FC_STRUCTPAD2:
3060 case RPC_FC_STRUCTPAD3:
3061 case RPC_FC_STRUCTPAD4:
3062 case RPC_FC_STRUCTPAD5:
3063 case RPC_FC_STRUCTPAD6:
3064 case RPC_FC_STRUCTPAD7:
3065 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3067 case RPC_FC_EMBEDDED_COMPLEX:
3068 pMemory += pFormat[1];
3070 desc = pFormat + *(const SHORT*)pFormat;
3071 size = EmbeddedComplexSize(pStubMsg, desc);
3072 m = NdrFreer[*desc & NDR_TABLE_MASK];
3075 /* for some reason interface pointers aren't generated as
3076 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3077 * they still need the derefencing treatment that pointers are
3079 if (*desc == RPC_FC_IP)
3080 m(pStubMsg, *(unsigned char **)pMemory, desc);
3082 m(pStubMsg, pMemory, desc);
3090 FIXME("unhandled format 0x%02x\n", *pFormat);
3098 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3099 PFORMAT_STRING pFormat,
3100 PFORMAT_STRING pPointer)
3102 PFORMAT_STRING desc;
3105 while (*pFormat != RPC_FC_END) {
3112 safe_buffer_increment(pStubMsg, 1);
3118 safe_buffer_increment(pStubMsg, 2);
3122 safe_buffer_increment(pStubMsg, 2);
3128 safe_buffer_increment(pStubMsg, 4);
3132 safe_buffer_increment(pStubMsg, 8);
3134 case RPC_FC_POINTER:
3136 unsigned char *saved_buffer;
3137 int pointer_buffer_mark_set = 0;
3138 if (*pPointer != RPC_FC_RP)
3139 ALIGN_POINTER(pStubMsg->Buffer, 4);
3140 saved_buffer = pStubMsg->Buffer;
3141 if (pStubMsg->PointerBufferMark)
3143 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3144 pStubMsg->PointerBufferMark = NULL;
3145 pointer_buffer_mark_set = 1;
3147 else if (*pPointer != RPC_FC_RP)
3148 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3150 if (!pStubMsg->IgnoreEmbeddedPointers)
3151 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3152 if (pointer_buffer_mark_set)
3154 STD_OVERFLOW_CHECK(pStubMsg);
3155 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3156 pStubMsg->Buffer = saved_buffer;
3157 if (*pPointer != RPC_FC_RP)
3158 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3161 size += sizeof(void *);
3164 case RPC_FC_ALIGNM4:
3165 ALIGN_LENGTH(size, 4);
3167 case RPC_FC_ALIGNM8:
3168 ALIGN_LENGTH(size, 8);
3170 case RPC_FC_STRUCTPAD1:
3171 case RPC_FC_STRUCTPAD2:
3172 case RPC_FC_STRUCTPAD3:
3173 case RPC_FC_STRUCTPAD4:
3174 case RPC_FC_STRUCTPAD5:
3175 case RPC_FC_STRUCTPAD6:
3176 case RPC_FC_STRUCTPAD7:
3177 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3179 case RPC_FC_EMBEDDED_COMPLEX:
3182 desc = pFormat + *(const SHORT*)pFormat;
3183 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3189 FIXME("unhandled format 0x%02x\n", *pFormat);
3197 ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
3199 PFORMAT_STRING desc;
3202 while (*pFormat != RPC_FC_END) {
3224 case RPC_FC_POINTER:
3225 size += sizeof(void *);
3227 case RPC_FC_ALIGNM4:
3228 ALIGN_LENGTH(size, 4);
3230 case RPC_FC_ALIGNM8:
3231 ALIGN_LENGTH(size, 8);
3233 case RPC_FC_STRUCTPAD1:
3234 case RPC_FC_STRUCTPAD2:
3235 case RPC_FC_STRUCTPAD3:
3236 case RPC_FC_STRUCTPAD4:
3237 case RPC_FC_STRUCTPAD5:
3238 case RPC_FC_STRUCTPAD6:
3239 case RPC_FC_STRUCTPAD7:
3240 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3242 case RPC_FC_EMBEDDED_COMPLEX:
3245 desc = pFormat + *(const SHORT*)pFormat;
3246 size += EmbeddedComplexSize(pStubMsg, desc);
3252 FIXME("unhandled format 0x%02x\n", *pFormat);
3260 /***********************************************************************
3261 * NdrComplexStructMarshall [RPCRT4.@]
3263 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3264 unsigned char *pMemory,
3265 PFORMAT_STRING pFormat)
3267 PFORMAT_STRING conf_array = NULL;
3268 PFORMAT_STRING pointer_desc = NULL;
3269 unsigned char *OldMemory = pStubMsg->Memory;
3270 int pointer_buffer_mark_set = 0;
3272 ULONG max_count = 0;
3275 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3277 if (!pStubMsg->PointerBufferMark)
3279 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3280 /* save buffer length */
3281 ULONG saved_buffer_length = pStubMsg->BufferLength;
3283 /* get the buffer pointer after complex array data, but before
3285 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3286 pStubMsg->IgnoreEmbeddedPointers = 1;
3287 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3288 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3290 /* save it for use by embedded pointer code later */
3291 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3292 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - pStubMsg->Buffer));
3293 pointer_buffer_mark_set = 1;
3295 /* restore the original buffer length */
3296 pStubMsg->BufferLength = saved_buffer_length;
3299 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
3302 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3304 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3307 pStubMsg->Memory = pMemory;
3311 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3312 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3313 pMemory + struct_size, conf_array);
3314 /* these could be changed in ComplexMarshall so save them for later */
3315 max_count = pStubMsg->MaxCount;
3316 count = pStubMsg->ActualCount;
3317 offset = pStubMsg->Offset;
3320 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3324 pStubMsg->MaxCount = max_count;
3325 pStubMsg->ActualCount = count;
3326 pStubMsg->Offset = offset;
3327 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3328 conf_array, TRUE /* fHasPointers */);
3331 pStubMsg->Memory = OldMemory;
3333 if (pointer_buffer_mark_set)
3335 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3336 pStubMsg->PointerBufferMark = NULL;
3339 STD_OVERFLOW_CHECK(pStubMsg);
3344 /***********************************************************************
3345 * NdrComplexStructUnmarshall [RPCRT4.@]
3347 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3348 unsigned char **ppMemory,
3349 PFORMAT_STRING pFormat,
3350 unsigned char fMustAlloc)
3352 unsigned size = *(const WORD*)(pFormat+2);
3353 PFORMAT_STRING conf_array = NULL;
3354 PFORMAT_STRING pointer_desc = NULL;
3355 unsigned char *pMemory;
3356 int pointer_buffer_mark_set = 0;
3358 ULONG max_count = 0;
3360 ULONG array_size = 0;
3362 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3364 if (!pStubMsg->PointerBufferMark)
3366 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3367 /* save buffer pointer */
3368 unsigned char *saved_buffer = pStubMsg->Buffer;
3370 /* get the buffer pointer after complex array data, but before
3372 pStubMsg->IgnoreEmbeddedPointers = 1;
3373 NdrComplexStructMemorySize(pStubMsg, pFormat);
3374 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3376 /* save it for use by embedded pointer code later */
3377 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3378 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - saved_buffer));
3379 pointer_buffer_mark_set = 1;
3381 /* restore the original buffer */
3382 pStubMsg->Buffer = saved_buffer;
3385 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3388 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3390 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3395 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3398 /* these could be changed in ComplexMarshall so save them for later */
3399 max_count = pStubMsg->MaxCount;
3400 count = pStubMsg->ActualCount;
3401 offset = pStubMsg->Offset;
3404 if (!fMustAlloc && !*ppMemory)
3407 *ppMemory = NdrAllocate(pStubMsg, size);
3409 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3413 pStubMsg->MaxCount = max_count;
3414 pStubMsg->ActualCount = count;
3415 pStubMsg->Offset = offset;
3417 memset(pMemory, 0, array_size);
3418 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3420 FALSE /* fUseBufferMemoryServer */,
3421 TRUE /* fUnmarshall */);
3424 if (pointer_buffer_mark_set)
3426 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3427 pStubMsg->PointerBufferMark = NULL;
3433 /***********************************************************************
3434 * NdrComplexStructBufferSize [RPCRT4.@]
3436 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3437 unsigned char *pMemory,
3438 PFORMAT_STRING pFormat)
3440 PFORMAT_STRING conf_array = NULL;
3441 PFORMAT_STRING pointer_desc = NULL;
3442 unsigned char *OldMemory = pStubMsg->Memory;
3443 int pointer_length_set = 0;
3445 ULONG max_count = 0;
3448 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3450 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
3452 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3454 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3455 ULONG saved_buffer_length = pStubMsg->BufferLength;
3457 /* get the buffer length after complex struct data, but before
3459 pStubMsg->IgnoreEmbeddedPointers = 1;
3460 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3461 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3463 /* save it for use by embedded pointer code later */
3464 pStubMsg->PointerLength = pStubMsg->BufferLength;
3465 pointer_length_set = 1;
3466 TRACE("difference = 0x%x\n", pStubMsg->PointerLength - saved_buffer_length);
3468 /* restore the original buffer length */
3469 pStubMsg->BufferLength = saved_buffer_length;
3473 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3475 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3478 pStubMsg->Memory = pMemory;
3482 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3483 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3486 /* these could be changed in ComplexMarshall so save them for later */
3487 max_count = pStubMsg->MaxCount;
3488 count = pStubMsg->ActualCount;
3489 offset = pStubMsg->Offset;
3492 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3496 pStubMsg->MaxCount = max_count;
3497 pStubMsg->ActualCount = count;
3498 pStubMsg->Offset = offset;
3499 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3500 TRUE /* fHasPointers */);
3503 pStubMsg->Memory = OldMemory;
3505 if(pointer_length_set)
3507 pStubMsg->BufferLength = pStubMsg->PointerLength;
3508 pStubMsg->PointerLength = 0;
3513 /***********************************************************************
3514 * NdrComplexStructMemorySize [RPCRT4.@]
3516 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3517 PFORMAT_STRING pFormat)
3519 unsigned size = *(const WORD*)(pFormat+2);
3520 PFORMAT_STRING conf_array = NULL;
3521 PFORMAT_STRING pointer_desc = NULL;
3523 ULONG max_count = 0;
3526 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3528 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3531 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3533 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3538 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3540 /* these could be changed in ComplexStructMemorySize so save them for
3542 max_count = pStubMsg->MaxCount;
3543 count = pStubMsg->ActualCount;
3544 offset = pStubMsg->Offset;
3547 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3551 pStubMsg->MaxCount = max_count;
3552 pStubMsg->ActualCount = count;
3553 pStubMsg->Offset = offset;
3554 array_memory_size(conf_array[0], pStubMsg, conf_array,
3555 TRUE /* fHasPointers */);
3561 /***********************************************************************
3562 * NdrComplexStructFree [RPCRT4.@]
3564 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3565 unsigned char *pMemory,
3566 PFORMAT_STRING pFormat)
3568 PFORMAT_STRING conf_array = NULL;
3569 PFORMAT_STRING pointer_desc = NULL;
3570 unsigned char *OldMemory = pStubMsg->Memory;
3572 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3575 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3577 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3580 pStubMsg->Memory = pMemory;
3582 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3585 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3586 TRUE /* fHasPointers */);
3588 pStubMsg->Memory = OldMemory;
3591 /***********************************************************************
3592 * NdrConformantArrayMarshall [RPCRT4.@]
3594 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3595 unsigned char *pMemory,
3596 PFORMAT_STRING pFormat)
3598 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3599 if (pFormat[0] != RPC_FC_CARRAY)
3601 ERR("invalid format = 0x%x\n", pFormat[0]);
3602 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3605 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory,
3607 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3608 TRUE /* fHasPointers */);
3613 /***********************************************************************
3614 * NdrConformantArrayUnmarshall [RPCRT4.@]
3616 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3617 unsigned char **ppMemory,
3618 PFORMAT_STRING pFormat,
3619 unsigned char fMustAlloc)
3621 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3622 if (pFormat[0] != RPC_FC_CARRAY)
3624 ERR("invalid format = 0x%x\n", pFormat[0]);
3625 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3628 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3629 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat,
3631 TRUE /* fUseBufferMemoryServer */,
3632 TRUE /* fUnmarshall */);
3637 /***********************************************************************
3638 * NdrConformantArrayBufferSize [RPCRT4.@]
3640 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3641 unsigned char *pMemory,
3642 PFORMAT_STRING pFormat)
3644 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3645 if (pFormat[0] != RPC_FC_CARRAY)
3647 ERR("invalid format = 0x%x\n", pFormat[0]);
3648 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3651 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat);
3652 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3653 TRUE /* fHasPointers */);
3656 /***********************************************************************
3657 * NdrConformantArrayMemorySize [RPCRT4.@]
3659 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3660 PFORMAT_STRING pFormat)
3662 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3663 if (pFormat[0] != RPC_FC_CARRAY)
3665 ERR("invalid format = 0x%x\n", pFormat[0]);
3666 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3669 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3670 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
3672 return pStubMsg->MemorySize;
3675 /***********************************************************************
3676 * NdrConformantArrayFree [RPCRT4.@]
3678 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3679 unsigned char *pMemory,
3680 PFORMAT_STRING pFormat)
3682 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3683 if (pFormat[0] != RPC_FC_CARRAY)
3685 ERR("invalid format = 0x%x\n", pFormat[0]);
3686 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3689 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3690 TRUE /* fHasPointers */);
3694 /***********************************************************************
3695 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3697 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
3698 unsigned char* pMemory,
3699 PFORMAT_STRING pFormat )
3701 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3703 if (pFormat[0] != RPC_FC_CVARRAY)
3705 ERR("invalid format type %x\n", pFormat[0]);
3706 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3710 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3712 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory,
3713 pFormat, TRUE /* fHasPointers */);
3719 /***********************************************************************
3720 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3722 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
3723 unsigned char** ppMemory,
3724 PFORMAT_STRING pFormat,
3725 unsigned char fMustAlloc )
3727 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3729 if (pFormat[0] != RPC_FC_CVARRAY)
3731 ERR("invalid format type %x\n", pFormat[0]);
3732 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3736 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3737 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory,
3738 pFormat, fMustAlloc,
3739 TRUE /* fUseBufferMemoryServer */,
3740 TRUE /* fUnmarshall */);
3746 /***********************************************************************
3747 * NdrConformantVaryingArrayFree [RPCRT4.@]
3749 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
3750 unsigned char* pMemory,
3751 PFORMAT_STRING pFormat )
3753 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3755 if (pFormat[0] != RPC_FC_CVARRAY)
3757 ERR("invalid format type %x\n", pFormat[0]);
3758 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3762 array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3763 TRUE /* fHasPointers */);
3767 /***********************************************************************
3768 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3770 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
3771 unsigned char* pMemory, PFORMAT_STRING pFormat )
3773 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3775 if (pFormat[0] != RPC_FC_CVARRAY)
3777 ERR("invalid format type %x\n", pFormat[0]);
3778 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3782 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3784 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3785 TRUE /* fHasPointers */);
3789 /***********************************************************************
3790 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3792 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
3793 PFORMAT_STRING pFormat )
3795 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3797 if (pFormat[0] != RPC_FC_CVARRAY)
3799 ERR("invalid format type %x\n", pFormat[0]);
3800 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3801 return pStubMsg->MemorySize;
3804 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3805 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat,
3806 TRUE /* fHasPointers */);
3808 return pStubMsg->MemorySize;
3812 /***********************************************************************
3813 * NdrComplexArrayMarshall [RPCRT4.@]
3815 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3816 unsigned char *pMemory,
3817 PFORMAT_STRING pFormat)
3819 ULONG i, count, def;
3820 BOOL variance_present;
3821 unsigned char alignment;
3822 int pointer_buffer_mark_set = 0;
3824 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3826 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3828 ERR("invalid format type %x\n", pFormat[0]);
3829 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3833 alignment = pFormat[1] + 1;
3835 if (!pStubMsg->PointerBufferMark)
3837 /* save buffer fields that may be changed by buffer sizer functions
3838 * and that may be needed later on */
3839 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3840 ULONG saved_buffer_length = pStubMsg->BufferLength;
3841 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
3842 ULONG saved_offset = pStubMsg->Offset;
3843 ULONG saved_actual_count = pStubMsg->ActualCount;
3845 /* get the buffer pointer after complex array data, but before
3847 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3848 pStubMsg->IgnoreEmbeddedPointers = 1;
3849 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3850 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3852 /* save it for use by embedded pointer code later */
3853 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3854 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer));
3855 pointer_buffer_mark_set = 1;
3857 /* restore fields */
3858 pStubMsg->ActualCount = saved_actual_count;
3859 pStubMsg->Offset = saved_offset;
3860 pStubMsg->MaxCount = saved_max_count;
3861 pStubMsg->BufferLength = saved_buffer_length;
3864 def = *(const WORD*)&pFormat[2];
3867 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3868 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3870 variance_present = IsConformanceOrVariancePresent(pFormat);
3871 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3872 TRACE("variance = %d\n", pStubMsg->ActualCount);
3874 WriteConformance(pStubMsg);
3875 if (variance_present)
3876 WriteVariance(pStubMsg);
3878 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3880 count = pStubMsg->ActualCount;
3881 for (i = 0; i < count; i++)
3882 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3884 STD_OVERFLOW_CHECK(pStubMsg);
3886 if (pointer_buffer_mark_set)
3888 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3889 pStubMsg->PointerBufferMark = NULL;
3895 /***********************************************************************
3896 * NdrComplexArrayUnmarshall [RPCRT4.@]
3898 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3899 unsigned char **ppMemory,
3900 PFORMAT_STRING pFormat,
3901 unsigned char fMustAlloc)
3903 ULONG i, count, size;
3904 unsigned char alignment;
3905 unsigned char *pMemory;
3906 unsigned char *saved_buffer;
3907 int pointer_buffer_mark_set = 0;
3908 int saved_ignore_embedded;
3910 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3912 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3914 ERR("invalid format type %x\n", pFormat[0]);
3915 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3919 alignment = pFormat[1] + 1;
3921 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3922 /* save buffer pointer */
3923 saved_buffer = pStubMsg->Buffer;
3924 /* get the buffer pointer after complex array data, but before
3926 pStubMsg->IgnoreEmbeddedPointers = 1;
3927 pStubMsg->MemorySize = 0;
3928 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3929 size = pStubMsg->MemorySize;
3930 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3932 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - saved_buffer));
3933 if (!pStubMsg->PointerBufferMark)
3935 /* save it for use by embedded pointer code later */
3936 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3937 pointer_buffer_mark_set = 1;
3939 /* restore the original buffer */
3940 pStubMsg->Buffer = saved_buffer;
3944 pFormat = ReadConformance(pStubMsg, pFormat);
3945 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3947 if (!fMustAlloc && !*ppMemory)
3950 *ppMemory = NdrAllocate(pStubMsg, size);
3952 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3954 pMemory = *ppMemory;
3955 count = pStubMsg->ActualCount;
3956 for (i = 0; i < count; i++)
3957 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
3959 if (pointer_buffer_mark_set)
3961 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3962 pStubMsg->PointerBufferMark = NULL;
3968 /***********************************************************************
3969 * NdrComplexArrayBufferSize [RPCRT4.@]
3971 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3972 unsigned char *pMemory,
3973 PFORMAT_STRING pFormat)
3975 ULONG i, count, def;
3976 unsigned char alignment;
3977 BOOL variance_present;
3978 int pointer_length_set = 0;
3980 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3982 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3984 ERR("invalid format type %x\n", pFormat[0]);
3985 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3989 alignment = pFormat[1] + 1;
3991 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3993 /* save buffer fields that may be changed by buffer sizer functions
3994 * and that may be needed later on */
3995 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3996 ULONG saved_buffer_length = pStubMsg->BufferLength;
3997 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
3998 ULONG saved_offset = pStubMsg->Offset;
3999 ULONG saved_actual_count = pStubMsg->ActualCount;
4001 /* get the buffer pointer after complex array data, but before
4003 pStubMsg->IgnoreEmbeddedPointers = 1;
4004 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4005 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4007 /* save it for use by embedded pointer code later */
4008 pStubMsg->PointerLength = pStubMsg->BufferLength;
4009 pointer_length_set = 1;
4011 /* restore fields */
4012 pStubMsg->ActualCount = saved_actual_count;
4013 pStubMsg->Offset = saved_offset;
4014 pStubMsg->MaxCount = saved_max_count;
4015 pStubMsg->BufferLength = saved_buffer_length;
4017 def = *(const WORD*)&pFormat[2];
4020 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4021 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4022 SizeConformance(pStubMsg);
4024 variance_present = IsConformanceOrVariancePresent(pFormat);
4025 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4026 TRACE("variance = %d\n", pStubMsg->ActualCount);
4028 if (variance_present)
4029 SizeVariance(pStubMsg);
4031 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4033 count = pStubMsg->ActualCount;
4034 for (i = 0; i < count; i++)
4035 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
4037 if(pointer_length_set)
4039 pStubMsg->BufferLength = pStubMsg->PointerLength;
4040 pStubMsg->PointerLength = 0;
4044 /***********************************************************************
4045 * NdrComplexArrayMemorySize [RPCRT4.@]
4047 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4048 PFORMAT_STRING pFormat)
4050 ULONG i, count, esize, SavedMemorySize, MemorySize;
4051 unsigned char alignment;
4053 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4055 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4057 ERR("invalid format type %x\n", pFormat[0]);
4058 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4062 alignment = pFormat[1] + 1;
4066 pFormat = ReadConformance(pStubMsg, pFormat);
4067 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
4069 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4071 SavedMemorySize = pStubMsg->MemorySize;
4073 esize = ComplexStructSize(pStubMsg, pFormat);
4075 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
4077 count = pStubMsg->ActualCount;
4078 for (i = 0; i < count; i++)
4079 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
4081 pStubMsg->MemorySize = SavedMemorySize;
4083 pStubMsg->MemorySize += MemorySize;
4087 /***********************************************************************
4088 * NdrComplexArrayFree [RPCRT4.@]
4090 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4091 unsigned char *pMemory,
4092 PFORMAT_STRING pFormat)
4094 ULONG i, count, def;
4096 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4098 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4100 ERR("invalid format type %x\n", pFormat[0]);
4101 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4105 def = *(const WORD*)&pFormat[2];
4108 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4109 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4111 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4112 TRACE("variance = %d\n", pStubMsg->ActualCount);
4114 count = pStubMsg->ActualCount;
4115 for (i = 0; i < count; i++)
4116 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4119 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4120 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4121 USER_MARSHAL_CB *umcb)
4123 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4124 pStubMsg->RpcMsg->DataRepresentation);
4125 umcb->pStubMsg = pStubMsg;
4126 umcb->pReserve = NULL;
4127 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4128 umcb->CBType = cbtype;
4129 umcb->pFormat = pFormat;
4130 umcb->pTypeFormat = NULL /* FIXME */;
4133 #define USER_MARSHAL_PTR_PREFIX \
4134 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4135 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4137 /***********************************************************************
4138 * NdrUserMarshalMarshall [RPCRT4.@]
4140 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4141 unsigned char *pMemory,
4142 PFORMAT_STRING pFormat)
4144 unsigned flags = pFormat[1];
4145 unsigned index = *(const WORD*)&pFormat[2];
4146 unsigned char *saved_buffer = NULL;
4147 USER_MARSHAL_CB umcb;
4149 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4150 TRACE("index=%d\n", index);
4152 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4154 if (flags & USER_MARSHAL_POINTER)
4156 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
4157 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4158 pStubMsg->Buffer += 4;
4159 if (pStubMsg->PointerBufferMark)
4161 saved_buffer = pStubMsg->Buffer;
4162 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4163 pStubMsg->PointerBufferMark = NULL;
4165 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
4168 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
4171 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4172 &umcb.Flags, pStubMsg->Buffer, pMemory);
4176 STD_OVERFLOW_CHECK(pStubMsg);
4177 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4178 pStubMsg->Buffer = saved_buffer;
4181 STD_OVERFLOW_CHECK(pStubMsg);
4186 /***********************************************************************
4187 * NdrUserMarshalUnmarshall [RPCRT4.@]
4189 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4190 unsigned char **ppMemory,
4191 PFORMAT_STRING pFormat,
4192 unsigned char fMustAlloc)
4194 unsigned flags = pFormat[1];
4195 unsigned index = *(const WORD*)&pFormat[2];
4196 DWORD memsize = *(const WORD*)&pFormat[4];
4197 unsigned char *saved_buffer = NULL;
4198 USER_MARSHAL_CB umcb;
4200 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4201 TRACE("index=%d\n", index);
4203 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4205 if (flags & USER_MARSHAL_POINTER)
4207 ALIGN_POINTER(pStubMsg->Buffer, 4);
4208 /* skip pointer prefix */
4209 pStubMsg->Buffer += 4;
4210 if (pStubMsg->PointerBufferMark)
4212 saved_buffer = pStubMsg->Buffer;
4213 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4214 pStubMsg->PointerBufferMark = NULL;
4216 ALIGN_POINTER(pStubMsg->Buffer, 8);
4219 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4221 if (!fMustAlloc && !*ppMemory)
4225 *ppMemory = NdrAllocate(pStubMsg, memsize);
4226 memset(*ppMemory, 0, memsize);
4230 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4231 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4235 STD_OVERFLOW_CHECK(pStubMsg);
4236 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4237 pStubMsg->Buffer = saved_buffer;
4243 /***********************************************************************
4244 * NdrUserMarshalBufferSize [RPCRT4.@]
4246 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4247 unsigned char *pMemory,
4248 PFORMAT_STRING pFormat)
4250 unsigned flags = pFormat[1];
4251 unsigned index = *(const WORD*)&pFormat[2];
4252 DWORD bufsize = *(const WORD*)&pFormat[6];
4253 USER_MARSHAL_CB umcb;
4254 ULONG saved_buffer_length = 0;
4256 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4257 TRACE("index=%d\n", index);
4259 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4261 if (flags & USER_MARSHAL_POINTER)
4263 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4264 /* skip pointer prefix */
4265 safe_buffer_length_increment(pStubMsg, 4);
4266 if (pStubMsg->IgnoreEmbeddedPointers)
4268 if (pStubMsg->PointerLength)
4270 saved_buffer_length = pStubMsg->BufferLength;
4271 pStubMsg->BufferLength = pStubMsg->PointerLength;
4272 pStubMsg->PointerLength = 0;
4274 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
4277 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
4280 TRACE("size=%d\n", bufsize);
4281 safe_buffer_length_increment(pStubMsg, bufsize);
4284 pStubMsg->BufferLength =
4285 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4286 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4288 if (saved_buffer_length)
4290 pStubMsg->PointerLength = pStubMsg->BufferLength;
4291 pStubMsg->BufferLength = saved_buffer_length;
4296 /***********************************************************************
4297 * NdrUserMarshalMemorySize [RPCRT4.@]
4299 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4300 PFORMAT_STRING pFormat)
4302 unsigned flags = pFormat[1];
4303 unsigned index = *(const WORD*)&pFormat[2];
4304 DWORD memsize = *(const WORD*)&pFormat[4];
4305 DWORD bufsize = *(const WORD*)&pFormat[6];
4307 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4308 TRACE("index=%d\n", index);
4310 pStubMsg->MemorySize += memsize;
4312 if (flags & USER_MARSHAL_POINTER)
4314 ALIGN_POINTER(pStubMsg->Buffer, 4);
4315 /* skip pointer prefix */
4316 pStubMsg->Buffer += 4;
4317 if (pStubMsg->IgnoreEmbeddedPointers)
4318 return pStubMsg->MemorySize;
4319 ALIGN_POINTER(pStubMsg->Buffer, 8);
4322 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4325 FIXME("not implemented for varying buffer size\n");
4327 pStubMsg->Buffer += bufsize;
4329 return pStubMsg->MemorySize;
4332 /***********************************************************************
4333 * NdrUserMarshalFree [RPCRT4.@]
4335 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4336 unsigned char *pMemory,
4337 PFORMAT_STRING pFormat)
4339 /* unsigned flags = pFormat[1]; */
4340 unsigned index = *(const WORD*)&pFormat[2];
4341 USER_MARSHAL_CB umcb;
4343 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4344 TRACE("index=%d\n", index);
4346 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4348 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4349 &umcb.Flags, pMemory);
4352 /***********************************************************************
4353 * NdrGetUserMarshalInfo [RPCRT4.@]
4355 RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi)
4357 USER_MARSHAL_CB *umcb = CONTAINING_RECORD(flags, USER_MARSHAL_CB, Flags);
4359 TRACE("(%p,%u,%p)\n", flags, level, umi);
4362 return RPC_S_INVALID_ARG;
4364 memset(&umi->Level1, 0, sizeof(umi->Level1));
4365 umi->InformationLevel = level;
4367 if (umcb->Signature != USER_MARSHAL_CB_SIGNATURE)
4368 return RPC_S_INVALID_ARG;
4370 umi->Level1.pfnAllocate = umcb->pStubMsg->pfnAllocate;
4371 umi->Level1.pfnFree = umcb->pStubMsg->pfnFree;
4372 umi->Level1.pRpcChannelBuffer = umcb->pStubMsg->pRpcChannelBuffer;
4374 switch (umcb->CBType)
4376 case USER_MARSHAL_CB_MARSHALL:
4377 case USER_MARSHAL_CB_UNMARSHALL:
4379 RPC_MESSAGE *msg = umcb->pStubMsg->RpcMsg;
4380 unsigned char *buffer_start = msg->Buffer;
4381 unsigned char *buffer_end =
4382 (unsigned char *)msg->Buffer + msg->BufferLength;
4384 if (umcb->pStubMsg->Buffer < buffer_start ||
4385 umcb->pStubMsg->Buffer > buffer_end)
4386 return ERROR_INVALID_USER_BUFFER;
4388 umi->Level1.Buffer = umcb->pStubMsg->Buffer;
4389 umi->Level1.BufferSize = buffer_end - umcb->pStubMsg->Buffer;
4392 case USER_MARSHAL_CB_BUFFER_SIZE:
4393 case USER_MARSHAL_CB_FREE:
4396 WARN("unrecognised CBType %d\n", umcb->CBType);
4402 /***********************************************************************
4403 * NdrClearOutParameters [RPCRT4.@]
4405 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4406 PFORMAT_STRING pFormat,
4409 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4412 /***********************************************************************
4413 * NdrConvert [RPCRT4.@]
4415 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4417 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4418 /* FIXME: since this stub doesn't do any converting, the proper behavior
4419 is to raise an exception */
4422 /***********************************************************************
4423 * NdrConvert2 [RPCRT4.@]
4425 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4427 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4428 pStubMsg, pFormat, NumberParams);
4429 /* FIXME: since this stub doesn't do any converting, the proper behavior
4430 is to raise an exception */
4433 #include "pshpack1.h"
4434 typedef struct _NDR_CSTRUCT_FORMAT
4437 unsigned char alignment;
4438 unsigned short memory_size;
4439 short offset_to_array_description;
4440 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4441 #include "poppack.h"
4443 /***********************************************************************
4444 * NdrConformantStructMarshall [RPCRT4.@]
4446 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4447 unsigned char *pMemory,
4448 PFORMAT_STRING pFormat)
4450 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4451 PFORMAT_STRING pCArrayFormat;
4452 ULONG esize, bufsize;
4454 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4456 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4457 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4459 ERR("invalid format type %x\n", pCStructFormat->type);
4460 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4464 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4465 pCStructFormat->offset_to_array_description;
4466 if (*pCArrayFormat != RPC_FC_CARRAY)
4468 ERR("invalid array format type %x\n", pCStructFormat->type);
4469 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4472 esize = *(const WORD*)(pCArrayFormat+2);
4474 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4475 pCArrayFormat + 4, 0);
4477 WriteConformance(pStubMsg);
4479 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4481 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4483 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4484 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4486 ERR("integer overflow of memory_size %u with bufsize %u\n",
4487 pCStructFormat->memory_size, bufsize);
4488 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4490 /* copy constant sized part of struct */
4491 pStubMsg->BufferMark = pStubMsg->Buffer;
4492 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4494 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4495 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4500 /***********************************************************************
4501 * NdrConformantStructUnmarshall [RPCRT4.@]
4503 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4504 unsigned char **ppMemory,
4505 PFORMAT_STRING pFormat,
4506 unsigned char fMustAlloc)
4508 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4509 PFORMAT_STRING pCArrayFormat;
4510 ULONG esize, bufsize;
4511 unsigned char *saved_buffer;
4513 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4515 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4516 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4518 ERR("invalid format type %x\n", pCStructFormat->type);
4519 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4522 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4523 pCStructFormat->offset_to_array_description;
4524 if (*pCArrayFormat != RPC_FC_CARRAY)
4526 ERR("invalid array format type %x\n", pCStructFormat->type);
4527 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4530 esize = *(const WORD*)(pCArrayFormat+2);
4532 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4534 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4536 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4538 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4539 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4541 ERR("integer overflow of memory_size %u with bufsize %u\n",
4542 pCStructFormat->memory_size, bufsize);
4543 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4548 SIZE_T size = pCStructFormat->memory_size + bufsize;
4549 *ppMemory = NdrAllocate(pStubMsg, size);
4553 if (!pStubMsg->IsClient && !*ppMemory)
4554 /* for servers, we just point straight into the RPC buffer */
4555 *ppMemory = pStubMsg->Buffer;
4558 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4559 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4560 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4561 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4563 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4564 if (*ppMemory != saved_buffer)
4565 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4570 /***********************************************************************
4571 * NdrConformantStructBufferSize [RPCRT4.@]
4573 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4574 unsigned char *pMemory,
4575 PFORMAT_STRING pFormat)
4577 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4578 PFORMAT_STRING pCArrayFormat;
4581 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4583 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4584 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4586 ERR("invalid format type %x\n", pCStructFormat->type);
4587 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4590 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4591 pCStructFormat->offset_to_array_description;
4592 if (*pCArrayFormat != RPC_FC_CARRAY)
4594 ERR("invalid array format type %x\n", pCStructFormat->type);
4595 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4598 esize = *(const WORD*)(pCArrayFormat+2);
4600 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4601 SizeConformance(pStubMsg);
4603 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4605 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4607 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4608 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4610 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4611 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4614 /***********************************************************************
4615 * NdrConformantStructMemorySize [RPCRT4.@]
4617 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4618 PFORMAT_STRING pFormat)
4624 /***********************************************************************
4625 * NdrConformantStructFree [RPCRT4.@]
4627 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4628 unsigned char *pMemory,
4629 PFORMAT_STRING pFormat)
4631 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4632 PFORMAT_STRING pCArrayFormat;
4634 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4636 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4637 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4639 ERR("invalid format type %x\n", pCStructFormat->type);
4640 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4644 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4645 pCStructFormat->offset_to_array_description;
4646 if (*pCArrayFormat != RPC_FC_CARRAY)
4648 ERR("invalid array format type %x\n", pCStructFormat->type);
4649 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4653 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4654 pCArrayFormat + 4, 0);
4656 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4658 /* copy constant sized part of struct */
4659 pStubMsg->BufferMark = pStubMsg->Buffer;
4661 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4662 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4665 /***********************************************************************
4666 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4668 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4669 unsigned char *pMemory,
4670 PFORMAT_STRING pFormat)
4672 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4673 PFORMAT_STRING pCVArrayFormat;
4675 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4677 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4678 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4680 ERR("invalid format type %x\n", pCVStructFormat->type);
4681 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4685 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4686 pCVStructFormat->offset_to_array_description;
4688 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4689 pMemory + pCVStructFormat->memory_size,
4692 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4694 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4696 /* write constant sized part */
4697 pStubMsg->BufferMark = pStubMsg->Buffer;
4698 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4700 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4701 pMemory + pCVStructFormat->memory_size,
4702 pCVArrayFormat, FALSE /* fHasPointers */);
4704 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4709 /***********************************************************************
4710 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4712 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4713 unsigned char **ppMemory,
4714 PFORMAT_STRING pFormat,
4715 unsigned char fMustAlloc)
4717 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4718 PFORMAT_STRING pCVArrayFormat;
4719 ULONG memsize, bufsize;
4720 unsigned char *saved_buffer, *saved_array_buffer;
4722 unsigned char *array_memory;
4724 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4726 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4727 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4729 ERR("invalid format type %x\n", pCVStructFormat->type);
4730 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4734 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4735 pCVStructFormat->offset_to_array_description;
4737 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4740 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4742 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4744 /* work out how much memory to allocate if we need to do so */
4745 if (!fMustAlloc && !*ppMemory)
4749 SIZE_T size = pCVStructFormat->memory_size + memsize;
4750 *ppMemory = NdrAllocate(pStubMsg, size);
4753 /* mark the start of the constant data */
4754 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4755 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4757 array_memory = *ppMemory + pCVStructFormat->memory_size;
4758 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
4759 &array_memory, pCVArrayFormat,
4760 FALSE /* fMustAlloc */,
4761 FALSE /* fUseServerBufferMemory */,
4762 FALSE /* fUnmarshall */);
4764 /* save offset in case unmarshalling pointers changes it */
4765 offset = pStubMsg->Offset;
4767 /* mark the start of the array data */
4768 saved_array_buffer = pStubMsg->Buffer;
4769 safe_buffer_increment(pStubMsg, bufsize);
4771 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4773 /* copy the constant data */
4774 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
4775 /* copy the array data */
4776 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
4777 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
4778 saved_array_buffer, bufsize);
4780 if (*pCVArrayFormat == RPC_FC_C_CSTRING)
4781 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
4782 else if (*pCVArrayFormat == RPC_FC_C_WSTRING)
4783 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
4788 /***********************************************************************
4789 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4791 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4792 unsigned char *pMemory,
4793 PFORMAT_STRING pFormat)
4795 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4796 PFORMAT_STRING pCVArrayFormat;
4798 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4800 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4801 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4803 ERR("invalid format type %x\n", pCVStructFormat->type);
4804 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4808 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4809 pCVStructFormat->offset_to_array_description;
4810 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
4811 pMemory + pCVStructFormat->memory_size,
4814 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4816 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4818 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4820 array_buffer_size(*pCVArrayFormat, pStubMsg,
4821 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4822 FALSE /* fHasPointers */);
4824 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4827 /***********************************************************************
4828 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4830 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4831 PFORMAT_STRING pFormat)
4833 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4834 PFORMAT_STRING pCVArrayFormat;
4836 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4838 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4839 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4841 ERR("invalid format type %x\n", pCVStructFormat->type);
4842 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4846 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4847 pCVStructFormat->offset_to_array_description;
4848 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
4850 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4852 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4854 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4855 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
4856 FALSE /* fHasPointers */);
4858 pStubMsg->MemorySize += pCVStructFormat->memory_size;
4860 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4862 return pStubMsg->MemorySize;
4865 /***********************************************************************
4866 * NdrConformantVaryingStructFree [RPCRT4.@]
4868 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4869 unsigned char *pMemory,
4870 PFORMAT_STRING pFormat)
4872 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4873 PFORMAT_STRING pCVArrayFormat;
4875 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4877 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4878 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4880 ERR("invalid format type %x\n", pCVStructFormat->type);
4881 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4885 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4886 pCVStructFormat->offset_to_array_description;
4887 array_free(*pCVArrayFormat, pStubMsg,
4888 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4889 FALSE /* fHasPointers */);
4891 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4893 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4896 #include "pshpack1.h"
4900 unsigned char alignment;
4901 unsigned short total_size;
4902 } NDR_SMFARRAY_FORMAT;
4907 unsigned char alignment;
4909 } NDR_LGFARRAY_FORMAT;
4910 #include "poppack.h"
4912 /***********************************************************************
4913 * NdrFixedArrayMarshall [RPCRT4.@]
4915 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4916 unsigned char *pMemory,
4917 PFORMAT_STRING pFormat)
4919 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4922 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4924 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4925 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4927 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4928 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4932 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4934 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4936 total_size = pSmFArrayFormat->total_size;
4937 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4941 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4942 total_size = pLgFArrayFormat->total_size;
4943 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4946 pStubMsg->BufferMark = pStubMsg->Buffer;
4947 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4949 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4954 /***********************************************************************
4955 * NdrFixedArrayUnmarshall [RPCRT4.@]
4957 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4958 unsigned char **ppMemory,
4959 PFORMAT_STRING pFormat,
4960 unsigned char fMustAlloc)
4962 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4964 unsigned char *saved_buffer;
4966 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4968 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4969 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4971 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4972 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4976 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4978 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4980 total_size = pSmFArrayFormat->total_size;
4981 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4985 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4986 total_size = pLgFArrayFormat->total_size;
4987 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4991 *ppMemory = NdrAllocate(pStubMsg, total_size);
4994 if (!pStubMsg->IsClient && !*ppMemory)
4995 /* for servers, we just point straight into the RPC buffer */
4996 *ppMemory = pStubMsg->Buffer;
4999 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5000 safe_buffer_increment(pStubMsg, total_size);
5001 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5003 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
5004 if (*ppMemory != saved_buffer)
5005 memcpy(*ppMemory, saved_buffer, total_size);
5010 /***********************************************************************
5011 * NdrFixedArrayBufferSize [RPCRT4.@]
5013 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5014 unsigned char *pMemory,
5015 PFORMAT_STRING pFormat)
5017 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5020 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5022 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5023 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5025 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5026 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5030 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
5032 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5034 total_size = pSmFArrayFormat->total_size;
5035 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5039 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5040 total_size = pLgFArrayFormat->total_size;
5041 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5043 safe_buffer_length_increment(pStubMsg, total_size);
5045 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5048 /***********************************************************************
5049 * NdrFixedArrayMemorySize [RPCRT4.@]
5051 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5052 PFORMAT_STRING pFormat)
5054 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5057 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5059 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5060 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5062 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5063 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5067 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5069 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5071 total_size = pSmFArrayFormat->total_size;
5072 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5076 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5077 total_size = pLgFArrayFormat->total_size;
5078 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5080 pStubMsg->BufferMark = pStubMsg->Buffer;
5081 safe_buffer_increment(pStubMsg, total_size);
5082 pStubMsg->MemorySize += total_size;
5084 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5089 /***********************************************************************
5090 * NdrFixedArrayFree [RPCRT4.@]
5092 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5093 unsigned char *pMemory,
5094 PFORMAT_STRING pFormat)
5096 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5098 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5100 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5101 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5103 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5104 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5108 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5109 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5112 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5113 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5116 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5119 /***********************************************************************
5120 * NdrVaryingArrayMarshall [RPCRT4.@]
5122 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5123 unsigned char *pMemory,
5124 PFORMAT_STRING pFormat)
5126 unsigned char alignment;
5127 DWORD elements, esize;
5130 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5132 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5133 (pFormat[0] != RPC_FC_LGVARRAY))
5135 ERR("invalid format type %x\n", pFormat[0]);
5136 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5140 alignment = pFormat[1] + 1;
5142 if (pFormat[0] == RPC_FC_SMVARRAY)
5145 pFormat += sizeof(WORD);
5146 elements = *(const WORD*)pFormat;
5147 pFormat += sizeof(WORD);
5152 pFormat += sizeof(DWORD);
5153 elements = *(const DWORD*)pFormat;
5154 pFormat += sizeof(DWORD);
5157 esize = *(const WORD*)pFormat;
5158 pFormat += sizeof(WORD);
5160 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5161 if ((pStubMsg->ActualCount > elements) ||
5162 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5164 RpcRaiseException(RPC_S_INVALID_BOUND);
5168 WriteVariance(pStubMsg);
5170 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
5172 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5173 pStubMsg->BufferMark = pStubMsg->Buffer;
5174 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5176 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5181 /***********************************************************************
5182 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5184 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5185 unsigned char **ppMemory,
5186 PFORMAT_STRING pFormat,
5187 unsigned char fMustAlloc)
5189 unsigned char alignment;
5190 DWORD size, elements, esize;
5192 unsigned char *saved_buffer;
5195 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5197 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5198 (pFormat[0] != RPC_FC_LGVARRAY))
5200 ERR("invalid format type %x\n", pFormat[0]);
5201 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5205 alignment = pFormat[1] + 1;
5207 if (pFormat[0] == RPC_FC_SMVARRAY)
5210 size = *(const WORD*)pFormat;
5211 pFormat += sizeof(WORD);
5212 elements = *(const WORD*)pFormat;
5213 pFormat += sizeof(WORD);
5218 size = *(const DWORD*)pFormat;
5219 pFormat += sizeof(DWORD);
5220 elements = *(const DWORD*)pFormat;
5221 pFormat += sizeof(DWORD);
5224 esize = *(const WORD*)pFormat;
5225 pFormat += sizeof(WORD);
5227 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5229 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5231 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5232 offset = pStubMsg->Offset;
5234 if (!fMustAlloc && !*ppMemory)
5237 *ppMemory = NdrAllocate(pStubMsg, size);
5238 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5239 safe_buffer_increment(pStubMsg, bufsize);
5241 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5243 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5248 /***********************************************************************
5249 * NdrVaryingArrayBufferSize [RPCRT4.@]
5251 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5252 unsigned char *pMemory,
5253 PFORMAT_STRING pFormat)
5255 unsigned char alignment;
5256 DWORD elements, esize;
5258 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5260 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5261 (pFormat[0] != RPC_FC_LGVARRAY))
5263 ERR("invalid format type %x\n", pFormat[0]);
5264 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5268 alignment = pFormat[1] + 1;
5270 if (pFormat[0] == RPC_FC_SMVARRAY)
5273 pFormat += sizeof(WORD);
5274 elements = *(const WORD*)pFormat;
5275 pFormat += sizeof(WORD);
5280 pFormat += sizeof(DWORD);
5281 elements = *(const DWORD*)pFormat;
5282 pFormat += sizeof(DWORD);
5285 esize = *(const WORD*)pFormat;
5286 pFormat += sizeof(WORD);
5288 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5289 if ((pStubMsg->ActualCount > elements) ||
5290 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5292 RpcRaiseException(RPC_S_INVALID_BOUND);
5296 SizeVariance(pStubMsg);
5298 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
5300 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5302 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5305 /***********************************************************************
5306 * NdrVaryingArrayMemorySize [RPCRT4.@]
5308 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5309 PFORMAT_STRING pFormat)
5311 unsigned char alignment;
5312 DWORD size, elements, esize;
5314 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5316 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5317 (pFormat[0] != RPC_FC_LGVARRAY))
5319 ERR("invalid format type %x\n", pFormat[0]);
5320 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5324 alignment = pFormat[1] + 1;
5326 if (pFormat[0] == RPC_FC_SMVARRAY)
5329 size = *(const WORD*)pFormat;
5330 pFormat += sizeof(WORD);
5331 elements = *(const WORD*)pFormat;
5332 pFormat += sizeof(WORD);
5337 size = *(const DWORD*)pFormat;
5338 pFormat += sizeof(DWORD);
5339 elements = *(const DWORD*)pFormat;
5340 pFormat += sizeof(DWORD);
5343 esize = *(const WORD*)pFormat;
5344 pFormat += sizeof(WORD);
5346 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5348 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5350 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5351 pStubMsg->MemorySize += size;
5353 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5355 return pStubMsg->MemorySize;
5358 /***********************************************************************
5359 * NdrVaryingArrayFree [RPCRT4.@]
5361 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5362 unsigned char *pMemory,
5363 PFORMAT_STRING pFormat)
5367 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5369 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5370 (pFormat[0] != RPC_FC_LGVARRAY))
5372 ERR("invalid format type %x\n", pFormat[0]);
5373 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5377 if (pFormat[0] == RPC_FC_SMVARRAY)
5380 pFormat += sizeof(WORD);
5381 elements = *(const WORD*)pFormat;
5382 pFormat += sizeof(WORD);
5387 pFormat += sizeof(DWORD);
5388 elements = *(const DWORD*)pFormat;
5389 pFormat += sizeof(DWORD);
5392 pFormat += sizeof(WORD);
5394 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5395 if ((pStubMsg->ActualCount > elements) ||
5396 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5398 RpcRaiseException(RPC_S_INVALID_BOUND);
5402 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5405 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5418 return *(const USHORT *)pMemory;
5422 return *(const ULONG *)pMemory;
5424 FIXME("Unhandled base type: 0x%02x\n", fc);
5429 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5431 PFORMAT_STRING pFormat)
5433 unsigned short num_arms, arm, type;
5435 num_arms = *(const SHORT*)pFormat & 0x0fff;
5437 for(arm = 0; arm < num_arms; arm++)
5439 if(discriminant == *(const ULONG*)pFormat)
5447 type = *(const unsigned short*)pFormat;
5448 TRACE("type %04x\n", type);
5449 if(arm == num_arms) /* default arm extras */
5453 ERR("no arm for 0x%x and no default case\n", discriminant);
5454 RpcRaiseException(RPC_S_INVALID_TAG);
5459 TRACE("falling back to empty default case for 0x%x\n", discriminant);
5466 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5468 unsigned short type;
5472 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5476 type = *(const unsigned short*)pFormat;
5477 if((type & 0xff00) == 0x8000)
5479 unsigned char basetype = LOBYTE(type);
5480 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5484 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5485 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5488 unsigned char *saved_buffer = NULL;
5489 int pointer_buffer_mark_set = 0;
5496 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5497 saved_buffer = pStubMsg->Buffer;
5498 if (pStubMsg->PointerBufferMark)
5500 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5501 pStubMsg->PointerBufferMark = NULL;
5502 pointer_buffer_mark_set = 1;
5505 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5507 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5508 if (pointer_buffer_mark_set)
5510 STD_OVERFLOW_CHECK(pStubMsg);
5511 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5512 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5514 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5515 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5516 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5518 pStubMsg->Buffer = saved_buffer + 4;
5522 m(pStubMsg, pMemory, desc);
5525 else FIXME("no marshaller for embedded type %02x\n", *desc);
5530 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5531 unsigned char **ppMemory,
5533 PFORMAT_STRING pFormat,
5534 unsigned char fMustAlloc)
5536 unsigned short type;
5540 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5544 type = *(const unsigned short*)pFormat;
5545 if((type & 0xff00) == 0x8000)
5547 unsigned char basetype = LOBYTE(type);
5548 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5552 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5553 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5556 unsigned char *saved_buffer = NULL;
5557 int pointer_buffer_mark_set = 0;
5564 ALIGN_POINTER(pStubMsg->Buffer, 4);
5565 saved_buffer = pStubMsg->Buffer;
5566 if (pStubMsg->PointerBufferMark)
5568 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5569 pStubMsg->PointerBufferMark = NULL;
5570 pointer_buffer_mark_set = 1;
5573 pStubMsg->Buffer += 4; /* for pointer ID */
5575 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5577 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5578 saved_buffer, pStubMsg->BufferEnd);
5579 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5582 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5583 if (pointer_buffer_mark_set)
5585 STD_OVERFLOW_CHECK(pStubMsg);
5586 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5587 pStubMsg->Buffer = saved_buffer + 4;
5591 m(pStubMsg, ppMemory, desc, fMustAlloc);
5594 else FIXME("no marshaller for embedded type %02x\n", *desc);
5599 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5600 unsigned char *pMemory,
5602 PFORMAT_STRING pFormat)
5604 unsigned short type;
5608 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5612 type = *(const unsigned short*)pFormat;
5613 if((type & 0xff00) == 0x8000)
5615 unsigned char basetype = LOBYTE(type);
5616 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5620 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5621 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5630 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5631 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5632 if (!pStubMsg->IgnoreEmbeddedPointers)
5634 int saved_buffer_length = pStubMsg->BufferLength;
5635 pStubMsg->BufferLength = pStubMsg->PointerLength;
5636 pStubMsg->PointerLength = 0;
5637 if(!pStubMsg->BufferLength)
5638 ERR("BufferLength == 0??\n");
5639 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5640 pStubMsg->PointerLength = pStubMsg->BufferLength;
5641 pStubMsg->BufferLength = saved_buffer_length;
5645 m(pStubMsg, pMemory, desc);
5648 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5652 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5654 PFORMAT_STRING pFormat)
5656 unsigned short type, size;
5658 size = *(const unsigned short*)pFormat;
5659 pStubMsg->Memory += size;
5662 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5666 type = *(const unsigned short*)pFormat;
5667 if((type & 0xff00) == 0x8000)
5669 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5673 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5674 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5675 unsigned char *saved_buffer;
5684 ALIGN_POINTER(pStubMsg->Buffer, 4);
5685 saved_buffer = pStubMsg->Buffer;
5686 safe_buffer_increment(pStubMsg, 4);
5687 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(void *));
5688 pStubMsg->MemorySize += sizeof(void *);
5689 if (!pStubMsg->IgnoreEmbeddedPointers)
5690 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5693 return m(pStubMsg, desc);
5696 else FIXME("no marshaller for embedded type %02x\n", *desc);
5699 TRACE("size %d\n", size);
5703 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5704 unsigned char *pMemory,
5706 PFORMAT_STRING pFormat)
5708 unsigned short type;
5712 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5716 type = *(const unsigned short*)pFormat;
5717 if((type & 0xff00) != 0x8000)
5719 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5720 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5729 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5732 m(pStubMsg, pMemory, desc);
5738 /***********************************************************************
5739 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5741 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5742 unsigned char *pMemory,
5743 PFORMAT_STRING pFormat)
5745 unsigned char switch_type;
5746 unsigned char increment;
5749 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5752 switch_type = *pFormat & 0xf;
5753 increment = (*pFormat & 0xf0) >> 4;
5756 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5758 switch_value = get_discriminant(switch_type, pMemory);
5759 TRACE("got switch value 0x%x\n", switch_value);
5761 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5762 pMemory += increment;
5764 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5767 /***********************************************************************
5768 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5770 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5771 unsigned char **ppMemory,
5772 PFORMAT_STRING pFormat,
5773 unsigned char fMustAlloc)
5775 unsigned char switch_type;
5776 unsigned char increment;
5778 unsigned short size;
5779 unsigned char *pMemoryArm;
5781 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5784 switch_type = *pFormat & 0xf;
5785 increment = (*pFormat & 0xf0) >> 4;
5788 ALIGN_POINTER(pStubMsg->Buffer, increment);
5789 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5790 TRACE("got switch value 0x%x\n", switch_value);
5792 size = *(const unsigned short*)pFormat + increment;
5793 if (!fMustAlloc && !*ppMemory)
5796 *ppMemory = NdrAllocate(pStubMsg, size);
5798 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
5799 * since the arm is part of the memory block that is encompassed by
5800 * the whole union. Memory is forced to allocate when pointers
5801 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
5802 * clearing the memory we pass in to the unmarshaller */
5804 memset(*ppMemory, 0, size);
5806 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5807 pMemoryArm = *ppMemory + increment;
5809 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, FALSE);
5812 /***********************************************************************
5813 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5815 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5816 unsigned char *pMemory,
5817 PFORMAT_STRING pFormat)
5819 unsigned char switch_type;
5820 unsigned char increment;
5823 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5826 switch_type = *pFormat & 0xf;
5827 increment = (*pFormat & 0xf0) >> 4;
5830 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5831 switch_value = get_discriminant(switch_type, pMemory);
5832 TRACE("got switch value 0x%x\n", switch_value);
5834 /* Add discriminant size */
5835 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5836 pMemory += increment;
5838 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5841 /***********************************************************************
5842 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5844 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5845 PFORMAT_STRING pFormat)
5847 unsigned char switch_type;
5848 unsigned char increment;
5851 switch_type = *pFormat & 0xf;
5852 increment = (*pFormat & 0xf0) >> 4;
5855 ALIGN_POINTER(pStubMsg->Buffer, increment);
5856 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5857 TRACE("got switch value 0x%x\n", switch_value);
5859 pStubMsg->Memory += increment;
5861 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5864 /***********************************************************************
5865 * NdrEncapsulatedUnionFree [RPCRT4.@]
5867 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5868 unsigned char *pMemory,
5869 PFORMAT_STRING pFormat)
5871 unsigned char switch_type;
5872 unsigned char increment;
5875 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5878 switch_type = *pFormat & 0xf;
5879 increment = (*pFormat & 0xf0) >> 4;
5882 switch_value = get_discriminant(switch_type, pMemory);
5883 TRACE("got switch value 0x%x\n", switch_value);
5885 pMemory += increment;
5887 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5890 /***********************************************************************
5891 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5893 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5894 unsigned char *pMemory,
5895 PFORMAT_STRING pFormat)
5897 unsigned char switch_type;
5899 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5902 switch_type = *pFormat;
5905 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5906 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5907 /* Marshall discriminant */
5908 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5910 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5913 static LONG unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5914 PFORMAT_STRING *ppFormat)
5916 LONG discriminant = 0;
5926 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5935 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5936 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5944 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5945 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5950 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5954 if (pStubMsg->fHasNewCorrDesc)
5958 return discriminant;
5961 /**********************************************************************
5962 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5964 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5965 unsigned char **ppMemory,
5966 PFORMAT_STRING pFormat,
5967 unsigned char fMustAlloc)
5970 unsigned short size;
5972 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5975 /* Unmarshall discriminant */
5976 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5977 TRACE("unmarshalled discriminant %x\n", discriminant);
5979 pFormat += *(const SHORT*)pFormat;
5981 size = *(const unsigned short*)pFormat;
5983 if (!fMustAlloc && !*ppMemory)
5986 *ppMemory = NdrAllocate(pStubMsg, size);
5988 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
5989 * since the arm is part of the memory block that is encompassed by
5990 * the whole union. Memory is forced to allocate when pointers
5991 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
5992 * clearing the memory we pass in to the unmarshaller */
5994 memset(*ppMemory, 0, size);
5996 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, FALSE);
5999 /***********************************************************************
6000 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6002 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6003 unsigned char *pMemory,
6004 PFORMAT_STRING pFormat)
6006 unsigned char switch_type;
6008 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6011 switch_type = *pFormat;
6014 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6015 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6016 /* Add discriminant size */
6017 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6019 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6022 /***********************************************************************
6023 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6025 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6026 PFORMAT_STRING pFormat)
6031 /* Unmarshall discriminant */
6032 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6033 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
6035 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
6038 /***********************************************************************
6039 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6041 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6042 unsigned char *pMemory,
6043 PFORMAT_STRING pFormat)
6045 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6049 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6050 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6052 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6055 /***********************************************************************
6056 * NdrByteCountPointerMarshall [RPCRT4.@]
6058 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6059 unsigned char *pMemory,
6060 PFORMAT_STRING pFormat)
6066 /***********************************************************************
6067 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6069 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6070 unsigned char **ppMemory,
6071 PFORMAT_STRING pFormat,
6072 unsigned char fMustAlloc)
6078 /***********************************************************************
6079 * NdrByteCountPointerBufferSize [RPCRT4.@]
6081 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6082 unsigned char *pMemory,
6083 PFORMAT_STRING pFormat)
6088 /***********************************************************************
6089 * NdrByteCountPointerMemorySize [internal]
6091 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6092 PFORMAT_STRING pFormat)
6098 /***********************************************************************
6099 * NdrByteCountPointerFree [RPCRT4.@]
6101 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6102 unsigned char *pMemory,
6103 PFORMAT_STRING pFormat)
6108 /***********************************************************************
6109 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6111 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6112 unsigned char *pMemory,
6113 PFORMAT_STRING pFormat)
6119 /***********************************************************************
6120 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6122 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6123 unsigned char **ppMemory,
6124 PFORMAT_STRING pFormat,
6125 unsigned char fMustAlloc)
6131 /***********************************************************************
6132 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6134 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6135 unsigned char *pMemory,
6136 PFORMAT_STRING pFormat)
6141 /***********************************************************************
6142 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6144 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6145 PFORMAT_STRING pFormat)
6151 /***********************************************************************
6152 * NdrXmitOrRepAsFree [RPCRT4.@]
6154 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6155 unsigned char *pMemory,
6156 PFORMAT_STRING pFormat)
6161 /***********************************************************************
6162 * NdrRangeMarshall [internal]
6164 static unsigned char *WINAPI NdrRangeMarshall(
6165 PMIDL_STUB_MESSAGE pStubMsg,
6166 unsigned char *pMemory,
6167 PFORMAT_STRING pFormat)
6169 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6170 unsigned char base_type;
6172 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6174 if (pRange->type != RPC_FC_RANGE)
6176 ERR("invalid format type %x\n", pRange->type);
6177 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6181 base_type = pRange->flags_type & 0xf;
6183 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6186 /***********************************************************************
6187 * NdrRangeUnmarshall [RPCRT4.@]
6189 unsigned char *WINAPI NdrRangeUnmarshall(
6190 PMIDL_STUB_MESSAGE pStubMsg,
6191 unsigned char **ppMemory,
6192 PFORMAT_STRING pFormat,
6193 unsigned char fMustAlloc)
6195 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6196 unsigned char base_type;
6198 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6200 if (pRange->type != RPC_FC_RANGE)
6202 ERR("invalid format type %x\n", pRange->type);
6203 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6206 base_type = pRange->flags_type & 0xf;
6208 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6209 base_type, pRange->low_value, pRange->high_value);
6211 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6214 ALIGN_POINTER(pStubMsg->Buffer, sizeof(wire_type)); \
6215 if (!fMustAlloc && !*ppMemory) \
6216 fMustAlloc = TRUE; \
6218 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6219 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6221 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6222 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6223 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6225 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6226 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6228 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6229 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6230 (mem_type)pRange->high_value); \
6231 RpcRaiseException(RPC_S_INVALID_BOUND); \
6234 TRACE("*ppMemory: %p\n", *ppMemory); \
6235 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6236 pStubMsg->Buffer += sizeof(wire_type); \
6243 RANGE_UNMARSHALL(UCHAR, UCHAR, "%d");
6244 TRACE("value: 0x%02x\n", **ppMemory);
6248 RANGE_UNMARSHALL(CHAR, CHAR, "%u");
6249 TRACE("value: 0x%02x\n", **ppMemory);
6251 case RPC_FC_WCHAR: /* FIXME: valid? */
6253 RANGE_UNMARSHALL(USHORT, USHORT, "%u");
6254 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6257 RANGE_UNMARSHALL(SHORT, SHORT, "%d");
6258 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6262 RANGE_UNMARSHALL(LONG, LONG, "%d");
6263 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6266 RANGE_UNMARSHALL(ULONG, ULONG, "%u");
6267 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6270 RANGE_UNMARSHALL(UINT, USHORT, "%u");
6271 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6277 ERR("invalid range base type: 0x%02x\n", base_type);
6278 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6284 /***********************************************************************
6285 * NdrRangeBufferSize [internal]
6287 static void WINAPI NdrRangeBufferSize(
6288 PMIDL_STUB_MESSAGE pStubMsg,
6289 unsigned char *pMemory,
6290 PFORMAT_STRING pFormat)
6292 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6293 unsigned char base_type;
6295 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6297 if (pRange->type != RPC_FC_RANGE)
6299 ERR("invalid format type %x\n", pRange->type);
6300 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6302 base_type = pRange->flags_type & 0xf;
6304 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6307 /***********************************************************************
6308 * NdrRangeMemorySize [internal]
6310 static ULONG WINAPI NdrRangeMemorySize(
6311 PMIDL_STUB_MESSAGE pStubMsg,
6312 PFORMAT_STRING pFormat)
6314 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6315 unsigned char base_type;
6317 if (pRange->type != RPC_FC_RANGE)
6319 ERR("invalid format type %x\n", pRange->type);
6320 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6323 base_type = pRange->flags_type & 0xf;
6325 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6328 /***********************************************************************
6329 * NdrRangeFree [internal]
6331 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6332 unsigned char *pMemory,
6333 PFORMAT_STRING pFormat)
6335 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6340 /***********************************************************************
6341 * NdrBaseTypeMarshall [internal]
6343 static unsigned char *WINAPI NdrBaseTypeMarshall(
6344 PMIDL_STUB_MESSAGE pStubMsg,
6345 unsigned char *pMemory,
6346 PFORMAT_STRING pFormat)
6348 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6356 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6357 TRACE("value: 0x%02x\n", *pMemory);
6362 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6363 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6364 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6368 case RPC_FC_ERROR_STATUS_T:
6370 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
6371 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6372 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6375 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
6376 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6379 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
6380 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6383 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
6384 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6385 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6388 /* only 16-bits on the wire, so do a sanity check */
6389 if (*(UINT *)pMemory > SHRT_MAX)
6390 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6391 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6392 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6393 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6394 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
6395 pStubMsg->Buffer += sizeof(USHORT);
6396 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6401 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6404 /* FIXME: what is the correct return value? */
6408 /***********************************************************************
6409 * NdrBaseTypeUnmarshall [internal]
6411 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6412 PMIDL_STUB_MESSAGE pStubMsg,
6413 unsigned char **ppMemory,
6414 PFORMAT_STRING pFormat,
6415 unsigned char fMustAlloc)
6417 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6419 #define BASE_TYPE_UNMARSHALL(type) \
6420 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6421 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6423 *ppMemory = pStubMsg->Buffer; \
6424 TRACE("*ppMemory: %p\n", *ppMemory); \
6425 safe_buffer_increment(pStubMsg, sizeof(type)); \
6430 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6431 TRACE("*ppMemory: %p\n", *ppMemory); \
6432 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6441 BASE_TYPE_UNMARSHALL(UCHAR);
6442 TRACE("value: 0x%02x\n", **ppMemory);
6447 BASE_TYPE_UNMARSHALL(USHORT);
6448 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6452 case RPC_FC_ERROR_STATUS_T:
6454 BASE_TYPE_UNMARSHALL(ULONG);
6455 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6458 BASE_TYPE_UNMARSHALL(float);
6459 TRACE("value: %f\n", **(float **)ppMemory);
6462 BASE_TYPE_UNMARSHALL(double);
6463 TRACE("value: %f\n", **(double **)ppMemory);
6466 BASE_TYPE_UNMARSHALL(ULONGLONG);
6467 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6470 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6471 if (!fMustAlloc && !*ppMemory)
6474 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6475 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
6476 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6477 TRACE("*ppMemory: %p\n", *ppMemory);
6478 /* 16-bits on the wire, but int in memory */
6479 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
6480 pStubMsg->Buffer += sizeof(USHORT);
6481 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6486 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6488 #undef BASE_TYPE_UNMARSHALL
6490 /* FIXME: what is the correct return value? */
6495 /***********************************************************************
6496 * NdrBaseTypeBufferSize [internal]
6498 static void WINAPI NdrBaseTypeBufferSize(
6499 PMIDL_STUB_MESSAGE pStubMsg,
6500 unsigned char *pMemory,
6501 PFORMAT_STRING pFormat)
6503 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6511 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6517 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
6518 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6523 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
6524 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6527 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
6528 safe_buffer_length_increment(pStubMsg, sizeof(float));
6531 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
6532 safe_buffer_length_increment(pStubMsg, sizeof(double));
6535 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
6536 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6538 case RPC_FC_ERROR_STATUS_T:
6539 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
6540 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6545 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6549 /***********************************************************************
6550 * NdrBaseTypeMemorySize [internal]
6552 static ULONG WINAPI NdrBaseTypeMemorySize(
6553 PMIDL_STUB_MESSAGE pStubMsg,
6554 PFORMAT_STRING pFormat)
6556 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6564 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6565 pStubMsg->MemorySize += sizeof(UCHAR);
6566 return sizeof(UCHAR);
6570 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6571 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6572 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(USHORT));
6573 pStubMsg->MemorySize += sizeof(USHORT);
6574 return sizeof(USHORT);
6578 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
6579 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6580 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(ULONG));
6581 pStubMsg->MemorySize += sizeof(ULONG);
6582 return sizeof(ULONG);
6584 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
6585 safe_buffer_increment(pStubMsg, sizeof(float));
6586 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(float));
6587 pStubMsg->MemorySize += sizeof(float);
6588 return sizeof(float);
6590 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
6591 safe_buffer_increment(pStubMsg, sizeof(double));
6592 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(double));
6593 pStubMsg->MemorySize += sizeof(double);
6594 return sizeof(double);
6596 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
6597 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6598 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(ULONGLONG));
6599 pStubMsg->MemorySize += sizeof(ULONGLONG);
6600 return sizeof(ULONGLONG);
6601 case RPC_FC_ERROR_STATUS_T:
6602 ALIGN_POINTER(pStubMsg->Buffer, sizeof(error_status_t));
6603 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6604 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(error_status_t));
6605 pStubMsg->MemorySize += sizeof(error_status_t);
6606 return sizeof(error_status_t);
6608 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6609 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6610 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(UINT));
6611 pStubMsg->MemorySize += sizeof(UINT);
6612 return sizeof(UINT);
6614 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(void *));
6615 pStubMsg->MemorySize += sizeof(void *);
6616 return sizeof(void *);
6618 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6623 /***********************************************************************
6624 * NdrBaseTypeFree [internal]
6626 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6627 unsigned char *pMemory,
6628 PFORMAT_STRING pFormat)
6630 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6635 /***********************************************************************
6636 * NdrContextHandleBufferSize [internal]
6638 static void WINAPI NdrContextHandleBufferSize(
6639 PMIDL_STUB_MESSAGE pStubMsg,
6640 unsigned char *pMemory,
6641 PFORMAT_STRING pFormat)
6643 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6645 if (*pFormat != RPC_FC_BIND_CONTEXT)
6647 ERR("invalid format type %x\n", *pFormat);
6648 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6650 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
6651 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6654 /***********************************************************************
6655 * NdrContextHandleMarshall [internal]
6657 static unsigned char *WINAPI NdrContextHandleMarshall(
6658 PMIDL_STUB_MESSAGE pStubMsg,
6659 unsigned char *pMemory,
6660 PFORMAT_STRING pFormat)
6662 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6664 if (*pFormat != RPC_FC_BIND_CONTEXT)
6666 ERR("invalid format type %x\n", *pFormat);
6667 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6669 TRACE("flags: 0x%02x\n", pFormat[1]);
6671 if (pFormat[1] & 0x80)
6672 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6674 NdrClientContextMarshall(pStubMsg, pMemory, FALSE);
6679 /***********************************************************************
6680 * NdrContextHandleUnmarshall [internal]
6682 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6683 PMIDL_STUB_MESSAGE pStubMsg,
6684 unsigned char **ppMemory,
6685 PFORMAT_STRING pFormat,
6686 unsigned char fMustAlloc)
6688 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6689 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6691 if (*pFormat != RPC_FC_BIND_CONTEXT)
6693 ERR("invalid format type %x\n", *pFormat);
6694 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6696 TRACE("flags: 0x%02x\n", pFormat[1]);
6698 /* [out]-only or [ret] param */
6699 if ((pFormat[1] & 0x60) == 0x20)
6700 **(NDR_CCONTEXT **)ppMemory = NULL;
6701 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6706 /***********************************************************************
6707 * NdrClientContextMarshall [RPCRT4.@]
6709 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6710 NDR_CCONTEXT ContextHandle,
6713 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
6715 ALIGN_POINTER_CLEAR(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 /* FIXME: what does fCheck do? */
6725 NDRCContextMarshall(ContextHandle,
6728 pStubMsg->Buffer += cbNDRContext;
6731 /***********************************************************************
6732 * NdrClientContextUnmarshall [RPCRT4.@]
6734 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6735 NDR_CCONTEXT * pContextHandle,
6736 RPC_BINDING_HANDLE BindHandle)
6738 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
6740 ALIGN_POINTER(pStubMsg->Buffer, 4);
6742 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
6743 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6745 NDRCContextUnmarshall(pContextHandle,
6748 pStubMsg->RpcMsg->DataRepresentation);
6750 pStubMsg->Buffer += cbNDRContext;
6753 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6754 NDR_SCONTEXT ContextHandle,
6755 NDR_RUNDOWN RundownRoutine )
6757 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
6759 ALIGN_POINTER(pStubMsg->Buffer, 4);
6761 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6763 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6764 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6765 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6768 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6769 pStubMsg->Buffer, RundownRoutine, NULL,
6770 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6771 pStubMsg->Buffer += cbNDRContext;
6774 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6776 NDR_SCONTEXT ContextHandle;
6778 TRACE("(%p)\n", pStubMsg);
6780 ALIGN_POINTER(pStubMsg->Buffer, 4);
6782 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6784 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6785 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6786 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6789 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6791 pStubMsg->RpcMsg->DataRepresentation,
6792 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6793 pStubMsg->Buffer += cbNDRContext;
6795 return ContextHandle;
6798 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6799 unsigned char* pMemory,
6800 PFORMAT_STRING pFormat)
6802 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6805 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6806 PFORMAT_STRING pFormat)
6808 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6809 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6811 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6813 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6814 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6815 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6816 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6817 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6819 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6820 if_id = &sif->InterfaceId;
6823 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
6824 pStubMsg->RpcMsg->DataRepresentation, if_id,
6828 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6829 NDR_SCONTEXT ContextHandle,
6830 NDR_RUNDOWN RundownRoutine,
6831 PFORMAT_STRING pFormat)
6833 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6834 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6836 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6838 ALIGN_POINTER(pStubMsg->Buffer, 4);
6840 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6842 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6843 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6844 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6847 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6848 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6849 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6850 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6851 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6853 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6854 if_id = &sif->InterfaceId;
6857 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6858 pStubMsg->Buffer, RundownRoutine, if_id, flags);
6859 pStubMsg->Buffer += cbNDRContext;
6862 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6863 PFORMAT_STRING pFormat)
6865 NDR_SCONTEXT ContextHandle;
6866 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6867 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6869 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6871 ALIGN_POINTER(pStubMsg->Buffer, 4);
6873 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6875 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6876 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6877 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6880 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6881 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6882 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6883 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6884 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6886 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6887 if_id = &sif->InterfaceId;
6890 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6892 pStubMsg->RpcMsg->DataRepresentation,
6894 pStubMsg->Buffer += cbNDRContext;
6896 return ContextHandle;
6899 /***********************************************************************
6900 * NdrCorrelationInitialize [RPCRT4.@]
6902 * Initializes correlation validity checking.
6905 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6906 * pMemory [I] Pointer to memory to use as a cache.
6907 * CacheSize [I] Size of the memory pointed to by pMemory.
6908 * Flags [I] Reserved. Set to zero.
6913 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
6915 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
6916 pStubMsg->fHasNewCorrDesc = TRUE;
6919 /***********************************************************************
6920 * NdrCorrelationPass [RPCRT4.@]
6922 * Performs correlation validity checking.
6925 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6930 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
6932 FIXME("(%p): stub\n", pStubMsg);
6935 /***********************************************************************
6936 * NdrCorrelationFree [RPCRT4.@]
6938 * Frees any resources used while unmarshalling parameters that need
6939 * correlation validity checking.
6942 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6947 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
6949 FIXME("(%p): stub\n", pStubMsg);