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
43 #include "wine/unicode.h"
44 #include "wine/rpcfc.h"
46 #include "wine/debug.h"
48 WINE_DEFAULT_DEBUG_CHANNEL(ole);
51 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
52 (*((UINT32 *)(pchar)) = (uint32))
54 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
55 (*((UINT32 *)(pchar)))
57 /* these would work for i386 too, but less efficient */
58 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
59 (*(pchar) = LOBYTE(LOWORD(uint32)), \
60 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
61 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
62 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
63 (uint32)) /* allow as r-value */
65 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
67 MAKEWORD(*(pchar), *((pchar)+1)), \
68 MAKEWORD(*((pchar)+2), *((pchar)+3))))
71 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
72 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
73 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
74 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
75 *(pchar) = HIBYTE(HIWORD(uint32)), \
76 (uint32)) /* allow as r-value */
78 #define BIG_ENDIAN_UINT32_READ(pchar) \
80 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
81 MAKEWORD(*((pchar)+1), *(pchar))))
83 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
84 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
85 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
86 # define NDR_LOCAL_UINT32_READ(pchar) \
87 BIG_ENDIAN_UINT32_READ(pchar)
89 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
90 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
91 # define NDR_LOCAL_UINT32_READ(pchar) \
92 LITTLE_ENDIAN_UINT32_READ(pchar)
95 /* _Align must be the desired alignment,
96 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
97 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
98 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
99 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
100 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
101 #define ALIGN_POINTER_CLEAR(_Ptr, _Align) \
103 memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \
104 ALIGN_POINTER(_Ptr, _Align); \
107 #define STD_OVERFLOW_CHECK(_Msg) do { \
108 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
109 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
110 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
113 #define NDR_POINTER_ID_BASE 0x20000
114 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
115 #define NDR_TABLE_SIZE 128
116 #define NDR_TABLE_MASK 127
118 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
119 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
120 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
121 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
122 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
124 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
125 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
126 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
128 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
130 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
131 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
132 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
133 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
137 NdrPointerMarshall, NdrPointerMarshall,
138 NdrPointerMarshall, NdrPointerMarshall,
140 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
141 NdrConformantStructMarshall, NdrConformantStructMarshall,
142 NdrConformantVaryingStructMarshall,
143 NdrComplexStructMarshall,
145 NdrConformantArrayMarshall,
146 NdrConformantVaryingArrayMarshall,
147 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
148 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
149 NdrComplexArrayMarshall,
151 NdrConformantStringMarshall, 0, 0,
152 NdrConformantStringMarshall,
153 NdrNonConformantStringMarshall, 0, 0, 0,
155 NdrEncapsulatedUnionMarshall,
156 NdrNonEncapsulatedUnionMarshall,
157 NdrByteCountPointerMarshall,
158 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
160 NdrInterfacePointerMarshall,
162 NdrContextHandleMarshall,
165 NdrUserMarshalMarshall,
170 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
172 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
173 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
174 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
175 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
177 NdrBaseTypeUnmarshall,
179 NdrPointerUnmarshall, NdrPointerUnmarshall,
180 NdrPointerUnmarshall, NdrPointerUnmarshall,
182 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
183 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
184 NdrConformantVaryingStructUnmarshall,
185 NdrComplexStructUnmarshall,
187 NdrConformantArrayUnmarshall,
188 NdrConformantVaryingArrayUnmarshall,
189 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
190 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
191 NdrComplexArrayUnmarshall,
193 NdrConformantStringUnmarshall, 0, 0,
194 NdrConformantStringUnmarshall,
195 NdrNonConformantStringUnmarshall, 0, 0, 0,
197 NdrEncapsulatedUnionUnmarshall,
198 NdrNonEncapsulatedUnionUnmarshall,
199 NdrByteCountPointerUnmarshall,
200 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
202 NdrInterfacePointerUnmarshall,
204 NdrContextHandleUnmarshall,
207 NdrUserMarshalUnmarshall,
212 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
214 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
215 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
216 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
217 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
219 NdrBaseTypeBufferSize,
221 NdrPointerBufferSize, NdrPointerBufferSize,
222 NdrPointerBufferSize, NdrPointerBufferSize,
224 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
225 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
226 NdrConformantVaryingStructBufferSize,
227 NdrComplexStructBufferSize,
229 NdrConformantArrayBufferSize,
230 NdrConformantVaryingArrayBufferSize,
231 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
232 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
233 NdrComplexArrayBufferSize,
235 NdrConformantStringBufferSize, 0, 0,
236 NdrConformantStringBufferSize,
237 NdrNonConformantStringBufferSize, 0, 0, 0,
239 NdrEncapsulatedUnionBufferSize,
240 NdrNonEncapsulatedUnionBufferSize,
241 NdrByteCountPointerBufferSize,
242 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
244 NdrInterfacePointerBufferSize,
246 NdrContextHandleBufferSize,
249 NdrUserMarshalBufferSize,
254 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
256 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
257 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
258 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
259 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
261 NdrBaseTypeMemorySize,
263 NdrPointerMemorySize, NdrPointerMemorySize,
264 NdrPointerMemorySize, NdrPointerMemorySize,
266 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
267 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
268 NdrConformantVaryingStructMemorySize,
269 NdrComplexStructMemorySize,
271 NdrConformantArrayMemorySize,
272 NdrConformantVaryingArrayMemorySize,
273 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
274 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
275 NdrComplexArrayMemorySize,
277 NdrConformantStringMemorySize, 0, 0,
278 NdrConformantStringMemorySize,
279 NdrNonConformantStringMemorySize, 0, 0, 0,
281 NdrEncapsulatedUnionMemorySize,
282 NdrNonEncapsulatedUnionMemorySize,
283 NdrByteCountPointerMemorySize,
284 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
286 NdrInterfacePointerMemorySize,
291 NdrUserMarshalMemorySize,
296 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
298 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
299 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
300 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
301 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
305 NdrPointerFree, NdrPointerFree,
306 NdrPointerFree, NdrPointerFree,
308 NdrSimpleStructFree, NdrSimpleStructFree,
309 NdrConformantStructFree, NdrConformantStructFree,
310 NdrConformantVaryingStructFree,
311 NdrComplexStructFree,
313 NdrConformantArrayFree,
314 NdrConformantVaryingArrayFree,
315 NdrFixedArrayFree, NdrFixedArrayFree,
316 NdrVaryingArrayFree, NdrVaryingArrayFree,
322 NdrEncapsulatedUnionFree,
323 NdrNonEncapsulatedUnionFree,
325 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
327 NdrInterfacePointerFree,
338 typedef struct _NDR_MEMORY_LIST
343 struct _NDR_MEMORY_LIST *next;
346 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
348 /***********************************************************************
349 * NdrAllocate [RPCRT4.@]
351 * Allocates a block of memory using pStubMsg->pfnAllocate.
354 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
355 * len [I] Size of memory block to allocate.
358 * The memory block of size len that was allocated.
361 * The memory block is always 8-byte aligned.
362 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
363 * exception is raised.
365 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
370 NDR_MEMORY_LIST *mem_list;
372 aligned_len = ALIGNED_LENGTH(len, 8);
373 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
374 /* check for overflow */
375 if (adjusted_len < len)
377 ERR("overflow of adjusted_len %d, len %d\n", adjusted_len, len);
378 RpcRaiseException(RPC_X_BAD_STUB_DATA);
381 p = pStubMsg->pfnAllocate(adjusted_len);
382 if (!p) RpcRaiseException(ERROR_OUTOFMEMORY);
384 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
385 mem_list->magic = MEML_MAGIC;
386 mem_list->size = aligned_len;
387 mem_list->reserved = 0;
388 mem_list->next = pStubMsg->pMemoryList;
389 pStubMsg->pMemoryList = mem_list;
395 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
397 TRACE("(%p, %p)\n", pStubMsg, Pointer);
399 pStubMsg->pfnFree(Pointer);
402 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
404 return (*(const ULONG *)pFormat != -1);
407 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
409 ALIGN_POINTER(pStubMsg->Buffer, 4);
410 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
411 RpcRaiseException(RPC_X_BAD_STUB_DATA);
412 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
413 pStubMsg->Buffer += 4;
414 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
415 if (pStubMsg->fHasNewCorrDesc)
421 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
423 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
425 pStubMsg->Offset = 0;
426 pStubMsg->ActualCount = pStubMsg->MaxCount;
430 ALIGN_POINTER(pStubMsg->Buffer, 4);
431 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
432 RpcRaiseException(RPC_X_BAD_STUB_DATA);
433 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
434 pStubMsg->Buffer += 4;
435 TRACE("offset is %d\n", pStubMsg->Offset);
436 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
437 pStubMsg->Buffer += 4;
438 TRACE("variance is %d\n", pStubMsg->ActualCount);
440 if ((pStubMsg->ActualCount > MaxValue) ||
441 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
443 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
444 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
445 RpcRaiseException(RPC_S_INVALID_BOUND);
450 if (pStubMsg->fHasNewCorrDesc)
456 /* writes the conformance value to the buffer */
457 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
459 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
460 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
461 RpcRaiseException(RPC_X_BAD_STUB_DATA);
462 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
463 pStubMsg->Buffer += 4;
466 /* writes the variance values to the buffer */
467 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
469 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
470 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
471 RpcRaiseException(RPC_X_BAD_STUB_DATA);
472 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
473 pStubMsg->Buffer += 4;
474 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
475 pStubMsg->Buffer += 4;
478 /* requests buffer space for the conformance value */
479 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
481 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
482 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
483 RpcRaiseException(RPC_X_BAD_STUB_DATA);
484 pStubMsg->BufferLength += 4;
487 /* requests buffer space for the variance values */
488 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
490 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
491 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
492 RpcRaiseException(RPC_X_BAD_STUB_DATA);
493 pStubMsg->BufferLength += 8;
496 PFORMAT_STRING ComputeConformanceOrVariance(
497 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
498 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
500 BYTE dtype = pFormat[0] & 0xf;
501 short ofs = *(const short *)&pFormat[2];
505 if (!IsConformanceOrVariancePresent(pFormat)) {
506 /* null descriptor */
511 switch (pFormat[0] & 0xf0) {
512 case RPC_FC_NORMAL_CONFORMANCE:
513 TRACE("normal conformance, ofs=%d\n", ofs);
516 case RPC_FC_POINTER_CONFORMANCE:
517 TRACE("pointer conformance, ofs=%d\n", ofs);
518 ptr = pStubMsg->Memory;
520 case RPC_FC_TOP_LEVEL_CONFORMANCE:
521 TRACE("toplevel conformance, ofs=%d\n", ofs);
522 if (pStubMsg->StackTop) {
523 ptr = pStubMsg->StackTop;
526 /* -Os mode, *pCount is already set */
530 case RPC_FC_CONSTANT_CONFORMANCE:
531 data = ofs | ((DWORD)pFormat[1] << 16);
532 TRACE("constant conformance, val=%d\n", data);
535 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
536 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
537 if (pStubMsg->StackTop) {
538 ptr = pStubMsg->StackTop;
546 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
549 switch (pFormat[1]) {
550 case RPC_FC_DEREFERENCE:
551 ptr = *(LPVOID*)((char *)ptr + ofs);
553 case RPC_FC_CALLBACK:
555 unsigned char *old_stack_top = pStubMsg->StackTop;
556 pStubMsg->StackTop = ptr;
558 /* ofs is index into StubDesc->apfnExprEval */
559 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
560 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
562 pStubMsg->StackTop = old_stack_top;
564 /* the callback function always stores the computed value in MaxCount */
565 *pCount = pStubMsg->MaxCount;
569 ptr = (char *)ptr + ofs;
582 data = *(USHORT*)ptr;
593 FIXME("unknown conformance data type %x\n", dtype);
596 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
599 switch (pFormat[1]) {
600 case RPC_FC_DEREFERENCE: /* already handled */
617 FIXME("unknown conformance op %d\n", pFormat[1]);
622 TRACE("resulting conformance is %ld\n", *pCount);
623 if (pStubMsg->fHasNewCorrDesc)
629 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
630 * the result overflows 32-bits */
631 static inline ULONG safe_multiply(ULONG a, ULONG b)
633 ULONGLONG ret = (ULONGLONG)a * b;
634 if (ret > 0xffffffff)
636 RpcRaiseException(RPC_S_INVALID_BOUND);
642 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
644 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
645 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
646 RpcRaiseException(RPC_X_BAD_STUB_DATA);
647 pStubMsg->Buffer += size;
650 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
652 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
654 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
655 pStubMsg->BufferLength, size);
656 RpcRaiseException(RPC_X_BAD_STUB_DATA);
658 pStubMsg->BufferLength += size;
661 /* copies data from the buffer, checking that there is enough data in the buffer
663 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
665 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
666 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
668 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
669 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
670 RpcRaiseException(RPC_X_BAD_STUB_DATA);
672 if (p == pStubMsg->Buffer)
673 ERR("pointer is the same as the buffer\n");
674 memcpy(p, pStubMsg->Buffer, size);
675 pStubMsg->Buffer += size;
678 /* copies data to the buffer, checking that there is enough space to do so */
679 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
681 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
682 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
684 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
685 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
687 RpcRaiseException(RPC_X_BAD_STUB_DATA);
689 memcpy(pStubMsg->Buffer, p, size);
690 pStubMsg->Buffer += size;
693 /* verify that string data sitting in the buffer is valid and safe to
695 static void validate_string_data(MIDL_STUB_MESSAGE *pStubMsg, ULONG bufsize, ULONG esize)
699 /* verify the buffer is safe to access */
700 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
701 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
703 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
704 pStubMsg->BufferEnd, pStubMsg->Buffer);
705 RpcRaiseException(RPC_X_BAD_STUB_DATA);
708 /* strings must always have null terminating bytes */
711 ERR("invalid string length of %d\n", bufsize / esize);
712 RpcRaiseException(RPC_S_INVALID_BOUND);
715 for (i = bufsize - esize; i < bufsize; i++)
716 if (pStubMsg->Buffer[i] != 0)
718 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
719 i, pStubMsg->Buffer[i]);
720 RpcRaiseException(RPC_S_INVALID_BOUND);
725 * NdrConformantString:
727 * What MS calls a ConformantString is, in DCE terminology,
728 * a Varying-Conformant String.
730 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
731 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
732 * into unmarshalled string)
733 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
735 * data: CHARTYPE[maxlen]
737 * ], where CHARTYPE is the appropriate character type (specified externally)
741 /***********************************************************************
742 * NdrConformantStringMarshall [RPCRT4.@]
744 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
745 unsigned char *pszMessage, PFORMAT_STRING pFormat)
749 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
751 if (*pFormat == RPC_FC_C_CSTRING) {
752 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
753 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
756 else if (*pFormat == RPC_FC_C_WSTRING) {
757 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
758 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
762 ERR("Unhandled string type: %#x\n", *pFormat);
763 /* FIXME: raise an exception. */
767 if (pFormat[1] == RPC_FC_STRING_SIZED)
768 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
770 pStubMsg->MaxCount = pStubMsg->ActualCount;
771 pStubMsg->Offset = 0;
772 WriteConformance(pStubMsg);
773 WriteVariance(pStubMsg);
775 size = safe_multiply(esize, pStubMsg->ActualCount);
776 safe_copy_to_buffer(pStubMsg, pszMessage, size); /* the string itself */
779 return NULL; /* is this always right? */
782 /***********************************************************************
783 * NdrConformantStringBufferSize [RPCRT4.@]
785 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
786 unsigned char* pMemory, PFORMAT_STRING pFormat)
790 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
792 SizeConformance(pStubMsg);
793 SizeVariance(pStubMsg);
795 if (*pFormat == RPC_FC_C_CSTRING) {
796 TRACE("string=%s\n", debugstr_a((char*)pMemory));
797 pStubMsg->ActualCount = strlen((char*)pMemory)+1;
800 else if (*pFormat == RPC_FC_C_WSTRING) {
801 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
802 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;
806 ERR("Unhandled string type: %#x\n", *pFormat);
807 /* FIXME: raise an exception */
811 if (pFormat[1] == RPC_FC_STRING_SIZED)
812 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
814 pStubMsg->MaxCount = pStubMsg->ActualCount;
816 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
819 /************************************************************************
820 * NdrConformantStringMemorySize [RPCRT4.@]
822 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
823 PFORMAT_STRING pFormat )
825 ULONG bufsize, memsize, esize;
827 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
829 ReadConformance(pStubMsg, NULL);
830 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
832 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
834 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
835 pStubMsg->ActualCount, pStubMsg->MaxCount);
836 RpcRaiseException(RPC_S_INVALID_BOUND);
838 if (pStubMsg->Offset)
840 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
841 RpcRaiseException(RPC_S_INVALID_BOUND);
844 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
845 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
847 ERR("Unhandled string type: %#x\n", *pFormat);
848 /* FIXME: raise an exception */
852 memsize = safe_multiply(esize, pStubMsg->MaxCount);
853 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
855 validate_string_data(pStubMsg, bufsize, esize);
857 safe_buffer_increment(pStubMsg, bufsize);
858 pStubMsg->MemorySize += memsize;
860 return pStubMsg->MemorySize;
863 /************************************************************************
864 * NdrConformantStringUnmarshall [RPCRT4.@]
866 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
867 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
869 ULONG bufsize, memsize, esize;
871 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
872 pStubMsg, *ppMemory, pFormat, fMustAlloc);
874 assert(pFormat && ppMemory && pStubMsg);
876 ReadConformance(pStubMsg, NULL);
877 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
879 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
881 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
882 pStubMsg->ActualCount, pStubMsg->MaxCount);
883 RpcRaiseException(RPC_S_INVALID_BOUND);
886 if (pStubMsg->Offset)
888 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
889 RpcRaiseException(RPC_S_INVALID_BOUND);
893 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
894 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
896 ERR("Unhandled string type: %#x\n", *pFormat);
897 /* FIXME: raise an exception */
901 memsize = safe_multiply(esize, pStubMsg->MaxCount);
902 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
904 validate_string_data(pStubMsg, bufsize, esize);
907 *ppMemory = NdrAllocate(pStubMsg, memsize);
910 if (!pStubMsg->IsClient && !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
911 /* if the data in the RPC buffer is big enough, we just point straight
913 *ppMemory = pStubMsg->Buffer;
915 *ppMemory = NdrAllocate(pStubMsg, memsize);
918 if (*ppMemory == pStubMsg->Buffer)
919 safe_buffer_increment(pStubMsg, bufsize);
921 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
923 if (*pFormat == RPC_FC_C_CSTRING) {
924 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
926 else if (*pFormat == RPC_FC_C_WSTRING) {
927 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
930 return NULL; /* FIXME: is this always right? */
933 /***********************************************************************
934 * NdrNonConformantStringMarshall [RPCRT4.@]
936 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
937 unsigned char *pMemory,
938 PFORMAT_STRING pFormat)
940 ULONG esize, size, maxsize;
942 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
944 maxsize = *(USHORT *)&pFormat[2];
946 if (*pFormat == RPC_FC_CSTRING)
949 const char *str = (const char *)pMemory;
950 for (i = 0; i < maxsize && *str; i++, str++)
952 TRACE("string=%s\n", debugstr_an(str, i));
953 pStubMsg->ActualCount = i + 1;
956 else if (*pFormat == RPC_FC_WSTRING)
959 const WCHAR *str = (const WCHAR *)pMemory;
960 for (i = 0; i < maxsize && *str; i++, str++)
962 TRACE("string=%s\n", debugstr_wn(str, i));
963 pStubMsg->ActualCount = i + 1;
968 ERR("Unhandled string type: %#x\n", *pFormat);
969 RpcRaiseException(RPC_X_BAD_STUB_DATA);
972 pStubMsg->Offset = 0;
973 WriteVariance(pStubMsg);
975 size = safe_multiply(esize, pStubMsg->ActualCount);
976 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
981 /***********************************************************************
982 * NdrNonConformantStringUnmarshall [RPCRT4.@]
984 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
985 unsigned char **ppMemory,
986 PFORMAT_STRING pFormat,
987 unsigned char fMustAlloc)
989 ULONG bufsize, memsize, esize, maxsize;
991 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
992 pStubMsg, *ppMemory, pFormat, fMustAlloc);
994 maxsize = *(USHORT *)&pFormat[2];
996 ReadVariance(pStubMsg, NULL, maxsize);
997 if (pStubMsg->Offset)
999 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
1000 RpcRaiseException(RPC_S_INVALID_BOUND);
1003 if (*pFormat == RPC_FC_CSTRING) esize = 1;
1004 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
1007 ERR("Unhandled string type: %#x\n", *pFormat);
1008 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1011 memsize = esize * maxsize;
1012 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
1014 validate_string_data(pStubMsg, bufsize, esize);
1016 if (fMustAlloc || !*ppMemory)
1017 *ppMemory = NdrAllocate(pStubMsg, memsize);
1019 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
1021 if (*pFormat == RPC_FC_CSTRING) {
1022 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
1024 else if (*pFormat == RPC_FC_WSTRING) {
1025 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
1031 /***********************************************************************
1032 * NdrNonConformantStringBufferSize [RPCRT4.@]
1034 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1035 unsigned char *pMemory,
1036 PFORMAT_STRING pFormat)
1038 ULONG esize, maxsize;
1040 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
1042 maxsize = *(USHORT *)&pFormat[2];
1044 SizeVariance(pStubMsg);
1046 if (*pFormat == RPC_FC_CSTRING)
1049 const char *str = (const char *)pMemory;
1050 for (i = 0; i < maxsize && *str; i++, str++)
1052 TRACE("string=%s\n", debugstr_an(str, i));
1053 pStubMsg->ActualCount = i + 1;
1056 else if (*pFormat == RPC_FC_WSTRING)
1059 const WCHAR *str = (const WCHAR *)pMemory;
1060 for (i = 0; i < maxsize && *str; i++, str++)
1062 TRACE("string=%s\n", debugstr_wn(str, i));
1063 pStubMsg->ActualCount = i + 1;
1068 ERR("Unhandled string type: %#x\n", *pFormat);
1069 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1072 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
1075 /***********************************************************************
1076 * NdrNonConformantStringMemorySize [RPCRT4.@]
1078 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1079 PFORMAT_STRING pFormat)
1081 ULONG bufsize, memsize, esize, maxsize;
1083 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
1085 maxsize = *(USHORT *)&pFormat[2];
1087 ReadVariance(pStubMsg, NULL, maxsize);
1089 if (pStubMsg->Offset)
1091 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
1092 RpcRaiseException(RPC_S_INVALID_BOUND);
1095 if (*pFormat == RPC_FC_CSTRING) esize = 1;
1096 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
1099 ERR("Unhandled string type: %#x\n", *pFormat);
1100 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1103 memsize = esize * maxsize;
1104 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
1106 validate_string_data(pStubMsg, bufsize, esize);
1108 safe_buffer_increment(pStubMsg, bufsize);
1109 pStubMsg->MemorySize += memsize;
1111 return pStubMsg->MemorySize;
1114 static inline void dump_pointer_attr(unsigned char attr)
1116 if (attr & RPC_FC_P_ALLOCALLNODES)
1117 TRACE(" RPC_FC_P_ALLOCALLNODES");
1118 if (attr & RPC_FC_P_DONTFREE)
1119 TRACE(" RPC_FC_P_DONTFREE");
1120 if (attr & RPC_FC_P_ONSTACK)
1121 TRACE(" RPC_FC_P_ONSTACK");
1122 if (attr & RPC_FC_P_SIMPLEPOINTER)
1123 TRACE(" RPC_FC_P_SIMPLEPOINTER");
1124 if (attr & RPC_FC_P_DEREF)
1125 TRACE(" RPC_FC_P_DEREF");
1129 /***********************************************************************
1130 * PointerMarshall [internal]
1132 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1133 unsigned char *Buffer,
1134 unsigned char *Pointer,
1135 PFORMAT_STRING pFormat)
1137 unsigned type = pFormat[0], attr = pFormat[1];
1138 PFORMAT_STRING desc;
1141 int pointer_needs_marshaling;
1143 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
1144 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1146 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1147 else desc = pFormat + *(const SHORT*)pFormat;
1150 case RPC_FC_RP: /* ref pointer (always non-null) */
1153 ERR("NULL ref pointer is not allowed\n");
1154 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1156 pointer_needs_marshaling = 1;
1158 case RPC_FC_UP: /* unique pointer */
1159 case RPC_FC_OP: /* object pointer - same as unique here */
1161 pointer_needs_marshaling = 1;
1163 pointer_needs_marshaling = 0;
1164 pointer_id = Pointer ? NDR_POINTER_ID(pStubMsg) : 0;
1165 TRACE("writing 0x%08x to buffer\n", pointer_id);
1166 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
1169 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
1170 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
1171 TRACE("writing 0x%08x to buffer\n", pointer_id);
1172 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
1175 FIXME("unhandled ptr type=%02x\n", type);
1176 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1180 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
1182 if (pointer_needs_marshaling) {
1183 if (attr & RPC_FC_P_DEREF) {
1184 Pointer = *(unsigned char**)Pointer;
1185 TRACE("deref => %p\n", Pointer);
1187 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1188 if (m) m(pStubMsg, Pointer, desc);
1189 else FIXME("no marshaller for data type=%02x\n", *desc);
1192 STD_OVERFLOW_CHECK(pStubMsg);
1195 /***********************************************************************
1196 * PointerUnmarshall [internal]
1198 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1199 unsigned char *Buffer,
1200 unsigned char **pPointer,
1201 unsigned char *pSrcPointer,
1202 PFORMAT_STRING pFormat,
1203 unsigned char fMustAlloc)
1205 unsigned type = pFormat[0], attr = pFormat[1];
1206 PFORMAT_STRING desc;
1208 DWORD pointer_id = 0;
1209 int pointer_needs_unmarshaling;
1211 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
1212 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1214 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1215 else desc = pFormat + *(const SHORT*)pFormat;
1218 case RPC_FC_RP: /* ref pointer (always non-null) */
1219 pointer_needs_unmarshaling = 1;
1221 case RPC_FC_UP: /* unique pointer */
1222 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1223 TRACE("pointer_id is 0x%08x\n", pointer_id);
1225 pointer_needs_unmarshaling = 1;
1228 pointer_needs_unmarshaling = 0;
1231 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1232 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1233 TRACE("pointer_id is 0x%08x\n", pointer_id);
1234 if (!fMustAlloc && pSrcPointer)
1236 FIXME("free object pointer %p\n", pSrcPointer);
1240 pointer_needs_unmarshaling = 1;
1242 pointer_needs_unmarshaling = 0;
1245 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1246 TRACE("pointer_id is 0x%08x\n", pointer_id);
1247 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
1248 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
1251 FIXME("unhandled ptr type=%02x\n", type);
1252 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1256 if (pointer_needs_unmarshaling) {
1257 unsigned char *base_ptr_val = *pPointer;
1258 unsigned char **current_ptr = pPointer;
1259 if (pStubMsg->IsClient) {
1261 /* if we aren't forcing allocation of memory then try to use the existing
1262 * (source) pointer to unmarshall the data into so that [in,out]
1263 * parameters behave correctly. it doesn't matter if the parameter is
1264 * [out] only since in that case the pointer will be NULL. we force
1265 * allocation when the source pointer is NULL here instead of in the type
1266 * unmarshalling routine for the benefit of the deref code below */
1269 TRACE("setting *pPointer to %p\n", pSrcPointer);
1270 *pPointer = base_ptr_val = pSrcPointer;
1276 /* the memory in a stub is never initialised, so we have to work out here
1277 * whether we have to initialise it so we can use the optimisation of
1278 * setting the pointer to the buffer, if possible, or set fMustAlloc to
1280 if (attr & RPC_FC_P_DEREF) {
1283 base_ptr_val = NULL;
1284 *current_ptr = NULL;
1288 if (attr & RPC_FC_P_ALLOCALLNODES)
1289 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
1291 if (attr & RPC_FC_P_DEREF) {
1293 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
1294 *pPointer = base_ptr_val;
1295 current_ptr = (unsigned char **)base_ptr_val;
1297 current_ptr = *(unsigned char***)current_ptr;
1298 TRACE("deref => %p\n", current_ptr);
1299 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
1301 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1302 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
1303 else FIXME("no unmarshaller for data type=%02x\n", *desc);
1305 if (type == RPC_FC_FP)
1306 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
1310 TRACE("pointer=%p\n", *pPointer);
1313 /***********************************************************************
1314 * PointerBufferSize [internal]
1316 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1317 unsigned char *Pointer,
1318 PFORMAT_STRING pFormat)
1320 unsigned type = pFormat[0], attr = pFormat[1];
1321 PFORMAT_STRING desc;
1323 int pointer_needs_sizing;
1326 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1327 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1329 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1330 else desc = pFormat + *(const SHORT*)pFormat;
1333 case RPC_FC_RP: /* ref pointer (always non-null) */
1336 ERR("NULL ref pointer is not allowed\n");
1337 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1342 /* NULL pointer has no further representation */
1347 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1348 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1349 if (!pointer_needs_sizing)
1353 FIXME("unhandled ptr type=%02x\n", type);
1354 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1358 if (attr & RPC_FC_P_DEREF) {
1359 Pointer = *(unsigned char**)Pointer;
1360 TRACE("deref => %p\n", Pointer);
1363 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1364 if (m) m(pStubMsg, Pointer, desc);
1365 else FIXME("no buffersizer for data type=%02x\n", *desc);
1368 /***********************************************************************
1369 * PointerMemorySize [internal]
1371 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1372 unsigned char *Buffer,
1373 PFORMAT_STRING pFormat)
1375 unsigned type = pFormat[0], attr = pFormat[1];
1376 PFORMAT_STRING desc;
1378 DWORD pointer_id = 0;
1379 int pointer_needs_sizing;
1381 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1382 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1384 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1385 else desc = pFormat + *(const SHORT*)pFormat;
1388 case RPC_FC_RP: /* ref pointer (always non-null) */
1389 pointer_needs_sizing = 1;
1391 case RPC_FC_UP: /* unique pointer */
1392 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1393 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1394 TRACE("pointer_id is 0x%08x\n", pointer_id);
1396 pointer_needs_sizing = 1;
1398 pointer_needs_sizing = 0;
1403 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1404 TRACE("pointer_id is 0x%08x\n", pointer_id);
1405 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1406 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1410 FIXME("unhandled ptr type=%02x\n", type);
1411 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1415 if (attr & RPC_FC_P_DEREF) {
1419 if (pointer_needs_sizing) {
1420 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1421 if (m) m(pStubMsg, desc);
1422 else FIXME("no memorysizer for data type=%02x\n", *desc);
1425 return pStubMsg->MemorySize;
1428 /***********************************************************************
1429 * PointerFree [internal]
1431 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1432 unsigned char *Pointer,
1433 PFORMAT_STRING pFormat)
1435 unsigned type = pFormat[0], attr = pFormat[1];
1436 PFORMAT_STRING desc;
1438 unsigned char *current_pointer = Pointer;
1440 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1441 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1442 if (attr & RPC_FC_P_DONTFREE) return;
1444 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1445 else desc = pFormat + *(const SHORT*)pFormat;
1447 if (!Pointer) return;
1449 if (type == RPC_FC_FP) {
1450 int pointer_needs_freeing = NdrFullPointerFree(
1451 pStubMsg->FullPtrXlatTables, Pointer);
1452 if (!pointer_needs_freeing)
1456 if (attr & RPC_FC_P_DEREF) {
1457 current_pointer = *(unsigned char**)Pointer;
1458 TRACE("deref => %p\n", current_pointer);
1461 m = NdrFreer[*desc & NDR_TABLE_MASK];
1462 if (m) m(pStubMsg, current_pointer, desc);
1464 /* this check stops us from trying to free buffer memory. we don't have to
1465 * worry about clients, since they won't call this function.
1466 * we don't have to check for the buffer being reallocated because
1467 * BufferStart and BufferEnd won't be reset when allocating memory for
1468 * sending the response. we don't have to check for the new buffer here as
1469 * it won't be used a type memory, only for buffer memory */
1470 if (Pointer >= pStubMsg->BufferStart && Pointer < pStubMsg->BufferEnd)
1473 if (attr & RPC_FC_P_ONSTACK) {
1474 TRACE("not freeing stack ptr %p\n", Pointer);
1477 TRACE("freeing %p\n", Pointer);
1478 NdrFree(pStubMsg, Pointer);
1481 TRACE("not freeing %p\n", Pointer);
1484 /***********************************************************************
1485 * EmbeddedPointerMarshall
1487 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1488 unsigned char *pMemory,
1489 PFORMAT_STRING pFormat)
1491 unsigned char *Mark = pStubMsg->BufferMark;
1492 unsigned rep, count, stride;
1494 unsigned char *saved_buffer = NULL;
1496 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1498 if (*pFormat != RPC_FC_PP) return NULL;
1501 if (pStubMsg->PointerBufferMark)
1503 saved_buffer = pStubMsg->Buffer;
1504 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1505 pStubMsg->PointerBufferMark = NULL;
1508 while (pFormat[0] != RPC_FC_END) {
1509 switch (pFormat[0]) {
1511 FIXME("unknown repeat type %d\n", pFormat[0]);
1512 case RPC_FC_NO_REPEAT:
1518 case RPC_FC_FIXED_REPEAT:
1519 rep = *(const WORD*)&pFormat[2];
1520 stride = *(const WORD*)&pFormat[4];
1521 count = *(const WORD*)&pFormat[8];
1524 case RPC_FC_VARIABLE_REPEAT:
1525 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1526 stride = *(const WORD*)&pFormat[2];
1527 count = *(const WORD*)&pFormat[6];
1531 for (i = 0; i < rep; i++) {
1532 PFORMAT_STRING info = pFormat;
1533 unsigned char *membase = pMemory + (i * stride);
1534 unsigned char *bufbase = Mark + (i * stride);
1537 for (u=0; u<count; u++,info+=8) {
1538 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1539 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1540 unsigned char *saved_memory = pStubMsg->Memory;
1542 pStubMsg->Memory = pMemory;
1543 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1544 pStubMsg->Memory = saved_memory;
1547 pFormat += 8 * count;
1552 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1553 pStubMsg->Buffer = saved_buffer;
1556 STD_OVERFLOW_CHECK(pStubMsg);
1561 /***********************************************************************
1562 * EmbeddedPointerUnmarshall
1564 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1565 unsigned char *pDstBuffer,
1566 unsigned char *pSrcMemoryPtrs,
1567 PFORMAT_STRING pFormat,
1568 unsigned char fMustAlloc)
1570 unsigned char *Mark = pStubMsg->BufferMark;
1571 unsigned rep, count, stride;
1573 unsigned char *saved_buffer = NULL;
1575 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc);
1577 if (*pFormat != RPC_FC_PP) return NULL;
1580 if (pStubMsg->PointerBufferMark)
1582 saved_buffer = pStubMsg->Buffer;
1583 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1584 pStubMsg->PointerBufferMark = NULL;
1587 while (pFormat[0] != RPC_FC_END) {
1588 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1589 switch (pFormat[0]) {
1591 FIXME("unknown repeat type %d\n", pFormat[0]);
1592 case RPC_FC_NO_REPEAT:
1598 case RPC_FC_FIXED_REPEAT:
1599 rep = *(const WORD*)&pFormat[2];
1600 stride = *(const WORD*)&pFormat[4];
1601 count = *(const WORD*)&pFormat[8];
1604 case RPC_FC_VARIABLE_REPEAT:
1605 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1606 stride = *(const WORD*)&pFormat[2];
1607 count = *(const WORD*)&pFormat[6];
1611 for (i = 0; i < rep; i++) {
1612 PFORMAT_STRING info = pFormat;
1613 unsigned char *bufdstbase = pDstBuffer + (i * stride);
1614 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1615 unsigned char *bufbase = Mark + (i * stride);
1618 for (u=0; u<count; u++,info+=8) {
1619 unsigned char **bufdstptr = (unsigned char **)(bufdstbase + *(const SHORT*)&info[2]);
1620 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1621 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1622 PointerUnmarshall(pStubMsg, bufptr, bufdstptr, *memsrcptr, info+4, fMustAlloc);
1625 pFormat += 8 * count;
1630 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1631 pStubMsg->Buffer = saved_buffer;
1637 /***********************************************************************
1638 * EmbeddedPointerBufferSize
1640 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1641 unsigned char *pMemory,
1642 PFORMAT_STRING pFormat)
1644 unsigned rep, count, stride;
1646 ULONG saved_buffer_length = 0;
1648 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1650 if (pStubMsg->IgnoreEmbeddedPointers) return;
1652 if (*pFormat != RPC_FC_PP) return;
1655 if (pStubMsg->PointerLength)
1657 saved_buffer_length = pStubMsg->BufferLength;
1658 pStubMsg->BufferLength = pStubMsg->PointerLength;
1659 pStubMsg->PointerLength = 0;
1662 while (pFormat[0] != RPC_FC_END) {
1663 switch (pFormat[0]) {
1665 FIXME("unknown repeat type %d\n", pFormat[0]);
1666 case RPC_FC_NO_REPEAT:
1672 case RPC_FC_FIXED_REPEAT:
1673 rep = *(const WORD*)&pFormat[2];
1674 stride = *(const WORD*)&pFormat[4];
1675 count = *(const WORD*)&pFormat[8];
1678 case RPC_FC_VARIABLE_REPEAT:
1679 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1680 stride = *(const WORD*)&pFormat[2];
1681 count = *(const WORD*)&pFormat[6];
1685 for (i = 0; i < rep; i++) {
1686 PFORMAT_STRING info = pFormat;
1687 unsigned char *membase = pMemory + (i * stride);
1690 for (u=0; u<count; u++,info+=8) {
1691 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1692 unsigned char *saved_memory = pStubMsg->Memory;
1694 pStubMsg->Memory = pMemory;
1695 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1696 pStubMsg->Memory = saved_memory;
1699 pFormat += 8 * count;
1702 if (saved_buffer_length)
1704 pStubMsg->PointerLength = pStubMsg->BufferLength;
1705 pStubMsg->BufferLength = saved_buffer_length;
1709 /***********************************************************************
1710 * EmbeddedPointerMemorySize [internal]
1712 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1713 PFORMAT_STRING pFormat)
1715 unsigned char *Mark = pStubMsg->BufferMark;
1716 unsigned rep, count, stride;
1718 unsigned char *saved_buffer = NULL;
1720 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1722 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1724 if (pStubMsg->PointerBufferMark)
1726 saved_buffer = pStubMsg->Buffer;
1727 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1728 pStubMsg->PointerBufferMark = NULL;
1731 if (*pFormat != RPC_FC_PP) return 0;
1734 while (pFormat[0] != RPC_FC_END) {
1735 switch (pFormat[0]) {
1737 FIXME("unknown repeat type %d\n", pFormat[0]);
1738 case RPC_FC_NO_REPEAT:
1744 case RPC_FC_FIXED_REPEAT:
1745 rep = *(const WORD*)&pFormat[2];
1746 stride = *(const WORD*)&pFormat[4];
1747 count = *(const WORD*)&pFormat[8];
1750 case RPC_FC_VARIABLE_REPEAT:
1751 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1752 stride = *(const WORD*)&pFormat[2];
1753 count = *(const WORD*)&pFormat[6];
1757 for (i = 0; i < rep; i++) {
1758 PFORMAT_STRING info = pFormat;
1759 unsigned char *bufbase = Mark + (i * stride);
1761 for (u=0; u<count; u++,info+=8) {
1762 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1763 PointerMemorySize(pStubMsg, bufptr, info+4);
1766 pFormat += 8 * count;
1771 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1772 pStubMsg->Buffer = saved_buffer;
1778 /***********************************************************************
1779 * EmbeddedPointerFree [internal]
1781 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1782 unsigned char *pMemory,
1783 PFORMAT_STRING pFormat)
1785 unsigned rep, count, stride;
1788 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1789 if (*pFormat != RPC_FC_PP) return;
1792 while (pFormat[0] != RPC_FC_END) {
1793 switch (pFormat[0]) {
1795 FIXME("unknown repeat type %d\n", pFormat[0]);
1796 case RPC_FC_NO_REPEAT:
1802 case RPC_FC_FIXED_REPEAT:
1803 rep = *(const WORD*)&pFormat[2];
1804 stride = *(const WORD*)&pFormat[4];
1805 count = *(const WORD*)&pFormat[8];
1808 case RPC_FC_VARIABLE_REPEAT:
1809 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1810 stride = *(const WORD*)&pFormat[2];
1811 count = *(const WORD*)&pFormat[6];
1815 for (i = 0; i < rep; i++) {
1816 PFORMAT_STRING info = pFormat;
1817 unsigned char *membase = pMemory + (i * stride);
1820 for (u=0; u<count; u++,info+=8) {
1821 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1822 unsigned char *saved_memory = pStubMsg->Memory;
1824 pStubMsg->Memory = pMemory;
1825 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1826 pStubMsg->Memory = saved_memory;
1829 pFormat += 8 * count;
1833 /***********************************************************************
1834 * NdrPointerMarshall [RPCRT4.@]
1836 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1837 unsigned char *pMemory,
1838 PFORMAT_STRING pFormat)
1840 unsigned char *Buffer;
1842 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1844 /* Increment the buffer here instead of in PointerMarshall,
1845 * as that is used by embedded pointers which already handle the incrementing
1846 * the buffer, and shouldn't write any additional pointer data to the wire */
1847 if (*pFormat != RPC_FC_RP)
1849 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
1850 Buffer = pStubMsg->Buffer;
1851 safe_buffer_increment(pStubMsg, 4);
1854 Buffer = pStubMsg->Buffer;
1856 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1861 /***********************************************************************
1862 * NdrPointerUnmarshall [RPCRT4.@]
1864 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1865 unsigned char **ppMemory,
1866 PFORMAT_STRING pFormat,
1867 unsigned char fMustAlloc)
1869 unsigned char *Buffer;
1871 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1873 /* Increment the buffer here instead of in PointerUnmarshall,
1874 * as that is used by embedded pointers which already handle the incrementing
1875 * the buffer, and shouldn't read any additional pointer data from the
1877 if (*pFormat != RPC_FC_RP)
1879 ALIGN_POINTER(pStubMsg->Buffer, 4);
1880 Buffer = pStubMsg->Buffer;
1881 safe_buffer_increment(pStubMsg, 4);
1884 Buffer = pStubMsg->Buffer;
1886 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1891 /***********************************************************************
1892 * NdrPointerBufferSize [RPCRT4.@]
1894 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1895 unsigned char *pMemory,
1896 PFORMAT_STRING pFormat)
1898 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1900 /* Increment the buffer length here instead of in PointerBufferSize,
1901 * as that is used by embedded pointers which already handle the buffer
1902 * length, and shouldn't write anything more to the wire */
1903 if (*pFormat != RPC_FC_RP)
1905 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1906 safe_buffer_length_increment(pStubMsg, 4);
1909 PointerBufferSize(pStubMsg, pMemory, pFormat);
1912 /***********************************************************************
1913 * NdrPointerMemorySize [RPCRT4.@]
1915 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1916 PFORMAT_STRING pFormat)
1918 /* unsigned size = *(LPWORD)(pFormat+2); */
1919 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1920 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1924 /***********************************************************************
1925 * NdrPointerFree [RPCRT4.@]
1927 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1928 unsigned char *pMemory,
1929 PFORMAT_STRING pFormat)
1931 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1932 PointerFree(pStubMsg, pMemory, pFormat);
1935 /***********************************************************************
1936 * NdrSimpleTypeMarshall [RPCRT4.@]
1938 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1939 unsigned char FormatChar )
1941 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1944 /***********************************************************************
1945 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1947 * Unmarshall a base type.
1950 * Doesn't check that the buffer is long enough before copying, so the caller
1953 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1954 unsigned char FormatChar )
1956 #define BASE_TYPE_UNMARSHALL(type) \
1957 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
1958 TRACE("pMemory: %p\n", pMemory); \
1959 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1960 pStubMsg->Buffer += sizeof(type);
1968 BASE_TYPE_UNMARSHALL(UCHAR);
1969 TRACE("value: 0x%02x\n", *pMemory);
1974 BASE_TYPE_UNMARSHALL(USHORT);
1975 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
1979 case RPC_FC_ERROR_STATUS_T:
1981 BASE_TYPE_UNMARSHALL(ULONG);
1982 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
1985 BASE_TYPE_UNMARSHALL(float);
1986 TRACE("value: %f\n", *(float *)pMemory);
1989 BASE_TYPE_UNMARSHALL(double);
1990 TRACE("value: %f\n", *(double *)pMemory);
1993 BASE_TYPE_UNMARSHALL(ULONGLONG);
1994 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
1997 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
1998 TRACE("pMemory: %p\n", pMemory);
1999 /* 16-bits on the wire, but int in memory */
2000 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
2001 pStubMsg->Buffer += sizeof(USHORT);
2002 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
2007 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
2009 #undef BASE_TYPE_UNMARSHALL
2012 /***********************************************************************
2013 * NdrSimpleStructMarshall [RPCRT4.@]
2015 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2016 unsigned char *pMemory,
2017 PFORMAT_STRING pFormat)
2019 unsigned size = *(const WORD*)(pFormat+2);
2020 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2022 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
2024 pStubMsg->BufferMark = pStubMsg->Buffer;
2025 safe_copy_to_buffer(pStubMsg, pMemory, size);
2027 if (pFormat[0] != RPC_FC_STRUCT)
2028 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
2033 /***********************************************************************
2034 * NdrSimpleStructUnmarshall [RPCRT4.@]
2036 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2037 unsigned char **ppMemory,
2038 PFORMAT_STRING pFormat,
2039 unsigned char fMustAlloc)
2041 unsigned size = *(const WORD*)(pFormat+2);
2042 unsigned char *saved_buffer;
2043 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2045 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2048 *ppMemory = NdrAllocate(pStubMsg, size);
2051 if (!pStubMsg->IsClient && !*ppMemory)
2052 /* for servers, we just point straight into the RPC buffer */
2053 *ppMemory = pStubMsg->Buffer;
2056 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
2057 safe_buffer_increment(pStubMsg, size);
2058 if (pFormat[0] == RPC_FC_PSTRUCT)
2059 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
2061 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2062 if (*ppMemory != saved_buffer)
2063 memcpy(*ppMemory, saved_buffer, size);
2068 /***********************************************************************
2069 * NdrSimpleStructBufferSize [RPCRT4.@]
2071 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2072 unsigned char *pMemory,
2073 PFORMAT_STRING pFormat)
2075 unsigned size = *(const WORD*)(pFormat+2);
2076 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2078 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2080 safe_buffer_length_increment(pStubMsg, size);
2081 if (pFormat[0] != RPC_FC_STRUCT)
2082 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
2085 /***********************************************************************
2086 * NdrSimpleStructMemorySize [RPCRT4.@]
2088 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2089 PFORMAT_STRING pFormat)
2091 unsigned short size = *(const WORD *)(pFormat+2);
2093 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2095 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2096 pStubMsg->MemorySize += size;
2097 safe_buffer_increment(pStubMsg, size);
2099 if (pFormat[0] != RPC_FC_STRUCT)
2100 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
2101 return pStubMsg->MemorySize;
2104 /***********************************************************************
2105 * NdrSimpleStructFree [RPCRT4.@]
2107 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2108 unsigned char *pMemory,
2109 PFORMAT_STRING pFormat)
2111 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2112 if (pFormat[0] != RPC_FC_STRUCT)
2113 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
2117 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE *pStubMsg,
2118 PFORMAT_STRING pFormat)
2122 case RPC_FC_PSTRUCT:
2123 case RPC_FC_CSTRUCT:
2124 case RPC_FC_BOGUS_STRUCT:
2125 case RPC_FC_SMFARRAY:
2126 case RPC_FC_SMVARRAY:
2127 case RPC_FC_CSTRING:
2128 return *(const WORD*)&pFormat[2];
2129 case RPC_FC_USER_MARSHAL:
2130 return *(const WORD*)&pFormat[4];
2131 case RPC_FC_NON_ENCAPSULATED_UNION:
2133 if (pStubMsg->fHasNewCorrDesc)
2138 pFormat += *(const SHORT*)pFormat;
2139 return *(const SHORT*)pFormat;
2141 return sizeof(void *);
2142 case RPC_FC_WSTRING:
2143 return *(const WORD*)&pFormat[2] * 2;
2145 FIXME("unhandled embedded type %02x\n", *pFormat);
2151 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2152 PFORMAT_STRING pFormat)
2154 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2158 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2162 return m(pStubMsg, pFormat);
2166 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2167 unsigned char *pMemory,
2168 PFORMAT_STRING pFormat,
2169 PFORMAT_STRING pPointer)
2171 PFORMAT_STRING desc;
2175 while (*pFormat != RPC_FC_END) {
2181 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2182 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2188 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2189 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2193 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2194 if (32767 < *(DWORD*)pMemory)
2195 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2196 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2202 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2203 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2207 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2208 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2211 case RPC_FC_POINTER:
2213 unsigned char *saved_buffer;
2214 int pointer_buffer_mark_set = 0;
2215 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2216 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
2217 saved_buffer = pStubMsg->Buffer;
2218 if (pStubMsg->PointerBufferMark)
2220 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2221 pStubMsg->PointerBufferMark = NULL;
2222 pointer_buffer_mark_set = 1;
2225 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2226 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2227 if (pointer_buffer_mark_set)
2229 STD_OVERFLOW_CHECK(pStubMsg);
2230 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2231 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2233 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2234 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2235 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2237 pStubMsg->Buffer = saved_buffer + 4;
2243 case RPC_FC_ALIGNM4:
2244 ALIGN_POINTER(pMemory, 4);
2246 case RPC_FC_ALIGNM8:
2247 ALIGN_POINTER(pMemory, 8);
2249 case RPC_FC_STRUCTPAD1:
2250 case RPC_FC_STRUCTPAD2:
2251 case RPC_FC_STRUCTPAD3:
2252 case RPC_FC_STRUCTPAD4:
2253 case RPC_FC_STRUCTPAD5:
2254 case RPC_FC_STRUCTPAD6:
2255 case RPC_FC_STRUCTPAD7:
2256 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2258 case RPC_FC_EMBEDDED_COMPLEX:
2259 pMemory += pFormat[1];
2261 desc = pFormat + *(const SHORT*)pFormat;
2262 size = EmbeddedComplexSize(pStubMsg, desc);
2263 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
2264 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2267 /* for some reason interface pointers aren't generated as
2268 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2269 * they still need the derefencing treatment that pointers are
2271 if (*desc == RPC_FC_IP)
2272 m(pStubMsg, *(unsigned char **)pMemory, desc);
2274 m(pStubMsg, pMemory, desc);
2276 else FIXME("no marshaller for embedded type %02x\n", *desc);
2283 FIXME("unhandled format 0x%02x\n", *pFormat);
2291 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2292 unsigned char *pMemory,
2293 PFORMAT_STRING pFormat,
2294 PFORMAT_STRING pPointer)
2296 PFORMAT_STRING desc;
2300 while (*pFormat != RPC_FC_END) {
2306 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2307 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2313 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2314 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2318 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2319 *(DWORD*)pMemory &= 0xffff;
2320 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
2321 if (32767 < *(DWORD*)pMemory)
2322 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2328 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2329 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2333 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2334 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2337 case RPC_FC_POINTER:
2339 unsigned char *saved_buffer;
2340 int pointer_buffer_mark_set = 0;
2341 TRACE("pointer => %p\n", pMemory);
2342 ALIGN_POINTER(pStubMsg->Buffer, 4);
2343 saved_buffer = pStubMsg->Buffer;
2344 if (pStubMsg->PointerBufferMark)
2346 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2347 pStubMsg->PointerBufferMark = NULL;
2348 pointer_buffer_mark_set = 1;
2351 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2353 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, TRUE);
2354 if (pointer_buffer_mark_set)
2356 STD_OVERFLOW_CHECK(pStubMsg);
2357 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2358 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2360 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2361 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2362 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2364 pStubMsg->Buffer = saved_buffer + 4;
2370 case RPC_FC_ALIGNM4:
2371 ALIGN_POINTER_CLEAR(pMemory, 4);
2373 case RPC_FC_ALIGNM8:
2374 ALIGN_POINTER_CLEAR(pMemory, 8);
2376 case RPC_FC_STRUCTPAD1:
2377 case RPC_FC_STRUCTPAD2:
2378 case RPC_FC_STRUCTPAD3:
2379 case RPC_FC_STRUCTPAD4:
2380 case RPC_FC_STRUCTPAD5:
2381 case RPC_FC_STRUCTPAD6:
2382 case RPC_FC_STRUCTPAD7:
2383 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2384 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2386 case RPC_FC_EMBEDDED_COMPLEX:
2387 pMemory += pFormat[1];
2389 desc = pFormat + *(const SHORT*)pFormat;
2390 size = EmbeddedComplexSize(pStubMsg, desc);
2391 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2392 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2393 memset(pMemory, 0, size); /* just in case */
2396 /* for some reason interface pointers aren't generated as
2397 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2398 * they still need the derefencing treatment that pointers are
2400 if (*desc == RPC_FC_IP)
2401 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2403 m(pStubMsg, &pMemory, desc, FALSE);
2405 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2412 FIXME("unhandled format %d\n", *pFormat);
2420 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2421 unsigned char *pMemory,
2422 PFORMAT_STRING pFormat,
2423 PFORMAT_STRING pPointer)
2425 PFORMAT_STRING desc;
2429 while (*pFormat != RPC_FC_END) {
2435 safe_buffer_length_increment(pStubMsg, 1);
2441 safe_buffer_length_increment(pStubMsg, 2);
2445 safe_buffer_length_increment(pStubMsg, 2);
2451 safe_buffer_length_increment(pStubMsg, 4);
2455 safe_buffer_length_increment(pStubMsg, 8);
2458 case RPC_FC_POINTER:
2459 if (!pStubMsg->IgnoreEmbeddedPointers)
2461 int saved_buffer_length = pStubMsg->BufferLength;
2462 pStubMsg->BufferLength = pStubMsg->PointerLength;
2463 pStubMsg->PointerLength = 0;
2464 if(!pStubMsg->BufferLength)
2465 ERR("BufferLength == 0??\n");
2466 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2467 pStubMsg->PointerLength = pStubMsg->BufferLength;
2468 pStubMsg->BufferLength = saved_buffer_length;
2470 safe_buffer_length_increment(pStubMsg, 4);
2474 case RPC_FC_ALIGNM4:
2475 ALIGN_POINTER(pMemory, 4);
2477 case RPC_FC_ALIGNM8:
2478 ALIGN_POINTER(pMemory, 8);
2480 case RPC_FC_STRUCTPAD1:
2481 case RPC_FC_STRUCTPAD2:
2482 case RPC_FC_STRUCTPAD3:
2483 case RPC_FC_STRUCTPAD4:
2484 case RPC_FC_STRUCTPAD5:
2485 case RPC_FC_STRUCTPAD6:
2486 case RPC_FC_STRUCTPAD7:
2487 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2489 case RPC_FC_EMBEDDED_COMPLEX:
2490 pMemory += pFormat[1];
2492 desc = pFormat + *(const SHORT*)pFormat;
2493 size = EmbeddedComplexSize(pStubMsg, desc);
2494 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2497 /* for some reason interface pointers aren't generated as
2498 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2499 * they still need the derefencing treatment that pointers are
2501 if (*desc == RPC_FC_IP)
2502 m(pStubMsg, *(unsigned char **)pMemory, desc);
2504 m(pStubMsg, pMemory, desc);
2506 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2513 FIXME("unhandled format 0x%02x\n", *pFormat);
2521 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2522 unsigned char *pMemory,
2523 PFORMAT_STRING pFormat,
2524 PFORMAT_STRING pPointer)
2526 PFORMAT_STRING desc;
2530 while (*pFormat != RPC_FC_END) {
2552 case RPC_FC_POINTER:
2553 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
2557 case RPC_FC_ALIGNM4:
2558 ALIGN_POINTER(pMemory, 4);
2560 case RPC_FC_ALIGNM8:
2561 ALIGN_POINTER(pMemory, 8);
2563 case RPC_FC_STRUCTPAD1:
2564 case RPC_FC_STRUCTPAD2:
2565 case RPC_FC_STRUCTPAD3:
2566 case RPC_FC_STRUCTPAD4:
2567 case RPC_FC_STRUCTPAD5:
2568 case RPC_FC_STRUCTPAD6:
2569 case RPC_FC_STRUCTPAD7:
2570 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2572 case RPC_FC_EMBEDDED_COMPLEX:
2573 pMemory += pFormat[1];
2575 desc = pFormat + *(const SHORT*)pFormat;
2576 size = EmbeddedComplexSize(pStubMsg, desc);
2577 m = NdrFreer[*desc & NDR_TABLE_MASK];
2580 /* for some reason interface pointers aren't generated as
2581 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2582 * they still need the derefencing treatment that pointers are
2584 if (*desc == RPC_FC_IP)
2585 m(pStubMsg, *(unsigned char **)pMemory, desc);
2587 m(pStubMsg, pMemory, desc);
2595 FIXME("unhandled format 0x%02x\n", *pFormat);
2603 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2604 PFORMAT_STRING pFormat)
2606 PFORMAT_STRING desc;
2607 unsigned long size = 0;
2609 while (*pFormat != RPC_FC_END) {
2616 safe_buffer_increment(pStubMsg, 1);
2622 safe_buffer_increment(pStubMsg, 2);
2626 safe_buffer_increment(pStubMsg, 2);
2632 safe_buffer_increment(pStubMsg, 4);
2636 safe_buffer_increment(pStubMsg, 8);
2638 case RPC_FC_POINTER:
2640 safe_buffer_increment(pStubMsg, 4);
2641 if (!pStubMsg->IgnoreEmbeddedPointers)
2642 FIXME("embedded pointers\n");
2644 case RPC_FC_ALIGNM4:
2645 ALIGN_LENGTH(size, 4);
2646 ALIGN_POINTER(pStubMsg->Buffer, 4);
2648 case RPC_FC_ALIGNM8:
2649 ALIGN_LENGTH(size, 8);
2650 ALIGN_POINTER(pStubMsg->Buffer, 8);
2652 case RPC_FC_STRUCTPAD1:
2653 case RPC_FC_STRUCTPAD2:
2654 case RPC_FC_STRUCTPAD3:
2655 case RPC_FC_STRUCTPAD4:
2656 case RPC_FC_STRUCTPAD5:
2657 case RPC_FC_STRUCTPAD6:
2658 case RPC_FC_STRUCTPAD7:
2659 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2661 case RPC_FC_EMBEDDED_COMPLEX:
2664 desc = pFormat + *(const SHORT*)pFormat;
2665 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2671 FIXME("unhandled format 0x%02x\n", *pFormat);
2679 unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg,
2680 PFORMAT_STRING pFormat)
2682 PFORMAT_STRING desc;
2683 unsigned long size = 0;
2685 while (*pFormat != RPC_FC_END) {
2707 case RPC_FC_POINTER:
2708 size += sizeof(void *);
2710 case RPC_FC_ALIGNM4:
2711 ALIGN_LENGTH(size, 4);
2713 case RPC_FC_ALIGNM8:
2714 ALIGN_LENGTH(size, 8);
2716 case RPC_FC_STRUCTPAD1:
2717 case RPC_FC_STRUCTPAD2:
2718 case RPC_FC_STRUCTPAD3:
2719 case RPC_FC_STRUCTPAD4:
2720 case RPC_FC_STRUCTPAD5:
2721 case RPC_FC_STRUCTPAD6:
2722 case RPC_FC_STRUCTPAD7:
2723 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2725 case RPC_FC_EMBEDDED_COMPLEX:
2728 desc = pFormat + *(const SHORT*)pFormat;
2729 size += EmbeddedComplexSize(pStubMsg, desc);
2735 FIXME("unhandled format 0x%02x\n", *pFormat);
2743 /***********************************************************************
2744 * NdrComplexStructMarshall [RPCRT4.@]
2746 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2747 unsigned char *pMemory,
2748 PFORMAT_STRING pFormat)
2750 PFORMAT_STRING conf_array = NULL;
2751 PFORMAT_STRING pointer_desc = NULL;
2752 unsigned char *OldMemory = pStubMsg->Memory;
2753 int pointer_buffer_mark_set = 0;
2755 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2757 if (!pStubMsg->PointerBufferMark)
2759 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2760 /* save buffer length */
2761 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2763 /* get the buffer pointer after complex array data, but before
2765 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2766 pStubMsg->IgnoreEmbeddedPointers = 1;
2767 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2768 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2770 /* save it for use by embedded pointer code later */
2771 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2772 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
2773 pointer_buffer_mark_set = 1;
2775 /* restore the original buffer length */
2776 pStubMsg->BufferLength = saved_buffer_length;
2779 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
2782 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2784 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2787 pStubMsg->Memory = pMemory;
2789 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2792 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2794 pStubMsg->Memory = OldMemory;
2796 if (pointer_buffer_mark_set)
2798 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2799 pStubMsg->PointerBufferMark = NULL;
2802 STD_OVERFLOW_CHECK(pStubMsg);
2807 /***********************************************************************
2808 * NdrComplexStructUnmarshall [RPCRT4.@]
2810 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2811 unsigned char **ppMemory,
2812 PFORMAT_STRING pFormat,
2813 unsigned char fMustAlloc)
2815 unsigned size = *(const WORD*)(pFormat+2);
2816 PFORMAT_STRING conf_array = NULL;
2817 PFORMAT_STRING pointer_desc = NULL;
2818 unsigned char *pMemory;
2819 int pointer_buffer_mark_set = 0;
2821 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2823 if (!pStubMsg->PointerBufferMark)
2825 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2826 /* save buffer pointer */
2827 unsigned char *saved_buffer = pStubMsg->Buffer;
2829 /* get the buffer pointer after complex array data, but before
2831 pStubMsg->IgnoreEmbeddedPointers = 1;
2832 NdrComplexStructMemorySize(pStubMsg, pFormat);
2833 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2835 /* save it for use by embedded pointer code later */
2836 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2837 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
2838 pointer_buffer_mark_set = 1;
2840 /* restore the original buffer */
2841 pStubMsg->Buffer = saved_buffer;
2844 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2846 if (fMustAlloc || !*ppMemory)
2848 *ppMemory = NdrAllocate(pStubMsg, size);
2849 memset(*ppMemory, 0, size);
2853 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2855 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2858 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2861 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2863 if (pointer_buffer_mark_set)
2865 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2866 pStubMsg->PointerBufferMark = NULL;
2872 /***********************************************************************
2873 * NdrComplexStructBufferSize [RPCRT4.@]
2875 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2876 unsigned char *pMemory,
2877 PFORMAT_STRING pFormat)
2879 PFORMAT_STRING conf_array = NULL;
2880 PFORMAT_STRING pointer_desc = NULL;
2881 unsigned char *OldMemory = pStubMsg->Memory;
2882 int pointer_length_set = 0;
2884 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2886 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2888 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2890 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2891 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2893 /* get the buffer length after complex struct data, but before
2895 pStubMsg->IgnoreEmbeddedPointers = 1;
2896 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2897 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2899 /* save it for use by embedded pointer code later */
2900 pStubMsg->PointerLength = pStubMsg->BufferLength;
2901 pointer_length_set = 1;
2902 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
2904 /* restore the original buffer length */
2905 pStubMsg->BufferLength = saved_buffer_length;
2909 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2911 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2914 pStubMsg->Memory = pMemory;
2916 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2919 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2921 pStubMsg->Memory = OldMemory;
2923 if(pointer_length_set)
2925 pStubMsg->BufferLength = pStubMsg->PointerLength;
2926 pStubMsg->PointerLength = 0;
2931 /***********************************************************************
2932 * NdrComplexStructMemorySize [RPCRT4.@]
2934 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2935 PFORMAT_STRING pFormat)
2937 unsigned size = *(const WORD*)(pFormat+2);
2938 PFORMAT_STRING conf_array = NULL;
2940 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2942 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2945 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2948 ComplexStructMemorySize(pStubMsg, pFormat);
2951 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2956 /***********************************************************************
2957 * NdrComplexStructFree [RPCRT4.@]
2959 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2960 unsigned char *pMemory,
2961 PFORMAT_STRING pFormat)
2963 PFORMAT_STRING conf_array = NULL;
2964 PFORMAT_STRING pointer_desc = NULL;
2965 unsigned char *OldMemory = pStubMsg->Memory;
2967 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2970 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2972 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2975 pStubMsg->Memory = pMemory;
2977 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2980 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2982 pStubMsg->Memory = OldMemory;
2985 /***********************************************************************
2986 * NdrConformantArrayMarshall [RPCRT4.@]
2988 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2989 unsigned char *pMemory,
2990 PFORMAT_STRING pFormat)
2992 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2993 unsigned char alignment = pFormat[1] + 1;
2995 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2996 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2998 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3000 WriteConformance(pStubMsg);
3002 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3004 size = safe_multiply(esize, pStubMsg->MaxCount);
3005 pStubMsg->BufferMark = pStubMsg->Buffer;
3006 safe_copy_to_buffer(pStubMsg, pMemory, size);
3008 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3013 /***********************************************************************
3014 * NdrConformantArrayUnmarshall [RPCRT4.@]
3016 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3017 unsigned char **ppMemory,
3018 PFORMAT_STRING pFormat,
3019 unsigned char fMustAlloc)
3021 DWORD size, esize = *(const WORD*)(pFormat+2);
3022 unsigned char alignment = pFormat[1] + 1;
3023 unsigned char *saved_buffer;
3025 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3026 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3028 pFormat = ReadConformance(pStubMsg, pFormat+4);
3030 size = safe_multiply(esize, pStubMsg->MaxCount);
3031 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3034 *ppMemory = NdrAllocate(pStubMsg, size);
3037 if (!pStubMsg->IsClient && !*ppMemory)
3038 /* for servers, we just point straight into the RPC buffer */
3039 *ppMemory = pStubMsg->Buffer;
3042 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3043 safe_buffer_increment(pStubMsg, size);
3044 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3046 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
3047 if (*ppMemory != saved_buffer)
3048 memcpy(*ppMemory, saved_buffer, size);
3053 /***********************************************************************
3054 * NdrConformantArrayBufferSize [RPCRT4.@]
3056 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3057 unsigned char *pMemory,
3058 PFORMAT_STRING pFormat)
3060 DWORD size, esize = *(const WORD*)(pFormat+2);
3061 unsigned char alignment = pFormat[1] + 1;
3063 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3064 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3066 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3068 SizeConformance(pStubMsg);
3070 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3072 size = safe_multiply(esize, pStubMsg->MaxCount);
3073 /* conformance value plus array */
3074 safe_buffer_length_increment(pStubMsg, size);
3076 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3079 /***********************************************************************
3080 * NdrConformantArrayMemorySize [RPCRT4.@]
3082 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3083 PFORMAT_STRING pFormat)
3085 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
3086 unsigned char alignment = pFormat[1] + 1;
3088 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3089 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3091 pFormat = ReadConformance(pStubMsg, pFormat+4);
3092 size = safe_multiply(esize, pStubMsg->MaxCount);
3093 pStubMsg->MemorySize += size;
3095 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3096 pStubMsg->BufferMark = pStubMsg->Buffer;
3097 safe_buffer_increment(pStubMsg, size);
3099 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3101 return pStubMsg->MemorySize;
3104 /***********************************************************************
3105 * NdrConformantArrayFree [RPCRT4.@]
3107 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3108 unsigned char *pMemory,
3109 PFORMAT_STRING pFormat)
3111 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3112 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3114 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3116 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3120 /***********************************************************************
3121 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3123 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
3124 unsigned char* pMemory,
3125 PFORMAT_STRING pFormat )
3128 unsigned char alignment = pFormat[1] + 1;
3129 DWORD esize = *(const WORD*)(pFormat+2);
3131 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3133 if (pFormat[0] != RPC_FC_CVARRAY)
3135 ERR("invalid format type %x\n", pFormat[0]);
3136 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3140 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3141 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3143 WriteConformance(pStubMsg);
3144 WriteVariance(pStubMsg);
3146 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3148 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3150 pStubMsg->BufferMark = pStubMsg->Buffer;
3151 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
3153 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3159 /***********************************************************************
3160 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3162 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
3163 unsigned char** ppMemory,
3164 PFORMAT_STRING pFormat,
3165 unsigned char fMustAlloc )
3167 ULONG bufsize, memsize;
3168 unsigned char alignment = pFormat[1] + 1;
3169 DWORD esize = *(const WORD*)(pFormat+2);
3170 unsigned char *saved_buffer;
3173 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3175 if (pFormat[0] != RPC_FC_CVARRAY)
3177 ERR("invalid format type %x\n", pFormat[0]);
3178 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3182 pFormat = ReadConformance(pStubMsg, pFormat+4);
3183 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3185 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3187 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3188 memsize = safe_multiply(esize, pStubMsg->MaxCount);
3189 offset = pStubMsg->Offset;
3191 if (!*ppMemory || fMustAlloc)
3192 *ppMemory = NdrAllocate(pStubMsg, memsize);
3193 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3194 safe_buffer_increment(pStubMsg, bufsize);
3196 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3198 memcpy(*ppMemory + offset, saved_buffer, bufsize);
3204 /***********************************************************************
3205 * NdrConformantVaryingArrayFree [RPCRT4.@]
3207 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
3208 unsigned char* pMemory,
3209 PFORMAT_STRING pFormat )
3211 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3213 if (pFormat[0] != RPC_FC_CVARRAY)
3215 ERR("invalid format type %x\n", pFormat[0]);
3216 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3220 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3221 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3223 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3227 /***********************************************************************
3228 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3230 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
3231 unsigned char* pMemory, PFORMAT_STRING pFormat )
3233 unsigned char alignment = pFormat[1] + 1;
3234 DWORD esize = *(const WORD*)(pFormat+2);
3236 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3238 if (pFormat[0] != RPC_FC_CVARRAY)
3240 ERR("invalid format type %x\n", pFormat[0]);
3241 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3246 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3247 /* compute length */
3248 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3250 SizeConformance(pStubMsg);
3251 SizeVariance(pStubMsg);
3253 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3255 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
3257 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3261 /***********************************************************************
3262 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3264 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
3265 PFORMAT_STRING pFormat )
3267 ULONG bufsize, memsize;
3268 unsigned char alignment = pFormat[1] + 1;
3269 DWORD esize = *(const WORD*)(pFormat+2);
3271 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3273 if (pFormat[0] != RPC_FC_CVARRAY)
3275 ERR("invalid format type %x\n", pFormat[0]);
3276 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3277 return pStubMsg->MemorySize;
3280 pFormat = ReadConformance(pStubMsg, pFormat+4);
3281 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3283 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3285 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3286 memsize = safe_multiply(esize, pStubMsg->MaxCount);
3288 safe_buffer_increment(pStubMsg, bufsize);
3289 pStubMsg->MemorySize += memsize;
3291 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3293 return pStubMsg->MemorySize;
3297 /***********************************************************************
3298 * NdrComplexArrayMarshall [RPCRT4.@]
3300 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3301 unsigned char *pMemory,
3302 PFORMAT_STRING pFormat)
3304 ULONG i, count, def;
3305 BOOL variance_present;
3306 unsigned char alignment;
3307 int pointer_buffer_mark_set = 0;
3309 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3311 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3313 ERR("invalid format type %x\n", pFormat[0]);
3314 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3318 alignment = pFormat[1] + 1;
3320 if (!pStubMsg->PointerBufferMark)
3322 /* save buffer fields that may be changed by buffer sizer functions
3323 * and that may be needed later on */
3324 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3325 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3326 unsigned long saved_max_count = pStubMsg->MaxCount;
3327 unsigned long saved_offset = pStubMsg->Offset;
3328 unsigned long saved_actual_count = pStubMsg->ActualCount;
3330 /* get the buffer pointer after complex array data, but before
3332 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3333 pStubMsg->IgnoreEmbeddedPointers = 1;
3334 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3335 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3337 /* save it for use by embedded pointer code later */
3338 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3339 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
3340 pointer_buffer_mark_set = 1;
3342 /* restore fields */
3343 pStubMsg->ActualCount = saved_actual_count;
3344 pStubMsg->Offset = saved_offset;
3345 pStubMsg->MaxCount = saved_max_count;
3346 pStubMsg->BufferLength = saved_buffer_length;
3349 def = *(const WORD*)&pFormat[2];
3352 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3353 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3355 variance_present = IsConformanceOrVariancePresent(pFormat);
3356 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3357 TRACE("variance = %d\n", pStubMsg->ActualCount);
3359 WriteConformance(pStubMsg);
3360 if (variance_present)
3361 WriteVariance(pStubMsg);
3363 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3365 count = pStubMsg->ActualCount;
3366 for (i = 0; i < count; i++)
3367 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3369 STD_OVERFLOW_CHECK(pStubMsg);
3371 if (pointer_buffer_mark_set)
3373 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3374 pStubMsg->PointerBufferMark = NULL;
3380 /***********************************************************************
3381 * NdrComplexArrayUnmarshall [RPCRT4.@]
3383 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3384 unsigned char **ppMemory,
3385 PFORMAT_STRING pFormat,
3386 unsigned char fMustAlloc)
3388 ULONG i, count, size;
3389 unsigned char alignment;
3390 unsigned char *pMemory;
3391 unsigned char *saved_buffer;
3392 int pointer_buffer_mark_set = 0;
3393 int saved_ignore_embedded;
3395 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3397 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3399 ERR("invalid format type %x\n", pFormat[0]);
3400 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3404 alignment = pFormat[1] + 1;
3406 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3407 /* save buffer pointer */
3408 saved_buffer = pStubMsg->Buffer;
3409 /* get the buffer pointer after complex array data, but before
3411 pStubMsg->IgnoreEmbeddedPointers = 1;
3412 pStubMsg->MemorySize = 0;
3413 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3414 size = pStubMsg->MemorySize;
3415 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3417 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
3418 if (!pStubMsg->PointerBufferMark)
3420 /* save it for use by embedded pointer code later */
3421 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3422 pointer_buffer_mark_set = 1;
3424 /* restore the original buffer */
3425 pStubMsg->Buffer = saved_buffer;
3429 pFormat = ReadConformance(pStubMsg, pFormat);
3430 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3432 if (fMustAlloc || !*ppMemory)
3434 *ppMemory = NdrAllocate(pStubMsg, size);
3435 memset(*ppMemory, 0, size);
3438 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3440 pMemory = *ppMemory;
3441 count = pStubMsg->ActualCount;
3442 for (i = 0; i < count; i++)
3443 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
3445 if (pointer_buffer_mark_set)
3447 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3448 pStubMsg->PointerBufferMark = NULL;
3454 /***********************************************************************
3455 * NdrComplexArrayBufferSize [RPCRT4.@]
3457 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3458 unsigned char *pMemory,
3459 PFORMAT_STRING pFormat)
3461 ULONG i, count, def;
3462 unsigned char alignment;
3463 BOOL variance_present;
3464 int pointer_length_set = 0;
3466 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3468 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3470 ERR("invalid format type %x\n", pFormat[0]);
3471 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3475 alignment = pFormat[1] + 1;
3477 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3479 /* save buffer fields that may be changed by buffer sizer functions
3480 * and that may be needed later on */
3481 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3482 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3483 unsigned long saved_max_count = pStubMsg->MaxCount;
3484 unsigned long saved_offset = pStubMsg->Offset;
3485 unsigned long saved_actual_count = pStubMsg->ActualCount;
3487 /* get the buffer pointer after complex array data, but before
3489 pStubMsg->IgnoreEmbeddedPointers = 1;
3490 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3491 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3493 /* save it for use by embedded pointer code later */
3494 pStubMsg->PointerLength = pStubMsg->BufferLength;
3495 pointer_length_set = 1;
3497 /* restore fields */
3498 pStubMsg->ActualCount = saved_actual_count;
3499 pStubMsg->Offset = saved_offset;
3500 pStubMsg->MaxCount = saved_max_count;
3501 pStubMsg->BufferLength = saved_buffer_length;
3503 def = *(const WORD*)&pFormat[2];
3506 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3507 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3508 SizeConformance(pStubMsg);
3510 variance_present = IsConformanceOrVariancePresent(pFormat);
3511 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3512 TRACE("variance = %d\n", pStubMsg->ActualCount);
3514 if (variance_present)
3515 SizeVariance(pStubMsg);
3517 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3519 count = pStubMsg->ActualCount;
3520 for (i = 0; i < count; i++)
3521 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
3523 if(pointer_length_set)
3525 pStubMsg->BufferLength = pStubMsg->PointerLength;
3526 pStubMsg->PointerLength = 0;
3530 /***********************************************************************
3531 * NdrComplexArrayMemorySize [RPCRT4.@]
3533 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3534 PFORMAT_STRING pFormat)
3536 ULONG i, count, esize, SavedMemorySize, MemorySize;
3537 unsigned char alignment;
3539 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3541 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3543 ERR("invalid format type %x\n", pFormat[0]);
3544 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3548 alignment = pFormat[1] + 1;
3552 pFormat = ReadConformance(pStubMsg, pFormat);
3553 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3555 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3557 SavedMemorySize = pStubMsg->MemorySize;
3559 esize = ComplexStructSize(pStubMsg, pFormat);
3561 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
3563 count = pStubMsg->ActualCount;
3564 for (i = 0; i < count; i++)
3565 ComplexStructMemorySize(pStubMsg, pFormat);
3567 pStubMsg->MemorySize = SavedMemorySize;
3569 pStubMsg->MemorySize += MemorySize;
3573 /***********************************************************************
3574 * NdrComplexArrayFree [RPCRT4.@]
3576 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3577 unsigned char *pMemory,
3578 PFORMAT_STRING pFormat)
3580 ULONG i, count, def;
3582 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3584 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3586 ERR("invalid format type %x\n", pFormat[0]);
3587 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3591 def = *(const WORD*)&pFormat[2];
3594 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3595 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3597 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3598 TRACE("variance = %d\n", pStubMsg->ActualCount);
3600 count = pStubMsg->ActualCount;
3601 for (i = 0; i < count; i++)
3602 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
3605 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
3606 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
3607 USER_MARSHAL_CB *umcb)
3609 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
3610 pStubMsg->RpcMsg->DataRepresentation);
3611 umcb->pStubMsg = pStubMsg;
3612 umcb->pReserve = NULL;
3613 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
3614 umcb->CBType = cbtype;
3615 umcb->pFormat = pFormat;
3616 umcb->pTypeFormat = NULL /* FIXME */;
3619 #define USER_MARSHAL_PTR_PREFIX \
3620 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3621 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3623 /***********************************************************************
3624 * NdrUserMarshalMarshall [RPCRT4.@]
3626 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3627 unsigned char *pMemory,
3628 PFORMAT_STRING pFormat)
3630 unsigned flags = pFormat[1];
3631 unsigned index = *(const WORD*)&pFormat[2];
3632 unsigned char *saved_buffer = NULL;
3633 USER_MARSHAL_CB umcb;
3635 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3636 TRACE("index=%d\n", index);
3638 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
3640 if (flags & USER_MARSHAL_POINTER)
3642 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
3643 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
3644 pStubMsg->Buffer += 4;
3645 if (pStubMsg->PointerBufferMark)
3647 saved_buffer = pStubMsg->Buffer;
3648 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3649 pStubMsg->PointerBufferMark = NULL;
3651 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
3654 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
3657 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
3658 &umcb.Flags, pStubMsg->Buffer, pMemory);
3662 STD_OVERFLOW_CHECK(pStubMsg);
3663 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3664 pStubMsg->Buffer = saved_buffer;
3667 STD_OVERFLOW_CHECK(pStubMsg);
3672 /***********************************************************************
3673 * NdrUserMarshalUnmarshall [RPCRT4.@]
3675 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3676 unsigned char **ppMemory,
3677 PFORMAT_STRING pFormat,
3678 unsigned char fMustAlloc)
3680 unsigned flags = pFormat[1];
3681 unsigned index = *(const WORD*)&pFormat[2];
3682 DWORD memsize = *(const WORD*)&pFormat[4];
3683 unsigned char *saved_buffer = NULL;
3684 USER_MARSHAL_CB umcb;
3686 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3687 TRACE("index=%d\n", index);
3689 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
3691 if (flags & USER_MARSHAL_POINTER)
3693 ALIGN_POINTER(pStubMsg->Buffer, 4);
3694 /* skip pointer prefix */
3695 pStubMsg->Buffer += 4;
3696 if (pStubMsg->PointerBufferMark)
3698 saved_buffer = pStubMsg->Buffer;
3699 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3700 pStubMsg->PointerBufferMark = NULL;
3702 ALIGN_POINTER(pStubMsg->Buffer, 8);
3705 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3707 if (fMustAlloc || !*ppMemory)
3708 *ppMemory = NdrAllocate(pStubMsg, memsize);
3711 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
3712 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
3716 STD_OVERFLOW_CHECK(pStubMsg);
3717 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3718 pStubMsg->Buffer = saved_buffer;
3724 /***********************************************************************
3725 * NdrUserMarshalBufferSize [RPCRT4.@]
3727 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3728 unsigned char *pMemory,
3729 PFORMAT_STRING pFormat)
3731 unsigned flags = pFormat[1];
3732 unsigned index = *(const WORD*)&pFormat[2];
3733 DWORD bufsize = *(const WORD*)&pFormat[6];
3734 USER_MARSHAL_CB umcb;
3735 unsigned long saved_buffer_length = 0;
3737 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3738 TRACE("index=%d\n", index);
3740 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
3742 if (flags & USER_MARSHAL_POINTER)
3744 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3745 /* skip pointer prefix */
3746 safe_buffer_length_increment(pStubMsg, 4);
3747 if (pStubMsg->IgnoreEmbeddedPointers)
3749 if (pStubMsg->PointerLength)
3751 saved_buffer_length = pStubMsg->BufferLength;
3752 pStubMsg->BufferLength = pStubMsg->PointerLength;
3753 pStubMsg->PointerLength = 0;
3755 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
3758 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
3761 TRACE("size=%d\n", bufsize);
3762 safe_buffer_length_increment(pStubMsg, bufsize);
3765 pStubMsg->BufferLength =
3766 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
3767 &umcb.Flags, pStubMsg->BufferLength, pMemory);
3769 if (saved_buffer_length)
3771 pStubMsg->PointerLength = pStubMsg->BufferLength;
3772 pStubMsg->BufferLength = saved_buffer_length;
3777 /***********************************************************************
3778 * NdrUserMarshalMemorySize [RPCRT4.@]
3780 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3781 PFORMAT_STRING pFormat)
3783 unsigned flags = pFormat[1];
3784 unsigned index = *(const WORD*)&pFormat[2];
3785 DWORD memsize = *(const WORD*)&pFormat[4];
3786 DWORD bufsize = *(const WORD*)&pFormat[6];
3788 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3789 TRACE("index=%d\n", index);
3791 pStubMsg->MemorySize += memsize;
3793 if (flags & USER_MARSHAL_POINTER)
3795 ALIGN_POINTER(pStubMsg->Buffer, 4);
3796 /* skip pointer prefix */
3797 pStubMsg->Buffer += 4;
3798 if (pStubMsg->IgnoreEmbeddedPointers)
3799 return pStubMsg->MemorySize;
3800 ALIGN_POINTER(pStubMsg->Buffer, 8);
3803 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3806 FIXME("not implemented for varying buffer size\n");
3808 pStubMsg->Buffer += bufsize;
3810 return pStubMsg->MemorySize;
3813 /***********************************************************************
3814 * NdrUserMarshalFree [RPCRT4.@]
3816 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
3817 unsigned char *pMemory,
3818 PFORMAT_STRING pFormat)
3820 /* unsigned flags = pFormat[1]; */
3821 unsigned index = *(const WORD*)&pFormat[2];
3822 USER_MARSHAL_CB umcb;
3824 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3825 TRACE("index=%d\n", index);
3827 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
3829 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
3830 &umcb.Flags, pMemory);
3833 /***********************************************************************
3834 * NdrClearOutParameters [RPCRT4.@]
3836 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
3837 PFORMAT_STRING pFormat,
3840 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
3843 /***********************************************************************
3844 * NdrConvert [RPCRT4.@]
3846 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
3848 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
3849 /* FIXME: since this stub doesn't do any converting, the proper behavior
3850 is to raise an exception */
3853 /***********************************************************************
3854 * NdrConvert2 [RPCRT4.@]
3856 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
3858 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3859 pStubMsg, pFormat, NumberParams);
3860 /* FIXME: since this stub doesn't do any converting, the proper behavior
3861 is to raise an exception */
3864 #include "pshpack1.h"
3865 typedef struct _NDR_CSTRUCT_FORMAT
3868 unsigned char alignment;
3869 unsigned short memory_size;
3870 short offset_to_array_description;
3871 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
3872 #include "poppack.h"
3874 /***********************************************************************
3875 * NdrConformantStructMarshall [RPCRT4.@]
3877 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3878 unsigned char *pMemory,
3879 PFORMAT_STRING pFormat)
3881 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3882 PFORMAT_STRING pCArrayFormat;
3883 ULONG esize, bufsize;
3885 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3887 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3888 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3890 ERR("invalid format type %x\n", pCStructFormat->type);
3891 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3895 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3896 pCStructFormat->offset_to_array_description;
3897 if (*pCArrayFormat != RPC_FC_CARRAY)
3899 ERR("invalid array format type %x\n", pCStructFormat->type);
3900 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3903 esize = *(const WORD*)(pCArrayFormat+2);
3905 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3906 pCArrayFormat + 4, 0);
3908 WriteConformance(pStubMsg);
3910 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3912 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3914 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3915 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3917 ERR("integer overflow of memory_size %u with bufsize %u\n",
3918 pCStructFormat->memory_size, bufsize);
3919 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3921 /* copy constant sized part of struct */
3922 pStubMsg->BufferMark = pStubMsg->Buffer;
3923 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
3925 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3926 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3931 /***********************************************************************
3932 * NdrConformantStructUnmarshall [RPCRT4.@]
3934 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3935 unsigned char **ppMemory,
3936 PFORMAT_STRING pFormat,
3937 unsigned char fMustAlloc)
3939 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3940 PFORMAT_STRING pCArrayFormat;
3941 ULONG esize, bufsize;
3942 unsigned char *saved_buffer;
3944 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3946 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3947 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3949 ERR("invalid format type %x\n", pCStructFormat->type);
3950 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3953 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3954 pCStructFormat->offset_to_array_description;
3955 if (*pCArrayFormat != RPC_FC_CARRAY)
3957 ERR("invalid array format type %x\n", pCStructFormat->type);
3958 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3961 esize = *(const WORD*)(pCArrayFormat+2);
3963 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3965 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3967 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3969 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3970 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3972 ERR("integer overflow of memory_size %u with bufsize %u\n",
3973 pCStructFormat->memory_size, bufsize);
3974 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3979 SIZE_T size = pCStructFormat->memory_size + bufsize;
3980 *ppMemory = NdrAllocate(pStubMsg, size);
3984 if (!pStubMsg->IsClient && !*ppMemory)
3985 /* for servers, we just point straight into the RPC buffer */
3986 *ppMemory = pStubMsg->Buffer;
3989 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3990 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
3991 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3992 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3994 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
3995 if (*ppMemory != saved_buffer)
3996 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4001 /***********************************************************************
4002 * NdrConformantStructBufferSize [RPCRT4.@]
4004 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4005 unsigned char *pMemory,
4006 PFORMAT_STRING pFormat)
4008 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4009 PFORMAT_STRING pCArrayFormat;
4012 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4014 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4015 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4017 ERR("invalid format type %x\n", pCStructFormat->type);
4018 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4021 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4022 pCStructFormat->offset_to_array_description;
4023 if (*pCArrayFormat != RPC_FC_CARRAY)
4025 ERR("invalid array format type %x\n", pCStructFormat->type);
4026 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4029 esize = *(const WORD*)(pCArrayFormat+2);
4031 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4032 SizeConformance(pStubMsg);
4034 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4036 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4038 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4039 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4041 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4042 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4045 /***********************************************************************
4046 * NdrConformantStructMemorySize [RPCRT4.@]
4048 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4049 PFORMAT_STRING pFormat)
4055 /***********************************************************************
4056 * NdrConformantStructFree [RPCRT4.@]
4058 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4059 unsigned char *pMemory,
4060 PFORMAT_STRING pFormat)
4062 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4063 PFORMAT_STRING pCArrayFormat;
4065 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4067 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4068 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4070 ERR("invalid format type %x\n", pCStructFormat->type);
4071 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4075 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4076 pCStructFormat->offset_to_array_description;
4077 if (*pCArrayFormat != RPC_FC_CARRAY)
4079 ERR("invalid array format type %x\n", pCStructFormat->type);
4080 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4084 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4085 pCArrayFormat + 4, 0);
4087 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4089 /* copy constant sized part of struct */
4090 pStubMsg->BufferMark = pStubMsg->Buffer;
4092 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4093 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4096 /***********************************************************************
4097 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4099 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4100 unsigned char *pMemory,
4101 PFORMAT_STRING pFormat)
4103 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4104 PFORMAT_STRING pCVArrayFormat;
4105 ULONG esize, bufsize;
4107 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4109 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4110 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4112 ERR("invalid format type %x\n", pCVStructFormat->type);
4113 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4117 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4118 pCVStructFormat->offset_to_array_description;
4119 switch (*pCVArrayFormat)
4121 case RPC_FC_CVARRAY:
4122 esize = *(const WORD*)(pCVArrayFormat+2);
4124 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4125 pCVArrayFormat + 4, 0);
4126 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4129 case RPC_FC_C_CSTRING:
4130 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4131 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4132 esize = sizeof(char);
4133 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4134 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4135 pCVArrayFormat + 2, 0);
4137 pStubMsg->MaxCount = pStubMsg->ActualCount;
4139 case RPC_FC_C_WSTRING:
4140 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4141 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4142 esize = sizeof(WCHAR);
4143 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4144 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4145 pCVArrayFormat + 2, 0);
4147 pStubMsg->MaxCount = pStubMsg->ActualCount;
4150 ERR("invalid array format type %x\n", *pCVArrayFormat);
4151 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4155 WriteConformance(pStubMsg);
4157 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4159 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4161 /* write constant sized part */
4162 pStubMsg->BufferMark = pStubMsg->Buffer;
4163 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4165 WriteVariance(pStubMsg);
4167 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4169 /* write array part */
4170 safe_copy_to_buffer(pStubMsg, pMemory + pCVStructFormat->memory_size, bufsize);
4172 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4177 /***********************************************************************
4178 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4180 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4181 unsigned char **ppMemory,
4182 PFORMAT_STRING pFormat,
4183 unsigned char fMustAlloc)
4185 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4186 PFORMAT_STRING pCVArrayFormat;
4187 ULONG esize, bufsize;
4188 unsigned char cvarray_type;
4189 unsigned char *saved_buffer, *saved_array_buffer;
4191 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4193 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4194 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4196 ERR("invalid format type %x\n", pCVStructFormat->type);
4197 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4201 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4202 pCVStructFormat->offset_to_array_description;
4203 cvarray_type = *pCVArrayFormat;
4204 switch (cvarray_type)
4206 case RPC_FC_CVARRAY:
4207 esize = *(const WORD*)(pCVArrayFormat+2);
4208 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4210 case RPC_FC_C_CSTRING:
4211 esize = sizeof(char);
4212 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4213 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4215 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4217 case RPC_FC_C_WSTRING:
4218 esize = sizeof(WCHAR);
4219 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4220 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4222 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4225 ERR("invalid array format type %x\n", *pCVArrayFormat);
4226 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4230 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4232 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4234 /* work out how much memory to allocate if we need to do so */
4235 if (!*ppMemory || fMustAlloc)
4237 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4238 *ppMemory = NdrAllocate(pStubMsg, size);
4241 /* mark the start of the constant data */
4242 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4243 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4245 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4247 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4249 if ((cvarray_type == RPC_FC_C_CSTRING) ||
4250 (cvarray_type == RPC_FC_C_WSTRING))
4251 validate_string_data(pStubMsg, bufsize, esize);
4253 /* mark the start of the array data */
4254 saved_array_buffer = pStubMsg->Buffer;
4255 safe_buffer_increment(pStubMsg, bufsize);
4257 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4259 /* copy the constant data */
4260 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
4261 /* copy the array data */
4262 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
4263 memcpy(*ppMemory + pCVStructFormat->memory_size, saved_array_buffer, bufsize);
4265 if (cvarray_type == RPC_FC_C_CSTRING)
4266 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
4267 else if (cvarray_type == RPC_FC_C_WSTRING)
4268 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
4273 /***********************************************************************
4274 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4276 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4277 unsigned char *pMemory,
4278 PFORMAT_STRING pFormat)
4280 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4281 PFORMAT_STRING pCVArrayFormat;
4284 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4286 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4287 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4289 ERR("invalid format type %x\n", pCVStructFormat->type);
4290 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4294 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4295 pCVStructFormat->offset_to_array_description;
4296 switch (*pCVArrayFormat)
4298 case RPC_FC_CVARRAY:
4299 esize = *(const WORD*)(pCVArrayFormat+2);
4301 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4302 pCVArrayFormat + 4, 0);
4303 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4306 case RPC_FC_C_CSTRING:
4307 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4308 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4309 esize = sizeof(char);
4310 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4311 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4312 pCVArrayFormat + 2, 0);
4314 pStubMsg->MaxCount = pStubMsg->ActualCount;
4316 case RPC_FC_C_WSTRING:
4317 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4318 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4319 esize = sizeof(WCHAR);
4320 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4321 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4322 pCVArrayFormat + 2, 0);
4324 pStubMsg->MaxCount = pStubMsg->ActualCount;
4327 ERR("invalid array format type %x\n", *pCVArrayFormat);
4328 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4332 SizeConformance(pStubMsg);
4334 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4336 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4338 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4339 SizeVariance(pStubMsg);
4340 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4342 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4345 /***********************************************************************
4346 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4348 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4349 PFORMAT_STRING pFormat)
4351 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4352 PFORMAT_STRING pCVArrayFormat;
4354 unsigned char cvarray_type;
4356 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4358 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4359 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4361 ERR("invalid format type %x\n", pCVStructFormat->type);
4362 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4366 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4367 pCVStructFormat->offset_to_array_description;
4368 cvarray_type = *pCVArrayFormat;
4369 switch (cvarray_type)
4371 case RPC_FC_CVARRAY:
4372 esize = *(const WORD*)(pCVArrayFormat+2);
4373 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4375 case RPC_FC_C_CSTRING:
4376 esize = sizeof(char);
4377 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4378 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4380 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4382 case RPC_FC_C_WSTRING:
4383 esize = sizeof(WCHAR);
4384 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4385 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4387 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4390 ERR("invalid array format type %x\n", *pCVArrayFormat);
4391 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4395 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4397 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4399 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4400 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4401 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4403 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4405 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4407 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
4410 /***********************************************************************
4411 * NdrConformantVaryingStructFree [RPCRT4.@]
4413 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4414 unsigned char *pMemory,
4415 PFORMAT_STRING pFormat)
4417 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4418 PFORMAT_STRING pCVArrayFormat;
4420 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4422 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4423 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4425 ERR("invalid format type %x\n", pCVStructFormat->type);
4426 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4430 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4431 pCVStructFormat->offset_to_array_description;
4432 switch (*pCVArrayFormat)
4434 case RPC_FC_CVARRAY:
4435 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4436 pCVArrayFormat + 4, 0);
4437 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4440 case RPC_FC_C_CSTRING:
4441 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4442 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4443 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4444 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4445 pCVArrayFormat + 2, 0);
4447 pStubMsg->MaxCount = pStubMsg->ActualCount;
4449 case RPC_FC_C_WSTRING:
4450 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4451 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4452 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4453 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4454 pCVArrayFormat + 2, 0);
4456 pStubMsg->MaxCount = pStubMsg->ActualCount;
4459 ERR("invalid array format type %x\n", *pCVArrayFormat);
4460 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4464 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4466 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4469 #include "pshpack1.h"
4473 unsigned char alignment;
4474 unsigned short total_size;
4475 } NDR_SMFARRAY_FORMAT;
4480 unsigned char alignment;
4481 unsigned long total_size;
4482 } NDR_LGFARRAY_FORMAT;
4483 #include "poppack.h"
4485 /***********************************************************************
4486 * NdrFixedArrayMarshall [RPCRT4.@]
4488 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4489 unsigned char *pMemory,
4490 PFORMAT_STRING pFormat)
4492 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4493 unsigned long total_size;
4495 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4497 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4498 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4500 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4501 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4505 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4507 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4509 total_size = pSmFArrayFormat->total_size;
4510 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4514 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4515 total_size = pLgFArrayFormat->total_size;
4516 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4519 pStubMsg->BufferMark = pStubMsg->Buffer;
4520 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4522 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4527 /***********************************************************************
4528 * NdrFixedArrayUnmarshall [RPCRT4.@]
4530 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4531 unsigned char **ppMemory,
4532 PFORMAT_STRING pFormat,
4533 unsigned char fMustAlloc)
4535 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4536 unsigned long total_size;
4537 unsigned char *saved_buffer;
4539 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4541 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4542 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4544 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4545 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4549 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4551 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4553 total_size = pSmFArrayFormat->total_size;
4554 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4558 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4559 total_size = pLgFArrayFormat->total_size;
4560 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4564 *ppMemory = NdrAllocate(pStubMsg, total_size);
4567 if (!pStubMsg->IsClient && !*ppMemory)
4568 /* for servers, we just point straight into the RPC buffer */
4569 *ppMemory = pStubMsg->Buffer;
4572 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4573 safe_buffer_increment(pStubMsg, total_size);
4574 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4576 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4577 if (*ppMemory != saved_buffer)
4578 memcpy(*ppMemory, saved_buffer, total_size);
4583 /***********************************************************************
4584 * NdrFixedArrayBufferSize [RPCRT4.@]
4586 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4587 unsigned char *pMemory,
4588 PFORMAT_STRING pFormat)
4590 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4591 unsigned long total_size;
4593 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4595 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4596 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4598 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4599 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4603 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4605 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4607 total_size = pSmFArrayFormat->total_size;
4608 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4612 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4613 total_size = pLgFArrayFormat->total_size;
4614 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4616 safe_buffer_length_increment(pStubMsg, total_size);
4618 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4621 /***********************************************************************
4622 * NdrFixedArrayMemorySize [RPCRT4.@]
4624 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4625 PFORMAT_STRING pFormat)
4627 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4630 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4632 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4633 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4635 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4636 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4640 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4642 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4644 total_size = pSmFArrayFormat->total_size;
4645 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4649 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4650 total_size = pLgFArrayFormat->total_size;
4651 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4653 pStubMsg->BufferMark = pStubMsg->Buffer;
4654 safe_buffer_increment(pStubMsg, total_size);
4655 pStubMsg->MemorySize += total_size;
4657 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4662 /***********************************************************************
4663 * NdrFixedArrayFree [RPCRT4.@]
4665 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4666 unsigned char *pMemory,
4667 PFORMAT_STRING pFormat)
4669 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4671 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4673 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4674 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4676 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4677 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4681 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4682 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4685 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4686 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4689 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4692 /***********************************************************************
4693 * NdrVaryingArrayMarshall [RPCRT4.@]
4695 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4696 unsigned char *pMemory,
4697 PFORMAT_STRING pFormat)
4699 unsigned char alignment;
4700 DWORD elements, esize;
4703 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4705 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4706 (pFormat[0] != RPC_FC_LGVARRAY))
4708 ERR("invalid format type %x\n", pFormat[0]);
4709 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4713 alignment = pFormat[1] + 1;
4715 if (pFormat[0] == RPC_FC_SMVARRAY)
4718 pFormat += sizeof(WORD);
4719 elements = *(const WORD*)pFormat;
4720 pFormat += sizeof(WORD);
4725 pFormat += sizeof(DWORD);
4726 elements = *(const DWORD*)pFormat;
4727 pFormat += sizeof(DWORD);
4730 esize = *(const WORD*)pFormat;
4731 pFormat += sizeof(WORD);
4733 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4734 if ((pStubMsg->ActualCount > elements) ||
4735 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4737 RpcRaiseException(RPC_S_INVALID_BOUND);
4741 WriteVariance(pStubMsg);
4743 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
4745 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4746 pStubMsg->BufferMark = pStubMsg->Buffer;
4747 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
4749 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4754 /***********************************************************************
4755 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4757 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4758 unsigned char **ppMemory,
4759 PFORMAT_STRING pFormat,
4760 unsigned char fMustAlloc)
4762 unsigned char alignment;
4763 DWORD size, elements, esize;
4765 unsigned char *saved_buffer;
4768 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4770 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4771 (pFormat[0] != RPC_FC_LGVARRAY))
4773 ERR("invalid format type %x\n", pFormat[0]);
4774 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4778 alignment = pFormat[1] + 1;
4780 if (pFormat[0] == RPC_FC_SMVARRAY)
4783 size = *(const WORD*)pFormat;
4784 pFormat += sizeof(WORD);
4785 elements = *(const WORD*)pFormat;
4786 pFormat += sizeof(WORD);
4791 size = *(const DWORD*)pFormat;
4792 pFormat += sizeof(DWORD);
4793 elements = *(const DWORD*)pFormat;
4794 pFormat += sizeof(DWORD);
4797 esize = *(const WORD*)pFormat;
4798 pFormat += sizeof(WORD);
4800 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4802 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4804 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4805 offset = pStubMsg->Offset;
4807 if (!*ppMemory || fMustAlloc)
4808 *ppMemory = NdrAllocate(pStubMsg, size);
4809 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4810 safe_buffer_increment(pStubMsg, bufsize);
4812 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4814 memcpy(*ppMemory + offset, saved_buffer, bufsize);
4819 /***********************************************************************
4820 * NdrVaryingArrayBufferSize [RPCRT4.@]
4822 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4823 unsigned char *pMemory,
4824 PFORMAT_STRING pFormat)
4826 unsigned char alignment;
4827 DWORD elements, esize;
4829 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4831 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4832 (pFormat[0] != RPC_FC_LGVARRAY))
4834 ERR("invalid format type %x\n", pFormat[0]);
4835 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4839 alignment = pFormat[1] + 1;
4841 if (pFormat[0] == RPC_FC_SMVARRAY)
4844 pFormat += sizeof(WORD);
4845 elements = *(const WORD*)pFormat;
4846 pFormat += sizeof(WORD);
4851 pFormat += sizeof(DWORD);
4852 elements = *(const DWORD*)pFormat;
4853 pFormat += sizeof(DWORD);
4856 esize = *(const WORD*)pFormat;
4857 pFormat += sizeof(WORD);
4859 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4860 if ((pStubMsg->ActualCount > elements) ||
4861 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4863 RpcRaiseException(RPC_S_INVALID_BOUND);
4867 SizeVariance(pStubMsg);
4869 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4871 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4873 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4876 /***********************************************************************
4877 * NdrVaryingArrayMemorySize [RPCRT4.@]
4879 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4880 PFORMAT_STRING pFormat)
4882 unsigned char alignment;
4883 DWORD size, elements, esize;
4885 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4887 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4888 (pFormat[0] != RPC_FC_LGVARRAY))
4890 ERR("invalid format type %x\n", pFormat[0]);
4891 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4895 alignment = pFormat[1] + 1;
4897 if (pFormat[0] == RPC_FC_SMVARRAY)
4900 size = *(const WORD*)pFormat;
4901 pFormat += sizeof(WORD);
4902 elements = *(const WORD*)pFormat;
4903 pFormat += sizeof(WORD);
4908 size = *(const DWORD*)pFormat;
4909 pFormat += sizeof(DWORD);
4910 elements = *(const DWORD*)pFormat;
4911 pFormat += sizeof(DWORD);
4914 esize = *(const WORD*)pFormat;
4915 pFormat += sizeof(WORD);
4917 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4919 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4921 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4922 pStubMsg->MemorySize += size;
4924 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4926 return pStubMsg->MemorySize;
4929 /***********************************************************************
4930 * NdrVaryingArrayFree [RPCRT4.@]
4932 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4933 unsigned char *pMemory,
4934 PFORMAT_STRING pFormat)
4938 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4940 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4941 (pFormat[0] != RPC_FC_LGVARRAY))
4943 ERR("invalid format type %x\n", pFormat[0]);
4944 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4948 if (pFormat[0] == RPC_FC_SMVARRAY)
4951 pFormat += sizeof(WORD);
4952 elements = *(const WORD*)pFormat;
4953 pFormat += sizeof(WORD);
4958 pFormat += sizeof(DWORD);
4959 elements = *(const DWORD*)pFormat;
4960 pFormat += sizeof(DWORD);
4963 pFormat += sizeof(WORD);
4965 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4966 if ((pStubMsg->ActualCount > elements) ||
4967 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4969 RpcRaiseException(RPC_S_INVALID_BOUND);
4973 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4976 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
4989 return *(const USHORT *)pMemory;
4993 return *(const ULONG *)pMemory;
4995 FIXME("Unhandled base type: 0x%02x\n", fc);
5000 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5001 unsigned long discriminant,
5002 PFORMAT_STRING pFormat)
5004 unsigned short num_arms, arm, type;
5006 num_arms = *(const SHORT*)pFormat & 0x0fff;
5008 for(arm = 0; arm < num_arms; arm++)
5010 if(discriminant == *(const ULONG*)pFormat)
5018 type = *(const unsigned short*)pFormat;
5019 TRACE("type %04x\n", type);
5020 if(arm == num_arms) /* default arm extras */
5024 ERR("no arm for 0x%lx and no default case\n", discriminant);
5025 RpcRaiseException(RPC_S_INVALID_TAG);
5030 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
5037 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5039 unsigned short type;
5043 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5047 type = *(const unsigned short*)pFormat;
5048 if((type & 0xff00) == 0x8000)
5050 unsigned char basetype = LOBYTE(type);
5051 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5055 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5056 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5059 unsigned char *saved_buffer = NULL;
5060 int pointer_buffer_mark_set = 0;
5067 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5068 saved_buffer = pStubMsg->Buffer;
5069 if (pStubMsg->PointerBufferMark)
5071 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5072 pStubMsg->PointerBufferMark = NULL;
5073 pointer_buffer_mark_set = 1;
5076 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5078 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5079 if (pointer_buffer_mark_set)
5081 STD_OVERFLOW_CHECK(pStubMsg);
5082 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5083 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5085 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5086 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5087 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5089 pStubMsg->Buffer = saved_buffer + 4;
5093 m(pStubMsg, pMemory, desc);
5096 else FIXME("no marshaller for embedded type %02x\n", *desc);
5101 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5102 unsigned char **ppMemory,
5104 PFORMAT_STRING pFormat,
5105 unsigned char fMustAlloc)
5107 unsigned short type;
5111 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5115 type = *(const unsigned short*)pFormat;
5116 if((type & 0xff00) == 0x8000)
5118 unsigned char basetype = LOBYTE(type);
5119 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5123 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5124 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5127 unsigned char *saved_buffer = NULL;
5128 int pointer_buffer_mark_set = 0;
5135 **(void***)ppMemory = NULL;
5136 ALIGN_POINTER(pStubMsg->Buffer, 4);
5137 saved_buffer = pStubMsg->Buffer;
5138 if (pStubMsg->PointerBufferMark)
5140 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5141 pStubMsg->PointerBufferMark = NULL;
5142 pointer_buffer_mark_set = 1;
5145 pStubMsg->Buffer += 4; /* for pointer ID */
5147 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5149 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5150 saved_buffer, pStubMsg->BufferEnd);
5151 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5154 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5155 if (pointer_buffer_mark_set)
5157 STD_OVERFLOW_CHECK(pStubMsg);
5158 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5159 pStubMsg->Buffer = saved_buffer + 4;
5163 m(pStubMsg, ppMemory, desc, fMustAlloc);
5166 else FIXME("no marshaller for embedded type %02x\n", *desc);
5171 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5172 unsigned char *pMemory,
5174 PFORMAT_STRING pFormat)
5176 unsigned short type;
5180 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5184 type = *(const unsigned short*)pFormat;
5185 if((type & 0xff00) == 0x8000)
5187 unsigned char basetype = LOBYTE(type);
5188 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5192 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5193 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5202 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5203 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5204 if (!pStubMsg->IgnoreEmbeddedPointers)
5206 int saved_buffer_length = pStubMsg->BufferLength;
5207 pStubMsg->BufferLength = pStubMsg->PointerLength;
5208 pStubMsg->PointerLength = 0;
5209 if(!pStubMsg->BufferLength)
5210 ERR("BufferLength == 0??\n");
5211 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5212 pStubMsg->PointerLength = pStubMsg->BufferLength;
5213 pStubMsg->BufferLength = saved_buffer_length;
5217 m(pStubMsg, pMemory, desc);
5220 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5224 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5226 PFORMAT_STRING pFormat)
5228 unsigned short type, size;
5230 size = *(const unsigned short*)pFormat;
5231 pStubMsg->Memory += size;
5234 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5238 type = *(const unsigned short*)pFormat;
5239 if((type & 0xff00) == 0x8000)
5241 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5245 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5246 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5247 unsigned char *saved_buffer;
5256 ALIGN_POINTER(pStubMsg->Buffer, 4);
5257 saved_buffer = pStubMsg->Buffer;
5258 safe_buffer_increment(pStubMsg, 4);
5259 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
5260 pStubMsg->MemorySize += 4;
5261 if (!pStubMsg->IgnoreEmbeddedPointers)
5262 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5265 return m(pStubMsg, desc);
5268 else FIXME("no marshaller for embedded type %02x\n", *desc);
5271 TRACE("size %d\n", size);
5275 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5276 unsigned char *pMemory,
5278 PFORMAT_STRING pFormat)
5280 unsigned short type;
5284 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5288 type = *(const unsigned short*)pFormat;
5289 if((type & 0xff00) != 0x8000)
5291 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5292 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5301 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5304 m(pStubMsg, pMemory, desc);
5310 /***********************************************************************
5311 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5313 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5314 unsigned char *pMemory,
5315 PFORMAT_STRING pFormat)
5317 unsigned char switch_type;
5318 unsigned char increment;
5321 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5324 switch_type = *pFormat & 0xf;
5325 increment = (*pFormat & 0xf0) >> 4;
5328 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5330 switch_value = get_discriminant(switch_type, pMemory);
5331 TRACE("got switch value 0x%x\n", switch_value);
5333 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5334 pMemory += increment;
5336 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5339 /***********************************************************************
5340 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5342 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5343 unsigned char **ppMemory,
5344 PFORMAT_STRING pFormat,
5345 unsigned char fMustAlloc)
5347 unsigned char switch_type;
5348 unsigned char increment;
5350 unsigned short size;
5351 unsigned char *pMemoryArm;
5353 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5356 switch_type = *pFormat & 0xf;
5357 increment = (*pFormat & 0xf0) >> 4;
5360 ALIGN_POINTER(pStubMsg->Buffer, increment);
5361 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5362 TRACE("got switch value 0x%x\n", switch_value);
5364 size = *(const unsigned short*)pFormat + increment;
5365 if(!*ppMemory || fMustAlloc)
5366 *ppMemory = NdrAllocate(pStubMsg, size);
5368 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5369 pMemoryArm = *ppMemory + increment;
5371 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
5374 /***********************************************************************
5375 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5377 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5378 unsigned char *pMemory,
5379 PFORMAT_STRING pFormat)
5381 unsigned char switch_type;
5382 unsigned char increment;
5385 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5388 switch_type = *pFormat & 0xf;
5389 increment = (*pFormat & 0xf0) >> 4;
5392 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5393 switch_value = get_discriminant(switch_type, pMemory);
5394 TRACE("got switch value 0x%x\n", switch_value);
5396 /* Add discriminant size */
5397 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5398 pMemory += increment;
5400 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5403 /***********************************************************************
5404 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5406 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5407 PFORMAT_STRING pFormat)
5409 unsigned char switch_type;
5410 unsigned char increment;
5413 switch_type = *pFormat & 0xf;
5414 increment = (*pFormat & 0xf0) >> 4;
5417 ALIGN_POINTER(pStubMsg->Buffer, increment);
5418 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5419 TRACE("got switch value 0x%x\n", switch_value);
5421 pStubMsg->Memory += increment;
5423 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5426 /***********************************************************************
5427 * NdrEncapsulatedUnionFree [RPCRT4.@]
5429 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5430 unsigned char *pMemory,
5431 PFORMAT_STRING pFormat)
5433 unsigned char switch_type;
5434 unsigned char increment;
5437 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5440 switch_type = *pFormat & 0xf;
5441 increment = (*pFormat & 0xf0) >> 4;
5444 switch_value = get_discriminant(switch_type, pMemory);
5445 TRACE("got switch value 0x%x\n", switch_value);
5447 pMemory += increment;
5449 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5452 /***********************************************************************
5453 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5455 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5456 unsigned char *pMemory,
5457 PFORMAT_STRING pFormat)
5459 unsigned char switch_type;
5461 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5464 switch_type = *pFormat;
5467 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5468 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5469 /* Marshall discriminant */
5470 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5472 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5475 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5476 PFORMAT_STRING *ppFormat)
5478 long discriminant = 0;
5488 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5497 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5498 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5506 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5507 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5512 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5516 if (pStubMsg->fHasNewCorrDesc)
5520 return discriminant;
5523 /**********************************************************************
5524 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5526 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5527 unsigned char **ppMemory,
5528 PFORMAT_STRING pFormat,
5529 unsigned char fMustAlloc)
5532 unsigned short size;
5534 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5537 /* Unmarshall discriminant */
5538 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5539 TRACE("unmarshalled discriminant %lx\n", discriminant);
5541 pFormat += *(const SHORT*)pFormat;
5543 size = *(const unsigned short*)pFormat;
5545 if(!*ppMemory || fMustAlloc)
5546 *ppMemory = NdrAllocate(pStubMsg, size);
5548 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5551 /***********************************************************************
5552 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5554 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5555 unsigned char *pMemory,
5556 PFORMAT_STRING pFormat)
5558 unsigned char switch_type;
5560 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5563 switch_type = *pFormat;
5566 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5567 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5568 /* Add discriminant size */
5569 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5571 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5574 /***********************************************************************
5575 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5577 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5578 PFORMAT_STRING pFormat)
5583 /* Unmarshall discriminant */
5584 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5585 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
5587 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
5590 /***********************************************************************
5591 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5593 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5594 unsigned char *pMemory,
5595 PFORMAT_STRING pFormat)
5597 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5601 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5602 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5604 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5607 /***********************************************************************
5608 * NdrByteCountPointerMarshall [RPCRT4.@]
5610 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5611 unsigned char *pMemory,
5612 PFORMAT_STRING pFormat)
5618 /***********************************************************************
5619 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5621 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5622 unsigned char **ppMemory,
5623 PFORMAT_STRING pFormat,
5624 unsigned char fMustAlloc)
5630 /***********************************************************************
5631 * NdrByteCountPointerBufferSize [RPCRT4.@]
5633 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5634 unsigned char *pMemory,
5635 PFORMAT_STRING pFormat)
5640 /***********************************************************************
5641 * NdrByteCountPointerMemorySize [RPCRT4.@]
5643 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5644 PFORMAT_STRING pFormat)
5650 /***********************************************************************
5651 * NdrByteCountPointerFree [RPCRT4.@]
5653 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
5654 unsigned char *pMemory,
5655 PFORMAT_STRING pFormat)
5660 /***********************************************************************
5661 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5663 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5664 unsigned char *pMemory,
5665 PFORMAT_STRING pFormat)
5671 /***********************************************************************
5672 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5674 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5675 unsigned char **ppMemory,
5676 PFORMAT_STRING pFormat,
5677 unsigned char fMustAlloc)
5683 /***********************************************************************
5684 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5686 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5687 unsigned char *pMemory,
5688 PFORMAT_STRING pFormat)
5693 /***********************************************************************
5694 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5696 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5697 PFORMAT_STRING pFormat)
5703 /***********************************************************************
5704 * NdrXmitOrRepAsFree [RPCRT4.@]
5706 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
5707 unsigned char *pMemory,
5708 PFORMAT_STRING pFormat)
5713 #include "pshpack1.h"
5717 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
5721 #include "poppack.h"
5723 /***********************************************************************
5724 * NdrRangeMarshall [internal]
5726 unsigned char *WINAPI NdrRangeMarshall(
5727 PMIDL_STUB_MESSAGE pStubMsg,
5728 unsigned char *pMemory,
5729 PFORMAT_STRING pFormat)
5731 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5732 unsigned char base_type;
5734 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5736 if (pRange->type != RPC_FC_RANGE)
5738 ERR("invalid format type %x\n", pRange->type);
5739 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5743 base_type = pRange->flags_type & 0xf;
5745 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
5748 /***********************************************************************
5749 * NdrRangeUnmarshall
5751 unsigned char *WINAPI NdrRangeUnmarshall(
5752 PMIDL_STUB_MESSAGE pStubMsg,
5753 unsigned char **ppMemory,
5754 PFORMAT_STRING pFormat,
5755 unsigned char fMustAlloc)
5757 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5758 unsigned char base_type;
5760 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5762 if (pRange->type != RPC_FC_RANGE)
5764 ERR("invalid format type %x\n", pRange->type);
5765 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5768 base_type = pRange->flags_type & 0xf;
5770 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5771 base_type, pRange->low_value, pRange->high_value);
5773 #define RANGE_UNMARSHALL(type, format_spec) \
5776 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5777 if (fMustAlloc || !*ppMemory) \
5778 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5779 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5781 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5782 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5783 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5785 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5786 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5788 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5789 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5790 (type)pRange->high_value); \
5791 RpcRaiseException(RPC_S_INVALID_BOUND); \
5794 TRACE("*ppMemory: %p\n", *ppMemory); \
5795 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5796 pStubMsg->Buffer += sizeof(type); \
5803 RANGE_UNMARSHALL(UCHAR, "%d");
5804 TRACE("value: 0x%02x\n", **ppMemory);
5808 RANGE_UNMARSHALL(CHAR, "%u");
5809 TRACE("value: 0x%02x\n", **ppMemory);
5811 case RPC_FC_WCHAR: /* FIXME: valid? */
5813 RANGE_UNMARSHALL(USHORT, "%u");
5814 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5817 RANGE_UNMARSHALL(SHORT, "%d");
5818 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5821 RANGE_UNMARSHALL(LONG, "%d");
5822 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5825 RANGE_UNMARSHALL(ULONG, "%u");
5826 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5830 FIXME("Unhandled enum type\n");
5832 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
5837 ERR("invalid range base type: 0x%02x\n", base_type);
5838 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5844 /***********************************************************************
5845 * NdrRangeBufferSize [internal]
5847 void WINAPI NdrRangeBufferSize(
5848 PMIDL_STUB_MESSAGE pStubMsg,
5849 unsigned char *pMemory,
5850 PFORMAT_STRING pFormat)
5852 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5853 unsigned char base_type;
5855 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5857 if (pRange->type != RPC_FC_RANGE)
5859 ERR("invalid format type %x\n", pRange->type);
5860 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5862 base_type = pRange->flags_type & 0xf;
5864 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
5867 /***********************************************************************
5868 * NdrRangeMemorySize [internal]
5870 ULONG WINAPI NdrRangeMemorySize(
5871 PMIDL_STUB_MESSAGE pStubMsg,
5872 PFORMAT_STRING pFormat)
5874 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5875 unsigned char base_type;
5877 if (pRange->type != RPC_FC_RANGE)
5879 ERR("invalid format type %x\n", pRange->type);
5880 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5883 base_type = pRange->flags_type & 0xf;
5885 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
5888 /***********************************************************************
5889 * NdrRangeFree [internal]
5891 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
5892 unsigned char *pMemory,
5893 PFORMAT_STRING pFormat)
5895 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5900 /***********************************************************************
5901 * NdrBaseTypeMarshall [internal]
5903 static unsigned char *WINAPI NdrBaseTypeMarshall(
5904 PMIDL_STUB_MESSAGE pStubMsg,
5905 unsigned char *pMemory,
5906 PFORMAT_STRING pFormat)
5908 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5916 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
5917 TRACE("value: 0x%02x\n", *pMemory);
5922 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
5923 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
5924 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
5928 case RPC_FC_ERROR_STATUS_T:
5930 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
5931 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
5932 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
5935 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
5936 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
5939 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
5940 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
5943 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
5944 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
5945 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
5948 /* only 16-bits on the wire, so do a sanity check */
5949 if (*(UINT *)pMemory > SHRT_MAX)
5950 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
5951 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
5952 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5953 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5954 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
5955 pStubMsg->Buffer += sizeof(USHORT);
5956 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
5961 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5964 /* FIXME: what is the correct return value? */
5968 /***********************************************************************
5969 * NdrBaseTypeUnmarshall [internal]
5971 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
5972 PMIDL_STUB_MESSAGE pStubMsg,
5973 unsigned char **ppMemory,
5974 PFORMAT_STRING pFormat,
5975 unsigned char fMustAlloc)
5977 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5979 #define BASE_TYPE_UNMARSHALL(type) \
5980 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5981 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
5983 *ppMemory = pStubMsg->Buffer; \
5984 TRACE("*ppMemory: %p\n", *ppMemory); \
5985 safe_buffer_increment(pStubMsg, sizeof(type)); \
5990 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5991 TRACE("*ppMemory: %p\n", *ppMemory); \
5992 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6001 BASE_TYPE_UNMARSHALL(UCHAR);
6002 TRACE("value: 0x%02x\n", **ppMemory);
6007 BASE_TYPE_UNMARSHALL(USHORT);
6008 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6012 case RPC_FC_ERROR_STATUS_T:
6014 BASE_TYPE_UNMARSHALL(ULONG);
6015 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6018 BASE_TYPE_UNMARSHALL(float);
6019 TRACE("value: %f\n", **(float **)ppMemory);
6022 BASE_TYPE_UNMARSHALL(double);
6023 TRACE("value: %f\n", **(double **)ppMemory);
6026 BASE_TYPE_UNMARSHALL(ULONGLONG);
6027 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6030 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6031 if (fMustAlloc || !*ppMemory)
6032 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6033 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
6034 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6035 TRACE("*ppMemory: %p\n", *ppMemory);
6036 /* 16-bits on the wire, but int in memory */
6037 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
6038 pStubMsg->Buffer += sizeof(USHORT);
6039 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6044 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6046 #undef BASE_TYPE_UNMARSHALL
6048 /* FIXME: what is the correct return value? */
6053 /***********************************************************************
6054 * NdrBaseTypeBufferSize [internal]
6056 static void WINAPI NdrBaseTypeBufferSize(
6057 PMIDL_STUB_MESSAGE pStubMsg,
6058 unsigned char *pMemory,
6059 PFORMAT_STRING pFormat)
6061 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6069 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6075 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
6076 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6081 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
6082 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6085 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
6086 safe_buffer_length_increment(pStubMsg, sizeof(float));
6089 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
6090 safe_buffer_length_increment(pStubMsg, sizeof(double));
6093 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
6094 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6096 case RPC_FC_ERROR_STATUS_T:
6097 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
6098 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6103 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6107 /***********************************************************************
6108 * NdrBaseTypeMemorySize [internal]
6110 static ULONG WINAPI NdrBaseTypeMemorySize(
6111 PMIDL_STUB_MESSAGE pStubMsg,
6112 PFORMAT_STRING pFormat)
6114 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6122 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6123 pStubMsg->MemorySize += sizeof(UCHAR);
6124 return sizeof(UCHAR);
6128 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6129 pStubMsg->MemorySize += sizeof(USHORT);
6130 return sizeof(USHORT);
6134 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6135 pStubMsg->MemorySize += sizeof(ULONG);
6136 return sizeof(ULONG);
6138 safe_buffer_increment(pStubMsg, sizeof(float));
6139 pStubMsg->MemorySize += sizeof(float);
6140 return sizeof(float);
6142 safe_buffer_increment(pStubMsg, sizeof(double));
6143 pStubMsg->MemorySize += sizeof(double);
6144 return sizeof(double);
6146 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6147 pStubMsg->MemorySize += sizeof(ULONGLONG);
6148 return sizeof(ULONGLONG);
6149 case RPC_FC_ERROR_STATUS_T:
6150 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6151 pStubMsg->MemorySize += sizeof(error_status_t);
6152 return sizeof(error_status_t);
6154 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6155 pStubMsg->MemorySize += sizeof(UINT);
6156 return sizeof(UINT);
6158 pStubMsg->MemorySize += sizeof(void *);
6159 return sizeof(void *);
6161 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6166 /***********************************************************************
6167 * NdrBaseTypeFree [internal]
6169 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6170 unsigned char *pMemory,
6171 PFORMAT_STRING pFormat)
6173 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6178 /***********************************************************************
6179 * NdrContextHandleBufferSize [internal]
6181 static void WINAPI NdrContextHandleBufferSize(
6182 PMIDL_STUB_MESSAGE pStubMsg,
6183 unsigned char *pMemory,
6184 PFORMAT_STRING pFormat)
6186 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6188 if (*pFormat != RPC_FC_BIND_CONTEXT)
6190 ERR("invalid format type %x\n", *pFormat);
6191 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6193 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
6194 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6197 /***********************************************************************
6198 * NdrContextHandleMarshall [internal]
6200 static unsigned char *WINAPI NdrContextHandleMarshall(
6201 PMIDL_STUB_MESSAGE pStubMsg,
6202 unsigned char *pMemory,
6203 PFORMAT_STRING pFormat)
6205 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6207 if (*pFormat != RPC_FC_BIND_CONTEXT)
6209 ERR("invalid format type %x\n", *pFormat);
6210 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6212 TRACE("flags: 0x%02x\n", pFormat[1]);
6214 if (pFormat[1] & 0x80)
6215 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6217 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
6222 /***********************************************************************
6223 * NdrContextHandleUnmarshall [internal]
6225 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6226 PMIDL_STUB_MESSAGE pStubMsg,
6227 unsigned char **ppMemory,
6228 PFORMAT_STRING pFormat,
6229 unsigned char fMustAlloc)
6231 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6232 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6234 if (*pFormat != RPC_FC_BIND_CONTEXT)
6236 ERR("invalid format type %x\n", *pFormat);
6237 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6239 TRACE("flags: 0x%02x\n", pFormat[1]);
6241 /* [out]-only or [ret] param */
6242 if ((pFormat[1] & 0x60) == 0x20)
6243 **(NDR_CCONTEXT **)ppMemory = NULL;
6244 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6249 /***********************************************************************
6250 * NdrClientContextMarshall [RPCRT4.@]
6252 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6253 NDR_CCONTEXT ContextHandle,
6256 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
6258 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
6260 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6262 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6263 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6264 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6267 /* FIXME: what does fCheck do? */
6268 NDRCContextMarshall(ContextHandle,
6271 pStubMsg->Buffer += cbNDRContext;
6274 /***********************************************************************
6275 * NdrClientContextUnmarshall [RPCRT4.@]
6277 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6278 NDR_CCONTEXT * pContextHandle,
6279 RPC_BINDING_HANDLE BindHandle)
6281 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
6283 ALIGN_POINTER(pStubMsg->Buffer, 4);
6285 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
6286 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6288 NDRCContextUnmarshall(pContextHandle,
6291 pStubMsg->RpcMsg->DataRepresentation);
6293 pStubMsg->Buffer += cbNDRContext;
6296 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6297 NDR_SCONTEXT ContextHandle,
6298 NDR_RUNDOWN RundownRoutine )
6300 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
6302 ALIGN_POINTER(pStubMsg->Buffer, 4);
6304 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6306 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6307 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6308 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6311 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6312 pStubMsg->Buffer, RundownRoutine, NULL,
6313 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6314 pStubMsg->Buffer += cbNDRContext;
6317 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6319 NDR_SCONTEXT ContextHandle;
6321 TRACE("(%p)\n", pStubMsg);
6323 ALIGN_POINTER(pStubMsg->Buffer, 4);
6325 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6327 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6328 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6329 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6332 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6334 pStubMsg->RpcMsg->DataRepresentation,
6335 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6336 pStubMsg->Buffer += cbNDRContext;
6338 return ContextHandle;
6341 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6342 unsigned char* pMemory,
6343 PFORMAT_STRING pFormat)
6345 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6348 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6349 PFORMAT_STRING pFormat)
6351 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6352 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6354 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6356 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6357 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6358 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6359 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6360 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6362 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6363 if_id = &sif->InterfaceId;
6366 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
6367 pStubMsg->RpcMsg->DataRepresentation, if_id,
6371 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6372 NDR_SCONTEXT ContextHandle,
6373 NDR_RUNDOWN RundownRoutine,
6374 PFORMAT_STRING pFormat)
6376 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6377 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6379 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6381 ALIGN_POINTER(pStubMsg->Buffer, 4);
6383 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6385 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6386 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6387 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6390 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6391 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6392 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6393 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6394 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6396 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6397 if_id = &sif->InterfaceId;
6400 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6401 pStubMsg->Buffer, RundownRoutine, if_id, flags);
6402 pStubMsg->Buffer += cbNDRContext;
6405 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6406 PFORMAT_STRING pFormat)
6408 NDR_SCONTEXT ContextHandle;
6409 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6410 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6412 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6414 ALIGN_POINTER(pStubMsg->Buffer, 4);
6416 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6418 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6419 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6420 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6423 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6424 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6425 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6426 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6427 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6429 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6430 if_id = &sif->InterfaceId;
6433 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6435 pStubMsg->RpcMsg->DataRepresentation,
6437 pStubMsg->Buffer += cbNDRContext;
6439 return ContextHandle;
6442 /***********************************************************************
6443 * NdrCorrelationInitialize [RPCRT4.@]
6445 * Initializes correlation validity checking.
6448 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6449 * pMemory [I] Pointer to memory to use as a cache.
6450 * CacheSize [I] Size of the memory pointed to by pMemory.
6451 * Flags [I] Reserved. Set to zero.
6456 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
6458 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
6459 pStubMsg->fHasNewCorrDesc = TRUE;
6462 /***********************************************************************
6463 * NdrCorrelationPass [RPCRT4.@]
6465 * Performs correlation validity checking.
6468 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6473 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
6475 FIXME("(%p): stub\n", pStubMsg);
6478 /***********************************************************************
6479 * NdrCorrelationFree [RPCRT4.@]
6481 * Frees any resources used while unmarshalling parameters that need
6482 * correlation validity checking.
6485 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6490 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
6492 FIXME("(%p): stub\n", pStubMsg);