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
22 * - Non-conformant strings
24 * - Byte count pointers
25 * - transmit_as/represent as
26 * - Multi-dimensional arrays
27 * - Conversion functions (NdrConvert)
28 * - Checks for integer addition overflow in base type and user marshall functions
44 #include "wine/unicode.h"
45 #include "wine/rpcfc.h"
47 #include "wine/debug.h"
48 #include "wine/list.h"
50 WINE_DEFAULT_DEBUG_CHANNEL(ole);
53 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
54 (*((UINT32 *)(pchar)) = (uint32))
56 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
57 (*((UINT32 *)(pchar)))
59 /* these would work for i386 too, but less efficient */
60 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
61 (*(pchar) = LOBYTE(LOWORD(uint32)), \
62 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
63 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
64 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
65 (uint32)) /* allow as r-value */
67 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
69 MAKEWORD(*(pchar), *((pchar)+1)), \
70 MAKEWORD(*((pchar)+2), *((pchar)+3))))
73 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
74 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
75 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
76 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
77 *(pchar) = HIBYTE(HIWORD(uint32)), \
78 (uint32)) /* allow as r-value */
80 #define BIG_ENDIAN_UINT32_READ(pchar) \
82 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
83 MAKEWORD(*((pchar)+1), *(pchar))))
85 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
86 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
87 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
88 # define NDR_LOCAL_UINT32_READ(pchar) \
89 BIG_ENDIAN_UINT32_READ(pchar)
91 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
92 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
93 # define NDR_LOCAL_UINT32_READ(pchar) \
94 LITTLE_ENDIAN_UINT32_READ(pchar)
97 /* _Align must be the desired alignment,
98 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
99 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
100 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
101 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
102 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
103 #define ALIGN_POINTER_CLEAR(_Ptr, _Align) \
105 memset((_Ptr), 0, (ULONG_PTR)(_Ptr) & ((_Align) - 1)); \
106 ALIGN_POINTER(_Ptr, _Align); \
109 #define STD_OVERFLOW_CHECK(_Msg) do { \
110 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
111 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
112 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
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))
667 RpcRaiseException(RPC_X_BAD_STUB_DATA);
668 memcpy(p, pStubMsg->Buffer, size);
669 pStubMsg->Buffer += size;
672 /* copies data to the buffer, checking that there is enough space to do so */
673 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
675 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
676 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
678 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
679 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
681 RpcRaiseException(RPC_X_BAD_STUB_DATA);
683 memcpy(pStubMsg->Buffer, p, size);
684 pStubMsg->Buffer += size;
688 * NdrConformantString:
690 * What MS calls a ConformantString is, in DCE terminology,
691 * a Varying-Conformant String.
693 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
694 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
695 * into unmarshalled string)
696 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
698 * data: CHARTYPE[maxlen]
700 * ], where CHARTYPE is the appropriate character type (specified externally)
704 /***********************************************************************
705 * NdrConformantStringMarshall [RPCRT4.@]
707 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
708 unsigned char *pszMessage, PFORMAT_STRING pFormat)
712 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
714 if (*pFormat == RPC_FC_C_CSTRING) {
715 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
716 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
719 else if (*pFormat == RPC_FC_C_WSTRING) {
720 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
721 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
725 ERR("Unhandled string type: %#x\n", *pFormat);
726 /* FIXME: raise an exception. */
730 if (pFormat[1] == RPC_FC_STRING_SIZED)
731 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
733 pStubMsg->MaxCount = pStubMsg->ActualCount;
734 pStubMsg->Offset = 0;
735 WriteConformance(pStubMsg);
736 WriteVariance(pStubMsg);
738 size = safe_multiply(esize, pStubMsg->ActualCount);
739 safe_copy_to_buffer(pStubMsg, pszMessage, size); /* the string itself */
742 return NULL; /* is this always right? */
745 /***********************************************************************
746 * NdrConformantStringBufferSize [RPCRT4.@]
748 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
749 unsigned char* pMemory, PFORMAT_STRING pFormat)
753 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
755 SizeConformance(pStubMsg);
756 SizeVariance(pStubMsg);
758 if (*pFormat == RPC_FC_C_CSTRING) {
759 TRACE("string=%s\n", debugstr_a((char*)pMemory));
760 pStubMsg->ActualCount = strlen((char*)pMemory)+1;
763 else if (*pFormat == RPC_FC_C_WSTRING) {
764 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
765 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;
769 ERR("Unhandled string type: %#x\n", *pFormat);
770 /* FIXME: raise an exception */
774 if (pFormat[1] == RPC_FC_STRING_SIZED)
775 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
777 pStubMsg->MaxCount = pStubMsg->ActualCount;
779 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
782 /************************************************************************
783 * NdrConformantStringMemorySize [RPCRT4.@]
785 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
786 PFORMAT_STRING pFormat )
790 FIXME("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
792 assert(pStubMsg && pFormat);
794 if (*pFormat == RPC_FC_C_CSTRING) {
795 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
797 else if (*pFormat == RPC_FC_C_WSTRING) {
798 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
801 ERR("Unhandled string type: %#x\n", *pFormat);
802 /* FIXME: raise an exception */
805 if (pFormat[1] != RPC_FC_PAD) {
806 FIXME("sized string format=%d\n", pFormat[1]);
809 TRACE(" --> %u\n", rslt);
813 /************************************************************************
814 * NdrConformantStringUnmarshall [RPCRT4.@]
816 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
817 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
819 ULONG bufsize, memsize, esize, i;
821 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
822 pStubMsg, *ppMemory, pFormat, fMustAlloc);
824 assert(pFormat && ppMemory && pStubMsg);
826 ReadConformance(pStubMsg, NULL);
827 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
829 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
831 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
832 pStubMsg->ActualCount, pStubMsg->MaxCount);
833 RpcRaiseException(RPC_S_INVALID_BOUND);
836 if (pStubMsg->Offset)
838 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
839 RpcRaiseException(RPC_S_INVALID_BOUND);
843 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
844 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
846 ERR("Unhandled string type: %#x\n", *pFormat);
847 /* FIXME: raise an exception */
851 memsize = safe_multiply(esize, pStubMsg->MaxCount);
852 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
854 /* strings must always have null terminating bytes */
857 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
858 RpcRaiseException(RPC_S_INVALID_BOUND);
862 /* verify the buffer is safe to access */
863 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
864 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
866 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
867 pStubMsg->BufferEnd, pStubMsg->Buffer);
868 RpcRaiseException(RPC_X_BAD_STUB_DATA);
872 for (i = bufsize - esize; i < bufsize; i++)
873 if (pStubMsg->Buffer[i] != 0)
875 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
876 i, pStubMsg->Buffer[i]);
877 RpcRaiseException(RPC_S_INVALID_BOUND);
882 *ppMemory = NdrAllocate(pStubMsg, memsize);
885 if (!pStubMsg->IsClient && !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
886 /* if the data in the RPC buffer is big enough, we just point straight
888 *ppMemory = pStubMsg->Buffer;
890 *ppMemory = NdrAllocate(pStubMsg, memsize);
893 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
895 if (*pFormat == RPC_FC_C_CSTRING) {
896 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
898 else if (*pFormat == RPC_FC_C_WSTRING) {
899 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
902 return NULL; /* FIXME: is this always right? */
905 /***********************************************************************
906 * NdrNonConformantStringMarshall [RPCRT4.@]
908 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
909 unsigned char *pMemory,
910 PFORMAT_STRING pFormat)
916 /***********************************************************************
917 * NdrNonConformantStringUnmarshall [RPCRT4.@]
919 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
920 unsigned char **ppMemory,
921 PFORMAT_STRING pFormat,
922 unsigned char fMustAlloc)
928 /***********************************************************************
929 * NdrNonConformantStringBufferSize [RPCRT4.@]
931 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
932 unsigned char *pMemory,
933 PFORMAT_STRING pFormat)
938 /***********************************************************************
939 * NdrNonConformantStringMemorySize [RPCRT4.@]
941 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
942 PFORMAT_STRING pFormat)
948 static inline void dump_pointer_attr(unsigned char attr)
950 if (attr & RPC_FC_P_ALLOCALLNODES)
951 TRACE(" RPC_FC_P_ALLOCALLNODES");
952 if (attr & RPC_FC_P_DONTFREE)
953 TRACE(" RPC_FC_P_DONTFREE");
954 if (attr & RPC_FC_P_ONSTACK)
955 TRACE(" RPC_FC_P_ONSTACK");
956 if (attr & RPC_FC_P_SIMPLEPOINTER)
957 TRACE(" RPC_FC_P_SIMPLEPOINTER");
958 if (attr & RPC_FC_P_DEREF)
959 TRACE(" RPC_FC_P_DEREF");
963 /***********************************************************************
964 * PointerMarshall [internal]
966 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
967 unsigned char *Buffer,
968 unsigned char *Pointer,
969 PFORMAT_STRING pFormat)
971 unsigned type = pFormat[0], attr = pFormat[1];
975 int pointer_needs_marshaling;
977 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
978 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
980 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
981 else desc = pFormat + *(const SHORT*)pFormat;
984 case RPC_FC_RP: /* ref pointer (always non-null) */
987 ERR("NULL ref pointer is not allowed\n");
988 RpcRaiseException(RPC_X_NULL_REF_POINTER);
990 pointer_needs_marshaling = 1;
992 case RPC_FC_UP: /* unique pointer */
993 case RPC_FC_OP: /* object pointer - same as unique here */
995 pointer_needs_marshaling = 1;
997 pointer_needs_marshaling = 0;
998 pointer_id = (ULONG)Pointer;
999 TRACE("writing 0x%08x to buffer\n", pointer_id);
1000 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
1003 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
1004 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
1005 TRACE("writing 0x%08x to buffer\n", pointer_id);
1006 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
1009 FIXME("unhandled ptr type=%02x\n", type);
1010 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1014 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
1016 if (pointer_needs_marshaling) {
1017 if (attr & RPC_FC_P_DEREF) {
1018 Pointer = *(unsigned char**)Pointer;
1019 TRACE("deref => %p\n", Pointer);
1021 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1022 if (m) m(pStubMsg, Pointer, desc);
1023 else FIXME("no marshaller for data type=%02x\n", *desc);
1026 STD_OVERFLOW_CHECK(pStubMsg);
1029 /***********************************************************************
1030 * PointerUnmarshall [internal]
1032 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1033 unsigned char *Buffer,
1034 unsigned char **pPointer,
1035 unsigned char *pSrcPointer,
1036 PFORMAT_STRING pFormat,
1037 unsigned char fMustAlloc)
1039 unsigned type = pFormat[0], attr = pFormat[1];
1040 PFORMAT_STRING desc;
1042 DWORD pointer_id = 0;
1043 int pointer_needs_unmarshaling;
1045 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
1046 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1048 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1049 else desc = pFormat + *(const SHORT*)pFormat;
1052 case RPC_FC_RP: /* ref pointer (always non-null) */
1053 pointer_needs_unmarshaling = 1;
1055 case RPC_FC_UP: /* unique pointer */
1056 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1057 TRACE("pointer_id is 0x%08x\n", pointer_id);
1059 pointer_needs_unmarshaling = 1;
1062 pointer_needs_unmarshaling = 0;
1065 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1066 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1067 TRACE("pointer_id is 0x%08x\n", pointer_id);
1068 if (!fMustAlloc && pSrcPointer)
1070 FIXME("free object pointer %p\n", pSrcPointer);
1074 pointer_needs_unmarshaling = 1;
1076 pointer_needs_unmarshaling = 0;
1079 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1080 TRACE("pointer_id is 0x%08x\n", pointer_id);
1081 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
1082 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
1085 FIXME("unhandled ptr type=%02x\n", type);
1086 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1090 if (pointer_needs_unmarshaling) {
1091 unsigned char *base_ptr_val = *pPointer;
1092 unsigned char **current_ptr = pPointer;
1093 if (pStubMsg->IsClient) {
1095 /* if we aren't forcing allocation of memory then try to use the existing
1096 * (source) pointer to unmarshall the data into so that [in,out]
1097 * parameters behave correctly. it doesn't matter if the parameter is
1098 * [out] only since in that case the pointer will be NULL. we force
1099 * allocation when the source pointer is NULL here instead of in the type
1100 * unmarshalling routine for the benefit of the deref code below */
1103 TRACE("setting *pPointer to %p\n", pSrcPointer);
1104 *pPointer = base_ptr_val = pSrcPointer;
1110 /* the memory in a stub is never initialised, so we have to work out here
1111 * whether we have to initialise it so we can use the optimisation of
1112 * setting the pointer to the buffer, if possible, or set fMustAlloc to
1114 if (attr & RPC_FC_P_DEREF) {
1117 base_ptr_val = NULL;
1118 *current_ptr = NULL;
1122 if (attr & RPC_FC_P_ALLOCALLNODES)
1123 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
1125 if (attr & RPC_FC_P_DEREF) {
1127 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
1128 *pPointer = base_ptr_val;
1129 current_ptr = (unsigned char **)base_ptr_val;
1131 current_ptr = *(unsigned char***)current_ptr;
1132 TRACE("deref => %p\n", current_ptr);
1133 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
1135 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1136 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
1137 else FIXME("no unmarshaller for data type=%02x\n", *desc);
1139 if (type == RPC_FC_FP)
1140 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
1144 TRACE("pointer=%p\n", *pPointer);
1147 /***********************************************************************
1148 * PointerBufferSize [internal]
1150 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1151 unsigned char *Pointer,
1152 PFORMAT_STRING pFormat)
1154 unsigned type = pFormat[0], attr = pFormat[1];
1155 PFORMAT_STRING desc;
1157 int pointer_needs_sizing;
1160 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1161 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1163 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1164 else desc = pFormat + *(const SHORT*)pFormat;
1167 case RPC_FC_RP: /* ref pointer (always non-null) */
1170 ERR("NULL ref pointer is not allowed\n");
1171 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1176 /* NULL pointer has no further representation */
1181 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1182 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1183 if (!pointer_needs_sizing)
1187 FIXME("unhandled ptr type=%02x\n", type);
1188 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1192 if (attr & RPC_FC_P_DEREF) {
1193 Pointer = *(unsigned char**)Pointer;
1194 TRACE("deref => %p\n", Pointer);
1197 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1198 if (m) m(pStubMsg, Pointer, desc);
1199 else FIXME("no buffersizer for data type=%02x\n", *desc);
1202 /***********************************************************************
1203 * PointerMemorySize [internal]
1205 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1206 unsigned char *Buffer,
1207 PFORMAT_STRING pFormat)
1209 unsigned type = pFormat[0], attr = pFormat[1];
1210 PFORMAT_STRING desc;
1212 DWORD pointer_id = 0;
1213 int pointer_needs_sizing;
1215 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1216 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1218 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1219 else desc = pFormat + *(const SHORT*)pFormat;
1222 case RPC_FC_RP: /* ref pointer (always non-null) */
1223 pointer_needs_sizing = 1;
1225 case RPC_FC_UP: /* unique pointer */
1226 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1227 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1228 TRACE("pointer_id is 0x%08x\n", pointer_id);
1230 pointer_needs_sizing = 1;
1232 pointer_needs_sizing = 0;
1237 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1238 TRACE("pointer_id is 0x%08x\n", pointer_id);
1239 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1240 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1244 FIXME("unhandled ptr type=%02x\n", type);
1245 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1249 if (attr & RPC_FC_P_DEREF) {
1253 if (pointer_needs_sizing) {
1254 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1255 if (m) m(pStubMsg, desc);
1256 else FIXME("no memorysizer for data type=%02x\n", *desc);
1259 return pStubMsg->MemorySize;
1262 /***********************************************************************
1263 * PointerFree [internal]
1265 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1266 unsigned char *Pointer,
1267 PFORMAT_STRING pFormat)
1269 unsigned type = pFormat[0], attr = pFormat[1];
1270 PFORMAT_STRING desc;
1272 unsigned char *current_pointer = Pointer;
1274 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1275 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1276 if (attr & RPC_FC_P_DONTFREE) return;
1278 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1279 else desc = pFormat + *(const SHORT*)pFormat;
1281 if (!Pointer) return;
1283 if (type == RPC_FC_FP) {
1284 int pointer_needs_freeing = NdrFullPointerFree(
1285 pStubMsg->FullPtrXlatTables, Pointer);
1286 if (!pointer_needs_freeing)
1290 if (attr & RPC_FC_P_DEREF) {
1291 current_pointer = *(unsigned char**)Pointer;
1292 TRACE("deref => %p\n", current_pointer);
1295 m = NdrFreer[*desc & NDR_TABLE_MASK];
1296 if (m) m(pStubMsg, current_pointer, desc);
1298 /* this check stops us from trying to free buffer memory. we don't have to
1299 * worry about clients, since they won't call this function.
1300 * we don't have to check for the buffer being reallocated because
1301 * BufferStart and BufferEnd won't be reset when allocating memory for
1302 * sending the response. we don't have to check for the new buffer here as
1303 * it won't be used a type memory, only for buffer memory */
1304 if (Pointer >= (unsigned char *)pStubMsg->BufferStart &&
1305 Pointer < (unsigned char *)pStubMsg->BufferEnd)
1308 if (attr & RPC_FC_P_ONSTACK) {
1309 TRACE("not freeing stack ptr %p\n", Pointer);
1312 TRACE("freeing %p\n", Pointer);
1313 NdrFree(pStubMsg, Pointer);
1316 TRACE("not freeing %p\n", Pointer);
1319 /***********************************************************************
1320 * EmbeddedPointerMarshall
1322 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1323 unsigned char *pMemory,
1324 PFORMAT_STRING pFormat)
1326 unsigned char *Mark = pStubMsg->BufferMark;
1327 unsigned rep, count, stride;
1329 unsigned char *saved_buffer = NULL;
1331 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1333 if (*pFormat != RPC_FC_PP) return NULL;
1336 if (pStubMsg->PointerBufferMark)
1338 saved_buffer = pStubMsg->Buffer;
1339 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1340 pStubMsg->PointerBufferMark = NULL;
1343 while (pFormat[0] != RPC_FC_END) {
1344 switch (pFormat[0]) {
1346 FIXME("unknown repeat type %d\n", pFormat[0]);
1347 case RPC_FC_NO_REPEAT:
1353 case RPC_FC_FIXED_REPEAT:
1354 rep = *(const WORD*)&pFormat[2];
1355 stride = *(const WORD*)&pFormat[4];
1356 count = *(const WORD*)&pFormat[8];
1359 case RPC_FC_VARIABLE_REPEAT:
1360 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1361 stride = *(const WORD*)&pFormat[2];
1362 count = *(const WORD*)&pFormat[6];
1366 for (i = 0; i < rep; i++) {
1367 PFORMAT_STRING info = pFormat;
1368 unsigned char *membase = pMemory + (i * stride);
1369 unsigned char *bufbase = Mark + (i * stride);
1372 for (u=0; u<count; u++,info+=8) {
1373 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1374 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1375 unsigned char *saved_memory = pStubMsg->Memory;
1377 pStubMsg->Memory = pMemory;
1378 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1379 pStubMsg->Memory = saved_memory;
1382 pFormat += 8 * count;
1387 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1388 pStubMsg->Buffer = saved_buffer;
1391 STD_OVERFLOW_CHECK(pStubMsg);
1396 /***********************************************************************
1397 * EmbeddedPointerUnmarshall
1399 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1400 unsigned char *pDstMemoryPtrs,
1401 unsigned char *pSrcMemoryPtrs,
1402 PFORMAT_STRING pFormat,
1403 unsigned char fMustAlloc)
1405 unsigned char *Mark = pStubMsg->BufferMark;
1406 unsigned rep, count, stride;
1408 unsigned char *saved_buffer = NULL;
1410 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstMemoryPtrs, pSrcMemoryPtrs, pFormat, fMustAlloc);
1412 if (*pFormat != RPC_FC_PP) return NULL;
1415 if (pStubMsg->PointerBufferMark)
1417 saved_buffer = pStubMsg->Buffer;
1418 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1419 pStubMsg->PointerBufferMark = NULL;
1422 while (pFormat[0] != RPC_FC_END) {
1423 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1424 switch (pFormat[0]) {
1426 FIXME("unknown repeat type %d\n", pFormat[0]);
1427 case RPC_FC_NO_REPEAT:
1433 case RPC_FC_FIXED_REPEAT:
1434 rep = *(const WORD*)&pFormat[2];
1435 stride = *(const WORD*)&pFormat[4];
1436 count = *(const WORD*)&pFormat[8];
1439 case RPC_FC_VARIABLE_REPEAT:
1440 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1441 stride = *(const WORD*)&pFormat[2];
1442 count = *(const WORD*)&pFormat[6];
1446 for (i = 0; i < rep; i++) {
1447 PFORMAT_STRING info = pFormat;
1448 unsigned char *memdstbase = pDstMemoryPtrs + (i * stride);
1449 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1450 unsigned char *bufbase = Mark + (i * stride);
1453 for (u=0; u<count; u++,info+=8) {
1454 unsigned char **memdstptr = (unsigned char **)(memdstbase + *(const SHORT*)&info[0]);
1455 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1456 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1457 PointerUnmarshall(pStubMsg, bufptr, memdstptr, *memsrcptr, info+4, fMustAlloc);
1460 pFormat += 8 * count;
1465 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1466 pStubMsg->Buffer = saved_buffer;
1472 /***********************************************************************
1473 * EmbeddedPointerBufferSize
1475 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1476 unsigned char *pMemory,
1477 PFORMAT_STRING pFormat)
1479 unsigned rep, count, stride;
1481 ULONG saved_buffer_length = 0;
1483 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1485 if (pStubMsg->IgnoreEmbeddedPointers) return;
1487 if (*pFormat != RPC_FC_PP) return;
1490 if (pStubMsg->PointerLength)
1492 saved_buffer_length = pStubMsg->BufferLength;
1493 pStubMsg->BufferLength = pStubMsg->PointerLength;
1494 pStubMsg->PointerLength = 0;
1497 while (pFormat[0] != RPC_FC_END) {
1498 switch (pFormat[0]) {
1500 FIXME("unknown repeat type %d\n", pFormat[0]);
1501 case RPC_FC_NO_REPEAT:
1507 case RPC_FC_FIXED_REPEAT:
1508 rep = *(const WORD*)&pFormat[2];
1509 stride = *(const WORD*)&pFormat[4];
1510 count = *(const WORD*)&pFormat[8];
1513 case RPC_FC_VARIABLE_REPEAT:
1514 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1515 stride = *(const WORD*)&pFormat[2];
1516 count = *(const WORD*)&pFormat[6];
1520 for (i = 0; i < rep; i++) {
1521 PFORMAT_STRING info = pFormat;
1522 unsigned char *membase = pMemory + (i * stride);
1525 for (u=0; u<count; u++,info+=8) {
1526 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1527 unsigned char *saved_memory = pStubMsg->Memory;
1529 pStubMsg->Memory = pMemory;
1530 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1531 pStubMsg->Memory = saved_memory;
1534 pFormat += 8 * count;
1537 if (saved_buffer_length)
1539 pStubMsg->PointerLength = pStubMsg->BufferLength;
1540 pStubMsg->BufferLength = saved_buffer_length;
1544 /***********************************************************************
1545 * EmbeddedPointerMemorySize [internal]
1547 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1548 PFORMAT_STRING pFormat)
1550 unsigned char *Mark = pStubMsg->BufferMark;
1551 unsigned rep, count, stride;
1553 unsigned char *saved_buffer = NULL;
1555 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1557 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1559 if (pStubMsg->PointerBufferMark)
1561 saved_buffer = pStubMsg->Buffer;
1562 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1563 pStubMsg->PointerBufferMark = NULL;
1566 if (*pFormat != RPC_FC_PP) return 0;
1569 while (pFormat[0] != RPC_FC_END) {
1570 switch (pFormat[0]) {
1572 FIXME("unknown repeat type %d\n", pFormat[0]);
1573 case RPC_FC_NO_REPEAT:
1579 case RPC_FC_FIXED_REPEAT:
1580 rep = *(const WORD*)&pFormat[2];
1581 stride = *(const WORD*)&pFormat[4];
1582 count = *(const WORD*)&pFormat[8];
1585 case RPC_FC_VARIABLE_REPEAT:
1586 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1587 stride = *(const WORD*)&pFormat[2];
1588 count = *(const WORD*)&pFormat[6];
1592 for (i = 0; i < rep; i++) {
1593 PFORMAT_STRING info = pFormat;
1594 unsigned char *bufbase = Mark + (i * stride);
1596 for (u=0; u<count; u++,info+=8) {
1597 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1598 PointerMemorySize(pStubMsg, bufptr, info+4);
1601 pFormat += 8 * count;
1606 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1607 pStubMsg->Buffer = saved_buffer;
1613 /***********************************************************************
1614 * EmbeddedPointerFree [internal]
1616 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1617 unsigned char *pMemory,
1618 PFORMAT_STRING pFormat)
1620 unsigned rep, count, stride;
1623 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1624 if (*pFormat != RPC_FC_PP) return;
1627 while (pFormat[0] != RPC_FC_END) {
1628 switch (pFormat[0]) {
1630 FIXME("unknown repeat type %d\n", pFormat[0]);
1631 case RPC_FC_NO_REPEAT:
1637 case RPC_FC_FIXED_REPEAT:
1638 rep = *(const WORD*)&pFormat[2];
1639 stride = *(const WORD*)&pFormat[4];
1640 count = *(const WORD*)&pFormat[8];
1643 case RPC_FC_VARIABLE_REPEAT:
1644 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1645 stride = *(const WORD*)&pFormat[2];
1646 count = *(const WORD*)&pFormat[6];
1650 for (i = 0; i < rep; i++) {
1651 PFORMAT_STRING info = pFormat;
1652 unsigned char *membase = pMemory + (i * stride);
1655 for (u=0; u<count; u++,info+=8) {
1656 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1657 unsigned char *saved_memory = pStubMsg->Memory;
1659 pStubMsg->Memory = pMemory;
1660 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1661 pStubMsg->Memory = saved_memory;
1664 pFormat += 8 * count;
1668 /***********************************************************************
1669 * NdrPointerMarshall [RPCRT4.@]
1671 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1672 unsigned char *pMemory,
1673 PFORMAT_STRING pFormat)
1675 unsigned char *Buffer;
1677 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1679 /* incremement the buffer here instead of in PointerMarshall,
1680 * as that is used by embedded pointers which already handle the incrementing
1681 * the buffer, and shouldn't write any additional pointer data to the wire */
1682 if (*pFormat != RPC_FC_RP)
1684 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
1685 Buffer = pStubMsg->Buffer;
1686 safe_buffer_increment(pStubMsg, 4);
1689 Buffer = pStubMsg->Buffer;
1691 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1696 /***********************************************************************
1697 * NdrPointerUnmarshall [RPCRT4.@]
1699 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1700 unsigned char **ppMemory,
1701 PFORMAT_STRING pFormat,
1702 unsigned char fMustAlloc)
1704 unsigned char *Buffer;
1706 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1708 /* incremement the buffer here instead of in PointerUnmarshall,
1709 * as that is used by embedded pointers which already handle the incrementing
1710 * the buffer, and shouldn't read any additional pointer data from the
1712 if (*pFormat != RPC_FC_RP)
1714 ALIGN_POINTER(pStubMsg->Buffer, 4);
1715 Buffer = pStubMsg->Buffer;
1716 safe_buffer_increment(pStubMsg, 4);
1719 Buffer = pStubMsg->Buffer;
1721 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1726 /***********************************************************************
1727 * NdrPointerBufferSize [RPCRT4.@]
1729 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1730 unsigned char *pMemory,
1731 PFORMAT_STRING pFormat)
1733 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1735 /* incremement the buffer length here instead of in PointerBufferSize,
1736 * as that is used by embedded pointers which already handle the buffer
1737 * length, and shouldn't write anything more to the wire */
1738 if (*pFormat != RPC_FC_RP)
1740 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1741 safe_buffer_length_increment(pStubMsg, 4);
1744 PointerBufferSize(pStubMsg, pMemory, pFormat);
1747 /***********************************************************************
1748 * NdrPointerMemorySize [RPCRT4.@]
1750 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1751 PFORMAT_STRING pFormat)
1753 /* unsigned size = *(LPWORD)(pFormat+2); */
1754 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1755 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1759 /***********************************************************************
1760 * NdrPointerFree [RPCRT4.@]
1762 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1763 unsigned char *pMemory,
1764 PFORMAT_STRING pFormat)
1766 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1767 PointerFree(pStubMsg, pMemory, pFormat);
1770 /***********************************************************************
1771 * NdrSimpleTypeMarshall [RPCRT4.@]
1773 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1774 unsigned char FormatChar )
1776 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1779 /***********************************************************************
1780 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1782 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1783 unsigned char FormatChar )
1785 NdrBaseTypeUnmarshall(pStubMsg, &pMemory, &FormatChar, 0);
1788 /***********************************************************************
1789 * NdrSimpleStructMarshall [RPCRT4.@]
1791 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1792 unsigned char *pMemory,
1793 PFORMAT_STRING pFormat)
1795 unsigned size = *(const WORD*)(pFormat+2);
1796 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1798 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
1800 pStubMsg->BufferMark = pStubMsg->Buffer;
1801 safe_copy_to_buffer(pStubMsg, pMemory, size);
1803 if (pFormat[0] != RPC_FC_STRUCT)
1804 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1809 /***********************************************************************
1810 * NdrSimpleStructUnmarshall [RPCRT4.@]
1812 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1813 unsigned char **ppMemory,
1814 PFORMAT_STRING pFormat,
1815 unsigned char fMustAlloc)
1817 unsigned size = *(const WORD*)(pFormat+2);
1818 unsigned char *saved_buffer;
1819 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1821 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1824 *ppMemory = NdrAllocate(pStubMsg, size);
1827 if (!pStubMsg->IsClient && !*ppMemory)
1828 /* for servers, we just point straight into the RPC buffer */
1829 *ppMemory = pStubMsg->Buffer;
1832 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1833 safe_buffer_increment(pStubMsg, size);
1834 if (pFormat[0] == RPC_FC_PSTRUCT)
1835 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1837 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1838 if (*ppMemory != saved_buffer)
1839 memcpy(*ppMemory, saved_buffer, size);
1844 /***********************************************************************
1845 * NdrSimpleStructBufferSize [RPCRT4.@]
1847 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1848 unsigned char *pMemory,
1849 PFORMAT_STRING pFormat)
1851 unsigned size = *(const WORD*)(pFormat+2);
1852 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1854 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1856 safe_buffer_length_increment(pStubMsg, size);
1857 if (pFormat[0] != RPC_FC_STRUCT)
1858 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1861 /***********************************************************************
1862 * NdrSimpleStructMemorySize [RPCRT4.@]
1864 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1865 PFORMAT_STRING pFormat)
1867 unsigned short size = *(const WORD *)(pFormat+2);
1869 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1871 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1872 pStubMsg->MemorySize += size;
1873 safe_buffer_increment(pStubMsg, size);
1875 if (pFormat[0] != RPC_FC_STRUCT)
1876 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1877 return pStubMsg->MemorySize;
1880 /***********************************************************************
1881 * NdrSimpleStructFree [RPCRT4.@]
1883 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1884 unsigned char *pMemory,
1885 PFORMAT_STRING pFormat)
1887 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1888 if (pFormat[0] != RPC_FC_STRUCT)
1889 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1893 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE *pStubMsg,
1894 PFORMAT_STRING pFormat)
1898 case RPC_FC_PSTRUCT:
1899 case RPC_FC_CSTRUCT:
1900 case RPC_FC_BOGUS_STRUCT:
1901 case RPC_FC_SMFARRAY:
1902 case RPC_FC_SMVARRAY:
1903 return *(const WORD*)&pFormat[2];
1904 case RPC_FC_USER_MARSHAL:
1905 return *(const WORD*)&pFormat[4];
1906 case RPC_FC_NON_ENCAPSULATED_UNION:
1908 if (pStubMsg->fHasNewCorrDesc)
1913 pFormat += *(const SHORT*)pFormat;
1914 return *(const SHORT*)pFormat;
1916 return sizeof(void *);
1918 FIXME("unhandled embedded type %02x\n", *pFormat);
1924 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1925 PFORMAT_STRING pFormat)
1927 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1931 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1935 return m(pStubMsg, pFormat);
1939 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1940 unsigned char *pMemory,
1941 PFORMAT_STRING pFormat,
1942 PFORMAT_STRING pPointer)
1944 PFORMAT_STRING desc;
1948 while (*pFormat != RPC_FC_END) {
1954 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
1955 safe_copy_to_buffer(pStubMsg, pMemory, 1);
1961 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1962 safe_copy_to_buffer(pStubMsg, pMemory, 2);
1968 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
1969 safe_copy_to_buffer(pStubMsg, pMemory, 4);
1973 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1974 safe_copy_to_buffer(pStubMsg, pMemory, 8);
1977 case RPC_FC_POINTER:
1979 unsigned char *saved_buffer;
1980 int pointer_buffer_mark_set = 0;
1981 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1982 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
1983 saved_buffer = pStubMsg->Buffer;
1984 if (pStubMsg->PointerBufferMark)
1986 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1987 pStubMsg->PointerBufferMark = NULL;
1988 pointer_buffer_mark_set = 1;
1991 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
1992 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
1993 if (pointer_buffer_mark_set)
1995 STD_OVERFLOW_CHECK(pStubMsg);
1996 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1997 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
1999 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2000 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2001 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2003 pStubMsg->Buffer = saved_buffer + 4;
2009 case RPC_FC_ALIGNM4:
2010 ALIGN_POINTER_CLEAR(pMemory, 4);
2012 case RPC_FC_ALIGNM8:
2013 ALIGN_POINTER_CLEAR(pMemory, 8);
2015 case RPC_FC_STRUCTPAD1:
2016 case RPC_FC_STRUCTPAD2:
2017 case RPC_FC_STRUCTPAD3:
2018 case RPC_FC_STRUCTPAD4:
2019 case RPC_FC_STRUCTPAD5:
2020 case RPC_FC_STRUCTPAD6:
2021 case RPC_FC_STRUCTPAD7:
2022 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2024 case RPC_FC_EMBEDDED_COMPLEX:
2025 pMemory += pFormat[1];
2027 desc = pFormat + *(const SHORT*)pFormat;
2028 size = EmbeddedComplexSize(pStubMsg, desc);
2029 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
2030 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2033 /* for some reason interface pointers aren't generated as
2034 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2035 * they still need the derefencing treatment that pointers are
2037 if (*desc == RPC_FC_IP)
2038 m(pStubMsg, *(unsigned char **)pMemory, desc);
2040 m(pStubMsg, pMemory, desc);
2042 else FIXME("no marshaller for embedded type %02x\n", *desc);
2049 FIXME("unhandled format 0x%02x\n", *pFormat);
2057 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2058 unsigned char *pMemory,
2059 PFORMAT_STRING pFormat,
2060 PFORMAT_STRING pPointer)
2062 PFORMAT_STRING desc;
2066 while (*pFormat != RPC_FC_END) {
2072 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2073 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2079 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2080 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2086 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2087 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2091 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2092 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2095 case RPC_FC_POINTER:
2097 unsigned char *saved_buffer;
2098 int pointer_buffer_mark_set = 0;
2099 TRACE("pointer => %p\n", pMemory);
2100 ALIGN_POINTER(pStubMsg->Buffer, 4);
2101 saved_buffer = pStubMsg->Buffer;
2102 if (pStubMsg->PointerBufferMark)
2104 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2105 pStubMsg->PointerBufferMark = NULL;
2106 pointer_buffer_mark_set = 1;
2109 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2111 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, TRUE);
2112 if (pointer_buffer_mark_set)
2114 STD_OVERFLOW_CHECK(pStubMsg);
2115 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2116 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2118 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2119 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2120 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2122 pStubMsg->Buffer = saved_buffer + 4;
2128 case RPC_FC_ALIGNM4:
2129 ALIGN_POINTER(pMemory, 4);
2131 case RPC_FC_ALIGNM8:
2132 ALIGN_POINTER(pMemory, 8);
2134 case RPC_FC_STRUCTPAD1:
2135 case RPC_FC_STRUCTPAD2:
2136 case RPC_FC_STRUCTPAD3:
2137 case RPC_FC_STRUCTPAD4:
2138 case RPC_FC_STRUCTPAD5:
2139 case RPC_FC_STRUCTPAD6:
2140 case RPC_FC_STRUCTPAD7:
2141 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2143 case RPC_FC_EMBEDDED_COMPLEX:
2144 pMemory += pFormat[1];
2146 desc = pFormat + *(const SHORT*)pFormat;
2147 size = EmbeddedComplexSize(pStubMsg, desc);
2148 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2149 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2150 memset(pMemory, 0, size); /* just in case */
2153 /* for some reason interface pointers aren't generated as
2154 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2155 * they still need the derefencing treatment that pointers are
2157 if (*desc == RPC_FC_IP)
2158 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2160 m(pStubMsg, &pMemory, desc, FALSE);
2162 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2169 FIXME("unhandled format %d\n", *pFormat);
2177 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2178 unsigned char *pMemory,
2179 PFORMAT_STRING pFormat,
2180 PFORMAT_STRING pPointer)
2182 PFORMAT_STRING desc;
2186 while (*pFormat != RPC_FC_END) {
2192 safe_buffer_length_increment(pStubMsg, 1);
2198 safe_buffer_length_increment(pStubMsg, 2);
2204 safe_buffer_length_increment(pStubMsg, 4);
2208 safe_buffer_length_increment(pStubMsg, 8);
2211 case RPC_FC_POINTER:
2212 if (!pStubMsg->IgnoreEmbeddedPointers)
2214 int saved_buffer_length = pStubMsg->BufferLength;
2215 pStubMsg->BufferLength = pStubMsg->PointerLength;
2216 pStubMsg->PointerLength = 0;
2217 if(!pStubMsg->BufferLength)
2218 ERR("BufferLength == 0??\n");
2219 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2220 pStubMsg->PointerLength = pStubMsg->BufferLength;
2221 pStubMsg->BufferLength = saved_buffer_length;
2223 safe_buffer_length_increment(pStubMsg, 4);
2227 case RPC_FC_ALIGNM4:
2228 ALIGN_POINTER(pMemory, 4);
2230 case RPC_FC_ALIGNM8:
2231 ALIGN_POINTER(pMemory, 8);
2233 case RPC_FC_STRUCTPAD1:
2234 case RPC_FC_STRUCTPAD2:
2235 case RPC_FC_STRUCTPAD3:
2236 case RPC_FC_STRUCTPAD4:
2237 case RPC_FC_STRUCTPAD5:
2238 case RPC_FC_STRUCTPAD6:
2239 case RPC_FC_STRUCTPAD7:
2240 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2242 case RPC_FC_EMBEDDED_COMPLEX:
2243 pMemory += pFormat[1];
2245 desc = pFormat + *(const SHORT*)pFormat;
2246 size = EmbeddedComplexSize(pStubMsg, desc);
2247 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2250 /* for some reason interface pointers aren't generated as
2251 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2252 * they still need the derefencing treatment that pointers are
2254 if (*desc == RPC_FC_IP)
2255 m(pStubMsg, *(unsigned char **)pMemory, desc);
2257 m(pStubMsg, pMemory, desc);
2259 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2266 FIXME("unhandled format 0x%02x\n", *pFormat);
2274 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2275 unsigned char *pMemory,
2276 PFORMAT_STRING pFormat,
2277 PFORMAT_STRING pPointer)
2279 PFORMAT_STRING desc;
2283 while (*pFormat != RPC_FC_END) {
2304 case RPC_FC_POINTER:
2305 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
2309 case RPC_FC_ALIGNM4:
2310 ALIGN_POINTER(pMemory, 4);
2312 case RPC_FC_ALIGNM8:
2313 ALIGN_POINTER(pMemory, 8);
2315 case RPC_FC_STRUCTPAD1:
2316 case RPC_FC_STRUCTPAD2:
2317 case RPC_FC_STRUCTPAD3:
2318 case RPC_FC_STRUCTPAD4:
2319 case RPC_FC_STRUCTPAD5:
2320 case RPC_FC_STRUCTPAD6:
2321 case RPC_FC_STRUCTPAD7:
2322 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2324 case RPC_FC_EMBEDDED_COMPLEX:
2325 pMemory += pFormat[1];
2327 desc = pFormat + *(const SHORT*)pFormat;
2328 size = EmbeddedComplexSize(pStubMsg, desc);
2329 m = NdrFreer[*desc & NDR_TABLE_MASK];
2332 /* for some reason interface pointers aren't generated as
2333 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2334 * they still need the derefencing treatment that pointers are
2336 if (*desc == RPC_FC_IP)
2337 m(pStubMsg, *(unsigned char **)pMemory, desc);
2339 m(pStubMsg, pMemory, desc);
2341 else FIXME("no freer for embedded type %02x\n", *desc);
2348 FIXME("unhandled format 0x%02x\n", *pFormat);
2356 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2357 PFORMAT_STRING pFormat)
2359 PFORMAT_STRING desc;
2360 unsigned long size = 0;
2362 while (*pFormat != RPC_FC_END) {
2369 safe_buffer_increment(pStubMsg, 1);
2375 safe_buffer_increment(pStubMsg, 2);
2381 safe_buffer_increment(pStubMsg, 4);
2385 safe_buffer_increment(pStubMsg, 8);
2387 case RPC_FC_POINTER:
2389 safe_buffer_increment(pStubMsg, 4);
2390 if (!pStubMsg->IgnoreEmbeddedPointers)
2391 FIXME("embedded pointers\n");
2393 case RPC_FC_ALIGNM4:
2394 ALIGN_LENGTH(size, 4);
2395 ALIGN_POINTER(pStubMsg->Buffer, 4);
2397 case RPC_FC_ALIGNM8:
2398 ALIGN_LENGTH(size, 8);
2399 ALIGN_POINTER(pStubMsg->Buffer, 8);
2401 case RPC_FC_STRUCTPAD1:
2402 case RPC_FC_STRUCTPAD2:
2403 case RPC_FC_STRUCTPAD3:
2404 case RPC_FC_STRUCTPAD4:
2405 case RPC_FC_STRUCTPAD5:
2406 case RPC_FC_STRUCTPAD6:
2407 case RPC_FC_STRUCTPAD7:
2408 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2410 case RPC_FC_EMBEDDED_COMPLEX:
2413 desc = pFormat + *(const SHORT*)pFormat;
2414 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2420 FIXME("unhandled format 0x%02x\n", *pFormat);
2428 /***********************************************************************
2429 * NdrComplexStructMarshall [RPCRT4.@]
2431 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2432 unsigned char *pMemory,
2433 PFORMAT_STRING pFormat)
2435 PFORMAT_STRING conf_array = NULL;
2436 PFORMAT_STRING pointer_desc = NULL;
2437 unsigned char *OldMemory = pStubMsg->Memory;
2438 int pointer_buffer_mark_set = 0;
2440 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2442 if (!pStubMsg->PointerBufferMark)
2444 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2445 /* save buffer length */
2446 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2448 /* get the buffer pointer after complex array data, but before
2450 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2451 pStubMsg->IgnoreEmbeddedPointers = 1;
2452 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2453 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2455 /* save it for use by embedded pointer code later */
2456 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2457 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
2458 pointer_buffer_mark_set = 1;
2460 /* restore the original buffer length */
2461 pStubMsg->BufferLength = saved_buffer_length;
2464 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
2467 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2469 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2472 pStubMsg->Memory = pMemory;
2474 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2477 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2479 pStubMsg->Memory = OldMemory;
2481 if (pointer_buffer_mark_set)
2483 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2484 pStubMsg->PointerBufferMark = NULL;
2487 STD_OVERFLOW_CHECK(pStubMsg);
2492 /***********************************************************************
2493 * NdrComplexStructUnmarshall [RPCRT4.@]
2495 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2496 unsigned char **ppMemory,
2497 PFORMAT_STRING pFormat,
2498 unsigned char fMustAlloc)
2500 unsigned size = *(const WORD*)(pFormat+2);
2501 PFORMAT_STRING conf_array = NULL;
2502 PFORMAT_STRING pointer_desc = NULL;
2503 unsigned char *pMemory;
2504 int pointer_buffer_mark_set = 0;
2506 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2508 if (!pStubMsg->PointerBufferMark)
2510 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2511 /* save buffer pointer */
2512 unsigned char *saved_buffer = pStubMsg->Buffer;
2514 /* get the buffer pointer after complex array data, but before
2516 pStubMsg->IgnoreEmbeddedPointers = 1;
2517 NdrComplexStructMemorySize(pStubMsg, pFormat);
2518 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2520 /* save it for use by embedded pointer code later */
2521 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2522 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
2523 pointer_buffer_mark_set = 1;
2525 /* restore the original buffer */
2526 pStubMsg->Buffer = saved_buffer;
2529 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2531 if (fMustAlloc || !*ppMemory)
2533 *ppMemory = NdrAllocate(pStubMsg, size);
2534 memset(*ppMemory, 0, size);
2538 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2540 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2543 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2546 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2548 if (pointer_buffer_mark_set)
2550 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2551 pStubMsg->PointerBufferMark = NULL;
2557 /***********************************************************************
2558 * NdrComplexStructBufferSize [RPCRT4.@]
2560 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2561 unsigned char *pMemory,
2562 PFORMAT_STRING pFormat)
2564 PFORMAT_STRING conf_array = NULL;
2565 PFORMAT_STRING pointer_desc = NULL;
2566 unsigned char *OldMemory = pStubMsg->Memory;
2567 int pointer_length_set = 0;
2569 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2571 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2573 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2575 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2576 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2578 /* get the buffer length after complex struct data, but before
2580 pStubMsg->IgnoreEmbeddedPointers = 1;
2581 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2582 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2584 /* save it for use by embedded pointer code later */
2585 pStubMsg->PointerLength = pStubMsg->BufferLength;
2586 pointer_length_set = 1;
2587 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
2589 /* restore the original buffer length */
2590 pStubMsg->BufferLength = saved_buffer_length;
2594 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2596 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2599 pStubMsg->Memory = pMemory;
2601 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2604 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2606 pStubMsg->Memory = OldMemory;
2608 if(pointer_length_set)
2610 pStubMsg->BufferLength = pStubMsg->PointerLength;
2611 pStubMsg->PointerLength = 0;
2616 /***********************************************************************
2617 * NdrComplexStructMemorySize [RPCRT4.@]
2619 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2620 PFORMAT_STRING pFormat)
2622 unsigned size = *(const WORD*)(pFormat+2);
2623 PFORMAT_STRING conf_array = NULL;
2624 PFORMAT_STRING pointer_desc = NULL;
2626 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2628 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2631 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2633 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2636 ComplexStructMemorySize(pStubMsg, pFormat);
2639 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2644 /***********************************************************************
2645 * NdrComplexStructFree [RPCRT4.@]
2647 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2648 unsigned char *pMemory,
2649 PFORMAT_STRING pFormat)
2651 PFORMAT_STRING conf_array = NULL;
2652 PFORMAT_STRING pointer_desc = NULL;
2653 unsigned char *OldMemory = pStubMsg->Memory;
2655 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2658 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2660 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2663 pStubMsg->Memory = pMemory;
2665 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2668 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2670 pStubMsg->Memory = OldMemory;
2673 /***********************************************************************
2674 * NdrConformantArrayMarshall [RPCRT4.@]
2676 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2677 unsigned char *pMemory,
2678 PFORMAT_STRING pFormat)
2680 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2681 unsigned char alignment = pFormat[1] + 1;
2683 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2684 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2686 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2688 WriteConformance(pStubMsg);
2690 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
2692 size = safe_multiply(esize, pStubMsg->MaxCount);
2693 pStubMsg->BufferMark = pStubMsg->Buffer;
2694 safe_copy_to_buffer(pStubMsg, pMemory, size);
2696 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2701 /***********************************************************************
2702 * NdrConformantArrayUnmarshall [RPCRT4.@]
2704 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2705 unsigned char **ppMemory,
2706 PFORMAT_STRING pFormat,
2707 unsigned char fMustAlloc)
2709 DWORD size, esize = *(const WORD*)(pFormat+2);
2710 unsigned char alignment = pFormat[1] + 1;
2711 unsigned char *saved_buffer;
2713 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2714 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2716 pFormat = ReadConformance(pStubMsg, pFormat+4);
2718 size = safe_multiply(esize, pStubMsg->MaxCount);
2719 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2722 *ppMemory = NdrAllocate(pStubMsg, size);
2725 if (!pStubMsg->IsClient && !*ppMemory)
2726 /* for servers, we just point straight into the RPC buffer */
2727 *ppMemory = pStubMsg->Buffer;
2730 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
2731 safe_buffer_increment(pStubMsg, size);
2732 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2734 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2735 if (*ppMemory != saved_buffer)
2736 memcpy(*ppMemory, saved_buffer, size);
2741 /***********************************************************************
2742 * NdrConformantArrayBufferSize [RPCRT4.@]
2744 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2745 unsigned char *pMemory,
2746 PFORMAT_STRING pFormat)
2748 DWORD size, esize = *(const WORD*)(pFormat+2);
2749 unsigned char alignment = pFormat[1] + 1;
2751 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2752 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2754 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2756 SizeConformance(pStubMsg);
2758 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2760 size = safe_multiply(esize, pStubMsg->MaxCount);
2761 /* conformance value plus array */
2762 safe_buffer_length_increment(pStubMsg, size);
2764 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2767 /***********************************************************************
2768 * NdrConformantArrayMemorySize [RPCRT4.@]
2770 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2771 PFORMAT_STRING pFormat)
2773 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2774 unsigned char alignment = pFormat[1] + 1;
2776 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2777 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2779 pFormat = ReadConformance(pStubMsg, pFormat+4);
2780 size = safe_multiply(esize, pStubMsg->MaxCount);
2781 pStubMsg->MemorySize += size;
2783 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2784 pStubMsg->BufferMark = pStubMsg->Buffer;
2785 safe_buffer_increment(pStubMsg, size);
2787 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2789 return pStubMsg->MemorySize;
2792 /***********************************************************************
2793 * NdrConformantArrayFree [RPCRT4.@]
2795 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2796 unsigned char *pMemory,
2797 PFORMAT_STRING pFormat)
2799 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2800 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2802 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2804 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2808 /***********************************************************************
2809 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2811 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2812 unsigned char* pMemory,
2813 PFORMAT_STRING pFormat )
2816 unsigned char alignment = pFormat[1] + 1;
2817 DWORD esize = *(const WORD*)(pFormat+2);
2819 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2821 if (pFormat[0] != RPC_FC_CVARRAY)
2823 ERR("invalid format type %x\n", pFormat[0]);
2824 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2828 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2829 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2831 WriteConformance(pStubMsg);
2832 WriteVariance(pStubMsg);
2834 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
2836 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2838 pStubMsg->BufferMark = pStubMsg->Buffer;
2839 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
2841 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2847 /***********************************************************************
2848 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2850 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2851 unsigned char** ppMemory,
2852 PFORMAT_STRING pFormat,
2853 unsigned char fMustAlloc )
2855 ULONG bufsize, memsize;
2856 unsigned char alignment = pFormat[1] + 1;
2857 DWORD esize = *(const WORD*)(pFormat+2);
2859 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2861 if (pFormat[0] != RPC_FC_CVARRAY)
2863 ERR("invalid format type %x\n", pFormat[0]);
2864 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2868 pFormat = ReadConformance(pStubMsg, pFormat+4);
2869 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2871 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2873 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2874 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2876 if (!*ppMemory || fMustAlloc)
2877 *ppMemory = NdrAllocate(pStubMsg, memsize);
2878 safe_copy_from_buffer(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize);
2880 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
2886 /***********************************************************************
2887 * NdrConformantVaryingArrayFree [RPCRT4.@]
2889 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2890 unsigned char* pMemory,
2891 PFORMAT_STRING pFormat )
2893 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2895 if (pFormat[0] != RPC_FC_CVARRAY)
2897 ERR("invalid format type %x\n", pFormat[0]);
2898 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2902 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2903 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2905 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2909 /***********************************************************************
2910 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2912 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2913 unsigned char* pMemory, PFORMAT_STRING pFormat )
2915 unsigned char alignment = pFormat[1] + 1;
2916 DWORD esize = *(const WORD*)(pFormat+2);
2918 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2920 if (pFormat[0] != RPC_FC_CVARRAY)
2922 ERR("invalid format type %x\n", pFormat[0]);
2923 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2928 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2929 /* compute length */
2930 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2932 SizeConformance(pStubMsg);
2933 SizeVariance(pStubMsg);
2935 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2937 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2939 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2943 /***********************************************************************
2944 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2946 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2947 PFORMAT_STRING pFormat )
2949 ULONG bufsize, memsize;
2950 unsigned char alignment = pFormat[1] + 1;
2951 DWORD esize = *(const WORD*)(pFormat+2);
2953 TRACE("(%p, %p)\n", pStubMsg, pFormat);
2955 if (pFormat[0] != RPC_FC_CVARRAY)
2957 ERR("invalid format type %x\n", pFormat[0]);
2958 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2959 return pStubMsg->MemorySize;
2962 pFormat = ReadConformance(pStubMsg, pFormat+4);
2963 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2965 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2967 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2968 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2970 safe_buffer_increment(pStubMsg, bufsize);
2971 pStubMsg->MemorySize += memsize;
2973 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2975 return pStubMsg->MemorySize;
2979 /***********************************************************************
2980 * NdrComplexArrayMarshall [RPCRT4.@]
2982 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2983 unsigned char *pMemory,
2984 PFORMAT_STRING pFormat)
2986 ULONG i, count, def;
2987 BOOL variance_present;
2988 unsigned char alignment;
2989 int pointer_buffer_mark_set = 0;
2991 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2993 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2995 ERR("invalid format type %x\n", pFormat[0]);
2996 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3000 alignment = pFormat[1] + 1;
3002 if (!pStubMsg->PointerBufferMark)
3004 /* save buffer fields that may be changed by buffer sizer functions
3005 * and that may be needed later on */
3006 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3007 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3008 unsigned long saved_max_count = pStubMsg->MaxCount;
3009 unsigned long saved_offset = pStubMsg->Offset;
3010 unsigned long saved_actual_count = pStubMsg->ActualCount;
3012 /* get the buffer pointer after complex array data, but before
3014 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3015 pStubMsg->IgnoreEmbeddedPointers = 1;
3016 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3017 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3019 /* save it for use by embedded pointer code later */
3020 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3021 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
3022 pointer_buffer_mark_set = 1;
3024 /* restore fields */
3025 pStubMsg->ActualCount = saved_actual_count;
3026 pStubMsg->Offset = saved_offset;
3027 pStubMsg->MaxCount = saved_max_count;
3028 pStubMsg->BufferLength = saved_buffer_length;
3031 def = *(const WORD*)&pFormat[2];
3034 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3035 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3037 variance_present = IsConformanceOrVariancePresent(pFormat);
3038 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3039 TRACE("variance = %d\n", pStubMsg->ActualCount);
3041 WriteConformance(pStubMsg);
3042 if (variance_present)
3043 WriteVariance(pStubMsg);
3045 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3047 count = pStubMsg->ActualCount;
3048 for (i = 0; i < count; i++)
3049 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3051 STD_OVERFLOW_CHECK(pStubMsg);
3053 if (pointer_buffer_mark_set)
3055 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3056 pStubMsg->PointerBufferMark = NULL;
3062 /***********************************************************************
3063 * NdrComplexArrayUnmarshall [RPCRT4.@]
3065 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3066 unsigned char **ppMemory,
3067 PFORMAT_STRING pFormat,
3068 unsigned char fMustAlloc)
3070 ULONG i, count, size;
3071 unsigned char alignment;
3072 unsigned char *pMemory;
3073 unsigned char *saved_buffer;
3074 int pointer_buffer_mark_set = 0;
3075 int saved_ignore_embedded;
3077 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3079 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3081 ERR("invalid format type %x\n", pFormat[0]);
3082 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3086 alignment = pFormat[1] + 1;
3088 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3089 /* save buffer pointer */
3090 saved_buffer = pStubMsg->Buffer;
3091 /* get the buffer pointer after complex array data, but before
3093 pStubMsg->IgnoreEmbeddedPointers = 1;
3094 pStubMsg->MemorySize = 0;
3095 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3096 size = pStubMsg->MemorySize;
3097 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3099 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
3100 if (!pStubMsg->PointerBufferMark)
3102 /* save it for use by embedded pointer code later */
3103 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3104 pointer_buffer_mark_set = 1;
3106 /* restore the original buffer */
3107 pStubMsg->Buffer = saved_buffer;
3111 pFormat = ReadConformance(pStubMsg, pFormat);
3112 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3114 if (fMustAlloc || !*ppMemory)
3116 *ppMemory = NdrAllocate(pStubMsg, size);
3117 memset(*ppMemory, 0, size);
3120 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3122 pMemory = *ppMemory;
3123 count = pStubMsg->ActualCount;
3124 for (i = 0; i < count; i++)
3125 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
3127 if (pointer_buffer_mark_set)
3129 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3130 pStubMsg->PointerBufferMark = NULL;
3136 /***********************************************************************
3137 * NdrComplexArrayBufferSize [RPCRT4.@]
3139 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3140 unsigned char *pMemory,
3141 PFORMAT_STRING pFormat)
3143 ULONG i, count, def;
3144 unsigned char alignment;
3145 BOOL variance_present;
3146 int pointer_length_set = 0;
3148 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3150 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3152 ERR("invalid format type %x\n", pFormat[0]);
3153 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3157 alignment = pFormat[1] + 1;
3159 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3161 /* save buffer fields that may be changed by buffer sizer functions
3162 * and that may be needed later on */
3163 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3164 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3165 unsigned long saved_max_count = pStubMsg->MaxCount;
3166 unsigned long saved_offset = pStubMsg->Offset;
3167 unsigned long saved_actual_count = pStubMsg->ActualCount;
3169 /* get the buffer pointer after complex array data, but before
3171 pStubMsg->IgnoreEmbeddedPointers = 1;
3172 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3173 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3175 /* save it for use by embedded pointer code later */
3176 pStubMsg->PointerLength = pStubMsg->BufferLength;
3177 pointer_length_set = 1;
3179 /* restore fields */
3180 pStubMsg->ActualCount = saved_actual_count;
3181 pStubMsg->Offset = saved_offset;
3182 pStubMsg->MaxCount = saved_max_count;
3183 pStubMsg->BufferLength = saved_buffer_length;
3185 def = *(const WORD*)&pFormat[2];
3188 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3189 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3190 SizeConformance(pStubMsg);
3192 variance_present = IsConformanceOrVariancePresent(pFormat);
3193 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3194 TRACE("variance = %d\n", pStubMsg->ActualCount);
3196 if (variance_present)
3197 SizeVariance(pStubMsg);
3199 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3201 count = pStubMsg->ActualCount;
3202 for (i = 0; i < count; i++)
3203 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
3205 if(pointer_length_set)
3207 pStubMsg->BufferLength = pStubMsg->PointerLength;
3208 pStubMsg->PointerLength = 0;
3212 /***********************************************************************
3213 * NdrComplexArrayMemorySize [RPCRT4.@]
3215 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3216 PFORMAT_STRING pFormat)
3218 ULONG i, count, esize, SavedMemorySize, MemorySize;
3219 unsigned char alignment;
3220 unsigned char *Buffer;
3222 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3224 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3226 ERR("invalid format type %x\n", pFormat[0]);
3227 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3231 alignment = pFormat[1] + 1;
3235 pFormat = ReadConformance(pStubMsg, pFormat);
3236 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3238 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3240 SavedMemorySize = pStubMsg->MemorySize;
3242 Buffer = pStubMsg->Buffer;
3243 pStubMsg->MemorySize = 0;
3244 esize = ComplexStructMemorySize(pStubMsg, pFormat);
3245 pStubMsg->Buffer = Buffer;
3247 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
3249 count = pStubMsg->ActualCount;
3250 for (i = 0; i < count; i++)
3251 ComplexStructMemorySize(pStubMsg, pFormat);
3253 pStubMsg->MemorySize = SavedMemorySize;
3255 pStubMsg->MemorySize += MemorySize;
3259 /***********************************************************************
3260 * NdrComplexArrayFree [RPCRT4.@]
3262 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3263 unsigned char *pMemory,
3264 PFORMAT_STRING pFormat)
3266 ULONG i, count, def;
3268 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3270 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3272 ERR("invalid format type %x\n", pFormat[0]);
3273 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3277 def = *(const WORD*)&pFormat[2];
3280 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3281 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3283 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3284 TRACE("variance = %d\n", pStubMsg->ActualCount);
3286 count = pStubMsg->ActualCount;
3287 for (i = 0; i < count; i++)
3288 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
3291 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
3292 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
3293 USER_MARSHAL_CB *umcb)
3295 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
3296 pStubMsg->RpcMsg->DataRepresentation);
3297 umcb->pStubMsg = pStubMsg;
3298 umcb->pReserve = NULL;
3299 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
3300 umcb->CBType = cbtype;
3301 umcb->pFormat = pFormat;
3302 umcb->pTypeFormat = NULL /* FIXME */;
3305 #define USER_MARSHAL_PTR_PREFIX \
3306 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3307 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3309 /***********************************************************************
3310 * NdrUserMarshalMarshall [RPCRT4.@]
3312 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3313 unsigned char *pMemory,
3314 PFORMAT_STRING pFormat)
3316 unsigned flags = pFormat[1];
3317 unsigned index = *(const WORD*)&pFormat[2];
3318 unsigned char *saved_buffer = NULL;
3319 USER_MARSHAL_CB umcb;
3321 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3322 TRACE("index=%d\n", index);
3324 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
3326 if (flags & USER_MARSHAL_POINTER)
3328 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
3329 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
3330 pStubMsg->Buffer += 4;
3331 if (pStubMsg->PointerBufferMark)
3333 saved_buffer = pStubMsg->Buffer;
3334 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3335 pStubMsg->PointerBufferMark = NULL;
3337 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
3340 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
3343 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
3344 &umcb.Flags, pStubMsg->Buffer, pMemory);
3348 STD_OVERFLOW_CHECK(pStubMsg);
3349 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3350 pStubMsg->Buffer = saved_buffer;
3353 STD_OVERFLOW_CHECK(pStubMsg);
3358 /***********************************************************************
3359 * NdrUserMarshalUnmarshall [RPCRT4.@]
3361 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3362 unsigned char **ppMemory,
3363 PFORMAT_STRING pFormat,
3364 unsigned char fMustAlloc)
3366 unsigned flags = pFormat[1];
3367 unsigned index = *(const WORD*)&pFormat[2];
3368 DWORD memsize = *(const WORD*)&pFormat[4];
3369 unsigned char *saved_buffer = NULL;
3370 USER_MARSHAL_CB umcb;
3372 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3373 TRACE("index=%d\n", index);
3375 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
3377 if (flags & USER_MARSHAL_POINTER)
3379 ALIGN_POINTER(pStubMsg->Buffer, 4);
3380 /* skip pointer prefix */
3381 pStubMsg->Buffer += 4;
3382 if (pStubMsg->PointerBufferMark)
3384 saved_buffer = pStubMsg->Buffer;
3385 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3386 pStubMsg->PointerBufferMark = NULL;
3388 ALIGN_POINTER(pStubMsg->Buffer, 8);
3391 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3393 if (fMustAlloc || !*ppMemory)
3394 *ppMemory = NdrAllocate(pStubMsg, memsize);
3397 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
3398 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
3402 STD_OVERFLOW_CHECK(pStubMsg);
3403 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3404 pStubMsg->Buffer = saved_buffer;
3410 /***********************************************************************
3411 * NdrUserMarshalBufferSize [RPCRT4.@]
3413 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3414 unsigned char *pMemory,
3415 PFORMAT_STRING pFormat)
3417 unsigned flags = pFormat[1];
3418 unsigned index = *(const WORD*)&pFormat[2];
3419 DWORD bufsize = *(const WORD*)&pFormat[6];
3420 USER_MARSHAL_CB umcb;
3421 unsigned long saved_buffer_length = 0;
3423 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3424 TRACE("index=%d\n", index);
3426 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
3428 if (flags & USER_MARSHAL_POINTER)
3430 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3431 /* skip pointer prefix */
3432 safe_buffer_length_increment(pStubMsg, 4);
3433 if (pStubMsg->IgnoreEmbeddedPointers)
3435 if (pStubMsg->PointerLength)
3437 saved_buffer_length = pStubMsg->BufferLength;
3438 pStubMsg->BufferLength = pStubMsg->PointerLength;
3439 pStubMsg->PointerLength = 0;
3441 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
3444 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
3447 TRACE("size=%d\n", bufsize);
3448 safe_buffer_length_increment(pStubMsg, bufsize);
3451 pStubMsg->BufferLength =
3452 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
3453 &umcb.Flags, pStubMsg->BufferLength, pMemory);
3455 if (saved_buffer_length)
3457 pStubMsg->PointerLength = pStubMsg->BufferLength;
3458 pStubMsg->BufferLength = saved_buffer_length;
3463 /***********************************************************************
3464 * NdrUserMarshalMemorySize [RPCRT4.@]
3466 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3467 PFORMAT_STRING pFormat)
3469 unsigned flags = pFormat[1];
3470 unsigned index = *(const WORD*)&pFormat[2];
3471 DWORD memsize = *(const WORD*)&pFormat[4];
3472 DWORD bufsize = *(const WORD*)&pFormat[6];
3474 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3475 TRACE("index=%d\n", index);
3477 pStubMsg->MemorySize += memsize;
3479 if (flags & USER_MARSHAL_POINTER)
3481 ALIGN_POINTER(pStubMsg->Buffer, 4);
3482 /* skip pointer prefix */
3483 pStubMsg->Buffer += 4;
3484 if (pStubMsg->IgnoreEmbeddedPointers)
3485 return pStubMsg->MemorySize;
3486 ALIGN_POINTER(pStubMsg->Buffer, 8);
3489 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3492 FIXME("not implemented for varying buffer size\n");
3494 pStubMsg->Buffer += bufsize;
3496 return pStubMsg->MemorySize;
3499 /***********************************************************************
3500 * NdrUserMarshalFree [RPCRT4.@]
3502 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
3503 unsigned char *pMemory,
3504 PFORMAT_STRING pFormat)
3506 /* unsigned flags = pFormat[1]; */
3507 unsigned index = *(const WORD*)&pFormat[2];
3508 USER_MARSHAL_CB umcb;
3510 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3511 TRACE("index=%d\n", index);
3513 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
3515 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
3516 &umcb.Flags, pMemory);
3519 /***********************************************************************
3520 * NdrClearOutParameters [RPCRT4.@]
3522 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
3523 PFORMAT_STRING pFormat,
3526 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
3529 /***********************************************************************
3530 * NdrConvert [RPCRT4.@]
3532 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
3534 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
3535 /* FIXME: since this stub doesn't do any converting, the proper behavior
3536 is to raise an exception */
3539 /***********************************************************************
3540 * NdrConvert2 [RPCRT4.@]
3542 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
3544 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3545 pStubMsg, pFormat, NumberParams);
3546 /* FIXME: since this stub doesn't do any converting, the proper behavior
3547 is to raise an exception */
3550 #include "pshpack1.h"
3551 typedef struct _NDR_CSTRUCT_FORMAT
3554 unsigned char alignment;
3555 unsigned short memory_size;
3556 short offset_to_array_description;
3557 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
3558 #include "poppack.h"
3560 /***********************************************************************
3561 * NdrConformantStructMarshall [RPCRT4.@]
3563 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3564 unsigned char *pMemory,
3565 PFORMAT_STRING pFormat)
3567 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3568 PFORMAT_STRING pCArrayFormat;
3569 ULONG esize, bufsize;
3571 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3573 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3574 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3576 ERR("invalid format type %x\n", pCStructFormat->type);
3577 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3581 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3582 pCStructFormat->offset_to_array_description;
3583 if (*pCArrayFormat != RPC_FC_CARRAY)
3585 ERR("invalid array format type %x\n", pCStructFormat->type);
3586 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3589 esize = *(const WORD*)(pCArrayFormat+2);
3591 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3592 pCArrayFormat + 4, 0);
3594 WriteConformance(pStubMsg);
3596 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3598 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3600 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3601 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3603 ERR("integer overflow of memory_size %u with bufsize %u\n",
3604 pCStructFormat->memory_size, bufsize);
3605 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3607 /* copy constant sized part of struct */
3608 pStubMsg->BufferMark = pStubMsg->Buffer;
3609 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
3611 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3612 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3617 /***********************************************************************
3618 * NdrConformantStructUnmarshall [RPCRT4.@]
3620 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3621 unsigned char **ppMemory,
3622 PFORMAT_STRING pFormat,
3623 unsigned char fMustAlloc)
3625 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3626 PFORMAT_STRING pCArrayFormat;
3627 ULONG esize, bufsize;
3628 unsigned char *saved_buffer;
3630 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3632 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3633 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3635 ERR("invalid format type %x\n", pCStructFormat->type);
3636 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3639 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3640 pCStructFormat->offset_to_array_description;
3641 if (*pCArrayFormat != RPC_FC_CARRAY)
3643 ERR("invalid array format type %x\n", pCStructFormat->type);
3644 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3647 esize = *(const WORD*)(pCArrayFormat+2);
3649 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3651 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3653 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3655 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3656 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3658 ERR("integer overflow of memory_size %u with bufsize %u\n",
3659 pCStructFormat->memory_size, bufsize);
3660 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3665 SIZE_T size = pCStructFormat->memory_size + bufsize;
3666 *ppMemory = NdrAllocate(pStubMsg, size);
3670 if (!pStubMsg->IsClient && !*ppMemory)
3671 /* for servers, we just point straight into the RPC buffer */
3672 *ppMemory = pStubMsg->Buffer;
3675 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3676 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
3677 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3678 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3680 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
3681 if (*ppMemory != saved_buffer)
3682 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
3687 /***********************************************************************
3688 * NdrConformantStructBufferSize [RPCRT4.@]
3690 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3691 unsigned char *pMemory,
3692 PFORMAT_STRING pFormat)
3694 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3695 PFORMAT_STRING pCArrayFormat;
3698 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3700 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3701 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3703 ERR("invalid format type %x\n", pCStructFormat->type);
3704 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3707 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3708 pCStructFormat->offset_to_array_description;
3709 if (*pCArrayFormat != RPC_FC_CARRAY)
3711 ERR("invalid array format type %x\n", pCStructFormat->type);
3712 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3715 esize = *(const WORD*)(pCArrayFormat+2);
3717 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
3718 SizeConformance(pStubMsg);
3720 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
3722 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3724 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
3725 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
3727 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3728 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3731 /***********************************************************************
3732 * NdrConformantStructMemorySize [RPCRT4.@]
3734 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3735 PFORMAT_STRING pFormat)
3741 /***********************************************************************
3742 * NdrConformantStructFree [RPCRT4.@]
3744 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3745 unsigned char *pMemory,
3746 PFORMAT_STRING pFormat)
3748 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3749 PFORMAT_STRING pCArrayFormat;
3752 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3754 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3755 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3757 ERR("invalid format type %x\n", pCStructFormat->type);
3758 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3762 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3763 pCStructFormat->offset_to_array_description;
3764 if (*pCArrayFormat != RPC_FC_CARRAY)
3766 ERR("invalid array format type %x\n", pCStructFormat->type);
3767 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3770 esize = *(const WORD*)(pCArrayFormat+2);
3772 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3773 pCArrayFormat + 4, 0);
3775 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3777 /* copy constant sized part of struct */
3778 pStubMsg->BufferMark = pStubMsg->Buffer;
3780 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3781 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3784 /***********************************************************************
3785 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3787 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3788 unsigned char *pMemory,
3789 PFORMAT_STRING pFormat)
3791 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3792 PFORMAT_STRING pCVArrayFormat;
3793 ULONG esize, bufsize;
3795 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3797 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3798 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3800 ERR("invalid format type %x\n", pCVStructFormat->type);
3801 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3805 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3806 pCVStructFormat->offset_to_array_description;
3807 switch (*pCVArrayFormat)
3809 case RPC_FC_CVARRAY:
3810 esize = *(const WORD*)(pCVArrayFormat+2);
3812 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3813 pCVArrayFormat + 4, 0);
3814 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3817 case RPC_FC_C_CSTRING:
3818 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3819 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3820 esize = sizeof(char);
3821 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3822 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3823 pCVArrayFormat + 2, 0);
3825 pStubMsg->MaxCount = pStubMsg->ActualCount;
3827 case RPC_FC_C_WSTRING:
3828 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3829 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3830 esize = sizeof(WCHAR);
3831 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3832 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3833 pCVArrayFormat + 2, 0);
3835 pStubMsg->MaxCount = pStubMsg->ActualCount;
3838 ERR("invalid array format type %x\n", *pCVArrayFormat);
3839 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3843 WriteConformance(pStubMsg);
3845 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3847 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3849 /* write constant sized part */
3850 pStubMsg->BufferMark = pStubMsg->Buffer;
3851 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
3853 WriteVariance(pStubMsg);
3855 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3857 /* write array part */
3858 safe_copy_to_buffer(pStubMsg, pMemory + pCVStructFormat->memory_size, bufsize);
3860 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3865 /***********************************************************************
3866 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3868 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3869 unsigned char **ppMemory,
3870 PFORMAT_STRING pFormat,
3871 unsigned char fMustAlloc)
3873 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3874 PFORMAT_STRING pCVArrayFormat;
3875 ULONG esize, bufsize;
3876 unsigned char cvarray_type;
3878 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3880 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3881 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3883 ERR("invalid format type %x\n", pCVStructFormat->type);
3884 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3888 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3889 pCVStructFormat->offset_to_array_description;
3890 cvarray_type = *pCVArrayFormat;
3891 switch (cvarray_type)
3893 case RPC_FC_CVARRAY:
3894 esize = *(const WORD*)(pCVArrayFormat+2);
3895 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3897 case RPC_FC_C_CSTRING:
3898 esize = sizeof(char);
3899 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3900 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3902 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3904 case RPC_FC_C_WSTRING:
3905 esize = sizeof(WCHAR);
3906 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3907 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3909 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3912 ERR("invalid array format type %x\n", *pCVArrayFormat);
3913 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3917 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3919 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3921 /* work out how much memory to allocate if we need to do so */
3922 if (!*ppMemory || fMustAlloc)
3924 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3925 *ppMemory = NdrAllocate(pStubMsg, size);
3928 /* copy the constant data */
3929 pStubMsg->BufferMark = pStubMsg->Buffer;
3930 safe_copy_from_buffer(pStubMsg, *ppMemory, pCVStructFormat->memory_size);
3932 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3934 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3936 if ((cvarray_type == RPC_FC_C_CSTRING) ||
3937 (cvarray_type == RPC_FC_C_WSTRING))
3940 /* strings must always have null terminating bytes */
3941 if (bufsize < esize)
3943 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
3944 RpcRaiseException(RPC_S_INVALID_BOUND);
3947 for (i = bufsize - esize; i < bufsize; i++)
3948 if (pStubMsg->Buffer[i] != 0)
3950 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3951 i, pStubMsg->Buffer[i]);
3952 RpcRaiseException(RPC_S_INVALID_BOUND);
3957 /* copy the array data */
3958 safe_copy_from_buffer(pStubMsg, *ppMemory + pCVStructFormat->memory_size, bufsize);
3960 if (cvarray_type == RPC_FC_C_CSTRING)
3961 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3962 else if (cvarray_type == RPC_FC_C_WSTRING)
3963 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3965 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
3970 /***********************************************************************
3971 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3973 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3974 unsigned char *pMemory,
3975 PFORMAT_STRING pFormat)
3977 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3978 PFORMAT_STRING pCVArrayFormat;
3981 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3983 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3984 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3986 ERR("invalid format type %x\n", pCVStructFormat->type);
3987 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3991 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3992 pCVStructFormat->offset_to_array_description;
3993 switch (*pCVArrayFormat)
3995 case RPC_FC_CVARRAY:
3996 esize = *(const WORD*)(pCVArrayFormat+2);
3998 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3999 pCVArrayFormat + 4, 0);
4000 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4003 case RPC_FC_C_CSTRING:
4004 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4005 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4006 esize = sizeof(char);
4007 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4008 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4009 pCVArrayFormat + 2, 0);
4011 pStubMsg->MaxCount = pStubMsg->ActualCount;
4013 case RPC_FC_C_WSTRING:
4014 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4015 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4016 esize = sizeof(WCHAR);
4017 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4018 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4019 pCVArrayFormat + 2, 0);
4021 pStubMsg->MaxCount = pStubMsg->ActualCount;
4024 ERR("invalid array format type %x\n", *pCVArrayFormat);
4025 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4029 SizeConformance(pStubMsg);
4031 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4033 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4035 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4036 SizeVariance(pStubMsg);
4037 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4039 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4042 /***********************************************************************
4043 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4045 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4046 PFORMAT_STRING pFormat)
4048 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4049 PFORMAT_STRING pCVArrayFormat;
4051 unsigned char cvarray_type;
4053 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4055 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4056 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4058 ERR("invalid format type %x\n", pCVStructFormat->type);
4059 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4063 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4064 pCVStructFormat->offset_to_array_description;
4065 cvarray_type = *pCVArrayFormat;
4066 switch (cvarray_type)
4068 case RPC_FC_CVARRAY:
4069 esize = *(const WORD*)(pCVArrayFormat+2);
4070 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4072 case RPC_FC_C_CSTRING:
4073 esize = sizeof(char);
4074 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4075 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4077 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4079 case RPC_FC_C_WSTRING:
4080 esize = sizeof(WCHAR);
4081 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4082 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4084 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4087 ERR("invalid array format type %x\n", *pCVArrayFormat);
4088 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4092 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4094 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4096 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4097 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4098 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4100 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4102 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4104 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
4107 /***********************************************************************
4108 * NdrConformantVaryingStructFree [RPCRT4.@]
4110 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4111 unsigned char *pMemory,
4112 PFORMAT_STRING pFormat)
4114 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4115 PFORMAT_STRING pCVArrayFormat;
4118 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4120 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4121 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4123 ERR("invalid format type %x\n", pCVStructFormat->type);
4124 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4128 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4129 pCVStructFormat->offset_to_array_description;
4130 switch (*pCVArrayFormat)
4132 case RPC_FC_CVARRAY:
4133 esize = *(const WORD*)(pCVArrayFormat+2);
4135 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4136 pCVArrayFormat + 4, 0);
4137 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4140 case RPC_FC_C_CSTRING:
4141 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4142 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4143 esize = sizeof(char);
4144 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4145 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4146 pCVArrayFormat + 2, 0);
4148 pStubMsg->MaxCount = pStubMsg->ActualCount;
4150 case RPC_FC_C_WSTRING:
4151 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4152 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4153 esize = sizeof(WCHAR);
4154 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4155 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4156 pCVArrayFormat + 2, 0);
4158 pStubMsg->MaxCount = pStubMsg->ActualCount;
4161 ERR("invalid array format type %x\n", *pCVArrayFormat);
4162 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4166 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4168 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4171 #include "pshpack1.h"
4175 unsigned char alignment;
4176 unsigned short total_size;
4177 } NDR_SMFARRAY_FORMAT;
4182 unsigned char alignment;
4183 unsigned long total_size;
4184 } NDR_LGFARRAY_FORMAT;
4185 #include "poppack.h"
4187 /***********************************************************************
4188 * NdrFixedArrayMarshall [RPCRT4.@]
4190 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4191 unsigned char *pMemory,
4192 PFORMAT_STRING pFormat)
4194 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4195 unsigned long total_size;
4197 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4199 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4200 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4202 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4203 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4207 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4209 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4211 total_size = pSmFArrayFormat->total_size;
4212 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4216 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4217 total_size = pLgFArrayFormat->total_size;
4218 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4221 pStubMsg->BufferMark = pStubMsg->Buffer;
4222 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4224 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4229 /***********************************************************************
4230 * NdrFixedArrayUnmarshall [RPCRT4.@]
4232 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4233 unsigned char **ppMemory,
4234 PFORMAT_STRING pFormat,
4235 unsigned char fMustAlloc)
4237 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4238 unsigned long total_size;
4239 unsigned char *saved_buffer;
4241 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4243 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4244 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4246 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4247 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4251 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4253 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4255 total_size = pSmFArrayFormat->total_size;
4256 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4260 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4261 total_size = pLgFArrayFormat->total_size;
4262 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4266 *ppMemory = NdrAllocate(pStubMsg, total_size);
4269 if (!pStubMsg->IsClient && !*ppMemory)
4270 /* for servers, we just point straight into the RPC buffer */
4271 *ppMemory = pStubMsg->Buffer;
4274 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4275 safe_buffer_increment(pStubMsg, total_size);
4276 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4278 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4279 if (*ppMemory != saved_buffer)
4280 memcpy(*ppMemory, saved_buffer, total_size);
4285 /***********************************************************************
4286 * NdrFixedArrayBufferSize [RPCRT4.@]
4288 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4289 unsigned char *pMemory,
4290 PFORMAT_STRING pFormat)
4292 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4293 unsigned long total_size;
4295 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4297 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4298 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4300 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4301 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4305 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4307 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4309 total_size = pSmFArrayFormat->total_size;
4310 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4314 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4315 total_size = pLgFArrayFormat->total_size;
4316 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4318 safe_buffer_length_increment(pStubMsg, total_size);
4320 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4323 /***********************************************************************
4324 * NdrFixedArrayMemorySize [RPCRT4.@]
4326 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4327 PFORMAT_STRING pFormat)
4329 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4332 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4334 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4335 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4337 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4338 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4342 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4344 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4346 total_size = pSmFArrayFormat->total_size;
4347 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4351 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4352 total_size = pLgFArrayFormat->total_size;
4353 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4355 pStubMsg->BufferMark = pStubMsg->Buffer;
4356 safe_buffer_increment(pStubMsg, total_size);
4357 pStubMsg->MemorySize += total_size;
4359 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4364 /***********************************************************************
4365 * NdrFixedArrayFree [RPCRT4.@]
4367 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4368 unsigned char *pMemory,
4369 PFORMAT_STRING pFormat)
4371 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4373 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4375 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4376 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4378 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4379 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4383 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4384 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4387 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4388 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4391 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4394 /***********************************************************************
4395 * NdrVaryingArrayMarshall [RPCRT4.@]
4397 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4398 unsigned char *pMemory,
4399 PFORMAT_STRING pFormat)
4401 unsigned char alignment;
4402 DWORD elements, esize;
4405 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4407 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4408 (pFormat[0] != RPC_FC_LGVARRAY))
4410 ERR("invalid format type %x\n", pFormat[0]);
4411 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4415 alignment = pFormat[1] + 1;
4417 if (pFormat[0] == RPC_FC_SMVARRAY)
4420 pFormat += sizeof(WORD);
4421 elements = *(const WORD*)pFormat;
4422 pFormat += sizeof(WORD);
4427 pFormat += sizeof(DWORD);
4428 elements = *(const DWORD*)pFormat;
4429 pFormat += sizeof(DWORD);
4432 esize = *(const WORD*)pFormat;
4433 pFormat += sizeof(WORD);
4435 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4436 if ((pStubMsg->ActualCount > elements) ||
4437 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4439 RpcRaiseException(RPC_S_INVALID_BOUND);
4443 WriteVariance(pStubMsg);
4445 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
4447 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4448 pStubMsg->BufferMark = pStubMsg->Buffer;
4449 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
4451 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4456 /***********************************************************************
4457 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4459 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4460 unsigned char **ppMemory,
4461 PFORMAT_STRING pFormat,
4462 unsigned char fMustAlloc)
4464 unsigned char alignment;
4465 DWORD size, elements, esize;
4468 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4470 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4471 (pFormat[0] != RPC_FC_LGVARRAY))
4473 ERR("invalid format type %x\n", pFormat[0]);
4474 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4478 alignment = pFormat[1] + 1;
4480 if (pFormat[0] == RPC_FC_SMVARRAY)
4483 size = *(const WORD*)pFormat;
4484 pFormat += sizeof(WORD);
4485 elements = *(const WORD*)pFormat;
4486 pFormat += sizeof(WORD);
4491 size = *(const DWORD*)pFormat;
4492 pFormat += sizeof(DWORD);
4493 elements = *(const DWORD*)pFormat;
4494 pFormat += sizeof(DWORD);
4497 esize = *(const WORD*)pFormat;
4498 pFormat += sizeof(WORD);
4500 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4502 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4504 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4506 if (!*ppMemory || fMustAlloc)
4507 *ppMemory = NdrAllocate(pStubMsg, size);
4508 safe_copy_from_buffer(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize);
4510 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
4515 /***********************************************************************
4516 * NdrVaryingArrayBufferSize [RPCRT4.@]
4518 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4519 unsigned char *pMemory,
4520 PFORMAT_STRING pFormat)
4522 unsigned char alignment;
4523 DWORD elements, esize;
4525 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4527 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4528 (pFormat[0] != RPC_FC_LGVARRAY))
4530 ERR("invalid format type %x\n", pFormat[0]);
4531 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4535 alignment = pFormat[1] + 1;
4537 if (pFormat[0] == RPC_FC_SMVARRAY)
4540 pFormat += sizeof(WORD);
4541 elements = *(const WORD*)pFormat;
4542 pFormat += sizeof(WORD);
4547 pFormat += sizeof(DWORD);
4548 elements = *(const DWORD*)pFormat;
4549 pFormat += sizeof(DWORD);
4552 esize = *(const WORD*)pFormat;
4553 pFormat += sizeof(WORD);
4555 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4556 if ((pStubMsg->ActualCount > elements) ||
4557 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4559 RpcRaiseException(RPC_S_INVALID_BOUND);
4563 SizeVariance(pStubMsg);
4565 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4567 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4569 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4572 /***********************************************************************
4573 * NdrVaryingArrayMemorySize [RPCRT4.@]
4575 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4576 PFORMAT_STRING pFormat)
4578 unsigned char alignment;
4579 DWORD size, elements, esize;
4581 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4583 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4584 (pFormat[0] != RPC_FC_LGVARRAY))
4586 ERR("invalid format type %x\n", pFormat[0]);
4587 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4591 alignment = pFormat[1] + 1;
4593 if (pFormat[0] == RPC_FC_SMVARRAY)
4596 size = *(const WORD*)pFormat;
4597 pFormat += sizeof(WORD);
4598 elements = *(const WORD*)pFormat;
4599 pFormat += sizeof(WORD);
4604 size = *(const DWORD*)pFormat;
4605 pFormat += sizeof(DWORD);
4606 elements = *(const DWORD*)pFormat;
4607 pFormat += sizeof(DWORD);
4610 esize = *(const WORD*)pFormat;
4611 pFormat += sizeof(WORD);
4613 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4615 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4617 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4618 pStubMsg->MemorySize += size;
4620 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4622 return pStubMsg->MemorySize;
4625 /***********************************************************************
4626 * NdrVaryingArrayFree [RPCRT4.@]
4628 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4629 unsigned char *pMemory,
4630 PFORMAT_STRING pFormat)
4632 unsigned char alignment;
4635 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4637 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4638 (pFormat[0] != RPC_FC_LGVARRAY))
4640 ERR("invalid format type %x\n", pFormat[0]);
4641 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4645 alignment = pFormat[1] + 1;
4647 if (pFormat[0] == RPC_FC_SMVARRAY)
4650 pFormat += sizeof(WORD);
4651 elements = *(const WORD*)pFormat;
4652 pFormat += sizeof(WORD);
4657 pFormat += sizeof(DWORD);
4658 elements = *(const DWORD*)pFormat;
4659 pFormat += sizeof(DWORD);
4662 pFormat += sizeof(WORD);
4664 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4665 if ((pStubMsg->ActualCount > elements) ||
4666 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4668 RpcRaiseException(RPC_S_INVALID_BOUND);
4672 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4675 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
4683 return *(const UCHAR *)pMemory;
4688 return *(const USHORT *)pMemory;
4692 return *(const ULONG *)pMemory;
4694 FIXME("Unhandled base type: 0x%02x\n", fc);
4699 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4700 unsigned long discriminant,
4701 PFORMAT_STRING pFormat)
4703 unsigned short num_arms, arm, type;
4705 num_arms = *(const SHORT*)pFormat & 0x0fff;
4707 for(arm = 0; arm < num_arms; arm++)
4709 if(discriminant == *(const ULONG*)pFormat)
4717 type = *(const unsigned short*)pFormat;
4718 TRACE("type %04x\n", type);
4719 if(arm == num_arms) /* default arm extras */
4723 ERR("no arm for 0x%lx and no default case\n", discriminant);
4724 RpcRaiseException(RPC_S_INVALID_TAG);
4729 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
4736 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
4738 unsigned short type;
4742 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4746 type = *(const unsigned short*)pFormat;
4747 if((type & 0xff00) == 0x8000)
4749 unsigned char basetype = LOBYTE(type);
4750 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
4754 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4755 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
4758 unsigned char *saved_buffer = NULL;
4759 int pointer_buffer_mark_set = 0;
4766 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
4767 saved_buffer = pStubMsg->Buffer;
4768 if (pStubMsg->PointerBufferMark)
4770 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4771 pStubMsg->PointerBufferMark = NULL;
4772 pointer_buffer_mark_set = 1;
4775 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
4777 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
4778 if (pointer_buffer_mark_set)
4780 STD_OVERFLOW_CHECK(pStubMsg);
4781 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4782 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
4784 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4785 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
4786 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4788 pStubMsg->Buffer = saved_buffer + 4;
4792 m(pStubMsg, pMemory, desc);
4795 else FIXME("no marshaller for embedded type %02x\n", *desc);
4800 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4801 unsigned char **ppMemory,
4803 PFORMAT_STRING pFormat,
4804 unsigned char fMustAlloc)
4806 unsigned short type;
4810 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4814 type = *(const unsigned short*)pFormat;
4815 if((type & 0xff00) == 0x8000)
4817 unsigned char basetype = LOBYTE(type);
4818 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
4822 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4823 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
4826 unsigned char *saved_buffer = NULL;
4827 int pointer_buffer_mark_set = 0;
4834 **(void***)ppMemory = NULL;
4835 ALIGN_POINTER(pStubMsg->Buffer, 4);
4836 saved_buffer = pStubMsg->Buffer;
4837 if (pStubMsg->PointerBufferMark)
4839 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4840 pStubMsg->PointerBufferMark = NULL;
4841 pointer_buffer_mark_set = 1;
4844 pStubMsg->Buffer += 4; /* for pointer ID */
4846 if (saved_buffer + 4 > pStubMsg->BufferEnd)
4848 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4849 saved_buffer, pStubMsg->BufferEnd);
4850 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4853 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
4854 if (pointer_buffer_mark_set)
4856 STD_OVERFLOW_CHECK(pStubMsg);
4857 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4858 pStubMsg->Buffer = saved_buffer + 4;
4862 m(pStubMsg, ppMemory, desc, fMustAlloc);
4865 else FIXME("no marshaller for embedded type %02x\n", *desc);
4870 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
4871 unsigned char *pMemory,
4873 PFORMAT_STRING pFormat)
4875 unsigned short type;
4879 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4883 type = *(const unsigned short*)pFormat;
4884 if((type & 0xff00) == 0x8000)
4886 unsigned char basetype = LOBYTE(type);
4887 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
4891 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4892 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
4901 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4902 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
4903 if (!pStubMsg->IgnoreEmbeddedPointers)
4905 int saved_buffer_length = pStubMsg->BufferLength;
4906 pStubMsg->BufferLength = pStubMsg->PointerLength;
4907 pStubMsg->PointerLength = 0;
4908 if(!pStubMsg->BufferLength)
4909 ERR("BufferLength == 0??\n");
4910 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
4911 pStubMsg->PointerLength = pStubMsg->BufferLength;
4912 pStubMsg->BufferLength = saved_buffer_length;
4916 m(pStubMsg, pMemory, desc);
4919 else FIXME("no buffersizer for embedded type %02x\n", *desc);
4923 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
4925 PFORMAT_STRING pFormat)
4927 unsigned short type, size;
4929 size = *(const unsigned short*)pFormat;
4930 pStubMsg->Memory += size;
4933 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4937 type = *(const unsigned short*)pFormat;
4938 if((type & 0xff00) == 0x8000)
4940 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
4944 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4945 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
4946 unsigned char *saved_buffer;
4955 ALIGN_POINTER(pStubMsg->Buffer, 4);
4956 saved_buffer = pStubMsg->Buffer;
4957 safe_buffer_increment(pStubMsg, 4);
4958 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
4959 pStubMsg->MemorySize += 4;
4960 if (!pStubMsg->IgnoreEmbeddedPointers)
4961 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
4964 return m(pStubMsg, desc);
4967 else FIXME("no marshaller for embedded type %02x\n", *desc);
4970 TRACE("size %d\n", size);
4974 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
4975 unsigned char *pMemory,
4977 PFORMAT_STRING pFormat)
4979 unsigned short type;
4983 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4987 type = *(const unsigned short*)pFormat;
4988 if((type & 0xff00) != 0x8000)
4990 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4991 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5000 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5003 m(pStubMsg, pMemory, desc);
5006 else FIXME("no freer for embedded type %02x\n", *desc);
5010 /***********************************************************************
5011 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5013 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5014 unsigned char *pMemory,
5015 PFORMAT_STRING pFormat)
5017 unsigned char switch_type;
5018 unsigned char increment;
5021 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5024 switch_type = *pFormat & 0xf;
5025 increment = (*pFormat & 0xf0) >> 4;
5028 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5030 switch_value = get_discriminant(switch_type, pMemory);
5031 TRACE("got switch value 0x%x\n", switch_value);
5033 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5034 pMemory += increment;
5036 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5039 /***********************************************************************
5040 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5042 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5043 unsigned char **ppMemory,
5044 PFORMAT_STRING pFormat,
5045 unsigned char fMustAlloc)
5047 unsigned char switch_type;
5048 unsigned char increment;
5050 unsigned short size;
5051 unsigned char *pMemoryArm;
5053 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5056 switch_type = *pFormat & 0xf;
5057 increment = (*pFormat & 0xf0) >> 4;
5060 ALIGN_POINTER(pStubMsg->Buffer, increment);
5061 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5062 TRACE("got switch value 0x%x\n", switch_value);
5064 size = *(const unsigned short*)pFormat + increment;
5065 if(!*ppMemory || fMustAlloc)
5066 *ppMemory = NdrAllocate(pStubMsg, size);
5068 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5069 pMemoryArm = *ppMemory + increment;
5071 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
5074 /***********************************************************************
5075 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5077 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5078 unsigned char *pMemory,
5079 PFORMAT_STRING pFormat)
5081 unsigned char switch_type;
5082 unsigned char increment;
5085 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5088 switch_type = *pFormat & 0xf;
5089 increment = (*pFormat & 0xf0) >> 4;
5092 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5093 switch_value = get_discriminant(switch_type, pMemory);
5094 TRACE("got switch value 0x%x\n", switch_value);
5096 /* Add discriminant size */
5097 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5098 pMemory += increment;
5100 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5103 /***********************************************************************
5104 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5106 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5107 PFORMAT_STRING pFormat)
5109 unsigned char switch_type;
5110 unsigned char increment;
5113 switch_type = *pFormat & 0xf;
5114 increment = (*pFormat & 0xf0) >> 4;
5117 ALIGN_POINTER(pStubMsg->Buffer, increment);
5118 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5119 TRACE("got switch value 0x%x\n", switch_value);
5121 pStubMsg->Memory += increment;
5123 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5126 /***********************************************************************
5127 * NdrEncapsulatedUnionFree [RPCRT4.@]
5129 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5130 unsigned char *pMemory,
5131 PFORMAT_STRING pFormat)
5133 unsigned char switch_type;
5134 unsigned char increment;
5137 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5140 switch_type = *pFormat & 0xf;
5141 increment = (*pFormat & 0xf0) >> 4;
5144 switch_value = get_discriminant(switch_type, pMemory);
5145 TRACE("got switch value 0x%x\n", switch_value);
5147 pMemory += increment;
5149 return union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5152 /***********************************************************************
5153 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5155 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5156 unsigned char *pMemory,
5157 PFORMAT_STRING pFormat)
5159 unsigned char switch_type;
5161 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5164 switch_type = *pFormat;
5167 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5168 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5169 /* Marshall discriminant */
5170 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5172 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5175 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5176 PFORMAT_STRING *ppFormat)
5178 long discriminant = 0;
5188 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5197 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5198 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5206 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5207 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5212 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5216 if (pStubMsg->fHasNewCorrDesc)
5220 return discriminant;
5223 /**********************************************************************
5224 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5226 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5227 unsigned char **ppMemory,
5228 PFORMAT_STRING pFormat,
5229 unsigned char fMustAlloc)
5232 unsigned short size;
5234 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5237 /* Unmarshall discriminant */
5238 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5239 TRACE("unmarshalled discriminant %lx\n", discriminant);
5241 pFormat += *(const SHORT*)pFormat;
5243 size = *(const unsigned short*)pFormat;
5245 if(!*ppMemory || fMustAlloc)
5246 *ppMemory = NdrAllocate(pStubMsg, size);
5248 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5251 /***********************************************************************
5252 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5254 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5255 unsigned char *pMemory,
5256 PFORMAT_STRING pFormat)
5258 unsigned char switch_type;
5260 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5263 switch_type = *pFormat;
5266 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5267 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5268 /* Add discriminant size */
5269 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5271 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5274 /***********************************************************************
5275 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5277 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5278 PFORMAT_STRING pFormat)
5283 /* Unmarshall discriminant */
5284 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5285 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
5287 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
5290 /***********************************************************************
5291 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5293 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5294 unsigned char *pMemory,
5295 PFORMAT_STRING pFormat)
5297 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5301 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5302 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5304 return union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5307 /***********************************************************************
5308 * NdrByteCountPointerMarshall [RPCRT4.@]
5310 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5311 unsigned char *pMemory,
5312 PFORMAT_STRING pFormat)
5318 /***********************************************************************
5319 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5321 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5322 unsigned char **ppMemory,
5323 PFORMAT_STRING pFormat,
5324 unsigned char fMustAlloc)
5330 /***********************************************************************
5331 * NdrByteCountPointerBufferSize [RPCRT4.@]
5333 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5334 unsigned char *pMemory,
5335 PFORMAT_STRING pFormat)
5340 /***********************************************************************
5341 * NdrByteCountPointerMemorySize [RPCRT4.@]
5343 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5344 PFORMAT_STRING pFormat)
5350 /***********************************************************************
5351 * NdrByteCountPointerFree [RPCRT4.@]
5353 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
5354 unsigned char *pMemory,
5355 PFORMAT_STRING pFormat)
5360 /***********************************************************************
5361 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5363 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5364 unsigned char *pMemory,
5365 PFORMAT_STRING pFormat)
5371 /***********************************************************************
5372 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5374 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5375 unsigned char **ppMemory,
5376 PFORMAT_STRING pFormat,
5377 unsigned char fMustAlloc)
5383 /***********************************************************************
5384 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5386 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5387 unsigned char *pMemory,
5388 PFORMAT_STRING pFormat)
5393 /***********************************************************************
5394 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5396 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5397 PFORMAT_STRING pFormat)
5403 /***********************************************************************
5404 * NdrXmitOrRepAsFree [RPCRT4.@]
5406 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
5407 unsigned char *pMemory,
5408 PFORMAT_STRING pFormat)
5413 #include "pshpack1.h"
5417 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
5421 #include "poppack.h"
5423 /***********************************************************************
5424 * NdrRangeMarshall [internal]
5426 unsigned char *WINAPI NdrRangeMarshall(
5427 PMIDL_STUB_MESSAGE pStubMsg,
5428 unsigned char *pMemory,
5429 PFORMAT_STRING pFormat)
5431 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5432 unsigned char base_type;
5434 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5436 if (pRange->type != RPC_FC_RANGE)
5438 ERR("invalid format type %x\n", pRange->type);
5439 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5443 base_type = pRange->flags_type & 0xf;
5445 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
5448 /***********************************************************************
5449 * NdrRangeUnmarshall
5451 unsigned char *WINAPI NdrRangeUnmarshall(
5452 PMIDL_STUB_MESSAGE pStubMsg,
5453 unsigned char **ppMemory,
5454 PFORMAT_STRING pFormat,
5455 unsigned char fMustAlloc)
5457 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5458 unsigned char base_type;
5460 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5462 if (pRange->type != RPC_FC_RANGE)
5464 ERR("invalid format type %x\n", pRange->type);
5465 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5468 base_type = pRange->flags_type & 0xf;
5470 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5471 base_type, pRange->low_value, pRange->high_value);
5473 #define RANGE_UNMARSHALL(type, format_spec) \
5476 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5477 if (fMustAlloc || !*ppMemory) \
5478 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5479 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5481 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5482 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5483 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5485 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5486 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5488 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5489 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5490 (type)pRange->high_value); \
5491 RpcRaiseException(RPC_S_INVALID_BOUND); \
5494 TRACE("*ppMemory: %p\n", *ppMemory); \
5495 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5496 pStubMsg->Buffer += sizeof(type); \
5503 RANGE_UNMARSHALL(UCHAR, "%d");
5504 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5508 RANGE_UNMARSHALL(CHAR, "%u");
5509 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5511 case RPC_FC_WCHAR: /* FIXME: valid? */
5513 RANGE_UNMARSHALL(USHORT, "%u");
5514 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5517 RANGE_UNMARSHALL(SHORT, "%d");
5518 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5521 RANGE_UNMARSHALL(LONG, "%d");
5522 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5525 RANGE_UNMARSHALL(ULONG, "%u");
5526 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5530 FIXME("Unhandled enum type\n");
5532 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
5537 ERR("invalid range base type: 0x%02x\n", base_type);
5538 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5544 /***********************************************************************
5545 * NdrRangeBufferSize [internal]
5547 void WINAPI NdrRangeBufferSize(
5548 PMIDL_STUB_MESSAGE pStubMsg,
5549 unsigned char *pMemory,
5550 PFORMAT_STRING pFormat)
5552 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5553 unsigned char base_type;
5555 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5557 if (pRange->type != RPC_FC_RANGE)
5559 ERR("invalid format type %x\n", pRange->type);
5560 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5562 base_type = pRange->flags_type & 0xf;
5564 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
5567 /***********************************************************************
5568 * NdrRangeMemorySize [internal]
5570 ULONG WINAPI NdrRangeMemorySize(
5571 PMIDL_STUB_MESSAGE pStubMsg,
5572 PFORMAT_STRING pFormat)
5574 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5575 unsigned char base_type;
5577 if (pRange->type != RPC_FC_RANGE)
5579 ERR("invalid format type %x\n", pRange->type);
5580 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5583 base_type = pRange->flags_type & 0xf;
5585 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
5588 /***********************************************************************
5589 * NdrRangeFree [internal]
5591 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
5592 unsigned char *pMemory,
5593 PFORMAT_STRING pFormat)
5595 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5600 /***********************************************************************
5601 * NdrBaseTypeMarshall [internal]
5603 static unsigned char *WINAPI NdrBaseTypeMarshall(
5604 PMIDL_STUB_MESSAGE pStubMsg,
5605 unsigned char *pMemory,
5606 PFORMAT_STRING pFormat)
5608 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5616 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
5617 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
5622 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
5623 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
5624 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
5628 case RPC_FC_ERROR_STATUS_T:
5630 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
5631 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
5632 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
5635 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
5636 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
5639 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
5640 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
5643 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
5644 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
5645 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
5648 /* only 16-bits on the wire, so do a sanity check */
5649 if (*(UINT *)pMemory > SHRT_MAX)
5650 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
5651 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
5652 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5653 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5654 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
5655 pStubMsg->Buffer += sizeof(USHORT);
5656 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
5661 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5664 /* FIXME: what is the correct return value? */
5668 /***********************************************************************
5669 * NdrBaseTypeUnmarshall [internal]
5671 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
5672 PMIDL_STUB_MESSAGE pStubMsg,
5673 unsigned char **ppMemory,
5674 PFORMAT_STRING pFormat,
5675 unsigned char fMustAlloc)
5677 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5679 #define BASE_TYPE_UNMARSHALL(type) \
5680 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5681 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
5683 *ppMemory = pStubMsg->Buffer; \
5684 TRACE("*ppMemory: %p\n", *ppMemory); \
5689 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5690 TRACE("*ppMemory: %p\n", *ppMemory); \
5691 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5693 pStubMsg->Buffer += sizeof(type);
5701 BASE_TYPE_UNMARSHALL(UCHAR);
5702 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5707 BASE_TYPE_UNMARSHALL(USHORT);
5708 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5712 case RPC_FC_ERROR_STATUS_T:
5714 BASE_TYPE_UNMARSHALL(ULONG);
5715 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5718 BASE_TYPE_UNMARSHALL(float);
5719 TRACE("value: %f\n", **(float **)ppMemory);
5722 BASE_TYPE_UNMARSHALL(double);
5723 TRACE("value: %f\n", **(double **)ppMemory);
5726 BASE_TYPE_UNMARSHALL(ULONGLONG);
5727 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
5730 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5731 if (fMustAlloc || !*ppMemory)
5732 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
5733 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
5734 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5735 TRACE("*ppMemory: %p\n", *ppMemory);
5736 /* 16-bits on the wire, but int in memory */
5737 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
5738 pStubMsg->Buffer += sizeof(USHORT);
5739 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
5744 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5746 #undef BASE_TYPE_UNMARSHALL
5748 /* FIXME: what is the correct return value? */
5753 /***********************************************************************
5754 * NdrBaseTypeBufferSize [internal]
5756 static void WINAPI NdrBaseTypeBufferSize(
5757 PMIDL_STUB_MESSAGE pStubMsg,
5758 unsigned char *pMemory,
5759 PFORMAT_STRING pFormat)
5761 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5769 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
5775 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
5776 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
5781 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
5782 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
5785 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
5786 safe_buffer_length_increment(pStubMsg, sizeof(float));
5789 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
5790 safe_buffer_length_increment(pStubMsg, sizeof(double));
5793 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
5794 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
5796 case RPC_FC_ERROR_STATUS_T:
5797 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
5798 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
5803 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5807 /***********************************************************************
5808 * NdrBaseTypeMemorySize [internal]
5810 static ULONG WINAPI NdrBaseTypeMemorySize(
5811 PMIDL_STUB_MESSAGE pStubMsg,
5812 PFORMAT_STRING pFormat)
5814 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
5822 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
5823 pStubMsg->MemorySize += sizeof(UCHAR);
5824 return sizeof(UCHAR);
5828 safe_buffer_increment(pStubMsg, sizeof(USHORT));
5829 pStubMsg->MemorySize += sizeof(USHORT);
5830 return sizeof(USHORT);
5834 safe_buffer_increment(pStubMsg, sizeof(ULONG));
5835 pStubMsg->MemorySize += sizeof(ULONG);
5836 return sizeof(ULONG);
5838 safe_buffer_increment(pStubMsg, sizeof(float));
5839 pStubMsg->MemorySize += sizeof(float);
5840 return sizeof(float);
5842 safe_buffer_increment(pStubMsg, sizeof(double));
5843 pStubMsg->MemorySize += sizeof(double);
5844 return sizeof(double);
5846 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
5847 pStubMsg->MemorySize += sizeof(ULONGLONG);
5848 return sizeof(ULONGLONG);
5849 case RPC_FC_ERROR_STATUS_T:
5850 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
5851 pStubMsg->MemorySize += sizeof(error_status_t);
5852 return sizeof(error_status_t);
5854 safe_buffer_increment(pStubMsg, sizeof(USHORT));
5855 pStubMsg->MemorySize += sizeof(UINT);
5856 return sizeof(UINT);
5858 pStubMsg->MemorySize += sizeof(void *);
5859 return sizeof(void *);
5861 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5866 /***********************************************************************
5867 * NdrBaseTypeFree [internal]
5869 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
5870 unsigned char *pMemory,
5871 PFORMAT_STRING pFormat)
5873 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5878 /***********************************************************************
5879 * NdrContextHandleBufferSize [internal]
5881 static void WINAPI NdrContextHandleBufferSize(
5882 PMIDL_STUB_MESSAGE pStubMsg,
5883 unsigned char *pMemory,
5884 PFORMAT_STRING pFormat)
5886 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5888 if (*pFormat != RPC_FC_BIND_CONTEXT)
5890 ERR("invalid format type %x\n", *pFormat);
5891 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5893 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5894 safe_buffer_length_increment(pStubMsg, cbNDRContext);
5897 /***********************************************************************
5898 * NdrContextHandleMarshall [internal]
5900 static unsigned char *WINAPI NdrContextHandleMarshall(
5901 PMIDL_STUB_MESSAGE pStubMsg,
5902 unsigned char *pMemory,
5903 PFORMAT_STRING pFormat)
5905 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5907 if (*pFormat != RPC_FC_BIND_CONTEXT)
5909 ERR("invalid format type %x\n", *pFormat);
5910 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5913 if (pFormat[1] & 0x80)
5914 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
5916 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
5921 /***********************************************************************
5922 * NdrContextHandleUnmarshall [internal]
5924 static unsigned char *WINAPI NdrContextHandleUnmarshall(
5925 PMIDL_STUB_MESSAGE pStubMsg,
5926 unsigned char **ppMemory,
5927 PFORMAT_STRING pFormat,
5928 unsigned char fMustAlloc)
5930 if (*pFormat != RPC_FC_BIND_CONTEXT)
5932 ERR("invalid format type %x\n", *pFormat);
5933 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5936 **(NDR_CCONTEXT **)ppMemory = NULL;
5937 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
5942 /***********************************************************************
5943 * NdrClientContextMarshall [RPCRT4.@]
5945 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5946 NDR_CCONTEXT ContextHandle,
5949 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
5951 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5953 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5955 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
5956 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5957 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5960 /* FIXME: what does fCheck do? */
5961 NDRCContextMarshall(ContextHandle,
5964 pStubMsg->Buffer += cbNDRContext;
5967 /***********************************************************************
5968 * NdrClientContextUnmarshall [RPCRT4.@]
5970 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5971 NDR_CCONTEXT * pContextHandle,
5972 RPC_BINDING_HANDLE BindHandle)
5974 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
5976 ALIGN_POINTER(pStubMsg->Buffer, 4);
5978 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
5979 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5981 NDRCContextUnmarshall(pContextHandle,
5984 pStubMsg->RpcMsg->DataRepresentation);
5986 pStubMsg->Buffer += cbNDRContext;
5989 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5990 NDR_SCONTEXT ContextHandle,
5991 NDR_RUNDOWN RundownRoutine )
5993 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
5996 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
5998 FIXME("(%p): stub\n", pStubMsg);
6002 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6003 unsigned char* pMemory,
6004 PFORMAT_STRING pFormat)
6006 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6009 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6010 PFORMAT_STRING pFormat)
6012 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
6016 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6017 NDR_SCONTEXT ContextHandle,
6018 NDR_RUNDOWN RundownRoutine,
6019 PFORMAT_STRING pFormat)
6021 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6024 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6025 PFORMAT_STRING pFormat)
6027 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
6031 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
6033 typedef struct ndr_context_handle
6037 } ndr_context_handle;
6039 struct context_handle_entry
6043 RPC_BINDING_HANDLE handle;
6044 ndr_context_handle wire_data;
6047 static struct list context_handle_list = LIST_INIT(context_handle_list);
6049 static CRITICAL_SECTION ndr_context_cs;
6050 static CRITICAL_SECTION_DEBUG ndr_context_debug =
6052 0, 0, &ndr_context_cs,
6053 { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
6054 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
6056 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
6058 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
6060 struct context_handle_entry *che = (struct context_handle_entry*) CContext;
6062 if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
6067 static struct context_handle_entry *context_entry_from_guid(LPCGUID uuid)
6069 struct context_handle_entry *che;
6070 LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
6071 if (IsEqualGUID(&che->wire_data.uuid, uuid))
6076 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
6078 struct context_handle_entry *che;
6079 RPC_BINDING_HANDLE handle = NULL;
6081 TRACE("%p\n", CContext);
6083 EnterCriticalSection(&ndr_context_cs);
6084 che = get_context_entry(CContext);
6086 handle = che->handle;
6087 LeaveCriticalSection(&ndr_context_cs);
6090 RpcRaiseException(ERROR_INVALID_HANDLE);
6094 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
6096 struct context_handle_entry *che;
6098 TRACE("%p %p\n", CContext, pBuff);
6102 EnterCriticalSection(&ndr_context_cs);
6103 che = get_context_entry(CContext);
6104 memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
6105 LeaveCriticalSection(&ndr_context_cs);
6109 ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
6110 wire_data->attributes = 0;
6111 wire_data->uuid = GUID_NULL;
6115 /***********************************************************************
6116 * RpcSmDestroyClientContext [RPCRT4.@]
6118 RPC_STATUS WINAPI RpcSmDestroyClientContext(void **ContextHandle)
6120 RPC_STATUS status = RPC_X_SS_CONTEXT_MISMATCH;
6121 struct context_handle_entry *che = NULL;
6123 TRACE("(%p)\n", ContextHandle);
6125 EnterCriticalSection(&ndr_context_cs);
6126 che = get_context_entry(*ContextHandle);
6127 *ContextHandle = NULL;
6131 list_remove(&che->entry);
6134 LeaveCriticalSection(&ndr_context_cs);
6138 RpcBindingFree(&che->handle);
6139 HeapFree(GetProcessHeap(), 0, che);
6145 /***********************************************************************
6146 * RpcSsDestroyClientContext [RPCRT4.@]
6148 void WINAPI RpcSsDestroyClientContext(void **ContextHandle)
6150 RPC_STATUS status = RpcSmDestroyClientContext(ContextHandle);
6151 if (status != RPC_S_OK)
6152 RpcRaiseException(status);
6155 static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
6156 RPC_BINDING_HANDLE hBinding,
6157 const ndr_context_handle *chi)
6159 struct context_handle_entry *che = NULL;
6161 /* a null UUID means we should free the context handle */
6162 if (IsEqualGUID(&chi->uuid, &GUID_NULL))
6166 che = get_context_entry(*CContext);
6168 return ERROR_INVALID_HANDLE;
6169 list_remove(&che->entry);
6170 RpcBindingFree(&che->handle);
6171 HeapFree(GetProcessHeap(), 0, che);
6175 /* if there's no existing entry matching the GUID, allocate one */
6176 else if (!(che = context_entry_from_guid(&chi->uuid)))
6178 che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
6180 return ERROR_NOT_ENOUGH_MEMORY;
6181 che->magic = NDR_CONTEXT_HANDLE_MAGIC;
6182 RpcBindingCopy(hBinding, &che->handle);
6183 list_add_tail(&context_handle_list, &che->entry);
6184 memcpy(&che->wire_data, chi, sizeof *chi);
6189 return ERROR_SUCCESS;
6192 /***********************************************************************
6193 * NDRCContextUnmarshall [RPCRT4.@]
6195 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
6196 RPC_BINDING_HANDLE hBinding,
6197 void *pBuff, ULONG DataRepresentation)
6201 TRACE("*%p=(%p) %p %p %08x\n",
6202 CContext, *CContext, hBinding, pBuff, DataRepresentation);
6204 EnterCriticalSection(&ndr_context_cs);
6205 r = ndr_update_context_handle(CContext, hBinding, pBuff);
6206 LeaveCriticalSection(&ndr_context_cs);
6208 RpcRaiseException(r);
6211 /***********************************************************************
6212 * NDRSContextMarshall [RPCRT4.@]
6214 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
6216 NDR_RUNDOWN userRunDownIn)
6218 FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn);
6221 /***********************************************************************
6222 * NDRSContextMarshallEx [RPCRT4.@]
6224 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
6225 NDR_SCONTEXT CContext,
6227 NDR_RUNDOWN userRunDownIn)
6229 FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn);
6232 /***********************************************************************
6233 * NDRSContextMarshall2 [RPCRT4.@]
6235 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
6236 NDR_SCONTEXT CContext,
6238 NDR_RUNDOWN userRunDownIn,
6239 void *CtxGuard, ULONG Flags)
6241 FIXME("(%p %p %p %p %p %u): stub\n",
6242 hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags);
6245 /***********************************************************************
6246 * NDRSContextUnmarshall [RPCRT4.@]
6248 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
6249 ULONG DataRepresentation)
6251 FIXME("(%p %08x): stub\n", pBuff, DataRepresentation);
6255 /***********************************************************************
6256 * NDRSContextUnmarshallEx [RPCRT4.@]
6258 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
6260 ULONG DataRepresentation)
6262 FIXME("(%p %p %08x): stub\n", hBinding, pBuff, DataRepresentation);
6266 /***********************************************************************
6267 * NDRSContextUnmarshall2 [RPCRT4.@]
6269 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
6271 ULONG DataRepresentation,
6272 void *CtxGuard, ULONG Flags)
6274 FIXME("(%p %p %08x %p %u): stub\n",
6275 hBinding, pBuff, DataRepresentation, CtxGuard, Flags);