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;
694 * NdrConformantString:
696 * What MS calls a ConformantString is, in DCE terminology,
697 * a Varying-Conformant String.
699 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
700 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
701 * into unmarshalled string)
702 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
704 * data: CHARTYPE[maxlen]
706 * ], where CHARTYPE is the appropriate character type (specified externally)
710 /***********************************************************************
711 * NdrConformantStringMarshall [RPCRT4.@]
713 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
714 unsigned char *pszMessage, PFORMAT_STRING pFormat)
718 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
720 if (*pFormat == RPC_FC_C_CSTRING) {
721 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
722 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
725 else if (*pFormat == RPC_FC_C_WSTRING) {
726 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
727 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
731 ERR("Unhandled string type: %#x\n", *pFormat);
732 /* FIXME: raise an exception. */
736 if (pFormat[1] == RPC_FC_STRING_SIZED)
737 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
739 pStubMsg->MaxCount = pStubMsg->ActualCount;
740 pStubMsg->Offset = 0;
741 WriteConformance(pStubMsg);
742 WriteVariance(pStubMsg);
744 size = safe_multiply(esize, pStubMsg->ActualCount);
745 safe_copy_to_buffer(pStubMsg, pszMessage, size); /* the string itself */
748 return NULL; /* is this always right? */
751 /***********************************************************************
752 * NdrConformantStringBufferSize [RPCRT4.@]
754 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
755 unsigned char* pMemory, PFORMAT_STRING pFormat)
759 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
761 SizeConformance(pStubMsg);
762 SizeVariance(pStubMsg);
764 if (*pFormat == RPC_FC_C_CSTRING) {
765 TRACE("string=%s\n", debugstr_a((char*)pMemory));
766 pStubMsg->ActualCount = strlen((char*)pMemory)+1;
769 else if (*pFormat == RPC_FC_C_WSTRING) {
770 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
771 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;
775 ERR("Unhandled string type: %#x\n", *pFormat);
776 /* FIXME: raise an exception */
780 if (pFormat[1] == RPC_FC_STRING_SIZED)
781 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
783 pStubMsg->MaxCount = pStubMsg->ActualCount;
785 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
788 /************************************************************************
789 * NdrConformantStringMemorySize [RPCRT4.@]
791 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
792 PFORMAT_STRING pFormat )
794 ULONG bufsize, memsize, esize, i;
796 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
798 ReadConformance(pStubMsg, NULL);
799 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
801 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
803 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
804 pStubMsg->ActualCount, pStubMsg->MaxCount);
805 RpcRaiseException(RPC_S_INVALID_BOUND);
807 if (pStubMsg->Offset)
809 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
810 RpcRaiseException(RPC_S_INVALID_BOUND);
813 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
814 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
816 ERR("Unhandled string type: %#x\n", *pFormat);
817 /* FIXME: raise an exception */
821 memsize = safe_multiply(esize, pStubMsg->MaxCount);
822 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
824 /* strings must always have null terminating bytes */
827 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
828 RpcRaiseException(RPC_S_INVALID_BOUND);
831 /* verify the buffer is safe to access */
832 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
833 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
835 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
836 pStubMsg->BufferEnd, pStubMsg->Buffer);
837 RpcRaiseException(RPC_X_BAD_STUB_DATA);
840 for (i = bufsize - esize; i < bufsize; i++)
841 if (pStubMsg->Buffer[i] != 0)
843 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
844 i, pStubMsg->Buffer[i]);
845 RpcRaiseException(RPC_S_INVALID_BOUND);
848 safe_buffer_increment(pStubMsg, bufsize);
849 pStubMsg->MemorySize += memsize;
851 return pStubMsg->MemorySize;
854 /************************************************************************
855 * NdrConformantStringUnmarshall [RPCRT4.@]
857 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
858 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
860 ULONG bufsize, memsize, esize, i;
862 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
863 pStubMsg, *ppMemory, pFormat, fMustAlloc);
865 assert(pFormat && ppMemory && pStubMsg);
867 ReadConformance(pStubMsg, NULL);
868 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
870 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
872 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
873 pStubMsg->ActualCount, pStubMsg->MaxCount);
874 RpcRaiseException(RPC_S_INVALID_BOUND);
877 if (pStubMsg->Offset)
879 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
880 RpcRaiseException(RPC_S_INVALID_BOUND);
884 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
885 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
887 ERR("Unhandled string type: %#x\n", *pFormat);
888 /* FIXME: raise an exception */
892 memsize = safe_multiply(esize, pStubMsg->MaxCount);
893 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
895 /* strings must always have null terminating bytes */
898 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
899 RpcRaiseException(RPC_S_INVALID_BOUND);
903 /* verify the buffer is safe to access */
904 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
905 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
907 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
908 pStubMsg->BufferEnd, pStubMsg->Buffer);
909 RpcRaiseException(RPC_X_BAD_STUB_DATA);
913 for (i = bufsize - esize; i < bufsize; i++)
914 if (pStubMsg->Buffer[i] != 0)
916 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
917 i, pStubMsg->Buffer[i]);
918 RpcRaiseException(RPC_S_INVALID_BOUND);
923 *ppMemory = NdrAllocate(pStubMsg, memsize);
926 if (!pStubMsg->IsClient && !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
927 /* if the data in the RPC buffer is big enough, we just point straight
929 *ppMemory = pStubMsg->Buffer;
931 *ppMemory = NdrAllocate(pStubMsg, memsize);
934 if (*ppMemory == pStubMsg->Buffer)
935 safe_buffer_increment(pStubMsg, bufsize);
937 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
939 if (*pFormat == RPC_FC_C_CSTRING) {
940 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
942 else if (*pFormat == RPC_FC_C_WSTRING) {
943 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
946 return NULL; /* FIXME: is this always right? */
949 /***********************************************************************
950 * NdrNonConformantStringMarshall [RPCRT4.@]
952 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
953 unsigned char *pMemory,
954 PFORMAT_STRING pFormat)
956 ULONG esize, size, maxsize;
958 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
960 maxsize = *(USHORT *)&pFormat[2];
962 if (*pFormat == RPC_FC_CSTRING)
965 const char *str = (const char *)pMemory;
966 for (i = 0; i < maxsize && *str; i++, str++)
968 TRACE("string=%s\n", debugstr_an(str, i));
969 pStubMsg->ActualCount = i + 1;
972 else if (*pFormat == RPC_FC_WSTRING)
975 const WCHAR *str = (const WCHAR *)pMemory;
976 for (i = 0; i < maxsize && *str; i++, str++)
978 TRACE("string=%s\n", debugstr_wn(str, i));
979 pStubMsg->ActualCount = i + 1;
984 ERR("Unhandled string type: %#x\n", *pFormat);
985 RpcRaiseException(RPC_X_BAD_STUB_DATA);
988 pStubMsg->Offset = 0;
989 WriteVariance(pStubMsg);
991 size = safe_multiply(esize, pStubMsg->ActualCount);
992 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
997 /***********************************************************************
998 * NdrNonConformantStringUnmarshall [RPCRT4.@]
1000 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1001 unsigned char **ppMemory,
1002 PFORMAT_STRING pFormat,
1003 unsigned char fMustAlloc)
1005 ULONG bufsize, memsize, esize, i, maxsize;
1007 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
1008 pStubMsg, *ppMemory, pFormat, fMustAlloc);
1010 maxsize = *(USHORT *)&pFormat[2];
1012 ReadVariance(pStubMsg, NULL, maxsize);
1013 if (pStubMsg->Offset)
1015 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
1016 RpcRaiseException(RPC_S_INVALID_BOUND);
1019 if (*pFormat == RPC_FC_CSTRING) esize = 1;
1020 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
1023 ERR("Unhandled string type: %#x\n", *pFormat);
1024 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1027 memsize = esize * maxsize;
1028 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
1030 if (bufsize < esize)
1032 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
1033 RpcRaiseException(RPC_S_INVALID_BOUND);
1037 /* verify the buffer is safe to access */
1038 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
1039 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
1041 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
1042 pStubMsg->BufferEnd, pStubMsg->Buffer);
1043 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1047 /* strings must always have null terminating bytes */
1048 for (i = bufsize - esize; i < bufsize; i++)
1049 if (pStubMsg->Buffer[i] != 0)
1051 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
1052 i, pStubMsg->Buffer[i]);
1053 RpcRaiseException(RPC_S_INVALID_BOUND);
1056 if (fMustAlloc || !*ppMemory)
1057 *ppMemory = NdrAllocate(pStubMsg, memsize);
1059 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
1061 if (*pFormat == RPC_FC_CSTRING) {
1062 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
1064 else if (*pFormat == RPC_FC_WSTRING) {
1065 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
1071 /***********************************************************************
1072 * NdrNonConformantStringBufferSize [RPCRT4.@]
1074 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1075 unsigned char *pMemory,
1076 PFORMAT_STRING pFormat)
1078 ULONG esize, maxsize;
1080 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
1082 maxsize = *(USHORT *)&pFormat[2];
1084 SizeVariance(pStubMsg);
1086 if (*pFormat == RPC_FC_CSTRING)
1089 const char *str = (const char *)pMemory;
1090 for (i = 0; i < maxsize && *str; i++, str++)
1092 TRACE("string=%s\n", debugstr_an(str, i));
1093 pStubMsg->ActualCount = i + 1;
1096 else if (*pFormat == RPC_FC_WSTRING)
1099 const WCHAR *str = (const WCHAR *)pMemory;
1100 for (i = 0; i < maxsize && *str; i++, str++)
1102 TRACE("string=%s\n", debugstr_wn(str, i));
1103 pStubMsg->ActualCount = i + 1;
1108 ERR("Unhandled string type: %#x\n", *pFormat);
1109 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1112 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
1115 /***********************************************************************
1116 * NdrNonConformantStringMemorySize [RPCRT4.@]
1118 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1119 PFORMAT_STRING pFormat)
1121 ULONG bufsize, memsize, esize, i, maxsize;
1123 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
1125 maxsize = *(USHORT *)&pFormat[2];
1127 ReadVariance(pStubMsg, NULL, maxsize);
1129 if (pStubMsg->Offset)
1131 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
1132 RpcRaiseException(RPC_S_INVALID_BOUND);
1135 if (*pFormat == RPC_FC_CSTRING) esize = 1;
1136 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
1139 ERR("Unhandled string type: %#x\n", *pFormat);
1140 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1143 memsize = esize * maxsize;
1144 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
1146 /* strings must always have null terminating bytes */
1147 if (bufsize < esize)
1149 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
1150 RpcRaiseException(RPC_S_INVALID_BOUND);
1153 /* verify the buffer is safe to access */
1154 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
1155 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
1157 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
1158 pStubMsg->BufferEnd, pStubMsg->Buffer);
1159 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1162 for (i = bufsize - esize; i < bufsize; i++)
1163 if (pStubMsg->Buffer[i] != 0)
1165 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
1166 i, pStubMsg->Buffer[i]);
1167 RpcRaiseException(RPC_S_INVALID_BOUND);
1170 safe_buffer_increment(pStubMsg, bufsize);
1171 pStubMsg->MemorySize += memsize;
1173 return pStubMsg->MemorySize;
1176 static inline void dump_pointer_attr(unsigned char attr)
1178 if (attr & RPC_FC_P_ALLOCALLNODES)
1179 TRACE(" RPC_FC_P_ALLOCALLNODES");
1180 if (attr & RPC_FC_P_DONTFREE)
1181 TRACE(" RPC_FC_P_DONTFREE");
1182 if (attr & RPC_FC_P_ONSTACK)
1183 TRACE(" RPC_FC_P_ONSTACK");
1184 if (attr & RPC_FC_P_SIMPLEPOINTER)
1185 TRACE(" RPC_FC_P_SIMPLEPOINTER");
1186 if (attr & RPC_FC_P_DEREF)
1187 TRACE(" RPC_FC_P_DEREF");
1191 /***********************************************************************
1192 * PointerMarshall [internal]
1194 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1195 unsigned char *Buffer,
1196 unsigned char *Pointer,
1197 PFORMAT_STRING pFormat)
1199 unsigned type = pFormat[0], attr = pFormat[1];
1200 PFORMAT_STRING desc;
1203 int pointer_needs_marshaling;
1205 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
1206 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1208 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1209 else desc = pFormat + *(const SHORT*)pFormat;
1212 case RPC_FC_RP: /* ref pointer (always non-null) */
1215 ERR("NULL ref pointer is not allowed\n");
1216 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1218 pointer_needs_marshaling = 1;
1220 case RPC_FC_UP: /* unique pointer */
1221 case RPC_FC_OP: /* object pointer - same as unique here */
1223 pointer_needs_marshaling = 1;
1225 pointer_needs_marshaling = 0;
1226 pointer_id = Pointer ? NDR_POINTER_ID(pStubMsg) : 0;
1227 TRACE("writing 0x%08x to buffer\n", pointer_id);
1228 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
1231 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
1232 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
1233 TRACE("writing 0x%08x to buffer\n", pointer_id);
1234 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
1237 FIXME("unhandled ptr type=%02x\n", type);
1238 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1242 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
1244 if (pointer_needs_marshaling) {
1245 if (attr & RPC_FC_P_DEREF) {
1246 Pointer = *(unsigned char**)Pointer;
1247 TRACE("deref => %p\n", Pointer);
1249 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1250 if (m) m(pStubMsg, Pointer, desc);
1251 else FIXME("no marshaller for data type=%02x\n", *desc);
1254 STD_OVERFLOW_CHECK(pStubMsg);
1257 /***********************************************************************
1258 * PointerUnmarshall [internal]
1260 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1261 unsigned char *Buffer,
1262 unsigned char **pPointer,
1263 unsigned char *pSrcPointer,
1264 PFORMAT_STRING pFormat,
1265 unsigned char fMustAlloc)
1267 unsigned type = pFormat[0], attr = pFormat[1];
1268 PFORMAT_STRING desc;
1270 DWORD pointer_id = 0;
1271 int pointer_needs_unmarshaling;
1273 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
1274 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1276 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1277 else desc = pFormat + *(const SHORT*)pFormat;
1280 case RPC_FC_RP: /* ref pointer (always non-null) */
1281 pointer_needs_unmarshaling = 1;
1283 case RPC_FC_UP: /* unique pointer */
1284 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1285 TRACE("pointer_id is 0x%08x\n", pointer_id);
1287 pointer_needs_unmarshaling = 1;
1290 pointer_needs_unmarshaling = 0;
1293 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1294 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1295 TRACE("pointer_id is 0x%08x\n", pointer_id);
1296 if (!fMustAlloc && pSrcPointer)
1298 FIXME("free object pointer %p\n", pSrcPointer);
1302 pointer_needs_unmarshaling = 1;
1304 pointer_needs_unmarshaling = 0;
1307 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1308 TRACE("pointer_id is 0x%08x\n", pointer_id);
1309 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
1310 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
1313 FIXME("unhandled ptr type=%02x\n", type);
1314 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1318 if (pointer_needs_unmarshaling) {
1319 unsigned char *base_ptr_val = *pPointer;
1320 unsigned char **current_ptr = pPointer;
1321 if (pStubMsg->IsClient) {
1323 /* if we aren't forcing allocation of memory then try to use the existing
1324 * (source) pointer to unmarshall the data into so that [in,out]
1325 * parameters behave correctly. it doesn't matter if the parameter is
1326 * [out] only since in that case the pointer will be NULL. we force
1327 * allocation when the source pointer is NULL here instead of in the type
1328 * unmarshalling routine for the benefit of the deref code below */
1331 TRACE("setting *pPointer to %p\n", pSrcPointer);
1332 *pPointer = base_ptr_val = pSrcPointer;
1338 /* the memory in a stub is never initialised, so we have to work out here
1339 * whether we have to initialise it so we can use the optimisation of
1340 * setting the pointer to the buffer, if possible, or set fMustAlloc to
1342 if (attr & RPC_FC_P_DEREF) {
1345 base_ptr_val = NULL;
1346 *current_ptr = NULL;
1350 if (attr & RPC_FC_P_ALLOCALLNODES)
1351 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
1353 if (attr & RPC_FC_P_DEREF) {
1355 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
1356 *pPointer = base_ptr_val;
1357 current_ptr = (unsigned char **)base_ptr_val;
1359 current_ptr = *(unsigned char***)current_ptr;
1360 TRACE("deref => %p\n", current_ptr);
1361 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
1363 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1364 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
1365 else FIXME("no unmarshaller for data type=%02x\n", *desc);
1367 if (type == RPC_FC_FP)
1368 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
1372 TRACE("pointer=%p\n", *pPointer);
1375 /***********************************************************************
1376 * PointerBufferSize [internal]
1378 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1379 unsigned char *Pointer,
1380 PFORMAT_STRING pFormat)
1382 unsigned type = pFormat[0], attr = pFormat[1];
1383 PFORMAT_STRING desc;
1385 int pointer_needs_sizing;
1388 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1389 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1391 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1392 else desc = pFormat + *(const SHORT*)pFormat;
1395 case RPC_FC_RP: /* ref pointer (always non-null) */
1398 ERR("NULL ref pointer is not allowed\n");
1399 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1404 /* NULL pointer has no further representation */
1409 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1410 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1411 if (!pointer_needs_sizing)
1415 FIXME("unhandled ptr type=%02x\n", type);
1416 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1420 if (attr & RPC_FC_P_DEREF) {
1421 Pointer = *(unsigned char**)Pointer;
1422 TRACE("deref => %p\n", Pointer);
1425 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1426 if (m) m(pStubMsg, Pointer, desc);
1427 else FIXME("no buffersizer for data type=%02x\n", *desc);
1430 /***********************************************************************
1431 * PointerMemorySize [internal]
1433 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1434 unsigned char *Buffer,
1435 PFORMAT_STRING pFormat)
1437 unsigned type = pFormat[0], attr = pFormat[1];
1438 PFORMAT_STRING desc;
1440 DWORD pointer_id = 0;
1441 int pointer_needs_sizing;
1443 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1444 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1446 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1447 else desc = pFormat + *(const SHORT*)pFormat;
1450 case RPC_FC_RP: /* ref pointer (always non-null) */
1451 pointer_needs_sizing = 1;
1453 case RPC_FC_UP: /* unique pointer */
1454 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1455 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1456 TRACE("pointer_id is 0x%08x\n", pointer_id);
1458 pointer_needs_sizing = 1;
1460 pointer_needs_sizing = 0;
1465 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1466 TRACE("pointer_id is 0x%08x\n", pointer_id);
1467 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1468 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1472 FIXME("unhandled ptr type=%02x\n", type);
1473 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1477 if (attr & RPC_FC_P_DEREF) {
1481 if (pointer_needs_sizing) {
1482 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1483 if (m) m(pStubMsg, desc);
1484 else FIXME("no memorysizer for data type=%02x\n", *desc);
1487 return pStubMsg->MemorySize;
1490 /***********************************************************************
1491 * PointerFree [internal]
1493 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1494 unsigned char *Pointer,
1495 PFORMAT_STRING pFormat)
1497 unsigned type = pFormat[0], attr = pFormat[1];
1498 PFORMAT_STRING desc;
1500 unsigned char *current_pointer = Pointer;
1502 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1503 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1504 if (attr & RPC_FC_P_DONTFREE) return;
1506 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1507 else desc = pFormat + *(const SHORT*)pFormat;
1509 if (!Pointer) return;
1511 if (type == RPC_FC_FP) {
1512 int pointer_needs_freeing = NdrFullPointerFree(
1513 pStubMsg->FullPtrXlatTables, Pointer);
1514 if (!pointer_needs_freeing)
1518 if (attr & RPC_FC_P_DEREF) {
1519 current_pointer = *(unsigned char**)Pointer;
1520 TRACE("deref => %p\n", current_pointer);
1523 m = NdrFreer[*desc & NDR_TABLE_MASK];
1524 if (m) m(pStubMsg, current_pointer, desc);
1526 /* this check stops us from trying to free buffer memory. we don't have to
1527 * worry about clients, since they won't call this function.
1528 * we don't have to check for the buffer being reallocated because
1529 * BufferStart and BufferEnd won't be reset when allocating memory for
1530 * sending the response. we don't have to check for the new buffer here as
1531 * it won't be used a type memory, only for buffer memory */
1532 if (Pointer >= pStubMsg->BufferStart && Pointer < pStubMsg->BufferEnd)
1535 if (attr & RPC_FC_P_ONSTACK) {
1536 TRACE("not freeing stack ptr %p\n", Pointer);
1539 TRACE("freeing %p\n", Pointer);
1540 NdrFree(pStubMsg, Pointer);
1543 TRACE("not freeing %p\n", Pointer);
1546 /***********************************************************************
1547 * EmbeddedPointerMarshall
1549 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1550 unsigned char *pMemory,
1551 PFORMAT_STRING pFormat)
1553 unsigned char *Mark = pStubMsg->BufferMark;
1554 unsigned rep, count, stride;
1556 unsigned char *saved_buffer = NULL;
1558 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1560 if (*pFormat != RPC_FC_PP) return NULL;
1563 if (pStubMsg->PointerBufferMark)
1565 saved_buffer = pStubMsg->Buffer;
1566 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1567 pStubMsg->PointerBufferMark = NULL;
1570 while (pFormat[0] != RPC_FC_END) {
1571 switch (pFormat[0]) {
1573 FIXME("unknown repeat type %d\n", pFormat[0]);
1574 case RPC_FC_NO_REPEAT:
1580 case RPC_FC_FIXED_REPEAT:
1581 rep = *(const WORD*)&pFormat[2];
1582 stride = *(const WORD*)&pFormat[4];
1583 count = *(const WORD*)&pFormat[8];
1586 case RPC_FC_VARIABLE_REPEAT:
1587 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1588 stride = *(const WORD*)&pFormat[2];
1589 count = *(const WORD*)&pFormat[6];
1593 for (i = 0; i < rep; i++) {
1594 PFORMAT_STRING info = pFormat;
1595 unsigned char *membase = pMemory + (i * stride);
1596 unsigned char *bufbase = Mark + (i * stride);
1599 for (u=0; u<count; u++,info+=8) {
1600 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1601 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1602 unsigned char *saved_memory = pStubMsg->Memory;
1604 pStubMsg->Memory = pMemory;
1605 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1606 pStubMsg->Memory = saved_memory;
1609 pFormat += 8 * count;
1614 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1615 pStubMsg->Buffer = saved_buffer;
1618 STD_OVERFLOW_CHECK(pStubMsg);
1623 /***********************************************************************
1624 * EmbeddedPointerUnmarshall
1626 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1627 unsigned char *pDstMemoryPtrs,
1628 unsigned char *pSrcMemoryPtrs,
1629 PFORMAT_STRING pFormat,
1630 unsigned char fMustAlloc)
1632 unsigned char *Mark = pStubMsg->BufferMark;
1633 unsigned rep, count, stride;
1635 unsigned char *saved_buffer = NULL;
1637 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstMemoryPtrs, pSrcMemoryPtrs, pFormat, fMustAlloc);
1639 if (*pFormat != RPC_FC_PP) return NULL;
1642 if (pStubMsg->PointerBufferMark)
1644 saved_buffer = pStubMsg->Buffer;
1645 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1646 pStubMsg->PointerBufferMark = NULL;
1649 while (pFormat[0] != RPC_FC_END) {
1650 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1651 switch (pFormat[0]) {
1653 FIXME("unknown repeat type %d\n", pFormat[0]);
1654 case RPC_FC_NO_REPEAT:
1660 case RPC_FC_FIXED_REPEAT:
1661 rep = *(const WORD*)&pFormat[2];
1662 stride = *(const WORD*)&pFormat[4];
1663 count = *(const WORD*)&pFormat[8];
1666 case RPC_FC_VARIABLE_REPEAT:
1667 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1668 stride = *(const WORD*)&pFormat[2];
1669 count = *(const WORD*)&pFormat[6];
1673 for (i = 0; i < rep; i++) {
1674 PFORMAT_STRING info = pFormat;
1675 unsigned char *memdstbase = pDstMemoryPtrs + (i * stride);
1676 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1677 unsigned char *bufbase = Mark + (i * stride);
1680 for (u=0; u<count; u++,info+=8) {
1681 unsigned char **memdstptr = (unsigned char **)(memdstbase + *(const SHORT*)&info[0]);
1682 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1683 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1684 PointerUnmarshall(pStubMsg, bufptr, memdstptr, *memsrcptr, info+4, fMustAlloc);
1687 pFormat += 8 * count;
1692 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1693 pStubMsg->Buffer = saved_buffer;
1699 /***********************************************************************
1700 * EmbeddedPointerBufferSize
1702 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1703 unsigned char *pMemory,
1704 PFORMAT_STRING pFormat)
1706 unsigned rep, count, stride;
1708 ULONG saved_buffer_length = 0;
1710 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1712 if (pStubMsg->IgnoreEmbeddedPointers) return;
1714 if (*pFormat != RPC_FC_PP) return;
1717 if (pStubMsg->PointerLength)
1719 saved_buffer_length = pStubMsg->BufferLength;
1720 pStubMsg->BufferLength = pStubMsg->PointerLength;
1721 pStubMsg->PointerLength = 0;
1724 while (pFormat[0] != RPC_FC_END) {
1725 switch (pFormat[0]) {
1727 FIXME("unknown repeat type %d\n", pFormat[0]);
1728 case RPC_FC_NO_REPEAT:
1734 case RPC_FC_FIXED_REPEAT:
1735 rep = *(const WORD*)&pFormat[2];
1736 stride = *(const WORD*)&pFormat[4];
1737 count = *(const WORD*)&pFormat[8];
1740 case RPC_FC_VARIABLE_REPEAT:
1741 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1742 stride = *(const WORD*)&pFormat[2];
1743 count = *(const WORD*)&pFormat[6];
1747 for (i = 0; i < rep; i++) {
1748 PFORMAT_STRING info = pFormat;
1749 unsigned char *membase = pMemory + (i * stride);
1752 for (u=0; u<count; u++,info+=8) {
1753 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1754 unsigned char *saved_memory = pStubMsg->Memory;
1756 pStubMsg->Memory = pMemory;
1757 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1758 pStubMsg->Memory = saved_memory;
1761 pFormat += 8 * count;
1764 if (saved_buffer_length)
1766 pStubMsg->PointerLength = pStubMsg->BufferLength;
1767 pStubMsg->BufferLength = saved_buffer_length;
1771 /***********************************************************************
1772 * EmbeddedPointerMemorySize [internal]
1774 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1775 PFORMAT_STRING pFormat)
1777 unsigned char *Mark = pStubMsg->BufferMark;
1778 unsigned rep, count, stride;
1780 unsigned char *saved_buffer = NULL;
1782 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1784 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1786 if (pStubMsg->PointerBufferMark)
1788 saved_buffer = pStubMsg->Buffer;
1789 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1790 pStubMsg->PointerBufferMark = NULL;
1793 if (*pFormat != RPC_FC_PP) return 0;
1796 while (pFormat[0] != RPC_FC_END) {
1797 switch (pFormat[0]) {
1799 FIXME("unknown repeat type %d\n", pFormat[0]);
1800 case RPC_FC_NO_REPEAT:
1806 case RPC_FC_FIXED_REPEAT:
1807 rep = *(const WORD*)&pFormat[2];
1808 stride = *(const WORD*)&pFormat[4];
1809 count = *(const WORD*)&pFormat[8];
1812 case RPC_FC_VARIABLE_REPEAT:
1813 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1814 stride = *(const WORD*)&pFormat[2];
1815 count = *(const WORD*)&pFormat[6];
1819 for (i = 0; i < rep; i++) {
1820 PFORMAT_STRING info = pFormat;
1821 unsigned char *bufbase = Mark + (i * stride);
1823 for (u=0; u<count; u++,info+=8) {
1824 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1825 PointerMemorySize(pStubMsg, bufptr, info+4);
1828 pFormat += 8 * count;
1833 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1834 pStubMsg->Buffer = saved_buffer;
1840 /***********************************************************************
1841 * EmbeddedPointerFree [internal]
1843 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1844 unsigned char *pMemory,
1845 PFORMAT_STRING pFormat)
1847 unsigned rep, count, stride;
1850 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1851 if (*pFormat != RPC_FC_PP) return;
1854 while (pFormat[0] != RPC_FC_END) {
1855 switch (pFormat[0]) {
1857 FIXME("unknown repeat type %d\n", pFormat[0]);
1858 case RPC_FC_NO_REPEAT:
1864 case RPC_FC_FIXED_REPEAT:
1865 rep = *(const WORD*)&pFormat[2];
1866 stride = *(const WORD*)&pFormat[4];
1867 count = *(const WORD*)&pFormat[8];
1870 case RPC_FC_VARIABLE_REPEAT:
1871 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1872 stride = *(const WORD*)&pFormat[2];
1873 count = *(const WORD*)&pFormat[6];
1877 for (i = 0; i < rep; i++) {
1878 PFORMAT_STRING info = pFormat;
1879 unsigned char *membase = pMemory + (i * stride);
1882 for (u=0; u<count; u++,info+=8) {
1883 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1884 unsigned char *saved_memory = pStubMsg->Memory;
1886 pStubMsg->Memory = pMemory;
1887 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1888 pStubMsg->Memory = saved_memory;
1891 pFormat += 8 * count;
1895 /***********************************************************************
1896 * NdrPointerMarshall [RPCRT4.@]
1898 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1899 unsigned char *pMemory,
1900 PFORMAT_STRING pFormat)
1902 unsigned char *Buffer;
1904 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1906 /* Increment the buffer here instead of in PointerMarshall,
1907 * as that is used by embedded pointers which already handle the incrementing
1908 * the buffer, and shouldn't write any additional pointer data to the wire */
1909 if (*pFormat != RPC_FC_RP)
1911 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
1912 Buffer = pStubMsg->Buffer;
1913 safe_buffer_increment(pStubMsg, 4);
1916 Buffer = pStubMsg->Buffer;
1918 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1923 /***********************************************************************
1924 * NdrPointerUnmarshall [RPCRT4.@]
1926 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1927 unsigned char **ppMemory,
1928 PFORMAT_STRING pFormat,
1929 unsigned char fMustAlloc)
1931 unsigned char *Buffer;
1933 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1935 /* Increment the buffer here instead of in PointerUnmarshall,
1936 * as that is used by embedded pointers which already handle the incrementing
1937 * the buffer, and shouldn't read any additional pointer data from the
1939 if (*pFormat != RPC_FC_RP)
1941 ALIGN_POINTER(pStubMsg->Buffer, 4);
1942 Buffer = pStubMsg->Buffer;
1943 safe_buffer_increment(pStubMsg, 4);
1946 Buffer = pStubMsg->Buffer;
1948 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1953 /***********************************************************************
1954 * NdrPointerBufferSize [RPCRT4.@]
1956 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1957 unsigned char *pMemory,
1958 PFORMAT_STRING pFormat)
1960 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1962 /* Increment the buffer length here instead of in PointerBufferSize,
1963 * as that is used by embedded pointers which already handle the buffer
1964 * length, and shouldn't write anything more to the wire */
1965 if (*pFormat != RPC_FC_RP)
1967 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1968 safe_buffer_length_increment(pStubMsg, 4);
1971 PointerBufferSize(pStubMsg, pMemory, pFormat);
1974 /***********************************************************************
1975 * NdrPointerMemorySize [RPCRT4.@]
1977 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1978 PFORMAT_STRING pFormat)
1980 /* unsigned size = *(LPWORD)(pFormat+2); */
1981 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1982 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1986 /***********************************************************************
1987 * NdrPointerFree [RPCRT4.@]
1989 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1990 unsigned char *pMemory,
1991 PFORMAT_STRING pFormat)
1993 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1994 PointerFree(pStubMsg, pMemory, pFormat);
1997 /***********************************************************************
1998 * NdrSimpleTypeMarshall [RPCRT4.@]
2000 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
2001 unsigned char FormatChar )
2003 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
2006 /***********************************************************************
2007 * NdrSimpleTypeUnmarshall [RPCRT4.@]
2009 * Unmarshall a base type.
2012 * Doesn't check that the buffer is long enough before copying, so the caller
2015 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
2016 unsigned char FormatChar )
2018 #define BASE_TYPE_UNMARSHALL(type) \
2019 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
2020 TRACE("pMemory: %p\n", pMemory); \
2021 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
2022 pStubMsg->Buffer += sizeof(type);
2030 BASE_TYPE_UNMARSHALL(UCHAR);
2031 TRACE("value: 0x%02x\n", *pMemory);
2036 BASE_TYPE_UNMARSHALL(USHORT);
2037 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
2041 case RPC_FC_ERROR_STATUS_T:
2043 BASE_TYPE_UNMARSHALL(ULONG);
2044 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
2047 BASE_TYPE_UNMARSHALL(float);
2048 TRACE("value: %f\n", *(float *)pMemory);
2051 BASE_TYPE_UNMARSHALL(double);
2052 TRACE("value: %f\n", *(double *)pMemory);
2055 BASE_TYPE_UNMARSHALL(ULONGLONG);
2056 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
2059 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
2060 TRACE("pMemory: %p\n", pMemory);
2061 /* 16-bits on the wire, but int in memory */
2062 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
2063 pStubMsg->Buffer += sizeof(USHORT);
2064 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
2069 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
2071 #undef BASE_TYPE_UNMARSHALL
2074 /***********************************************************************
2075 * NdrSimpleStructMarshall [RPCRT4.@]
2077 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2078 unsigned char *pMemory,
2079 PFORMAT_STRING pFormat)
2081 unsigned size = *(const WORD*)(pFormat+2);
2082 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2084 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
2086 pStubMsg->BufferMark = pStubMsg->Buffer;
2087 safe_copy_to_buffer(pStubMsg, pMemory, size);
2089 if (pFormat[0] != RPC_FC_STRUCT)
2090 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
2095 /***********************************************************************
2096 * NdrSimpleStructUnmarshall [RPCRT4.@]
2098 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2099 unsigned char **ppMemory,
2100 PFORMAT_STRING pFormat,
2101 unsigned char fMustAlloc)
2103 unsigned size = *(const WORD*)(pFormat+2);
2104 unsigned char *saved_buffer;
2105 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2107 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2110 *ppMemory = NdrAllocate(pStubMsg, size);
2113 if (!pStubMsg->IsClient && !*ppMemory)
2114 /* for servers, we just point straight into the RPC buffer */
2115 *ppMemory = pStubMsg->Buffer;
2118 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
2119 safe_buffer_increment(pStubMsg, size);
2120 if (pFormat[0] == RPC_FC_PSTRUCT)
2121 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
2123 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2124 if (*ppMemory != saved_buffer)
2125 memcpy(*ppMemory, saved_buffer, size);
2130 /***********************************************************************
2131 * NdrSimpleStructBufferSize [RPCRT4.@]
2133 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2134 unsigned char *pMemory,
2135 PFORMAT_STRING pFormat)
2137 unsigned size = *(const WORD*)(pFormat+2);
2138 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2140 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2142 safe_buffer_length_increment(pStubMsg, size);
2143 if (pFormat[0] != RPC_FC_STRUCT)
2144 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
2147 /***********************************************************************
2148 * NdrSimpleStructMemorySize [RPCRT4.@]
2150 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2151 PFORMAT_STRING pFormat)
2153 unsigned short size = *(const WORD *)(pFormat+2);
2155 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2157 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2158 pStubMsg->MemorySize += size;
2159 safe_buffer_increment(pStubMsg, size);
2161 if (pFormat[0] != RPC_FC_STRUCT)
2162 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
2163 return pStubMsg->MemorySize;
2166 /***********************************************************************
2167 * NdrSimpleStructFree [RPCRT4.@]
2169 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2170 unsigned char *pMemory,
2171 PFORMAT_STRING pFormat)
2173 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2174 if (pFormat[0] != RPC_FC_STRUCT)
2175 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
2179 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE *pStubMsg,
2180 PFORMAT_STRING pFormat)
2184 case RPC_FC_PSTRUCT:
2185 case RPC_FC_CSTRUCT:
2186 case RPC_FC_BOGUS_STRUCT:
2187 case RPC_FC_SMFARRAY:
2188 case RPC_FC_SMVARRAY:
2189 case RPC_FC_CSTRING:
2190 return *(const WORD*)&pFormat[2];
2191 case RPC_FC_USER_MARSHAL:
2192 return *(const WORD*)&pFormat[4];
2193 case RPC_FC_NON_ENCAPSULATED_UNION:
2195 if (pStubMsg->fHasNewCorrDesc)
2200 pFormat += *(const SHORT*)pFormat;
2201 return *(const SHORT*)pFormat;
2203 return sizeof(void *);
2204 case RPC_FC_WSTRING:
2205 return *(const WORD*)&pFormat[2] * 2;
2207 FIXME("unhandled embedded type %02x\n", *pFormat);
2213 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2214 PFORMAT_STRING pFormat)
2216 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2220 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2224 return m(pStubMsg, pFormat);
2228 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2229 unsigned char *pMemory,
2230 PFORMAT_STRING pFormat,
2231 PFORMAT_STRING pPointer)
2233 PFORMAT_STRING desc;
2237 while (*pFormat != RPC_FC_END) {
2243 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2244 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2250 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2251 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2255 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2256 if (32767 < *(DWORD*)pMemory)
2257 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2258 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2264 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2265 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2269 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2270 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2273 case RPC_FC_POINTER:
2275 unsigned char *saved_buffer;
2276 int pointer_buffer_mark_set = 0;
2277 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2278 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
2279 saved_buffer = pStubMsg->Buffer;
2280 if (pStubMsg->PointerBufferMark)
2282 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2283 pStubMsg->PointerBufferMark = NULL;
2284 pointer_buffer_mark_set = 1;
2287 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2288 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2289 if (pointer_buffer_mark_set)
2291 STD_OVERFLOW_CHECK(pStubMsg);
2292 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2293 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2295 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2296 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2297 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2299 pStubMsg->Buffer = saved_buffer + 4;
2305 case RPC_FC_ALIGNM4:
2306 ALIGN_POINTER(pMemory, 4);
2308 case RPC_FC_ALIGNM8:
2309 ALIGN_POINTER(pMemory, 8);
2311 case RPC_FC_STRUCTPAD1:
2312 case RPC_FC_STRUCTPAD2:
2313 case RPC_FC_STRUCTPAD3:
2314 case RPC_FC_STRUCTPAD4:
2315 case RPC_FC_STRUCTPAD5:
2316 case RPC_FC_STRUCTPAD6:
2317 case RPC_FC_STRUCTPAD7:
2318 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2320 case RPC_FC_EMBEDDED_COMPLEX:
2321 pMemory += pFormat[1];
2323 desc = pFormat + *(const SHORT*)pFormat;
2324 size = EmbeddedComplexSize(pStubMsg, desc);
2325 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
2326 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2329 /* for some reason interface pointers aren't generated as
2330 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2331 * they still need the derefencing treatment that pointers are
2333 if (*desc == RPC_FC_IP)
2334 m(pStubMsg, *(unsigned char **)pMemory, desc);
2336 m(pStubMsg, pMemory, desc);
2338 else FIXME("no marshaller for embedded type %02x\n", *desc);
2345 FIXME("unhandled format 0x%02x\n", *pFormat);
2353 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2354 unsigned char *pMemory,
2355 PFORMAT_STRING pFormat,
2356 PFORMAT_STRING pPointer)
2358 PFORMAT_STRING desc;
2362 while (*pFormat != RPC_FC_END) {
2368 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2369 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2375 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2376 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2380 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2381 *(DWORD*)pMemory &= 0xffff;
2382 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
2383 if (32767 < *(DWORD*)pMemory)
2384 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2390 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2391 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2395 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2396 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2399 case RPC_FC_POINTER:
2401 unsigned char *saved_buffer;
2402 int pointer_buffer_mark_set = 0;
2403 TRACE("pointer => %p\n", pMemory);
2404 ALIGN_POINTER(pStubMsg->Buffer, 4);
2405 saved_buffer = pStubMsg->Buffer;
2406 if (pStubMsg->PointerBufferMark)
2408 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2409 pStubMsg->PointerBufferMark = NULL;
2410 pointer_buffer_mark_set = 1;
2413 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2415 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, TRUE);
2416 if (pointer_buffer_mark_set)
2418 STD_OVERFLOW_CHECK(pStubMsg);
2419 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2420 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2422 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2423 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2424 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2426 pStubMsg->Buffer = saved_buffer + 4;
2432 case RPC_FC_ALIGNM4:
2433 ALIGN_POINTER_CLEAR(pMemory, 4);
2435 case RPC_FC_ALIGNM8:
2436 ALIGN_POINTER_CLEAR(pMemory, 8);
2438 case RPC_FC_STRUCTPAD1:
2439 case RPC_FC_STRUCTPAD2:
2440 case RPC_FC_STRUCTPAD3:
2441 case RPC_FC_STRUCTPAD4:
2442 case RPC_FC_STRUCTPAD5:
2443 case RPC_FC_STRUCTPAD6:
2444 case RPC_FC_STRUCTPAD7:
2445 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2446 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2448 case RPC_FC_EMBEDDED_COMPLEX:
2449 pMemory += pFormat[1];
2451 desc = pFormat + *(const SHORT*)pFormat;
2452 size = EmbeddedComplexSize(pStubMsg, desc);
2453 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2454 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2455 memset(pMemory, 0, size); /* just in case */
2458 /* for some reason interface pointers aren't generated as
2459 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2460 * they still need the derefencing treatment that pointers are
2462 if (*desc == RPC_FC_IP)
2463 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2465 m(pStubMsg, &pMemory, desc, FALSE);
2467 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2474 FIXME("unhandled format %d\n", *pFormat);
2482 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2483 unsigned char *pMemory,
2484 PFORMAT_STRING pFormat,
2485 PFORMAT_STRING pPointer)
2487 PFORMAT_STRING desc;
2491 while (*pFormat != RPC_FC_END) {
2497 safe_buffer_length_increment(pStubMsg, 1);
2503 safe_buffer_length_increment(pStubMsg, 2);
2507 safe_buffer_length_increment(pStubMsg, 2);
2513 safe_buffer_length_increment(pStubMsg, 4);
2517 safe_buffer_length_increment(pStubMsg, 8);
2520 case RPC_FC_POINTER:
2521 if (!pStubMsg->IgnoreEmbeddedPointers)
2523 int saved_buffer_length = pStubMsg->BufferLength;
2524 pStubMsg->BufferLength = pStubMsg->PointerLength;
2525 pStubMsg->PointerLength = 0;
2526 if(!pStubMsg->BufferLength)
2527 ERR("BufferLength == 0??\n");
2528 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2529 pStubMsg->PointerLength = pStubMsg->BufferLength;
2530 pStubMsg->BufferLength = saved_buffer_length;
2532 safe_buffer_length_increment(pStubMsg, 4);
2536 case RPC_FC_ALIGNM4:
2537 ALIGN_POINTER(pMemory, 4);
2539 case RPC_FC_ALIGNM8:
2540 ALIGN_POINTER(pMemory, 8);
2542 case RPC_FC_STRUCTPAD1:
2543 case RPC_FC_STRUCTPAD2:
2544 case RPC_FC_STRUCTPAD3:
2545 case RPC_FC_STRUCTPAD4:
2546 case RPC_FC_STRUCTPAD5:
2547 case RPC_FC_STRUCTPAD6:
2548 case RPC_FC_STRUCTPAD7:
2549 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2551 case RPC_FC_EMBEDDED_COMPLEX:
2552 pMemory += pFormat[1];
2554 desc = pFormat + *(const SHORT*)pFormat;
2555 size = EmbeddedComplexSize(pStubMsg, desc);
2556 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2559 /* for some reason interface pointers aren't generated as
2560 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2561 * they still need the derefencing treatment that pointers are
2563 if (*desc == RPC_FC_IP)
2564 m(pStubMsg, *(unsigned char **)pMemory, desc);
2566 m(pStubMsg, pMemory, desc);
2568 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2575 FIXME("unhandled format 0x%02x\n", *pFormat);
2583 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2584 unsigned char *pMemory,
2585 PFORMAT_STRING pFormat,
2586 PFORMAT_STRING pPointer)
2588 PFORMAT_STRING desc;
2592 while (*pFormat != RPC_FC_END) {
2614 case RPC_FC_POINTER:
2615 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
2619 case RPC_FC_ALIGNM4:
2620 ALIGN_POINTER(pMemory, 4);
2622 case RPC_FC_ALIGNM8:
2623 ALIGN_POINTER(pMemory, 8);
2625 case RPC_FC_STRUCTPAD1:
2626 case RPC_FC_STRUCTPAD2:
2627 case RPC_FC_STRUCTPAD3:
2628 case RPC_FC_STRUCTPAD4:
2629 case RPC_FC_STRUCTPAD5:
2630 case RPC_FC_STRUCTPAD6:
2631 case RPC_FC_STRUCTPAD7:
2632 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2634 case RPC_FC_EMBEDDED_COMPLEX:
2635 pMemory += pFormat[1];
2637 desc = pFormat + *(const SHORT*)pFormat;
2638 size = EmbeddedComplexSize(pStubMsg, desc);
2639 m = NdrFreer[*desc & NDR_TABLE_MASK];
2642 /* for some reason interface pointers aren't generated as
2643 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2644 * they still need the derefencing treatment that pointers are
2646 if (*desc == RPC_FC_IP)
2647 m(pStubMsg, *(unsigned char **)pMemory, desc);
2649 m(pStubMsg, pMemory, desc);
2657 FIXME("unhandled format 0x%02x\n", *pFormat);
2665 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2666 PFORMAT_STRING pFormat)
2668 PFORMAT_STRING desc;
2669 unsigned long size = 0;
2671 while (*pFormat != RPC_FC_END) {
2678 safe_buffer_increment(pStubMsg, 1);
2684 safe_buffer_increment(pStubMsg, 2);
2688 safe_buffer_increment(pStubMsg, 2);
2694 safe_buffer_increment(pStubMsg, 4);
2698 safe_buffer_increment(pStubMsg, 8);
2700 case RPC_FC_POINTER:
2702 safe_buffer_increment(pStubMsg, 4);
2703 if (!pStubMsg->IgnoreEmbeddedPointers)
2704 FIXME("embedded pointers\n");
2706 case RPC_FC_ALIGNM4:
2707 ALIGN_LENGTH(size, 4);
2708 ALIGN_POINTER(pStubMsg->Buffer, 4);
2710 case RPC_FC_ALIGNM8:
2711 ALIGN_LENGTH(size, 8);
2712 ALIGN_POINTER(pStubMsg->Buffer, 8);
2714 case RPC_FC_STRUCTPAD1:
2715 case RPC_FC_STRUCTPAD2:
2716 case RPC_FC_STRUCTPAD3:
2717 case RPC_FC_STRUCTPAD4:
2718 case RPC_FC_STRUCTPAD5:
2719 case RPC_FC_STRUCTPAD6:
2720 case RPC_FC_STRUCTPAD7:
2721 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2723 case RPC_FC_EMBEDDED_COMPLEX:
2726 desc = pFormat + *(const SHORT*)pFormat;
2727 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2733 FIXME("unhandled format 0x%02x\n", *pFormat);
2741 unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg,
2742 PFORMAT_STRING pFormat)
2744 PFORMAT_STRING desc;
2745 unsigned long size = 0;
2747 while (*pFormat != RPC_FC_END) {
2769 case RPC_FC_POINTER:
2770 size += sizeof(void *);
2772 case RPC_FC_ALIGNM4:
2773 ALIGN_LENGTH(size, 4);
2775 case RPC_FC_ALIGNM8:
2776 ALIGN_LENGTH(size, 8);
2778 case RPC_FC_STRUCTPAD1:
2779 case RPC_FC_STRUCTPAD2:
2780 case RPC_FC_STRUCTPAD3:
2781 case RPC_FC_STRUCTPAD4:
2782 case RPC_FC_STRUCTPAD5:
2783 case RPC_FC_STRUCTPAD6:
2784 case RPC_FC_STRUCTPAD7:
2785 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2787 case RPC_FC_EMBEDDED_COMPLEX:
2790 desc = pFormat + *(const SHORT*)pFormat;
2791 size += EmbeddedComplexSize(pStubMsg, desc);
2797 FIXME("unhandled format 0x%02x\n", *pFormat);
2805 /***********************************************************************
2806 * NdrComplexStructMarshall [RPCRT4.@]
2808 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2809 unsigned char *pMemory,
2810 PFORMAT_STRING pFormat)
2812 PFORMAT_STRING conf_array = NULL;
2813 PFORMAT_STRING pointer_desc = NULL;
2814 unsigned char *OldMemory = pStubMsg->Memory;
2815 int pointer_buffer_mark_set = 0;
2817 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2819 if (!pStubMsg->PointerBufferMark)
2821 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2822 /* save buffer length */
2823 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2825 /* get the buffer pointer after complex array data, but before
2827 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2828 pStubMsg->IgnoreEmbeddedPointers = 1;
2829 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2830 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2832 /* save it for use by embedded pointer code later */
2833 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2834 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
2835 pointer_buffer_mark_set = 1;
2837 /* restore the original buffer length */
2838 pStubMsg->BufferLength = saved_buffer_length;
2841 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
2844 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2846 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2849 pStubMsg->Memory = pMemory;
2851 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2854 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2856 pStubMsg->Memory = OldMemory;
2858 if (pointer_buffer_mark_set)
2860 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2861 pStubMsg->PointerBufferMark = NULL;
2864 STD_OVERFLOW_CHECK(pStubMsg);
2869 /***********************************************************************
2870 * NdrComplexStructUnmarshall [RPCRT4.@]
2872 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2873 unsigned char **ppMemory,
2874 PFORMAT_STRING pFormat,
2875 unsigned char fMustAlloc)
2877 unsigned size = *(const WORD*)(pFormat+2);
2878 PFORMAT_STRING conf_array = NULL;
2879 PFORMAT_STRING pointer_desc = NULL;
2880 unsigned char *pMemory;
2881 int pointer_buffer_mark_set = 0;
2883 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2885 if (!pStubMsg->PointerBufferMark)
2887 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2888 /* save buffer pointer */
2889 unsigned char *saved_buffer = pStubMsg->Buffer;
2891 /* get the buffer pointer after complex array data, but before
2893 pStubMsg->IgnoreEmbeddedPointers = 1;
2894 NdrComplexStructMemorySize(pStubMsg, pFormat);
2895 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2897 /* save it for use by embedded pointer code later */
2898 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2899 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
2900 pointer_buffer_mark_set = 1;
2902 /* restore the original buffer */
2903 pStubMsg->Buffer = saved_buffer;
2906 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2908 if (fMustAlloc || !*ppMemory)
2910 *ppMemory = NdrAllocate(pStubMsg, size);
2911 memset(*ppMemory, 0, size);
2915 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2917 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2920 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2923 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2925 if (pointer_buffer_mark_set)
2927 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2928 pStubMsg->PointerBufferMark = NULL;
2934 /***********************************************************************
2935 * NdrComplexStructBufferSize [RPCRT4.@]
2937 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2938 unsigned char *pMemory,
2939 PFORMAT_STRING pFormat)
2941 PFORMAT_STRING conf_array = NULL;
2942 PFORMAT_STRING pointer_desc = NULL;
2943 unsigned char *OldMemory = pStubMsg->Memory;
2944 int pointer_length_set = 0;
2946 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2948 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2950 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2952 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2953 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2955 /* get the buffer length after complex struct data, but before
2957 pStubMsg->IgnoreEmbeddedPointers = 1;
2958 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2959 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2961 /* save it for use by embedded pointer code later */
2962 pStubMsg->PointerLength = pStubMsg->BufferLength;
2963 pointer_length_set = 1;
2964 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
2966 /* restore the original buffer length */
2967 pStubMsg->BufferLength = saved_buffer_length;
2971 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2973 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2976 pStubMsg->Memory = pMemory;
2978 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2981 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2983 pStubMsg->Memory = OldMemory;
2985 if(pointer_length_set)
2987 pStubMsg->BufferLength = pStubMsg->PointerLength;
2988 pStubMsg->PointerLength = 0;
2993 /***********************************************************************
2994 * NdrComplexStructMemorySize [RPCRT4.@]
2996 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2997 PFORMAT_STRING pFormat)
2999 unsigned size = *(const WORD*)(pFormat+2);
3000 PFORMAT_STRING conf_array = NULL;
3002 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3004 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3007 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
3010 ComplexStructMemorySize(pStubMsg, pFormat);
3013 NdrConformantArrayMemorySize(pStubMsg, conf_array);
3018 /***********************************************************************
3019 * NdrComplexStructFree [RPCRT4.@]
3021 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3022 unsigned char *pMemory,
3023 PFORMAT_STRING pFormat)
3025 PFORMAT_STRING conf_array = NULL;
3026 PFORMAT_STRING pointer_desc = NULL;
3027 unsigned char *OldMemory = pStubMsg->Memory;
3029 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3032 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
3034 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3037 pStubMsg->Memory = pMemory;
3039 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3042 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
3044 pStubMsg->Memory = OldMemory;
3047 /***********************************************************************
3048 * NdrConformantArrayMarshall [RPCRT4.@]
3050 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3051 unsigned char *pMemory,
3052 PFORMAT_STRING pFormat)
3054 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
3055 unsigned char alignment = pFormat[1] + 1;
3057 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3058 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3060 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3062 WriteConformance(pStubMsg);
3064 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3066 size = safe_multiply(esize, pStubMsg->MaxCount);
3067 pStubMsg->BufferMark = pStubMsg->Buffer;
3068 safe_copy_to_buffer(pStubMsg, pMemory, size);
3070 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3075 /***********************************************************************
3076 * NdrConformantArrayUnmarshall [RPCRT4.@]
3078 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3079 unsigned char **ppMemory,
3080 PFORMAT_STRING pFormat,
3081 unsigned char fMustAlloc)
3083 DWORD size, esize = *(const WORD*)(pFormat+2);
3084 unsigned char alignment = pFormat[1] + 1;
3085 unsigned char *saved_buffer;
3087 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3088 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3090 pFormat = ReadConformance(pStubMsg, pFormat+4);
3092 size = safe_multiply(esize, pStubMsg->MaxCount);
3093 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3096 *ppMemory = NdrAllocate(pStubMsg, size);
3099 if (!pStubMsg->IsClient && !*ppMemory)
3100 /* for servers, we just point straight into the RPC buffer */
3101 *ppMemory = pStubMsg->Buffer;
3104 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3105 safe_buffer_increment(pStubMsg, size);
3106 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3108 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
3109 if (*ppMemory != saved_buffer)
3110 memcpy(*ppMemory, saved_buffer, size);
3115 /***********************************************************************
3116 * NdrConformantArrayBufferSize [RPCRT4.@]
3118 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3119 unsigned char *pMemory,
3120 PFORMAT_STRING pFormat)
3122 DWORD size, esize = *(const WORD*)(pFormat+2);
3123 unsigned char alignment = pFormat[1] + 1;
3125 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3126 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3128 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3130 SizeConformance(pStubMsg);
3132 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3134 size = safe_multiply(esize, pStubMsg->MaxCount);
3135 /* conformance value plus array */
3136 safe_buffer_length_increment(pStubMsg, size);
3138 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3141 /***********************************************************************
3142 * NdrConformantArrayMemorySize [RPCRT4.@]
3144 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3145 PFORMAT_STRING pFormat)
3147 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
3148 unsigned char alignment = pFormat[1] + 1;
3150 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3151 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3153 pFormat = ReadConformance(pStubMsg, pFormat+4);
3154 size = safe_multiply(esize, pStubMsg->MaxCount);
3155 pStubMsg->MemorySize += size;
3157 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3158 pStubMsg->BufferMark = pStubMsg->Buffer;
3159 safe_buffer_increment(pStubMsg, size);
3161 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3163 return pStubMsg->MemorySize;
3166 /***********************************************************************
3167 * NdrConformantArrayFree [RPCRT4.@]
3169 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3170 unsigned char *pMemory,
3171 PFORMAT_STRING pFormat)
3173 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3174 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3176 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3178 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3182 /***********************************************************************
3183 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3185 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
3186 unsigned char* pMemory,
3187 PFORMAT_STRING pFormat )
3190 unsigned char alignment = pFormat[1] + 1;
3191 DWORD esize = *(const WORD*)(pFormat+2);
3193 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3195 if (pFormat[0] != RPC_FC_CVARRAY)
3197 ERR("invalid format type %x\n", pFormat[0]);
3198 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3202 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3203 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3205 WriteConformance(pStubMsg);
3206 WriteVariance(pStubMsg);
3208 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3210 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3212 pStubMsg->BufferMark = pStubMsg->Buffer;
3213 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
3215 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3221 /***********************************************************************
3222 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3224 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
3225 unsigned char** ppMemory,
3226 PFORMAT_STRING pFormat,
3227 unsigned char fMustAlloc )
3229 ULONG bufsize, memsize;
3230 unsigned char alignment = pFormat[1] + 1;
3231 DWORD esize = *(const WORD*)(pFormat+2);
3232 unsigned char *saved_buffer;
3235 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3237 if (pFormat[0] != RPC_FC_CVARRAY)
3239 ERR("invalid format type %x\n", pFormat[0]);
3240 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3244 pFormat = ReadConformance(pStubMsg, pFormat+4);
3245 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3247 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3249 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3250 memsize = safe_multiply(esize, pStubMsg->MaxCount);
3251 offset = pStubMsg->Offset;
3253 if (!*ppMemory || fMustAlloc)
3254 *ppMemory = NdrAllocate(pStubMsg, memsize);
3255 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3256 safe_buffer_increment(pStubMsg, bufsize);
3258 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3260 memcpy(*ppMemory + offset, saved_buffer, bufsize);
3266 /***********************************************************************
3267 * NdrConformantVaryingArrayFree [RPCRT4.@]
3269 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
3270 unsigned char* pMemory,
3271 PFORMAT_STRING pFormat )
3273 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3275 if (pFormat[0] != RPC_FC_CVARRAY)
3277 ERR("invalid format type %x\n", pFormat[0]);
3278 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3282 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3283 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3285 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3289 /***********************************************************************
3290 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3292 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
3293 unsigned char* pMemory, PFORMAT_STRING pFormat )
3295 unsigned char alignment = pFormat[1] + 1;
3296 DWORD esize = *(const WORD*)(pFormat+2);
3298 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3300 if (pFormat[0] != RPC_FC_CVARRAY)
3302 ERR("invalid format type %x\n", pFormat[0]);
3303 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3308 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3309 /* compute length */
3310 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3312 SizeConformance(pStubMsg);
3313 SizeVariance(pStubMsg);
3315 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3317 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
3319 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3323 /***********************************************************************
3324 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3326 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
3327 PFORMAT_STRING pFormat )
3329 ULONG bufsize, memsize;
3330 unsigned char alignment = pFormat[1] + 1;
3331 DWORD esize = *(const WORD*)(pFormat+2);
3333 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3335 if (pFormat[0] != RPC_FC_CVARRAY)
3337 ERR("invalid format type %x\n", pFormat[0]);
3338 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3339 return pStubMsg->MemorySize;
3342 pFormat = ReadConformance(pStubMsg, pFormat+4);
3343 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3345 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3347 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3348 memsize = safe_multiply(esize, pStubMsg->MaxCount);
3350 safe_buffer_increment(pStubMsg, bufsize);
3351 pStubMsg->MemorySize += memsize;
3353 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3355 return pStubMsg->MemorySize;
3359 /***********************************************************************
3360 * NdrComplexArrayMarshall [RPCRT4.@]
3362 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3363 unsigned char *pMemory,
3364 PFORMAT_STRING pFormat)
3366 ULONG i, count, def;
3367 BOOL variance_present;
3368 unsigned char alignment;
3369 int pointer_buffer_mark_set = 0;
3371 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3373 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3375 ERR("invalid format type %x\n", pFormat[0]);
3376 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3380 alignment = pFormat[1] + 1;
3382 if (!pStubMsg->PointerBufferMark)
3384 /* save buffer fields that may be changed by buffer sizer functions
3385 * and that may be needed later on */
3386 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3387 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3388 unsigned long saved_max_count = pStubMsg->MaxCount;
3389 unsigned long saved_offset = pStubMsg->Offset;
3390 unsigned long saved_actual_count = pStubMsg->ActualCount;
3392 /* get the buffer pointer after complex array data, but before
3394 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3395 pStubMsg->IgnoreEmbeddedPointers = 1;
3396 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3397 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3399 /* save it for use by embedded pointer code later */
3400 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3401 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
3402 pointer_buffer_mark_set = 1;
3404 /* restore fields */
3405 pStubMsg->ActualCount = saved_actual_count;
3406 pStubMsg->Offset = saved_offset;
3407 pStubMsg->MaxCount = saved_max_count;
3408 pStubMsg->BufferLength = saved_buffer_length;
3411 def = *(const WORD*)&pFormat[2];
3414 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3415 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3417 variance_present = IsConformanceOrVariancePresent(pFormat);
3418 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3419 TRACE("variance = %d\n", pStubMsg->ActualCount);
3421 WriteConformance(pStubMsg);
3422 if (variance_present)
3423 WriteVariance(pStubMsg);
3425 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3427 count = pStubMsg->ActualCount;
3428 for (i = 0; i < count; i++)
3429 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3431 STD_OVERFLOW_CHECK(pStubMsg);
3433 if (pointer_buffer_mark_set)
3435 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3436 pStubMsg->PointerBufferMark = NULL;
3442 /***********************************************************************
3443 * NdrComplexArrayUnmarshall [RPCRT4.@]
3445 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3446 unsigned char **ppMemory,
3447 PFORMAT_STRING pFormat,
3448 unsigned char fMustAlloc)
3450 ULONG i, count, size;
3451 unsigned char alignment;
3452 unsigned char *pMemory;
3453 unsigned char *saved_buffer;
3454 int pointer_buffer_mark_set = 0;
3455 int saved_ignore_embedded;
3457 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3459 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3461 ERR("invalid format type %x\n", pFormat[0]);
3462 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3466 alignment = pFormat[1] + 1;
3468 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3469 /* save buffer pointer */
3470 saved_buffer = pStubMsg->Buffer;
3471 /* get the buffer pointer after complex array data, but before
3473 pStubMsg->IgnoreEmbeddedPointers = 1;
3474 pStubMsg->MemorySize = 0;
3475 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3476 size = pStubMsg->MemorySize;
3477 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3479 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
3480 if (!pStubMsg->PointerBufferMark)
3482 /* save it for use by embedded pointer code later */
3483 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3484 pointer_buffer_mark_set = 1;
3486 /* restore the original buffer */
3487 pStubMsg->Buffer = saved_buffer;
3491 pFormat = ReadConformance(pStubMsg, pFormat);
3492 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3494 if (fMustAlloc || !*ppMemory)
3496 *ppMemory = NdrAllocate(pStubMsg, size);
3497 memset(*ppMemory, 0, size);
3500 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3502 pMemory = *ppMemory;
3503 count = pStubMsg->ActualCount;
3504 for (i = 0; i < count; i++)
3505 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
3507 if (pointer_buffer_mark_set)
3509 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3510 pStubMsg->PointerBufferMark = NULL;
3516 /***********************************************************************
3517 * NdrComplexArrayBufferSize [RPCRT4.@]
3519 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3520 unsigned char *pMemory,
3521 PFORMAT_STRING pFormat)
3523 ULONG i, count, def;
3524 unsigned char alignment;
3525 BOOL variance_present;
3526 int pointer_length_set = 0;
3528 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3530 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3532 ERR("invalid format type %x\n", pFormat[0]);
3533 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3537 alignment = pFormat[1] + 1;
3539 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3541 /* save buffer fields that may be changed by buffer sizer functions
3542 * and that may be needed later on */
3543 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3544 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3545 unsigned long saved_max_count = pStubMsg->MaxCount;
3546 unsigned long saved_offset = pStubMsg->Offset;
3547 unsigned long saved_actual_count = pStubMsg->ActualCount;
3549 /* get the buffer pointer after complex array data, but before
3551 pStubMsg->IgnoreEmbeddedPointers = 1;
3552 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3553 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3555 /* save it for use by embedded pointer code later */
3556 pStubMsg->PointerLength = pStubMsg->BufferLength;
3557 pointer_length_set = 1;
3559 /* restore fields */
3560 pStubMsg->ActualCount = saved_actual_count;
3561 pStubMsg->Offset = saved_offset;
3562 pStubMsg->MaxCount = saved_max_count;
3563 pStubMsg->BufferLength = saved_buffer_length;
3565 def = *(const WORD*)&pFormat[2];
3568 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3569 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3570 SizeConformance(pStubMsg);
3572 variance_present = IsConformanceOrVariancePresent(pFormat);
3573 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3574 TRACE("variance = %d\n", pStubMsg->ActualCount);
3576 if (variance_present)
3577 SizeVariance(pStubMsg);
3579 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3581 count = pStubMsg->ActualCount;
3582 for (i = 0; i < count; i++)
3583 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
3585 if(pointer_length_set)
3587 pStubMsg->BufferLength = pStubMsg->PointerLength;
3588 pStubMsg->PointerLength = 0;
3592 /***********************************************************************
3593 * NdrComplexArrayMemorySize [RPCRT4.@]
3595 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3596 PFORMAT_STRING pFormat)
3598 ULONG i, count, esize, SavedMemorySize, MemorySize;
3599 unsigned char alignment;
3601 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3603 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3605 ERR("invalid format type %x\n", pFormat[0]);
3606 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3610 alignment = pFormat[1] + 1;
3614 pFormat = ReadConformance(pStubMsg, pFormat);
3615 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3617 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3619 SavedMemorySize = pStubMsg->MemorySize;
3621 esize = ComplexStructSize(pStubMsg, pFormat);
3623 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
3625 count = pStubMsg->ActualCount;
3626 for (i = 0; i < count; i++)
3627 ComplexStructMemorySize(pStubMsg, pFormat);
3629 pStubMsg->MemorySize = SavedMemorySize;
3631 pStubMsg->MemorySize += MemorySize;
3635 /***********************************************************************
3636 * NdrComplexArrayFree [RPCRT4.@]
3638 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3639 unsigned char *pMemory,
3640 PFORMAT_STRING pFormat)
3642 ULONG i, count, def;
3644 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3646 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3648 ERR("invalid format type %x\n", pFormat[0]);
3649 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3653 def = *(const WORD*)&pFormat[2];
3656 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3657 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3659 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3660 TRACE("variance = %d\n", pStubMsg->ActualCount);
3662 count = pStubMsg->ActualCount;
3663 for (i = 0; i < count; i++)
3664 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
3667 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
3668 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
3669 USER_MARSHAL_CB *umcb)
3671 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
3672 pStubMsg->RpcMsg->DataRepresentation);
3673 umcb->pStubMsg = pStubMsg;
3674 umcb->pReserve = NULL;
3675 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
3676 umcb->CBType = cbtype;
3677 umcb->pFormat = pFormat;
3678 umcb->pTypeFormat = NULL /* FIXME */;
3681 #define USER_MARSHAL_PTR_PREFIX \
3682 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3683 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3685 /***********************************************************************
3686 * NdrUserMarshalMarshall [RPCRT4.@]
3688 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3689 unsigned char *pMemory,
3690 PFORMAT_STRING pFormat)
3692 unsigned flags = pFormat[1];
3693 unsigned index = *(const WORD*)&pFormat[2];
3694 unsigned char *saved_buffer = NULL;
3695 USER_MARSHAL_CB umcb;
3697 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3698 TRACE("index=%d\n", index);
3700 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
3702 if (flags & USER_MARSHAL_POINTER)
3704 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
3705 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
3706 pStubMsg->Buffer += 4;
3707 if (pStubMsg->PointerBufferMark)
3709 saved_buffer = pStubMsg->Buffer;
3710 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3711 pStubMsg->PointerBufferMark = NULL;
3713 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
3716 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
3719 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
3720 &umcb.Flags, pStubMsg->Buffer, pMemory);
3724 STD_OVERFLOW_CHECK(pStubMsg);
3725 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3726 pStubMsg->Buffer = saved_buffer;
3729 STD_OVERFLOW_CHECK(pStubMsg);
3734 /***********************************************************************
3735 * NdrUserMarshalUnmarshall [RPCRT4.@]
3737 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3738 unsigned char **ppMemory,
3739 PFORMAT_STRING pFormat,
3740 unsigned char fMustAlloc)
3742 unsigned flags = pFormat[1];
3743 unsigned index = *(const WORD*)&pFormat[2];
3744 DWORD memsize = *(const WORD*)&pFormat[4];
3745 unsigned char *saved_buffer = NULL;
3746 USER_MARSHAL_CB umcb;
3748 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3749 TRACE("index=%d\n", index);
3751 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
3753 if (flags & USER_MARSHAL_POINTER)
3755 ALIGN_POINTER(pStubMsg->Buffer, 4);
3756 /* skip pointer prefix */
3757 pStubMsg->Buffer += 4;
3758 if (pStubMsg->PointerBufferMark)
3760 saved_buffer = pStubMsg->Buffer;
3761 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3762 pStubMsg->PointerBufferMark = NULL;
3764 ALIGN_POINTER(pStubMsg->Buffer, 8);
3767 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3769 if (fMustAlloc || !*ppMemory)
3770 *ppMemory = NdrAllocate(pStubMsg, memsize);
3773 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
3774 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
3778 STD_OVERFLOW_CHECK(pStubMsg);
3779 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3780 pStubMsg->Buffer = saved_buffer;
3786 /***********************************************************************
3787 * NdrUserMarshalBufferSize [RPCRT4.@]
3789 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3790 unsigned char *pMemory,
3791 PFORMAT_STRING pFormat)
3793 unsigned flags = pFormat[1];
3794 unsigned index = *(const WORD*)&pFormat[2];
3795 DWORD bufsize = *(const WORD*)&pFormat[6];
3796 USER_MARSHAL_CB umcb;
3797 unsigned long saved_buffer_length = 0;
3799 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3800 TRACE("index=%d\n", index);
3802 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
3804 if (flags & USER_MARSHAL_POINTER)
3806 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3807 /* skip pointer prefix */
3808 safe_buffer_length_increment(pStubMsg, 4);
3809 if (pStubMsg->IgnoreEmbeddedPointers)
3811 if (pStubMsg->PointerLength)
3813 saved_buffer_length = pStubMsg->BufferLength;
3814 pStubMsg->BufferLength = pStubMsg->PointerLength;
3815 pStubMsg->PointerLength = 0;
3817 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
3820 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
3823 TRACE("size=%d\n", bufsize);
3824 safe_buffer_length_increment(pStubMsg, bufsize);
3827 pStubMsg->BufferLength =
3828 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
3829 &umcb.Flags, pStubMsg->BufferLength, pMemory);
3831 if (saved_buffer_length)
3833 pStubMsg->PointerLength = pStubMsg->BufferLength;
3834 pStubMsg->BufferLength = saved_buffer_length;
3839 /***********************************************************************
3840 * NdrUserMarshalMemorySize [RPCRT4.@]
3842 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3843 PFORMAT_STRING pFormat)
3845 unsigned flags = pFormat[1];
3846 unsigned index = *(const WORD*)&pFormat[2];
3847 DWORD memsize = *(const WORD*)&pFormat[4];
3848 DWORD bufsize = *(const WORD*)&pFormat[6];
3850 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3851 TRACE("index=%d\n", index);
3853 pStubMsg->MemorySize += memsize;
3855 if (flags & USER_MARSHAL_POINTER)
3857 ALIGN_POINTER(pStubMsg->Buffer, 4);
3858 /* skip pointer prefix */
3859 pStubMsg->Buffer += 4;
3860 if (pStubMsg->IgnoreEmbeddedPointers)
3861 return pStubMsg->MemorySize;
3862 ALIGN_POINTER(pStubMsg->Buffer, 8);
3865 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3868 FIXME("not implemented for varying buffer size\n");
3870 pStubMsg->Buffer += bufsize;
3872 return pStubMsg->MemorySize;
3875 /***********************************************************************
3876 * NdrUserMarshalFree [RPCRT4.@]
3878 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
3879 unsigned char *pMemory,
3880 PFORMAT_STRING pFormat)
3882 /* unsigned flags = pFormat[1]; */
3883 unsigned index = *(const WORD*)&pFormat[2];
3884 USER_MARSHAL_CB umcb;
3886 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3887 TRACE("index=%d\n", index);
3889 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
3891 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
3892 &umcb.Flags, pMemory);
3895 /***********************************************************************
3896 * NdrClearOutParameters [RPCRT4.@]
3898 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
3899 PFORMAT_STRING pFormat,
3902 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
3905 /***********************************************************************
3906 * NdrConvert [RPCRT4.@]
3908 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
3910 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
3911 /* FIXME: since this stub doesn't do any converting, the proper behavior
3912 is to raise an exception */
3915 /***********************************************************************
3916 * NdrConvert2 [RPCRT4.@]
3918 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
3920 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3921 pStubMsg, pFormat, NumberParams);
3922 /* FIXME: since this stub doesn't do any converting, the proper behavior
3923 is to raise an exception */
3926 #include "pshpack1.h"
3927 typedef struct _NDR_CSTRUCT_FORMAT
3930 unsigned char alignment;
3931 unsigned short memory_size;
3932 short offset_to_array_description;
3933 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
3934 #include "poppack.h"
3936 /***********************************************************************
3937 * NdrConformantStructMarshall [RPCRT4.@]
3939 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3940 unsigned char *pMemory,
3941 PFORMAT_STRING pFormat)
3943 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3944 PFORMAT_STRING pCArrayFormat;
3945 ULONG esize, bufsize;
3947 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3949 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3950 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3952 ERR("invalid format type %x\n", pCStructFormat->type);
3953 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3957 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3958 pCStructFormat->offset_to_array_description;
3959 if (*pCArrayFormat != RPC_FC_CARRAY)
3961 ERR("invalid array format type %x\n", pCStructFormat->type);
3962 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3965 esize = *(const WORD*)(pCArrayFormat+2);
3967 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3968 pCArrayFormat + 4, 0);
3970 WriteConformance(pStubMsg);
3972 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3974 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3976 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3977 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3979 ERR("integer overflow of memory_size %u with bufsize %u\n",
3980 pCStructFormat->memory_size, bufsize);
3981 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3983 /* copy constant sized part of struct */
3984 pStubMsg->BufferMark = pStubMsg->Buffer;
3985 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
3987 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3988 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3993 /***********************************************************************
3994 * NdrConformantStructUnmarshall [RPCRT4.@]
3996 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3997 unsigned char **ppMemory,
3998 PFORMAT_STRING pFormat,
3999 unsigned char fMustAlloc)
4001 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4002 PFORMAT_STRING pCArrayFormat;
4003 ULONG esize, bufsize;
4004 unsigned char *saved_buffer;
4006 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4008 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4009 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4011 ERR("invalid format type %x\n", pCStructFormat->type);
4012 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4015 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4016 pCStructFormat->offset_to_array_description;
4017 if (*pCArrayFormat != RPC_FC_CARRAY)
4019 ERR("invalid array format type %x\n", pCStructFormat->type);
4020 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4023 esize = *(const WORD*)(pCArrayFormat+2);
4025 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4027 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4029 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4031 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4032 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4034 ERR("integer overflow of memory_size %u with bufsize %u\n",
4035 pCStructFormat->memory_size, bufsize);
4036 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4041 SIZE_T size = pCStructFormat->memory_size + bufsize;
4042 *ppMemory = NdrAllocate(pStubMsg, size);
4046 if (!pStubMsg->IsClient && !*ppMemory)
4047 /* for servers, we just point straight into the RPC buffer */
4048 *ppMemory = pStubMsg->Buffer;
4051 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4052 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4053 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4054 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4056 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4057 if (*ppMemory != saved_buffer)
4058 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4063 /***********************************************************************
4064 * NdrConformantStructBufferSize [RPCRT4.@]
4066 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4067 unsigned char *pMemory,
4068 PFORMAT_STRING pFormat)
4070 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4071 PFORMAT_STRING pCArrayFormat;
4074 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4076 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4077 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4079 ERR("invalid format type %x\n", pCStructFormat->type);
4080 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4083 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4084 pCStructFormat->offset_to_array_description;
4085 if (*pCArrayFormat != RPC_FC_CARRAY)
4087 ERR("invalid array format type %x\n", pCStructFormat->type);
4088 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4091 esize = *(const WORD*)(pCArrayFormat+2);
4093 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4094 SizeConformance(pStubMsg);
4096 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4098 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4100 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4101 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4103 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4104 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4107 /***********************************************************************
4108 * NdrConformantStructMemorySize [RPCRT4.@]
4110 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4111 PFORMAT_STRING pFormat)
4117 /***********************************************************************
4118 * NdrConformantStructFree [RPCRT4.@]
4120 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4121 unsigned char *pMemory,
4122 PFORMAT_STRING pFormat)
4124 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4125 PFORMAT_STRING pCArrayFormat;
4127 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4129 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4130 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4132 ERR("invalid format type %x\n", pCStructFormat->type);
4133 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4137 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4138 pCStructFormat->offset_to_array_description;
4139 if (*pCArrayFormat != RPC_FC_CARRAY)
4141 ERR("invalid array format type %x\n", pCStructFormat->type);
4142 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4146 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4147 pCArrayFormat + 4, 0);
4149 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4151 /* copy constant sized part of struct */
4152 pStubMsg->BufferMark = pStubMsg->Buffer;
4154 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4155 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4158 /***********************************************************************
4159 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4161 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4162 unsigned char *pMemory,
4163 PFORMAT_STRING pFormat)
4165 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4166 PFORMAT_STRING pCVArrayFormat;
4167 ULONG esize, bufsize;
4169 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4171 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4172 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4174 ERR("invalid format type %x\n", pCVStructFormat->type);
4175 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4179 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4180 pCVStructFormat->offset_to_array_description;
4181 switch (*pCVArrayFormat)
4183 case RPC_FC_CVARRAY:
4184 esize = *(const WORD*)(pCVArrayFormat+2);
4186 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4187 pCVArrayFormat + 4, 0);
4188 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4191 case RPC_FC_C_CSTRING:
4192 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4193 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4194 esize = sizeof(char);
4195 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4196 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4197 pCVArrayFormat + 2, 0);
4199 pStubMsg->MaxCount = pStubMsg->ActualCount;
4201 case RPC_FC_C_WSTRING:
4202 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4203 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4204 esize = sizeof(WCHAR);
4205 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4206 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4207 pCVArrayFormat + 2, 0);
4209 pStubMsg->MaxCount = pStubMsg->ActualCount;
4212 ERR("invalid array format type %x\n", *pCVArrayFormat);
4213 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4217 WriteConformance(pStubMsg);
4219 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4221 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4223 /* write constant sized part */
4224 pStubMsg->BufferMark = pStubMsg->Buffer;
4225 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4227 WriteVariance(pStubMsg);
4229 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4231 /* write array part */
4232 safe_copy_to_buffer(pStubMsg, pMemory + pCVStructFormat->memory_size, bufsize);
4234 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4239 /***********************************************************************
4240 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4242 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4243 unsigned char **ppMemory,
4244 PFORMAT_STRING pFormat,
4245 unsigned char fMustAlloc)
4247 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4248 PFORMAT_STRING pCVArrayFormat;
4249 ULONG esize, bufsize;
4250 unsigned char cvarray_type;
4252 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4254 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4255 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4257 ERR("invalid format type %x\n", pCVStructFormat->type);
4258 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4262 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4263 pCVStructFormat->offset_to_array_description;
4264 cvarray_type = *pCVArrayFormat;
4265 switch (cvarray_type)
4267 case RPC_FC_CVARRAY:
4268 esize = *(const WORD*)(pCVArrayFormat+2);
4269 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4271 case RPC_FC_C_CSTRING:
4272 esize = sizeof(char);
4273 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4274 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4276 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4278 case RPC_FC_C_WSTRING:
4279 esize = sizeof(WCHAR);
4280 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4281 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4283 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4286 ERR("invalid array format type %x\n", *pCVArrayFormat);
4287 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4291 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4293 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4295 /* work out how much memory to allocate if we need to do so */
4296 if (!*ppMemory || fMustAlloc)
4298 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4299 *ppMemory = NdrAllocate(pStubMsg, size);
4302 /* copy the constant data */
4303 pStubMsg->BufferMark = pStubMsg->Buffer;
4304 safe_copy_from_buffer(pStubMsg, *ppMemory, pCVStructFormat->memory_size);
4306 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4308 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4310 if ((cvarray_type == RPC_FC_C_CSTRING) ||
4311 (cvarray_type == RPC_FC_C_WSTRING))
4314 /* strings must always have null terminating bytes */
4315 if (bufsize < esize)
4317 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
4318 RpcRaiseException(RPC_S_INVALID_BOUND);
4321 for (i = bufsize - esize; i < bufsize; i++)
4322 if (pStubMsg->Buffer[i] != 0)
4324 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
4325 i, pStubMsg->Buffer[i]);
4326 RpcRaiseException(RPC_S_INVALID_BOUND);
4331 /* copy the array data */
4332 safe_copy_from_buffer(pStubMsg, *ppMemory + pCVStructFormat->memory_size, bufsize);
4334 if (cvarray_type == RPC_FC_C_CSTRING)
4335 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
4336 else if (cvarray_type == RPC_FC_C_WSTRING)
4337 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
4339 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
4344 /***********************************************************************
4345 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4347 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4348 unsigned char *pMemory,
4349 PFORMAT_STRING pFormat)
4351 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4352 PFORMAT_STRING pCVArrayFormat;
4355 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4357 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4358 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4360 ERR("invalid format type %x\n", pCVStructFormat->type);
4361 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4365 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4366 pCVStructFormat->offset_to_array_description;
4367 switch (*pCVArrayFormat)
4369 case RPC_FC_CVARRAY:
4370 esize = *(const WORD*)(pCVArrayFormat+2);
4372 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4373 pCVArrayFormat + 4, 0);
4374 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4377 case RPC_FC_C_CSTRING:
4378 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4379 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4380 esize = sizeof(char);
4381 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4382 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4383 pCVArrayFormat + 2, 0);
4385 pStubMsg->MaxCount = pStubMsg->ActualCount;
4387 case RPC_FC_C_WSTRING:
4388 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4389 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4390 esize = sizeof(WCHAR);
4391 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4392 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4393 pCVArrayFormat + 2, 0);
4395 pStubMsg->MaxCount = pStubMsg->ActualCount;
4398 ERR("invalid array format type %x\n", *pCVArrayFormat);
4399 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4403 SizeConformance(pStubMsg);
4405 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4407 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4409 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4410 SizeVariance(pStubMsg);
4411 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4413 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4416 /***********************************************************************
4417 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4419 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4420 PFORMAT_STRING pFormat)
4422 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4423 PFORMAT_STRING pCVArrayFormat;
4425 unsigned char cvarray_type;
4427 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4429 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4430 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4432 ERR("invalid format type %x\n", pCVStructFormat->type);
4433 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4437 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4438 pCVStructFormat->offset_to_array_description;
4439 cvarray_type = *pCVArrayFormat;
4440 switch (cvarray_type)
4442 case RPC_FC_CVARRAY:
4443 esize = *(const WORD*)(pCVArrayFormat+2);
4444 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4446 case RPC_FC_C_CSTRING:
4447 esize = sizeof(char);
4448 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4449 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4451 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4453 case RPC_FC_C_WSTRING:
4454 esize = sizeof(WCHAR);
4455 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4456 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4458 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4461 ERR("invalid array format type %x\n", *pCVArrayFormat);
4462 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4466 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4468 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4470 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4471 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4472 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4474 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4476 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4478 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
4481 /***********************************************************************
4482 * NdrConformantVaryingStructFree [RPCRT4.@]
4484 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4485 unsigned char *pMemory,
4486 PFORMAT_STRING pFormat)
4488 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4489 PFORMAT_STRING pCVArrayFormat;
4491 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4493 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4494 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4496 ERR("invalid format type %x\n", pCVStructFormat->type);
4497 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4501 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4502 pCVStructFormat->offset_to_array_description;
4503 switch (*pCVArrayFormat)
4505 case RPC_FC_CVARRAY:
4506 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4507 pCVArrayFormat + 4, 0);
4508 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4511 case RPC_FC_C_CSTRING:
4512 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4513 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4514 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4515 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4516 pCVArrayFormat + 2, 0);
4518 pStubMsg->MaxCount = pStubMsg->ActualCount;
4520 case RPC_FC_C_WSTRING:
4521 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4522 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4523 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4524 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4525 pCVArrayFormat + 2, 0);
4527 pStubMsg->MaxCount = pStubMsg->ActualCount;
4530 ERR("invalid array format type %x\n", *pCVArrayFormat);
4531 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4535 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4537 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4540 #include "pshpack1.h"
4544 unsigned char alignment;
4545 unsigned short total_size;
4546 } NDR_SMFARRAY_FORMAT;
4551 unsigned char alignment;
4552 unsigned long total_size;
4553 } NDR_LGFARRAY_FORMAT;
4554 #include "poppack.h"
4556 /***********************************************************************
4557 * NdrFixedArrayMarshall [RPCRT4.@]
4559 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4560 unsigned char *pMemory,
4561 PFORMAT_STRING pFormat)
4563 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4564 unsigned long total_size;
4566 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4568 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4569 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4571 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4572 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4576 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4578 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4580 total_size = pSmFArrayFormat->total_size;
4581 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4585 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4586 total_size = pLgFArrayFormat->total_size;
4587 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4590 pStubMsg->BufferMark = pStubMsg->Buffer;
4591 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4593 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4598 /***********************************************************************
4599 * NdrFixedArrayUnmarshall [RPCRT4.@]
4601 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4602 unsigned char **ppMemory,
4603 PFORMAT_STRING pFormat,
4604 unsigned char fMustAlloc)
4606 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4607 unsigned long total_size;
4608 unsigned char *saved_buffer;
4610 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4612 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4613 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4615 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4616 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4620 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4622 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4624 total_size = pSmFArrayFormat->total_size;
4625 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4629 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4630 total_size = pLgFArrayFormat->total_size;
4631 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4635 *ppMemory = NdrAllocate(pStubMsg, total_size);
4638 if (!pStubMsg->IsClient && !*ppMemory)
4639 /* for servers, we just point straight into the RPC buffer */
4640 *ppMemory = pStubMsg->Buffer;
4643 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4644 safe_buffer_increment(pStubMsg, total_size);
4645 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4647 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4648 if (*ppMemory != saved_buffer)
4649 memcpy(*ppMemory, saved_buffer, total_size);
4654 /***********************************************************************
4655 * NdrFixedArrayBufferSize [RPCRT4.@]
4657 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4658 unsigned char *pMemory,
4659 PFORMAT_STRING pFormat)
4661 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4662 unsigned long total_size;
4664 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4666 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4667 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4669 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4670 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4674 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4676 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4678 total_size = pSmFArrayFormat->total_size;
4679 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4683 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4684 total_size = pLgFArrayFormat->total_size;
4685 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4687 safe_buffer_length_increment(pStubMsg, total_size);
4689 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4692 /***********************************************************************
4693 * NdrFixedArrayMemorySize [RPCRT4.@]
4695 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4696 PFORMAT_STRING pFormat)
4698 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4701 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4703 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4704 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4706 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4707 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4711 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4713 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4715 total_size = pSmFArrayFormat->total_size;
4716 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4720 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4721 total_size = pLgFArrayFormat->total_size;
4722 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4724 pStubMsg->BufferMark = pStubMsg->Buffer;
4725 safe_buffer_increment(pStubMsg, total_size);
4726 pStubMsg->MemorySize += total_size;
4728 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4733 /***********************************************************************
4734 * NdrFixedArrayFree [RPCRT4.@]
4736 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4737 unsigned char *pMemory,
4738 PFORMAT_STRING pFormat)
4740 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4742 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4744 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4745 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4747 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4748 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4752 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4753 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4756 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4757 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4760 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4763 /***********************************************************************
4764 * NdrVaryingArrayMarshall [RPCRT4.@]
4766 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4767 unsigned char *pMemory,
4768 PFORMAT_STRING pFormat)
4770 unsigned char alignment;
4771 DWORD elements, esize;
4774 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4776 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4777 (pFormat[0] != RPC_FC_LGVARRAY))
4779 ERR("invalid format type %x\n", pFormat[0]);
4780 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4784 alignment = pFormat[1] + 1;
4786 if (pFormat[0] == RPC_FC_SMVARRAY)
4789 pFormat += sizeof(WORD);
4790 elements = *(const WORD*)pFormat;
4791 pFormat += sizeof(WORD);
4796 pFormat += sizeof(DWORD);
4797 elements = *(const DWORD*)pFormat;
4798 pFormat += sizeof(DWORD);
4801 esize = *(const WORD*)pFormat;
4802 pFormat += sizeof(WORD);
4804 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4805 if ((pStubMsg->ActualCount > elements) ||
4806 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4808 RpcRaiseException(RPC_S_INVALID_BOUND);
4812 WriteVariance(pStubMsg);
4814 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
4816 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4817 pStubMsg->BufferMark = pStubMsg->Buffer;
4818 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
4820 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4825 /***********************************************************************
4826 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4828 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4829 unsigned char **ppMemory,
4830 PFORMAT_STRING pFormat,
4831 unsigned char fMustAlloc)
4833 unsigned char alignment;
4834 DWORD size, elements, esize;
4836 unsigned char *saved_buffer;
4839 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4841 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4842 (pFormat[0] != RPC_FC_LGVARRAY))
4844 ERR("invalid format type %x\n", pFormat[0]);
4845 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4849 alignment = pFormat[1] + 1;
4851 if (pFormat[0] == RPC_FC_SMVARRAY)
4854 size = *(const WORD*)pFormat;
4855 pFormat += sizeof(WORD);
4856 elements = *(const WORD*)pFormat;
4857 pFormat += sizeof(WORD);
4862 size = *(const DWORD*)pFormat;
4863 pFormat += sizeof(DWORD);
4864 elements = *(const DWORD*)pFormat;
4865 pFormat += sizeof(DWORD);
4868 esize = *(const WORD*)pFormat;
4869 pFormat += sizeof(WORD);
4871 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4873 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4875 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4876 offset = pStubMsg->Offset;
4878 if (!*ppMemory || fMustAlloc)
4879 *ppMemory = NdrAllocate(pStubMsg, size);
4880 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4881 safe_buffer_increment(pStubMsg, bufsize);
4883 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4885 memcpy(*ppMemory + offset, saved_buffer, bufsize);
4890 /***********************************************************************
4891 * NdrVaryingArrayBufferSize [RPCRT4.@]
4893 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4894 unsigned char *pMemory,
4895 PFORMAT_STRING pFormat)
4897 unsigned char alignment;
4898 DWORD elements, esize;
4900 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4902 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4903 (pFormat[0] != RPC_FC_LGVARRAY))
4905 ERR("invalid format type %x\n", pFormat[0]);
4906 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4910 alignment = pFormat[1] + 1;
4912 if (pFormat[0] == RPC_FC_SMVARRAY)
4915 pFormat += sizeof(WORD);
4916 elements = *(const WORD*)pFormat;
4917 pFormat += sizeof(WORD);
4922 pFormat += sizeof(DWORD);
4923 elements = *(const DWORD*)pFormat;
4924 pFormat += sizeof(DWORD);
4927 esize = *(const WORD*)pFormat;
4928 pFormat += sizeof(WORD);
4930 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4931 if ((pStubMsg->ActualCount > elements) ||
4932 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4934 RpcRaiseException(RPC_S_INVALID_BOUND);
4938 SizeVariance(pStubMsg);
4940 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4942 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4944 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4947 /***********************************************************************
4948 * NdrVaryingArrayMemorySize [RPCRT4.@]
4950 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4951 PFORMAT_STRING pFormat)
4953 unsigned char alignment;
4954 DWORD size, elements, esize;
4956 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4958 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4959 (pFormat[0] != RPC_FC_LGVARRAY))
4961 ERR("invalid format type %x\n", pFormat[0]);
4962 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4966 alignment = pFormat[1] + 1;
4968 if (pFormat[0] == RPC_FC_SMVARRAY)
4971 size = *(const WORD*)pFormat;
4972 pFormat += sizeof(WORD);
4973 elements = *(const WORD*)pFormat;
4974 pFormat += sizeof(WORD);
4979 size = *(const DWORD*)pFormat;
4980 pFormat += sizeof(DWORD);
4981 elements = *(const DWORD*)pFormat;
4982 pFormat += sizeof(DWORD);
4985 esize = *(const WORD*)pFormat;
4986 pFormat += sizeof(WORD);
4988 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4990 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4992 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4993 pStubMsg->MemorySize += size;
4995 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4997 return pStubMsg->MemorySize;
5000 /***********************************************************************
5001 * NdrVaryingArrayFree [RPCRT4.@]
5003 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5004 unsigned char *pMemory,
5005 PFORMAT_STRING pFormat)
5009 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5011 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5012 (pFormat[0] != RPC_FC_LGVARRAY))
5014 ERR("invalid format type %x\n", pFormat[0]);
5015 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5019 if (pFormat[0] == RPC_FC_SMVARRAY)
5022 pFormat += sizeof(WORD);
5023 elements = *(const WORD*)pFormat;
5024 pFormat += sizeof(WORD);
5029 pFormat += sizeof(DWORD);
5030 elements = *(const DWORD*)pFormat;
5031 pFormat += sizeof(DWORD);
5034 pFormat += sizeof(WORD);
5036 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5037 if ((pStubMsg->ActualCount > elements) ||
5038 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5040 RpcRaiseException(RPC_S_INVALID_BOUND);
5044 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5047 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5060 return *(const USHORT *)pMemory;
5064 return *(const ULONG *)pMemory;
5066 FIXME("Unhandled base type: 0x%02x\n", fc);
5071 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5072 unsigned long discriminant,
5073 PFORMAT_STRING pFormat)
5075 unsigned short num_arms, arm, type;
5077 num_arms = *(const SHORT*)pFormat & 0x0fff;
5079 for(arm = 0; arm < num_arms; arm++)
5081 if(discriminant == *(const ULONG*)pFormat)
5089 type = *(const unsigned short*)pFormat;
5090 TRACE("type %04x\n", type);
5091 if(arm == num_arms) /* default arm extras */
5095 ERR("no arm for 0x%lx and no default case\n", discriminant);
5096 RpcRaiseException(RPC_S_INVALID_TAG);
5101 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
5108 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5110 unsigned short type;
5114 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5118 type = *(const unsigned short*)pFormat;
5119 if((type & 0xff00) == 0x8000)
5121 unsigned char basetype = LOBYTE(type);
5122 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5126 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5127 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5130 unsigned char *saved_buffer = NULL;
5131 int pointer_buffer_mark_set = 0;
5138 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5139 saved_buffer = pStubMsg->Buffer;
5140 if (pStubMsg->PointerBufferMark)
5142 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5143 pStubMsg->PointerBufferMark = NULL;
5144 pointer_buffer_mark_set = 1;
5147 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5149 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5150 if (pointer_buffer_mark_set)
5152 STD_OVERFLOW_CHECK(pStubMsg);
5153 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5154 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5156 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5157 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5158 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5160 pStubMsg->Buffer = saved_buffer + 4;
5164 m(pStubMsg, pMemory, desc);
5167 else FIXME("no marshaller for embedded type %02x\n", *desc);
5172 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5173 unsigned char **ppMemory,
5175 PFORMAT_STRING pFormat,
5176 unsigned char fMustAlloc)
5178 unsigned short type;
5182 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5186 type = *(const unsigned short*)pFormat;
5187 if((type & 0xff00) == 0x8000)
5189 unsigned char basetype = LOBYTE(type);
5190 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5194 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5195 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5198 unsigned char *saved_buffer = NULL;
5199 int pointer_buffer_mark_set = 0;
5206 **(void***)ppMemory = NULL;
5207 ALIGN_POINTER(pStubMsg->Buffer, 4);
5208 saved_buffer = pStubMsg->Buffer;
5209 if (pStubMsg->PointerBufferMark)
5211 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5212 pStubMsg->PointerBufferMark = NULL;
5213 pointer_buffer_mark_set = 1;
5216 pStubMsg->Buffer += 4; /* for pointer ID */
5218 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5220 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5221 saved_buffer, pStubMsg->BufferEnd);
5222 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5225 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5226 if (pointer_buffer_mark_set)
5228 STD_OVERFLOW_CHECK(pStubMsg);
5229 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5230 pStubMsg->Buffer = saved_buffer + 4;
5234 m(pStubMsg, ppMemory, desc, fMustAlloc);
5237 else FIXME("no marshaller for embedded type %02x\n", *desc);
5242 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5243 unsigned char *pMemory,
5245 PFORMAT_STRING pFormat)
5247 unsigned short type;
5251 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5255 type = *(const unsigned short*)pFormat;
5256 if((type & 0xff00) == 0x8000)
5258 unsigned char basetype = LOBYTE(type);
5259 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5263 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5264 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5273 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5274 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5275 if (!pStubMsg->IgnoreEmbeddedPointers)
5277 int saved_buffer_length = pStubMsg->BufferLength;
5278 pStubMsg->BufferLength = pStubMsg->PointerLength;
5279 pStubMsg->PointerLength = 0;
5280 if(!pStubMsg->BufferLength)
5281 ERR("BufferLength == 0??\n");
5282 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5283 pStubMsg->PointerLength = pStubMsg->BufferLength;
5284 pStubMsg->BufferLength = saved_buffer_length;
5288 m(pStubMsg, pMemory, desc);
5291 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5295 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5297 PFORMAT_STRING pFormat)
5299 unsigned short type, size;
5301 size = *(const unsigned short*)pFormat;
5302 pStubMsg->Memory += size;
5305 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5309 type = *(const unsigned short*)pFormat;
5310 if((type & 0xff00) == 0x8000)
5312 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5316 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5317 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5318 unsigned char *saved_buffer;
5327 ALIGN_POINTER(pStubMsg->Buffer, 4);
5328 saved_buffer = pStubMsg->Buffer;
5329 safe_buffer_increment(pStubMsg, 4);
5330 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
5331 pStubMsg->MemorySize += 4;
5332 if (!pStubMsg->IgnoreEmbeddedPointers)
5333 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5336 return m(pStubMsg, desc);
5339 else FIXME("no marshaller for embedded type %02x\n", *desc);
5342 TRACE("size %d\n", size);
5346 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5347 unsigned char *pMemory,
5349 PFORMAT_STRING pFormat)
5351 unsigned short type;
5355 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5359 type = *(const unsigned short*)pFormat;
5360 if((type & 0xff00) != 0x8000)
5362 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5363 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5372 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5375 m(pStubMsg, pMemory, desc);
5381 /***********************************************************************
5382 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5384 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5385 unsigned char *pMemory,
5386 PFORMAT_STRING pFormat)
5388 unsigned char switch_type;
5389 unsigned char increment;
5392 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5395 switch_type = *pFormat & 0xf;
5396 increment = (*pFormat & 0xf0) >> 4;
5399 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5401 switch_value = get_discriminant(switch_type, pMemory);
5402 TRACE("got switch value 0x%x\n", switch_value);
5404 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5405 pMemory += increment;
5407 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5410 /***********************************************************************
5411 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5413 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5414 unsigned char **ppMemory,
5415 PFORMAT_STRING pFormat,
5416 unsigned char fMustAlloc)
5418 unsigned char switch_type;
5419 unsigned char increment;
5421 unsigned short size;
5422 unsigned char *pMemoryArm;
5424 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5427 switch_type = *pFormat & 0xf;
5428 increment = (*pFormat & 0xf0) >> 4;
5431 ALIGN_POINTER(pStubMsg->Buffer, increment);
5432 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5433 TRACE("got switch value 0x%x\n", switch_value);
5435 size = *(const unsigned short*)pFormat + increment;
5436 if(!*ppMemory || fMustAlloc)
5437 *ppMemory = NdrAllocate(pStubMsg, size);
5439 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5440 pMemoryArm = *ppMemory + increment;
5442 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
5445 /***********************************************************************
5446 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5448 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5449 unsigned char *pMemory,
5450 PFORMAT_STRING pFormat)
5452 unsigned char switch_type;
5453 unsigned char increment;
5456 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5459 switch_type = *pFormat & 0xf;
5460 increment = (*pFormat & 0xf0) >> 4;
5463 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5464 switch_value = get_discriminant(switch_type, pMemory);
5465 TRACE("got switch value 0x%x\n", switch_value);
5467 /* Add discriminant size */
5468 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5469 pMemory += increment;
5471 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5474 /***********************************************************************
5475 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5477 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5478 PFORMAT_STRING pFormat)
5480 unsigned char switch_type;
5481 unsigned char increment;
5484 switch_type = *pFormat & 0xf;
5485 increment = (*pFormat & 0xf0) >> 4;
5488 ALIGN_POINTER(pStubMsg->Buffer, increment);
5489 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5490 TRACE("got switch value 0x%x\n", switch_value);
5492 pStubMsg->Memory += increment;
5494 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5497 /***********************************************************************
5498 * NdrEncapsulatedUnionFree [RPCRT4.@]
5500 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5501 unsigned char *pMemory,
5502 PFORMAT_STRING pFormat)
5504 unsigned char switch_type;
5505 unsigned char increment;
5508 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5511 switch_type = *pFormat & 0xf;
5512 increment = (*pFormat & 0xf0) >> 4;
5515 switch_value = get_discriminant(switch_type, pMemory);
5516 TRACE("got switch value 0x%x\n", switch_value);
5518 pMemory += increment;
5520 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5523 /***********************************************************************
5524 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5526 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5527 unsigned char *pMemory,
5528 PFORMAT_STRING pFormat)
5530 unsigned char switch_type;
5532 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5535 switch_type = *pFormat;
5538 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5539 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5540 /* Marshall discriminant */
5541 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5543 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5546 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5547 PFORMAT_STRING *ppFormat)
5549 long discriminant = 0;
5559 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5568 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5569 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5577 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5578 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5583 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5587 if (pStubMsg->fHasNewCorrDesc)
5591 return discriminant;
5594 /**********************************************************************
5595 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5597 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5598 unsigned char **ppMemory,
5599 PFORMAT_STRING pFormat,
5600 unsigned char fMustAlloc)
5603 unsigned short size;
5605 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5608 /* Unmarshall discriminant */
5609 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5610 TRACE("unmarshalled discriminant %lx\n", discriminant);
5612 pFormat += *(const SHORT*)pFormat;
5614 size = *(const unsigned short*)pFormat;
5616 if(!*ppMemory || fMustAlloc)
5617 *ppMemory = NdrAllocate(pStubMsg, size);
5619 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5622 /***********************************************************************
5623 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5625 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5626 unsigned char *pMemory,
5627 PFORMAT_STRING pFormat)
5629 unsigned char switch_type;
5631 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5634 switch_type = *pFormat;
5637 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5638 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5639 /* Add discriminant size */
5640 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5642 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5645 /***********************************************************************
5646 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5648 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5649 PFORMAT_STRING pFormat)
5654 /* Unmarshall discriminant */
5655 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5656 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
5658 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
5661 /***********************************************************************
5662 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5664 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5665 unsigned char *pMemory,
5666 PFORMAT_STRING pFormat)
5668 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5672 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5673 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5675 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5678 /***********************************************************************
5679 * NdrByteCountPointerMarshall [RPCRT4.@]
5681 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5682 unsigned char *pMemory,
5683 PFORMAT_STRING pFormat)
5689 /***********************************************************************
5690 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5692 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5693 unsigned char **ppMemory,
5694 PFORMAT_STRING pFormat,
5695 unsigned char fMustAlloc)
5701 /***********************************************************************
5702 * NdrByteCountPointerBufferSize [RPCRT4.@]
5704 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5705 unsigned char *pMemory,
5706 PFORMAT_STRING pFormat)
5711 /***********************************************************************
5712 * NdrByteCountPointerMemorySize [RPCRT4.@]
5714 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5715 PFORMAT_STRING pFormat)
5721 /***********************************************************************
5722 * NdrByteCountPointerFree [RPCRT4.@]
5724 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
5725 unsigned char *pMemory,
5726 PFORMAT_STRING pFormat)
5731 /***********************************************************************
5732 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5734 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5735 unsigned char *pMemory,
5736 PFORMAT_STRING pFormat)
5742 /***********************************************************************
5743 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5745 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5746 unsigned char **ppMemory,
5747 PFORMAT_STRING pFormat,
5748 unsigned char fMustAlloc)
5754 /***********************************************************************
5755 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5757 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5758 unsigned char *pMemory,
5759 PFORMAT_STRING pFormat)
5764 /***********************************************************************
5765 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5767 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5768 PFORMAT_STRING pFormat)
5774 /***********************************************************************
5775 * NdrXmitOrRepAsFree [RPCRT4.@]
5777 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
5778 unsigned char *pMemory,
5779 PFORMAT_STRING pFormat)
5784 #include "pshpack1.h"
5788 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
5792 #include "poppack.h"
5794 /***********************************************************************
5795 * NdrRangeMarshall [internal]
5797 unsigned char *WINAPI NdrRangeMarshall(
5798 PMIDL_STUB_MESSAGE pStubMsg,
5799 unsigned char *pMemory,
5800 PFORMAT_STRING pFormat)
5802 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5803 unsigned char base_type;
5805 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5807 if (pRange->type != RPC_FC_RANGE)
5809 ERR("invalid format type %x\n", pRange->type);
5810 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5814 base_type = pRange->flags_type & 0xf;
5816 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
5819 /***********************************************************************
5820 * NdrRangeUnmarshall
5822 unsigned char *WINAPI NdrRangeUnmarshall(
5823 PMIDL_STUB_MESSAGE pStubMsg,
5824 unsigned char **ppMemory,
5825 PFORMAT_STRING pFormat,
5826 unsigned char fMustAlloc)
5828 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5829 unsigned char base_type;
5831 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5833 if (pRange->type != RPC_FC_RANGE)
5835 ERR("invalid format type %x\n", pRange->type);
5836 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5839 base_type = pRange->flags_type & 0xf;
5841 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5842 base_type, pRange->low_value, pRange->high_value);
5844 #define RANGE_UNMARSHALL(type, format_spec) \
5847 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5848 if (fMustAlloc || !*ppMemory) \
5849 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5850 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5852 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5853 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5854 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5856 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5857 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5859 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5860 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5861 (type)pRange->high_value); \
5862 RpcRaiseException(RPC_S_INVALID_BOUND); \
5865 TRACE("*ppMemory: %p\n", *ppMemory); \
5866 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5867 pStubMsg->Buffer += sizeof(type); \
5874 RANGE_UNMARSHALL(UCHAR, "%d");
5875 TRACE("value: 0x%02x\n", **ppMemory);
5879 RANGE_UNMARSHALL(CHAR, "%u");
5880 TRACE("value: 0x%02x\n", **ppMemory);
5882 case RPC_FC_WCHAR: /* FIXME: valid? */
5884 RANGE_UNMARSHALL(USHORT, "%u");
5885 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5888 RANGE_UNMARSHALL(SHORT, "%d");
5889 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5892 RANGE_UNMARSHALL(LONG, "%d");
5893 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5896 RANGE_UNMARSHALL(ULONG, "%u");
5897 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5901 FIXME("Unhandled enum type\n");
5903 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
5908 ERR("invalid range base type: 0x%02x\n", base_type);
5909 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5915 /***********************************************************************
5916 * NdrRangeBufferSize [internal]
5918 void WINAPI NdrRangeBufferSize(
5919 PMIDL_STUB_MESSAGE pStubMsg,
5920 unsigned char *pMemory,
5921 PFORMAT_STRING pFormat)
5923 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5924 unsigned char base_type;
5926 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5928 if (pRange->type != RPC_FC_RANGE)
5930 ERR("invalid format type %x\n", pRange->type);
5931 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5933 base_type = pRange->flags_type & 0xf;
5935 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
5938 /***********************************************************************
5939 * NdrRangeMemorySize [internal]
5941 ULONG WINAPI NdrRangeMemorySize(
5942 PMIDL_STUB_MESSAGE pStubMsg,
5943 PFORMAT_STRING pFormat)
5945 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5946 unsigned char base_type;
5948 if (pRange->type != RPC_FC_RANGE)
5950 ERR("invalid format type %x\n", pRange->type);
5951 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5954 base_type = pRange->flags_type & 0xf;
5956 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
5959 /***********************************************************************
5960 * NdrRangeFree [internal]
5962 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
5963 unsigned char *pMemory,
5964 PFORMAT_STRING pFormat)
5966 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5971 /***********************************************************************
5972 * NdrBaseTypeMarshall [internal]
5974 static unsigned char *WINAPI NdrBaseTypeMarshall(
5975 PMIDL_STUB_MESSAGE pStubMsg,
5976 unsigned char *pMemory,
5977 PFORMAT_STRING pFormat)
5979 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5987 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
5988 TRACE("value: 0x%02x\n", *pMemory);
5993 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
5994 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
5995 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
5999 case RPC_FC_ERROR_STATUS_T:
6001 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
6002 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6003 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6006 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
6007 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6010 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
6011 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6014 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
6015 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6016 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6019 /* only 16-bits on the wire, so do a sanity check */
6020 if (*(UINT *)pMemory > SHRT_MAX)
6021 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6022 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6023 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6024 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6025 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
6026 pStubMsg->Buffer += sizeof(USHORT);
6027 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6032 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6035 /* FIXME: what is the correct return value? */
6039 /***********************************************************************
6040 * NdrBaseTypeUnmarshall [internal]
6042 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6043 PMIDL_STUB_MESSAGE pStubMsg,
6044 unsigned char **ppMemory,
6045 PFORMAT_STRING pFormat,
6046 unsigned char fMustAlloc)
6048 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6050 #define BASE_TYPE_UNMARSHALL(type) \
6051 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6052 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6054 *ppMemory = pStubMsg->Buffer; \
6055 TRACE("*ppMemory: %p\n", *ppMemory); \
6056 safe_buffer_increment(pStubMsg, sizeof(type)); \
6061 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6062 TRACE("*ppMemory: %p\n", *ppMemory); \
6063 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6072 BASE_TYPE_UNMARSHALL(UCHAR);
6073 TRACE("value: 0x%02x\n", **ppMemory);
6078 BASE_TYPE_UNMARSHALL(USHORT);
6079 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6083 case RPC_FC_ERROR_STATUS_T:
6085 BASE_TYPE_UNMARSHALL(ULONG);
6086 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6089 BASE_TYPE_UNMARSHALL(float);
6090 TRACE("value: %f\n", **(float **)ppMemory);
6093 BASE_TYPE_UNMARSHALL(double);
6094 TRACE("value: %f\n", **(double **)ppMemory);
6097 BASE_TYPE_UNMARSHALL(ULONGLONG);
6098 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6101 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6102 if (fMustAlloc || !*ppMemory)
6103 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6104 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
6105 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6106 TRACE("*ppMemory: %p\n", *ppMemory);
6107 /* 16-bits on the wire, but int in memory */
6108 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
6109 pStubMsg->Buffer += sizeof(USHORT);
6110 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6115 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6117 #undef BASE_TYPE_UNMARSHALL
6119 /* FIXME: what is the correct return value? */
6124 /***********************************************************************
6125 * NdrBaseTypeBufferSize [internal]
6127 static void WINAPI NdrBaseTypeBufferSize(
6128 PMIDL_STUB_MESSAGE pStubMsg,
6129 unsigned char *pMemory,
6130 PFORMAT_STRING pFormat)
6132 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6140 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6146 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
6147 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6152 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
6153 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6156 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
6157 safe_buffer_length_increment(pStubMsg, sizeof(float));
6160 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
6161 safe_buffer_length_increment(pStubMsg, sizeof(double));
6164 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
6165 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6167 case RPC_FC_ERROR_STATUS_T:
6168 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
6169 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6174 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6178 /***********************************************************************
6179 * NdrBaseTypeMemorySize [internal]
6181 static ULONG WINAPI NdrBaseTypeMemorySize(
6182 PMIDL_STUB_MESSAGE pStubMsg,
6183 PFORMAT_STRING pFormat)
6185 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6193 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6194 pStubMsg->MemorySize += sizeof(UCHAR);
6195 return sizeof(UCHAR);
6199 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6200 pStubMsg->MemorySize += sizeof(USHORT);
6201 return sizeof(USHORT);
6205 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6206 pStubMsg->MemorySize += sizeof(ULONG);
6207 return sizeof(ULONG);
6209 safe_buffer_increment(pStubMsg, sizeof(float));
6210 pStubMsg->MemorySize += sizeof(float);
6211 return sizeof(float);
6213 safe_buffer_increment(pStubMsg, sizeof(double));
6214 pStubMsg->MemorySize += sizeof(double);
6215 return sizeof(double);
6217 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6218 pStubMsg->MemorySize += sizeof(ULONGLONG);
6219 return sizeof(ULONGLONG);
6220 case RPC_FC_ERROR_STATUS_T:
6221 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6222 pStubMsg->MemorySize += sizeof(error_status_t);
6223 return sizeof(error_status_t);
6225 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6226 pStubMsg->MemorySize += sizeof(UINT);
6227 return sizeof(UINT);
6229 pStubMsg->MemorySize += sizeof(void *);
6230 return sizeof(void *);
6232 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6237 /***********************************************************************
6238 * NdrBaseTypeFree [internal]
6240 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6241 unsigned char *pMemory,
6242 PFORMAT_STRING pFormat)
6244 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6249 /***********************************************************************
6250 * NdrContextHandleBufferSize [internal]
6252 static void WINAPI NdrContextHandleBufferSize(
6253 PMIDL_STUB_MESSAGE pStubMsg,
6254 unsigned char *pMemory,
6255 PFORMAT_STRING pFormat)
6257 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6259 if (*pFormat != RPC_FC_BIND_CONTEXT)
6261 ERR("invalid format type %x\n", *pFormat);
6262 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6264 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
6265 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6268 /***********************************************************************
6269 * NdrContextHandleMarshall [internal]
6271 static unsigned char *WINAPI NdrContextHandleMarshall(
6272 PMIDL_STUB_MESSAGE pStubMsg,
6273 unsigned char *pMemory,
6274 PFORMAT_STRING pFormat)
6276 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6278 if (*pFormat != RPC_FC_BIND_CONTEXT)
6280 ERR("invalid format type %x\n", *pFormat);
6281 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6283 TRACE("flags: 0x%02x\n", pFormat[1]);
6285 if (pFormat[1] & 0x80)
6286 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6288 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
6293 /***********************************************************************
6294 * NdrContextHandleUnmarshall [internal]
6296 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6297 PMIDL_STUB_MESSAGE pStubMsg,
6298 unsigned char **ppMemory,
6299 PFORMAT_STRING pFormat,
6300 unsigned char fMustAlloc)
6302 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6303 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6305 if (*pFormat != RPC_FC_BIND_CONTEXT)
6307 ERR("invalid format type %x\n", *pFormat);
6308 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6310 TRACE("flags: 0x%02x\n", pFormat[1]);
6312 /* [out]-only or [ret] param */
6313 if ((pFormat[1] & 0x60) == 0x20)
6314 **(NDR_CCONTEXT **)ppMemory = NULL;
6315 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6320 /***********************************************************************
6321 * NdrClientContextMarshall [RPCRT4.@]
6323 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6324 NDR_CCONTEXT ContextHandle,
6327 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
6329 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
6331 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6333 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6334 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6335 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6338 /* FIXME: what does fCheck do? */
6339 NDRCContextMarshall(ContextHandle,
6342 pStubMsg->Buffer += cbNDRContext;
6345 /***********************************************************************
6346 * NdrClientContextUnmarshall [RPCRT4.@]
6348 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6349 NDR_CCONTEXT * pContextHandle,
6350 RPC_BINDING_HANDLE BindHandle)
6352 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
6354 ALIGN_POINTER(pStubMsg->Buffer, 4);
6356 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
6357 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6359 NDRCContextUnmarshall(pContextHandle,
6362 pStubMsg->RpcMsg->DataRepresentation);
6364 pStubMsg->Buffer += cbNDRContext;
6367 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6368 NDR_SCONTEXT ContextHandle,
6369 NDR_RUNDOWN RundownRoutine )
6371 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
6373 ALIGN_POINTER(pStubMsg->Buffer, 4);
6375 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6377 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6378 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6379 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6382 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6383 pStubMsg->Buffer, RundownRoutine, NULL,
6384 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6385 pStubMsg->Buffer += cbNDRContext;
6388 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6390 NDR_SCONTEXT ContextHandle;
6392 TRACE("(%p)\n", pStubMsg);
6394 ALIGN_POINTER(pStubMsg->Buffer, 4);
6396 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6398 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6399 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6400 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6403 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6405 pStubMsg->RpcMsg->DataRepresentation,
6406 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6407 pStubMsg->Buffer += cbNDRContext;
6409 return ContextHandle;
6412 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6413 unsigned char* pMemory,
6414 PFORMAT_STRING pFormat)
6416 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6419 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6420 PFORMAT_STRING pFormat)
6422 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6423 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6425 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6427 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6428 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6429 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6430 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6431 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6433 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6434 if_id = &sif->InterfaceId;
6437 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
6438 pStubMsg->RpcMsg->DataRepresentation, if_id,
6442 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6443 NDR_SCONTEXT ContextHandle,
6444 NDR_RUNDOWN RundownRoutine,
6445 PFORMAT_STRING pFormat)
6447 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6448 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6450 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6452 ALIGN_POINTER(pStubMsg->Buffer, 4);
6454 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6456 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6457 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6458 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6461 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6462 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6463 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6464 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6465 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6467 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6468 if_id = &sif->InterfaceId;
6471 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6472 pStubMsg->Buffer, RundownRoutine, if_id, flags);
6473 pStubMsg->Buffer += cbNDRContext;
6476 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6477 PFORMAT_STRING pFormat)
6479 NDR_SCONTEXT ContextHandle;
6480 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6481 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6483 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6485 ALIGN_POINTER(pStubMsg->Buffer, 4);
6487 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6489 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6490 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6491 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6494 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6495 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6496 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6497 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6498 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6500 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6501 if_id = &sif->InterfaceId;
6504 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6506 pStubMsg->RpcMsg->DataRepresentation,
6508 pStubMsg->Buffer += cbNDRContext;
6510 return ContextHandle;
6513 /***********************************************************************
6514 * NdrCorrelationInitialize [RPCRT4.@]
6516 * Initializes correlation validity checking.
6519 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6520 * pMemory [I] Pointer to memory to use as a cache.
6521 * CacheSize [I] Size of the memory pointed to by pMemory.
6522 * Flags [I] Reserved. Set to zero.
6527 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
6529 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
6530 pStubMsg->fHasNewCorrDesc = TRUE;
6533 /***********************************************************************
6534 * NdrCorrelationPass [RPCRT4.@]
6536 * Performs correlation validity checking.
6539 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6544 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
6546 FIXME("(%p): stub\n", pStubMsg);
6549 /***********************************************************************
6550 * NdrCorrelationFree [RPCRT4.@]
6552 * Frees any resources used while unmarshalling parameters that need
6553 * correlation validity checking.
6556 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6561 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
6563 FIXME("(%p): stub\n", pStubMsg);