4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 * - Non-conformant strings
24 * - Byte count pointers
25 * - transmit_as/represent as
26 * - Multi-dimensional arrays
27 * - Conversion functions (NdrConvert)
28 * - Checks for integer addition overflow in base type and user marshall functions
44 #include "wine/unicode.h"
45 #include "wine/rpcfc.h"
47 #include "wine/debug.h"
48 #include "wine/list.h"
50 WINE_DEFAULT_DEBUG_CHANNEL(ole);
53 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
54 (*((UINT32 *)(pchar)) = (uint32))
56 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
57 (*((UINT32 *)(pchar)))
59 /* these would work for i386 too, but less efficient */
60 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
61 (*(pchar) = LOBYTE(LOWORD(uint32)), \
62 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
63 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
64 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
65 (uint32)) /* allow as r-value */
67 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
69 MAKEWORD(*(pchar), *((pchar)+1)), \
70 MAKEWORD(*((pchar)+2), *((pchar)+3))))
73 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
74 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
75 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
76 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
77 *(pchar) = HIBYTE(HIWORD(uint32)), \
78 (uint32)) /* allow as r-value */
80 #define BIG_ENDIAN_UINT32_READ(pchar) \
82 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
83 MAKEWORD(*((pchar)+1), *(pchar))))
85 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
86 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
87 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
88 # define NDR_LOCAL_UINT32_READ(pchar) \
89 BIG_ENDIAN_UINT32_READ(pchar)
91 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
92 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
93 # define NDR_LOCAL_UINT32_READ(pchar) \
94 LITTLE_ENDIAN_UINT32_READ(pchar)
97 /* _Align must be the desired alignment,
98 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
99 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
100 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
101 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
102 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
104 #define STD_OVERFLOW_CHECK(_Msg) do { \
105 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
106 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
107 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
110 #define NDR_TABLE_SIZE 128
111 #define NDR_TABLE_MASK 127
113 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
114 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
115 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
116 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
117 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
119 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
120 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
121 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
123 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
125 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
126 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
127 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
128 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
132 NdrPointerMarshall, NdrPointerMarshall,
133 NdrPointerMarshall, NdrPointerMarshall,
135 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
136 NdrConformantStructMarshall, NdrConformantStructMarshall,
137 NdrConformantVaryingStructMarshall,
138 NdrComplexStructMarshall,
140 NdrConformantArrayMarshall,
141 NdrConformantVaryingArrayMarshall,
142 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
143 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
144 NdrComplexArrayMarshall,
146 NdrConformantStringMarshall, 0, 0,
147 NdrConformantStringMarshall,
148 NdrNonConformantStringMarshall, 0, 0, 0,
150 NdrEncapsulatedUnionMarshall,
151 NdrNonEncapsulatedUnionMarshall,
152 NdrByteCountPointerMarshall,
153 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
155 NdrInterfacePointerMarshall,
157 NdrContextHandleMarshall,
160 NdrUserMarshalMarshall,
165 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
167 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
168 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
169 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
170 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
172 NdrBaseTypeUnmarshall,
174 NdrPointerUnmarshall, NdrPointerUnmarshall,
175 NdrPointerUnmarshall, NdrPointerUnmarshall,
177 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
178 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
179 NdrConformantVaryingStructUnmarshall,
180 NdrComplexStructUnmarshall,
182 NdrConformantArrayUnmarshall,
183 NdrConformantVaryingArrayUnmarshall,
184 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
185 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
186 NdrComplexArrayUnmarshall,
188 NdrConformantStringUnmarshall, 0, 0,
189 NdrConformantStringUnmarshall,
190 NdrNonConformantStringUnmarshall, 0, 0, 0,
192 NdrEncapsulatedUnionUnmarshall,
193 NdrNonEncapsulatedUnionUnmarshall,
194 NdrByteCountPointerUnmarshall,
195 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
197 NdrInterfacePointerUnmarshall,
199 NdrContextHandleUnmarshall,
202 NdrUserMarshalUnmarshall,
207 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
209 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
210 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
211 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
212 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
214 NdrBaseTypeBufferSize,
216 NdrPointerBufferSize, NdrPointerBufferSize,
217 NdrPointerBufferSize, NdrPointerBufferSize,
219 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
220 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
221 NdrConformantVaryingStructBufferSize,
222 NdrComplexStructBufferSize,
224 NdrConformantArrayBufferSize,
225 NdrConformantVaryingArrayBufferSize,
226 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
227 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
228 NdrComplexArrayBufferSize,
230 NdrConformantStringBufferSize, 0, 0,
231 NdrConformantStringBufferSize,
232 NdrNonConformantStringBufferSize, 0, 0, 0,
234 NdrEncapsulatedUnionBufferSize,
235 NdrNonEncapsulatedUnionBufferSize,
236 NdrByteCountPointerBufferSize,
237 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
239 NdrInterfacePointerBufferSize,
241 NdrContextHandleBufferSize,
244 NdrUserMarshalBufferSize,
249 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
251 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
252 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
253 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
254 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
256 NdrBaseTypeMemorySize,
258 NdrPointerMemorySize, NdrPointerMemorySize,
259 NdrPointerMemorySize, NdrPointerMemorySize,
261 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
262 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
263 NdrConformantVaryingStructMemorySize,
264 NdrComplexStructMemorySize,
266 NdrConformantArrayMemorySize,
267 NdrConformantVaryingArrayMemorySize,
268 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
269 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
270 NdrComplexArrayMemorySize,
272 NdrConformantStringMemorySize, 0, 0,
273 NdrConformantStringMemorySize,
274 NdrNonConformantStringMemorySize, 0, 0, 0,
276 NdrEncapsulatedUnionMemorySize,
277 NdrNonEncapsulatedUnionMemorySize,
278 NdrByteCountPointerMemorySize,
279 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
281 NdrInterfacePointerMemorySize,
286 NdrUserMarshalMemorySize,
291 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
293 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
294 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
295 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
296 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
300 NdrPointerFree, NdrPointerFree,
301 NdrPointerFree, NdrPointerFree,
303 NdrSimpleStructFree, NdrSimpleStructFree,
304 NdrConformantStructFree, NdrConformantStructFree,
305 NdrConformantVaryingStructFree,
306 NdrComplexStructFree,
308 NdrConformantArrayFree,
309 NdrConformantVaryingArrayFree,
310 NdrFixedArrayFree, NdrFixedArrayFree,
311 NdrVaryingArrayFree, NdrVaryingArrayFree,
317 NdrEncapsulatedUnionFree,
318 NdrNonEncapsulatedUnionFree,
320 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
322 NdrInterfacePointerFree,
333 typedef struct _NDR_MEMORY_LIST
338 struct _NDR_MEMORY_LIST *next;
341 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
343 /***********************************************************************
344 * NdrAllocate [RPCRT4.@]
346 * Allocates a block of memory using pStubMsg->pfnAllocate.
349 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
350 * len [I] Size of memory block to allocate.
353 * The memory block of size len that was allocated.
356 * The memory block is always 8-byte aligned.
357 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
358 * exception is raised.
360 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
365 NDR_MEMORY_LIST *mem_list;
367 aligned_len = ALIGNED_LENGTH(len, 8);
368 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
369 /* check for overflow */
370 if (adjusted_len < len)
372 ERR("overflow of adjusted_len %d, len %d\n", adjusted_len, len);
373 RpcRaiseException(RPC_X_BAD_STUB_DATA);
376 p = pStubMsg->pfnAllocate(adjusted_len);
377 if (!p) RpcRaiseException(ERROR_OUTOFMEMORY);
379 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
380 mem_list->magic = MEML_MAGIC;
381 mem_list->size = aligned_len;
382 mem_list->reserved = 0;
383 mem_list->next = pStubMsg->pMemoryList;
384 pStubMsg->pMemoryList = mem_list;
390 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
392 TRACE("(%p, %p)\n", pStubMsg, Pointer);
394 pStubMsg->pfnFree(Pointer);
397 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
399 return (*(const ULONG *)pFormat != -1);
402 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
404 ALIGN_POINTER(pStubMsg->Buffer, 4);
405 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
406 RpcRaiseException(RPC_X_BAD_STUB_DATA);
407 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
408 pStubMsg->Buffer += 4;
409 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
410 if (pStubMsg->fHasNewCorrDesc)
416 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
418 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
420 pStubMsg->Offset = 0;
421 pStubMsg->ActualCount = pStubMsg->MaxCount;
425 ALIGN_POINTER(pStubMsg->Buffer, 4);
426 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
427 RpcRaiseException(RPC_X_BAD_STUB_DATA);
428 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
429 pStubMsg->Buffer += 4;
430 TRACE("offset is %d\n", pStubMsg->Offset);
431 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
432 pStubMsg->Buffer += 4;
433 TRACE("variance is %d\n", pStubMsg->ActualCount);
435 if ((pStubMsg->ActualCount > MaxValue) ||
436 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
438 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
439 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
440 RpcRaiseException(RPC_S_INVALID_BOUND);
445 if (pStubMsg->fHasNewCorrDesc)
451 /* writes the conformance value to the buffer */
452 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
454 ALIGN_POINTER(pStubMsg->Buffer, 4);
455 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
456 RpcRaiseException(RPC_X_BAD_STUB_DATA);
457 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
458 pStubMsg->Buffer += 4;
461 /* writes the variance values to the buffer */
462 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
464 ALIGN_POINTER(pStubMsg->Buffer, 4);
465 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
466 RpcRaiseException(RPC_X_BAD_STUB_DATA);
467 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
468 pStubMsg->Buffer += 4;
469 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
470 pStubMsg->Buffer += 4;
473 /* requests buffer space for the conformance value */
474 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
476 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
477 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
478 RpcRaiseException(RPC_X_BAD_STUB_DATA);
479 pStubMsg->BufferLength += 4;
482 /* requests buffer space for the variance values */
483 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
485 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
486 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
487 RpcRaiseException(RPC_X_BAD_STUB_DATA);
488 pStubMsg->BufferLength += 8;
491 PFORMAT_STRING ComputeConformanceOrVariance(
492 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
493 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
495 BYTE dtype = pFormat[0] & 0xf;
496 short ofs = *(const short *)&pFormat[2];
500 if (!IsConformanceOrVariancePresent(pFormat)) {
501 /* null descriptor */
506 switch (pFormat[0] & 0xf0) {
507 case RPC_FC_NORMAL_CONFORMANCE:
508 TRACE("normal conformance, ofs=%d\n", ofs);
511 case RPC_FC_POINTER_CONFORMANCE:
512 TRACE("pointer conformance, ofs=%d\n", ofs);
513 ptr = pStubMsg->Memory;
515 case RPC_FC_TOP_LEVEL_CONFORMANCE:
516 TRACE("toplevel conformance, ofs=%d\n", ofs);
517 if (pStubMsg->StackTop) {
518 ptr = pStubMsg->StackTop;
521 /* -Os mode, *pCount is already set */
525 case RPC_FC_CONSTANT_CONFORMANCE:
526 data = ofs | ((DWORD)pFormat[1] << 16);
527 TRACE("constant conformance, val=%d\n", data);
530 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
531 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
532 if (pStubMsg->StackTop) {
533 ptr = pStubMsg->StackTop;
541 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
544 switch (pFormat[1]) {
545 case RPC_FC_DEREFERENCE:
546 ptr = *(LPVOID*)((char *)ptr + ofs);
548 case RPC_FC_CALLBACK:
550 unsigned char *old_stack_top = pStubMsg->StackTop;
551 pStubMsg->StackTop = ptr;
553 /* ofs is index into StubDesc->apfnExprEval */
554 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
555 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
557 pStubMsg->StackTop = old_stack_top;
559 /* the callback function always stores the computed value in MaxCount */
560 *pCount = pStubMsg->MaxCount;
564 ptr = (char *)ptr + ofs;
577 data = *(USHORT*)ptr;
588 FIXME("unknown conformance data type %x\n", dtype);
591 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
594 switch (pFormat[1]) {
595 case RPC_FC_DEREFERENCE: /* already handled */
612 FIXME("unknown conformance op %d\n", pFormat[1]);
617 TRACE("resulting conformance is %ld\n", *pCount);
618 if (pStubMsg->fHasNewCorrDesc)
624 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
625 * the result overflows 32-bits */
626 static inline ULONG safe_multiply(ULONG a, ULONG b)
628 ULONGLONG ret = (ULONGLONG)a * b;
629 if (ret > 0xffffffff)
631 RpcRaiseException(RPC_S_INVALID_BOUND);
637 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
639 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
640 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
641 RpcRaiseException(RPC_X_BAD_STUB_DATA);
642 pStubMsg->Buffer += size;
645 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
647 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
649 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
650 pStubMsg->BufferLength, size);
651 RpcRaiseException(RPC_X_BAD_STUB_DATA);
653 pStubMsg->BufferLength += size;
656 /* copies data from the buffer, checking that there is enough data in the buffer
658 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
660 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
661 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
662 RpcRaiseException(RPC_X_BAD_STUB_DATA);
663 memcpy(p, pStubMsg->Buffer, size);
664 pStubMsg->Buffer += size;
667 /* copies data to the buffer, checking that there is enough space to do so */
668 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
670 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
671 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
673 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
674 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
676 RpcRaiseException(RPC_X_BAD_STUB_DATA);
678 memcpy(pStubMsg->Buffer, p, size);
679 pStubMsg->Buffer += size;
683 * NdrConformantString:
685 * What MS calls a ConformantString is, in DCE terminology,
686 * a Varying-Conformant String.
688 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
689 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
690 * into unmarshalled string)
691 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
693 * data: CHARTYPE[maxlen]
695 * ], where CHARTYPE is the appropriate character type (specified externally)
699 /***********************************************************************
700 * NdrConformantStringMarshall [RPCRT4.@]
702 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
703 unsigned char *pszMessage, PFORMAT_STRING pFormat)
707 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
709 if (*pFormat == RPC_FC_C_CSTRING) {
710 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
711 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
714 else if (*pFormat == RPC_FC_C_WSTRING) {
715 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
716 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
720 ERR("Unhandled string type: %#x\n", *pFormat);
721 /* FIXME: raise an exception. */
725 if (pFormat[1] == RPC_FC_STRING_SIZED)
726 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
728 pStubMsg->MaxCount = pStubMsg->ActualCount;
729 pStubMsg->Offset = 0;
730 WriteConformance(pStubMsg);
731 WriteVariance(pStubMsg);
733 size = safe_multiply(esize, pStubMsg->ActualCount);
734 safe_copy_to_buffer(pStubMsg, pszMessage, size); /* the string itself */
737 return NULL; /* is this always right? */
740 /***********************************************************************
741 * NdrConformantStringBufferSize [RPCRT4.@]
743 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
744 unsigned char* pMemory, PFORMAT_STRING pFormat)
748 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
750 SizeConformance(pStubMsg);
751 SizeVariance(pStubMsg);
753 if (*pFormat == RPC_FC_C_CSTRING) {
754 TRACE("string=%s\n", debugstr_a((char*)pMemory));
755 pStubMsg->ActualCount = strlen((char*)pMemory)+1;
758 else if (*pFormat == RPC_FC_C_WSTRING) {
759 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
760 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;
764 ERR("Unhandled string type: %#x\n", *pFormat);
765 /* FIXME: raise an exception */
769 if (pFormat[1] == RPC_FC_STRING_SIZED)
770 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
772 pStubMsg->MaxCount = pStubMsg->ActualCount;
774 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
777 /************************************************************************
778 * NdrConformantStringMemorySize [RPCRT4.@]
780 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
781 PFORMAT_STRING pFormat )
785 FIXME("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
787 assert(pStubMsg && pFormat);
789 if (*pFormat == RPC_FC_C_CSTRING) {
790 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
792 else if (*pFormat == RPC_FC_C_WSTRING) {
793 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
796 ERR("Unhandled string type: %#x\n", *pFormat);
797 /* FIXME: raise an exception */
800 if (pFormat[1] != RPC_FC_PAD) {
801 FIXME("sized string format=%d\n", pFormat[1]);
804 TRACE(" --> %u\n", rslt);
808 /************************************************************************
809 * NdrConformantStringUnmarshall [RPCRT4.@]
811 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
812 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
814 ULONG bufsize, memsize, esize, i;
816 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
817 pStubMsg, *ppMemory, pFormat, fMustAlloc);
819 assert(pFormat && ppMemory && pStubMsg);
821 ReadConformance(pStubMsg, NULL);
822 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
824 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
825 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
827 ERR("Unhandled string type: %#x\n", *pFormat);
828 /* FIXME: raise an exception */
832 memsize = safe_multiply(esize, pStubMsg->MaxCount);
833 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
835 /* strings must always have null terminating bytes */
838 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
839 RpcRaiseException(RPC_S_INVALID_BOUND);
843 /* verify the buffer is safe to access */
844 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
845 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
847 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
848 pStubMsg->BufferEnd, pStubMsg->Buffer);
849 RpcRaiseException(RPC_X_BAD_STUB_DATA);
853 for (i = bufsize - esize; i < bufsize; i++)
854 if (pStubMsg->Buffer[i] != 0)
856 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
857 i, pStubMsg->Buffer[i]);
858 RpcRaiseException(RPC_S_INVALID_BOUND);
862 if (fMustAlloc || !*ppMemory)
863 *ppMemory = NdrAllocate(pStubMsg, memsize);
865 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
867 if (*pFormat == RPC_FC_C_CSTRING) {
868 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
870 else if (*pFormat == RPC_FC_C_WSTRING) {
871 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
874 return NULL; /* FIXME: is this always right? */
877 /***********************************************************************
878 * NdrNonConformantStringMarshall [RPCRT4.@]
880 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
881 unsigned char *pMemory,
882 PFORMAT_STRING pFormat)
888 /***********************************************************************
889 * NdrNonConformantStringUnmarshall [RPCRT4.@]
891 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
892 unsigned char **ppMemory,
893 PFORMAT_STRING pFormat,
894 unsigned char fMustAlloc)
900 /***********************************************************************
901 * NdrNonConformantStringBufferSize [RPCRT4.@]
903 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
904 unsigned char *pMemory,
905 PFORMAT_STRING pFormat)
910 /***********************************************************************
911 * NdrNonConformantStringMemorySize [RPCRT4.@]
913 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
914 PFORMAT_STRING pFormat)
920 static inline void dump_pointer_attr(unsigned char attr)
922 if (attr & RPC_FC_P_ALLOCALLNODES)
923 TRACE(" RPC_FC_P_ALLOCALLNODES");
924 if (attr & RPC_FC_P_DONTFREE)
925 TRACE(" RPC_FC_P_DONTFREE");
926 if (attr & RPC_FC_P_ONSTACK)
927 TRACE(" RPC_FC_P_ONSTACK");
928 if (attr & RPC_FC_P_SIMPLEPOINTER)
929 TRACE(" RPC_FC_P_SIMPLEPOINTER");
930 if (attr & RPC_FC_P_DEREF)
931 TRACE(" RPC_FC_P_DEREF");
935 /***********************************************************************
936 * PointerMarshall [internal]
938 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
939 unsigned char *Buffer,
940 unsigned char *Pointer,
941 PFORMAT_STRING pFormat)
943 unsigned type = pFormat[0], attr = pFormat[1];
947 int pointer_needs_marshaling;
949 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
950 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
952 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
953 else desc = pFormat + *(const SHORT*)pFormat;
956 case RPC_FC_RP: /* ref pointer (always non-null) */
959 ERR("NULL ref pointer is not allowed\n");
960 RpcRaiseException(RPC_X_NULL_REF_POINTER);
962 pointer_needs_marshaling = 1;
964 case RPC_FC_UP: /* unique pointer */
965 case RPC_FC_OP: /* object pointer - same as unique here */
967 pointer_needs_marshaling = 1;
969 pointer_needs_marshaling = 0;
970 pointer_id = (ULONG)Pointer;
971 TRACE("writing 0x%08x to buffer\n", pointer_id);
972 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
975 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
976 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
977 TRACE("writing 0x%08x to buffer\n", pointer_id);
978 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
981 FIXME("unhandled ptr type=%02x\n", type);
982 RpcRaiseException(RPC_X_BAD_STUB_DATA);
986 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
988 if (pointer_needs_marshaling) {
989 if (attr & RPC_FC_P_DEREF) {
990 Pointer = *(unsigned char**)Pointer;
991 TRACE("deref => %p\n", Pointer);
993 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
994 if (m) m(pStubMsg, Pointer, desc);
995 else FIXME("no marshaller for data type=%02x\n", *desc);
998 STD_OVERFLOW_CHECK(pStubMsg);
1001 /***********************************************************************
1002 * PointerUnmarshall [internal]
1004 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1005 unsigned char *Buffer,
1006 unsigned char **pPointer,
1007 unsigned char *pSrcPointer,
1008 PFORMAT_STRING pFormat,
1009 unsigned char fMustAlloc)
1011 unsigned type = pFormat[0], attr = pFormat[1];
1012 PFORMAT_STRING desc;
1014 DWORD pointer_id = 0;
1015 int pointer_needs_unmarshaling;
1017 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
1018 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1020 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1021 else desc = pFormat + *(const SHORT*)pFormat;
1024 case RPC_FC_RP: /* ref pointer (always non-null) */
1025 pointer_needs_unmarshaling = 1;
1027 case RPC_FC_UP: /* unique pointer */
1028 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1029 TRACE("pointer_id is 0x%08x\n", pointer_id);
1031 pointer_needs_unmarshaling = 1;
1034 pointer_needs_unmarshaling = 0;
1037 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1038 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1039 TRACE("pointer_id is 0x%08x\n", pointer_id);
1040 if (!fMustAlloc && pSrcPointer)
1042 FIXME("free object pointer %p\n", pSrcPointer);
1046 pointer_needs_unmarshaling = 1;
1048 pointer_needs_unmarshaling = 0;
1051 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1052 TRACE("pointer_id is 0x%08x\n", pointer_id);
1053 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
1054 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
1057 FIXME("unhandled ptr type=%02x\n", type);
1058 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1062 if (pointer_needs_unmarshaling) {
1063 unsigned char *base_ptr_val = *pPointer;
1064 unsigned char **current_ptr = pPointer;
1065 if (pStubMsg->IsClient) {
1067 /* if we aren't forcing allocation of memory then try to use the existing
1068 * (source) pointer to unmarshall the data into so that [in,out]
1069 * parameters behave correctly. it doesn't matter if the parameter is
1070 * [out] only since in that case the pointer will be NULL. we force
1071 * allocation when the source pointer is NULL here instead of in the type
1072 * unmarshalling routine for the benefit of the deref code below */
1075 TRACE("setting *pPointer to %p\n", pSrcPointer);
1076 *pPointer = base_ptr_val = pSrcPointer;
1082 /* the memory in a stub is never initialised, so we have to work out here
1083 * whether we have to initialise it so we can use the optimisation of
1084 * setting the pointer to the buffer, if possible, or set fMustAlloc to
1086 if (attr & RPC_FC_P_DEREF) {
1089 base_ptr_val = NULL;
1090 *current_ptr = NULL;
1094 if (attr & RPC_FC_P_DEREF) {
1096 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
1097 *pPointer = base_ptr_val;
1098 current_ptr = (unsigned char **)base_ptr_val;
1100 current_ptr = *(unsigned char***)current_ptr;
1101 TRACE("deref => %p\n", current_ptr);
1102 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
1104 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1105 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
1106 else FIXME("no unmarshaller for data type=%02x\n", *desc);
1108 if (type == RPC_FC_FP)
1109 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
1113 TRACE("pointer=%p\n", *pPointer);
1116 /***********************************************************************
1117 * PointerBufferSize [internal]
1119 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1120 unsigned char *Pointer,
1121 PFORMAT_STRING pFormat)
1123 unsigned type = pFormat[0], attr = pFormat[1];
1124 PFORMAT_STRING desc;
1126 int pointer_needs_sizing;
1129 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1130 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1132 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1133 else desc = pFormat + *(const SHORT*)pFormat;
1136 case RPC_FC_RP: /* ref pointer (always non-null) */
1139 ERR("NULL ref pointer is not allowed\n");
1140 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1145 /* NULL pointer has no further representation */
1150 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1151 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1152 if (!pointer_needs_sizing)
1156 FIXME("unhandled ptr type=%02x\n", type);
1157 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1161 if (attr & RPC_FC_P_DEREF) {
1162 Pointer = *(unsigned char**)Pointer;
1163 TRACE("deref => %p\n", Pointer);
1166 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1167 if (m) m(pStubMsg, Pointer, desc);
1168 else FIXME("no buffersizer for data type=%02x\n", *desc);
1171 /***********************************************************************
1172 * PointerMemorySize [internal]
1174 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1175 unsigned char *Buffer,
1176 PFORMAT_STRING pFormat)
1178 unsigned type = pFormat[0], attr = pFormat[1];
1179 PFORMAT_STRING desc;
1181 DWORD pointer_id = 0;
1182 int pointer_needs_sizing;
1184 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1185 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1187 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1188 else desc = pFormat + *(const SHORT*)pFormat;
1191 case RPC_FC_RP: /* ref pointer (always non-null) */
1192 pointer_needs_sizing = 1;
1194 case RPC_FC_UP: /* unique pointer */
1195 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1196 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1197 TRACE("pointer_id is 0x%08x\n", pointer_id);
1199 pointer_needs_sizing = 1;
1201 pointer_needs_sizing = 0;
1206 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1207 TRACE("pointer_id is 0x%08x\n", pointer_id);
1208 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1209 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1213 FIXME("unhandled ptr type=%02x\n", type);
1214 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1218 if (attr & RPC_FC_P_DEREF) {
1222 if (pointer_needs_sizing) {
1223 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1224 if (m) m(pStubMsg, desc);
1225 else FIXME("no memorysizer for data type=%02x\n", *desc);
1228 return pStubMsg->MemorySize;
1231 /***********************************************************************
1232 * PointerFree [internal]
1234 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1235 unsigned char *Pointer,
1236 PFORMAT_STRING pFormat)
1238 unsigned type = pFormat[0], attr = pFormat[1];
1239 PFORMAT_STRING desc;
1241 unsigned char *current_pointer = Pointer;
1243 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1244 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1245 if (attr & RPC_FC_P_DONTFREE) return;
1247 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1248 else desc = pFormat + *(const SHORT*)pFormat;
1250 if (!Pointer) return;
1252 if (type == RPC_FC_FP) {
1253 int pointer_needs_freeing = NdrFullPointerFree(
1254 pStubMsg->FullPtrXlatTables, Pointer);
1255 if (!pointer_needs_freeing)
1259 if (attr & RPC_FC_P_DEREF) {
1260 current_pointer = *(unsigned char**)Pointer;
1261 TRACE("deref => %p\n", current_pointer);
1264 m = NdrFreer[*desc & NDR_TABLE_MASK];
1265 if (m) m(pStubMsg, current_pointer, desc);
1267 /* this check stops us from trying to free buffer memory. we don't have to
1268 * worry about clients, since they won't call this function.
1269 * we don't have to check for the buffer being reallocated because
1270 * BufferStart and BufferEnd won't be reset when allocating memory for
1271 * sending the response. we don't have to check for the new buffer here as
1272 * it won't be used a type memory, only for buffer memory */
1273 if (Pointer >= (unsigned char *)pStubMsg->BufferStart &&
1274 Pointer < (unsigned char *)pStubMsg->BufferEnd)
1277 if (attr & RPC_FC_P_ONSTACK) {
1278 TRACE("not freeing stack ptr %p\n", Pointer);
1281 TRACE("freeing %p\n", Pointer);
1282 NdrFree(pStubMsg, Pointer);
1285 TRACE("not freeing %p\n", Pointer);
1288 /***********************************************************************
1289 * EmbeddedPointerMarshall
1291 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1292 unsigned char *pMemory,
1293 PFORMAT_STRING pFormat)
1295 unsigned char *Mark = pStubMsg->BufferMark;
1296 unsigned rep, count, stride;
1298 unsigned char *saved_buffer = NULL;
1300 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1302 if (*pFormat != RPC_FC_PP) return NULL;
1305 if (pStubMsg->PointerBufferMark)
1307 saved_buffer = pStubMsg->Buffer;
1308 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1309 pStubMsg->PointerBufferMark = NULL;
1312 while (pFormat[0] != RPC_FC_END) {
1313 switch (pFormat[0]) {
1315 FIXME("unknown repeat type %d\n", pFormat[0]);
1316 case RPC_FC_NO_REPEAT:
1322 case RPC_FC_FIXED_REPEAT:
1323 rep = *(const WORD*)&pFormat[2];
1324 stride = *(const WORD*)&pFormat[4];
1325 count = *(const WORD*)&pFormat[8];
1328 case RPC_FC_VARIABLE_REPEAT:
1329 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1330 stride = *(const WORD*)&pFormat[2];
1331 count = *(const WORD*)&pFormat[6];
1335 for (i = 0; i < rep; i++) {
1336 PFORMAT_STRING info = pFormat;
1337 unsigned char *membase = pMemory + (i * stride);
1338 unsigned char *bufbase = Mark + (i * stride);
1341 for (u=0; u<count; u++,info+=8) {
1342 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1343 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1344 unsigned char *saved_memory = pStubMsg->Memory;
1346 pStubMsg->Memory = pMemory;
1347 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1348 pStubMsg->Memory = saved_memory;
1351 pFormat += 8 * count;
1356 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1357 pStubMsg->Buffer = saved_buffer;
1360 STD_OVERFLOW_CHECK(pStubMsg);
1365 /***********************************************************************
1366 * EmbeddedPointerUnmarshall
1368 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1369 unsigned char *pDstMemoryPtrs,
1370 unsigned char *pSrcMemoryPtrs,
1371 PFORMAT_STRING pFormat,
1372 unsigned char fMustAlloc)
1374 unsigned char *Mark = pStubMsg->BufferMark;
1375 unsigned rep, count, stride;
1377 unsigned char *saved_buffer = NULL;
1379 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstMemoryPtrs, pSrcMemoryPtrs, pFormat, fMustAlloc);
1381 if (*pFormat != RPC_FC_PP) return NULL;
1384 if (pStubMsg->PointerBufferMark)
1386 saved_buffer = pStubMsg->Buffer;
1387 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1388 pStubMsg->PointerBufferMark = NULL;
1391 while (pFormat[0] != RPC_FC_END) {
1392 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1393 switch (pFormat[0]) {
1395 FIXME("unknown repeat type %d\n", pFormat[0]);
1396 case RPC_FC_NO_REPEAT:
1402 case RPC_FC_FIXED_REPEAT:
1403 rep = *(const WORD*)&pFormat[2];
1404 stride = *(const WORD*)&pFormat[4];
1405 count = *(const WORD*)&pFormat[8];
1408 case RPC_FC_VARIABLE_REPEAT:
1409 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1410 stride = *(const WORD*)&pFormat[2];
1411 count = *(const WORD*)&pFormat[6];
1415 for (i = 0; i < rep; i++) {
1416 PFORMAT_STRING info = pFormat;
1417 unsigned char *memdstbase = pDstMemoryPtrs + (i * stride);
1418 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1419 unsigned char *bufbase = Mark + (i * stride);
1422 for (u=0; u<count; u++,info+=8) {
1423 unsigned char **memdstptr = (unsigned char **)(memdstbase + *(const SHORT*)&info[0]);
1424 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1425 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1426 PointerUnmarshall(pStubMsg, bufptr, memdstptr, *memsrcptr, info+4, fMustAlloc);
1429 pFormat += 8 * count;
1434 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1435 pStubMsg->Buffer = saved_buffer;
1441 /***********************************************************************
1442 * EmbeddedPointerBufferSize
1444 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1445 unsigned char *pMemory,
1446 PFORMAT_STRING pFormat)
1448 unsigned rep, count, stride;
1450 ULONG saved_buffer_length = 0;
1452 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1454 if (pStubMsg->IgnoreEmbeddedPointers) return;
1456 if (*pFormat != RPC_FC_PP) return;
1459 if (pStubMsg->PointerLength)
1461 saved_buffer_length = pStubMsg->BufferLength;
1462 pStubMsg->BufferLength = pStubMsg->PointerLength;
1463 pStubMsg->PointerLength = 0;
1466 while (pFormat[0] != RPC_FC_END) {
1467 switch (pFormat[0]) {
1469 FIXME("unknown repeat type %d\n", pFormat[0]);
1470 case RPC_FC_NO_REPEAT:
1476 case RPC_FC_FIXED_REPEAT:
1477 rep = *(const WORD*)&pFormat[2];
1478 stride = *(const WORD*)&pFormat[4];
1479 count = *(const WORD*)&pFormat[8];
1482 case RPC_FC_VARIABLE_REPEAT:
1483 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1484 stride = *(const WORD*)&pFormat[2];
1485 count = *(const WORD*)&pFormat[6];
1489 for (i = 0; i < rep; i++) {
1490 PFORMAT_STRING info = pFormat;
1491 unsigned char *membase = pMemory + (i * stride);
1494 for (u=0; u<count; u++,info+=8) {
1495 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1496 unsigned char *saved_memory = pStubMsg->Memory;
1498 pStubMsg->Memory = pMemory;
1499 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1500 pStubMsg->Memory = saved_memory;
1503 pFormat += 8 * count;
1506 if (saved_buffer_length)
1508 pStubMsg->PointerLength = pStubMsg->BufferLength;
1509 pStubMsg->BufferLength = saved_buffer_length;
1513 /***********************************************************************
1514 * EmbeddedPointerMemorySize [internal]
1516 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1517 PFORMAT_STRING pFormat)
1519 unsigned char *Mark = pStubMsg->BufferMark;
1520 unsigned rep, count, stride;
1522 unsigned char *saved_buffer = NULL;
1524 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1526 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1528 if (pStubMsg->PointerBufferMark)
1530 saved_buffer = pStubMsg->Buffer;
1531 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1532 pStubMsg->PointerBufferMark = NULL;
1535 if (*pFormat != RPC_FC_PP) return 0;
1538 while (pFormat[0] != RPC_FC_END) {
1539 switch (pFormat[0]) {
1541 FIXME("unknown repeat type %d\n", pFormat[0]);
1542 case RPC_FC_NO_REPEAT:
1548 case RPC_FC_FIXED_REPEAT:
1549 rep = *(const WORD*)&pFormat[2];
1550 stride = *(const WORD*)&pFormat[4];
1551 count = *(const WORD*)&pFormat[8];
1554 case RPC_FC_VARIABLE_REPEAT:
1555 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1556 stride = *(const WORD*)&pFormat[2];
1557 count = *(const WORD*)&pFormat[6];
1561 for (i = 0; i < rep; i++) {
1562 PFORMAT_STRING info = pFormat;
1563 unsigned char *bufbase = Mark + (i * stride);
1565 for (u=0; u<count; u++,info+=8) {
1566 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1567 PointerMemorySize(pStubMsg, bufptr, info+4);
1570 pFormat += 8 * count;
1575 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1576 pStubMsg->Buffer = saved_buffer;
1582 /***********************************************************************
1583 * EmbeddedPointerFree [internal]
1585 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1586 unsigned char *pMemory,
1587 PFORMAT_STRING pFormat)
1589 unsigned rep, count, stride;
1592 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1593 if (*pFormat != RPC_FC_PP) return;
1596 while (pFormat[0] != RPC_FC_END) {
1597 switch (pFormat[0]) {
1599 FIXME("unknown repeat type %d\n", pFormat[0]);
1600 case RPC_FC_NO_REPEAT:
1606 case RPC_FC_FIXED_REPEAT:
1607 rep = *(const WORD*)&pFormat[2];
1608 stride = *(const WORD*)&pFormat[4];
1609 count = *(const WORD*)&pFormat[8];
1612 case RPC_FC_VARIABLE_REPEAT:
1613 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1614 stride = *(const WORD*)&pFormat[2];
1615 count = *(const WORD*)&pFormat[6];
1619 for (i = 0; i < rep; i++) {
1620 PFORMAT_STRING info = pFormat;
1621 unsigned char *membase = pMemory + (i * stride);
1624 for (u=0; u<count; u++,info+=8) {
1625 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1626 unsigned char *saved_memory = pStubMsg->Memory;
1628 pStubMsg->Memory = pMemory;
1629 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1630 pStubMsg->Memory = saved_memory;
1633 pFormat += 8 * count;
1637 /***********************************************************************
1638 * NdrPointerMarshall [RPCRT4.@]
1640 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1641 unsigned char *pMemory,
1642 PFORMAT_STRING pFormat)
1644 unsigned char *Buffer;
1646 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1648 /* incremement the buffer here instead of in PointerMarshall,
1649 * as that is used by embedded pointers which already handle the incrementing
1650 * the buffer, and shouldn't write any additional pointer data to the wire */
1651 if (*pFormat != RPC_FC_RP)
1653 ALIGN_POINTER(pStubMsg->Buffer, 4);
1654 Buffer = pStubMsg->Buffer;
1655 safe_buffer_increment(pStubMsg, 4);
1658 Buffer = pStubMsg->Buffer;
1660 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1665 /***********************************************************************
1666 * NdrPointerUnmarshall [RPCRT4.@]
1668 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1669 unsigned char **ppMemory,
1670 PFORMAT_STRING pFormat,
1671 unsigned char fMustAlloc)
1673 unsigned char *Buffer;
1675 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1677 /* incremement the buffer here instead of in PointerUnmarshall,
1678 * as that is used by embedded pointers which already handle the incrementing
1679 * the buffer, and shouldn't read any additional pointer data from the
1681 if (*pFormat != RPC_FC_RP)
1683 ALIGN_POINTER(pStubMsg->Buffer, 4);
1684 Buffer = pStubMsg->Buffer;
1685 safe_buffer_increment(pStubMsg, 4);
1688 Buffer = pStubMsg->Buffer;
1690 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1695 /***********************************************************************
1696 * NdrPointerBufferSize [RPCRT4.@]
1698 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1699 unsigned char *pMemory,
1700 PFORMAT_STRING pFormat)
1702 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1704 /* incremement the buffer length here instead of in PointerBufferSize,
1705 * as that is used by embedded pointers which already handle the buffer
1706 * length, and shouldn't write anything more to the wire */
1707 if (*pFormat != RPC_FC_RP)
1709 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1710 safe_buffer_length_increment(pStubMsg, 4);
1713 PointerBufferSize(pStubMsg, pMemory, pFormat);
1716 /***********************************************************************
1717 * NdrPointerMemorySize [RPCRT4.@]
1719 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1720 PFORMAT_STRING pFormat)
1722 /* unsigned size = *(LPWORD)(pFormat+2); */
1723 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1724 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1728 /***********************************************************************
1729 * NdrPointerFree [RPCRT4.@]
1731 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1732 unsigned char *pMemory,
1733 PFORMAT_STRING pFormat)
1735 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1736 PointerFree(pStubMsg, pMemory, pFormat);
1739 /***********************************************************************
1740 * NdrSimpleTypeMarshall [RPCRT4.@]
1742 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1743 unsigned char FormatChar )
1745 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1748 /***********************************************************************
1749 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1751 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1752 unsigned char FormatChar )
1754 NdrBaseTypeUnmarshall(pStubMsg, &pMemory, &FormatChar, 0);
1757 /***********************************************************************
1758 * NdrSimpleStructMarshall [RPCRT4.@]
1760 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1761 unsigned char *pMemory,
1762 PFORMAT_STRING pFormat)
1764 unsigned size = *(const WORD*)(pFormat+2);
1765 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1767 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1769 pStubMsg->BufferMark = pStubMsg->Buffer;
1770 safe_copy_to_buffer(pStubMsg, pMemory, size);
1772 if (pFormat[0] != RPC_FC_STRUCT)
1773 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1778 /***********************************************************************
1779 * NdrSimpleStructUnmarshall [RPCRT4.@]
1781 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1782 unsigned char **ppMemory,
1783 PFORMAT_STRING pFormat,
1784 unsigned char fMustAlloc)
1786 unsigned size = *(const WORD*)(pFormat+2);
1787 unsigned char *saved_buffer;
1788 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1790 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1793 *ppMemory = NdrAllocate(pStubMsg, size);
1796 if (!pStubMsg->IsClient && !*ppMemory)
1797 /* for servers, we just point straight into the RPC buffer */
1798 *ppMemory = pStubMsg->Buffer;
1801 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1802 safe_buffer_increment(pStubMsg, size);
1803 if (pFormat[0] == RPC_FC_PSTRUCT)
1804 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1806 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1807 if (*ppMemory != saved_buffer)
1808 memcpy(*ppMemory, saved_buffer, size);
1813 /***********************************************************************
1814 * NdrSimpleStructBufferSize [RPCRT4.@]
1816 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1817 unsigned char *pMemory,
1818 PFORMAT_STRING pFormat)
1820 unsigned size = *(const WORD*)(pFormat+2);
1821 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1823 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1825 safe_buffer_length_increment(pStubMsg, size);
1826 if (pFormat[0] != RPC_FC_STRUCT)
1827 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1830 /***********************************************************************
1831 * NdrSimpleStructMemorySize [RPCRT4.@]
1833 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1834 PFORMAT_STRING pFormat)
1836 unsigned short size = *(const WORD *)(pFormat+2);
1838 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1840 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1841 pStubMsg->MemorySize += size;
1842 safe_buffer_increment(pStubMsg, size);
1844 if (pFormat[0] != RPC_FC_STRUCT)
1845 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1846 return pStubMsg->MemorySize;
1849 /***********************************************************************
1850 * NdrSimpleStructFree [RPCRT4.@]
1852 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1853 unsigned char *pMemory,
1854 PFORMAT_STRING pFormat)
1856 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1857 if (pFormat[0] != RPC_FC_STRUCT)
1858 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1862 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE *pStubMsg,
1863 PFORMAT_STRING pFormat)
1867 case RPC_FC_PSTRUCT:
1868 case RPC_FC_CSTRUCT:
1869 case RPC_FC_BOGUS_STRUCT:
1870 case RPC_FC_SMFARRAY:
1871 case RPC_FC_SMVARRAY:
1872 return *(const WORD*)&pFormat[2];
1873 case RPC_FC_USER_MARSHAL:
1874 return *(const WORD*)&pFormat[4];
1875 case RPC_FC_NON_ENCAPSULATED_UNION:
1877 if (pStubMsg->fHasNewCorrDesc)
1882 pFormat += *(const SHORT*)pFormat;
1883 return *(const SHORT*)pFormat;
1885 return sizeof(void *);
1887 FIXME("unhandled embedded type %02x\n", *pFormat);
1893 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1894 PFORMAT_STRING pFormat)
1896 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1900 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1904 return m(pStubMsg, pFormat);
1908 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1909 unsigned char *pMemory,
1910 PFORMAT_STRING pFormat,
1911 PFORMAT_STRING pPointer)
1913 PFORMAT_STRING desc;
1917 while (*pFormat != RPC_FC_END) {
1923 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
1924 safe_copy_to_buffer(pStubMsg, pMemory, 1);
1930 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1931 safe_copy_to_buffer(pStubMsg, pMemory, 2);
1937 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
1938 safe_copy_to_buffer(pStubMsg, pMemory, 4);
1942 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1943 safe_copy_to_buffer(pStubMsg, pMemory, 8);
1946 case RPC_FC_POINTER:
1948 unsigned char *saved_buffer;
1949 int pointer_buffer_mark_set = 0;
1950 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1951 saved_buffer = pStubMsg->Buffer;
1952 if (pStubMsg->PointerBufferMark)
1954 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1955 pStubMsg->PointerBufferMark = NULL;
1956 pointer_buffer_mark_set = 1;
1959 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
1960 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
1961 if (pointer_buffer_mark_set)
1963 STD_OVERFLOW_CHECK(pStubMsg);
1964 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1965 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
1967 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
1968 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
1969 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1971 pStubMsg->Buffer = saved_buffer + 4;
1977 case RPC_FC_ALIGNM4:
1978 ALIGN_POINTER(pMemory, 4);
1980 case RPC_FC_ALIGNM8:
1981 ALIGN_POINTER(pMemory, 8);
1983 case RPC_FC_STRUCTPAD1:
1984 case RPC_FC_STRUCTPAD2:
1985 case RPC_FC_STRUCTPAD3:
1986 case RPC_FC_STRUCTPAD4:
1987 case RPC_FC_STRUCTPAD5:
1988 case RPC_FC_STRUCTPAD6:
1989 case RPC_FC_STRUCTPAD7:
1990 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1992 case RPC_FC_EMBEDDED_COMPLEX:
1993 pMemory += pFormat[1];
1995 desc = pFormat + *(const SHORT*)pFormat;
1996 size = EmbeddedComplexSize(pStubMsg, desc);
1997 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1998 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2001 /* for some reason interface pointers aren't generated as
2002 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2003 * they still need the derefencing treatment that pointers are
2005 if (*desc == RPC_FC_IP)
2006 m(pStubMsg, *(unsigned char **)pMemory, desc);
2008 m(pStubMsg, pMemory, desc);
2010 else FIXME("no marshaller for embedded type %02x\n", *desc);
2017 FIXME("unhandled format 0x%02x\n", *pFormat);
2025 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2026 unsigned char *pMemory,
2027 PFORMAT_STRING pFormat,
2028 PFORMAT_STRING pPointer)
2030 PFORMAT_STRING desc;
2034 while (*pFormat != RPC_FC_END) {
2040 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2041 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2047 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2048 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2054 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2055 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2059 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2060 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2063 case RPC_FC_POINTER:
2065 unsigned char *saved_buffer;
2066 int pointer_buffer_mark_set = 0;
2067 TRACE("pointer => %p\n", pMemory);
2068 ALIGN_POINTER(pStubMsg->Buffer, 4);
2069 saved_buffer = pStubMsg->Buffer;
2070 if (pStubMsg->PointerBufferMark)
2072 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2073 pStubMsg->PointerBufferMark = NULL;
2074 pointer_buffer_mark_set = 1;
2077 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2079 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, TRUE);
2080 if (pointer_buffer_mark_set)
2082 STD_OVERFLOW_CHECK(pStubMsg);
2083 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2084 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2086 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2087 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2088 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2090 pStubMsg->Buffer = saved_buffer + 4;
2096 case RPC_FC_ALIGNM4:
2097 ALIGN_POINTER(pMemory, 4);
2099 case RPC_FC_ALIGNM8:
2100 ALIGN_POINTER(pMemory, 8);
2102 case RPC_FC_STRUCTPAD1:
2103 case RPC_FC_STRUCTPAD2:
2104 case RPC_FC_STRUCTPAD3:
2105 case RPC_FC_STRUCTPAD4:
2106 case RPC_FC_STRUCTPAD5:
2107 case RPC_FC_STRUCTPAD6:
2108 case RPC_FC_STRUCTPAD7:
2109 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2111 case RPC_FC_EMBEDDED_COMPLEX:
2112 pMemory += pFormat[1];
2114 desc = pFormat + *(const SHORT*)pFormat;
2115 size = EmbeddedComplexSize(pStubMsg, desc);
2116 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2117 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2118 memset(pMemory, 0, size); /* just in case */
2121 /* for some reason interface pointers aren't generated as
2122 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2123 * they still need the derefencing treatment that pointers are
2125 if (*desc == RPC_FC_IP)
2126 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2128 m(pStubMsg, &pMemory, desc, FALSE);
2130 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2137 FIXME("unhandled format %d\n", *pFormat);
2145 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2146 unsigned char *pMemory,
2147 PFORMAT_STRING pFormat,
2148 PFORMAT_STRING pPointer)
2150 PFORMAT_STRING desc;
2154 while (*pFormat != RPC_FC_END) {
2160 safe_buffer_length_increment(pStubMsg, 1);
2166 safe_buffer_length_increment(pStubMsg, 2);
2172 safe_buffer_length_increment(pStubMsg, 4);
2176 safe_buffer_length_increment(pStubMsg, 8);
2179 case RPC_FC_POINTER:
2180 if (!pStubMsg->IgnoreEmbeddedPointers)
2182 int saved_buffer_length = pStubMsg->BufferLength;
2183 pStubMsg->BufferLength = pStubMsg->PointerLength;
2184 pStubMsg->PointerLength = 0;
2185 if(!pStubMsg->BufferLength)
2186 ERR("BufferLength == 0??\n");
2187 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2188 pStubMsg->PointerLength = pStubMsg->BufferLength;
2189 pStubMsg->BufferLength = saved_buffer_length;
2191 safe_buffer_length_increment(pStubMsg, 4);
2195 case RPC_FC_ALIGNM4:
2196 ALIGN_POINTER(pMemory, 4);
2198 case RPC_FC_ALIGNM8:
2199 ALIGN_POINTER(pMemory, 8);
2201 case RPC_FC_STRUCTPAD1:
2202 case RPC_FC_STRUCTPAD2:
2203 case RPC_FC_STRUCTPAD3:
2204 case RPC_FC_STRUCTPAD4:
2205 case RPC_FC_STRUCTPAD5:
2206 case RPC_FC_STRUCTPAD6:
2207 case RPC_FC_STRUCTPAD7:
2208 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2210 case RPC_FC_EMBEDDED_COMPLEX:
2211 pMemory += pFormat[1];
2213 desc = pFormat + *(const SHORT*)pFormat;
2214 size = EmbeddedComplexSize(pStubMsg, desc);
2215 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2218 /* for some reason interface pointers aren't generated as
2219 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2220 * they still need the derefencing treatment that pointers are
2222 if (*desc == RPC_FC_IP)
2223 m(pStubMsg, *(unsigned char **)pMemory, desc);
2225 m(pStubMsg, pMemory, desc);
2227 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2234 FIXME("unhandled format 0x%02x\n", *pFormat);
2242 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2243 unsigned char *pMemory,
2244 PFORMAT_STRING pFormat,
2245 PFORMAT_STRING pPointer)
2247 PFORMAT_STRING desc;
2251 while (*pFormat != RPC_FC_END) {
2272 case RPC_FC_POINTER:
2273 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
2277 case RPC_FC_ALIGNM4:
2278 ALIGN_POINTER(pMemory, 4);
2280 case RPC_FC_ALIGNM8:
2281 ALIGN_POINTER(pMemory, 8);
2283 case RPC_FC_STRUCTPAD1:
2284 case RPC_FC_STRUCTPAD2:
2285 case RPC_FC_STRUCTPAD3:
2286 case RPC_FC_STRUCTPAD4:
2287 case RPC_FC_STRUCTPAD5:
2288 case RPC_FC_STRUCTPAD6:
2289 case RPC_FC_STRUCTPAD7:
2290 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2292 case RPC_FC_EMBEDDED_COMPLEX:
2293 pMemory += pFormat[1];
2295 desc = pFormat + *(const SHORT*)pFormat;
2296 size = EmbeddedComplexSize(pStubMsg, desc);
2297 m = NdrFreer[*desc & NDR_TABLE_MASK];
2300 /* for some reason interface pointers aren't generated as
2301 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2302 * they still need the derefencing treatment that pointers are
2304 if (*desc == RPC_FC_IP)
2305 m(pStubMsg, *(unsigned char **)pMemory, desc);
2307 m(pStubMsg, pMemory, desc);
2309 else FIXME("no freer for embedded type %02x\n", *desc);
2316 FIXME("unhandled format 0x%02x\n", *pFormat);
2324 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2325 PFORMAT_STRING pFormat)
2327 PFORMAT_STRING desc;
2328 unsigned long size = 0;
2330 while (*pFormat != RPC_FC_END) {
2337 safe_buffer_increment(pStubMsg, 1);
2343 safe_buffer_increment(pStubMsg, 2);
2349 safe_buffer_increment(pStubMsg, 4);
2353 safe_buffer_increment(pStubMsg, 8);
2355 case RPC_FC_POINTER:
2357 safe_buffer_increment(pStubMsg, 4);
2358 if (!pStubMsg->IgnoreEmbeddedPointers)
2359 FIXME("embedded pointers\n");
2361 case RPC_FC_ALIGNM4:
2362 ALIGN_LENGTH(size, 4);
2363 ALIGN_POINTER(pStubMsg->Buffer, 4);
2365 case RPC_FC_ALIGNM8:
2366 ALIGN_LENGTH(size, 8);
2367 ALIGN_POINTER(pStubMsg->Buffer, 8);
2369 case RPC_FC_STRUCTPAD1:
2370 case RPC_FC_STRUCTPAD2:
2371 case RPC_FC_STRUCTPAD3:
2372 case RPC_FC_STRUCTPAD4:
2373 case RPC_FC_STRUCTPAD5:
2374 case RPC_FC_STRUCTPAD6:
2375 case RPC_FC_STRUCTPAD7:
2376 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2378 case RPC_FC_EMBEDDED_COMPLEX:
2381 desc = pFormat + *(const SHORT*)pFormat;
2382 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2388 FIXME("unhandled format 0x%02x\n", *pFormat);
2396 /***********************************************************************
2397 * NdrComplexStructMarshall [RPCRT4.@]
2399 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2400 unsigned char *pMemory,
2401 PFORMAT_STRING pFormat)
2403 PFORMAT_STRING conf_array = NULL;
2404 PFORMAT_STRING pointer_desc = NULL;
2405 unsigned char *OldMemory = pStubMsg->Memory;
2406 int pointer_buffer_mark_set = 0;
2408 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2410 if (!pStubMsg->PointerBufferMark)
2412 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2413 /* save buffer length */
2414 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2416 /* get the buffer pointer after complex array data, but before
2418 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2419 pStubMsg->IgnoreEmbeddedPointers = 1;
2420 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2421 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2423 /* save it for use by embedded pointer code later */
2424 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2425 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
2426 pointer_buffer_mark_set = 1;
2428 /* restore the original buffer length */
2429 pStubMsg->BufferLength = saved_buffer_length;
2432 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2435 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2437 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2440 pStubMsg->Memory = pMemory;
2442 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2445 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2447 pStubMsg->Memory = OldMemory;
2449 if (pointer_buffer_mark_set)
2451 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2452 pStubMsg->PointerBufferMark = NULL;
2455 STD_OVERFLOW_CHECK(pStubMsg);
2460 /***********************************************************************
2461 * NdrComplexStructUnmarshall [RPCRT4.@]
2463 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2464 unsigned char **ppMemory,
2465 PFORMAT_STRING pFormat,
2466 unsigned char fMustAlloc)
2468 unsigned size = *(const WORD*)(pFormat+2);
2469 PFORMAT_STRING conf_array = NULL;
2470 PFORMAT_STRING pointer_desc = NULL;
2471 unsigned char *pMemory;
2472 int pointer_buffer_mark_set = 0;
2474 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2476 if (!pStubMsg->PointerBufferMark)
2478 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2479 /* save buffer pointer */
2480 unsigned char *saved_buffer = pStubMsg->Buffer;
2482 /* get the buffer pointer after complex array data, but before
2484 pStubMsg->IgnoreEmbeddedPointers = 1;
2485 NdrComplexStructMemorySize(pStubMsg, pFormat);
2486 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2488 /* save it for use by embedded pointer code later */
2489 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2490 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
2491 pointer_buffer_mark_set = 1;
2493 /* restore the original buffer */
2494 pStubMsg->Buffer = saved_buffer;
2497 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2499 if (fMustAlloc || !*ppMemory)
2501 *ppMemory = NdrAllocate(pStubMsg, size);
2502 memset(*ppMemory, 0, size);
2506 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2508 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2511 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2514 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2516 if (pointer_buffer_mark_set)
2518 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2519 pStubMsg->PointerBufferMark = NULL;
2525 /***********************************************************************
2526 * NdrComplexStructBufferSize [RPCRT4.@]
2528 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2529 unsigned char *pMemory,
2530 PFORMAT_STRING pFormat)
2532 PFORMAT_STRING conf_array = NULL;
2533 PFORMAT_STRING pointer_desc = NULL;
2534 unsigned char *OldMemory = pStubMsg->Memory;
2535 int pointer_length_set = 0;
2537 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2539 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2541 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2543 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2544 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2546 /* get the buffer length after complex struct data, but before
2548 pStubMsg->IgnoreEmbeddedPointers = 1;
2549 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2550 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2552 /* save it for use by embedded pointer code later */
2553 pStubMsg->PointerLength = pStubMsg->BufferLength;
2554 pointer_length_set = 1;
2555 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
2557 /* restore the original buffer length */
2558 pStubMsg->BufferLength = saved_buffer_length;
2562 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2564 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2567 pStubMsg->Memory = pMemory;
2569 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2572 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2574 pStubMsg->Memory = OldMemory;
2576 if(pointer_length_set)
2578 pStubMsg->BufferLength = pStubMsg->PointerLength;
2579 pStubMsg->PointerLength = 0;
2584 /***********************************************************************
2585 * NdrComplexStructMemorySize [RPCRT4.@]
2587 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2588 PFORMAT_STRING pFormat)
2590 unsigned size = *(const WORD*)(pFormat+2);
2591 PFORMAT_STRING conf_array = NULL;
2592 PFORMAT_STRING pointer_desc = NULL;
2594 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2596 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2599 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2601 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2604 ComplexStructMemorySize(pStubMsg, pFormat);
2607 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2612 /***********************************************************************
2613 * NdrComplexStructFree [RPCRT4.@]
2615 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2616 unsigned char *pMemory,
2617 PFORMAT_STRING pFormat)
2619 PFORMAT_STRING conf_array = NULL;
2620 PFORMAT_STRING pointer_desc = NULL;
2621 unsigned char *OldMemory = pStubMsg->Memory;
2623 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2626 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2628 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2631 pStubMsg->Memory = pMemory;
2633 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2636 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2638 pStubMsg->Memory = OldMemory;
2641 /***********************************************************************
2642 * NdrConformantArrayMarshall [RPCRT4.@]
2644 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2645 unsigned char *pMemory,
2646 PFORMAT_STRING pFormat)
2648 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2649 unsigned char alignment = pFormat[1] + 1;
2651 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2652 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2654 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2656 WriteConformance(pStubMsg);
2658 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2660 size = safe_multiply(esize, pStubMsg->MaxCount);
2661 pStubMsg->BufferMark = pStubMsg->Buffer;
2662 safe_copy_to_buffer(pStubMsg, pMemory, size);
2664 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2669 /***********************************************************************
2670 * NdrConformantArrayUnmarshall [RPCRT4.@]
2672 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2673 unsigned char **ppMemory,
2674 PFORMAT_STRING pFormat,
2675 unsigned char fMustAlloc)
2677 DWORD size, esize = *(const WORD*)(pFormat+2);
2678 unsigned char alignment = pFormat[1] + 1;
2679 unsigned char *saved_buffer;
2681 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2682 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2684 pFormat = ReadConformance(pStubMsg, pFormat+4);
2686 size = safe_multiply(esize, pStubMsg->MaxCount);
2687 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2690 *ppMemory = NdrAllocate(pStubMsg, size);
2693 if (!pStubMsg->IsClient && !*ppMemory)
2694 /* for servers, we just point straight into the RPC buffer */
2695 *ppMemory = pStubMsg->Buffer;
2698 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
2699 safe_buffer_increment(pStubMsg, size);
2700 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2702 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2703 if (*ppMemory != saved_buffer)
2704 memcpy(*ppMemory, saved_buffer, size);
2709 /***********************************************************************
2710 * NdrConformantArrayBufferSize [RPCRT4.@]
2712 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2713 unsigned char *pMemory,
2714 PFORMAT_STRING pFormat)
2716 DWORD size, esize = *(const WORD*)(pFormat+2);
2717 unsigned char alignment = pFormat[1] + 1;
2719 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2720 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2722 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2724 SizeConformance(pStubMsg);
2726 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2728 size = safe_multiply(esize, pStubMsg->MaxCount);
2729 /* conformance value plus array */
2730 safe_buffer_length_increment(pStubMsg, size);
2732 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2735 /***********************************************************************
2736 * NdrConformantArrayMemorySize [RPCRT4.@]
2738 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2739 PFORMAT_STRING pFormat)
2741 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2742 unsigned char alignment = pFormat[1] + 1;
2744 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2745 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2747 pFormat = ReadConformance(pStubMsg, pFormat+4);
2748 size = safe_multiply(esize, pStubMsg->MaxCount);
2749 pStubMsg->MemorySize += size;
2751 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2752 pStubMsg->BufferMark = pStubMsg->Buffer;
2753 safe_buffer_increment(pStubMsg, size);
2755 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2757 return pStubMsg->MemorySize;
2760 /***********************************************************************
2761 * NdrConformantArrayFree [RPCRT4.@]
2763 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2764 unsigned char *pMemory,
2765 PFORMAT_STRING pFormat)
2767 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2768 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2770 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2772 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2776 /***********************************************************************
2777 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2779 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2780 unsigned char* pMemory,
2781 PFORMAT_STRING pFormat )
2784 unsigned char alignment = pFormat[1] + 1;
2785 DWORD esize = *(const WORD*)(pFormat+2);
2787 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2789 if (pFormat[0] != RPC_FC_CVARRAY)
2791 ERR("invalid format type %x\n", pFormat[0]);
2792 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2796 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2797 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2799 WriteConformance(pStubMsg);
2800 WriteVariance(pStubMsg);
2802 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2804 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2806 pStubMsg->BufferMark = pStubMsg->Buffer;
2807 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
2809 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2815 /***********************************************************************
2816 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2818 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2819 unsigned char** ppMemory,
2820 PFORMAT_STRING pFormat,
2821 unsigned char fMustAlloc )
2823 ULONG bufsize, memsize;
2824 unsigned char alignment = pFormat[1] + 1;
2825 DWORD esize = *(const WORD*)(pFormat+2);
2827 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2829 if (pFormat[0] != RPC_FC_CVARRAY)
2831 ERR("invalid format type %x\n", pFormat[0]);
2832 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2836 pFormat = ReadConformance(pStubMsg, pFormat+4);
2837 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2839 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2841 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2842 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2844 if (!*ppMemory || fMustAlloc)
2845 *ppMemory = NdrAllocate(pStubMsg, memsize);
2846 safe_copy_from_buffer(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize);
2848 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
2854 /***********************************************************************
2855 * NdrConformantVaryingArrayFree [RPCRT4.@]
2857 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2858 unsigned char* pMemory,
2859 PFORMAT_STRING pFormat )
2861 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2863 if (pFormat[0] != RPC_FC_CVARRAY)
2865 ERR("invalid format type %x\n", pFormat[0]);
2866 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2870 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2871 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2873 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2877 /***********************************************************************
2878 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2880 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2881 unsigned char* pMemory, PFORMAT_STRING pFormat )
2883 unsigned char alignment = pFormat[1] + 1;
2884 DWORD esize = *(const WORD*)(pFormat+2);
2886 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2888 if (pFormat[0] != RPC_FC_CVARRAY)
2890 ERR("invalid format type %x\n", pFormat[0]);
2891 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2896 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2897 /* compute length */
2898 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2900 SizeConformance(pStubMsg);
2901 SizeVariance(pStubMsg);
2903 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2905 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2907 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2911 /***********************************************************************
2912 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2914 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2915 PFORMAT_STRING pFormat )
2917 ULONG bufsize, memsize;
2918 unsigned char alignment = pFormat[1] + 1;
2919 DWORD esize = *(const WORD*)(pFormat+2);
2921 TRACE("(%p, %p)\n", pStubMsg, pFormat);
2923 if (pFormat[0] != RPC_FC_CVARRAY)
2925 ERR("invalid format type %x\n", pFormat[0]);
2926 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2927 return pStubMsg->MemorySize;
2930 pFormat = ReadConformance(pStubMsg, pFormat+4);
2931 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2933 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2935 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2936 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2938 safe_buffer_increment(pStubMsg, bufsize);
2939 pStubMsg->MemorySize += memsize;
2941 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2943 return pStubMsg->MemorySize;
2947 /***********************************************************************
2948 * NdrComplexArrayMarshall [RPCRT4.@]
2950 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2951 unsigned char *pMemory,
2952 PFORMAT_STRING pFormat)
2954 ULONG i, count, def;
2955 BOOL variance_present;
2956 unsigned char alignment;
2957 int pointer_buffer_mark_set = 0;
2959 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2961 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2963 ERR("invalid format type %x\n", pFormat[0]);
2964 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2968 alignment = pFormat[1] + 1;
2970 if (!pStubMsg->PointerBufferMark)
2972 /* save buffer fields that may be changed by buffer sizer functions
2973 * and that may be needed later on */
2974 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2975 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2976 unsigned long saved_max_count = pStubMsg->MaxCount;
2977 unsigned long saved_offset = pStubMsg->Offset;
2978 unsigned long saved_actual_count = pStubMsg->ActualCount;
2980 /* get the buffer pointer after complex array data, but before
2982 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2983 pStubMsg->IgnoreEmbeddedPointers = 1;
2984 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
2985 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2987 /* save it for use by embedded pointer code later */
2988 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2989 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
2990 pointer_buffer_mark_set = 1;
2992 /* restore fields */
2993 pStubMsg->ActualCount = saved_actual_count;
2994 pStubMsg->Offset = saved_offset;
2995 pStubMsg->MaxCount = saved_max_count;
2996 pStubMsg->BufferLength = saved_buffer_length;
2999 def = *(const WORD*)&pFormat[2];
3002 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3003 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3005 variance_present = IsConformanceOrVariancePresent(pFormat);
3006 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3007 TRACE("variance = %d\n", pStubMsg->ActualCount);
3009 WriteConformance(pStubMsg);
3010 if (variance_present)
3011 WriteVariance(pStubMsg);
3013 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3015 count = pStubMsg->ActualCount;
3016 for (i = 0; i < count; i++)
3017 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3019 STD_OVERFLOW_CHECK(pStubMsg);
3021 if (pointer_buffer_mark_set)
3023 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3024 pStubMsg->PointerBufferMark = NULL;
3030 /***********************************************************************
3031 * NdrComplexArrayUnmarshall [RPCRT4.@]
3033 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3034 unsigned char **ppMemory,
3035 PFORMAT_STRING pFormat,
3036 unsigned char fMustAlloc)
3038 ULONG i, count, size;
3039 unsigned char alignment;
3040 unsigned char *pMemory;
3041 unsigned char *saved_buffer;
3042 int pointer_buffer_mark_set = 0;
3043 int saved_ignore_embedded;
3045 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3047 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3049 ERR("invalid format type %x\n", pFormat[0]);
3050 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3054 alignment = pFormat[1] + 1;
3056 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3057 /* save buffer pointer */
3058 saved_buffer = pStubMsg->Buffer;
3059 /* get the buffer pointer after complex array data, but before
3061 pStubMsg->IgnoreEmbeddedPointers = 1;
3062 pStubMsg->MemorySize = 0;
3063 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3064 size = pStubMsg->MemorySize;
3065 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3067 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
3068 if (!pStubMsg->PointerBufferMark)
3070 /* save it for use by embedded pointer code later */
3071 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3072 pointer_buffer_mark_set = 1;
3074 /* restore the original buffer */
3075 pStubMsg->Buffer = saved_buffer;
3079 pFormat = ReadConformance(pStubMsg, pFormat);
3080 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3082 if (fMustAlloc || !*ppMemory)
3084 *ppMemory = NdrAllocate(pStubMsg, size);
3085 memset(*ppMemory, 0, size);
3088 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3090 pMemory = *ppMemory;
3091 count = pStubMsg->ActualCount;
3092 for (i = 0; i < count; i++)
3093 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
3095 if (pointer_buffer_mark_set)
3097 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3098 pStubMsg->PointerBufferMark = NULL;
3104 /***********************************************************************
3105 * NdrComplexArrayBufferSize [RPCRT4.@]
3107 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3108 unsigned char *pMemory,
3109 PFORMAT_STRING pFormat)
3111 ULONG i, count, def;
3112 unsigned char alignment;
3113 BOOL variance_present;
3114 int pointer_length_set = 0;
3116 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3118 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3120 ERR("invalid format type %x\n", pFormat[0]);
3121 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3125 alignment = pFormat[1] + 1;
3127 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3129 /* save buffer fields that may be changed by buffer sizer functions
3130 * and that may be needed later on */
3131 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3132 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3133 unsigned long saved_max_count = pStubMsg->MaxCount;
3134 unsigned long saved_offset = pStubMsg->Offset;
3135 unsigned long saved_actual_count = pStubMsg->ActualCount;
3137 /* get the buffer pointer after complex array data, but before
3139 pStubMsg->IgnoreEmbeddedPointers = 1;
3140 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3141 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3143 /* save it for use by embedded pointer code later */
3144 pStubMsg->PointerLength = pStubMsg->BufferLength;
3145 pointer_length_set = 1;
3147 /* restore fields */
3148 pStubMsg->ActualCount = saved_actual_count;
3149 pStubMsg->Offset = saved_offset;
3150 pStubMsg->MaxCount = saved_max_count;
3151 pStubMsg->BufferLength = saved_buffer_length;
3153 def = *(const WORD*)&pFormat[2];
3156 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3157 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3158 SizeConformance(pStubMsg);
3160 variance_present = IsConformanceOrVariancePresent(pFormat);
3161 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3162 TRACE("variance = %d\n", pStubMsg->ActualCount);
3164 if (variance_present)
3165 SizeVariance(pStubMsg);
3167 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3169 count = pStubMsg->ActualCount;
3170 for (i = 0; i < count; i++)
3171 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
3173 if(pointer_length_set)
3175 pStubMsg->BufferLength = pStubMsg->PointerLength;
3176 pStubMsg->PointerLength = 0;
3180 /***********************************************************************
3181 * NdrComplexArrayMemorySize [RPCRT4.@]
3183 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3184 PFORMAT_STRING pFormat)
3186 ULONG i, count, esize, SavedMemorySize, MemorySize;
3187 unsigned char alignment;
3188 unsigned char *Buffer;
3190 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3192 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3194 ERR("invalid format type %x\n", pFormat[0]);
3195 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3199 alignment = pFormat[1] + 1;
3203 pFormat = ReadConformance(pStubMsg, pFormat);
3204 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3206 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3208 SavedMemorySize = pStubMsg->MemorySize;
3210 Buffer = pStubMsg->Buffer;
3211 pStubMsg->MemorySize = 0;
3212 esize = ComplexStructMemorySize(pStubMsg, pFormat);
3213 pStubMsg->Buffer = Buffer;
3215 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
3217 count = pStubMsg->ActualCount;
3218 for (i = 0; i < count; i++)
3219 ComplexStructMemorySize(pStubMsg, pFormat);
3221 pStubMsg->MemorySize = SavedMemorySize;
3223 pStubMsg->MemorySize += MemorySize;
3227 /***********************************************************************
3228 * NdrComplexArrayFree [RPCRT4.@]
3230 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3231 unsigned char *pMemory,
3232 PFORMAT_STRING pFormat)
3234 ULONG i, count, def;
3236 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3238 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3240 ERR("invalid format type %x\n", pFormat[0]);
3241 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3245 def = *(const WORD*)&pFormat[2];
3248 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3249 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3251 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3252 TRACE("variance = %d\n", pStubMsg->ActualCount);
3254 count = pStubMsg->ActualCount;
3255 for (i = 0; i < count; i++)
3256 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
3259 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
3260 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
3261 USER_MARSHAL_CB *umcb)
3263 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
3264 pStubMsg->RpcMsg->DataRepresentation);
3265 umcb->pStubMsg = pStubMsg;
3266 umcb->pReserve = NULL;
3267 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
3268 umcb->CBType = cbtype;
3269 umcb->pFormat = pFormat;
3270 umcb->pTypeFormat = NULL /* FIXME */;
3273 #define USER_MARSHAL_PTR_PREFIX \
3274 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3275 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3277 /***********************************************************************
3278 * NdrUserMarshalMarshall [RPCRT4.@]
3280 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3281 unsigned char *pMemory,
3282 PFORMAT_STRING pFormat)
3284 unsigned flags = pFormat[1];
3285 unsigned index = *(const WORD*)&pFormat[2];
3286 unsigned char *saved_buffer = NULL;
3287 USER_MARSHAL_CB umcb;
3289 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3290 TRACE("index=%d\n", index);
3292 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
3294 if (flags & USER_MARSHAL_POINTER)
3296 ALIGN_POINTER(pStubMsg->Buffer, 4);
3297 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
3298 pStubMsg->Buffer += 4;
3299 if (pStubMsg->PointerBufferMark)
3301 saved_buffer = pStubMsg->Buffer;
3302 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3303 pStubMsg->PointerBufferMark = NULL;
3305 ALIGN_POINTER(pStubMsg->Buffer, 8);
3308 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3311 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
3312 &umcb.Flags, pStubMsg->Buffer, pMemory);
3316 STD_OVERFLOW_CHECK(pStubMsg);
3317 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3318 pStubMsg->Buffer = saved_buffer;
3321 STD_OVERFLOW_CHECK(pStubMsg);
3326 /***********************************************************************
3327 * NdrUserMarshalUnmarshall [RPCRT4.@]
3329 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3330 unsigned char **ppMemory,
3331 PFORMAT_STRING pFormat,
3332 unsigned char fMustAlloc)
3334 unsigned flags = pFormat[1];
3335 unsigned index = *(const WORD*)&pFormat[2];
3336 DWORD memsize = *(const WORD*)&pFormat[4];
3337 unsigned char *saved_buffer = NULL;
3338 USER_MARSHAL_CB umcb;
3340 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3341 TRACE("index=%d\n", index);
3343 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
3345 if (flags & USER_MARSHAL_POINTER)
3347 ALIGN_POINTER(pStubMsg->Buffer, 4);
3348 /* skip pointer prefix */
3349 pStubMsg->Buffer += 4;
3350 if (pStubMsg->PointerBufferMark)
3352 saved_buffer = pStubMsg->Buffer;
3353 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3354 pStubMsg->PointerBufferMark = NULL;
3356 ALIGN_POINTER(pStubMsg->Buffer, 8);
3359 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3361 if (fMustAlloc || !*ppMemory)
3362 *ppMemory = NdrAllocate(pStubMsg, memsize);
3365 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
3366 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
3370 STD_OVERFLOW_CHECK(pStubMsg);
3371 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3372 pStubMsg->Buffer = saved_buffer;
3378 /***********************************************************************
3379 * NdrUserMarshalBufferSize [RPCRT4.@]
3381 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3382 unsigned char *pMemory,
3383 PFORMAT_STRING pFormat)
3385 unsigned flags = pFormat[1];
3386 unsigned index = *(const WORD*)&pFormat[2];
3387 DWORD bufsize = *(const WORD*)&pFormat[6];
3388 USER_MARSHAL_CB umcb;
3389 unsigned long saved_buffer_length = 0;
3391 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3392 TRACE("index=%d\n", index);
3394 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
3396 if (flags & USER_MARSHAL_POINTER)
3398 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3399 /* skip pointer prefix */
3400 safe_buffer_length_increment(pStubMsg, 4);
3401 if (pStubMsg->IgnoreEmbeddedPointers)
3403 if (pStubMsg->PointerLength)
3405 saved_buffer_length = pStubMsg->BufferLength;
3406 pStubMsg->BufferLength = pStubMsg->PointerLength;
3407 pStubMsg->PointerLength = 0;
3409 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
3412 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
3415 TRACE("size=%d\n", bufsize);
3416 safe_buffer_length_increment(pStubMsg, bufsize);
3419 pStubMsg->BufferLength =
3420 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
3421 &umcb.Flags, pStubMsg->BufferLength, pMemory);
3423 if (saved_buffer_length)
3425 pStubMsg->PointerLength = pStubMsg->BufferLength;
3426 pStubMsg->BufferLength = saved_buffer_length;
3431 /***********************************************************************
3432 * NdrUserMarshalMemorySize [RPCRT4.@]
3434 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3435 PFORMAT_STRING pFormat)
3437 unsigned flags = pFormat[1];
3438 unsigned index = *(const WORD*)&pFormat[2];
3439 DWORD memsize = *(const WORD*)&pFormat[4];
3440 DWORD bufsize = *(const WORD*)&pFormat[6];
3442 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3443 TRACE("index=%d\n", index);
3445 pStubMsg->MemorySize += memsize;
3447 if (flags & USER_MARSHAL_POINTER)
3449 ALIGN_POINTER(pStubMsg->Buffer, 4);
3450 /* skip pointer prefix */
3451 pStubMsg->Buffer += 4;
3452 if (pStubMsg->IgnoreEmbeddedPointers)
3453 return pStubMsg->MemorySize;
3454 ALIGN_POINTER(pStubMsg->Buffer, 8);
3457 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3460 FIXME("not implemented for varying buffer size\n");
3462 pStubMsg->Buffer += bufsize;
3464 return pStubMsg->MemorySize;
3467 /***********************************************************************
3468 * NdrUserMarshalFree [RPCRT4.@]
3470 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
3471 unsigned char *pMemory,
3472 PFORMAT_STRING pFormat)
3474 /* unsigned flags = pFormat[1]; */
3475 unsigned index = *(const WORD*)&pFormat[2];
3476 USER_MARSHAL_CB umcb;
3478 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3479 TRACE("index=%d\n", index);
3481 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
3483 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
3484 &umcb.Flags, pMemory);
3487 /***********************************************************************
3488 * NdrClearOutParameters [RPCRT4.@]
3490 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
3491 PFORMAT_STRING pFormat,
3494 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
3497 /***********************************************************************
3498 * NdrConvert [RPCRT4.@]
3500 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
3502 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
3503 /* FIXME: since this stub doesn't do any converting, the proper behavior
3504 is to raise an exception */
3507 /***********************************************************************
3508 * NdrConvert2 [RPCRT4.@]
3510 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
3512 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3513 pStubMsg, pFormat, NumberParams);
3514 /* FIXME: since this stub doesn't do any converting, the proper behavior
3515 is to raise an exception */
3518 #include "pshpack1.h"
3519 typedef struct _NDR_CSTRUCT_FORMAT
3522 unsigned char alignment;
3523 unsigned short memory_size;
3524 short offset_to_array_description;
3525 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
3526 #include "poppack.h"
3528 /***********************************************************************
3529 * NdrConformantStructMarshall [RPCRT4.@]
3531 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3532 unsigned char *pMemory,
3533 PFORMAT_STRING pFormat)
3535 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3536 PFORMAT_STRING pCArrayFormat;
3537 ULONG esize, bufsize;
3539 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3541 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3542 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3544 ERR("invalid format type %x\n", pCStructFormat->type);
3545 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3549 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3550 pCStructFormat->offset_to_array_description;
3551 if (*pCArrayFormat != RPC_FC_CARRAY)
3553 ERR("invalid array format type %x\n", pCStructFormat->type);
3554 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3557 esize = *(const WORD*)(pCArrayFormat+2);
3559 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3560 pCArrayFormat + 4, 0);
3562 WriteConformance(pStubMsg);
3564 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3566 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3568 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3569 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3571 ERR("integer overflow of memory_size %u with bufsize %u\n",
3572 pCStructFormat->memory_size, bufsize);
3573 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3575 /* copy constant sized part of struct */
3576 pStubMsg->BufferMark = pStubMsg->Buffer;
3577 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
3579 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3580 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3585 /***********************************************************************
3586 * NdrConformantStructUnmarshall [RPCRT4.@]
3588 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3589 unsigned char **ppMemory,
3590 PFORMAT_STRING pFormat,
3591 unsigned char fMustAlloc)
3593 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3594 PFORMAT_STRING pCArrayFormat;
3595 ULONG esize, bufsize;
3596 unsigned char *saved_buffer;
3598 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3600 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3601 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3603 ERR("invalid format type %x\n", pCStructFormat->type);
3604 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3607 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3608 pCStructFormat->offset_to_array_description;
3609 if (*pCArrayFormat != RPC_FC_CARRAY)
3611 ERR("invalid array format type %x\n", pCStructFormat->type);
3612 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3615 esize = *(const WORD*)(pCArrayFormat+2);
3617 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3619 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3621 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3623 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3624 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3626 ERR("integer overflow of memory_size %u with bufsize %u\n",
3627 pCStructFormat->memory_size, bufsize);
3628 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3633 SIZE_T size = pCStructFormat->memory_size + bufsize;
3634 *ppMemory = NdrAllocate(pStubMsg, size);
3638 if (!pStubMsg->IsClient && !*ppMemory)
3639 /* for servers, we just point straight into the RPC buffer */
3640 *ppMemory = pStubMsg->Buffer;
3643 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3644 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
3645 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3646 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3648 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
3649 if (*ppMemory != saved_buffer)
3650 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
3655 /***********************************************************************
3656 * NdrConformantStructBufferSize [RPCRT4.@]
3658 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3659 unsigned char *pMemory,
3660 PFORMAT_STRING pFormat)
3662 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3663 PFORMAT_STRING pCArrayFormat;
3666 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3668 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3669 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3671 ERR("invalid format type %x\n", pCStructFormat->type);
3672 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3675 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3676 pCStructFormat->offset_to_array_description;
3677 if (*pCArrayFormat != RPC_FC_CARRAY)
3679 ERR("invalid array format type %x\n", pCStructFormat->type);
3680 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3683 esize = *(const WORD*)(pCArrayFormat+2);
3685 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
3686 SizeConformance(pStubMsg);
3688 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
3690 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3692 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
3693 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
3695 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3696 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3699 /***********************************************************************
3700 * NdrConformantStructMemorySize [RPCRT4.@]
3702 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3703 PFORMAT_STRING pFormat)
3709 /***********************************************************************
3710 * NdrConformantStructFree [RPCRT4.@]
3712 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3713 unsigned char *pMemory,
3714 PFORMAT_STRING pFormat)
3716 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3717 PFORMAT_STRING pCArrayFormat;
3720 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3722 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3723 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3725 ERR("invalid format type %x\n", pCStructFormat->type);
3726 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3730 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3731 pCStructFormat->offset_to_array_description;
3732 if (*pCArrayFormat != RPC_FC_CARRAY)
3734 ERR("invalid array format type %x\n", pCStructFormat->type);
3735 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3738 esize = *(const WORD*)(pCArrayFormat+2);
3740 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3741 pCArrayFormat + 4, 0);
3743 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3745 /* copy constant sized part of struct */
3746 pStubMsg->BufferMark = pStubMsg->Buffer;
3748 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3749 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3752 /***********************************************************************
3753 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3755 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3756 unsigned char *pMemory,
3757 PFORMAT_STRING pFormat)
3759 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3760 PFORMAT_STRING pCVArrayFormat;
3761 ULONG esize, bufsize;
3763 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3765 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3766 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3768 ERR("invalid format type %x\n", pCVStructFormat->type);
3769 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3773 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3774 pCVStructFormat->offset_to_array_description;
3775 switch (*pCVArrayFormat)
3777 case RPC_FC_CVARRAY:
3778 esize = *(const WORD*)(pCVArrayFormat+2);
3780 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3781 pCVArrayFormat + 4, 0);
3782 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3785 case RPC_FC_C_CSTRING:
3786 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3787 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3788 esize = sizeof(char);
3789 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3790 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3791 pCVArrayFormat + 2, 0);
3793 pStubMsg->MaxCount = pStubMsg->ActualCount;
3795 case RPC_FC_C_WSTRING:
3796 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3797 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3798 esize = sizeof(WCHAR);
3799 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3800 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3801 pCVArrayFormat + 2, 0);
3803 pStubMsg->MaxCount = pStubMsg->ActualCount;
3806 ERR("invalid array format type %x\n", *pCVArrayFormat);
3807 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3811 WriteConformance(pStubMsg);
3813 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3815 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3817 /* write constant sized part */
3818 pStubMsg->BufferMark = pStubMsg->Buffer;
3819 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
3821 WriteVariance(pStubMsg);
3823 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3825 /* write array part */
3826 safe_copy_to_buffer(pStubMsg, pMemory + pCVStructFormat->memory_size, bufsize);
3828 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3833 /***********************************************************************
3834 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3836 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3837 unsigned char **ppMemory,
3838 PFORMAT_STRING pFormat,
3839 unsigned char fMustAlloc)
3841 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3842 PFORMAT_STRING pCVArrayFormat;
3843 ULONG esize, bufsize;
3844 unsigned char cvarray_type;
3846 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3848 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3849 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3851 ERR("invalid format type %x\n", pCVStructFormat->type);
3852 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3856 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3857 pCVStructFormat->offset_to_array_description;
3858 cvarray_type = *pCVArrayFormat;
3859 switch (cvarray_type)
3861 case RPC_FC_CVARRAY:
3862 esize = *(const WORD*)(pCVArrayFormat+2);
3863 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3865 case RPC_FC_C_CSTRING:
3866 esize = sizeof(char);
3867 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3868 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3870 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3872 case RPC_FC_C_WSTRING:
3873 esize = sizeof(WCHAR);
3874 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3875 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3877 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3880 ERR("invalid array format type %x\n", *pCVArrayFormat);
3881 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3885 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3887 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3889 /* work out how much memory to allocate if we need to do so */
3890 if (!*ppMemory || fMustAlloc)
3892 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3893 *ppMemory = NdrAllocate(pStubMsg, size);
3896 /* copy the constant data */
3897 pStubMsg->BufferMark = pStubMsg->Buffer;
3898 safe_copy_from_buffer(pStubMsg, *ppMemory, pCVStructFormat->memory_size);
3900 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3902 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3904 if ((cvarray_type == RPC_FC_C_CSTRING) ||
3905 (cvarray_type == RPC_FC_C_WSTRING))
3908 /* strings must always have null terminating bytes */
3909 if (bufsize < esize)
3911 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
3912 RpcRaiseException(RPC_S_INVALID_BOUND);
3915 for (i = bufsize - esize; i < bufsize; i++)
3916 if (pStubMsg->Buffer[i] != 0)
3918 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3919 i, pStubMsg->Buffer[i]);
3920 RpcRaiseException(RPC_S_INVALID_BOUND);
3925 /* copy the array data */
3926 safe_copy_from_buffer(pStubMsg, *ppMemory + pCVStructFormat->memory_size, bufsize);
3928 if (cvarray_type == RPC_FC_C_CSTRING)
3929 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3930 else if (cvarray_type == RPC_FC_C_WSTRING)
3931 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3933 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
3938 /***********************************************************************
3939 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3941 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3942 unsigned char *pMemory,
3943 PFORMAT_STRING pFormat)
3945 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3946 PFORMAT_STRING pCVArrayFormat;
3949 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3951 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3952 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3954 ERR("invalid format type %x\n", pCVStructFormat->type);
3955 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3959 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3960 pCVStructFormat->offset_to_array_description;
3961 switch (*pCVArrayFormat)
3963 case RPC_FC_CVARRAY:
3964 esize = *(const WORD*)(pCVArrayFormat+2);
3966 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3967 pCVArrayFormat + 4, 0);
3968 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3971 case RPC_FC_C_CSTRING:
3972 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3973 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3974 esize = sizeof(char);
3975 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3976 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3977 pCVArrayFormat + 2, 0);
3979 pStubMsg->MaxCount = pStubMsg->ActualCount;
3981 case RPC_FC_C_WSTRING:
3982 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3983 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3984 esize = sizeof(WCHAR);
3985 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3986 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3987 pCVArrayFormat + 2, 0);
3989 pStubMsg->MaxCount = pStubMsg->ActualCount;
3992 ERR("invalid array format type %x\n", *pCVArrayFormat);
3993 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3997 SizeConformance(pStubMsg);
3999 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4001 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4003 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4004 SizeVariance(pStubMsg);
4005 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4007 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4010 /***********************************************************************
4011 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4013 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4014 PFORMAT_STRING pFormat)
4016 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4017 PFORMAT_STRING pCVArrayFormat;
4019 unsigned char cvarray_type;
4021 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4023 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4024 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4026 ERR("invalid format type %x\n", pCVStructFormat->type);
4027 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4031 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4032 pCVStructFormat->offset_to_array_description;
4033 cvarray_type = *pCVArrayFormat;
4034 switch (cvarray_type)
4036 case RPC_FC_CVARRAY:
4037 esize = *(const WORD*)(pCVArrayFormat+2);
4038 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4040 case RPC_FC_C_CSTRING:
4041 esize = sizeof(char);
4042 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4043 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4045 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4047 case RPC_FC_C_WSTRING:
4048 esize = sizeof(WCHAR);
4049 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4050 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4052 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4055 ERR("invalid array format type %x\n", *pCVArrayFormat);
4056 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4060 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4062 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4064 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4065 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4066 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4068 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4070 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4072 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
4075 /***********************************************************************
4076 * NdrConformantVaryingStructFree [RPCRT4.@]
4078 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4079 unsigned char *pMemory,
4080 PFORMAT_STRING pFormat)
4082 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4083 PFORMAT_STRING pCVArrayFormat;
4086 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4088 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4089 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4091 ERR("invalid format type %x\n", pCVStructFormat->type);
4092 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4096 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4097 pCVStructFormat->offset_to_array_description;
4098 switch (*pCVArrayFormat)
4100 case RPC_FC_CVARRAY:
4101 esize = *(const WORD*)(pCVArrayFormat+2);
4103 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4104 pCVArrayFormat + 4, 0);
4105 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4108 case RPC_FC_C_CSTRING:
4109 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4110 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4111 esize = sizeof(char);
4112 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4113 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4114 pCVArrayFormat + 2, 0);
4116 pStubMsg->MaxCount = pStubMsg->ActualCount;
4118 case RPC_FC_C_WSTRING:
4119 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4120 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4121 esize = sizeof(WCHAR);
4122 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4123 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4124 pCVArrayFormat + 2, 0);
4126 pStubMsg->MaxCount = pStubMsg->ActualCount;
4129 ERR("invalid array format type %x\n", *pCVArrayFormat);
4130 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4134 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4136 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4139 #include "pshpack1.h"
4143 unsigned char alignment;
4144 unsigned short total_size;
4145 } NDR_SMFARRAY_FORMAT;
4150 unsigned char alignment;
4151 unsigned long total_size;
4152 } NDR_LGFARRAY_FORMAT;
4153 #include "poppack.h"
4155 /***********************************************************************
4156 * NdrFixedArrayMarshall [RPCRT4.@]
4158 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4159 unsigned char *pMemory,
4160 PFORMAT_STRING pFormat)
4162 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4163 unsigned long total_size;
4165 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4167 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4168 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4170 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4171 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4175 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4177 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4179 total_size = pSmFArrayFormat->total_size;
4180 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4184 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4185 total_size = pLgFArrayFormat->total_size;
4186 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4189 pStubMsg->BufferMark = pStubMsg->Buffer;
4190 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4192 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4197 /***********************************************************************
4198 * NdrFixedArrayUnmarshall [RPCRT4.@]
4200 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4201 unsigned char **ppMemory,
4202 PFORMAT_STRING pFormat,
4203 unsigned char fMustAlloc)
4205 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4206 unsigned long total_size;
4207 unsigned char *saved_buffer;
4209 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4211 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4212 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4214 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4215 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4219 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4221 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4223 total_size = pSmFArrayFormat->total_size;
4224 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4228 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4229 total_size = pLgFArrayFormat->total_size;
4230 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4234 *ppMemory = NdrAllocate(pStubMsg, total_size);
4237 if (!pStubMsg->IsClient && !*ppMemory)
4238 /* for servers, we just point straight into the RPC buffer */
4239 *ppMemory = pStubMsg->Buffer;
4242 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4243 safe_buffer_increment(pStubMsg, total_size);
4244 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4246 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4247 if (*ppMemory != saved_buffer)
4248 memcpy(*ppMemory, saved_buffer, total_size);
4253 /***********************************************************************
4254 * NdrFixedArrayBufferSize [RPCRT4.@]
4256 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4257 unsigned char *pMemory,
4258 PFORMAT_STRING pFormat)
4260 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4261 unsigned long total_size;
4263 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4265 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4266 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4268 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4269 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4273 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4275 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4277 total_size = pSmFArrayFormat->total_size;
4278 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4282 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4283 total_size = pLgFArrayFormat->total_size;
4284 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4286 safe_buffer_length_increment(pStubMsg, total_size);
4288 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4291 /***********************************************************************
4292 * NdrFixedArrayMemorySize [RPCRT4.@]
4294 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4295 PFORMAT_STRING pFormat)
4297 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4300 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4302 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4303 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4305 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4306 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4310 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4312 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4314 total_size = pSmFArrayFormat->total_size;
4315 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4319 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4320 total_size = pLgFArrayFormat->total_size;
4321 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4323 pStubMsg->BufferMark = pStubMsg->Buffer;
4324 safe_buffer_increment(pStubMsg, total_size);
4325 pStubMsg->MemorySize += total_size;
4327 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4332 /***********************************************************************
4333 * NdrFixedArrayFree [RPCRT4.@]
4335 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4336 unsigned char *pMemory,
4337 PFORMAT_STRING pFormat)
4339 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4341 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4343 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4344 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4346 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4347 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4351 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4352 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4355 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4356 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4359 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4362 /***********************************************************************
4363 * NdrVaryingArrayMarshall [RPCRT4.@]
4365 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4366 unsigned char *pMemory,
4367 PFORMAT_STRING pFormat)
4369 unsigned char alignment;
4370 DWORD elements, esize;
4373 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4375 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4376 (pFormat[0] != RPC_FC_LGVARRAY))
4378 ERR("invalid format type %x\n", pFormat[0]);
4379 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4383 alignment = pFormat[1] + 1;
4385 if (pFormat[0] == RPC_FC_SMVARRAY)
4388 pFormat += sizeof(WORD);
4389 elements = *(const WORD*)pFormat;
4390 pFormat += sizeof(WORD);
4395 pFormat += sizeof(DWORD);
4396 elements = *(const DWORD*)pFormat;
4397 pFormat += sizeof(DWORD);
4400 esize = *(const WORD*)pFormat;
4401 pFormat += sizeof(WORD);
4403 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4404 if ((pStubMsg->ActualCount > elements) ||
4405 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4407 RpcRaiseException(RPC_S_INVALID_BOUND);
4411 WriteVariance(pStubMsg);
4413 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4415 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4416 pStubMsg->BufferMark = pStubMsg->Buffer;
4417 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
4419 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4424 /***********************************************************************
4425 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4427 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4428 unsigned char **ppMemory,
4429 PFORMAT_STRING pFormat,
4430 unsigned char fMustAlloc)
4432 unsigned char alignment;
4433 DWORD size, elements, esize;
4436 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4438 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4439 (pFormat[0] != RPC_FC_LGVARRAY))
4441 ERR("invalid format type %x\n", pFormat[0]);
4442 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4446 alignment = pFormat[1] + 1;
4448 if (pFormat[0] == RPC_FC_SMVARRAY)
4451 size = *(const WORD*)pFormat;
4452 pFormat += sizeof(WORD);
4453 elements = *(const WORD*)pFormat;
4454 pFormat += sizeof(WORD);
4459 size = *(const DWORD*)pFormat;
4460 pFormat += sizeof(DWORD);
4461 elements = *(const DWORD*)pFormat;
4462 pFormat += sizeof(DWORD);
4465 esize = *(const WORD*)pFormat;
4466 pFormat += sizeof(WORD);
4468 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4470 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4472 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4474 if (!*ppMemory || fMustAlloc)
4475 *ppMemory = NdrAllocate(pStubMsg, size);
4476 safe_copy_from_buffer(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize);
4478 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
4483 /***********************************************************************
4484 * NdrVaryingArrayBufferSize [RPCRT4.@]
4486 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4487 unsigned char *pMemory,
4488 PFORMAT_STRING pFormat)
4490 unsigned char alignment;
4491 DWORD elements, esize;
4493 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4495 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4496 (pFormat[0] != RPC_FC_LGVARRAY))
4498 ERR("invalid format type %x\n", pFormat[0]);
4499 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4503 alignment = pFormat[1] + 1;
4505 if (pFormat[0] == RPC_FC_SMVARRAY)
4508 pFormat += sizeof(WORD);
4509 elements = *(const WORD*)pFormat;
4510 pFormat += sizeof(WORD);
4515 pFormat += sizeof(DWORD);
4516 elements = *(const DWORD*)pFormat;
4517 pFormat += sizeof(DWORD);
4520 esize = *(const WORD*)pFormat;
4521 pFormat += sizeof(WORD);
4523 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4524 if ((pStubMsg->ActualCount > elements) ||
4525 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4527 RpcRaiseException(RPC_S_INVALID_BOUND);
4531 SizeVariance(pStubMsg);
4533 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4535 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4537 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4540 /***********************************************************************
4541 * NdrVaryingArrayMemorySize [RPCRT4.@]
4543 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4544 PFORMAT_STRING pFormat)
4546 unsigned char alignment;
4547 DWORD size, elements, esize;
4549 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4551 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4552 (pFormat[0] != RPC_FC_LGVARRAY))
4554 ERR("invalid format type %x\n", pFormat[0]);
4555 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4559 alignment = pFormat[1] + 1;
4561 if (pFormat[0] == RPC_FC_SMVARRAY)
4564 size = *(const WORD*)pFormat;
4565 pFormat += sizeof(WORD);
4566 elements = *(const WORD*)pFormat;
4567 pFormat += sizeof(WORD);
4572 size = *(const DWORD*)pFormat;
4573 pFormat += sizeof(DWORD);
4574 elements = *(const DWORD*)pFormat;
4575 pFormat += sizeof(DWORD);
4578 esize = *(const WORD*)pFormat;
4579 pFormat += sizeof(WORD);
4581 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4583 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4585 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4586 pStubMsg->MemorySize += size;
4588 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4590 return pStubMsg->MemorySize;
4593 /***********************************************************************
4594 * NdrVaryingArrayFree [RPCRT4.@]
4596 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4597 unsigned char *pMemory,
4598 PFORMAT_STRING pFormat)
4600 unsigned char alignment;
4603 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4605 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4606 (pFormat[0] != RPC_FC_LGVARRAY))
4608 ERR("invalid format type %x\n", pFormat[0]);
4609 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4613 alignment = pFormat[1] + 1;
4615 if (pFormat[0] == RPC_FC_SMVARRAY)
4618 pFormat += sizeof(WORD);
4619 elements = *(const WORD*)pFormat;
4620 pFormat += sizeof(WORD);
4625 pFormat += sizeof(DWORD);
4626 elements = *(const DWORD*)pFormat;
4627 pFormat += sizeof(DWORD);
4630 pFormat += sizeof(WORD);
4632 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4633 if ((pStubMsg->ActualCount > elements) ||
4634 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4636 RpcRaiseException(RPC_S_INVALID_BOUND);
4640 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4643 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
4651 return *(const UCHAR *)pMemory;
4656 return *(const USHORT *)pMemory;
4660 return *(const ULONG *)pMemory;
4662 FIXME("Unhandled base type: 0x%02x\n", fc);
4667 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4668 unsigned long discriminant,
4669 PFORMAT_STRING pFormat)
4671 unsigned short num_arms, arm, type;
4673 num_arms = *(const SHORT*)pFormat & 0x0fff;
4675 for(arm = 0; arm < num_arms; arm++)
4677 if(discriminant == *(const ULONG*)pFormat)
4685 type = *(const unsigned short*)pFormat;
4686 TRACE("type %04x\n", type);
4687 if(arm == num_arms) /* default arm extras */
4691 ERR("no arm for 0x%lx and no default case\n", discriminant);
4692 RpcRaiseException(RPC_S_INVALID_TAG);
4697 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
4704 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
4706 unsigned short type;
4710 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4714 type = *(const unsigned short*)pFormat;
4715 if((type & 0xff00) == 0x8000)
4717 unsigned char basetype = LOBYTE(type);
4718 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
4722 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4723 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
4726 unsigned char *saved_buffer = NULL;
4727 int pointer_buffer_mark_set = 0;
4734 ALIGN_POINTER(pStubMsg->Buffer, 4);
4735 saved_buffer = pStubMsg->Buffer;
4736 if (pStubMsg->PointerBufferMark)
4738 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4739 pStubMsg->PointerBufferMark = NULL;
4740 pointer_buffer_mark_set = 1;
4743 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
4745 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
4746 if (pointer_buffer_mark_set)
4748 STD_OVERFLOW_CHECK(pStubMsg);
4749 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4750 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
4752 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4753 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
4754 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4756 pStubMsg->Buffer = saved_buffer + 4;
4760 m(pStubMsg, pMemory, desc);
4763 else FIXME("no marshaller for embedded type %02x\n", *desc);
4768 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4769 unsigned char **ppMemory,
4771 PFORMAT_STRING pFormat,
4772 unsigned char fMustAlloc)
4774 unsigned short type;
4778 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4782 type = *(const unsigned short*)pFormat;
4783 if((type & 0xff00) == 0x8000)
4785 unsigned char basetype = LOBYTE(type);
4786 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
4790 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4791 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
4794 unsigned char *saved_buffer = NULL;
4795 int pointer_buffer_mark_set = 0;
4802 **(void***)ppMemory = NULL;
4803 ALIGN_POINTER(pStubMsg->Buffer, 4);
4804 saved_buffer = pStubMsg->Buffer;
4805 if (pStubMsg->PointerBufferMark)
4807 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4808 pStubMsg->PointerBufferMark = NULL;
4809 pointer_buffer_mark_set = 1;
4812 pStubMsg->Buffer += 4; /* for pointer ID */
4814 if (saved_buffer + 4 > pStubMsg->BufferEnd)
4816 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4817 saved_buffer, pStubMsg->BufferEnd);
4818 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4821 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
4822 if (pointer_buffer_mark_set)
4824 STD_OVERFLOW_CHECK(pStubMsg);
4825 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4826 pStubMsg->Buffer = saved_buffer + 4;
4830 m(pStubMsg, ppMemory, desc, fMustAlloc);
4833 else FIXME("no marshaller for embedded type %02x\n", *desc);
4838 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
4839 unsigned char *pMemory,
4841 PFORMAT_STRING pFormat)
4843 unsigned short type;
4847 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4851 type = *(const unsigned short*)pFormat;
4852 if((type & 0xff00) == 0x8000)
4854 unsigned char basetype = LOBYTE(type);
4855 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
4859 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4860 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
4869 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4870 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
4871 if (!pStubMsg->IgnoreEmbeddedPointers)
4873 int saved_buffer_length = pStubMsg->BufferLength;
4874 pStubMsg->BufferLength = pStubMsg->PointerLength;
4875 pStubMsg->PointerLength = 0;
4876 if(!pStubMsg->BufferLength)
4877 ERR("BufferLength == 0??\n");
4878 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
4879 pStubMsg->PointerLength = pStubMsg->BufferLength;
4880 pStubMsg->BufferLength = saved_buffer_length;
4884 m(pStubMsg, pMemory, desc);
4887 else FIXME("no buffersizer for embedded type %02x\n", *desc);
4891 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
4893 PFORMAT_STRING pFormat)
4895 unsigned short type, size;
4897 size = *(const unsigned short*)pFormat;
4898 pStubMsg->Memory += size;
4901 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4905 type = *(const unsigned short*)pFormat;
4906 if((type & 0xff00) == 0x8000)
4908 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
4912 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4913 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
4914 unsigned char *saved_buffer;
4923 ALIGN_POINTER(pStubMsg->Buffer, 4);
4924 saved_buffer = pStubMsg->Buffer;
4925 safe_buffer_increment(pStubMsg, 4);
4926 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
4927 pStubMsg->MemorySize += 4;
4928 if (!pStubMsg->IgnoreEmbeddedPointers)
4929 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
4932 return m(pStubMsg, desc);
4935 else FIXME("no marshaller for embedded type %02x\n", *desc);
4938 TRACE("size %d\n", size);
4942 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
4943 unsigned char *pMemory,
4945 PFORMAT_STRING pFormat)
4947 unsigned short type;
4951 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4955 type = *(const unsigned short*)pFormat;
4956 if((type & 0xff00) != 0x8000)
4958 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4959 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
4968 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
4971 m(pStubMsg, pMemory, desc);
4974 else FIXME("no freer for embedded type %02x\n", *desc);
4978 /***********************************************************************
4979 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4981 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4982 unsigned char *pMemory,
4983 PFORMAT_STRING pFormat)
4985 unsigned char switch_type;
4986 unsigned char increment;
4989 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4992 switch_type = *pFormat & 0xf;
4993 increment = (*pFormat & 0xf0) >> 4;
4996 ALIGN_POINTER(pStubMsg->Buffer, increment);
4998 switch_value = get_discriminant(switch_type, pMemory);
4999 TRACE("got switch value 0x%x\n", switch_value);
5001 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5002 pMemory += increment;
5004 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5007 /***********************************************************************
5008 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5010 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5011 unsigned char **ppMemory,
5012 PFORMAT_STRING pFormat,
5013 unsigned char fMustAlloc)
5015 unsigned char switch_type;
5016 unsigned char increment;
5018 unsigned short size;
5019 unsigned char *pMemoryArm;
5021 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5024 switch_type = *pFormat & 0xf;
5025 increment = (*pFormat & 0xf0) >> 4;
5028 ALIGN_POINTER(pStubMsg->Buffer, increment);
5029 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5030 TRACE("got switch value 0x%x\n", switch_value);
5032 size = *(const unsigned short*)pFormat + increment;
5033 if(!*ppMemory || fMustAlloc)
5034 *ppMemory = NdrAllocate(pStubMsg, size);
5036 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5037 pMemoryArm = *ppMemory + increment;
5039 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
5042 /***********************************************************************
5043 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5045 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5046 unsigned char *pMemory,
5047 PFORMAT_STRING pFormat)
5049 unsigned char switch_type;
5050 unsigned char increment;
5053 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5056 switch_type = *pFormat & 0xf;
5057 increment = (*pFormat & 0xf0) >> 4;
5060 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5061 switch_value = get_discriminant(switch_type, pMemory);
5062 TRACE("got switch value 0x%x\n", switch_value);
5064 /* Add discriminant size */
5065 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5066 pMemory += increment;
5068 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5071 /***********************************************************************
5072 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5074 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5075 PFORMAT_STRING pFormat)
5077 unsigned char switch_type;
5078 unsigned char increment;
5081 switch_type = *pFormat & 0xf;
5082 increment = (*pFormat & 0xf0) >> 4;
5085 ALIGN_POINTER(pStubMsg->Buffer, increment);
5086 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5087 TRACE("got switch value 0x%x\n", switch_value);
5089 pStubMsg->Memory += increment;
5091 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5094 /***********************************************************************
5095 * NdrEncapsulatedUnionFree [RPCRT4.@]
5097 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5098 unsigned char *pMemory,
5099 PFORMAT_STRING pFormat)
5101 unsigned char switch_type;
5102 unsigned char increment;
5105 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5108 switch_type = *pFormat & 0xf;
5109 increment = (*pFormat & 0xf0) >> 4;
5112 switch_value = get_discriminant(switch_type, pMemory);
5113 TRACE("got switch value 0x%x\n", switch_value);
5115 pMemory += increment;
5117 return union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5120 /***********************************************************************
5121 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5123 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5124 unsigned char *pMemory,
5125 PFORMAT_STRING pFormat)
5127 unsigned char switch_type;
5129 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5132 switch_type = *pFormat;
5135 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5136 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5137 /* Marshall discriminant */
5138 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5140 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5143 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5144 PFORMAT_STRING *ppFormat)
5146 long discriminant = 0;
5156 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5165 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5166 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5174 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5175 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5180 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5184 if (pStubMsg->fHasNewCorrDesc)
5188 return discriminant;
5191 /**********************************************************************
5192 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5194 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5195 unsigned char **ppMemory,
5196 PFORMAT_STRING pFormat,
5197 unsigned char fMustAlloc)
5200 unsigned short size;
5202 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5205 /* Unmarshall discriminant */
5206 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5207 TRACE("unmarshalled discriminant %lx\n", discriminant);
5209 pFormat += *(const SHORT*)pFormat;
5211 size = *(const unsigned short*)pFormat;
5213 if(!*ppMemory || fMustAlloc)
5214 *ppMemory = NdrAllocate(pStubMsg, size);
5216 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5219 /***********************************************************************
5220 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5222 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5223 unsigned char *pMemory,
5224 PFORMAT_STRING pFormat)
5226 unsigned char switch_type;
5228 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5231 switch_type = *pFormat;
5234 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5235 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5236 /* Add discriminant size */
5237 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5239 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5242 /***********************************************************************
5243 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5245 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5246 PFORMAT_STRING pFormat)
5251 /* Unmarshall discriminant */
5252 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5253 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
5255 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
5258 /***********************************************************************
5259 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5261 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5262 unsigned char *pMemory,
5263 PFORMAT_STRING pFormat)
5265 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5269 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5270 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5272 return union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5275 /***********************************************************************
5276 * NdrByteCountPointerMarshall [RPCRT4.@]
5278 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5279 unsigned char *pMemory,
5280 PFORMAT_STRING pFormat)
5286 /***********************************************************************
5287 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5289 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5290 unsigned char **ppMemory,
5291 PFORMAT_STRING pFormat,
5292 unsigned char fMustAlloc)
5298 /***********************************************************************
5299 * NdrByteCountPointerBufferSize [RPCRT4.@]
5301 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5302 unsigned char *pMemory,
5303 PFORMAT_STRING pFormat)
5308 /***********************************************************************
5309 * NdrByteCountPointerMemorySize [RPCRT4.@]
5311 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5312 PFORMAT_STRING pFormat)
5318 /***********************************************************************
5319 * NdrByteCountPointerFree [RPCRT4.@]
5321 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
5322 unsigned char *pMemory,
5323 PFORMAT_STRING pFormat)
5328 /***********************************************************************
5329 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5331 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5332 unsigned char *pMemory,
5333 PFORMAT_STRING pFormat)
5339 /***********************************************************************
5340 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5342 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5343 unsigned char **ppMemory,
5344 PFORMAT_STRING pFormat,
5345 unsigned char fMustAlloc)
5351 /***********************************************************************
5352 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5354 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5355 unsigned char *pMemory,
5356 PFORMAT_STRING pFormat)
5361 /***********************************************************************
5362 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5364 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5365 PFORMAT_STRING pFormat)
5371 /***********************************************************************
5372 * NdrXmitOrRepAsFree [RPCRT4.@]
5374 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
5375 unsigned char *pMemory,
5376 PFORMAT_STRING pFormat)
5381 #include "pshpack1.h"
5385 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
5389 #include "poppack.h"
5391 /***********************************************************************
5392 * NdrRangeMarshall [internal]
5394 unsigned char *WINAPI NdrRangeMarshall(
5395 PMIDL_STUB_MESSAGE pStubMsg,
5396 unsigned char *pMemory,
5397 PFORMAT_STRING pFormat)
5399 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5400 unsigned char base_type;
5402 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5404 if (pRange->type != RPC_FC_RANGE)
5406 ERR("invalid format type %x\n", pRange->type);
5407 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5411 base_type = pRange->flags_type & 0xf;
5413 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
5416 /***********************************************************************
5417 * NdrRangeUnmarshall
5419 unsigned char *WINAPI NdrRangeUnmarshall(
5420 PMIDL_STUB_MESSAGE pStubMsg,
5421 unsigned char **ppMemory,
5422 PFORMAT_STRING pFormat,
5423 unsigned char fMustAlloc)
5425 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5426 unsigned char base_type;
5428 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5430 if (pRange->type != RPC_FC_RANGE)
5432 ERR("invalid format type %x\n", pRange->type);
5433 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5436 base_type = pRange->flags_type & 0xf;
5438 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5439 base_type, pRange->low_value, pRange->high_value);
5441 #define RANGE_UNMARSHALL(type, format_spec) \
5444 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5445 if (fMustAlloc || !*ppMemory) \
5446 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5447 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5449 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5450 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5451 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5453 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5454 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5456 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5457 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5458 (type)pRange->high_value); \
5459 RpcRaiseException(RPC_S_INVALID_BOUND); \
5462 TRACE("*ppMemory: %p\n", *ppMemory); \
5463 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5464 pStubMsg->Buffer += sizeof(type); \
5471 RANGE_UNMARSHALL(UCHAR, "%d");
5472 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5476 RANGE_UNMARSHALL(CHAR, "%u");
5477 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5479 case RPC_FC_WCHAR: /* FIXME: valid? */
5481 RANGE_UNMARSHALL(USHORT, "%u");
5482 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5485 RANGE_UNMARSHALL(SHORT, "%d");
5486 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5489 RANGE_UNMARSHALL(LONG, "%d");
5490 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5493 RANGE_UNMARSHALL(ULONG, "%u");
5494 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5498 FIXME("Unhandled enum type\n");
5500 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
5505 ERR("invalid range base type: 0x%02x\n", base_type);
5506 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5512 /***********************************************************************
5513 * NdrRangeBufferSize [internal]
5515 void WINAPI NdrRangeBufferSize(
5516 PMIDL_STUB_MESSAGE pStubMsg,
5517 unsigned char *pMemory,
5518 PFORMAT_STRING pFormat)
5520 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5521 unsigned char base_type;
5523 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5525 if (pRange->type != RPC_FC_RANGE)
5527 ERR("invalid format type %x\n", pRange->type);
5528 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5530 base_type = pRange->flags_type & 0xf;
5532 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
5535 /***********************************************************************
5536 * NdrRangeMemorySize [internal]
5538 ULONG WINAPI NdrRangeMemorySize(
5539 PMIDL_STUB_MESSAGE pStubMsg,
5540 PFORMAT_STRING pFormat)
5542 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5543 unsigned char base_type;
5545 if (pRange->type != RPC_FC_RANGE)
5547 ERR("invalid format type %x\n", pRange->type);
5548 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5551 base_type = pRange->flags_type & 0xf;
5553 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
5556 /***********************************************************************
5557 * NdrRangeFree [internal]
5559 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
5560 unsigned char *pMemory,
5561 PFORMAT_STRING pFormat)
5563 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5568 /***********************************************************************
5569 * NdrBaseTypeMarshall [internal]
5571 static unsigned char *WINAPI NdrBaseTypeMarshall(
5572 PMIDL_STUB_MESSAGE pStubMsg,
5573 unsigned char *pMemory,
5574 PFORMAT_STRING pFormat)
5576 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5584 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
5585 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
5590 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5591 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
5592 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
5596 case RPC_FC_ERROR_STATUS_T:
5598 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5599 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
5600 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
5603 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
5604 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
5607 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
5608 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
5611 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
5612 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
5613 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
5616 /* only 16-bits on the wire, so do a sanity check */
5617 if (*(UINT *)pMemory > SHRT_MAX)
5618 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
5619 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5620 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5621 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5622 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
5623 pStubMsg->Buffer += sizeof(USHORT);
5624 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
5629 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5632 /* FIXME: what is the correct return value? */
5636 /***********************************************************************
5637 * NdrBaseTypeUnmarshall [internal]
5639 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
5640 PMIDL_STUB_MESSAGE pStubMsg,
5641 unsigned char **ppMemory,
5642 PFORMAT_STRING pFormat,
5643 unsigned char fMustAlloc)
5645 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5647 #define BASE_TYPE_UNMARSHALL(type) \
5648 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5649 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
5651 *ppMemory = pStubMsg->Buffer; \
5652 TRACE("*ppMemory: %p\n", *ppMemory); \
5657 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5658 TRACE("*ppMemory: %p\n", *ppMemory); \
5659 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5661 pStubMsg->Buffer += sizeof(type);
5669 BASE_TYPE_UNMARSHALL(UCHAR);
5670 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5675 BASE_TYPE_UNMARSHALL(USHORT);
5676 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5680 case RPC_FC_ERROR_STATUS_T:
5682 BASE_TYPE_UNMARSHALL(ULONG);
5683 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5686 BASE_TYPE_UNMARSHALL(float);
5687 TRACE("value: %f\n", **(float **)ppMemory);
5690 BASE_TYPE_UNMARSHALL(double);
5691 TRACE("value: %f\n", **(double **)ppMemory);
5694 BASE_TYPE_UNMARSHALL(ULONGLONG);
5695 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
5698 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5699 if (fMustAlloc || !*ppMemory)
5700 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
5701 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
5702 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5703 TRACE("*ppMemory: %p\n", *ppMemory);
5704 /* 16-bits on the wire, but int in memory */
5705 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
5706 pStubMsg->Buffer += sizeof(USHORT);
5707 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
5712 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5714 #undef BASE_TYPE_UNMARSHALL
5716 /* FIXME: what is the correct return value? */
5721 /***********************************************************************
5722 * NdrBaseTypeBufferSize [internal]
5724 static void WINAPI NdrBaseTypeBufferSize(
5725 PMIDL_STUB_MESSAGE pStubMsg,
5726 unsigned char *pMemory,
5727 PFORMAT_STRING pFormat)
5729 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5737 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
5743 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
5744 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
5749 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
5750 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
5753 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
5754 safe_buffer_length_increment(pStubMsg, sizeof(float));
5757 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
5758 safe_buffer_length_increment(pStubMsg, sizeof(double));
5761 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
5762 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
5764 case RPC_FC_ERROR_STATUS_T:
5765 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
5766 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
5771 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5775 /***********************************************************************
5776 * NdrBaseTypeMemorySize [internal]
5778 static ULONG WINAPI NdrBaseTypeMemorySize(
5779 PMIDL_STUB_MESSAGE pStubMsg,
5780 PFORMAT_STRING pFormat)
5782 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
5790 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
5791 pStubMsg->MemorySize += sizeof(UCHAR);
5792 return sizeof(UCHAR);
5796 safe_buffer_increment(pStubMsg, sizeof(USHORT));
5797 pStubMsg->MemorySize += sizeof(USHORT);
5798 return sizeof(USHORT);
5802 safe_buffer_increment(pStubMsg, sizeof(ULONG));
5803 pStubMsg->MemorySize += sizeof(ULONG);
5804 return sizeof(ULONG);
5806 safe_buffer_increment(pStubMsg, sizeof(float));
5807 pStubMsg->MemorySize += sizeof(float);
5808 return sizeof(float);
5810 safe_buffer_increment(pStubMsg, sizeof(double));
5811 pStubMsg->MemorySize += sizeof(double);
5812 return sizeof(double);
5814 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
5815 pStubMsg->MemorySize += sizeof(ULONGLONG);
5816 return sizeof(ULONGLONG);
5817 case RPC_FC_ERROR_STATUS_T:
5818 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
5819 pStubMsg->MemorySize += sizeof(error_status_t);
5820 return sizeof(error_status_t);
5822 safe_buffer_increment(pStubMsg, sizeof(USHORT));
5823 pStubMsg->MemorySize += sizeof(UINT);
5824 return sizeof(UINT);
5826 pStubMsg->MemorySize += sizeof(void *);
5827 return sizeof(void *);
5829 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5834 /***********************************************************************
5835 * NdrBaseTypeFree [internal]
5837 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
5838 unsigned char *pMemory,
5839 PFORMAT_STRING pFormat)
5841 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5846 /***********************************************************************
5847 * NdrContextHandleBufferSize [internal]
5849 static void WINAPI NdrContextHandleBufferSize(
5850 PMIDL_STUB_MESSAGE pStubMsg,
5851 unsigned char *pMemory,
5852 PFORMAT_STRING pFormat)
5854 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5856 if (*pFormat != RPC_FC_BIND_CONTEXT)
5858 ERR("invalid format type %x\n", *pFormat);
5859 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5861 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5862 safe_buffer_length_increment(pStubMsg, cbNDRContext);
5865 /***********************************************************************
5866 * NdrContextHandleMarshall [internal]
5868 static unsigned char *WINAPI NdrContextHandleMarshall(
5869 PMIDL_STUB_MESSAGE pStubMsg,
5870 unsigned char *pMemory,
5871 PFORMAT_STRING pFormat)
5873 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5875 if (*pFormat != RPC_FC_BIND_CONTEXT)
5877 ERR("invalid format type %x\n", *pFormat);
5878 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5881 if (pFormat[1] & 0x80)
5882 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
5884 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
5889 /***********************************************************************
5890 * NdrContextHandleUnmarshall [internal]
5892 static unsigned char *WINAPI NdrContextHandleUnmarshall(
5893 PMIDL_STUB_MESSAGE pStubMsg,
5894 unsigned char **ppMemory,
5895 PFORMAT_STRING pFormat,
5896 unsigned char fMustAlloc)
5898 if (*pFormat != RPC_FC_BIND_CONTEXT)
5900 ERR("invalid format type %x\n", *pFormat);
5901 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5904 **(NDR_CCONTEXT **)ppMemory = NULL;
5905 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
5910 /***********************************************************************
5911 * NdrClientContextMarshall [RPCRT4.@]
5913 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5914 NDR_CCONTEXT ContextHandle,
5917 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
5919 ALIGN_POINTER(pStubMsg->Buffer, 4);
5921 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5923 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
5924 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5925 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5928 /* FIXME: what does fCheck do? */
5929 NDRCContextMarshall(ContextHandle,
5932 pStubMsg->Buffer += cbNDRContext;
5935 /***********************************************************************
5936 * NdrClientContextUnmarshall [RPCRT4.@]
5938 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5939 NDR_CCONTEXT * pContextHandle,
5940 RPC_BINDING_HANDLE BindHandle)
5942 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
5944 ALIGN_POINTER(pStubMsg->Buffer, 4);
5946 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
5947 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5949 NDRCContextUnmarshall(pContextHandle,
5952 pStubMsg->RpcMsg->DataRepresentation);
5954 pStubMsg->Buffer += cbNDRContext;
5957 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5958 NDR_SCONTEXT ContextHandle,
5959 NDR_RUNDOWN RundownRoutine )
5961 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
5964 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
5966 FIXME("(%p): stub\n", pStubMsg);
5970 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
5971 unsigned char* pMemory,
5972 PFORMAT_STRING pFormat)
5974 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
5977 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
5978 PFORMAT_STRING pFormat)
5980 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
5984 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5985 NDR_SCONTEXT ContextHandle,
5986 NDR_RUNDOWN RundownRoutine,
5987 PFORMAT_STRING pFormat)
5989 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
5992 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5993 PFORMAT_STRING pFormat)
5995 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
5999 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
6001 typedef struct ndr_context_handle
6005 } ndr_context_handle;
6007 struct context_handle_entry
6011 RPC_BINDING_HANDLE handle;
6012 ndr_context_handle wire_data;
6015 static struct list context_handle_list = LIST_INIT(context_handle_list);
6017 static CRITICAL_SECTION ndr_context_cs;
6018 static CRITICAL_SECTION_DEBUG ndr_context_debug =
6020 0, 0, &ndr_context_cs,
6021 { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
6022 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
6024 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
6026 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
6028 struct context_handle_entry *che = (struct context_handle_entry*) CContext;
6030 if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
6035 static struct context_handle_entry *context_entry_from_guid(LPCGUID uuid)
6037 struct context_handle_entry *che;
6038 LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
6039 if (IsEqualGUID(&che->wire_data.uuid, uuid))
6044 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
6046 struct context_handle_entry *che;
6047 RPC_BINDING_HANDLE handle = NULL;
6049 TRACE("%p\n", CContext);
6051 EnterCriticalSection(&ndr_context_cs);
6052 che = get_context_entry(CContext);
6054 handle = che->handle;
6055 LeaveCriticalSection(&ndr_context_cs);
6058 RpcRaiseException(ERROR_INVALID_HANDLE);
6062 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
6064 struct context_handle_entry *che;
6066 TRACE("%p %p\n", CContext, pBuff);
6070 EnterCriticalSection(&ndr_context_cs);
6071 che = get_context_entry(CContext);
6072 memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
6073 LeaveCriticalSection(&ndr_context_cs);
6077 ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
6078 wire_data->attributes = 0;
6079 wire_data->uuid = GUID_NULL;
6083 /***********************************************************************
6084 * RpcSmDestroyClientContext [RPCRT4.@]
6086 RPC_STATUS WINAPI RpcSmDestroyClientContext(void **ContextHandle)
6088 RPC_STATUS status = RPC_X_SS_CONTEXT_MISMATCH;
6089 struct context_handle_entry *che = NULL;
6091 TRACE("(%p)\n", ContextHandle);
6093 EnterCriticalSection(&ndr_context_cs);
6094 che = get_context_entry(*ContextHandle);
6095 *ContextHandle = NULL;
6099 list_remove(&che->entry);
6102 LeaveCriticalSection(&ndr_context_cs);
6106 RpcBindingFree(&che->handle);
6107 HeapFree(GetProcessHeap(), 0, che);
6113 /***********************************************************************
6114 * RpcSsDestroyClientContext [RPCRT4.@]
6116 void WINAPI RpcSsDestroyClientContext(void **ContextHandle)
6118 RPC_STATUS status = RpcSmDestroyClientContext(ContextHandle);
6119 if (status != RPC_S_OK)
6120 RpcRaiseException(status);
6123 static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
6124 RPC_BINDING_HANDLE hBinding,
6125 const ndr_context_handle *chi)
6127 struct context_handle_entry *che = NULL;
6129 /* a null UUID means we should free the context handle */
6130 if (IsEqualGUID(&chi->uuid, &GUID_NULL))
6134 che = get_context_entry(*CContext);
6136 return ERROR_INVALID_HANDLE;
6137 list_remove(&che->entry);
6138 RpcBindingFree(&che->handle);
6139 HeapFree(GetProcessHeap(), 0, che);
6143 /* if there's no existing entry matching the GUID, allocate one */
6144 else if (!(che = context_entry_from_guid(&chi->uuid)))
6146 che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
6148 return ERROR_NOT_ENOUGH_MEMORY;
6149 che->magic = NDR_CONTEXT_HANDLE_MAGIC;
6150 RpcBindingCopy(hBinding, &che->handle);
6151 list_add_tail(&context_handle_list, &che->entry);
6152 memcpy(&che->wire_data, chi, sizeof *chi);
6157 return ERROR_SUCCESS;
6160 /***********************************************************************
6161 * NDRCContextUnmarshall [RPCRT4.@]
6163 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
6164 RPC_BINDING_HANDLE hBinding,
6165 void *pBuff, ULONG DataRepresentation)
6169 TRACE("*%p=(%p) %p %p %08x\n",
6170 CContext, *CContext, hBinding, pBuff, DataRepresentation);
6172 EnterCriticalSection(&ndr_context_cs);
6173 r = ndr_update_context_handle(CContext, hBinding, pBuff);
6174 LeaveCriticalSection(&ndr_context_cs);
6176 RpcRaiseException(r);
6179 /***********************************************************************
6180 * NDRSContextMarshall [RPCRT4.@]
6182 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
6184 NDR_RUNDOWN userRunDownIn)
6186 FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn);
6189 /***********************************************************************
6190 * NDRSContextMarshallEx [RPCRT4.@]
6192 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
6193 NDR_SCONTEXT CContext,
6195 NDR_RUNDOWN userRunDownIn)
6197 FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn);
6200 /***********************************************************************
6201 * NDRSContextMarshall2 [RPCRT4.@]
6203 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
6204 NDR_SCONTEXT CContext,
6206 NDR_RUNDOWN userRunDownIn,
6207 void *CtxGuard, ULONG Flags)
6209 FIXME("(%p %p %p %p %p %u): stub\n",
6210 hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags);
6213 /***********************************************************************
6214 * NDRSContextUnmarshall [RPCRT4.@]
6216 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
6217 ULONG DataRepresentation)
6219 FIXME("(%p %08x): stub\n", pBuff, DataRepresentation);
6223 /***********************************************************************
6224 * NDRSContextUnmarshallEx [RPCRT4.@]
6226 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
6228 ULONG DataRepresentation)
6230 FIXME("(%p %p %08x): stub\n", hBinding, pBuff, DataRepresentation);
6234 /***********************************************************************
6235 * NDRSContextUnmarshall2 [RPCRT4.@]
6237 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
6239 ULONG DataRepresentation,
6240 void *CtxGuard, ULONG Flags)
6242 FIXME("(%p %p %08x %p %u): stub\n",
6243 hBinding, pBuff, DataRepresentation, CtxGuard, Flags);