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
29 * - Checks for out-of-memory conditions
45 #include "wine/unicode.h"
46 #include "wine/rpcfc.h"
48 #include "wine/debug.h"
49 #include "wine/list.h"
51 WINE_DEFAULT_DEBUG_CHANNEL(ole);
54 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
55 (*((UINT32 *)(pchar)) = (uint32))
57 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
58 (*((UINT32 *)(pchar)))
60 /* these would work for i386 too, but less efficient */
61 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
62 (*(pchar) = LOBYTE(LOWORD(uint32)), \
63 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
64 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
65 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
66 (uint32)) /* allow as r-value */
68 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
70 MAKEWORD(*(pchar), *((pchar)+1)), \
71 MAKEWORD(*((pchar)+2), *((pchar)+3))))
74 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
75 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
76 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
77 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
78 *(pchar) = HIBYTE(HIWORD(uint32)), \
79 (uint32)) /* allow as r-value */
81 #define BIG_ENDIAN_UINT32_READ(pchar) \
83 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
84 MAKEWORD(*((pchar)+1), *(pchar))))
86 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
87 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
88 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
89 # define NDR_LOCAL_UINT32_READ(pchar) \
90 BIG_ENDIAN_UINT32_READ(pchar)
92 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
93 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
94 # define NDR_LOCAL_UINT32_READ(pchar) \
95 LITTLE_ENDIAN_UINT32_READ(pchar)
98 /* _Align must be the desired alignment,
99 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
100 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
101 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
102 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
103 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
105 #define STD_OVERFLOW_CHECK(_Msg) do { \
106 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
107 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
108 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
111 #define NDR_TABLE_SIZE 128
112 #define NDR_TABLE_MASK 127
114 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
115 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
116 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
117 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
118 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
120 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
121 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
122 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
124 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
126 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
127 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
128 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
129 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
133 NdrPointerMarshall, NdrPointerMarshall,
134 NdrPointerMarshall, NdrPointerMarshall,
136 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
137 NdrConformantStructMarshall, NdrConformantStructMarshall,
138 NdrConformantVaryingStructMarshall,
139 NdrComplexStructMarshall,
141 NdrConformantArrayMarshall,
142 NdrConformantVaryingArrayMarshall,
143 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
144 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
145 NdrComplexArrayMarshall,
147 NdrConformantStringMarshall, 0, 0,
148 NdrConformantStringMarshall,
149 NdrNonConformantStringMarshall, 0, 0, 0,
151 NdrEncapsulatedUnionMarshall,
152 NdrNonEncapsulatedUnionMarshall,
153 NdrByteCountPointerMarshall,
154 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
156 NdrInterfacePointerMarshall,
158 NdrContextHandleMarshall,
161 NdrUserMarshalMarshall,
166 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
168 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
169 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
170 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
171 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
173 NdrBaseTypeUnmarshall,
175 NdrPointerUnmarshall, NdrPointerUnmarshall,
176 NdrPointerUnmarshall, NdrPointerUnmarshall,
178 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
179 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
180 NdrConformantVaryingStructUnmarshall,
181 NdrComplexStructUnmarshall,
183 NdrConformantArrayUnmarshall,
184 NdrConformantVaryingArrayUnmarshall,
185 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
186 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
187 NdrComplexArrayUnmarshall,
189 NdrConformantStringUnmarshall, 0, 0,
190 NdrConformantStringUnmarshall,
191 NdrNonConformantStringUnmarshall, 0, 0, 0,
193 NdrEncapsulatedUnionUnmarshall,
194 NdrNonEncapsulatedUnionUnmarshall,
195 NdrByteCountPointerUnmarshall,
196 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
198 NdrInterfacePointerUnmarshall,
200 NdrContextHandleUnmarshall,
203 NdrUserMarshalUnmarshall,
208 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
210 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
211 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
212 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
213 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
215 NdrBaseTypeBufferSize,
217 NdrPointerBufferSize, NdrPointerBufferSize,
218 NdrPointerBufferSize, NdrPointerBufferSize,
220 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
221 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
222 NdrConformantVaryingStructBufferSize,
223 NdrComplexStructBufferSize,
225 NdrConformantArrayBufferSize,
226 NdrConformantVaryingArrayBufferSize,
227 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
228 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
229 NdrComplexArrayBufferSize,
231 NdrConformantStringBufferSize, 0, 0,
232 NdrConformantStringBufferSize,
233 NdrNonConformantStringBufferSize, 0, 0, 0,
235 NdrEncapsulatedUnionBufferSize,
236 NdrNonEncapsulatedUnionBufferSize,
237 NdrByteCountPointerBufferSize,
238 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
240 NdrInterfacePointerBufferSize,
242 NdrContextHandleBufferSize,
245 NdrUserMarshalBufferSize,
250 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
252 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
253 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
254 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
255 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
257 NdrBaseTypeMemorySize,
259 NdrPointerMemorySize, NdrPointerMemorySize,
260 NdrPointerMemorySize, NdrPointerMemorySize,
262 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
263 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
264 NdrConformantVaryingStructMemorySize,
265 NdrComplexStructMemorySize,
267 NdrConformantArrayMemorySize,
268 NdrConformantVaryingArrayMemorySize,
269 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
270 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
271 NdrComplexArrayMemorySize,
273 NdrConformantStringMemorySize, 0, 0,
274 NdrConformantStringMemorySize,
275 NdrNonConformantStringMemorySize, 0, 0, 0,
277 NdrEncapsulatedUnionMemorySize,
278 NdrNonEncapsulatedUnionMemorySize,
279 NdrByteCountPointerMemorySize,
280 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
282 NdrInterfacePointerMemorySize,
287 NdrUserMarshalMemorySize,
292 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
294 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
295 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
296 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
297 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
301 NdrPointerFree, NdrPointerFree,
302 NdrPointerFree, NdrPointerFree,
304 NdrSimpleStructFree, NdrSimpleStructFree,
305 NdrConformantStructFree, NdrConformantStructFree,
306 NdrConformantVaryingStructFree,
307 NdrComplexStructFree,
309 NdrConformantArrayFree,
310 NdrConformantVaryingArrayFree,
311 NdrFixedArrayFree, NdrFixedArrayFree,
312 NdrVaryingArrayFree, NdrVaryingArrayFree,
318 NdrEncapsulatedUnionFree,
319 NdrNonEncapsulatedUnionFree,
321 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
323 NdrInterfacePointerFree,
334 typedef struct _NDR_MEMORY_LIST
339 struct _NDR_MEMORY_LIST *next;
342 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
344 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
349 NDR_MEMORY_LIST *mem_list;
351 aligned_len = ALIGNED_LENGTH(len, 8);
352 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
353 /* check for overflow */
354 if (adjusted_len < len)
356 ERR("overflow of adjusted_len %d, len %d\n", adjusted_len, len);
357 RpcRaiseException(RPC_X_BAD_STUB_DATA);
360 p = pStubMsg->pfnAllocate(adjusted_len);
361 if (!p) RpcRaiseException(ERROR_OUTOFMEMORY);
363 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
364 mem_list->magic = MEML_MAGIC;
365 mem_list->size = aligned_len;
366 mem_list->reserved = 0;
367 mem_list->next = pStubMsg->pMemoryList;
368 pStubMsg->pMemoryList = mem_list;
374 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
376 NDR_MEMORY_LIST *mem_list, *prev_mem_list;
378 TRACE("(%p, %p)\n", pStubMsg, Pointer);
380 for (prev_mem_list = NULL, mem_list = pStubMsg->pMemoryList;
382 prev_mem_list = mem_list, mem_list = mem_list->next)
384 const unsigned char *base_pointer = (unsigned char *)mem_list - mem_list->size;
385 if (base_pointer == Pointer)
387 if (mem_list->magic != MEML_MAGIC)
389 ERR("memory linked list corrupted, magic changed to 0x%08x\n", mem_list->magic);
393 /* fixup next pointers */
395 prev_mem_list->next = mem_list->next;
397 pStubMsg->pMemoryList = mem_list->next;
398 pStubMsg->pfnFree(Pointer);
404 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
406 return (*(const ULONG *)pFormat != -1);
409 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
411 ALIGN_POINTER(pStubMsg->Buffer, 4);
412 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
413 RpcRaiseException(RPC_X_BAD_STUB_DATA);
414 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
415 pStubMsg->Buffer += 4;
416 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
417 if (pStubMsg->fHasNewCorrDesc)
423 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
425 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
427 pStubMsg->Offset = 0;
428 pStubMsg->ActualCount = pStubMsg->MaxCount;
432 ALIGN_POINTER(pStubMsg->Buffer, 4);
433 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
434 RpcRaiseException(RPC_X_BAD_STUB_DATA);
435 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
436 pStubMsg->Buffer += 4;
437 TRACE("offset is %d\n", pStubMsg->Offset);
438 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
439 pStubMsg->Buffer += 4;
440 TRACE("variance is %d\n", pStubMsg->ActualCount);
442 if ((pStubMsg->ActualCount > MaxValue) ||
443 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
445 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
446 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
447 RpcRaiseException(RPC_S_INVALID_BOUND);
452 if (pStubMsg->fHasNewCorrDesc)
458 /* writes the conformance value to the buffer */
459 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
461 ALIGN_POINTER(pStubMsg->Buffer, 4);
462 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
463 RpcRaiseException(RPC_X_BAD_STUB_DATA);
464 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
465 pStubMsg->Buffer += 4;
468 /* writes the variance values to the buffer */
469 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
471 ALIGN_POINTER(pStubMsg->Buffer, 4);
472 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
473 RpcRaiseException(RPC_X_BAD_STUB_DATA);
474 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
475 pStubMsg->Buffer += 4;
476 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
477 pStubMsg->Buffer += 4;
480 /* requests buffer space for the conformance value */
481 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
483 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
484 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
485 RpcRaiseException(RPC_X_BAD_STUB_DATA);
486 pStubMsg->BufferLength += 4;
489 /* requests buffer space for the variance values */
490 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
492 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
493 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
494 RpcRaiseException(RPC_X_BAD_STUB_DATA);
495 pStubMsg->BufferLength += 8;
498 PFORMAT_STRING ComputeConformanceOrVariance(
499 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
500 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
502 BYTE dtype = pFormat[0] & 0xf;
503 short ofs = *(const short *)&pFormat[2];
507 if (!IsConformanceOrVariancePresent(pFormat)) {
508 /* null descriptor */
513 switch (pFormat[0] & 0xf0) {
514 case RPC_FC_NORMAL_CONFORMANCE:
515 TRACE("normal conformance, ofs=%d\n", ofs);
518 case RPC_FC_POINTER_CONFORMANCE:
519 TRACE("pointer conformance, ofs=%d\n", ofs);
520 ptr = pStubMsg->Memory;
522 case RPC_FC_TOP_LEVEL_CONFORMANCE:
523 TRACE("toplevel conformance, ofs=%d\n", ofs);
524 if (pStubMsg->StackTop) {
525 ptr = pStubMsg->StackTop;
528 /* -Os mode, *pCount is already set */
532 case RPC_FC_CONSTANT_CONFORMANCE:
533 data = ofs | ((DWORD)pFormat[1] << 16);
534 TRACE("constant conformance, val=%d\n", data);
537 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
538 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
539 if (pStubMsg->StackTop) {
540 ptr = pStubMsg->StackTop;
548 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
551 switch (pFormat[1]) {
552 case RPC_FC_DEREFERENCE:
553 ptr = *(LPVOID*)((char *)ptr + ofs);
555 case RPC_FC_CALLBACK:
557 unsigned char *old_stack_top = pStubMsg->StackTop;
558 pStubMsg->StackTop = ptr;
560 /* ofs is index into StubDesc->apfnExprEval */
561 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
562 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
564 pStubMsg->StackTop = old_stack_top;
566 /* the callback function always stores the computed value in MaxCount */
567 *pCount = pStubMsg->MaxCount;
571 ptr = (char *)ptr + ofs;
584 data = *(USHORT*)ptr;
595 FIXME("unknown conformance data type %x\n", dtype);
598 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
601 switch (pFormat[1]) {
602 case RPC_FC_DEREFERENCE: /* already handled */
619 FIXME("unknown conformance op %d\n", pFormat[1]);
624 TRACE("resulting conformance is %ld\n", *pCount);
625 if (pStubMsg->fHasNewCorrDesc)
631 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
632 * the result overflows 32-bits */
633 static inline ULONG safe_multiply(ULONG a, ULONG b)
635 ULONGLONG ret = (ULONGLONG)a * b;
636 if (ret > 0xffffffff)
638 RpcRaiseException(RPC_S_INVALID_BOUND);
644 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
646 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
647 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
648 RpcRaiseException(RPC_X_BAD_STUB_DATA);
649 pStubMsg->Buffer += size;
652 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
654 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
656 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
657 pStubMsg->BufferLength, size);
658 RpcRaiseException(RPC_X_BAD_STUB_DATA);
660 pStubMsg->BufferLength += size;
663 /* copies data from the buffer, checking that there is enough data in the buffer
665 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
667 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
668 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
669 RpcRaiseException(RPC_X_BAD_STUB_DATA);
670 memcpy(p, pStubMsg->Buffer, size);
671 pStubMsg->Buffer += size;
674 /* copies data to the buffer, checking that there is enough space to do so */
675 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
677 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
678 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
680 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
681 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
683 RpcRaiseException(RPC_X_BAD_STUB_DATA);
685 memcpy(pStubMsg->Buffer, p, size);
686 pStubMsg->Buffer += size;
690 * NdrConformantString:
692 * What MS calls a ConformantString is, in DCE terminology,
693 * a Varying-Conformant String.
695 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
696 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
697 * into unmarshalled string)
698 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
700 * data: CHARTYPE[maxlen]
702 * ], where CHARTYPE is the appropriate character type (specified externally)
706 /***********************************************************************
707 * NdrConformantStringMarshall [RPCRT4.@]
709 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
710 unsigned char *pszMessage, PFORMAT_STRING pFormat)
714 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
716 if (*pFormat == RPC_FC_C_CSTRING) {
717 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
718 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
721 else if (*pFormat == RPC_FC_C_WSTRING) {
722 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
723 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
727 ERR("Unhandled string type: %#x\n", *pFormat);
728 /* FIXME: raise an exception. */
732 if (pFormat[1] == RPC_FC_STRING_SIZED)
733 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
735 pStubMsg->MaxCount = pStubMsg->ActualCount;
736 pStubMsg->Offset = 0;
737 WriteConformance(pStubMsg);
738 WriteVariance(pStubMsg);
740 size = safe_multiply(esize, pStubMsg->ActualCount);
741 safe_copy_to_buffer(pStubMsg, pszMessage, size); /* the string itself */
744 return NULL; /* is this always right? */
747 /***********************************************************************
748 * NdrConformantStringBufferSize [RPCRT4.@]
750 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
751 unsigned char* pMemory, PFORMAT_STRING pFormat)
755 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
757 SizeConformance(pStubMsg);
758 SizeVariance(pStubMsg);
760 if (*pFormat == RPC_FC_C_CSTRING) {
761 TRACE("string=%s\n", debugstr_a((char*)pMemory));
762 pStubMsg->ActualCount = strlen((char*)pMemory)+1;
765 else if (*pFormat == RPC_FC_C_WSTRING) {
766 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
767 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;
771 ERR("Unhandled string type: %#x\n", *pFormat);
772 /* FIXME: raise an exception */
776 if (pFormat[1] == RPC_FC_STRING_SIZED)
777 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
779 pStubMsg->MaxCount = pStubMsg->ActualCount;
781 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
784 /************************************************************************
785 * NdrConformantStringMemorySize [RPCRT4.@]
787 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
788 PFORMAT_STRING pFormat )
792 FIXME("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
794 assert(pStubMsg && pFormat);
796 if (*pFormat == RPC_FC_C_CSTRING) {
797 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
799 else if (*pFormat == RPC_FC_C_WSTRING) {
800 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
803 ERR("Unhandled string type: %#x\n", *pFormat);
804 /* FIXME: raise an exception */
807 if (pFormat[1] != RPC_FC_PAD) {
808 FIXME("sized string format=%d\n", pFormat[1]);
811 TRACE(" --> %u\n", rslt);
815 /************************************************************************
816 * NdrConformantStringUnmarshall [RPCRT4.@]
818 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
819 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
821 ULONG bufsize, memsize, esize, i;
823 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
824 pStubMsg, *ppMemory, pFormat, fMustAlloc);
826 assert(pFormat && ppMemory && pStubMsg);
828 ReadConformance(pStubMsg, NULL);
829 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
831 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
832 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
834 ERR("Unhandled string type: %#x\n", *pFormat);
835 /* FIXME: raise an exception */
839 memsize = safe_multiply(esize, pStubMsg->MaxCount);
840 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
842 /* strings must always have null terminating bytes */
845 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
846 RpcRaiseException(RPC_S_INVALID_BOUND);
850 /* verify the buffer is safe to access */
851 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
852 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
854 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
855 pStubMsg->BufferEnd, pStubMsg->Buffer);
856 RpcRaiseException(RPC_X_BAD_STUB_DATA);
860 for (i = bufsize - esize; i < bufsize; i++)
861 if (pStubMsg->Buffer[i] != 0)
863 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
864 i, pStubMsg->Buffer[i]);
865 RpcRaiseException(RPC_S_INVALID_BOUND);
869 if (fMustAlloc || !*ppMemory)
870 *ppMemory = NdrAllocate(pStubMsg, memsize);
872 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
874 if (*pFormat == RPC_FC_C_CSTRING) {
875 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
877 else if (*pFormat == RPC_FC_C_WSTRING) {
878 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
881 return NULL; /* FIXME: is this always right? */
884 /***********************************************************************
885 * NdrNonConformantStringMarshall [RPCRT4.@]
887 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
888 unsigned char *pMemory,
889 PFORMAT_STRING pFormat)
895 /***********************************************************************
896 * NdrNonConformantStringUnmarshall [RPCRT4.@]
898 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
899 unsigned char **ppMemory,
900 PFORMAT_STRING pFormat,
901 unsigned char fMustAlloc)
907 /***********************************************************************
908 * NdrNonConformantStringBufferSize [RPCRT4.@]
910 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
911 unsigned char *pMemory,
912 PFORMAT_STRING pFormat)
917 /***********************************************************************
918 * NdrNonConformantStringMemorySize [RPCRT4.@]
920 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
921 PFORMAT_STRING pFormat)
927 static inline void dump_pointer_attr(unsigned char attr)
929 if (attr & RPC_FC_P_ALLOCALLNODES)
930 TRACE(" RPC_FC_P_ALLOCALLNODES");
931 if (attr & RPC_FC_P_DONTFREE)
932 TRACE(" RPC_FC_P_DONTFREE");
933 if (attr & RPC_FC_P_ONSTACK)
934 TRACE(" RPC_FC_P_ONSTACK");
935 if (attr & RPC_FC_P_SIMPLEPOINTER)
936 TRACE(" RPC_FC_P_SIMPLEPOINTER");
937 if (attr & RPC_FC_P_DEREF)
938 TRACE(" RPC_FC_P_DEREF");
942 /***********************************************************************
943 * PointerMarshall [internal]
945 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
946 unsigned char *Buffer,
947 unsigned char *Pointer,
948 PFORMAT_STRING pFormat)
950 unsigned type = pFormat[0], attr = pFormat[1];
954 int pointer_needs_marshaling;
956 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
957 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
959 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
960 else desc = pFormat + *(const SHORT*)pFormat;
963 case RPC_FC_RP: /* ref pointer (always non-null) */
966 ERR("NULL ref pointer is not allowed\n");
967 RpcRaiseException(RPC_X_NULL_REF_POINTER);
969 pointer_needs_marshaling = 1;
971 case RPC_FC_UP: /* unique pointer */
972 case RPC_FC_OP: /* object pointer - same as unique here */
974 pointer_needs_marshaling = 1;
976 pointer_needs_marshaling = 0;
977 pointer_id = (ULONG)Pointer;
978 TRACE("writing 0x%08x to buffer\n", pointer_id);
979 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
982 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
983 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
984 TRACE("writing 0x%08x to buffer\n", pointer_id);
985 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
988 FIXME("unhandled ptr type=%02x\n", type);
989 RpcRaiseException(RPC_X_BAD_STUB_DATA);
993 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
995 if (pointer_needs_marshaling) {
996 if (attr & RPC_FC_P_DEREF) {
997 Pointer = *(unsigned char**)Pointer;
998 TRACE("deref => %p\n", Pointer);
1000 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1001 if (m) m(pStubMsg, Pointer, desc);
1002 else FIXME("no marshaller for data type=%02x\n", *desc);
1005 STD_OVERFLOW_CHECK(pStubMsg);
1008 /***********************************************************************
1009 * PointerUnmarshall [internal]
1011 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1012 unsigned char *Buffer,
1013 unsigned char **pPointer,
1014 unsigned char *pSrcPointer,
1015 PFORMAT_STRING pFormat,
1016 unsigned char fMustAlloc)
1018 unsigned type = pFormat[0], attr = pFormat[1];
1019 PFORMAT_STRING desc;
1021 DWORD pointer_id = 0;
1022 int pointer_needs_unmarshaling;
1024 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
1025 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1027 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1028 else desc = pFormat + *(const SHORT*)pFormat;
1031 case RPC_FC_RP: /* ref pointer (always non-null) */
1032 pointer_needs_unmarshaling = 1;
1034 case RPC_FC_UP: /* unique pointer */
1035 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1036 TRACE("pointer_id is 0x%08x\n", pointer_id);
1038 pointer_needs_unmarshaling = 1;
1041 pointer_needs_unmarshaling = 0;
1044 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1045 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1046 TRACE("pointer_id is 0x%08x\n", pointer_id);
1047 if (!fMustAlloc && pSrcPointer)
1049 FIXME("free object pointer %p\n", pSrcPointer);
1053 pointer_needs_unmarshaling = 1;
1055 pointer_needs_unmarshaling = 0;
1058 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1059 TRACE("pointer_id is 0x%08x\n", pointer_id);
1060 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
1061 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
1064 FIXME("unhandled ptr type=%02x\n", type);
1065 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1069 if (pointer_needs_unmarshaling) {
1070 unsigned char *base_ptr_val = *pPointer;
1071 unsigned char **current_ptr = pPointer;
1072 if (pStubMsg->IsClient) {
1074 /* if we aren't forcing allocation of memory then try to use the existing
1075 * (source) pointer to unmarshall the data into so that [in,out]
1076 * parameters behave correctly. it doesn't matter if the parameter is
1077 * [out] only since in that case the pointer will be NULL. we force
1078 * allocation when the source pointer is NULL here instead of in the type
1079 * unmarshalling routine for the benefit of the deref code below */
1082 TRACE("setting *pPointer to %p\n", pSrcPointer);
1083 *pPointer = base_ptr_val = pSrcPointer;
1089 /* the memory in a stub is never initialised, so we have to work out here
1090 * whether we have to initialise it so we can use the optimisation of
1091 * setting the pointer to the buffer, if possible, or set fMustAlloc to
1093 if (attr & RPC_FC_P_DEREF) {
1096 base_ptr_val = NULL;
1097 *current_ptr = NULL;
1101 if (attr & RPC_FC_P_DEREF) {
1103 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
1104 *pPointer = base_ptr_val;
1105 current_ptr = (unsigned char **)base_ptr_val;
1107 current_ptr = *(unsigned char***)current_ptr;
1108 TRACE("deref => %p\n", current_ptr);
1109 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
1111 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1112 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
1113 else FIXME("no unmarshaller for data type=%02x\n", *desc);
1115 if (type == RPC_FC_FP)
1116 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
1120 TRACE("pointer=%p\n", *pPointer);
1123 /***********************************************************************
1124 * PointerBufferSize [internal]
1126 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1127 unsigned char *Pointer,
1128 PFORMAT_STRING pFormat)
1130 unsigned type = pFormat[0], attr = pFormat[1];
1131 PFORMAT_STRING desc;
1133 int pointer_needs_sizing;
1136 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1137 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1139 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1140 else desc = pFormat + *(const SHORT*)pFormat;
1143 case RPC_FC_RP: /* ref pointer (always non-null) */
1146 ERR("NULL ref pointer is not allowed\n");
1147 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1152 /* NULL pointer has no further representation */
1157 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1158 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1159 if (!pointer_needs_sizing)
1163 FIXME("unhandled ptr type=%02x\n", type);
1164 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1168 if (attr & RPC_FC_P_DEREF) {
1169 Pointer = *(unsigned char**)Pointer;
1170 TRACE("deref => %p\n", Pointer);
1173 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1174 if (m) m(pStubMsg, Pointer, desc);
1175 else FIXME("no buffersizer for data type=%02x\n", *desc);
1178 /***********************************************************************
1179 * PointerMemorySize [internal]
1181 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1182 unsigned char *Buffer,
1183 PFORMAT_STRING pFormat)
1185 unsigned type = pFormat[0], attr = pFormat[1];
1186 PFORMAT_STRING desc;
1188 DWORD pointer_id = 0;
1189 int pointer_needs_sizing;
1191 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1192 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1194 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1195 else desc = pFormat + *(const SHORT*)pFormat;
1198 case RPC_FC_RP: /* ref pointer (always non-null) */
1199 pointer_needs_sizing = 1;
1201 case RPC_FC_UP: /* unique pointer */
1202 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1203 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1204 TRACE("pointer_id is 0x%08x\n", pointer_id);
1206 pointer_needs_sizing = 1;
1208 pointer_needs_sizing = 0;
1213 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1214 TRACE("pointer_id is 0x%08x\n", pointer_id);
1215 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1216 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1220 FIXME("unhandled ptr type=%02x\n", type);
1221 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1225 if (attr & RPC_FC_P_DEREF) {
1229 if (pointer_needs_sizing) {
1230 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1231 if (m) m(pStubMsg, desc);
1232 else FIXME("no memorysizer for data type=%02x\n", *desc);
1235 return pStubMsg->MemorySize;
1238 /***********************************************************************
1239 * PointerFree [internal]
1241 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1242 unsigned char *Pointer,
1243 PFORMAT_STRING pFormat)
1245 unsigned type = pFormat[0], attr = pFormat[1];
1246 PFORMAT_STRING desc;
1249 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1250 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1251 if (attr & RPC_FC_P_DONTFREE) return;
1253 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1254 else desc = pFormat + *(const SHORT*)pFormat;
1256 if (!Pointer) return;
1258 if (type == RPC_FC_FP) {
1259 int pointer_needs_freeing = NdrFullPointerFree(
1260 pStubMsg->FullPtrXlatTables, Pointer);
1261 if (!pointer_needs_freeing)
1265 if (attr & RPC_FC_P_DEREF) {
1266 Pointer = *(unsigned char**)Pointer;
1267 TRACE("deref => %p\n", Pointer);
1270 m = NdrFreer[*desc & NDR_TABLE_MASK];
1271 if (m) m(pStubMsg, Pointer, desc);
1273 /* this check stops us from trying to free buffer memory. we don't have to
1274 * worry about clients, since they won't call this function.
1275 * we don't have to check for the buffer being reallocated because
1276 * BufferStart and BufferEnd won't be reset when allocating memory for
1277 * sending the response. we don't have to check for the new buffer here as
1278 * it won't be used a type memory, only for buffer memory */
1279 if (Pointer >= (unsigned char *)pStubMsg->BufferStart &&
1280 Pointer < (unsigned char *)pStubMsg->BufferEnd)
1283 if (attr & RPC_FC_P_ONSTACK) {
1284 TRACE("not freeing stack ptr %p\n", Pointer);
1287 TRACE("freeing %p\n", Pointer);
1288 NdrFree(pStubMsg, Pointer);
1291 TRACE("not freeing %p\n", Pointer);
1294 /***********************************************************************
1295 * EmbeddedPointerMarshall
1297 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1298 unsigned char *pMemory,
1299 PFORMAT_STRING pFormat)
1301 unsigned char *Mark = pStubMsg->BufferMark;
1302 unsigned rep, count, stride;
1304 unsigned char *saved_buffer = NULL;
1306 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1308 if (*pFormat != RPC_FC_PP) return NULL;
1311 if (pStubMsg->PointerBufferMark)
1313 saved_buffer = pStubMsg->Buffer;
1314 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1315 pStubMsg->PointerBufferMark = NULL;
1318 while (pFormat[0] != RPC_FC_END) {
1319 switch (pFormat[0]) {
1321 FIXME("unknown repeat type %d\n", pFormat[0]);
1322 case RPC_FC_NO_REPEAT:
1328 case RPC_FC_FIXED_REPEAT:
1329 rep = *(const WORD*)&pFormat[2];
1330 stride = *(const WORD*)&pFormat[4];
1331 count = *(const WORD*)&pFormat[8];
1334 case RPC_FC_VARIABLE_REPEAT:
1335 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1336 stride = *(const WORD*)&pFormat[2];
1337 count = *(const WORD*)&pFormat[6];
1341 for (i = 0; i < rep; i++) {
1342 PFORMAT_STRING info = pFormat;
1343 unsigned char *membase = pMemory + (i * stride);
1344 unsigned char *bufbase = Mark + (i * stride);
1347 for (u=0; u<count; u++,info+=8) {
1348 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1349 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1350 unsigned char *saved_memory = pStubMsg->Memory;
1352 pStubMsg->Memory = pMemory;
1353 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1354 pStubMsg->Memory = saved_memory;
1357 pFormat += 8 * count;
1362 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1363 pStubMsg->Buffer = saved_buffer;
1366 STD_OVERFLOW_CHECK(pStubMsg);
1371 /***********************************************************************
1372 * EmbeddedPointerUnmarshall
1374 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1375 unsigned char *pDstMemoryPtrs,
1376 unsigned char *pSrcMemoryPtrs,
1377 PFORMAT_STRING pFormat,
1378 unsigned char fMustAlloc)
1380 unsigned char *Mark = pStubMsg->BufferMark;
1381 unsigned rep, count, stride;
1383 unsigned char *saved_buffer = NULL;
1385 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstMemoryPtrs, pSrcMemoryPtrs, pFormat, fMustAlloc);
1387 if (*pFormat != RPC_FC_PP) return NULL;
1390 if (pStubMsg->PointerBufferMark)
1392 saved_buffer = pStubMsg->Buffer;
1393 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1394 pStubMsg->PointerBufferMark = NULL;
1397 while (pFormat[0] != RPC_FC_END) {
1398 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1399 switch (pFormat[0]) {
1401 FIXME("unknown repeat type %d\n", pFormat[0]);
1402 case RPC_FC_NO_REPEAT:
1408 case RPC_FC_FIXED_REPEAT:
1409 rep = *(const WORD*)&pFormat[2];
1410 stride = *(const WORD*)&pFormat[4];
1411 count = *(const WORD*)&pFormat[8];
1414 case RPC_FC_VARIABLE_REPEAT:
1415 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1416 stride = *(const WORD*)&pFormat[2];
1417 count = *(const WORD*)&pFormat[6];
1421 for (i = 0; i < rep; i++) {
1422 PFORMAT_STRING info = pFormat;
1423 unsigned char *memdstbase = pDstMemoryPtrs + (i * stride);
1424 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1425 unsigned char *bufbase = Mark + (i * stride);
1428 for (u=0; u<count; u++,info+=8) {
1429 unsigned char **memdstptr = (unsigned char **)(memdstbase + *(const SHORT*)&info[0]);
1430 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1431 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1432 PointerUnmarshall(pStubMsg, bufptr, memdstptr, *memsrcptr, info+4, fMustAlloc);
1435 pFormat += 8 * count;
1440 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1441 pStubMsg->Buffer = saved_buffer;
1447 /***********************************************************************
1448 * EmbeddedPointerBufferSize
1450 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1451 unsigned char *pMemory,
1452 PFORMAT_STRING pFormat)
1454 unsigned rep, count, stride;
1456 ULONG saved_buffer_length = 0;
1458 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1460 if (pStubMsg->IgnoreEmbeddedPointers) return;
1462 if (*pFormat != RPC_FC_PP) return;
1465 if (pStubMsg->PointerLength)
1467 saved_buffer_length = pStubMsg->BufferLength;
1468 pStubMsg->BufferLength = pStubMsg->PointerLength;
1469 pStubMsg->PointerLength = 0;
1472 while (pFormat[0] != RPC_FC_END) {
1473 switch (pFormat[0]) {
1475 FIXME("unknown repeat type %d\n", pFormat[0]);
1476 case RPC_FC_NO_REPEAT:
1482 case RPC_FC_FIXED_REPEAT:
1483 rep = *(const WORD*)&pFormat[2];
1484 stride = *(const WORD*)&pFormat[4];
1485 count = *(const WORD*)&pFormat[8];
1488 case RPC_FC_VARIABLE_REPEAT:
1489 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1490 stride = *(const WORD*)&pFormat[2];
1491 count = *(const WORD*)&pFormat[6];
1495 for (i = 0; i < rep; i++) {
1496 PFORMAT_STRING info = pFormat;
1497 unsigned char *membase = pMemory + (i * stride);
1500 for (u=0; u<count; u++,info+=8) {
1501 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1502 unsigned char *saved_memory = pStubMsg->Memory;
1504 pStubMsg->Memory = pMemory;
1505 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1506 pStubMsg->Memory = saved_memory;
1509 pFormat += 8 * count;
1512 if (saved_buffer_length)
1514 pStubMsg->PointerLength = pStubMsg->BufferLength;
1515 pStubMsg->BufferLength = saved_buffer_length;
1519 /***********************************************************************
1520 * EmbeddedPointerMemorySize [internal]
1522 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1523 PFORMAT_STRING pFormat)
1525 unsigned char *Mark = pStubMsg->BufferMark;
1526 unsigned rep, count, stride;
1528 unsigned char *saved_buffer = NULL;
1530 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1532 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1534 if (pStubMsg->PointerBufferMark)
1536 saved_buffer = pStubMsg->Buffer;
1537 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1538 pStubMsg->PointerBufferMark = NULL;
1541 if (*pFormat != RPC_FC_PP) return 0;
1544 while (pFormat[0] != RPC_FC_END) {
1545 switch (pFormat[0]) {
1547 FIXME("unknown repeat type %d\n", pFormat[0]);
1548 case RPC_FC_NO_REPEAT:
1554 case RPC_FC_FIXED_REPEAT:
1555 rep = *(const WORD*)&pFormat[2];
1556 stride = *(const WORD*)&pFormat[4];
1557 count = *(const WORD*)&pFormat[8];
1560 case RPC_FC_VARIABLE_REPEAT:
1561 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1562 stride = *(const WORD*)&pFormat[2];
1563 count = *(const WORD*)&pFormat[6];
1567 for (i = 0; i < rep; i++) {
1568 PFORMAT_STRING info = pFormat;
1569 unsigned char *bufbase = Mark + (i * stride);
1571 for (u=0; u<count; u++,info+=8) {
1572 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1573 PointerMemorySize(pStubMsg, bufptr, info+4);
1576 pFormat += 8 * count;
1581 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1582 pStubMsg->Buffer = saved_buffer;
1588 /***********************************************************************
1589 * EmbeddedPointerFree [internal]
1591 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1592 unsigned char *pMemory,
1593 PFORMAT_STRING pFormat)
1595 unsigned rep, count, stride;
1598 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1599 if (*pFormat != RPC_FC_PP) return;
1602 while (pFormat[0] != RPC_FC_END) {
1603 switch (pFormat[0]) {
1605 FIXME("unknown repeat type %d\n", pFormat[0]);
1606 case RPC_FC_NO_REPEAT:
1612 case RPC_FC_FIXED_REPEAT:
1613 rep = *(const WORD*)&pFormat[2];
1614 stride = *(const WORD*)&pFormat[4];
1615 count = *(const WORD*)&pFormat[8];
1618 case RPC_FC_VARIABLE_REPEAT:
1619 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1620 stride = *(const WORD*)&pFormat[2];
1621 count = *(const WORD*)&pFormat[6];
1625 for (i = 0; i < rep; i++) {
1626 PFORMAT_STRING info = pFormat;
1627 unsigned char *membase = pMemory + (i * stride);
1630 for (u=0; u<count; u++,info+=8) {
1631 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1632 unsigned char *saved_memory = pStubMsg->Memory;
1634 pStubMsg->Memory = pMemory;
1635 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1636 pStubMsg->Memory = saved_memory;
1639 pFormat += 8 * count;
1643 /***********************************************************************
1644 * NdrPointerMarshall [RPCRT4.@]
1646 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1647 unsigned char *pMemory,
1648 PFORMAT_STRING pFormat)
1650 unsigned char *Buffer;
1652 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1654 /* incremement the buffer here instead of in PointerMarshall,
1655 * as that is used by embedded pointers which already handle the incrementing
1656 * the buffer, and shouldn't write any additional pointer data to the wire */
1657 if (*pFormat != RPC_FC_RP)
1659 ALIGN_POINTER(pStubMsg->Buffer, 4);
1660 Buffer = pStubMsg->Buffer;
1661 safe_buffer_increment(pStubMsg, 4);
1664 Buffer = pStubMsg->Buffer;
1666 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1671 /***********************************************************************
1672 * NdrPointerUnmarshall [RPCRT4.@]
1674 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1675 unsigned char **ppMemory,
1676 PFORMAT_STRING pFormat,
1677 unsigned char fMustAlloc)
1679 unsigned char *Buffer;
1681 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1683 /* incremement the buffer here instead of in PointerUnmarshall,
1684 * as that is used by embedded pointers which already handle the incrementing
1685 * the buffer, and shouldn't read any additional pointer data from the
1687 if (*pFormat != RPC_FC_RP)
1689 ALIGN_POINTER(pStubMsg->Buffer, 4);
1690 Buffer = pStubMsg->Buffer;
1691 safe_buffer_increment(pStubMsg, 4);
1694 Buffer = pStubMsg->Buffer;
1696 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1701 /***********************************************************************
1702 * NdrPointerBufferSize [RPCRT4.@]
1704 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1705 unsigned char *pMemory,
1706 PFORMAT_STRING pFormat)
1708 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1710 /* incremement the buffer length here instead of in PointerBufferSize,
1711 * as that is used by embedded pointers which already handle the buffer
1712 * length, and shouldn't write anything more to the wire */
1713 if (*pFormat != RPC_FC_RP)
1715 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1716 safe_buffer_length_increment(pStubMsg, 4);
1719 PointerBufferSize(pStubMsg, pMemory, pFormat);
1722 /***********************************************************************
1723 * NdrPointerMemorySize [RPCRT4.@]
1725 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1726 PFORMAT_STRING pFormat)
1728 /* unsigned size = *(LPWORD)(pFormat+2); */
1729 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1730 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1734 /***********************************************************************
1735 * NdrPointerFree [RPCRT4.@]
1737 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1738 unsigned char *pMemory,
1739 PFORMAT_STRING pFormat)
1741 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1742 PointerFree(pStubMsg, pMemory, pFormat);
1745 /***********************************************************************
1746 * NdrSimpleTypeMarshall [RPCRT4.@]
1748 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1749 unsigned char FormatChar )
1751 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1754 /***********************************************************************
1755 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1757 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1758 unsigned char FormatChar )
1760 NdrBaseTypeUnmarshall(pStubMsg, &pMemory, &FormatChar, 0);
1763 /***********************************************************************
1764 * NdrSimpleStructMarshall [RPCRT4.@]
1766 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1767 unsigned char *pMemory,
1768 PFORMAT_STRING pFormat)
1770 unsigned size = *(const WORD*)(pFormat+2);
1771 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1773 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1775 pStubMsg->BufferMark = pStubMsg->Buffer;
1776 safe_copy_to_buffer(pStubMsg, pMemory, size);
1778 if (pFormat[0] != RPC_FC_STRUCT)
1779 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1784 /***********************************************************************
1785 * NdrSimpleStructUnmarshall [RPCRT4.@]
1787 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1788 unsigned char **ppMemory,
1789 PFORMAT_STRING pFormat,
1790 unsigned char fMustAlloc)
1792 unsigned size = *(const WORD*)(pFormat+2);
1793 unsigned char *saved_buffer;
1794 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1796 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1799 *ppMemory = NdrAllocate(pStubMsg, size);
1802 if (!pStubMsg->IsClient && !*ppMemory)
1803 /* for servers, we just point straight into the RPC buffer */
1804 *ppMemory = pStubMsg->Buffer;
1807 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1808 safe_buffer_increment(pStubMsg, size);
1809 if (pFormat[0] == RPC_FC_PSTRUCT)
1810 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1812 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1813 if (*ppMemory != saved_buffer)
1814 memcpy(*ppMemory, saved_buffer, size);
1819 /***********************************************************************
1820 * NdrSimpleStructBufferSize [RPCRT4.@]
1822 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1823 unsigned char *pMemory,
1824 PFORMAT_STRING pFormat)
1826 unsigned size = *(const WORD*)(pFormat+2);
1827 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1829 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1831 safe_buffer_length_increment(pStubMsg, size);
1832 if (pFormat[0] != RPC_FC_STRUCT)
1833 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1836 /***********************************************************************
1837 * NdrSimpleStructMemorySize [RPCRT4.@]
1839 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1840 PFORMAT_STRING pFormat)
1842 unsigned short size = *(const WORD *)(pFormat+2);
1844 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1846 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1847 pStubMsg->MemorySize += size;
1848 safe_buffer_increment(pStubMsg, size);
1850 if (pFormat[0] != RPC_FC_STRUCT)
1851 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1852 return pStubMsg->MemorySize;
1855 /***********************************************************************
1856 * NdrSimpleStructFree [RPCRT4.@]
1858 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1859 unsigned char *pMemory,
1860 PFORMAT_STRING pFormat)
1862 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1863 if (pFormat[0] != RPC_FC_STRUCT)
1864 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1868 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE *pStubMsg,
1869 PFORMAT_STRING pFormat)
1873 case RPC_FC_PSTRUCT:
1874 case RPC_FC_CSTRUCT:
1875 case RPC_FC_BOGUS_STRUCT:
1876 case RPC_FC_SMFARRAY:
1877 case RPC_FC_SMVARRAY:
1878 return *(const WORD*)&pFormat[2];
1879 case RPC_FC_USER_MARSHAL:
1880 return *(const WORD*)&pFormat[4];
1881 case RPC_FC_NON_ENCAPSULATED_UNION:
1883 if (pStubMsg->fHasNewCorrDesc)
1888 pFormat += *(const SHORT*)pFormat;
1889 return *(const SHORT*)pFormat;
1891 return sizeof(void *);
1893 FIXME("unhandled embedded type %02x\n", *pFormat);
1899 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1900 PFORMAT_STRING pFormat)
1902 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1906 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1910 return m(pStubMsg, pFormat);
1914 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1915 unsigned char *pMemory,
1916 PFORMAT_STRING pFormat,
1917 PFORMAT_STRING pPointer)
1919 PFORMAT_STRING desc;
1923 while (*pFormat != RPC_FC_END) {
1929 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
1930 safe_copy_to_buffer(pStubMsg, pMemory, 1);
1936 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1937 safe_copy_to_buffer(pStubMsg, pMemory, 2);
1943 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
1944 safe_copy_to_buffer(pStubMsg, pMemory, 4);
1948 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1949 safe_copy_to_buffer(pStubMsg, pMemory, 8);
1952 case RPC_FC_POINTER:
1954 unsigned char *saved_buffer;
1955 int pointer_buffer_mark_set = 0;
1956 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1957 saved_buffer = pStubMsg->Buffer;
1958 if (pStubMsg->PointerBufferMark)
1960 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1961 pStubMsg->PointerBufferMark = NULL;
1962 pointer_buffer_mark_set = 1;
1965 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
1966 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
1967 if (pointer_buffer_mark_set)
1969 STD_OVERFLOW_CHECK(pStubMsg);
1970 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1971 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
1973 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
1974 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
1975 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1977 pStubMsg->Buffer = saved_buffer + 4;
1983 case RPC_FC_ALIGNM4:
1984 ALIGN_POINTER(pMemory, 4);
1986 case RPC_FC_ALIGNM8:
1987 ALIGN_POINTER(pMemory, 8);
1989 case RPC_FC_STRUCTPAD1:
1990 case RPC_FC_STRUCTPAD2:
1991 case RPC_FC_STRUCTPAD3:
1992 case RPC_FC_STRUCTPAD4:
1993 case RPC_FC_STRUCTPAD5:
1994 case RPC_FC_STRUCTPAD6:
1995 case RPC_FC_STRUCTPAD7:
1996 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1998 case RPC_FC_EMBEDDED_COMPLEX:
1999 pMemory += pFormat[1];
2001 desc = pFormat + *(const SHORT*)pFormat;
2002 size = EmbeddedComplexSize(pStubMsg, desc);
2003 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
2004 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2007 /* for some reason interface pointers aren't generated as
2008 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2009 * they still need the derefencing treatment that pointers are
2011 if (*desc == RPC_FC_IP)
2012 m(pStubMsg, *(unsigned char **)pMemory, desc);
2014 m(pStubMsg, pMemory, desc);
2016 else FIXME("no marshaller for embedded type %02x\n", *desc);
2023 FIXME("unhandled format 0x%02x\n", *pFormat);
2031 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2032 unsigned char *pMemory,
2033 PFORMAT_STRING pFormat,
2034 PFORMAT_STRING pPointer)
2036 PFORMAT_STRING desc;
2040 while (*pFormat != RPC_FC_END) {
2046 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2047 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2053 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2054 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2060 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2061 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2065 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2066 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2069 case RPC_FC_POINTER:
2071 unsigned char *saved_buffer;
2072 int pointer_buffer_mark_set = 0;
2073 TRACE("pointer => %p\n", pMemory);
2074 ALIGN_POINTER(pStubMsg->Buffer, 4);
2075 saved_buffer = pStubMsg->Buffer;
2076 if (pStubMsg->PointerBufferMark)
2078 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2079 pStubMsg->PointerBufferMark = NULL;
2080 pointer_buffer_mark_set = 1;
2083 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2085 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, TRUE);
2086 if (pointer_buffer_mark_set)
2088 STD_OVERFLOW_CHECK(pStubMsg);
2089 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2090 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2092 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2093 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2094 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2096 pStubMsg->Buffer = saved_buffer + 4;
2102 case RPC_FC_ALIGNM4:
2103 ALIGN_POINTER(pMemory, 4);
2105 case RPC_FC_ALIGNM8:
2106 ALIGN_POINTER(pMemory, 8);
2108 case RPC_FC_STRUCTPAD1:
2109 case RPC_FC_STRUCTPAD2:
2110 case RPC_FC_STRUCTPAD3:
2111 case RPC_FC_STRUCTPAD4:
2112 case RPC_FC_STRUCTPAD5:
2113 case RPC_FC_STRUCTPAD6:
2114 case RPC_FC_STRUCTPAD7:
2115 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2117 case RPC_FC_EMBEDDED_COMPLEX:
2118 pMemory += pFormat[1];
2120 desc = pFormat + *(const SHORT*)pFormat;
2121 size = EmbeddedComplexSize(pStubMsg, desc);
2122 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2123 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2124 memset(pMemory, 0, size); /* just in case */
2127 /* for some reason interface pointers aren't generated as
2128 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2129 * they still need the derefencing treatment that pointers are
2131 if (*desc == RPC_FC_IP)
2132 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2134 m(pStubMsg, &pMemory, desc, FALSE);
2136 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2143 FIXME("unhandled format %d\n", *pFormat);
2151 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2152 unsigned char *pMemory,
2153 PFORMAT_STRING pFormat,
2154 PFORMAT_STRING pPointer)
2156 PFORMAT_STRING desc;
2160 while (*pFormat != RPC_FC_END) {
2166 safe_buffer_length_increment(pStubMsg, 1);
2172 safe_buffer_length_increment(pStubMsg, 2);
2178 safe_buffer_length_increment(pStubMsg, 4);
2182 safe_buffer_length_increment(pStubMsg, 8);
2185 case RPC_FC_POINTER:
2186 if (!pStubMsg->IgnoreEmbeddedPointers)
2188 int saved_buffer_length = pStubMsg->BufferLength;
2189 pStubMsg->BufferLength = pStubMsg->PointerLength;
2190 pStubMsg->PointerLength = 0;
2191 if(!pStubMsg->BufferLength)
2192 ERR("BufferLength == 0??\n");
2193 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2194 pStubMsg->PointerLength = pStubMsg->BufferLength;
2195 pStubMsg->BufferLength = saved_buffer_length;
2197 safe_buffer_length_increment(pStubMsg, 4);
2201 case RPC_FC_ALIGNM4:
2202 ALIGN_POINTER(pMemory, 4);
2204 case RPC_FC_ALIGNM8:
2205 ALIGN_POINTER(pMemory, 8);
2207 case RPC_FC_STRUCTPAD1:
2208 case RPC_FC_STRUCTPAD2:
2209 case RPC_FC_STRUCTPAD3:
2210 case RPC_FC_STRUCTPAD4:
2211 case RPC_FC_STRUCTPAD5:
2212 case RPC_FC_STRUCTPAD6:
2213 case RPC_FC_STRUCTPAD7:
2214 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2216 case RPC_FC_EMBEDDED_COMPLEX:
2217 pMemory += pFormat[1];
2219 desc = pFormat + *(const SHORT*)pFormat;
2220 size = EmbeddedComplexSize(pStubMsg, desc);
2221 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2224 /* for some reason interface pointers aren't generated as
2225 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2226 * they still need the derefencing treatment that pointers are
2228 if (*desc == RPC_FC_IP)
2229 m(pStubMsg, *(unsigned char **)pMemory, desc);
2231 m(pStubMsg, pMemory, desc);
2233 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2240 FIXME("unhandled format 0x%02x\n", *pFormat);
2248 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2249 unsigned char *pMemory,
2250 PFORMAT_STRING pFormat,
2251 PFORMAT_STRING pPointer)
2253 PFORMAT_STRING desc;
2257 while (*pFormat != RPC_FC_END) {
2278 case RPC_FC_POINTER:
2279 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
2283 case RPC_FC_ALIGNM4:
2284 ALIGN_POINTER(pMemory, 4);
2286 case RPC_FC_ALIGNM8:
2287 ALIGN_POINTER(pMemory, 8);
2289 case RPC_FC_STRUCTPAD1:
2290 case RPC_FC_STRUCTPAD2:
2291 case RPC_FC_STRUCTPAD3:
2292 case RPC_FC_STRUCTPAD4:
2293 case RPC_FC_STRUCTPAD5:
2294 case RPC_FC_STRUCTPAD6:
2295 case RPC_FC_STRUCTPAD7:
2296 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2298 case RPC_FC_EMBEDDED_COMPLEX:
2299 pMemory += pFormat[1];
2301 desc = pFormat + *(const SHORT*)pFormat;
2302 size = EmbeddedComplexSize(pStubMsg, desc);
2303 m = NdrFreer[*desc & NDR_TABLE_MASK];
2306 /* for some reason interface pointers aren't generated as
2307 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2308 * they still need the derefencing treatment that pointers are
2310 if (*desc == RPC_FC_IP)
2311 m(pStubMsg, *(unsigned char **)pMemory, desc);
2313 m(pStubMsg, pMemory, desc);
2315 else FIXME("no freer for embedded type %02x\n", *desc);
2322 FIXME("unhandled format 0x%02x\n", *pFormat);
2330 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2331 PFORMAT_STRING pFormat)
2333 PFORMAT_STRING desc;
2334 unsigned long size = 0;
2336 while (*pFormat != RPC_FC_END) {
2343 safe_buffer_increment(pStubMsg, 1);
2349 safe_buffer_increment(pStubMsg, 2);
2355 safe_buffer_increment(pStubMsg, 4);
2359 safe_buffer_increment(pStubMsg, 8);
2361 case RPC_FC_POINTER:
2363 safe_buffer_increment(pStubMsg, 4);
2364 if (!pStubMsg->IgnoreEmbeddedPointers)
2365 FIXME("embedded pointers\n");
2367 case RPC_FC_ALIGNM4:
2368 ALIGN_LENGTH(size, 4);
2369 ALIGN_POINTER(pStubMsg->Buffer, 4);
2371 case RPC_FC_ALIGNM8:
2372 ALIGN_LENGTH(size, 8);
2373 ALIGN_POINTER(pStubMsg->Buffer, 8);
2375 case RPC_FC_STRUCTPAD1:
2376 case RPC_FC_STRUCTPAD2:
2377 case RPC_FC_STRUCTPAD3:
2378 case RPC_FC_STRUCTPAD4:
2379 case RPC_FC_STRUCTPAD5:
2380 case RPC_FC_STRUCTPAD6:
2381 case RPC_FC_STRUCTPAD7:
2382 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2384 case RPC_FC_EMBEDDED_COMPLEX:
2387 desc = pFormat + *(const SHORT*)pFormat;
2388 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2394 FIXME("unhandled format 0x%02x\n", *pFormat);
2402 /***********************************************************************
2403 * NdrComplexStructMarshall [RPCRT4.@]
2405 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2406 unsigned char *pMemory,
2407 PFORMAT_STRING pFormat)
2409 PFORMAT_STRING conf_array = NULL;
2410 PFORMAT_STRING pointer_desc = NULL;
2411 unsigned char *OldMemory = pStubMsg->Memory;
2412 int pointer_buffer_mark_set = 0;
2414 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2416 if (!pStubMsg->PointerBufferMark)
2418 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2419 /* save buffer length */
2420 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2422 /* get the buffer pointer after complex array data, but before
2424 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2425 pStubMsg->IgnoreEmbeddedPointers = 1;
2426 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2427 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2429 /* save it for use by embedded pointer code later */
2430 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2431 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
2432 pointer_buffer_mark_set = 1;
2434 /* restore the original buffer length */
2435 pStubMsg->BufferLength = saved_buffer_length;
2438 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2441 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2443 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2446 pStubMsg->Memory = pMemory;
2448 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2451 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2453 pStubMsg->Memory = OldMemory;
2455 if (pointer_buffer_mark_set)
2457 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2458 pStubMsg->PointerBufferMark = NULL;
2461 STD_OVERFLOW_CHECK(pStubMsg);
2466 /***********************************************************************
2467 * NdrComplexStructUnmarshall [RPCRT4.@]
2469 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2470 unsigned char **ppMemory,
2471 PFORMAT_STRING pFormat,
2472 unsigned char fMustAlloc)
2474 unsigned size = *(const WORD*)(pFormat+2);
2475 PFORMAT_STRING conf_array = NULL;
2476 PFORMAT_STRING pointer_desc = NULL;
2477 unsigned char *pMemory;
2478 int pointer_buffer_mark_set = 0;
2480 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2482 if (!pStubMsg->PointerBufferMark)
2484 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2485 /* save buffer pointer */
2486 unsigned char *saved_buffer = pStubMsg->Buffer;
2488 /* get the buffer pointer after complex array data, but before
2490 pStubMsg->IgnoreEmbeddedPointers = 1;
2491 NdrComplexStructMemorySize(pStubMsg, pFormat);
2492 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2494 /* save it for use by embedded pointer code later */
2495 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2496 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
2497 pointer_buffer_mark_set = 1;
2499 /* restore the original buffer */
2500 pStubMsg->Buffer = saved_buffer;
2503 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2505 if (fMustAlloc || !*ppMemory)
2507 *ppMemory = NdrAllocate(pStubMsg, size);
2508 memset(*ppMemory, 0, size);
2512 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2514 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2517 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2520 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2522 if (pointer_buffer_mark_set)
2524 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2525 pStubMsg->PointerBufferMark = NULL;
2531 /***********************************************************************
2532 * NdrComplexStructBufferSize [RPCRT4.@]
2534 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2535 unsigned char *pMemory,
2536 PFORMAT_STRING pFormat)
2538 PFORMAT_STRING conf_array = NULL;
2539 PFORMAT_STRING pointer_desc = NULL;
2540 unsigned char *OldMemory = pStubMsg->Memory;
2541 int pointer_length_set = 0;
2543 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2545 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2547 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2549 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2550 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2552 /* get the buffer length after complex struct data, but before
2554 pStubMsg->IgnoreEmbeddedPointers = 1;
2555 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2556 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2558 /* save it for use by embedded pointer code later */
2559 pStubMsg->PointerLength = pStubMsg->BufferLength;
2560 pointer_length_set = 1;
2561 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
2563 /* restore the original buffer length */
2564 pStubMsg->BufferLength = saved_buffer_length;
2568 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2570 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2573 pStubMsg->Memory = pMemory;
2575 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2578 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2580 pStubMsg->Memory = OldMemory;
2582 if(pointer_length_set)
2584 pStubMsg->BufferLength = pStubMsg->PointerLength;
2585 pStubMsg->PointerLength = 0;
2590 /***********************************************************************
2591 * NdrComplexStructMemorySize [RPCRT4.@]
2593 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2594 PFORMAT_STRING pFormat)
2596 unsigned size = *(const WORD*)(pFormat+2);
2597 PFORMAT_STRING conf_array = NULL;
2598 PFORMAT_STRING pointer_desc = NULL;
2600 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2602 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2605 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2607 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2610 ComplexStructMemorySize(pStubMsg, pFormat);
2613 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2618 /***********************************************************************
2619 * NdrComplexStructFree [RPCRT4.@]
2621 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2622 unsigned char *pMemory,
2623 PFORMAT_STRING pFormat)
2625 PFORMAT_STRING conf_array = NULL;
2626 PFORMAT_STRING pointer_desc = NULL;
2627 unsigned char *OldMemory = pStubMsg->Memory;
2629 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2632 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2634 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2637 pStubMsg->Memory = pMemory;
2639 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2642 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2644 pStubMsg->Memory = OldMemory;
2647 /***********************************************************************
2648 * NdrConformantArrayMarshall [RPCRT4.@]
2650 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2651 unsigned char *pMemory,
2652 PFORMAT_STRING pFormat)
2654 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2655 unsigned char alignment = pFormat[1] + 1;
2657 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2658 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2660 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2662 WriteConformance(pStubMsg);
2664 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2666 size = safe_multiply(esize, pStubMsg->MaxCount);
2667 pStubMsg->BufferMark = pStubMsg->Buffer;
2668 safe_copy_to_buffer(pStubMsg, pMemory, size);
2670 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2675 /***********************************************************************
2676 * NdrConformantArrayUnmarshall [RPCRT4.@]
2678 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2679 unsigned char **ppMemory,
2680 PFORMAT_STRING pFormat,
2681 unsigned char fMustAlloc)
2683 DWORD size, esize = *(const WORD*)(pFormat+2);
2684 unsigned char alignment = pFormat[1] + 1;
2685 unsigned char *saved_buffer;
2687 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2688 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2690 pFormat = ReadConformance(pStubMsg, pFormat+4);
2692 size = safe_multiply(esize, pStubMsg->MaxCount);
2693 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2696 *ppMemory = NdrAllocate(pStubMsg, size);
2699 if (!pStubMsg->IsClient && !*ppMemory)
2700 /* for servers, we just point straight into the RPC buffer */
2701 *ppMemory = pStubMsg->Buffer;
2704 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
2705 safe_buffer_increment(pStubMsg, size);
2706 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2708 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2709 if (*ppMemory != saved_buffer)
2710 memcpy(*ppMemory, saved_buffer, size);
2715 /***********************************************************************
2716 * NdrConformantArrayBufferSize [RPCRT4.@]
2718 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2719 unsigned char *pMemory,
2720 PFORMAT_STRING pFormat)
2722 DWORD size, esize = *(const WORD*)(pFormat+2);
2723 unsigned char alignment = pFormat[1] + 1;
2725 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2726 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2728 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2730 SizeConformance(pStubMsg);
2732 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2734 size = safe_multiply(esize, pStubMsg->MaxCount);
2735 /* conformance value plus array */
2736 safe_buffer_length_increment(pStubMsg, size);
2738 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2741 /***********************************************************************
2742 * NdrConformantArrayMemorySize [RPCRT4.@]
2744 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2745 PFORMAT_STRING pFormat)
2747 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2748 unsigned char alignment = pFormat[1] + 1;
2750 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2751 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2753 pFormat = ReadConformance(pStubMsg, pFormat+4);
2754 size = safe_multiply(esize, pStubMsg->MaxCount);
2755 pStubMsg->MemorySize += size;
2757 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2758 pStubMsg->BufferMark = pStubMsg->Buffer;
2759 safe_buffer_increment(pStubMsg, size);
2761 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2763 return pStubMsg->MemorySize;
2766 /***********************************************************************
2767 * NdrConformantArrayFree [RPCRT4.@]
2769 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2770 unsigned char *pMemory,
2771 PFORMAT_STRING pFormat)
2773 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2774 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2776 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2778 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2782 /***********************************************************************
2783 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2785 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2786 unsigned char* pMemory,
2787 PFORMAT_STRING pFormat )
2790 unsigned char alignment = pFormat[1] + 1;
2791 DWORD esize = *(const WORD*)(pFormat+2);
2793 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2795 if (pFormat[0] != RPC_FC_CVARRAY)
2797 ERR("invalid format type %x\n", pFormat[0]);
2798 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2802 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2803 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2805 WriteConformance(pStubMsg);
2806 WriteVariance(pStubMsg);
2808 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2810 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2812 pStubMsg->BufferMark = pStubMsg->Buffer;
2813 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
2815 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2821 /***********************************************************************
2822 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2824 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2825 unsigned char** ppMemory,
2826 PFORMAT_STRING pFormat,
2827 unsigned char fMustAlloc )
2829 ULONG bufsize, memsize;
2830 unsigned char alignment = pFormat[1] + 1;
2831 DWORD esize = *(const WORD*)(pFormat+2);
2833 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2835 if (pFormat[0] != RPC_FC_CVARRAY)
2837 ERR("invalid format type %x\n", pFormat[0]);
2838 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2842 pFormat = ReadConformance(pStubMsg, pFormat+4);
2843 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2845 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2847 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2848 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2850 if (!*ppMemory || fMustAlloc)
2851 *ppMemory = NdrAllocate(pStubMsg, memsize);
2852 safe_copy_from_buffer(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize);
2854 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
2860 /***********************************************************************
2861 * NdrConformantVaryingArrayFree [RPCRT4.@]
2863 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2864 unsigned char* pMemory,
2865 PFORMAT_STRING pFormat )
2867 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2869 if (pFormat[0] != RPC_FC_CVARRAY)
2871 ERR("invalid format type %x\n", pFormat[0]);
2872 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2876 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2877 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2879 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2883 /***********************************************************************
2884 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2886 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2887 unsigned char* pMemory, PFORMAT_STRING pFormat )
2889 unsigned char alignment = pFormat[1] + 1;
2890 DWORD esize = *(const WORD*)(pFormat+2);
2892 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2894 if (pFormat[0] != RPC_FC_CVARRAY)
2896 ERR("invalid format type %x\n", pFormat[0]);
2897 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2902 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2903 /* compute length */
2904 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2906 SizeConformance(pStubMsg);
2907 SizeVariance(pStubMsg);
2909 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2911 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2913 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2917 /***********************************************************************
2918 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2920 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2921 PFORMAT_STRING pFormat )
2923 ULONG bufsize, memsize;
2924 unsigned char alignment = pFormat[1] + 1;
2925 DWORD esize = *(const WORD*)(pFormat+2);
2927 TRACE("(%p, %p)\n", pStubMsg, pFormat);
2929 if (pFormat[0] != RPC_FC_CVARRAY)
2931 ERR("invalid format type %x\n", pFormat[0]);
2932 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2933 return pStubMsg->MemorySize;
2936 pFormat = ReadConformance(pStubMsg, pFormat+4);
2937 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2939 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2941 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2942 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2944 safe_buffer_increment(pStubMsg, bufsize);
2945 pStubMsg->MemorySize += memsize;
2947 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2949 return pStubMsg->MemorySize;
2953 /***********************************************************************
2954 * NdrComplexArrayMarshall [RPCRT4.@]
2956 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2957 unsigned char *pMemory,
2958 PFORMAT_STRING pFormat)
2960 ULONG i, count, def;
2961 BOOL variance_present;
2962 unsigned char alignment;
2963 int pointer_buffer_mark_set = 0;
2965 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2967 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2969 ERR("invalid format type %x\n", pFormat[0]);
2970 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2974 alignment = pFormat[1] + 1;
2976 if (!pStubMsg->PointerBufferMark)
2978 /* save buffer fields that may be changed by buffer sizer functions
2979 * and that may be needed later on */
2980 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2981 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2982 unsigned long saved_max_count = pStubMsg->MaxCount;
2983 unsigned long saved_offset = pStubMsg->Offset;
2984 unsigned long saved_actual_count = pStubMsg->ActualCount;
2986 /* get the buffer pointer after complex array data, but before
2988 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2989 pStubMsg->IgnoreEmbeddedPointers = 1;
2990 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
2991 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2993 /* save it for use by embedded pointer code later */
2994 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2995 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
2996 pointer_buffer_mark_set = 1;
2998 /* restore fields */
2999 pStubMsg->ActualCount = saved_actual_count;
3000 pStubMsg->Offset = saved_offset;
3001 pStubMsg->MaxCount = saved_max_count;
3002 pStubMsg->BufferLength = saved_buffer_length;
3005 def = *(const WORD*)&pFormat[2];
3008 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3009 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3011 variance_present = IsConformanceOrVariancePresent(pFormat);
3012 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3013 TRACE("variance = %d\n", pStubMsg->ActualCount);
3015 WriteConformance(pStubMsg);
3016 if (variance_present)
3017 WriteVariance(pStubMsg);
3019 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3021 count = pStubMsg->ActualCount;
3022 for (i = 0; i < count; i++)
3023 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3025 STD_OVERFLOW_CHECK(pStubMsg);
3027 if (pointer_buffer_mark_set)
3029 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3030 pStubMsg->PointerBufferMark = NULL;
3036 /***********************************************************************
3037 * NdrComplexArrayUnmarshall [RPCRT4.@]
3039 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3040 unsigned char **ppMemory,
3041 PFORMAT_STRING pFormat,
3042 unsigned char fMustAlloc)
3044 ULONG i, count, size;
3045 unsigned char alignment;
3046 unsigned char *pMemory;
3047 unsigned char *saved_buffer;
3048 int pointer_buffer_mark_set = 0;
3049 int saved_ignore_embedded;
3051 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3053 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3055 ERR("invalid format type %x\n", pFormat[0]);
3056 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3060 alignment = pFormat[1] + 1;
3062 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3063 /* save buffer pointer */
3064 saved_buffer = pStubMsg->Buffer;
3065 /* get the buffer pointer after complex array data, but before
3067 pStubMsg->IgnoreEmbeddedPointers = 1;
3068 pStubMsg->MemorySize = 0;
3069 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3070 size = pStubMsg->MemorySize;
3071 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3073 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
3074 if (!pStubMsg->PointerBufferMark)
3076 /* save it for use by embedded pointer code later */
3077 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3078 pointer_buffer_mark_set = 1;
3080 /* restore the original buffer */
3081 pStubMsg->Buffer = saved_buffer;
3085 pFormat = ReadConformance(pStubMsg, pFormat);
3086 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3088 if (fMustAlloc || !*ppMemory)
3090 *ppMemory = NdrAllocate(pStubMsg, size);
3091 memset(*ppMemory, 0, size);
3094 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3096 pMemory = *ppMemory;
3097 count = pStubMsg->ActualCount;
3098 for (i = 0; i < count; i++)
3099 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
3101 if (pointer_buffer_mark_set)
3103 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3104 pStubMsg->PointerBufferMark = NULL;
3110 /***********************************************************************
3111 * NdrComplexArrayBufferSize [RPCRT4.@]
3113 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3114 unsigned char *pMemory,
3115 PFORMAT_STRING pFormat)
3117 ULONG i, count, def;
3118 unsigned char alignment;
3119 BOOL variance_present;
3120 int pointer_length_set = 0;
3122 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3124 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3126 ERR("invalid format type %x\n", pFormat[0]);
3127 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3131 alignment = pFormat[1] + 1;
3133 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3135 /* save buffer fields that may be changed by buffer sizer functions
3136 * and that may be needed later on */
3137 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3138 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3139 unsigned long saved_max_count = pStubMsg->MaxCount;
3140 unsigned long saved_offset = pStubMsg->Offset;
3141 unsigned long saved_actual_count = pStubMsg->ActualCount;
3143 /* get the buffer pointer after complex array data, but before
3145 pStubMsg->IgnoreEmbeddedPointers = 1;
3146 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3147 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3149 /* save it for use by embedded pointer code later */
3150 pStubMsg->PointerLength = pStubMsg->BufferLength;
3151 pointer_length_set = 1;
3153 /* restore fields */
3154 pStubMsg->ActualCount = saved_actual_count;
3155 pStubMsg->Offset = saved_offset;
3156 pStubMsg->MaxCount = saved_max_count;
3157 pStubMsg->BufferLength = saved_buffer_length;
3159 def = *(const WORD*)&pFormat[2];
3162 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3163 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3164 SizeConformance(pStubMsg);
3166 variance_present = IsConformanceOrVariancePresent(pFormat);
3167 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3168 TRACE("variance = %d\n", pStubMsg->ActualCount);
3170 if (variance_present)
3171 SizeVariance(pStubMsg);
3173 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3175 count = pStubMsg->ActualCount;
3176 for (i = 0; i < count; i++)
3177 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
3179 if(pointer_length_set)
3181 pStubMsg->BufferLength = pStubMsg->PointerLength;
3182 pStubMsg->PointerLength = 0;
3186 /***********************************************************************
3187 * NdrComplexArrayMemorySize [RPCRT4.@]
3189 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3190 PFORMAT_STRING pFormat)
3192 ULONG i, count, esize, SavedMemorySize, MemorySize;
3193 unsigned char alignment;
3194 unsigned char *Buffer;
3196 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3198 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3200 ERR("invalid format type %x\n", pFormat[0]);
3201 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3205 alignment = pFormat[1] + 1;
3209 pFormat = ReadConformance(pStubMsg, pFormat);
3210 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3212 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3214 SavedMemorySize = pStubMsg->MemorySize;
3216 Buffer = pStubMsg->Buffer;
3217 pStubMsg->MemorySize = 0;
3218 esize = ComplexStructMemorySize(pStubMsg, pFormat);
3219 pStubMsg->Buffer = Buffer;
3221 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
3223 count = pStubMsg->ActualCount;
3224 for (i = 0; i < count; i++)
3225 ComplexStructMemorySize(pStubMsg, pFormat);
3227 pStubMsg->MemorySize = SavedMemorySize;
3229 pStubMsg->MemorySize += MemorySize;
3233 /***********************************************************************
3234 * NdrComplexArrayFree [RPCRT4.@]
3236 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3237 unsigned char *pMemory,
3238 PFORMAT_STRING pFormat)
3240 ULONG i, count, def;
3242 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3244 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3246 ERR("invalid format type %x\n", pFormat[0]);
3247 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3251 def = *(const WORD*)&pFormat[2];
3254 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3255 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3257 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3258 TRACE("variance = %d\n", pStubMsg->ActualCount);
3260 count = pStubMsg->ActualCount;
3261 for (i = 0; i < count; i++)
3262 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
3265 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
3266 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
3267 USER_MARSHAL_CB *umcb)
3269 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
3270 pStubMsg->RpcMsg->DataRepresentation);
3271 umcb->pStubMsg = pStubMsg;
3272 umcb->pReserve = NULL;
3273 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
3274 umcb->CBType = cbtype;
3275 umcb->pFormat = pFormat;
3276 umcb->pTypeFormat = NULL /* FIXME */;
3279 #define USER_MARSHAL_PTR_PREFIX \
3280 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3281 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3283 /***********************************************************************
3284 * NdrUserMarshalMarshall [RPCRT4.@]
3286 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3287 unsigned char *pMemory,
3288 PFORMAT_STRING pFormat)
3290 unsigned flags = pFormat[1];
3291 unsigned index = *(const WORD*)&pFormat[2];
3292 unsigned char *saved_buffer = NULL;
3293 USER_MARSHAL_CB umcb;
3295 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3296 TRACE("index=%d\n", index);
3298 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
3300 if (flags & USER_MARSHAL_POINTER)
3302 ALIGN_POINTER(pStubMsg->Buffer, 4);
3303 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
3304 pStubMsg->Buffer += 4;
3305 if (pStubMsg->PointerBufferMark)
3307 saved_buffer = pStubMsg->Buffer;
3308 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3309 pStubMsg->PointerBufferMark = NULL;
3311 ALIGN_POINTER(pStubMsg->Buffer, 8);
3314 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3317 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
3318 &umcb.Flags, pStubMsg->Buffer, pMemory);
3322 STD_OVERFLOW_CHECK(pStubMsg);
3323 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3324 pStubMsg->Buffer = saved_buffer;
3327 STD_OVERFLOW_CHECK(pStubMsg);
3332 /***********************************************************************
3333 * NdrUserMarshalUnmarshall [RPCRT4.@]
3335 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3336 unsigned char **ppMemory,
3337 PFORMAT_STRING pFormat,
3338 unsigned char fMustAlloc)
3340 unsigned flags = pFormat[1];
3341 unsigned index = *(const WORD*)&pFormat[2];
3342 DWORD memsize = *(const WORD*)&pFormat[4];
3343 unsigned char *saved_buffer = NULL;
3344 USER_MARSHAL_CB umcb;
3346 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3347 TRACE("index=%d\n", index);
3349 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
3351 if (flags & USER_MARSHAL_POINTER)
3353 ALIGN_POINTER(pStubMsg->Buffer, 4);
3354 /* skip pointer prefix */
3355 pStubMsg->Buffer += 4;
3356 if (pStubMsg->PointerBufferMark)
3358 saved_buffer = pStubMsg->Buffer;
3359 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3360 pStubMsg->PointerBufferMark = NULL;
3362 ALIGN_POINTER(pStubMsg->Buffer, 8);
3365 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3367 if (fMustAlloc || !*ppMemory)
3368 *ppMemory = NdrAllocate(pStubMsg, memsize);
3371 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
3372 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
3376 STD_OVERFLOW_CHECK(pStubMsg);
3377 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3378 pStubMsg->Buffer = saved_buffer;
3384 /***********************************************************************
3385 * NdrUserMarshalBufferSize [RPCRT4.@]
3387 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3388 unsigned char *pMemory,
3389 PFORMAT_STRING pFormat)
3391 unsigned flags = pFormat[1];
3392 unsigned index = *(const WORD*)&pFormat[2];
3393 DWORD bufsize = *(const WORD*)&pFormat[6];
3394 USER_MARSHAL_CB umcb;
3395 unsigned long saved_buffer_length = 0;
3397 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3398 TRACE("index=%d\n", index);
3400 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
3402 if (flags & USER_MARSHAL_POINTER)
3404 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3405 /* skip pointer prefix */
3406 safe_buffer_length_increment(pStubMsg, 4);
3407 if (pStubMsg->IgnoreEmbeddedPointers)
3409 if (pStubMsg->PointerLength)
3411 saved_buffer_length = pStubMsg->BufferLength;
3412 pStubMsg->BufferLength = pStubMsg->PointerLength;
3413 pStubMsg->PointerLength = 0;
3415 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
3418 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
3421 TRACE("size=%d\n", bufsize);
3422 safe_buffer_length_increment(pStubMsg, bufsize);
3425 pStubMsg->BufferLength =
3426 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
3427 &umcb.Flags, pStubMsg->BufferLength, pMemory);
3429 if (saved_buffer_length)
3431 pStubMsg->PointerLength = pStubMsg->BufferLength;
3432 pStubMsg->BufferLength = saved_buffer_length;
3437 /***********************************************************************
3438 * NdrUserMarshalMemorySize [RPCRT4.@]
3440 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3441 PFORMAT_STRING pFormat)
3443 unsigned flags = pFormat[1];
3444 unsigned index = *(const WORD*)&pFormat[2];
3445 DWORD memsize = *(const WORD*)&pFormat[4];
3446 DWORD bufsize = *(const WORD*)&pFormat[6];
3448 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3449 TRACE("index=%d\n", index);
3451 pStubMsg->MemorySize += memsize;
3453 if (flags & USER_MARSHAL_POINTER)
3455 ALIGN_POINTER(pStubMsg->Buffer, 4);
3456 /* skip pointer prefix */
3457 pStubMsg->Buffer += 4;
3458 if (pStubMsg->IgnoreEmbeddedPointers)
3459 return pStubMsg->MemorySize;
3460 ALIGN_POINTER(pStubMsg->Buffer, 8);
3463 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3466 FIXME("not implemented for varying buffer size\n");
3468 pStubMsg->Buffer += bufsize;
3470 return pStubMsg->MemorySize;
3473 /***********************************************************************
3474 * NdrUserMarshalFree [RPCRT4.@]
3476 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
3477 unsigned char *pMemory,
3478 PFORMAT_STRING pFormat)
3480 /* unsigned flags = pFormat[1]; */
3481 unsigned index = *(const WORD*)&pFormat[2];
3482 USER_MARSHAL_CB umcb;
3484 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3485 TRACE("index=%d\n", index);
3487 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
3489 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
3490 &umcb.Flags, pMemory);
3493 /***********************************************************************
3494 * NdrClearOutParameters [RPCRT4.@]
3496 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
3497 PFORMAT_STRING pFormat,
3500 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
3503 /***********************************************************************
3504 * NdrConvert [RPCRT4.@]
3506 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
3508 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
3509 /* FIXME: since this stub doesn't do any converting, the proper behavior
3510 is to raise an exception */
3513 /***********************************************************************
3514 * NdrConvert2 [RPCRT4.@]
3516 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
3518 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3519 pStubMsg, pFormat, NumberParams);
3520 /* FIXME: since this stub doesn't do any converting, the proper behavior
3521 is to raise an exception */
3524 #include "pshpack1.h"
3525 typedef struct _NDR_CSTRUCT_FORMAT
3528 unsigned char alignment;
3529 unsigned short memory_size;
3530 short offset_to_array_description;
3531 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
3532 #include "poppack.h"
3534 /***********************************************************************
3535 * NdrConformantStructMarshall [RPCRT4.@]
3537 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3538 unsigned char *pMemory,
3539 PFORMAT_STRING pFormat)
3541 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3542 PFORMAT_STRING pCArrayFormat;
3543 ULONG esize, bufsize;
3545 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3547 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3548 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3550 ERR("invalid format type %x\n", pCStructFormat->type);
3551 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3555 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3556 pCStructFormat->offset_to_array_description;
3557 if (*pCArrayFormat != RPC_FC_CARRAY)
3559 ERR("invalid array format type %x\n", pCStructFormat->type);
3560 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3563 esize = *(const WORD*)(pCArrayFormat+2);
3565 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3566 pCArrayFormat + 4, 0);
3568 WriteConformance(pStubMsg);
3570 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3572 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3574 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3575 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3577 ERR("integer overflow of memory_size %u with bufsize %u\n",
3578 pCStructFormat->memory_size, bufsize);
3579 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3581 /* copy constant sized part of struct */
3582 pStubMsg->BufferMark = pStubMsg->Buffer;
3583 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
3585 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3586 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3591 /***********************************************************************
3592 * NdrConformantStructUnmarshall [RPCRT4.@]
3594 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3595 unsigned char **ppMemory,
3596 PFORMAT_STRING pFormat,
3597 unsigned char fMustAlloc)
3599 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3600 PFORMAT_STRING pCArrayFormat;
3601 ULONG esize, bufsize;
3602 unsigned char *saved_buffer;
3604 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3606 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3607 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3609 ERR("invalid format type %x\n", pCStructFormat->type);
3610 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3613 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3614 pCStructFormat->offset_to_array_description;
3615 if (*pCArrayFormat != RPC_FC_CARRAY)
3617 ERR("invalid array format type %x\n", pCStructFormat->type);
3618 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3621 esize = *(const WORD*)(pCArrayFormat+2);
3623 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3625 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3627 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3629 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3630 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3632 ERR("integer overflow of memory_size %u with bufsize %u\n",
3633 pCStructFormat->memory_size, bufsize);
3634 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3639 SIZE_T size = pCStructFormat->memory_size + bufsize;
3640 *ppMemory = NdrAllocate(pStubMsg, size);
3644 if (!pStubMsg->IsClient && !*ppMemory)
3645 /* for servers, we just point straight into the RPC buffer */
3646 *ppMemory = pStubMsg->Buffer;
3649 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3650 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
3651 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3652 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3654 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
3655 if (*ppMemory != saved_buffer)
3656 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
3661 /***********************************************************************
3662 * NdrConformantStructBufferSize [RPCRT4.@]
3664 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3665 unsigned char *pMemory,
3666 PFORMAT_STRING pFormat)
3668 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3669 PFORMAT_STRING pCArrayFormat;
3672 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3674 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3675 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3677 ERR("invalid format type %x\n", pCStructFormat->type);
3678 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3681 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3682 pCStructFormat->offset_to_array_description;
3683 if (*pCArrayFormat != RPC_FC_CARRAY)
3685 ERR("invalid array format type %x\n", pCStructFormat->type);
3686 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3689 esize = *(const WORD*)(pCArrayFormat+2);
3691 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
3692 SizeConformance(pStubMsg);
3694 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
3696 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3698 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
3699 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
3701 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3702 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3705 /***********************************************************************
3706 * NdrConformantStructMemorySize [RPCRT4.@]
3708 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3709 PFORMAT_STRING pFormat)
3715 /***********************************************************************
3716 * NdrConformantStructFree [RPCRT4.@]
3718 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3719 unsigned char *pMemory,
3720 PFORMAT_STRING pFormat)
3722 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3723 PFORMAT_STRING pCArrayFormat;
3726 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3728 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3729 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3731 ERR("invalid format type %x\n", pCStructFormat->type);
3732 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3736 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3737 pCStructFormat->offset_to_array_description;
3738 if (*pCArrayFormat != RPC_FC_CARRAY)
3740 ERR("invalid array format type %x\n", pCStructFormat->type);
3741 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3744 esize = *(const WORD*)(pCArrayFormat+2);
3746 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3747 pCArrayFormat + 4, 0);
3749 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3751 /* copy constant sized part of struct */
3752 pStubMsg->BufferMark = pStubMsg->Buffer;
3754 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3755 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3758 /***********************************************************************
3759 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3761 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3762 unsigned char *pMemory,
3763 PFORMAT_STRING pFormat)
3765 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3766 PFORMAT_STRING pCVArrayFormat;
3767 ULONG esize, bufsize;
3769 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3771 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3772 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3774 ERR("invalid format type %x\n", pCVStructFormat->type);
3775 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3779 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3780 pCVStructFormat->offset_to_array_description;
3781 switch (*pCVArrayFormat)
3783 case RPC_FC_CVARRAY:
3784 esize = *(const WORD*)(pCVArrayFormat+2);
3786 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3787 pCVArrayFormat + 4, 0);
3788 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3791 case RPC_FC_C_CSTRING:
3792 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3793 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3794 esize = sizeof(char);
3795 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3796 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3797 pCVArrayFormat + 2, 0);
3799 pStubMsg->MaxCount = pStubMsg->ActualCount;
3801 case RPC_FC_C_WSTRING:
3802 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3803 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3804 esize = sizeof(WCHAR);
3805 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3806 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3807 pCVArrayFormat + 2, 0);
3809 pStubMsg->MaxCount = pStubMsg->ActualCount;
3812 ERR("invalid array format type %x\n", *pCVArrayFormat);
3813 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3817 WriteConformance(pStubMsg);
3819 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3821 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3823 /* write constant sized part */
3824 pStubMsg->BufferMark = pStubMsg->Buffer;
3825 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
3827 WriteVariance(pStubMsg);
3829 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3831 /* write array part */
3832 safe_copy_to_buffer(pStubMsg, pMemory + pCVStructFormat->memory_size, bufsize);
3834 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3839 /***********************************************************************
3840 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3842 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3843 unsigned char **ppMemory,
3844 PFORMAT_STRING pFormat,
3845 unsigned char fMustAlloc)
3847 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3848 PFORMAT_STRING pCVArrayFormat;
3849 ULONG esize, bufsize;
3850 unsigned char cvarray_type;
3852 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3854 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3855 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3857 ERR("invalid format type %x\n", pCVStructFormat->type);
3858 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3862 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3863 pCVStructFormat->offset_to_array_description;
3864 cvarray_type = *pCVArrayFormat;
3865 switch (cvarray_type)
3867 case RPC_FC_CVARRAY:
3868 esize = *(const WORD*)(pCVArrayFormat+2);
3869 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3871 case RPC_FC_C_CSTRING:
3872 esize = sizeof(char);
3873 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3874 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3876 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3878 case RPC_FC_C_WSTRING:
3879 esize = sizeof(WCHAR);
3880 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3881 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3883 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3886 ERR("invalid array format type %x\n", *pCVArrayFormat);
3887 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3891 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3893 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3895 /* work out how much memory to allocate if we need to do so */
3896 if (!*ppMemory || fMustAlloc)
3898 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3899 *ppMemory = NdrAllocate(pStubMsg, size);
3902 /* copy the constant data */
3903 pStubMsg->BufferMark = pStubMsg->Buffer;
3904 safe_copy_from_buffer(pStubMsg, *ppMemory, pCVStructFormat->memory_size);
3906 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3908 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3910 if ((cvarray_type == RPC_FC_C_CSTRING) ||
3911 (cvarray_type == RPC_FC_C_WSTRING))
3914 /* strings must always have null terminating bytes */
3915 if (bufsize < esize)
3917 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
3918 RpcRaiseException(RPC_S_INVALID_BOUND);
3921 for (i = bufsize - esize; i < bufsize; i++)
3922 if (pStubMsg->Buffer[i] != 0)
3924 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3925 i, pStubMsg->Buffer[i]);
3926 RpcRaiseException(RPC_S_INVALID_BOUND);
3931 /* copy the array data */
3932 safe_copy_from_buffer(pStubMsg, *ppMemory + pCVStructFormat->memory_size, bufsize);
3934 if (cvarray_type == RPC_FC_C_CSTRING)
3935 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3936 else if (cvarray_type == RPC_FC_C_WSTRING)
3937 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3939 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
3944 /***********************************************************************
3945 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3947 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3948 unsigned char *pMemory,
3949 PFORMAT_STRING pFormat)
3951 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3952 PFORMAT_STRING pCVArrayFormat;
3955 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3957 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3958 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3960 ERR("invalid format type %x\n", pCVStructFormat->type);
3961 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3965 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3966 pCVStructFormat->offset_to_array_description;
3967 switch (*pCVArrayFormat)
3969 case RPC_FC_CVARRAY:
3970 esize = *(const WORD*)(pCVArrayFormat+2);
3972 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3973 pCVArrayFormat + 4, 0);
3974 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3977 case RPC_FC_C_CSTRING:
3978 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3979 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3980 esize = sizeof(char);
3981 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3982 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3983 pCVArrayFormat + 2, 0);
3985 pStubMsg->MaxCount = pStubMsg->ActualCount;
3987 case RPC_FC_C_WSTRING:
3988 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3989 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3990 esize = sizeof(WCHAR);
3991 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3992 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3993 pCVArrayFormat + 2, 0);
3995 pStubMsg->MaxCount = pStubMsg->ActualCount;
3998 ERR("invalid array format type %x\n", *pCVArrayFormat);
3999 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4003 SizeConformance(pStubMsg);
4005 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4007 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4009 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4010 SizeVariance(pStubMsg);
4011 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4013 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4016 /***********************************************************************
4017 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4019 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4020 PFORMAT_STRING pFormat)
4022 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4023 PFORMAT_STRING pCVArrayFormat;
4025 unsigned char cvarray_type;
4027 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4029 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4030 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4032 ERR("invalid format type %x\n", pCVStructFormat->type);
4033 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4037 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4038 pCVStructFormat->offset_to_array_description;
4039 cvarray_type = *pCVArrayFormat;
4040 switch (cvarray_type)
4042 case RPC_FC_CVARRAY:
4043 esize = *(const WORD*)(pCVArrayFormat+2);
4044 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4046 case RPC_FC_C_CSTRING:
4047 esize = sizeof(char);
4048 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4049 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4051 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4053 case RPC_FC_C_WSTRING:
4054 esize = sizeof(WCHAR);
4055 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4056 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4058 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4061 ERR("invalid array format type %x\n", *pCVArrayFormat);
4062 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4066 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4068 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4070 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4071 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4072 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4074 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4076 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4078 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
4081 /***********************************************************************
4082 * NdrConformantVaryingStructFree [RPCRT4.@]
4084 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4085 unsigned char *pMemory,
4086 PFORMAT_STRING pFormat)
4088 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4089 PFORMAT_STRING pCVArrayFormat;
4092 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4094 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4095 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4097 ERR("invalid format type %x\n", pCVStructFormat->type);
4098 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4102 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4103 pCVStructFormat->offset_to_array_description;
4104 switch (*pCVArrayFormat)
4106 case RPC_FC_CVARRAY:
4107 esize = *(const WORD*)(pCVArrayFormat+2);
4109 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4110 pCVArrayFormat + 4, 0);
4111 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4114 case RPC_FC_C_CSTRING:
4115 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4116 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4117 esize = sizeof(char);
4118 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4119 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4120 pCVArrayFormat + 2, 0);
4122 pStubMsg->MaxCount = pStubMsg->ActualCount;
4124 case RPC_FC_C_WSTRING:
4125 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4126 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4127 esize = sizeof(WCHAR);
4128 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4129 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4130 pCVArrayFormat + 2, 0);
4132 pStubMsg->MaxCount = pStubMsg->ActualCount;
4135 ERR("invalid array format type %x\n", *pCVArrayFormat);
4136 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4140 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4142 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4145 #include "pshpack1.h"
4149 unsigned char alignment;
4150 unsigned short total_size;
4151 } NDR_SMFARRAY_FORMAT;
4156 unsigned char alignment;
4157 unsigned long total_size;
4158 } NDR_LGFARRAY_FORMAT;
4159 #include "poppack.h"
4161 /***********************************************************************
4162 * NdrFixedArrayMarshall [RPCRT4.@]
4164 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4165 unsigned char *pMemory,
4166 PFORMAT_STRING pFormat)
4168 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4169 unsigned long total_size;
4171 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4173 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4174 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4176 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4177 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4181 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4183 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4185 total_size = pSmFArrayFormat->total_size;
4186 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4190 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4191 total_size = pLgFArrayFormat->total_size;
4192 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4195 pStubMsg->BufferMark = pStubMsg->Buffer;
4196 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4198 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4203 /***********************************************************************
4204 * NdrFixedArrayUnmarshall [RPCRT4.@]
4206 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4207 unsigned char **ppMemory,
4208 PFORMAT_STRING pFormat,
4209 unsigned char fMustAlloc)
4211 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4212 unsigned long total_size;
4213 unsigned char *saved_buffer;
4215 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4217 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4218 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4220 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4221 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4225 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4227 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4229 total_size = pSmFArrayFormat->total_size;
4230 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4234 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4235 total_size = pLgFArrayFormat->total_size;
4236 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4240 *ppMemory = NdrAllocate(pStubMsg, total_size);
4243 if (!pStubMsg->IsClient && !*ppMemory)
4244 /* for servers, we just point straight into the RPC buffer */
4245 *ppMemory = pStubMsg->Buffer;
4248 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4249 safe_buffer_increment(pStubMsg, total_size);
4250 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4252 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4253 if (*ppMemory != saved_buffer)
4254 memcpy(*ppMemory, saved_buffer, total_size);
4259 /***********************************************************************
4260 * NdrFixedArrayBufferSize [RPCRT4.@]
4262 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4263 unsigned char *pMemory,
4264 PFORMAT_STRING pFormat)
4266 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4267 unsigned long total_size;
4269 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4271 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4272 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4274 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4275 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4279 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4281 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4283 total_size = pSmFArrayFormat->total_size;
4284 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4288 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4289 total_size = pLgFArrayFormat->total_size;
4290 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4292 safe_buffer_length_increment(pStubMsg, total_size);
4294 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4297 /***********************************************************************
4298 * NdrFixedArrayMemorySize [RPCRT4.@]
4300 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4301 PFORMAT_STRING pFormat)
4303 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4306 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4308 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4309 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4311 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4312 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4316 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4318 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4320 total_size = pSmFArrayFormat->total_size;
4321 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4325 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4326 total_size = pLgFArrayFormat->total_size;
4327 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4329 pStubMsg->BufferMark = pStubMsg->Buffer;
4330 safe_buffer_increment(pStubMsg, total_size);
4331 pStubMsg->MemorySize += total_size;
4333 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4338 /***********************************************************************
4339 * NdrFixedArrayFree [RPCRT4.@]
4341 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4342 unsigned char *pMemory,
4343 PFORMAT_STRING pFormat)
4345 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4347 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4349 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4350 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4352 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4353 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4357 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4358 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4361 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4362 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4365 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4368 /***********************************************************************
4369 * NdrVaryingArrayMarshall [RPCRT4.@]
4371 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4372 unsigned char *pMemory,
4373 PFORMAT_STRING pFormat)
4375 unsigned char alignment;
4376 DWORD elements, esize;
4379 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4381 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4382 (pFormat[0] != RPC_FC_LGVARRAY))
4384 ERR("invalid format type %x\n", pFormat[0]);
4385 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4389 alignment = pFormat[1] + 1;
4391 if (pFormat[0] == RPC_FC_SMVARRAY)
4394 pFormat += sizeof(WORD);
4395 elements = *(const WORD*)pFormat;
4396 pFormat += sizeof(WORD);
4401 pFormat += sizeof(DWORD);
4402 elements = *(const DWORD*)pFormat;
4403 pFormat += sizeof(DWORD);
4406 esize = *(const WORD*)pFormat;
4407 pFormat += sizeof(WORD);
4409 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4410 if ((pStubMsg->ActualCount > elements) ||
4411 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4413 RpcRaiseException(RPC_S_INVALID_BOUND);
4417 WriteVariance(pStubMsg);
4419 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4421 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4422 pStubMsg->BufferMark = pStubMsg->Buffer;
4423 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
4425 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4430 /***********************************************************************
4431 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4433 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4434 unsigned char **ppMemory,
4435 PFORMAT_STRING pFormat,
4436 unsigned char fMustAlloc)
4438 unsigned char alignment;
4439 DWORD size, elements, esize;
4442 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4444 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4445 (pFormat[0] != RPC_FC_LGVARRAY))
4447 ERR("invalid format type %x\n", pFormat[0]);
4448 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4452 alignment = pFormat[1] + 1;
4454 if (pFormat[0] == RPC_FC_SMVARRAY)
4457 size = *(const WORD*)pFormat;
4458 pFormat += sizeof(WORD);
4459 elements = *(const WORD*)pFormat;
4460 pFormat += sizeof(WORD);
4465 size = *(const DWORD*)pFormat;
4466 pFormat += sizeof(DWORD);
4467 elements = *(const DWORD*)pFormat;
4468 pFormat += sizeof(DWORD);
4471 esize = *(const WORD*)pFormat;
4472 pFormat += sizeof(WORD);
4474 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4476 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4478 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4480 if (!*ppMemory || fMustAlloc)
4481 *ppMemory = NdrAllocate(pStubMsg, size);
4482 safe_copy_from_buffer(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize);
4484 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
4489 /***********************************************************************
4490 * NdrVaryingArrayBufferSize [RPCRT4.@]
4492 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4493 unsigned char *pMemory,
4494 PFORMAT_STRING pFormat)
4496 unsigned char alignment;
4497 DWORD elements, esize;
4499 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4501 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4502 (pFormat[0] != RPC_FC_LGVARRAY))
4504 ERR("invalid format type %x\n", pFormat[0]);
4505 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4509 alignment = pFormat[1] + 1;
4511 if (pFormat[0] == RPC_FC_SMVARRAY)
4514 pFormat += sizeof(WORD);
4515 elements = *(const WORD*)pFormat;
4516 pFormat += sizeof(WORD);
4521 pFormat += sizeof(DWORD);
4522 elements = *(const DWORD*)pFormat;
4523 pFormat += sizeof(DWORD);
4526 esize = *(const WORD*)pFormat;
4527 pFormat += sizeof(WORD);
4529 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4530 if ((pStubMsg->ActualCount > elements) ||
4531 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4533 RpcRaiseException(RPC_S_INVALID_BOUND);
4537 SizeVariance(pStubMsg);
4539 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4541 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4543 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4546 /***********************************************************************
4547 * NdrVaryingArrayMemorySize [RPCRT4.@]
4549 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4550 PFORMAT_STRING pFormat)
4552 unsigned char alignment;
4553 DWORD size, elements, esize;
4555 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4557 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4558 (pFormat[0] != RPC_FC_LGVARRAY))
4560 ERR("invalid format type %x\n", pFormat[0]);
4561 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4565 alignment = pFormat[1] + 1;
4567 if (pFormat[0] == RPC_FC_SMVARRAY)
4570 size = *(const WORD*)pFormat;
4571 pFormat += sizeof(WORD);
4572 elements = *(const WORD*)pFormat;
4573 pFormat += sizeof(WORD);
4578 size = *(const DWORD*)pFormat;
4579 pFormat += sizeof(DWORD);
4580 elements = *(const DWORD*)pFormat;
4581 pFormat += sizeof(DWORD);
4584 esize = *(const WORD*)pFormat;
4585 pFormat += sizeof(WORD);
4587 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4589 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4591 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4592 pStubMsg->MemorySize += size;
4594 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4596 return pStubMsg->MemorySize;
4599 /***********************************************************************
4600 * NdrVaryingArrayFree [RPCRT4.@]
4602 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4603 unsigned char *pMemory,
4604 PFORMAT_STRING pFormat)
4606 unsigned char alignment;
4609 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4611 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4612 (pFormat[0] != RPC_FC_LGVARRAY))
4614 ERR("invalid format type %x\n", pFormat[0]);
4615 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4619 alignment = pFormat[1] + 1;
4621 if (pFormat[0] == RPC_FC_SMVARRAY)
4624 pFormat += sizeof(WORD);
4625 elements = *(const WORD*)pFormat;
4626 pFormat += sizeof(WORD);
4631 pFormat += sizeof(DWORD);
4632 elements = *(const DWORD*)pFormat;
4633 pFormat += sizeof(DWORD);
4636 pFormat += sizeof(WORD);
4638 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4639 if ((pStubMsg->ActualCount > elements) ||
4640 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4642 RpcRaiseException(RPC_S_INVALID_BOUND);
4646 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4649 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
4657 return *(const UCHAR *)pMemory;
4662 return *(const USHORT *)pMemory;
4666 return *(const ULONG *)pMemory;
4668 FIXME("Unhandled base type: 0x%02x\n", fc);
4673 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4674 unsigned long discriminant,
4675 PFORMAT_STRING pFormat)
4677 unsigned short num_arms, arm, type;
4679 num_arms = *(const SHORT*)pFormat & 0x0fff;
4681 for(arm = 0; arm < num_arms; arm++)
4683 if(discriminant == *(const ULONG*)pFormat)
4691 type = *(const unsigned short*)pFormat;
4692 TRACE("type %04x\n", type);
4693 if(arm == num_arms) /* default arm extras */
4697 ERR("no arm for 0x%lx and no default case\n", discriminant);
4698 RpcRaiseException(RPC_S_INVALID_TAG);
4703 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
4710 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
4712 unsigned short type;
4716 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4720 type = *(const unsigned short*)pFormat;
4721 if((type & 0xff00) == 0x8000)
4723 unsigned char basetype = LOBYTE(type);
4724 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
4728 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4729 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
4732 unsigned char *saved_buffer = NULL;
4733 int pointer_buffer_mark_set = 0;
4740 ALIGN_POINTER(pStubMsg->Buffer, 4);
4741 saved_buffer = pStubMsg->Buffer;
4742 if (pStubMsg->PointerBufferMark)
4744 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4745 pStubMsg->PointerBufferMark = NULL;
4746 pointer_buffer_mark_set = 1;
4749 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
4751 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
4752 if (pointer_buffer_mark_set)
4754 STD_OVERFLOW_CHECK(pStubMsg);
4755 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4756 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
4758 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4759 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
4760 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4762 pStubMsg->Buffer = saved_buffer + 4;
4766 m(pStubMsg, pMemory, desc);
4769 else FIXME("no marshaller for embedded type %02x\n", *desc);
4774 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4775 unsigned char **ppMemory,
4777 PFORMAT_STRING pFormat,
4778 unsigned char fMustAlloc)
4780 unsigned short type;
4784 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4788 type = *(const unsigned short*)pFormat;
4789 if((type & 0xff00) == 0x8000)
4791 unsigned char basetype = LOBYTE(type);
4792 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
4796 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4797 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
4800 unsigned char *saved_buffer = NULL;
4801 int pointer_buffer_mark_set = 0;
4808 **(void***)ppMemory = NULL;
4809 ALIGN_POINTER(pStubMsg->Buffer, 4);
4810 saved_buffer = pStubMsg->Buffer;
4811 if (pStubMsg->PointerBufferMark)
4813 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4814 pStubMsg->PointerBufferMark = NULL;
4815 pointer_buffer_mark_set = 1;
4818 pStubMsg->Buffer += 4; /* for pointer ID */
4820 if (saved_buffer + 4 > pStubMsg->BufferEnd)
4822 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4823 saved_buffer, pStubMsg->BufferEnd);
4824 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4827 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
4828 if (pointer_buffer_mark_set)
4830 STD_OVERFLOW_CHECK(pStubMsg);
4831 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4832 pStubMsg->Buffer = saved_buffer + 4;
4836 m(pStubMsg, ppMemory, desc, fMustAlloc);
4839 else FIXME("no marshaller for embedded type %02x\n", *desc);
4844 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
4845 unsigned char *pMemory,
4847 PFORMAT_STRING pFormat)
4849 unsigned short type;
4853 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4857 type = *(const unsigned short*)pFormat;
4858 if((type & 0xff00) == 0x8000)
4860 unsigned char basetype = LOBYTE(type);
4861 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
4865 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4866 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
4875 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4876 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
4877 if (!pStubMsg->IgnoreEmbeddedPointers)
4879 int saved_buffer_length = pStubMsg->BufferLength;
4880 pStubMsg->BufferLength = pStubMsg->PointerLength;
4881 pStubMsg->PointerLength = 0;
4882 if(!pStubMsg->BufferLength)
4883 ERR("BufferLength == 0??\n");
4884 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
4885 pStubMsg->PointerLength = pStubMsg->BufferLength;
4886 pStubMsg->BufferLength = saved_buffer_length;
4890 m(pStubMsg, pMemory, desc);
4893 else FIXME("no buffersizer for embedded type %02x\n", *desc);
4897 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
4899 PFORMAT_STRING pFormat)
4901 unsigned short type, size;
4903 size = *(const unsigned short*)pFormat;
4904 pStubMsg->Memory += size;
4907 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4911 type = *(const unsigned short*)pFormat;
4912 if((type & 0xff00) == 0x8000)
4914 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
4918 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4919 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
4920 unsigned char *saved_buffer;
4929 ALIGN_POINTER(pStubMsg->Buffer, 4);
4930 saved_buffer = pStubMsg->Buffer;
4931 safe_buffer_increment(pStubMsg, 4);
4932 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
4933 pStubMsg->MemorySize += 4;
4934 if (!pStubMsg->IgnoreEmbeddedPointers)
4935 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
4938 return m(pStubMsg, desc);
4941 else FIXME("no marshaller for embedded type %02x\n", *desc);
4944 TRACE("size %d\n", size);
4948 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
4949 unsigned char *pMemory,
4951 PFORMAT_STRING pFormat)
4953 unsigned short type;
4957 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4961 type = *(const unsigned short*)pFormat;
4962 if((type & 0xff00) != 0x8000)
4964 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4965 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
4974 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
4977 m(pStubMsg, pMemory, desc);
4980 else FIXME("no freer for embedded type %02x\n", *desc);
4984 /***********************************************************************
4985 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4987 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4988 unsigned char *pMemory,
4989 PFORMAT_STRING pFormat)
4991 unsigned char switch_type;
4992 unsigned char increment;
4995 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4998 switch_type = *pFormat & 0xf;
4999 increment = (*pFormat & 0xf0) >> 4;
5002 ALIGN_POINTER(pStubMsg->Buffer, increment);
5004 switch_value = get_discriminant(switch_type, pMemory);
5005 TRACE("got switch value 0x%x\n", switch_value);
5007 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5008 pMemory += increment;
5010 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5013 /***********************************************************************
5014 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5016 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5017 unsigned char **ppMemory,
5018 PFORMAT_STRING pFormat,
5019 unsigned char fMustAlloc)
5021 unsigned char switch_type;
5022 unsigned char increment;
5024 unsigned short size;
5025 unsigned char *pMemoryArm;
5027 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5030 switch_type = *pFormat & 0xf;
5031 increment = (*pFormat & 0xf0) >> 4;
5034 ALIGN_POINTER(pStubMsg->Buffer, increment);
5035 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5036 TRACE("got switch value 0x%x\n", switch_value);
5038 size = *(const unsigned short*)pFormat + increment;
5039 if(!*ppMemory || fMustAlloc)
5040 *ppMemory = NdrAllocate(pStubMsg, size);
5042 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5043 pMemoryArm = *ppMemory + increment;
5045 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
5048 /***********************************************************************
5049 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5051 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5052 unsigned char *pMemory,
5053 PFORMAT_STRING pFormat)
5055 unsigned char switch_type;
5056 unsigned char increment;
5059 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5062 switch_type = *pFormat & 0xf;
5063 increment = (*pFormat & 0xf0) >> 4;
5066 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5067 switch_value = get_discriminant(switch_type, pMemory);
5068 TRACE("got switch value 0x%x\n", switch_value);
5070 /* Add discriminant size */
5071 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5072 pMemory += increment;
5074 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5077 /***********************************************************************
5078 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5080 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5081 PFORMAT_STRING pFormat)
5083 unsigned char switch_type;
5084 unsigned char increment;
5087 switch_type = *pFormat & 0xf;
5088 increment = (*pFormat & 0xf0) >> 4;
5091 ALIGN_POINTER(pStubMsg->Buffer, increment);
5092 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5093 TRACE("got switch value 0x%x\n", switch_value);
5095 pStubMsg->Memory += increment;
5097 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5100 /***********************************************************************
5101 * NdrEncapsulatedUnionFree [RPCRT4.@]
5103 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5104 unsigned char *pMemory,
5105 PFORMAT_STRING pFormat)
5107 unsigned char switch_type;
5108 unsigned char increment;
5111 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5114 switch_type = *pFormat & 0xf;
5115 increment = (*pFormat & 0xf0) >> 4;
5118 switch_value = get_discriminant(switch_type, pMemory);
5119 TRACE("got switch value 0x%x\n", switch_value);
5121 pMemory += increment;
5123 return union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5126 /***********************************************************************
5127 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5129 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5130 unsigned char *pMemory,
5131 PFORMAT_STRING pFormat)
5133 unsigned char switch_type;
5135 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5138 switch_type = *pFormat;
5141 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5142 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5143 /* Marshall discriminant */
5144 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5146 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5149 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5150 PFORMAT_STRING *ppFormat)
5152 long discriminant = 0;
5162 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5171 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5172 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5180 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5181 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5186 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5190 if (pStubMsg->fHasNewCorrDesc)
5194 return discriminant;
5197 /**********************************************************************
5198 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5200 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5201 unsigned char **ppMemory,
5202 PFORMAT_STRING pFormat,
5203 unsigned char fMustAlloc)
5206 unsigned short size;
5208 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5211 /* Unmarshall discriminant */
5212 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5213 TRACE("unmarshalled discriminant %lx\n", discriminant);
5215 pFormat += *(const SHORT*)pFormat;
5217 size = *(const unsigned short*)pFormat;
5219 if(!*ppMemory || fMustAlloc)
5220 *ppMemory = NdrAllocate(pStubMsg, size);
5222 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5225 /***********************************************************************
5226 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5228 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5229 unsigned char *pMemory,
5230 PFORMAT_STRING pFormat)
5232 unsigned char switch_type;
5234 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5237 switch_type = *pFormat;
5240 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5241 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5242 /* Add discriminant size */
5243 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5245 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5248 /***********************************************************************
5249 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5251 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5252 PFORMAT_STRING pFormat)
5257 /* Unmarshall discriminant */
5258 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5259 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
5261 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
5264 /***********************************************************************
5265 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5267 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5268 unsigned char *pMemory,
5269 PFORMAT_STRING pFormat)
5271 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5275 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5276 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5278 return union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5281 /***********************************************************************
5282 * NdrByteCountPointerMarshall [RPCRT4.@]
5284 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5285 unsigned char *pMemory,
5286 PFORMAT_STRING pFormat)
5292 /***********************************************************************
5293 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5295 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5296 unsigned char **ppMemory,
5297 PFORMAT_STRING pFormat,
5298 unsigned char fMustAlloc)
5304 /***********************************************************************
5305 * NdrByteCountPointerBufferSize [RPCRT4.@]
5307 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5308 unsigned char *pMemory,
5309 PFORMAT_STRING pFormat)
5314 /***********************************************************************
5315 * NdrByteCountPointerMemorySize [RPCRT4.@]
5317 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5318 PFORMAT_STRING pFormat)
5324 /***********************************************************************
5325 * NdrByteCountPointerFree [RPCRT4.@]
5327 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
5328 unsigned char *pMemory,
5329 PFORMAT_STRING pFormat)
5334 /***********************************************************************
5335 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5337 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5338 unsigned char *pMemory,
5339 PFORMAT_STRING pFormat)
5345 /***********************************************************************
5346 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5348 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5349 unsigned char **ppMemory,
5350 PFORMAT_STRING pFormat,
5351 unsigned char fMustAlloc)
5357 /***********************************************************************
5358 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5360 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5361 unsigned char *pMemory,
5362 PFORMAT_STRING pFormat)
5367 /***********************************************************************
5368 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5370 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5371 PFORMAT_STRING pFormat)
5377 /***********************************************************************
5378 * NdrXmitOrRepAsFree [RPCRT4.@]
5380 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
5381 unsigned char *pMemory,
5382 PFORMAT_STRING pFormat)
5387 #include "pshpack1.h"
5391 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
5395 #include "poppack.h"
5397 /***********************************************************************
5398 * NdrRangeMarshall [internal]
5400 unsigned char *WINAPI NdrRangeMarshall(
5401 PMIDL_STUB_MESSAGE pStubMsg,
5402 unsigned char *pMemory,
5403 PFORMAT_STRING pFormat)
5405 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5406 unsigned char base_type;
5408 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5410 if (pRange->type != RPC_FC_RANGE)
5412 ERR("invalid format type %x\n", pRange->type);
5413 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5417 base_type = pRange->flags_type & 0xf;
5419 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
5422 /***********************************************************************
5423 * NdrRangeUnmarshall
5425 unsigned char *WINAPI NdrRangeUnmarshall(
5426 PMIDL_STUB_MESSAGE pStubMsg,
5427 unsigned char **ppMemory,
5428 PFORMAT_STRING pFormat,
5429 unsigned char fMustAlloc)
5431 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5432 unsigned char base_type;
5434 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5436 if (pRange->type != RPC_FC_RANGE)
5438 ERR("invalid format type %x\n", pRange->type);
5439 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5442 base_type = pRange->flags_type & 0xf;
5444 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5445 base_type, pRange->low_value, pRange->high_value);
5447 #define RANGE_UNMARSHALL(type, format_spec) \
5450 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5451 if (fMustAlloc || !*ppMemory) \
5452 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5453 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5455 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5456 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5457 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5459 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5460 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5462 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5463 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5464 (type)pRange->high_value); \
5465 RpcRaiseException(RPC_S_INVALID_BOUND); \
5468 TRACE("*ppMemory: %p\n", *ppMemory); \
5469 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5470 pStubMsg->Buffer += sizeof(type); \
5477 RANGE_UNMARSHALL(UCHAR, "%d");
5478 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5482 RANGE_UNMARSHALL(CHAR, "%u");
5483 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5485 case RPC_FC_WCHAR: /* FIXME: valid? */
5487 RANGE_UNMARSHALL(USHORT, "%u");
5488 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5491 RANGE_UNMARSHALL(SHORT, "%d");
5492 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5495 RANGE_UNMARSHALL(LONG, "%d");
5496 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5499 RANGE_UNMARSHALL(ULONG, "%u");
5500 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5504 FIXME("Unhandled enum type\n");
5506 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
5511 ERR("invalid range base type: 0x%02x\n", base_type);
5512 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5518 /***********************************************************************
5519 * NdrRangeBufferSize [internal]
5521 void WINAPI NdrRangeBufferSize(
5522 PMIDL_STUB_MESSAGE pStubMsg,
5523 unsigned char *pMemory,
5524 PFORMAT_STRING pFormat)
5526 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5527 unsigned char base_type;
5529 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5531 if (pRange->type != RPC_FC_RANGE)
5533 ERR("invalid format type %x\n", pRange->type);
5534 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5536 base_type = pRange->flags_type & 0xf;
5538 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
5541 /***********************************************************************
5542 * NdrRangeMemorySize [internal]
5544 ULONG WINAPI NdrRangeMemorySize(
5545 PMIDL_STUB_MESSAGE pStubMsg,
5546 PFORMAT_STRING pFormat)
5548 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5549 unsigned char base_type;
5551 if (pRange->type != RPC_FC_RANGE)
5553 ERR("invalid format type %x\n", pRange->type);
5554 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5557 base_type = pRange->flags_type & 0xf;
5559 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
5562 /***********************************************************************
5563 * NdrRangeFree [internal]
5565 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
5566 unsigned char *pMemory,
5567 PFORMAT_STRING pFormat)
5569 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5574 /***********************************************************************
5575 * NdrBaseTypeMarshall [internal]
5577 static unsigned char *WINAPI NdrBaseTypeMarshall(
5578 PMIDL_STUB_MESSAGE pStubMsg,
5579 unsigned char *pMemory,
5580 PFORMAT_STRING pFormat)
5582 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5590 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
5591 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
5596 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5597 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
5598 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
5602 case RPC_FC_ERROR_STATUS_T:
5604 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5605 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
5606 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
5609 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
5610 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
5613 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
5614 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
5617 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
5618 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
5619 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
5622 /* only 16-bits on the wire, so do a sanity check */
5623 if (*(UINT *)pMemory > SHRT_MAX)
5624 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
5625 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5626 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5627 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5628 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
5629 pStubMsg->Buffer += sizeof(USHORT);
5630 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
5635 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5638 /* FIXME: what is the correct return value? */
5642 /***********************************************************************
5643 * NdrBaseTypeUnmarshall [internal]
5645 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
5646 PMIDL_STUB_MESSAGE pStubMsg,
5647 unsigned char **ppMemory,
5648 PFORMAT_STRING pFormat,
5649 unsigned char fMustAlloc)
5651 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5653 #define BASE_TYPE_UNMARSHALL(type) \
5654 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5655 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
5657 *ppMemory = pStubMsg->Buffer; \
5658 TRACE("*ppMemory: %p\n", *ppMemory); \
5663 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5664 TRACE("*ppMemory: %p\n", *ppMemory); \
5665 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5667 pStubMsg->Buffer += sizeof(type);
5675 BASE_TYPE_UNMARSHALL(UCHAR);
5676 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5681 BASE_TYPE_UNMARSHALL(USHORT);
5682 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5686 case RPC_FC_ERROR_STATUS_T:
5688 BASE_TYPE_UNMARSHALL(ULONG);
5689 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5692 BASE_TYPE_UNMARSHALL(float);
5693 TRACE("value: %f\n", **(float **)ppMemory);
5696 BASE_TYPE_UNMARSHALL(double);
5697 TRACE("value: %f\n", **(double **)ppMemory);
5700 BASE_TYPE_UNMARSHALL(ULONGLONG);
5701 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
5704 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5705 if (fMustAlloc || !*ppMemory)
5706 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
5707 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
5708 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5709 TRACE("*ppMemory: %p\n", *ppMemory);
5710 /* 16-bits on the wire, but int in memory */
5711 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
5712 pStubMsg->Buffer += sizeof(USHORT);
5713 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
5718 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5720 #undef BASE_TYPE_UNMARSHALL
5722 /* FIXME: what is the correct return value? */
5727 /***********************************************************************
5728 * NdrBaseTypeBufferSize [internal]
5730 static void WINAPI NdrBaseTypeBufferSize(
5731 PMIDL_STUB_MESSAGE pStubMsg,
5732 unsigned char *pMemory,
5733 PFORMAT_STRING pFormat)
5735 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5743 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
5749 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
5750 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
5755 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
5756 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
5759 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
5760 safe_buffer_length_increment(pStubMsg, sizeof(float));
5763 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
5764 safe_buffer_length_increment(pStubMsg, sizeof(double));
5767 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
5768 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
5770 case RPC_FC_ERROR_STATUS_T:
5771 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
5772 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
5777 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5781 /***********************************************************************
5782 * NdrBaseTypeMemorySize [internal]
5784 static ULONG WINAPI NdrBaseTypeMemorySize(
5785 PMIDL_STUB_MESSAGE pStubMsg,
5786 PFORMAT_STRING pFormat)
5788 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
5796 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
5797 pStubMsg->MemorySize += sizeof(UCHAR);
5798 return sizeof(UCHAR);
5802 safe_buffer_increment(pStubMsg, sizeof(USHORT));
5803 pStubMsg->MemorySize += sizeof(USHORT);
5804 return sizeof(USHORT);
5808 safe_buffer_increment(pStubMsg, sizeof(ULONG));
5809 pStubMsg->MemorySize += sizeof(ULONG);
5810 return sizeof(ULONG);
5812 safe_buffer_increment(pStubMsg, sizeof(float));
5813 pStubMsg->MemorySize += sizeof(float);
5814 return sizeof(float);
5816 safe_buffer_increment(pStubMsg, sizeof(double));
5817 pStubMsg->MemorySize += sizeof(double);
5818 return sizeof(double);
5820 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
5821 pStubMsg->MemorySize += sizeof(ULONGLONG);
5822 return sizeof(ULONGLONG);
5823 case RPC_FC_ERROR_STATUS_T:
5824 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
5825 pStubMsg->MemorySize += sizeof(error_status_t);
5826 return sizeof(error_status_t);
5828 safe_buffer_increment(pStubMsg, sizeof(USHORT));
5829 pStubMsg->MemorySize += sizeof(UINT);
5830 return sizeof(UINT);
5832 pStubMsg->MemorySize += sizeof(void *);
5833 return sizeof(void *);
5835 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5840 /***********************************************************************
5841 * NdrBaseTypeFree [internal]
5843 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
5844 unsigned char *pMemory,
5845 PFORMAT_STRING pFormat)
5847 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5852 /***********************************************************************
5853 * NdrContextHandleBufferSize [internal]
5855 static void WINAPI NdrContextHandleBufferSize(
5856 PMIDL_STUB_MESSAGE pStubMsg,
5857 unsigned char *pMemory,
5858 PFORMAT_STRING pFormat)
5860 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5862 if (*pFormat != RPC_FC_BIND_CONTEXT)
5864 ERR("invalid format type %x\n", *pFormat);
5865 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5867 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5868 safe_buffer_length_increment(pStubMsg, cbNDRContext);
5871 /***********************************************************************
5872 * NdrContextHandleMarshall [internal]
5874 static unsigned char *WINAPI NdrContextHandleMarshall(
5875 PMIDL_STUB_MESSAGE pStubMsg,
5876 unsigned char *pMemory,
5877 PFORMAT_STRING pFormat)
5879 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5881 if (*pFormat != RPC_FC_BIND_CONTEXT)
5883 ERR("invalid format type %x\n", *pFormat);
5884 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5887 if (pFormat[1] & 0x80)
5888 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
5890 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
5895 /***********************************************************************
5896 * NdrContextHandleUnmarshall [internal]
5898 static unsigned char *WINAPI NdrContextHandleUnmarshall(
5899 PMIDL_STUB_MESSAGE pStubMsg,
5900 unsigned char **ppMemory,
5901 PFORMAT_STRING pFormat,
5902 unsigned char fMustAlloc)
5904 if (*pFormat != RPC_FC_BIND_CONTEXT)
5906 ERR("invalid format type %x\n", *pFormat);
5907 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5910 **(NDR_CCONTEXT **)ppMemory = NULL;
5911 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
5916 /***********************************************************************
5917 * NdrClientContextMarshall [RPCRT4.@]
5919 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5920 NDR_CCONTEXT ContextHandle,
5923 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
5925 ALIGN_POINTER(pStubMsg->Buffer, 4);
5927 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5929 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
5930 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5931 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5934 /* FIXME: what does fCheck do? */
5935 NDRCContextMarshall(ContextHandle,
5938 pStubMsg->Buffer += cbNDRContext;
5941 /***********************************************************************
5942 * NdrClientContextUnmarshall [RPCRT4.@]
5944 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5945 NDR_CCONTEXT * pContextHandle,
5946 RPC_BINDING_HANDLE BindHandle)
5948 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
5950 ALIGN_POINTER(pStubMsg->Buffer, 4);
5952 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
5953 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5955 NDRCContextUnmarshall(pContextHandle,
5958 pStubMsg->RpcMsg->DataRepresentation);
5960 pStubMsg->Buffer += cbNDRContext;
5963 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5964 NDR_SCONTEXT ContextHandle,
5965 NDR_RUNDOWN RundownRoutine )
5967 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
5970 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
5972 FIXME("(%p): stub\n", pStubMsg);
5976 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
5977 unsigned char* pMemory,
5978 PFORMAT_STRING pFormat)
5980 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
5983 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
5984 PFORMAT_STRING pFormat)
5986 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
5990 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5991 NDR_SCONTEXT ContextHandle,
5992 NDR_RUNDOWN RundownRoutine,
5993 PFORMAT_STRING pFormat)
5995 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
5998 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5999 PFORMAT_STRING pFormat)
6001 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
6005 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
6007 typedef struct ndr_context_handle
6011 } ndr_context_handle;
6013 struct context_handle_entry
6017 RPC_BINDING_HANDLE handle;
6018 ndr_context_handle wire_data;
6021 static struct list context_handle_list = LIST_INIT(context_handle_list);
6023 static CRITICAL_SECTION ndr_context_cs;
6024 static CRITICAL_SECTION_DEBUG ndr_context_debug =
6026 0, 0, &ndr_context_cs,
6027 { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
6028 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
6030 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
6032 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
6034 struct context_handle_entry *che = (struct context_handle_entry*) CContext;
6036 if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
6041 static struct context_handle_entry *context_entry_from_guid(LPCGUID uuid)
6043 struct context_handle_entry *che;
6044 LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
6045 if (IsEqualGUID(&che->wire_data.uuid, uuid))
6050 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
6052 struct context_handle_entry *che;
6053 RPC_BINDING_HANDLE handle = NULL;
6055 TRACE("%p\n", CContext);
6057 EnterCriticalSection(&ndr_context_cs);
6058 che = get_context_entry(CContext);
6060 handle = che->handle;
6061 LeaveCriticalSection(&ndr_context_cs);
6064 RpcRaiseException(ERROR_INVALID_HANDLE);
6068 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
6070 struct context_handle_entry *che;
6072 TRACE("%p %p\n", CContext, pBuff);
6076 EnterCriticalSection(&ndr_context_cs);
6077 che = get_context_entry(CContext);
6078 memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
6079 LeaveCriticalSection(&ndr_context_cs);
6083 ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
6084 wire_data->attributes = 0;
6085 wire_data->uuid = GUID_NULL;
6089 /***********************************************************************
6090 * RpcSmDestroyClientContext [RPCRT4.@]
6092 RPC_STATUS WINAPI RpcSmDestroyClientContext(void **ContextHandle)
6094 RPC_STATUS status = RPC_X_SS_CONTEXT_MISMATCH;
6095 struct context_handle_entry *che = NULL;
6097 TRACE("(%p)\n", ContextHandle);
6099 EnterCriticalSection(&ndr_context_cs);
6100 che = get_context_entry(*ContextHandle);
6101 *ContextHandle = NULL;
6105 list_remove(&che->entry);
6108 LeaveCriticalSection(&ndr_context_cs);
6112 RpcBindingFree(&che->handle);
6113 HeapFree(GetProcessHeap(), 0, che);
6119 /***********************************************************************
6120 * RpcSsDestroyClientContext [RPCRT4.@]
6122 void WINAPI RpcSsDestroyClientContext(void **ContextHandle)
6124 RPC_STATUS status = RpcSmDestroyClientContext(ContextHandle);
6125 if (status != RPC_S_OK)
6126 RpcRaiseException(status);
6129 static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
6130 RPC_BINDING_HANDLE hBinding,
6131 const ndr_context_handle *chi)
6133 struct context_handle_entry *che = NULL;
6135 /* a null UUID means we should free the context handle */
6136 if (IsEqualGUID(&chi->uuid, &GUID_NULL))
6140 che = get_context_entry(*CContext);
6142 return ERROR_INVALID_HANDLE;
6143 list_remove(&che->entry);
6144 RpcBindingFree(&che->handle);
6145 HeapFree(GetProcessHeap(), 0, che);
6149 /* if there's no existing entry matching the GUID, allocate one */
6150 else if (!(che = context_entry_from_guid(&chi->uuid)))
6152 che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
6154 return ERROR_NOT_ENOUGH_MEMORY;
6155 che->magic = NDR_CONTEXT_HANDLE_MAGIC;
6156 RpcBindingCopy(hBinding, &che->handle);
6157 list_add_tail(&context_handle_list, &che->entry);
6158 memcpy(&che->wire_data, chi, sizeof *chi);
6163 return ERROR_SUCCESS;
6166 /***********************************************************************
6167 * NDRCContextUnmarshall [RPCRT4.@]
6169 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
6170 RPC_BINDING_HANDLE hBinding,
6171 void *pBuff, ULONG DataRepresentation)
6175 TRACE("*%p=(%p) %p %p %08x\n",
6176 CContext, *CContext, hBinding, pBuff, DataRepresentation);
6178 EnterCriticalSection(&ndr_context_cs);
6179 r = ndr_update_context_handle(CContext, hBinding, pBuff);
6180 LeaveCriticalSection(&ndr_context_cs);
6182 RpcRaiseException(r);
6185 /***********************************************************************
6186 * NDRSContextMarshall [RPCRT4.@]
6188 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
6190 NDR_RUNDOWN userRunDownIn)
6192 FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn);
6195 /***********************************************************************
6196 * NDRSContextMarshallEx [RPCRT4.@]
6198 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
6199 NDR_SCONTEXT CContext,
6201 NDR_RUNDOWN userRunDownIn)
6203 FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn);
6206 /***********************************************************************
6207 * NDRSContextMarshall2 [RPCRT4.@]
6209 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
6210 NDR_SCONTEXT CContext,
6212 NDR_RUNDOWN userRunDownIn,
6213 void *CtxGuard, ULONG Flags)
6215 FIXME("(%p %p %p %p %p %u): stub\n",
6216 hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags);
6219 /***********************************************************************
6220 * NDRSContextUnmarshall [RPCRT4.@]
6222 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
6223 ULONG DataRepresentation)
6225 FIXME("(%p %08x): stub\n", pBuff, DataRepresentation);
6229 /***********************************************************************
6230 * NDRSContextUnmarshallEx [RPCRT4.@]
6232 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
6234 ULONG DataRepresentation)
6236 FIXME("(%p %p %08x): stub\n", hBinding, pBuff, DataRepresentation);
6240 /***********************************************************************
6241 * NDRSContextUnmarshall2 [RPCRT4.@]
6243 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
6245 ULONG DataRepresentation,
6246 void *CtxGuard, ULONG Flags)
6248 FIXME("(%p %p %08x %p %u): stub\n",
6249 hBinding, pBuff, DataRepresentation, CtxGuard, Flags);