4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 * - Non-conformant strings
24 * - Byte count pointers
25 * - transmit_as/represent as
26 * - Multi-dimensional arrays
27 * - Conversion functions (NdrConvert)
28 * - Checks for integer addition overflow
29 * - Checks for out-of-memory conditions
45 #include "wine/unicode.h"
46 #include "wine/rpcfc.h"
48 #include "wine/debug.h"
49 #include "wine/list.h"
51 WINE_DEFAULT_DEBUG_CHANNEL(ole);
54 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
55 (*((UINT32 *)(pchar)) = (uint32))
57 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
58 (*((UINT32 *)(pchar)))
60 /* these would work for i386 too, but less efficient */
61 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
62 (*(pchar) = LOBYTE(LOWORD(uint32)), \
63 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
64 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
65 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
66 (uint32)) /* allow as r-value */
68 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
70 MAKEWORD(*(pchar), *((pchar)+1)), \
71 MAKEWORD(*((pchar)+2), *((pchar)+3))))
74 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
75 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
76 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
77 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
78 *(pchar) = HIBYTE(HIWORD(uint32)), \
79 (uint32)) /* allow as r-value */
81 #define BIG_ENDIAN_UINT32_READ(pchar) \
83 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
84 MAKEWORD(*((pchar)+1), *(pchar))))
86 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
87 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
88 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
89 # define NDR_LOCAL_UINT32_READ(pchar) \
90 BIG_ENDIAN_UINT32_READ(pchar)
92 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
93 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
94 # define NDR_LOCAL_UINT32_READ(pchar) \
95 LITTLE_ENDIAN_UINT32_READ(pchar)
98 /* _Align must be the desired alignment,
99 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
100 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
101 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
102 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
103 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
105 #define STD_OVERFLOW_CHECK(_Msg) do { \
106 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
107 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
108 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
111 #define NDR_TABLE_SIZE 128
112 #define NDR_TABLE_MASK 127
114 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
115 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
116 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
117 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
118 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
120 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
121 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
122 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
124 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
126 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
127 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
128 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
129 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
133 NdrPointerMarshall, NdrPointerMarshall,
134 NdrPointerMarshall, NdrPointerMarshall,
136 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
137 NdrConformantStructMarshall, NdrConformantStructMarshall,
138 NdrConformantVaryingStructMarshall,
139 NdrComplexStructMarshall,
141 NdrConformantArrayMarshall,
142 NdrConformantVaryingArrayMarshall,
143 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
144 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
145 NdrComplexArrayMarshall,
147 NdrConformantStringMarshall, 0, 0,
148 NdrConformantStringMarshall,
149 NdrNonConformantStringMarshall, 0, 0, 0,
151 NdrEncapsulatedUnionMarshall,
152 NdrNonEncapsulatedUnionMarshall,
153 NdrByteCountPointerMarshall,
154 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
156 NdrInterfacePointerMarshall,
158 NdrContextHandleMarshall,
161 NdrUserMarshalMarshall,
166 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
168 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
169 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
170 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
171 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
173 NdrBaseTypeUnmarshall,
175 NdrPointerUnmarshall, NdrPointerUnmarshall,
176 NdrPointerUnmarshall, NdrPointerUnmarshall,
178 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
179 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
180 NdrConformantVaryingStructUnmarshall,
181 NdrComplexStructUnmarshall,
183 NdrConformantArrayUnmarshall,
184 NdrConformantVaryingArrayUnmarshall,
185 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
186 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
187 NdrComplexArrayUnmarshall,
189 NdrConformantStringUnmarshall, 0, 0,
190 NdrConformantStringUnmarshall,
191 NdrNonConformantStringUnmarshall, 0, 0, 0,
193 NdrEncapsulatedUnionUnmarshall,
194 NdrNonEncapsulatedUnionUnmarshall,
195 NdrByteCountPointerUnmarshall,
196 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
198 NdrInterfacePointerUnmarshall,
200 NdrContextHandleUnmarshall,
203 NdrUserMarshalUnmarshall,
208 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
210 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
211 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
212 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
213 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
215 NdrBaseTypeBufferSize,
217 NdrPointerBufferSize, NdrPointerBufferSize,
218 NdrPointerBufferSize, NdrPointerBufferSize,
220 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
221 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
222 NdrConformantVaryingStructBufferSize,
223 NdrComplexStructBufferSize,
225 NdrConformantArrayBufferSize,
226 NdrConformantVaryingArrayBufferSize,
227 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
228 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
229 NdrComplexArrayBufferSize,
231 NdrConformantStringBufferSize, 0, 0,
232 NdrConformantStringBufferSize,
233 NdrNonConformantStringBufferSize, 0, 0, 0,
235 NdrEncapsulatedUnionBufferSize,
236 NdrNonEncapsulatedUnionBufferSize,
237 NdrByteCountPointerBufferSize,
238 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
240 NdrInterfacePointerBufferSize,
242 NdrContextHandleBufferSize,
245 NdrUserMarshalBufferSize,
250 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
252 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
253 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
254 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
255 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
257 NdrBaseTypeMemorySize,
259 NdrPointerMemorySize, NdrPointerMemorySize,
260 NdrPointerMemorySize, NdrPointerMemorySize,
262 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
263 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
264 NdrConformantVaryingStructMemorySize,
265 NdrComplexStructMemorySize,
267 NdrConformantArrayMemorySize,
268 NdrConformantVaryingArrayMemorySize,
269 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
270 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
271 NdrComplexArrayMemorySize,
273 NdrConformantStringMemorySize, 0, 0,
274 NdrConformantStringMemorySize,
275 NdrNonConformantStringMemorySize, 0, 0, 0,
277 NdrEncapsulatedUnionMemorySize,
278 NdrNonEncapsulatedUnionMemorySize,
279 NdrByteCountPointerMemorySize,
280 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
282 NdrInterfacePointerMemorySize,
287 NdrUserMarshalMemorySize,
292 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
294 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
295 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
296 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
297 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
301 NdrPointerFree, NdrPointerFree,
302 NdrPointerFree, NdrPointerFree,
304 NdrSimpleStructFree, NdrSimpleStructFree,
305 NdrConformantStructFree, NdrConformantStructFree,
306 NdrConformantVaryingStructFree,
307 NdrComplexStructFree,
309 NdrConformantArrayFree,
310 NdrConformantVaryingArrayFree,
311 NdrFixedArrayFree, NdrFixedArrayFree,
312 NdrVaryingArrayFree, NdrVaryingArrayFree,
318 NdrEncapsulatedUnionFree,
319 NdrNonEncapsulatedUnionFree,
321 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
323 NdrInterfacePointerFree,
334 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
336 /* hmm, this is probably supposed to do more? */
337 return pStubMsg->pfnAllocate(len);
340 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
342 pStubMsg->pfnFree(Pointer);
345 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
347 return (*(const ULONG *)pFormat != -1);
350 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
352 ALIGN_POINTER(pStubMsg->Buffer, 4);
353 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
354 RpcRaiseException(RPC_X_BAD_STUB_DATA);
355 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
356 pStubMsg->Buffer += 4;
357 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
358 if (pStubMsg->fHasNewCorrDesc)
364 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
366 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
368 pStubMsg->Offset = 0;
369 pStubMsg->ActualCount = pStubMsg->MaxCount;
373 ALIGN_POINTER(pStubMsg->Buffer, 4);
374 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
375 RpcRaiseException(RPC_X_BAD_STUB_DATA);
376 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
377 pStubMsg->Buffer += 4;
378 TRACE("offset is %d\n", pStubMsg->Offset);
379 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
380 pStubMsg->Buffer += 4;
381 TRACE("variance is %d\n", pStubMsg->ActualCount);
383 if ((pStubMsg->ActualCount > MaxValue) ||
384 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
386 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
387 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
388 RpcRaiseException(RPC_S_INVALID_BOUND);
393 if (pStubMsg->fHasNewCorrDesc)
399 /* writes the conformance value to the buffer */
400 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
402 ALIGN_POINTER(pStubMsg->Buffer, 4);
403 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
404 pStubMsg->Buffer += 4;
407 /* writes the variance values to the buffer */
408 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
410 ALIGN_POINTER(pStubMsg->Buffer, 4);
411 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
412 pStubMsg->Buffer += 4;
413 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
414 pStubMsg->Buffer += 4;
417 /* requests buffer space for the conformance value */
418 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
420 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
421 pStubMsg->BufferLength += 4;
424 /* requests buffer space for the variance values */
425 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
427 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
428 pStubMsg->BufferLength += 8;
431 PFORMAT_STRING ComputeConformanceOrVariance(
432 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
433 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
435 BYTE dtype = pFormat[0] & 0xf;
436 short ofs = *(const short *)&pFormat[2];
440 if (!IsConformanceOrVariancePresent(pFormat)) {
441 /* null descriptor */
446 switch (pFormat[0] & 0xf0) {
447 case RPC_FC_NORMAL_CONFORMANCE:
448 TRACE("normal conformance, ofs=%d\n", ofs);
451 case RPC_FC_POINTER_CONFORMANCE:
452 TRACE("pointer conformance, ofs=%d\n", ofs);
453 ptr = pStubMsg->Memory;
455 case RPC_FC_TOP_LEVEL_CONFORMANCE:
456 TRACE("toplevel conformance, ofs=%d\n", ofs);
457 if (pStubMsg->StackTop) {
458 ptr = pStubMsg->StackTop;
461 /* -Os mode, *pCount is already set */
465 case RPC_FC_CONSTANT_CONFORMANCE:
466 data = ofs | ((DWORD)pFormat[1] << 16);
467 TRACE("constant conformance, val=%d\n", data);
470 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
471 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
472 if (pStubMsg->StackTop) {
473 ptr = pStubMsg->StackTop;
481 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
484 switch (pFormat[1]) {
485 case RPC_FC_DEREFERENCE:
486 ptr = *(LPVOID*)((char *)ptr + ofs);
488 case RPC_FC_CALLBACK:
490 unsigned char *old_stack_top = pStubMsg->StackTop;
491 pStubMsg->StackTop = ptr;
493 /* ofs is index into StubDesc->apfnExprEval */
494 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
495 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
497 pStubMsg->StackTop = old_stack_top;
499 /* the callback function always stores the computed value in MaxCount */
500 *pCount = pStubMsg->MaxCount;
504 ptr = (char *)ptr + ofs;
517 data = *(USHORT*)ptr;
528 FIXME("unknown conformance data type %x\n", dtype);
531 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
534 switch (pFormat[1]) {
535 case RPC_FC_DEREFERENCE: /* already handled */
552 FIXME("unknown conformance op %d\n", pFormat[1]);
557 TRACE("resulting conformance is %ld\n", *pCount);
558 if (pStubMsg->fHasNewCorrDesc)
564 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
565 * the result overflows 32-bits */
566 static inline ULONG safe_multiply(ULONG a, ULONG b)
568 ULONGLONG ret = (ULONGLONG)a * b;
569 if (ret > 0xffffffff)
571 RpcRaiseException(RPC_S_INVALID_BOUND);
577 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
579 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
580 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
581 RpcRaiseException(RPC_X_BAD_STUB_DATA);
582 pStubMsg->Buffer += size;
585 /* copies data from the buffer, checking that there is enough data in the buffer
587 static inline void safe_buffer_copy(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
589 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
590 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
591 RpcRaiseException(RPC_X_BAD_STUB_DATA);
592 memcpy(p, pStubMsg->Buffer, size);
593 pStubMsg->Buffer += size;
597 * NdrConformantString:
599 * What MS calls a ConformantString is, in DCE terminology,
600 * a Varying-Conformant String.
602 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
603 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
604 * into unmarshalled string)
605 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
607 * data: CHARTYPE[maxlen]
609 * ], where CHARTYPE is the appropriate character type (specified externally)
613 /***********************************************************************
614 * NdrConformantStringMarshall [RPCRT4.@]
616 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
617 unsigned char *pszMessage, PFORMAT_STRING pFormat)
621 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
623 if (*pFormat == RPC_FC_C_CSTRING) {
624 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
625 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
628 else if (*pFormat == RPC_FC_C_WSTRING) {
629 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
630 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
634 ERR("Unhandled string type: %#x\n", *pFormat);
635 /* FIXME: raise an exception. */
639 if (pFormat[1] == RPC_FC_STRING_SIZED)
640 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
642 pStubMsg->MaxCount = pStubMsg->ActualCount;
643 pStubMsg->Offset = 0;
644 WriteConformance(pStubMsg);
645 WriteVariance(pStubMsg);
647 size = safe_multiply(esize, pStubMsg->ActualCount);
648 memcpy(pStubMsg->Buffer, pszMessage, size); /* the string itself */
649 pStubMsg->Buffer += size;
651 STD_OVERFLOW_CHECK(pStubMsg);
654 return NULL; /* is this always right? */
657 /***********************************************************************
658 * NdrConformantStringBufferSize [RPCRT4.@]
660 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
661 unsigned char* pMemory, PFORMAT_STRING pFormat)
665 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
667 SizeConformance(pStubMsg);
668 SizeVariance(pStubMsg);
670 if (*pFormat == RPC_FC_C_CSTRING) {
671 TRACE("string=%s\n", debugstr_a((char*)pMemory));
672 pStubMsg->ActualCount = strlen((char*)pMemory)+1;
675 else if (*pFormat == RPC_FC_C_WSTRING) {
676 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
677 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;
681 ERR("Unhandled string type: %#x\n", *pFormat);
682 /* FIXME: raise an exception */
686 if (pFormat[1] == RPC_FC_STRING_SIZED)
687 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
689 pStubMsg->MaxCount = pStubMsg->ActualCount;
691 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
694 /************************************************************************
695 * NdrConformantStringMemorySize [RPCRT4.@]
697 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
698 PFORMAT_STRING pFormat )
702 FIXME("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
704 assert(pStubMsg && pFormat);
706 if (*pFormat == RPC_FC_C_CSTRING) {
707 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
709 else if (*pFormat == RPC_FC_C_WSTRING) {
710 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
713 ERR("Unhandled string type: %#x\n", *pFormat);
714 /* FIXME: raise an exception */
717 if (pFormat[1] != RPC_FC_PAD) {
718 FIXME("sized string format=%d\n", pFormat[1]);
721 TRACE(" --> %u\n", rslt);
725 /************************************************************************
726 * NdrConformantStringUnmarshall [RPCRT4.@]
728 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
729 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
731 ULONG bufsize, memsize, esize, i;
733 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
734 pStubMsg, *ppMemory, pFormat, fMustAlloc);
736 assert(pFormat && ppMemory && pStubMsg);
738 ReadConformance(pStubMsg, NULL);
739 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
741 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
742 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
744 ERR("Unhandled string type: %#x\n", *pFormat);
745 /* FIXME: raise an exception */
749 memsize = safe_multiply(esize, pStubMsg->MaxCount);
750 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
752 /* strings must always have null terminating bytes */
755 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
756 RpcRaiseException(RPC_S_INVALID_BOUND);
760 /* verify the buffer is safe to access */
761 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
762 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
764 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
765 pStubMsg->BufferEnd, pStubMsg->Buffer);
766 RpcRaiseException(RPC_X_BAD_STUB_DATA);
770 for (i = bufsize - esize; i < bufsize; i++)
771 if (pStubMsg->Buffer[i] != 0)
773 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
774 i, pStubMsg->Buffer[i]);
775 RpcRaiseException(RPC_S_INVALID_BOUND);
779 if (fMustAlloc || !*ppMemory)
780 *ppMemory = NdrAllocate(pStubMsg, memsize);
782 safe_buffer_copy(pStubMsg, *ppMemory, bufsize);
784 if (*pFormat == RPC_FC_C_CSTRING) {
785 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
787 else if (*pFormat == RPC_FC_C_WSTRING) {
788 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
791 return NULL; /* FIXME: is this always right? */
794 /***********************************************************************
795 * NdrNonConformantStringMarshall [RPCRT4.@]
797 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
798 unsigned char *pMemory,
799 PFORMAT_STRING pFormat)
805 /***********************************************************************
806 * NdrNonConformantStringUnmarshall [RPCRT4.@]
808 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
809 unsigned char **ppMemory,
810 PFORMAT_STRING pFormat,
811 unsigned char fMustAlloc)
817 /***********************************************************************
818 * NdrNonConformantStringBufferSize [RPCRT4.@]
820 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
821 unsigned char *pMemory,
822 PFORMAT_STRING pFormat)
827 /***********************************************************************
828 * NdrNonConformantStringMemorySize [RPCRT4.@]
830 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
831 PFORMAT_STRING pFormat)
837 static inline void dump_pointer_attr(unsigned char attr)
839 if (attr & RPC_FC_P_ALLOCALLNODES)
840 TRACE(" RPC_FC_P_ALLOCALLNODES");
841 if (attr & RPC_FC_P_DONTFREE)
842 TRACE(" RPC_FC_P_DONTFREE");
843 if (attr & RPC_FC_P_ONSTACK)
844 TRACE(" RPC_FC_P_ONSTACK");
845 if (attr & RPC_FC_P_SIMPLEPOINTER)
846 TRACE(" RPC_FC_P_SIMPLEPOINTER");
847 if (attr & RPC_FC_P_DEREF)
848 TRACE(" RPC_FC_P_DEREF");
852 /***********************************************************************
853 * PointerMarshall [internal]
855 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
856 unsigned char *Buffer,
857 unsigned char *Pointer,
858 PFORMAT_STRING pFormat)
860 unsigned type = pFormat[0], attr = pFormat[1];
864 int pointer_needs_marshaling;
866 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
867 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
869 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
870 else desc = pFormat + *(const SHORT*)pFormat;
873 case RPC_FC_RP: /* ref pointer (always non-null) */
874 #if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
876 RpcRaiseException(RPC_X_NULL_REF_POINTER);
878 pointer_needs_marshaling = 1;
880 case RPC_FC_UP: /* unique pointer */
881 case RPC_FC_OP: /* object pointer - same as unique here */
883 pointer_needs_marshaling = 1;
885 pointer_needs_marshaling = 0;
886 pointer_id = (ULONG)Pointer;
887 TRACE("writing 0x%08x to buffer\n", pointer_id);
888 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
891 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
892 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
893 TRACE("writing 0x%08x to buffer\n", pointer_id);
894 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
897 FIXME("unhandled ptr type=%02x\n", type);
898 RpcRaiseException(RPC_X_BAD_STUB_DATA);
902 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
904 if (pointer_needs_marshaling) {
905 if (attr & RPC_FC_P_DEREF) {
906 Pointer = *(unsigned char**)Pointer;
907 TRACE("deref => %p\n", Pointer);
909 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
910 if (m) m(pStubMsg, Pointer, desc);
911 else FIXME("no marshaller for data type=%02x\n", *desc);
914 STD_OVERFLOW_CHECK(pStubMsg);
917 /***********************************************************************
918 * PointerUnmarshall [internal]
920 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
921 unsigned char *Buffer,
922 unsigned char **pPointer,
923 PFORMAT_STRING pFormat,
924 unsigned char fMustAlloc)
926 unsigned type = pFormat[0], attr = pFormat[1];
929 DWORD pointer_id = 0;
930 int pointer_needs_unmarshaling;
932 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pFormat, fMustAlloc);
933 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
935 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
936 else desc = pFormat + *(const SHORT*)pFormat;
939 case RPC_FC_RP: /* ref pointer (always non-null) */
940 pointer_needs_unmarshaling = 1;
942 case RPC_FC_UP: /* unique pointer */
943 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
944 TRACE("pointer_id is 0x%08x\n", pointer_id);
946 pointer_needs_unmarshaling = 1;
949 pointer_needs_unmarshaling = 0;
952 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
953 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
954 TRACE("pointer_id is 0x%08x\n", pointer_id);
955 if (!fMustAlloc && *pPointer)
957 FIXME("free object pointer %p\n", *pPointer);
961 pointer_needs_unmarshaling = 1;
963 pointer_needs_unmarshaling = 0;
966 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
967 TRACE("pointer_id is 0x%08x\n", pointer_id);
968 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
969 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
972 FIXME("unhandled ptr type=%02x\n", type);
973 RpcRaiseException(RPC_X_BAD_STUB_DATA);
977 if (pointer_needs_unmarshaling) {
978 if (attr & RPC_FC_P_DEREF) {
979 if (!*pPointer || fMustAlloc) {
980 *pPointer = NdrAllocate(pStubMsg, sizeof(void *));
981 *(unsigned char**) *pPointer = NULL;
983 pPointer = *(unsigned char***)pPointer;
984 TRACE("deref => %p\n", pPointer);
986 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
987 if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
988 else FIXME("no unmarshaller for data type=%02x\n", *desc);
990 if (type == RPC_FC_FP)
991 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
995 TRACE("pointer=%p\n", *pPointer);
998 /***********************************************************************
999 * PointerBufferSize [internal]
1001 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1002 unsigned char *Pointer,
1003 PFORMAT_STRING pFormat)
1005 unsigned type = pFormat[0], attr = pFormat[1];
1006 PFORMAT_STRING desc;
1008 int pointer_needs_sizing;
1011 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1012 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1014 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1015 else desc = pFormat + *(const SHORT*)pFormat;
1018 case RPC_FC_RP: /* ref pointer (always non-null) */
1022 /* NULL pointer has no further representation */
1027 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1028 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1029 if (!pointer_needs_sizing)
1033 FIXME("unhandled ptr type=%02x\n", type);
1034 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1038 if (attr & RPC_FC_P_DEREF) {
1039 Pointer = *(unsigned char**)Pointer;
1040 TRACE("deref => %p\n", Pointer);
1043 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1044 if (m) m(pStubMsg, Pointer, desc);
1045 else FIXME("no buffersizer for data type=%02x\n", *desc);
1048 /***********************************************************************
1049 * PointerMemorySize [internal]
1051 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1052 unsigned char *Buffer,
1053 PFORMAT_STRING pFormat)
1055 unsigned type = pFormat[0], attr = pFormat[1];
1056 PFORMAT_STRING desc;
1059 FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat);
1060 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1062 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1063 else desc = pFormat + *(const SHORT*)pFormat;
1066 case RPC_FC_RP: /* ref pointer (always non-null) */
1069 FIXME("unhandled ptr type=%02x\n", type);
1070 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1073 if (attr & RPC_FC_P_DEREF) {
1077 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1078 if (m) m(pStubMsg, desc);
1079 else FIXME("no memorysizer for data type=%02x\n", *desc);
1084 /***********************************************************************
1085 * PointerFree [internal]
1087 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1088 unsigned char *Pointer,
1089 PFORMAT_STRING pFormat)
1091 unsigned type = pFormat[0], attr = pFormat[1];
1092 PFORMAT_STRING desc;
1095 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1096 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1097 if (attr & RPC_FC_P_DONTFREE) return;
1099 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1100 else desc = pFormat + *(const SHORT*)pFormat;
1102 if (!Pointer) return;
1104 if (type == RPC_FC_FP) {
1105 int pointer_needs_freeing = NdrFullPointerFree(
1106 pStubMsg->FullPtrXlatTables, Pointer);
1107 if (!pointer_needs_freeing)
1111 if (attr & RPC_FC_P_DEREF) {
1112 Pointer = *(unsigned char**)Pointer;
1113 TRACE("deref => %p\n", Pointer);
1116 m = NdrFreer[*desc & NDR_TABLE_MASK];
1117 if (m) m(pStubMsg, Pointer, desc);
1119 /* hmm... is this sensible?
1120 * perhaps we should check if the memory comes from NdrAllocate,
1121 * and deallocate only if so - checking if the pointer is between
1122 * BufferStart and BufferEnd is probably no good since the buffer
1123 * may be reallocated when the server wants to marshal the reply */
1125 case RPC_FC_BOGUS_STRUCT:
1126 case RPC_FC_BOGUS_ARRAY:
1127 case RPC_FC_USER_MARSHAL:
1129 case RPC_FC_CVARRAY:
1132 FIXME("unhandled data type=%02x\n", *desc);
1134 case RPC_FC_C_CSTRING:
1135 case RPC_FC_C_WSTRING:
1136 if (pStubMsg->ReuseBuffer) goto notfree;
1142 if (attr & RPC_FC_P_ONSTACK) {
1143 TRACE("not freeing stack ptr %p\n", Pointer);
1146 TRACE("freeing %p\n", Pointer);
1147 NdrFree(pStubMsg, Pointer);
1150 TRACE("not freeing %p\n", Pointer);
1153 /***********************************************************************
1154 * EmbeddedPointerMarshall
1156 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1157 unsigned char *pMemory,
1158 PFORMAT_STRING pFormat)
1160 unsigned char *Mark = pStubMsg->BufferMark;
1161 unsigned rep, count, stride;
1163 unsigned char *saved_buffer = NULL;
1165 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1167 if (*pFormat != RPC_FC_PP) return NULL;
1170 if (pStubMsg->PointerBufferMark)
1172 saved_buffer = pStubMsg->Buffer;
1173 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1174 pStubMsg->PointerBufferMark = NULL;
1177 while (pFormat[0] != RPC_FC_END) {
1178 switch (pFormat[0]) {
1180 FIXME("unknown repeat type %d\n", pFormat[0]);
1181 case RPC_FC_NO_REPEAT:
1187 case RPC_FC_FIXED_REPEAT:
1188 rep = *(const WORD*)&pFormat[2];
1189 stride = *(const WORD*)&pFormat[4];
1190 count = *(const WORD*)&pFormat[8];
1193 case RPC_FC_VARIABLE_REPEAT:
1194 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1195 stride = *(const WORD*)&pFormat[2];
1196 count = *(const WORD*)&pFormat[6];
1200 for (i = 0; i < rep; i++) {
1201 PFORMAT_STRING info = pFormat;
1202 unsigned char *membase = pMemory + (i * stride);
1203 unsigned char *bufbase = Mark + (i * stride);
1206 for (u=0; u<count; u++,info+=8) {
1207 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1208 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1209 unsigned char *saved_memory = pStubMsg->Memory;
1211 pStubMsg->Memory = pMemory;
1212 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1213 pStubMsg->Memory = saved_memory;
1216 pFormat += 8 * count;
1221 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1222 pStubMsg->Buffer = saved_buffer;
1225 STD_OVERFLOW_CHECK(pStubMsg);
1230 /***********************************************************************
1231 * EmbeddedPointerUnmarshall
1233 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1234 unsigned char **ppMemory,
1235 PFORMAT_STRING pFormat,
1236 unsigned char fMustAlloc)
1238 unsigned char *Mark = pStubMsg->BufferMark;
1239 unsigned rep, count, stride;
1241 unsigned char *saved_buffer = NULL;
1243 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1245 if (*pFormat != RPC_FC_PP) return NULL;
1248 if (pStubMsg->PointerBufferMark)
1250 saved_buffer = pStubMsg->Buffer;
1251 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1252 pStubMsg->PointerBufferMark = NULL;
1255 while (pFormat[0] != RPC_FC_END) {
1256 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1257 switch (pFormat[0]) {
1259 FIXME("unknown repeat type %d\n", pFormat[0]);
1260 case RPC_FC_NO_REPEAT:
1266 case RPC_FC_FIXED_REPEAT:
1267 rep = *(const WORD*)&pFormat[2];
1268 stride = *(const WORD*)&pFormat[4];
1269 count = *(const WORD*)&pFormat[8];
1272 case RPC_FC_VARIABLE_REPEAT:
1273 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1274 stride = *(const WORD*)&pFormat[2];
1275 count = *(const WORD*)&pFormat[6];
1279 for (i = 0; i < rep; i++) {
1280 PFORMAT_STRING info = pFormat;
1281 unsigned char *membase = *ppMemory + (i * stride);
1282 unsigned char *bufbase = Mark + (i * stride);
1285 for (u=0; u<count; u++,info+=8) {
1286 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1287 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1288 PointerUnmarshall(pStubMsg, bufptr, (unsigned char**)memptr, info+4, TRUE);
1291 pFormat += 8 * count;
1296 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1297 pStubMsg->Buffer = saved_buffer;
1303 /***********************************************************************
1304 * EmbeddedPointerBufferSize
1306 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1307 unsigned char *pMemory,
1308 PFORMAT_STRING pFormat)
1310 unsigned rep, count, stride;
1312 ULONG saved_buffer_length = 0;
1314 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1316 if (pStubMsg->IgnoreEmbeddedPointers) return;
1318 if (*pFormat != RPC_FC_PP) return;
1321 if (pStubMsg->PointerLength)
1323 saved_buffer_length = pStubMsg->BufferLength;
1324 pStubMsg->BufferLength = pStubMsg->PointerLength;
1325 pStubMsg->PointerLength = 0;
1328 while (pFormat[0] != RPC_FC_END) {
1329 switch (pFormat[0]) {
1331 FIXME("unknown repeat type %d\n", pFormat[0]);
1332 case RPC_FC_NO_REPEAT:
1338 case RPC_FC_FIXED_REPEAT:
1339 rep = *(const WORD*)&pFormat[2];
1340 stride = *(const WORD*)&pFormat[4];
1341 count = *(const WORD*)&pFormat[8];
1344 case RPC_FC_VARIABLE_REPEAT:
1345 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1346 stride = *(const WORD*)&pFormat[2];
1347 count = *(const WORD*)&pFormat[6];
1351 for (i = 0; i < rep; i++) {
1352 PFORMAT_STRING info = pFormat;
1353 unsigned char *membase = pMemory + (i * stride);
1356 for (u=0; u<count; u++,info+=8) {
1357 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1358 unsigned char *saved_memory = pStubMsg->Memory;
1360 pStubMsg->Memory = pMemory;
1361 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1362 pStubMsg->Memory = saved_memory;
1365 pFormat += 8 * count;
1368 if (saved_buffer_length)
1370 pStubMsg->PointerLength = pStubMsg->BufferLength;
1371 pStubMsg->BufferLength = saved_buffer_length;
1375 /***********************************************************************
1376 * EmbeddedPointerMemorySize [internal]
1378 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1379 PFORMAT_STRING pFormat)
1381 unsigned char *Mark = pStubMsg->BufferMark;
1382 unsigned rep, count, stride;
1385 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1387 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1389 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1391 if (*pFormat != RPC_FC_PP) return 0;
1394 while (pFormat[0] != RPC_FC_END) {
1395 switch (pFormat[0]) {
1397 FIXME("unknown repeat type %d\n", pFormat[0]);
1398 case RPC_FC_NO_REPEAT:
1404 case RPC_FC_FIXED_REPEAT:
1405 rep = *(const WORD*)&pFormat[2];
1406 stride = *(const WORD*)&pFormat[4];
1407 count = *(const WORD*)&pFormat[8];
1410 case RPC_FC_VARIABLE_REPEAT:
1411 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1412 stride = *(const WORD*)&pFormat[2];
1413 count = *(const WORD*)&pFormat[6];
1417 for (i = 0; i < rep; i++) {
1418 PFORMAT_STRING info = pFormat;
1419 unsigned char *bufbase = Mark + (i * stride);
1421 for (u=0; u<count; u++,info+=8) {
1422 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1423 PointerMemorySize(pStubMsg, bufptr, info+4);
1426 pFormat += 8 * count;
1432 /***********************************************************************
1433 * EmbeddedPointerFree [internal]
1435 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1436 unsigned char *pMemory,
1437 PFORMAT_STRING pFormat)
1439 unsigned rep, count, stride;
1442 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1443 if (*pFormat != RPC_FC_PP) return;
1446 while (pFormat[0] != RPC_FC_END) {
1447 switch (pFormat[0]) {
1449 FIXME("unknown repeat type %d\n", pFormat[0]);
1450 case RPC_FC_NO_REPEAT:
1456 case RPC_FC_FIXED_REPEAT:
1457 rep = *(const WORD*)&pFormat[2];
1458 stride = *(const WORD*)&pFormat[4];
1459 count = *(const WORD*)&pFormat[8];
1462 case RPC_FC_VARIABLE_REPEAT:
1463 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1464 stride = *(const WORD*)&pFormat[2];
1465 count = *(const WORD*)&pFormat[6];
1469 for (i = 0; i < rep; i++) {
1470 PFORMAT_STRING info = pFormat;
1471 unsigned char *membase = pMemory + (i * stride);
1474 for (u=0; u<count; u++,info+=8) {
1475 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1476 unsigned char *saved_memory = pStubMsg->Memory;
1478 pStubMsg->Memory = pMemory;
1479 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1480 pStubMsg->Memory = saved_memory;
1483 pFormat += 8 * count;
1487 /***********************************************************************
1488 * NdrPointerMarshall [RPCRT4.@]
1490 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1491 unsigned char *pMemory,
1492 PFORMAT_STRING pFormat)
1494 unsigned char *Buffer;
1496 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1498 /* incremement the buffer here instead of in PointerMarshall,
1499 * as that is used by embedded pointers which already handle the incrementing
1500 * the buffer, and shouldn't write any additional pointer data to the wire */
1501 if (*pFormat != RPC_FC_RP)
1503 ALIGN_POINTER(pStubMsg->Buffer, 4);
1504 Buffer = pStubMsg->Buffer;
1505 pStubMsg->Buffer += 4;
1508 Buffer = pStubMsg->Buffer;
1510 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1512 STD_OVERFLOW_CHECK(pStubMsg);
1517 /***********************************************************************
1518 * NdrPointerUnmarshall [RPCRT4.@]
1520 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1521 unsigned char **ppMemory,
1522 PFORMAT_STRING pFormat,
1523 unsigned char fMustAlloc)
1525 unsigned char *Buffer;
1527 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1529 /* incremement the buffer here instead of in PointerUnmarshall,
1530 * as that is used by embedded pointers which already handle the incrementing
1531 * the buffer, and shouldn't read any additional pointer data from the
1533 if (*pFormat != RPC_FC_RP)
1535 ALIGN_POINTER(pStubMsg->Buffer, 4);
1536 Buffer = pStubMsg->Buffer;
1537 safe_buffer_increment(pStubMsg, 4);
1540 Buffer = pStubMsg->Buffer;
1542 PointerUnmarshall(pStubMsg, Buffer, ppMemory, pFormat, fMustAlloc);
1547 /***********************************************************************
1548 * NdrPointerBufferSize [RPCRT4.@]
1550 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1551 unsigned char *pMemory,
1552 PFORMAT_STRING pFormat)
1554 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1556 /* incremement the buffer length here instead of in PointerBufferSize,
1557 * as that is used by embedded pointers which already handle the buffer
1558 * length, and shouldn't write anything more to the wire */
1559 if (*pFormat != RPC_FC_RP)
1561 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1562 pStubMsg->BufferLength += 4;
1565 PointerBufferSize(pStubMsg, pMemory, pFormat);
1568 /***********************************************************************
1569 * NdrPointerMemorySize [RPCRT4.@]
1571 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1572 PFORMAT_STRING pFormat)
1574 /* unsigned size = *(LPWORD)(pFormat+2); */
1575 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1576 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1580 /***********************************************************************
1581 * NdrPointerFree [RPCRT4.@]
1583 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1584 unsigned char *pMemory,
1585 PFORMAT_STRING pFormat)
1587 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1588 PointerFree(pStubMsg, pMemory, pFormat);
1591 /***********************************************************************
1592 * NdrSimpleTypeMarshall [RPCRT4.@]
1594 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1595 unsigned char FormatChar )
1597 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1600 /***********************************************************************
1601 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1603 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1604 unsigned char FormatChar )
1606 NdrBaseTypeUnmarshall(pStubMsg, &pMemory, &FormatChar, 0);
1609 /***********************************************************************
1610 * NdrSimpleStructMarshall [RPCRT4.@]
1612 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1613 unsigned char *pMemory,
1614 PFORMAT_STRING pFormat)
1616 unsigned size = *(const WORD*)(pFormat+2);
1617 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1619 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1621 memcpy(pStubMsg->Buffer, pMemory, size);
1622 pStubMsg->BufferMark = pStubMsg->Buffer;
1623 pStubMsg->Buffer += size;
1625 if (pFormat[0] != RPC_FC_STRUCT)
1626 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1628 STD_OVERFLOW_CHECK(pStubMsg);
1633 /***********************************************************************
1634 * NdrSimpleStructUnmarshall [RPCRT4.@]
1636 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1637 unsigned char **ppMemory,
1638 PFORMAT_STRING pFormat,
1639 unsigned char fMustAlloc)
1641 unsigned size = *(const WORD*)(pFormat+2);
1642 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1644 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1647 *ppMemory = NdrAllocate(pStubMsg, size);
1648 memcpy(*ppMemory, pStubMsg->Buffer, size);
1650 if (!pStubMsg->IsClient && !*ppMemory)
1651 /* for servers, we just point straight into the RPC buffer */
1652 *ppMemory = pStubMsg->Buffer;
1654 /* for clients, memory should be provided by caller */
1655 memcpy(*ppMemory, pStubMsg->Buffer, size);
1658 pStubMsg->BufferMark = pStubMsg->Buffer;
1659 pStubMsg->Buffer += size;
1661 if (pFormat[0] != RPC_FC_STRUCT)
1662 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat+4, fMustAlloc);
1667 /***********************************************************************
1668 * NdrSimpleStructBufferSize [RPCRT4.@]
1670 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1671 unsigned char *pMemory,
1672 PFORMAT_STRING pFormat)
1674 unsigned size = *(const WORD*)(pFormat+2);
1675 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1677 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1679 pStubMsg->BufferLength += size;
1680 if (pFormat[0] != RPC_FC_STRUCT)
1681 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1684 /***********************************************************************
1685 * NdrSimpleStructMemorySize [RPCRT4.@]
1687 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1688 PFORMAT_STRING pFormat)
1690 unsigned short size = *(const WORD *)(pFormat+2);
1692 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1694 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1695 pStubMsg->MemorySize += size;
1696 pStubMsg->Buffer += size;
1698 if (pFormat[0] != RPC_FC_STRUCT)
1699 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1703 /***********************************************************************
1704 * NdrSimpleStructFree [RPCRT4.@]
1706 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1707 unsigned char *pMemory,
1708 PFORMAT_STRING pFormat)
1710 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1711 if (pFormat[0] != RPC_FC_STRUCT)
1712 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1716 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE *pStubMsg,
1717 PFORMAT_STRING pFormat)
1721 case RPC_FC_PSTRUCT:
1722 case RPC_FC_CSTRUCT:
1723 case RPC_FC_BOGUS_STRUCT:
1724 case RPC_FC_SMFARRAY:
1725 case RPC_FC_SMVARRAY:
1726 return *(const WORD*)&pFormat[2];
1727 case RPC_FC_USER_MARSHAL:
1728 return *(const WORD*)&pFormat[4];
1729 case RPC_FC_NON_ENCAPSULATED_UNION:
1731 if (pStubMsg->fHasNewCorrDesc)
1736 pFormat += *(const SHORT*)pFormat;
1737 return *(const SHORT*)pFormat;
1739 return sizeof(void *);
1741 FIXME("unhandled embedded type %02x\n", *pFormat);
1747 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1748 PFORMAT_STRING pFormat)
1750 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1754 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1758 return m(pStubMsg, pFormat);
1762 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1763 unsigned char *pMemory,
1764 PFORMAT_STRING pFormat,
1765 PFORMAT_STRING pPointer)
1767 PFORMAT_STRING desc;
1771 while (*pFormat != RPC_FC_END) {
1777 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
1778 memcpy(pStubMsg->Buffer, pMemory, 1);
1779 pStubMsg->Buffer += 1;
1785 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1786 memcpy(pStubMsg->Buffer, pMemory, 2);
1787 pStubMsg->Buffer += 2;
1793 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
1794 memcpy(pStubMsg->Buffer, pMemory, 4);
1795 pStubMsg->Buffer += 4;
1799 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1800 memcpy(pStubMsg->Buffer, pMemory, 8);
1801 pStubMsg->Buffer += 8;
1804 case RPC_FC_POINTER:
1806 unsigned char *saved_buffer;
1807 int pointer_buffer_mark_set = 0;
1808 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1809 saved_buffer = pStubMsg->Buffer;
1810 if (pStubMsg->PointerBufferMark)
1812 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1813 pStubMsg->PointerBufferMark = NULL;
1814 pointer_buffer_mark_set = 1;
1817 pStubMsg->Buffer += 4; /* for pointer ID */
1818 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
1819 if (pointer_buffer_mark_set)
1821 STD_OVERFLOW_CHECK(pStubMsg);
1822 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1823 pStubMsg->Buffer = saved_buffer + 4;
1829 case RPC_FC_ALIGNM4:
1830 ALIGN_POINTER(pMemory, 4);
1832 case RPC_FC_ALIGNM8:
1833 ALIGN_POINTER(pMemory, 8);
1835 case RPC_FC_STRUCTPAD1:
1836 case RPC_FC_STRUCTPAD2:
1837 case RPC_FC_STRUCTPAD3:
1838 case RPC_FC_STRUCTPAD4:
1839 case RPC_FC_STRUCTPAD5:
1840 case RPC_FC_STRUCTPAD6:
1841 case RPC_FC_STRUCTPAD7:
1842 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1844 case RPC_FC_EMBEDDED_COMPLEX:
1845 pMemory += pFormat[1];
1847 desc = pFormat + *(const SHORT*)pFormat;
1848 size = EmbeddedComplexSize(pStubMsg, desc);
1849 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1850 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1853 /* for some reason interface pointers aren't generated as
1854 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
1855 * they still need the derefencing treatment that pointers are
1857 if (*desc == RPC_FC_IP)
1858 m(pStubMsg, *(unsigned char **)pMemory, desc);
1860 m(pStubMsg, pMemory, desc);
1862 else FIXME("no marshaller for embedded type %02x\n", *desc);
1869 FIXME("unhandled format 0x%02x\n", *pFormat);
1877 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1878 unsigned char *pMemory,
1879 PFORMAT_STRING pFormat,
1880 PFORMAT_STRING pPointer)
1882 PFORMAT_STRING desc;
1886 while (*pFormat != RPC_FC_END) {
1892 safe_buffer_copy(pStubMsg, pMemory, 1);
1893 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
1899 safe_buffer_copy(pStubMsg, pMemory, 2);
1900 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1906 safe_buffer_copy(pStubMsg, pMemory, 4);
1907 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
1911 safe_buffer_copy(pStubMsg, pMemory, 8);
1912 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1915 case RPC_FC_POINTER:
1917 unsigned char *saved_buffer;
1918 int pointer_buffer_mark_set = 0;
1919 TRACE("pointer => %p\n", pMemory);
1920 ALIGN_POINTER(pStubMsg->Buffer, 4);
1921 saved_buffer = pStubMsg->Buffer;
1922 if (pStubMsg->PointerBufferMark)
1924 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1925 pStubMsg->PointerBufferMark = NULL;
1926 pointer_buffer_mark_set = 1;
1929 pStubMsg->Buffer += 4; /* for pointer ID */
1931 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, pPointer, TRUE);
1932 if (pointer_buffer_mark_set)
1934 STD_OVERFLOW_CHECK(pStubMsg);
1935 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1936 pStubMsg->Buffer = saved_buffer + 4;
1942 case RPC_FC_ALIGNM4:
1943 ALIGN_POINTER(pMemory, 4);
1945 case RPC_FC_ALIGNM8:
1946 ALIGN_POINTER(pMemory, 8);
1948 case RPC_FC_STRUCTPAD1:
1949 case RPC_FC_STRUCTPAD2:
1950 case RPC_FC_STRUCTPAD3:
1951 case RPC_FC_STRUCTPAD4:
1952 case RPC_FC_STRUCTPAD5:
1953 case RPC_FC_STRUCTPAD6:
1954 case RPC_FC_STRUCTPAD7:
1955 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1957 case RPC_FC_EMBEDDED_COMPLEX:
1958 pMemory += pFormat[1];
1960 desc = pFormat + *(const SHORT*)pFormat;
1961 size = EmbeddedComplexSize(pStubMsg, desc);
1962 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
1963 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1964 memset(pMemory, 0, size); /* just in case */
1967 /* for some reason interface pointers aren't generated as
1968 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
1969 * they still need the derefencing treatment that pointers are
1971 if (*desc == RPC_FC_IP)
1972 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
1974 m(pStubMsg, &pMemory, desc, FALSE);
1976 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
1983 FIXME("unhandled format %d\n", *pFormat);
1991 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1992 unsigned char *pMemory,
1993 PFORMAT_STRING pFormat,
1994 PFORMAT_STRING pPointer)
1996 PFORMAT_STRING desc;
2000 while (*pFormat != RPC_FC_END) {
2006 pStubMsg->BufferLength += 1;
2012 pStubMsg->BufferLength += 2;
2018 pStubMsg->BufferLength += 4;
2022 pStubMsg->BufferLength += 8;
2025 case RPC_FC_POINTER:
2026 if (!pStubMsg->IgnoreEmbeddedPointers)
2028 int saved_buffer_length = pStubMsg->BufferLength;
2029 pStubMsg->BufferLength = pStubMsg->PointerLength;
2030 pStubMsg->PointerLength = 0;
2031 if(!pStubMsg->BufferLength)
2032 ERR("BufferLength == 0??\n");
2033 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2034 pStubMsg->PointerLength = pStubMsg->BufferLength;
2035 pStubMsg->BufferLength = saved_buffer_length;
2037 pStubMsg->BufferLength += 4;
2041 case RPC_FC_ALIGNM4:
2042 ALIGN_POINTER(pMemory, 4);
2044 case RPC_FC_ALIGNM8:
2045 ALIGN_POINTER(pMemory, 8);
2047 case RPC_FC_STRUCTPAD1:
2048 case RPC_FC_STRUCTPAD2:
2049 case RPC_FC_STRUCTPAD3:
2050 case RPC_FC_STRUCTPAD4:
2051 case RPC_FC_STRUCTPAD5:
2052 case RPC_FC_STRUCTPAD6:
2053 case RPC_FC_STRUCTPAD7:
2054 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2056 case RPC_FC_EMBEDDED_COMPLEX:
2057 pMemory += pFormat[1];
2059 desc = pFormat + *(const SHORT*)pFormat;
2060 size = EmbeddedComplexSize(pStubMsg, desc);
2061 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2064 /* for some reason interface pointers aren't generated as
2065 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2066 * they still need the derefencing treatment that pointers are
2068 if (*desc == RPC_FC_IP)
2069 m(pStubMsg, *(unsigned char **)pMemory, desc);
2071 m(pStubMsg, pMemory, desc);
2073 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2080 FIXME("unhandled format 0x%02x\n", *pFormat);
2088 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2089 unsigned char *pMemory,
2090 PFORMAT_STRING pFormat,
2091 PFORMAT_STRING pPointer)
2093 PFORMAT_STRING desc;
2097 while (*pFormat != RPC_FC_END) {
2118 case RPC_FC_POINTER:
2119 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
2123 case RPC_FC_ALIGNM4:
2124 ALIGN_POINTER(pMemory, 4);
2126 case RPC_FC_ALIGNM8:
2127 ALIGN_POINTER(pMemory, 8);
2129 case RPC_FC_STRUCTPAD1:
2130 case RPC_FC_STRUCTPAD2:
2131 case RPC_FC_STRUCTPAD3:
2132 case RPC_FC_STRUCTPAD4:
2133 case RPC_FC_STRUCTPAD5:
2134 case RPC_FC_STRUCTPAD6:
2135 case RPC_FC_STRUCTPAD7:
2136 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2138 case RPC_FC_EMBEDDED_COMPLEX:
2139 pMemory += pFormat[1];
2141 desc = pFormat + *(const SHORT*)pFormat;
2142 size = EmbeddedComplexSize(pStubMsg, desc);
2143 m = NdrFreer[*desc & NDR_TABLE_MASK];
2146 /* for some reason interface pointers aren't generated as
2147 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2148 * they still need the derefencing treatment that pointers are
2150 if (*desc == RPC_FC_IP)
2151 m(pStubMsg, *(unsigned char **)pMemory, desc);
2153 m(pStubMsg, pMemory, desc);
2155 else FIXME("no freer for embedded type %02x\n", *desc);
2162 FIXME("unhandled format 0x%02x\n", *pFormat);
2170 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2171 PFORMAT_STRING pFormat)
2173 PFORMAT_STRING desc;
2174 unsigned long size = 0;
2176 while (*pFormat != RPC_FC_END) {
2183 pStubMsg->Buffer += 1;
2189 pStubMsg->Buffer += 2;
2195 pStubMsg->Buffer += 4;
2199 pStubMsg->Buffer += 8;
2201 case RPC_FC_POINTER:
2203 pStubMsg->Buffer += 4;
2204 if (!pStubMsg->IgnoreEmbeddedPointers)
2205 FIXME("embedded pointers\n");
2207 case RPC_FC_ALIGNM4:
2208 ALIGN_LENGTH(size, 4);
2209 ALIGN_POINTER(pStubMsg->Buffer, 4);
2211 case RPC_FC_ALIGNM8:
2212 ALIGN_LENGTH(size, 8);
2213 ALIGN_POINTER(pStubMsg->Buffer, 8);
2215 case RPC_FC_STRUCTPAD1:
2216 case RPC_FC_STRUCTPAD2:
2217 case RPC_FC_STRUCTPAD3:
2218 case RPC_FC_STRUCTPAD4:
2219 case RPC_FC_STRUCTPAD5:
2220 case RPC_FC_STRUCTPAD6:
2221 case RPC_FC_STRUCTPAD7:
2222 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2224 case RPC_FC_EMBEDDED_COMPLEX:
2227 desc = pFormat + *(const SHORT*)pFormat;
2228 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2234 FIXME("unhandled format 0x%02x\n", *pFormat);
2242 /***********************************************************************
2243 * NdrComplexStructMarshall [RPCRT4.@]
2245 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2246 unsigned char *pMemory,
2247 PFORMAT_STRING pFormat)
2249 PFORMAT_STRING conf_array = NULL;
2250 PFORMAT_STRING pointer_desc = NULL;
2251 unsigned char *OldMemory = pStubMsg->Memory;
2252 int pointer_buffer_mark_set = 0;
2254 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2256 if (!pStubMsg->PointerBufferMark)
2258 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2259 /* save buffer length */
2260 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2262 /* get the buffer pointer after complex array data, but before
2264 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2265 pStubMsg->IgnoreEmbeddedPointers = 1;
2266 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2267 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2269 /* save it for use by embedded pointer code later */
2270 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2271 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
2272 pointer_buffer_mark_set = 1;
2274 /* restore the original buffer length */
2275 pStubMsg->BufferLength = saved_buffer_length;
2278 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2281 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2283 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2286 pStubMsg->Memory = pMemory;
2288 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2291 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2293 pStubMsg->Memory = OldMemory;
2295 if (pointer_buffer_mark_set)
2297 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2298 pStubMsg->PointerBufferMark = NULL;
2301 STD_OVERFLOW_CHECK(pStubMsg);
2306 /***********************************************************************
2307 * NdrComplexStructUnmarshall [RPCRT4.@]
2309 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2310 unsigned char **ppMemory,
2311 PFORMAT_STRING pFormat,
2312 unsigned char fMustAlloc)
2314 unsigned size = *(const WORD*)(pFormat+2);
2315 PFORMAT_STRING conf_array = NULL;
2316 PFORMAT_STRING pointer_desc = NULL;
2317 unsigned char *pMemory;
2318 int pointer_buffer_mark_set = 0;
2320 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2322 if (!pStubMsg->PointerBufferMark)
2324 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2325 /* save buffer pointer */
2326 unsigned char *saved_buffer = pStubMsg->Buffer;
2328 /* get the buffer pointer after complex array data, but before
2330 pStubMsg->IgnoreEmbeddedPointers = 1;
2331 NdrComplexStructMemorySize(pStubMsg, pFormat);
2332 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2334 /* save it for use by embedded pointer code later */
2335 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2336 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
2337 pointer_buffer_mark_set = 1;
2339 /* restore the original buffer */
2340 pStubMsg->Buffer = saved_buffer;
2343 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2345 if (fMustAlloc || !*ppMemory)
2347 *ppMemory = NdrAllocate(pStubMsg, size);
2348 memset(*ppMemory, 0, size);
2352 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2354 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2357 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2360 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2362 if (pointer_buffer_mark_set)
2364 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2365 pStubMsg->PointerBufferMark = NULL;
2371 /***********************************************************************
2372 * NdrComplexStructBufferSize [RPCRT4.@]
2374 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2375 unsigned char *pMemory,
2376 PFORMAT_STRING pFormat)
2378 PFORMAT_STRING conf_array = NULL;
2379 PFORMAT_STRING pointer_desc = NULL;
2380 unsigned char *OldMemory = pStubMsg->Memory;
2381 int pointer_length_set = 0;
2383 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2385 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2387 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2389 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2390 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2392 /* get the buffer length after complex struct data, but before
2394 pStubMsg->IgnoreEmbeddedPointers = 1;
2395 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2396 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2398 /* save it for use by embedded pointer code later */
2399 pStubMsg->PointerLength = pStubMsg->BufferLength;
2400 pointer_length_set = 1;
2401 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
2403 /* restore the original buffer length */
2404 pStubMsg->BufferLength = saved_buffer_length;
2408 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2410 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2413 pStubMsg->Memory = pMemory;
2415 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2418 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2420 pStubMsg->Memory = OldMemory;
2422 if(pointer_length_set)
2424 pStubMsg->BufferLength = pStubMsg->PointerLength;
2425 pStubMsg->PointerLength = 0;
2430 /***********************************************************************
2431 * NdrComplexStructMemorySize [RPCRT4.@]
2433 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2434 PFORMAT_STRING pFormat)
2436 unsigned size = *(const WORD*)(pFormat+2);
2437 PFORMAT_STRING conf_array = NULL;
2438 PFORMAT_STRING pointer_desc = NULL;
2440 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2442 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2445 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2447 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2450 ComplexStructMemorySize(pStubMsg, pFormat);
2453 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2458 /***********************************************************************
2459 * NdrComplexStructFree [RPCRT4.@]
2461 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2462 unsigned char *pMemory,
2463 PFORMAT_STRING pFormat)
2465 PFORMAT_STRING conf_array = NULL;
2466 PFORMAT_STRING pointer_desc = NULL;
2467 unsigned char *OldMemory = pStubMsg->Memory;
2469 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2472 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2474 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2477 pStubMsg->Memory = pMemory;
2479 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2482 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2484 pStubMsg->Memory = OldMemory;
2487 /***********************************************************************
2488 * NdrConformantArrayMarshall [RPCRT4.@]
2490 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2491 unsigned char *pMemory,
2492 PFORMAT_STRING pFormat)
2494 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2495 unsigned char alignment = pFormat[1] + 1;
2497 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2498 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2500 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2502 WriteConformance(pStubMsg);
2504 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2506 size = safe_multiply(esize, pStubMsg->MaxCount);
2507 memcpy(pStubMsg->Buffer, pMemory, size);
2508 pStubMsg->BufferMark = pStubMsg->Buffer;
2509 pStubMsg->Buffer += size;
2511 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2513 STD_OVERFLOW_CHECK(pStubMsg);
2518 /***********************************************************************
2519 * NdrConformantArrayUnmarshall [RPCRT4.@]
2521 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2522 unsigned char **ppMemory,
2523 PFORMAT_STRING pFormat,
2524 unsigned char fMustAlloc)
2526 DWORD size, esize = *(const WORD*)(pFormat+2);
2527 unsigned char alignment = pFormat[1] + 1;
2529 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2530 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2532 pFormat = ReadConformance(pStubMsg, pFormat+4);
2534 size = safe_multiply(esize, pStubMsg->MaxCount);
2536 if (fMustAlloc || !*ppMemory)
2537 *ppMemory = NdrAllocate(pStubMsg, size);
2539 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2541 pStubMsg->BufferMark = pStubMsg->Buffer;
2542 safe_buffer_copy(pStubMsg, *ppMemory, size);
2544 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2549 /***********************************************************************
2550 * NdrConformantArrayBufferSize [RPCRT4.@]
2552 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2553 unsigned char *pMemory,
2554 PFORMAT_STRING pFormat)
2556 DWORD size, esize = *(const WORD*)(pFormat+2);
2557 unsigned char alignment = pFormat[1] + 1;
2559 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2560 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2562 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2564 SizeConformance(pStubMsg);
2566 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2568 size = safe_multiply(esize, pStubMsg->MaxCount);
2569 /* conformance value plus array */
2570 pStubMsg->BufferLength += size;
2572 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2575 /***********************************************************************
2576 * NdrConformantArrayMemorySize [RPCRT4.@]
2578 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2579 PFORMAT_STRING pFormat)
2581 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2582 unsigned char alignment = pFormat[1] + 1;
2584 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2585 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2587 pFormat = ReadConformance(pStubMsg, pFormat+4);
2588 size = safe_multiply(esize, pStubMsg->MaxCount);
2589 pStubMsg->MemorySize += size;
2591 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2592 pStubMsg->BufferMark = pStubMsg->Buffer;
2593 pStubMsg->Buffer += size;
2595 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2597 return pStubMsg->MemorySize;
2600 /***********************************************************************
2601 * NdrConformantArrayFree [RPCRT4.@]
2603 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2604 unsigned char *pMemory,
2605 PFORMAT_STRING pFormat)
2607 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2608 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2610 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2612 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2616 /***********************************************************************
2617 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2619 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2620 unsigned char* pMemory,
2621 PFORMAT_STRING pFormat )
2624 unsigned char alignment = pFormat[1] + 1;
2625 DWORD esize = *(const WORD*)(pFormat+2);
2627 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2629 if (pFormat[0] != RPC_FC_CVARRAY)
2631 ERR("invalid format type %x\n", pFormat[0]);
2632 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2636 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2637 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2639 WriteConformance(pStubMsg);
2640 WriteVariance(pStubMsg);
2642 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2644 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2646 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
2647 pStubMsg->BufferMark = pStubMsg->Buffer;
2648 pStubMsg->Buffer += bufsize;
2650 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2652 STD_OVERFLOW_CHECK(pStubMsg);
2658 /***********************************************************************
2659 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2661 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2662 unsigned char** ppMemory,
2663 PFORMAT_STRING pFormat,
2664 unsigned char fMustAlloc )
2666 ULONG bufsize, memsize;
2667 unsigned char alignment = pFormat[1] + 1;
2668 DWORD esize = *(const WORD*)(pFormat+2);
2670 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2672 if (pFormat[0] != RPC_FC_CVARRAY)
2674 ERR("invalid format type %x\n", pFormat[0]);
2675 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2679 pFormat = ReadConformance(pStubMsg, pFormat+4);
2680 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2682 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2684 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2685 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2687 if (!*ppMemory || fMustAlloc)
2688 *ppMemory = NdrAllocate(pStubMsg, memsize);
2689 safe_buffer_copy(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize);
2691 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2697 /***********************************************************************
2698 * NdrConformantVaryingArrayFree [RPCRT4.@]
2700 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2701 unsigned char* pMemory,
2702 PFORMAT_STRING pFormat )
2704 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2706 if (pFormat[0] != RPC_FC_CVARRAY)
2708 ERR("invalid format type %x\n", pFormat[0]);
2709 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2713 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2714 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2716 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2720 /***********************************************************************
2721 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2723 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2724 unsigned char* pMemory, PFORMAT_STRING pFormat )
2726 unsigned char alignment = pFormat[1] + 1;
2727 DWORD esize = *(const WORD*)(pFormat+2);
2729 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2731 if (pFormat[0] != RPC_FC_CVARRAY)
2733 ERR("invalid format type %x\n", pFormat[0]);
2734 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2739 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2740 /* compute length */
2741 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2743 SizeConformance(pStubMsg);
2744 SizeVariance(pStubMsg);
2746 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2748 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
2750 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2754 /***********************************************************************
2755 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2757 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2758 PFORMAT_STRING pFormat )
2765 /***********************************************************************
2766 * NdrComplexArrayMarshall [RPCRT4.@]
2768 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2769 unsigned char *pMemory,
2770 PFORMAT_STRING pFormat)
2772 ULONG i, count, def;
2773 BOOL variance_present;
2774 unsigned char alignment;
2775 int pointer_buffer_mark_set = 0;
2777 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2779 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2781 ERR("invalid format type %x\n", pFormat[0]);
2782 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2786 alignment = pFormat[1] + 1;
2788 if (!pStubMsg->PointerBufferMark)
2790 /* save buffer fields that may be changed by buffer sizer functions
2791 * and that may be needed later on */
2792 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2793 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2794 unsigned long saved_max_count = pStubMsg->MaxCount;
2795 unsigned long saved_offset = pStubMsg->Offset;
2796 unsigned long saved_actual_count = pStubMsg->ActualCount;
2798 /* get the buffer pointer after complex array data, but before
2800 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2801 pStubMsg->IgnoreEmbeddedPointers = 1;
2802 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
2803 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2805 /* save it for use by embedded pointer code later */
2806 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2807 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
2808 pointer_buffer_mark_set = 1;
2810 /* restore fields */
2811 pStubMsg->ActualCount = saved_actual_count;
2812 pStubMsg->Offset = saved_offset;
2813 pStubMsg->MaxCount = saved_max_count;
2814 pStubMsg->BufferLength = saved_buffer_length;
2817 def = *(const WORD*)&pFormat[2];
2820 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2821 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2823 variance_present = IsConformanceOrVariancePresent(pFormat);
2824 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2825 TRACE("variance = %d\n", pStubMsg->ActualCount);
2827 WriteConformance(pStubMsg);
2828 if (variance_present)
2829 WriteVariance(pStubMsg);
2831 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2833 count = pStubMsg->ActualCount;
2834 for (i = 0; i < count; i++)
2835 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2837 STD_OVERFLOW_CHECK(pStubMsg);
2839 if (pointer_buffer_mark_set)
2841 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2842 pStubMsg->PointerBufferMark = NULL;
2848 /***********************************************************************
2849 * NdrComplexArrayUnmarshall [RPCRT4.@]
2851 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2852 unsigned char **ppMemory,
2853 PFORMAT_STRING pFormat,
2854 unsigned char fMustAlloc)
2856 ULONG i, count, size;
2857 unsigned char alignment;
2858 unsigned char *pMemory;
2859 unsigned char *saved_buffer;
2860 int pointer_buffer_mark_set = 0;
2861 int saved_ignore_embedded;
2863 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2865 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2867 ERR("invalid format type %x\n", pFormat[0]);
2868 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2872 alignment = pFormat[1] + 1;
2874 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2875 /* save buffer pointer */
2876 saved_buffer = pStubMsg->Buffer;
2877 /* get the buffer pointer after complex array data, but before
2879 pStubMsg->IgnoreEmbeddedPointers = 1;
2880 pStubMsg->MemorySize = 0;
2881 NdrComplexArrayMemorySize(pStubMsg, pFormat);
2882 size = pStubMsg->MemorySize;
2883 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2885 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
2886 if (!pStubMsg->PointerBufferMark)
2888 /* save it for use by embedded pointer code later */
2889 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2890 pointer_buffer_mark_set = 1;
2892 /* restore the original buffer */
2893 pStubMsg->Buffer = saved_buffer;
2897 pFormat = ReadConformance(pStubMsg, pFormat);
2898 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2900 if (fMustAlloc || !*ppMemory)
2902 *ppMemory = NdrAllocate(pStubMsg, size);
2903 memset(*ppMemory, 0, size);
2906 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2908 pMemory = *ppMemory;
2909 count = pStubMsg->ActualCount;
2910 for (i = 0; i < count; i++)
2911 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
2913 if (pointer_buffer_mark_set)
2915 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2916 pStubMsg->PointerBufferMark = NULL;
2922 /***********************************************************************
2923 * NdrComplexArrayBufferSize [RPCRT4.@]
2925 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2926 unsigned char *pMemory,
2927 PFORMAT_STRING pFormat)
2929 ULONG i, count, def;
2930 unsigned char alignment;
2931 BOOL variance_present;
2932 int pointer_length_set = 0;
2934 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2936 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2938 ERR("invalid format type %x\n", pFormat[0]);
2939 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2943 alignment = pFormat[1] + 1;
2945 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2947 /* save buffer fields that may be changed by buffer sizer functions
2948 * and that may be needed later on */
2949 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2950 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2951 unsigned long saved_max_count = pStubMsg->MaxCount;
2952 unsigned long saved_offset = pStubMsg->Offset;
2953 unsigned long saved_actual_count = pStubMsg->ActualCount;
2955 /* get the buffer pointer after complex array data, but before
2957 pStubMsg->IgnoreEmbeddedPointers = 1;
2958 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
2959 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2961 /* save it for use by embedded pointer code later */
2962 pStubMsg->PointerLength = pStubMsg->BufferLength;
2963 pointer_length_set = 1;
2965 /* restore fields */
2966 pStubMsg->ActualCount = saved_actual_count;
2967 pStubMsg->Offset = saved_offset;
2968 pStubMsg->MaxCount = saved_max_count;
2969 pStubMsg->BufferLength = saved_buffer_length;
2971 def = *(const WORD*)&pFormat[2];
2974 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2975 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2976 SizeConformance(pStubMsg);
2978 variance_present = IsConformanceOrVariancePresent(pFormat);
2979 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2980 TRACE("variance = %d\n", pStubMsg->ActualCount);
2982 if (variance_present)
2983 SizeVariance(pStubMsg);
2985 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2987 count = pStubMsg->ActualCount;
2988 for (i = 0; i < count; i++)
2989 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
2991 if(pointer_length_set)
2993 pStubMsg->BufferLength = pStubMsg->PointerLength;
2994 pStubMsg->PointerLength = 0;
2998 /***********************************************************************
2999 * NdrComplexArrayMemorySize [RPCRT4.@]
3001 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3002 PFORMAT_STRING pFormat)
3004 ULONG i, count, esize, SavedMemorySize, MemorySize;
3005 unsigned char alignment;
3006 unsigned char *Buffer;
3008 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3010 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3012 ERR("invalid format type %x\n", pFormat[0]);
3013 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3017 alignment = pFormat[1] + 1;
3021 pFormat = ReadConformance(pStubMsg, pFormat);
3022 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3024 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3026 SavedMemorySize = pStubMsg->MemorySize;
3028 Buffer = pStubMsg->Buffer;
3029 pStubMsg->MemorySize = 0;
3030 esize = ComplexStructMemorySize(pStubMsg, pFormat);
3031 pStubMsg->Buffer = Buffer;
3033 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
3035 count = pStubMsg->ActualCount;
3036 for (i = 0; i < count; i++)
3037 ComplexStructMemorySize(pStubMsg, pFormat);
3039 pStubMsg->MemorySize = SavedMemorySize;
3041 pStubMsg->MemorySize += MemorySize;
3045 /***********************************************************************
3046 * NdrComplexArrayFree [RPCRT4.@]
3048 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3049 unsigned char *pMemory,
3050 PFORMAT_STRING pFormat)
3052 ULONG i, count, def;
3054 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3056 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3058 ERR("invalid format type %x\n", pFormat[0]);
3059 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3063 def = *(const WORD*)&pFormat[2];
3066 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3067 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3069 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3070 TRACE("variance = %d\n", pStubMsg->ActualCount);
3072 count = pStubMsg->ActualCount;
3073 for (i = 0; i < count; i++)
3074 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
3077 static ULONG UserMarshalFlags(const MIDL_STUB_MESSAGE *pStubMsg)
3079 return MAKELONG(pStubMsg->dwDestContext,
3080 pStubMsg->RpcMsg->DataRepresentation);
3083 #define USER_MARSHAL_PTR_PREFIX \
3084 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3085 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3087 /***********************************************************************
3088 * NdrUserMarshalMarshall [RPCRT4.@]
3090 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3091 unsigned char *pMemory,
3092 PFORMAT_STRING pFormat)
3094 unsigned flags = pFormat[1];
3095 unsigned index = *(const WORD*)&pFormat[2];
3096 unsigned char *saved_buffer = NULL;
3097 ULONG uflag = UserMarshalFlags(pStubMsg);
3098 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3099 TRACE("index=%d\n", index);
3101 if (flags & USER_MARSHAL_POINTER)
3103 ALIGN_POINTER(pStubMsg->Buffer, 4);
3104 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
3105 pStubMsg->Buffer += 4;
3106 if (pStubMsg->PointerBufferMark)
3108 saved_buffer = pStubMsg->Buffer;
3109 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3110 pStubMsg->PointerBufferMark = NULL;
3112 ALIGN_POINTER(pStubMsg->Buffer, 8);
3115 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3118 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
3119 &uflag, pStubMsg->Buffer, pMemory);
3123 STD_OVERFLOW_CHECK(pStubMsg);
3124 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3125 pStubMsg->Buffer = saved_buffer;
3128 STD_OVERFLOW_CHECK(pStubMsg);
3133 /***********************************************************************
3134 * NdrUserMarshalUnmarshall [RPCRT4.@]
3136 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3137 unsigned char **ppMemory,
3138 PFORMAT_STRING pFormat,
3139 unsigned char fMustAlloc)
3141 unsigned flags = pFormat[1];
3142 unsigned index = *(const WORD*)&pFormat[2];
3143 DWORD memsize = *(const WORD*)&pFormat[4];
3144 unsigned char *saved_buffer = NULL;
3145 ULONG uflag = UserMarshalFlags(pStubMsg);
3146 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3147 TRACE("index=%d\n", index);
3149 if (flags & USER_MARSHAL_POINTER)
3151 ALIGN_POINTER(pStubMsg->Buffer, 4);
3152 /* skip pointer prefix */
3153 pStubMsg->Buffer += 4;
3154 if (pStubMsg->PointerBufferMark)
3156 saved_buffer = pStubMsg->Buffer;
3157 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3158 pStubMsg->PointerBufferMark = NULL;
3160 ALIGN_POINTER(pStubMsg->Buffer, 8);
3163 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3165 if (fMustAlloc || !*ppMemory)
3166 *ppMemory = NdrAllocate(pStubMsg, memsize);
3169 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
3170 &uflag, pStubMsg->Buffer, *ppMemory);
3174 STD_OVERFLOW_CHECK(pStubMsg);
3175 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3176 pStubMsg->Buffer = saved_buffer;
3182 /***********************************************************************
3183 * NdrUserMarshalBufferSize [RPCRT4.@]
3185 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3186 unsigned char *pMemory,
3187 PFORMAT_STRING pFormat)
3189 unsigned flags = pFormat[1];
3190 unsigned index = *(const WORD*)&pFormat[2];
3191 DWORD bufsize = *(const WORD*)&pFormat[6];
3192 ULONG uflag = UserMarshalFlags(pStubMsg);
3193 unsigned long saved_buffer_length = 0;
3194 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3195 TRACE("index=%d\n", index);
3197 if (flags & USER_MARSHAL_POINTER)
3199 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3200 /* skip pointer prefix */
3201 pStubMsg->BufferLength += 4;
3202 if (pStubMsg->IgnoreEmbeddedPointers)
3204 if (pStubMsg->PointerLength)
3206 saved_buffer_length = pStubMsg->BufferLength;
3207 pStubMsg->BufferLength = pStubMsg->PointerLength;
3208 pStubMsg->PointerLength = 0;
3210 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
3213 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
3216 TRACE("size=%d\n", bufsize);
3217 pStubMsg->BufferLength += bufsize;
3220 pStubMsg->BufferLength =
3221 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
3222 &uflag, pStubMsg->BufferLength, pMemory);
3224 if (saved_buffer_length)
3226 pStubMsg->PointerLength = pStubMsg->BufferLength;
3227 pStubMsg->BufferLength = saved_buffer_length;
3232 /***********************************************************************
3233 * NdrUserMarshalMemorySize [RPCRT4.@]
3235 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3236 PFORMAT_STRING pFormat)
3238 unsigned flags = pFormat[1];
3239 unsigned index = *(const WORD*)&pFormat[2];
3240 DWORD memsize = *(const WORD*)&pFormat[4];
3241 DWORD bufsize = *(const WORD*)&pFormat[6];
3243 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3244 TRACE("index=%d\n", index);
3246 pStubMsg->MemorySize += memsize;
3248 if (flags & USER_MARSHAL_POINTER)
3250 ALIGN_POINTER(pStubMsg->Buffer, 4);
3251 /* skip pointer prefix */
3252 pStubMsg->Buffer += 4;
3253 if (pStubMsg->IgnoreEmbeddedPointers)
3254 return pStubMsg->MemorySize;
3255 ALIGN_POINTER(pStubMsg->Buffer, 8);
3258 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3261 FIXME("not implemented for varying buffer size\n");
3263 pStubMsg->Buffer += bufsize;
3265 return pStubMsg->MemorySize;
3268 /***********************************************************************
3269 * NdrUserMarshalFree [RPCRT4.@]
3271 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
3272 unsigned char *pMemory,
3273 PFORMAT_STRING pFormat)
3275 /* unsigned flags = pFormat[1]; */
3276 unsigned index = *(const WORD*)&pFormat[2];
3277 ULONG uflag = UserMarshalFlags(pStubMsg);
3278 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3279 TRACE("index=%d\n", index);
3281 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
3285 /***********************************************************************
3286 * NdrClearOutParameters [RPCRT4.@]
3288 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
3289 PFORMAT_STRING pFormat,
3292 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
3295 /***********************************************************************
3296 * NdrConvert [RPCRT4.@]
3298 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
3300 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
3301 /* FIXME: since this stub doesn't do any converting, the proper behavior
3302 is to raise an exception */
3305 /***********************************************************************
3306 * NdrConvert2 [RPCRT4.@]
3308 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
3310 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3311 pStubMsg, pFormat, NumberParams);
3312 /* FIXME: since this stub doesn't do any converting, the proper behavior
3313 is to raise an exception */
3316 #include "pshpack1.h"
3317 typedef struct _NDR_CSTRUCT_FORMAT
3320 unsigned char alignment;
3321 unsigned short memory_size;
3322 short offset_to_array_description;
3323 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
3324 #include "poppack.h"
3326 /***********************************************************************
3327 * NdrConformantStructMarshall [RPCRT4.@]
3329 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3330 unsigned char *pMemory,
3331 PFORMAT_STRING pFormat)
3333 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3334 PFORMAT_STRING pCArrayFormat;
3335 ULONG esize, bufsize;
3337 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3339 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3340 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3342 ERR("invalid format type %x\n", pCStructFormat->type);
3343 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3347 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3348 pCStructFormat->offset_to_array_description;
3349 if (*pCArrayFormat != RPC_FC_CARRAY)
3351 ERR("invalid array format type %x\n", pCStructFormat->type);
3352 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3355 esize = *(const WORD*)(pCArrayFormat+2);
3357 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3358 pCArrayFormat + 4, 0);
3360 WriteConformance(pStubMsg);
3362 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3364 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3366 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3367 /* copy constant sized part of struct */
3368 pStubMsg->BufferMark = pStubMsg->Buffer;
3369 memcpy(pStubMsg->Buffer, pMemory, pCStructFormat->memory_size + bufsize);
3370 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
3372 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3373 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3375 STD_OVERFLOW_CHECK(pStubMsg);
3380 /***********************************************************************
3381 * NdrConformantStructUnmarshall [RPCRT4.@]
3383 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3384 unsigned char **ppMemory,
3385 PFORMAT_STRING pFormat,
3386 unsigned char fMustAlloc)
3388 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3389 PFORMAT_STRING pCArrayFormat;
3390 ULONG esize, bufsize;
3392 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3394 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3395 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3397 ERR("invalid format type %x\n", pCStructFormat->type);
3398 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3401 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3402 pCStructFormat->offset_to_array_description;
3403 if (*pCArrayFormat != RPC_FC_CARRAY)
3405 ERR("invalid array format type %x\n", pCStructFormat->type);
3406 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3409 esize = *(const WORD*)(pCArrayFormat+2);
3411 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3413 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3415 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3417 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3418 /* work out how much memory to allocate if we need to do so */
3419 if (!*ppMemory || fMustAlloc)
3421 SIZE_T size = pCStructFormat->memory_size + bufsize;
3422 *ppMemory = NdrAllocate(pStubMsg, size);
3425 /* now copy the data */
3426 pStubMsg->BufferMark = pStubMsg->Buffer;
3427 safe_buffer_copy(pStubMsg, *ppMemory, pCStructFormat->memory_size + bufsize);
3429 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3430 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3435 /***********************************************************************
3436 * NdrConformantStructBufferSize [RPCRT4.@]
3438 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3439 unsigned char *pMemory,
3440 PFORMAT_STRING pFormat)
3442 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3443 PFORMAT_STRING pCArrayFormat;
3446 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3448 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3449 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3451 ERR("invalid format type %x\n", pCStructFormat->type);
3452 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3455 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3456 pCStructFormat->offset_to_array_description;
3457 if (*pCArrayFormat != RPC_FC_CARRAY)
3459 ERR("invalid array format type %x\n", pCStructFormat->type);
3460 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3463 esize = *(const WORD*)(pCArrayFormat+2);
3465 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
3466 SizeConformance(pStubMsg);
3468 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
3470 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3472 pStubMsg->BufferLength += pCStructFormat->memory_size +
3473 safe_multiply(pStubMsg->MaxCount, esize);
3475 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3476 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3479 /***********************************************************************
3480 * NdrConformantStructMemorySize [RPCRT4.@]
3482 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3483 PFORMAT_STRING pFormat)
3489 /***********************************************************************
3490 * NdrConformantStructFree [RPCRT4.@]
3492 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3493 unsigned char *pMemory,
3494 PFORMAT_STRING pFormat)
3499 /***********************************************************************
3500 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3502 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3503 unsigned char *pMemory,
3504 PFORMAT_STRING pFormat)
3506 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3507 PFORMAT_STRING pCVArrayFormat;
3508 ULONG esize, bufsize;
3510 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3512 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3513 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3515 ERR("invalid format type %x\n", pCVStructFormat->type);
3516 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3520 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3521 pCVStructFormat->offset_to_array_description;
3522 switch (*pCVArrayFormat)
3524 case RPC_FC_CVARRAY:
3525 esize = *(const WORD*)(pCVArrayFormat+2);
3527 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3528 pCVArrayFormat + 4, 0);
3529 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3532 case RPC_FC_C_CSTRING:
3533 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3534 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3535 esize = sizeof(char);
3536 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3537 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3538 pCVArrayFormat + 2, 0);
3540 pStubMsg->MaxCount = pStubMsg->ActualCount;
3542 case RPC_FC_C_WSTRING:
3543 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3544 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3545 esize = sizeof(WCHAR);
3546 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3547 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3548 pCVArrayFormat + 2, 0);
3550 pStubMsg->MaxCount = pStubMsg->ActualCount;
3553 ERR("invalid array format type %x\n", *pCVArrayFormat);
3554 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3558 WriteConformance(pStubMsg);
3560 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3562 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3564 /* write constant sized part */
3565 pStubMsg->BufferMark = pStubMsg->Buffer;
3566 memcpy(pStubMsg->Buffer, pMemory, pCVStructFormat->memory_size);
3567 pStubMsg->Buffer += pCVStructFormat->memory_size;
3569 WriteVariance(pStubMsg);
3571 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3573 /* write array part */
3574 memcpy(pStubMsg->Buffer, pMemory + pCVStructFormat->memory_size, bufsize);
3575 pStubMsg->Buffer += bufsize;
3577 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3579 STD_OVERFLOW_CHECK(pStubMsg);
3584 /***********************************************************************
3585 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3587 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3588 unsigned char **ppMemory,
3589 PFORMAT_STRING pFormat,
3590 unsigned char fMustAlloc)
3592 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3593 PFORMAT_STRING pCVArrayFormat;
3594 ULONG esize, bufsize;
3595 unsigned char cvarray_type;
3597 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3599 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3600 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3602 ERR("invalid format type %x\n", pCVStructFormat->type);
3603 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3607 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3608 pCVStructFormat->offset_to_array_description;
3609 cvarray_type = *pCVArrayFormat;
3610 switch (cvarray_type)
3612 case RPC_FC_CVARRAY:
3613 esize = *(const WORD*)(pCVArrayFormat+2);
3614 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3616 case RPC_FC_C_CSTRING:
3617 esize = sizeof(char);
3618 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3619 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3621 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3623 case RPC_FC_C_WSTRING:
3624 esize = sizeof(WCHAR);
3625 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3626 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3628 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3631 ERR("invalid array format type %x\n", *pCVArrayFormat);
3632 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3636 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3638 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3640 /* work out how much memory to allocate if we need to do so */
3641 if (!*ppMemory || fMustAlloc)
3643 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3644 *ppMemory = NdrAllocate(pStubMsg, size);
3647 /* copy the constant data */
3648 pStubMsg->BufferMark = pStubMsg->Buffer;
3649 safe_buffer_copy(pStubMsg, *ppMemory, pCVStructFormat->memory_size);
3651 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3653 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3655 if ((cvarray_type == RPC_FC_C_CSTRING) ||
3656 (cvarray_type == RPC_FC_C_WSTRING))
3659 /* strings must always have null terminating bytes */
3660 if (bufsize < esize)
3662 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
3663 RpcRaiseException(RPC_S_INVALID_BOUND);
3666 for (i = bufsize - esize; i < bufsize; i++)
3667 if (pStubMsg->Buffer[i] != 0)
3669 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3670 i, pStubMsg->Buffer[i]);
3671 RpcRaiseException(RPC_S_INVALID_BOUND);
3676 /* copy the array data */
3677 safe_buffer_copy(pStubMsg, *ppMemory + pCVStructFormat->memory_size, bufsize);
3679 if (cvarray_type == RPC_FC_C_CSTRING)
3680 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3681 else if (cvarray_type == RPC_FC_C_WSTRING)
3682 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3684 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3689 /***********************************************************************
3690 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3692 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3693 unsigned char *pMemory,
3694 PFORMAT_STRING pFormat)
3696 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3697 PFORMAT_STRING pCVArrayFormat;
3700 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3702 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3703 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3705 ERR("invalid format type %x\n", pCVStructFormat->type);
3706 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3710 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3711 pCVStructFormat->offset_to_array_description;
3712 switch (*pCVArrayFormat)
3714 case RPC_FC_CVARRAY:
3715 esize = *(const WORD*)(pCVArrayFormat+2);
3717 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3718 pCVArrayFormat + 4, 0);
3719 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3722 case RPC_FC_C_CSTRING:
3723 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3724 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3725 esize = sizeof(char);
3726 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3727 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3728 pCVArrayFormat + 2, 0);
3730 pStubMsg->MaxCount = pStubMsg->ActualCount;
3732 case RPC_FC_C_WSTRING:
3733 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3734 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3735 esize = sizeof(WCHAR);
3736 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3737 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3738 pCVArrayFormat + 2, 0);
3740 pStubMsg->MaxCount = pStubMsg->ActualCount;
3743 ERR("invalid array format type %x\n", *pCVArrayFormat);
3744 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3748 SizeConformance(pStubMsg);
3750 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
3752 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3754 pStubMsg->BufferLength += pCVStructFormat->memory_size;
3755 SizeVariance(pStubMsg);
3756 pStubMsg->BufferLength += safe_multiply(pStubMsg->MaxCount, esize);
3758 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3761 /***********************************************************************
3762 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3764 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3765 PFORMAT_STRING pFormat)
3767 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3768 PFORMAT_STRING pCVArrayFormat;
3770 unsigned char cvarray_type;
3772 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3774 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3775 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3777 ERR("invalid format type %x\n", pCVStructFormat->type);
3778 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3782 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3783 pCVStructFormat->offset_to_array_description;
3784 cvarray_type = *pCVArrayFormat;
3785 switch (cvarray_type)
3787 case RPC_FC_CVARRAY:
3788 esize = *(const WORD*)(pCVArrayFormat+2);
3789 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3791 case RPC_FC_C_CSTRING:
3792 esize = sizeof(char);
3793 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3794 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3796 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3798 case RPC_FC_C_WSTRING:
3799 esize = sizeof(WCHAR);
3800 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3801 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3803 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3806 ERR("invalid array format type %x\n", *pCVArrayFormat);
3807 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3811 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3813 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3815 pStubMsg->Buffer += pCVStructFormat->memory_size;
3816 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3817 pStubMsg->Buffer += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->ActualCount);
3819 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3821 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3823 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3826 /***********************************************************************
3827 * NdrConformantVaryingStructFree [RPCRT4.@]
3829 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3830 unsigned char *pMemory,
3831 PFORMAT_STRING pFormat)
3833 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3834 PFORMAT_STRING pCVArrayFormat;
3837 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3839 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3840 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3842 ERR("invalid format type %x\n", pCVStructFormat->type);
3843 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3847 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3848 pCVStructFormat->offset_to_array_description;
3849 switch (*pCVArrayFormat)
3851 case RPC_FC_CVARRAY:
3852 esize = *(const WORD*)(pCVArrayFormat+2);
3854 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3855 pCVArrayFormat + 4, 0);
3856 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3859 case RPC_FC_C_CSTRING:
3860 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3861 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3862 esize = sizeof(char);
3863 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3864 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3865 pCVArrayFormat + 2, 0);
3867 pStubMsg->MaxCount = pStubMsg->ActualCount;
3869 case RPC_FC_C_WSTRING:
3870 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3871 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3872 esize = sizeof(WCHAR);
3873 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3874 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3875 pCVArrayFormat + 2, 0);
3877 pStubMsg->MaxCount = pStubMsg->ActualCount;
3880 ERR("invalid array format type %x\n", *pCVArrayFormat);
3881 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3885 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3887 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3890 #include "pshpack1.h"
3894 unsigned char alignment;
3895 unsigned short total_size;
3896 } NDR_SMFARRAY_FORMAT;
3901 unsigned char alignment;
3902 unsigned long total_size;
3903 } NDR_LGFARRAY_FORMAT;
3904 #include "poppack.h"
3906 /***********************************************************************
3907 * NdrFixedArrayMarshall [RPCRT4.@]
3909 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3910 unsigned char *pMemory,
3911 PFORMAT_STRING pFormat)
3913 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3914 unsigned long total_size;
3916 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3918 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3919 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3921 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3922 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3926 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3928 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3930 total_size = pSmFArrayFormat->total_size;
3931 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3935 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3936 total_size = pLgFArrayFormat->total_size;
3937 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3940 memcpy(pStubMsg->Buffer, pMemory, total_size);
3941 pStubMsg->BufferMark = pStubMsg->Buffer;
3942 pStubMsg->Buffer += total_size;
3944 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3949 /***********************************************************************
3950 * NdrFixedArrayUnmarshall [RPCRT4.@]
3952 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3953 unsigned char **ppMemory,
3954 PFORMAT_STRING pFormat,
3955 unsigned char fMustAlloc)
3957 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3958 unsigned long total_size;
3960 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3962 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3963 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3965 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3966 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3970 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3972 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3974 total_size = pSmFArrayFormat->total_size;
3975 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3979 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3980 total_size = pLgFArrayFormat->total_size;
3981 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3984 if (fMustAlloc || !*ppMemory)
3985 *ppMemory = NdrAllocate(pStubMsg, total_size);
3986 pStubMsg->BufferMark = pStubMsg->Buffer;
3987 safe_buffer_copy(pStubMsg, *ppMemory, total_size);
3989 pFormat = EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3994 /***********************************************************************
3995 * NdrFixedArrayBufferSize [RPCRT4.@]
3997 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3998 unsigned char *pMemory,
3999 PFORMAT_STRING pFormat)
4001 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4002 unsigned long total_size;
4004 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4006 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4007 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4009 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4010 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4014 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4016 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4018 total_size = pSmFArrayFormat->total_size;
4019 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4023 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4024 total_size = pLgFArrayFormat->total_size;
4025 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4027 pStubMsg->BufferLength += total_size;
4029 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4032 /***********************************************************************
4033 * NdrFixedArrayMemorySize [RPCRT4.@]
4035 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4036 PFORMAT_STRING pFormat)
4038 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4041 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4043 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4044 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4046 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4047 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4051 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4053 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4055 total_size = pSmFArrayFormat->total_size;
4056 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4060 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4061 total_size = pLgFArrayFormat->total_size;
4062 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4064 pStubMsg->BufferMark = pStubMsg->Buffer;
4065 pStubMsg->Buffer += total_size;
4066 pStubMsg->MemorySize += total_size;
4068 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4073 /***********************************************************************
4074 * NdrFixedArrayFree [RPCRT4.@]
4076 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4077 unsigned char *pMemory,
4078 PFORMAT_STRING pFormat)
4080 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4082 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4084 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4085 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4087 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4088 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4092 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4093 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4096 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4097 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4100 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4103 /***********************************************************************
4104 * NdrVaryingArrayMarshall [RPCRT4.@]
4106 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4107 unsigned char *pMemory,
4108 PFORMAT_STRING pFormat)
4110 unsigned char alignment;
4111 DWORD elements, esize;
4114 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4116 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4117 (pFormat[0] != RPC_FC_LGVARRAY))
4119 ERR("invalid format type %x\n", pFormat[0]);
4120 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4124 alignment = pFormat[1] + 1;
4126 if (pFormat[0] == RPC_FC_SMVARRAY)
4129 pFormat += sizeof(WORD);
4130 elements = *(const WORD*)pFormat;
4131 pFormat += sizeof(WORD);
4136 pFormat += sizeof(DWORD);
4137 elements = *(const DWORD*)pFormat;
4138 pFormat += sizeof(DWORD);
4141 esize = *(const WORD*)pFormat;
4142 pFormat += sizeof(WORD);
4144 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4145 if ((pStubMsg->ActualCount > elements) ||
4146 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4148 RpcRaiseException(RPC_S_INVALID_BOUND);
4152 WriteVariance(pStubMsg);
4154 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4156 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4157 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
4158 pStubMsg->BufferMark = pStubMsg->Buffer;
4159 pStubMsg->Buffer += bufsize;
4161 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4163 STD_OVERFLOW_CHECK(pStubMsg);
4168 /***********************************************************************
4169 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4171 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4172 unsigned char **ppMemory,
4173 PFORMAT_STRING pFormat,
4174 unsigned char fMustAlloc)
4176 unsigned char alignment;
4177 DWORD size, elements, esize;
4180 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4182 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4183 (pFormat[0] != RPC_FC_LGVARRAY))
4185 ERR("invalid format type %x\n", pFormat[0]);
4186 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4190 alignment = pFormat[1] + 1;
4192 if (pFormat[0] == RPC_FC_SMVARRAY)
4195 size = *(const WORD*)pFormat;
4196 pFormat += sizeof(WORD);
4197 elements = *(const WORD*)pFormat;
4198 pFormat += sizeof(WORD);
4203 size = *(const DWORD*)pFormat;
4204 pFormat += sizeof(DWORD);
4205 elements = *(const DWORD*)pFormat;
4206 pFormat += sizeof(DWORD);
4209 esize = *(const WORD*)pFormat;
4210 pFormat += sizeof(WORD);
4212 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4214 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4216 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4218 if (!*ppMemory || fMustAlloc)
4219 *ppMemory = NdrAllocate(pStubMsg, size);
4220 safe_buffer_copy(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize);
4222 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
4227 /***********************************************************************
4228 * NdrVaryingArrayBufferSize [RPCRT4.@]
4230 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4231 unsigned char *pMemory,
4232 PFORMAT_STRING pFormat)
4234 unsigned char alignment;
4235 DWORD elements, esize;
4237 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4239 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4240 (pFormat[0] != RPC_FC_LGVARRAY))
4242 ERR("invalid format type %x\n", pFormat[0]);
4243 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4247 alignment = pFormat[1] + 1;
4249 if (pFormat[0] == RPC_FC_SMVARRAY)
4252 pFormat += sizeof(WORD);
4253 elements = *(const WORD*)pFormat;
4254 pFormat += sizeof(WORD);
4259 pFormat += sizeof(DWORD);
4260 elements = *(const DWORD*)pFormat;
4261 pFormat += sizeof(DWORD);
4264 esize = *(const WORD*)pFormat;
4265 pFormat += sizeof(WORD);
4267 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4268 if ((pStubMsg->ActualCount > elements) ||
4269 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4271 RpcRaiseException(RPC_S_INVALID_BOUND);
4275 SizeVariance(pStubMsg);
4277 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4279 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
4281 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4284 /***********************************************************************
4285 * NdrVaryingArrayMemorySize [RPCRT4.@]
4287 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4288 PFORMAT_STRING pFormat)
4290 unsigned char alignment;
4291 DWORD size, elements, esize;
4293 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4295 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4296 (pFormat[0] != RPC_FC_LGVARRAY))
4298 ERR("invalid format type %x\n", pFormat[0]);
4299 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4303 alignment = pFormat[1] + 1;
4305 if (pFormat[0] == RPC_FC_SMVARRAY)
4308 size = *(const WORD*)pFormat;
4309 pFormat += sizeof(WORD);
4310 elements = *(const WORD*)pFormat;
4311 pFormat += sizeof(WORD);
4316 size = *(const DWORD*)pFormat;
4317 pFormat += sizeof(DWORD);
4318 elements = *(const DWORD*)pFormat;
4319 pFormat += sizeof(DWORD);
4322 esize = *(const WORD*)pFormat;
4323 pFormat += sizeof(WORD);
4325 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4327 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4329 pStubMsg->Buffer += safe_multiply(esize, pStubMsg->ActualCount);
4330 pStubMsg->MemorySize += size;
4332 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4334 return pStubMsg->MemorySize;
4337 /***********************************************************************
4338 * NdrVaryingArrayFree [RPCRT4.@]
4340 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4341 unsigned char *pMemory,
4342 PFORMAT_STRING pFormat)
4344 unsigned char alignment;
4347 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4349 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4350 (pFormat[0] != RPC_FC_LGVARRAY))
4352 ERR("invalid format type %x\n", pFormat[0]);
4353 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4357 alignment = pFormat[1] + 1;
4359 if (pFormat[0] == RPC_FC_SMVARRAY)
4362 pFormat += sizeof(WORD);
4363 elements = *(const WORD*)pFormat;
4364 pFormat += sizeof(WORD);
4369 pFormat += sizeof(DWORD);
4370 elements = *(const DWORD*)pFormat;
4371 pFormat += sizeof(DWORD);
4374 pFormat += sizeof(WORD);
4376 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4377 if ((pStubMsg->ActualCount > elements) ||
4378 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4380 RpcRaiseException(RPC_S_INVALID_BOUND);
4384 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4387 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
4395 return *(const UCHAR *)pMemory;
4400 return *(const USHORT *)pMemory;
4404 return *(const ULONG *)pMemory;
4406 FIXME("Unhandled base type: 0x%02x\n", fc);
4411 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4412 unsigned long discriminant,
4413 PFORMAT_STRING pFormat)
4415 unsigned short num_arms, arm, type;
4417 num_arms = *(const SHORT*)pFormat & 0x0fff;
4419 for(arm = 0; arm < num_arms; arm++)
4421 if(discriminant == *(const ULONG*)pFormat)
4429 type = *(const unsigned short*)pFormat;
4430 TRACE("type %04x\n", type);
4431 if(arm == num_arms) /* default arm extras */
4435 ERR("no arm for 0x%lx and no default case\n", discriminant);
4436 RpcRaiseException(RPC_S_INVALID_TAG);
4441 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
4448 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
4450 unsigned short type;
4454 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4458 type = *(const unsigned short*)pFormat;
4459 if((type & 0xff00) == 0x8000)
4461 unsigned char basetype = LOBYTE(type);
4462 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
4466 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4467 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
4470 unsigned char *saved_buffer = NULL;
4471 int pointer_buffer_mark_set = 0;
4478 ALIGN_POINTER(pStubMsg->Buffer, 4);
4479 saved_buffer = pStubMsg->Buffer;
4480 if (pStubMsg->PointerBufferMark)
4482 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4483 pStubMsg->PointerBufferMark = NULL;
4484 pointer_buffer_mark_set = 1;
4487 pStubMsg->Buffer += 4; /* for pointer ID */
4489 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
4490 if (pointer_buffer_mark_set)
4492 STD_OVERFLOW_CHECK(pStubMsg);
4493 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4494 pStubMsg->Buffer = saved_buffer + 4;
4498 m(pStubMsg, pMemory, desc);
4501 else FIXME("no marshaller for embedded type %02x\n", *desc);
4506 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4507 unsigned char **ppMemory,
4509 PFORMAT_STRING pFormat,
4510 unsigned char fMustAlloc)
4512 unsigned short type;
4516 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4520 type = *(const unsigned short*)pFormat;
4521 if((type & 0xff00) == 0x8000)
4523 unsigned char basetype = LOBYTE(type);
4524 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
4528 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4529 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
4532 unsigned char *saved_buffer = NULL;
4533 int pointer_buffer_mark_set = 0;
4540 **(void***)ppMemory = NULL;
4541 ALIGN_POINTER(pStubMsg->Buffer, 4);
4542 saved_buffer = pStubMsg->Buffer;
4543 if (pStubMsg->PointerBufferMark)
4545 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4546 pStubMsg->PointerBufferMark = NULL;
4547 pointer_buffer_mark_set = 1;
4550 pStubMsg->Buffer += 4; /* for pointer ID */
4552 if (saved_buffer + 4 > pStubMsg->BufferEnd)
4553 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4555 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, desc, fMustAlloc);
4556 if (pointer_buffer_mark_set)
4558 STD_OVERFLOW_CHECK(pStubMsg);
4559 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4560 pStubMsg->Buffer = saved_buffer + 4;
4564 m(pStubMsg, ppMemory, desc, fMustAlloc);
4567 else FIXME("no marshaller for embedded type %02x\n", *desc);
4572 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
4573 unsigned char *pMemory,
4575 PFORMAT_STRING pFormat)
4577 unsigned short type;
4581 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4585 type = *(const unsigned short*)pFormat;
4586 if((type & 0xff00) == 0x8000)
4588 unsigned char basetype = LOBYTE(type);
4589 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
4593 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4594 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
4603 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4604 pStubMsg->BufferLength += 4; /* for pointer ID */
4605 if (!pStubMsg->IgnoreEmbeddedPointers)
4607 int saved_buffer_length = pStubMsg->BufferLength;
4608 pStubMsg->BufferLength = pStubMsg->PointerLength;
4609 pStubMsg->PointerLength = 0;
4610 if(!pStubMsg->BufferLength)
4611 ERR("BufferLength == 0??\n");
4612 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
4613 pStubMsg->PointerLength = pStubMsg->BufferLength;
4614 pStubMsg->BufferLength = saved_buffer_length;
4618 m(pStubMsg, pMemory, desc);
4621 else FIXME("no buffersizer for embedded type %02x\n", *desc);
4625 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
4627 PFORMAT_STRING pFormat)
4629 unsigned short type, size;
4631 size = *(const unsigned short*)pFormat;
4632 pStubMsg->Memory += size;
4635 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4639 type = *(const unsigned short*)pFormat;
4640 if((type & 0xff00) == 0x8000)
4642 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
4646 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4647 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
4648 unsigned char *saved_buffer;
4657 ALIGN_POINTER(pStubMsg->Buffer, 4);
4658 saved_buffer = pStubMsg->Buffer;
4659 pStubMsg->Buffer += 4;
4660 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
4661 pStubMsg->MemorySize += 4;
4662 if (!pStubMsg->IgnoreEmbeddedPointers)
4663 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
4666 return m(pStubMsg, desc);
4669 else FIXME("no marshaller for embedded type %02x\n", *desc);
4672 TRACE("size %d\n", size);
4676 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
4677 unsigned char *pMemory,
4679 PFORMAT_STRING pFormat)
4681 unsigned short type;
4685 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4689 type = *(const unsigned short*)pFormat;
4690 if((type & 0xff00) != 0x8000)
4692 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4693 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
4702 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
4705 m(pStubMsg, pMemory, desc);
4708 else FIXME("no freer for embedded type %02x\n", *desc);
4712 /***********************************************************************
4713 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4715 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4716 unsigned char *pMemory,
4717 PFORMAT_STRING pFormat)
4719 unsigned char switch_type;
4720 unsigned char increment;
4723 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4726 switch_type = *pFormat & 0xf;
4727 increment = (*pFormat & 0xf0) >> 4;
4730 ALIGN_POINTER(pStubMsg->Buffer, increment);
4732 switch_value = get_discriminant(switch_type, pMemory);
4733 TRACE("got switch value 0x%x\n", switch_value);
4735 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
4736 pMemory += increment;
4738 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
4741 /***********************************************************************
4742 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4744 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4745 unsigned char **ppMemory,
4746 PFORMAT_STRING pFormat,
4747 unsigned char fMustAlloc)
4749 unsigned char switch_type;
4750 unsigned char increment;
4752 unsigned short size;
4753 unsigned char *pMemoryArm;
4755 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4758 switch_type = *pFormat & 0xf;
4759 increment = (*pFormat & 0xf0) >> 4;
4762 ALIGN_POINTER(pStubMsg->Buffer, increment);
4763 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
4764 TRACE("got switch value 0x%x\n", switch_value);
4766 size = *(const unsigned short*)pFormat + increment;
4767 if(!*ppMemory || fMustAlloc)
4768 *ppMemory = NdrAllocate(pStubMsg, size);
4770 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
4771 pMemoryArm = *ppMemory + increment;
4773 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
4776 /***********************************************************************
4777 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4779 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4780 unsigned char *pMemory,
4781 PFORMAT_STRING pFormat)
4783 unsigned char switch_type;
4784 unsigned char increment;
4787 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4790 switch_type = *pFormat & 0xf;
4791 increment = (*pFormat & 0xf0) >> 4;
4794 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
4795 switch_value = get_discriminant(switch_type, pMemory);
4796 TRACE("got switch value 0x%x\n", switch_value);
4798 /* Add discriminant size */
4799 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
4800 pMemory += increment;
4802 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
4805 /***********************************************************************
4806 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4808 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4809 PFORMAT_STRING pFormat)
4811 unsigned char switch_type;
4812 unsigned char increment;
4815 switch_type = *pFormat & 0xf;
4816 increment = (*pFormat & 0xf0) >> 4;
4819 ALIGN_POINTER(pStubMsg->Buffer, increment);
4820 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
4821 TRACE("got switch value 0x%x\n", switch_value);
4823 pStubMsg->Memory += increment;
4825 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
4828 /***********************************************************************
4829 * NdrEncapsulatedUnionFree [RPCRT4.@]
4831 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4832 unsigned char *pMemory,
4833 PFORMAT_STRING pFormat)
4835 unsigned char switch_type;
4836 unsigned char increment;
4839 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4842 switch_type = *pFormat & 0xf;
4843 increment = (*pFormat & 0xf0) >> 4;
4846 switch_value = get_discriminant(switch_type, pMemory);
4847 TRACE("got switch value 0x%x\n", switch_value);
4849 pMemory += increment;
4851 return union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
4854 /***********************************************************************
4855 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
4857 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4858 unsigned char *pMemory,
4859 PFORMAT_STRING pFormat)
4861 unsigned char switch_type;
4863 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4866 switch_type = *pFormat;
4869 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4870 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4871 /* Marshall discriminant */
4872 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4874 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
4877 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
4878 PFORMAT_STRING *ppFormat)
4880 long discriminant = 0;
4890 safe_buffer_copy(pStubMsg, &d, sizeof(d));
4899 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4900 safe_buffer_copy(pStubMsg, &d, sizeof(d));
4908 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4909 safe_buffer_copy(pStubMsg, &d, sizeof(d));
4914 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
4918 if (pStubMsg->fHasNewCorrDesc)
4922 return discriminant;
4925 /**********************************************************************
4926 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
4928 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4929 unsigned char **ppMemory,
4930 PFORMAT_STRING pFormat,
4931 unsigned char fMustAlloc)
4934 unsigned short size;
4936 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4939 /* Unmarshall discriminant */
4940 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4941 TRACE("unmarshalled discriminant %lx\n", discriminant);
4943 pFormat += *(const SHORT*)pFormat;
4945 size = *(const unsigned short*)pFormat;
4947 if(!*ppMemory || fMustAlloc)
4948 *ppMemory = NdrAllocate(pStubMsg, size);
4950 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
4953 /***********************************************************************
4954 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
4956 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4957 unsigned char *pMemory,
4958 PFORMAT_STRING pFormat)
4960 unsigned char switch_type;
4962 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4965 switch_type = *pFormat;
4968 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4969 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4970 /* Add discriminant size */
4971 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4973 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
4976 /***********************************************************************
4977 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
4979 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4980 PFORMAT_STRING pFormat)
4985 /* Unmarshall discriminant */
4986 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4987 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
4989 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
4992 /***********************************************************************
4993 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
4995 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4996 unsigned char *pMemory,
4997 PFORMAT_STRING pFormat)
4999 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5003 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5004 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5006 return union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5009 /***********************************************************************
5010 * NdrByteCountPointerMarshall [RPCRT4.@]
5012 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5013 unsigned char *pMemory,
5014 PFORMAT_STRING pFormat)
5020 /***********************************************************************
5021 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5023 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5024 unsigned char **ppMemory,
5025 PFORMAT_STRING pFormat,
5026 unsigned char fMustAlloc)
5032 /***********************************************************************
5033 * NdrByteCountPointerBufferSize [RPCRT4.@]
5035 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5036 unsigned char *pMemory,
5037 PFORMAT_STRING pFormat)
5042 /***********************************************************************
5043 * NdrByteCountPointerMemorySize [RPCRT4.@]
5045 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5046 PFORMAT_STRING pFormat)
5052 /***********************************************************************
5053 * NdrByteCountPointerFree [RPCRT4.@]
5055 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
5056 unsigned char *pMemory,
5057 PFORMAT_STRING pFormat)
5062 /***********************************************************************
5063 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5065 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5066 unsigned char *pMemory,
5067 PFORMAT_STRING pFormat)
5073 /***********************************************************************
5074 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5076 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5077 unsigned char **ppMemory,
5078 PFORMAT_STRING pFormat,
5079 unsigned char fMustAlloc)
5085 /***********************************************************************
5086 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5088 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5089 unsigned char *pMemory,
5090 PFORMAT_STRING pFormat)
5095 /***********************************************************************
5096 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5098 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5099 PFORMAT_STRING pFormat)
5105 /***********************************************************************
5106 * NdrXmitOrRepAsFree [RPCRT4.@]
5108 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
5109 unsigned char *pMemory,
5110 PFORMAT_STRING pFormat)
5115 #include "pshpack1.h"
5119 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
5123 #include "poppack.h"
5125 /***********************************************************************
5126 * NdrRangeMarshall [internal]
5128 unsigned char *WINAPI NdrRangeMarshall(
5129 PMIDL_STUB_MESSAGE pStubMsg,
5130 unsigned char *pMemory,
5131 PFORMAT_STRING pFormat)
5133 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5134 unsigned char base_type;
5136 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5138 if (pRange->type != RPC_FC_RANGE)
5140 ERR("invalid format type %x\n", pRange->type);
5141 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5145 base_type = pRange->flags_type & 0xf;
5147 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
5150 /***********************************************************************
5151 * NdrRangeUnmarshall
5153 unsigned char *WINAPI NdrRangeUnmarshall(
5154 PMIDL_STUB_MESSAGE pStubMsg,
5155 unsigned char **ppMemory,
5156 PFORMAT_STRING pFormat,
5157 unsigned char fMustAlloc)
5159 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5160 unsigned char base_type;
5162 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5164 if (pRange->type != RPC_FC_RANGE)
5166 ERR("invalid format type %x\n", pRange->type);
5167 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5170 base_type = pRange->flags_type & 0xf;
5172 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5173 base_type, pRange->low_value, pRange->high_value);
5175 #define RANGE_UNMARSHALL(type, format_spec) \
5178 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5179 if (fMustAlloc || !*ppMemory) \
5180 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5181 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5182 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5184 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5185 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5186 (type)pRange->high_value); \
5187 RpcRaiseException(RPC_S_INVALID_BOUND); \
5190 TRACE("*ppMemory: %p\n", *ppMemory); \
5191 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5192 pStubMsg->Buffer += sizeof(type); \
5199 RANGE_UNMARSHALL(UCHAR, "%d");
5200 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5204 RANGE_UNMARSHALL(CHAR, "%u");
5205 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5207 case RPC_FC_WCHAR: /* FIXME: valid? */
5209 RANGE_UNMARSHALL(USHORT, "%u");
5210 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5213 RANGE_UNMARSHALL(SHORT, "%d");
5214 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5217 RANGE_UNMARSHALL(LONG, "%d");
5218 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5221 RANGE_UNMARSHALL(ULONG, "%u");
5222 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5226 FIXME("Unhandled enum type\n");
5228 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
5233 ERR("invalid range base type: 0x%02x\n", base_type);
5234 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5240 /***********************************************************************
5241 * NdrRangeBufferSize [internal]
5243 void WINAPI NdrRangeBufferSize(
5244 PMIDL_STUB_MESSAGE pStubMsg,
5245 unsigned char *pMemory,
5246 PFORMAT_STRING pFormat)
5248 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5249 unsigned char base_type;
5251 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5253 if (pRange->type != RPC_FC_RANGE)
5255 ERR("invalid format type %x\n", pRange->type);
5256 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5258 base_type = pRange->flags_type & 0xf;
5260 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
5263 /***********************************************************************
5264 * NdrRangeMemorySize [internal]
5266 ULONG WINAPI NdrRangeMemorySize(
5267 PMIDL_STUB_MESSAGE pStubMsg,
5268 PFORMAT_STRING pFormat)
5270 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5271 unsigned char base_type;
5273 if (pRange->type != RPC_FC_RANGE)
5275 ERR("invalid format type %x\n", pRange->type);
5276 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5279 base_type = pRange->flags_type & 0xf;
5281 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
5284 /***********************************************************************
5285 * NdrRangeFree [internal]
5287 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
5288 unsigned char *pMemory,
5289 PFORMAT_STRING pFormat)
5291 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5296 /***********************************************************************
5297 * NdrBaseTypeMarshall [internal]
5299 static unsigned char *WINAPI NdrBaseTypeMarshall(
5300 PMIDL_STUB_MESSAGE pStubMsg,
5301 unsigned char *pMemory,
5302 PFORMAT_STRING pFormat)
5304 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5312 *(UCHAR *)pStubMsg->Buffer = *(UCHAR *)pMemory;
5313 pStubMsg->Buffer += sizeof(UCHAR);
5314 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
5319 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5320 *(USHORT *)pStubMsg->Buffer = *(USHORT *)pMemory;
5321 pStubMsg->Buffer += sizeof(USHORT);
5322 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
5326 case RPC_FC_ERROR_STATUS_T:
5328 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5329 *(ULONG *)pStubMsg->Buffer = *(ULONG *)pMemory;
5330 pStubMsg->Buffer += sizeof(ULONG);
5331 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
5334 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
5335 *(float *)pStubMsg->Buffer = *(float *)pMemory;
5336 pStubMsg->Buffer += sizeof(float);
5339 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
5340 *(double *)pStubMsg->Buffer = *(double *)pMemory;
5341 pStubMsg->Buffer += sizeof(double);
5344 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
5345 *(ULONGLONG *)pStubMsg->Buffer = *(ULONGLONG *)pMemory;
5346 pStubMsg->Buffer += sizeof(ULONGLONG);
5347 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
5350 /* only 16-bits on the wire, so do a sanity check */
5351 if (*(UINT *)pMemory > SHRT_MAX)
5352 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
5353 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5354 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
5355 pStubMsg->Buffer += sizeof(USHORT);
5356 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
5361 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5364 STD_OVERFLOW_CHECK(pStubMsg);
5366 /* FIXME: what is the correct return value? */
5370 /***********************************************************************
5371 * NdrBaseTypeUnmarshall [internal]
5373 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
5374 PMIDL_STUB_MESSAGE pStubMsg,
5375 unsigned char **ppMemory,
5376 PFORMAT_STRING pFormat,
5377 unsigned char fMustAlloc)
5379 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5381 #define BASE_TYPE_UNMARSHALL(type) \
5382 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5383 if (fMustAlloc || !*ppMemory) \
5384 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5385 TRACE("*ppMemory: %p\n", *ppMemory); \
5386 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5387 pStubMsg->Buffer += sizeof(type);
5395 BASE_TYPE_UNMARSHALL(UCHAR);
5396 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5401 BASE_TYPE_UNMARSHALL(USHORT);
5402 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5406 case RPC_FC_ERROR_STATUS_T:
5408 BASE_TYPE_UNMARSHALL(ULONG);
5409 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5412 BASE_TYPE_UNMARSHALL(float);
5413 TRACE("value: %f\n", **(float **)ppMemory);
5416 BASE_TYPE_UNMARSHALL(double);
5417 TRACE("value: %f\n", **(double **)ppMemory);
5420 BASE_TYPE_UNMARSHALL(ULONGLONG);
5421 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
5424 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5425 if (fMustAlloc || !*ppMemory)
5426 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
5427 TRACE("*ppMemory: %p\n", *ppMemory);
5428 /* 16-bits on the wire, but int in memory */
5429 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
5430 pStubMsg->Buffer += sizeof(USHORT);
5431 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
5436 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5438 #undef BASE_TYPE_UNMARSHALL
5440 /* FIXME: what is the correct return value? */
5445 /***********************************************************************
5446 * NdrBaseTypeBufferSize [internal]
5448 static void WINAPI NdrBaseTypeBufferSize(
5449 PMIDL_STUB_MESSAGE pStubMsg,
5450 unsigned char *pMemory,
5451 PFORMAT_STRING pFormat)
5453 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5461 pStubMsg->BufferLength += sizeof(UCHAR);
5467 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
5468 pStubMsg->BufferLength += sizeof(USHORT);
5473 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
5474 pStubMsg->BufferLength += sizeof(ULONG);
5477 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
5478 pStubMsg->BufferLength += sizeof(float);
5481 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
5482 pStubMsg->BufferLength += sizeof(double);
5485 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
5486 pStubMsg->BufferLength += sizeof(ULONGLONG);
5488 case RPC_FC_ERROR_STATUS_T:
5489 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
5490 pStubMsg->BufferLength += sizeof(error_status_t);
5495 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5499 /***********************************************************************
5500 * NdrBaseTypeMemorySize [internal]
5502 static ULONG WINAPI NdrBaseTypeMemorySize(
5503 PMIDL_STUB_MESSAGE pStubMsg,
5504 PFORMAT_STRING pFormat)
5512 pStubMsg->Buffer += sizeof(UCHAR);
5513 pStubMsg->MemorySize += sizeof(UCHAR);
5514 return sizeof(UCHAR);
5518 pStubMsg->Buffer += sizeof(USHORT);
5519 pStubMsg->MemorySize += sizeof(USHORT);
5520 return sizeof(USHORT);
5523 pStubMsg->Buffer += sizeof(ULONG);
5524 pStubMsg->MemorySize += sizeof(ULONG);
5525 return sizeof(ULONG);
5527 pStubMsg->Buffer += sizeof(float);
5528 pStubMsg->MemorySize += sizeof(float);
5529 return sizeof(float);
5531 pStubMsg->Buffer += sizeof(double);
5532 pStubMsg->MemorySize += sizeof(double);
5533 return sizeof(double);
5535 pStubMsg->Buffer += sizeof(ULONGLONG);
5536 pStubMsg->MemorySize += sizeof(ULONGLONG);
5537 return sizeof(ULONGLONG);
5538 case RPC_FC_ERROR_STATUS_T:
5539 pStubMsg->Buffer += sizeof(error_status_t);
5540 pStubMsg->MemorySize += sizeof(error_status_t);
5541 return sizeof(error_status_t);
5544 pStubMsg->Buffer += sizeof(INT);
5545 pStubMsg->MemorySize += sizeof(INT);
5548 pStubMsg->MemorySize += sizeof(void *);
5549 return sizeof(void *);
5551 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5556 /***********************************************************************
5557 * NdrBaseTypeFree [internal]
5559 static void WINAPI NdrBaseTypeFree(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 * NdrContextHandleBufferSize [internal]
5571 static void WINAPI NdrContextHandleBufferSize(
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);
5578 if (*pFormat != RPC_FC_BIND_CONTEXT)
5580 ERR("invalid format type %x\n", *pFormat);
5581 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5583 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5584 pStubMsg->BufferLength += cbNDRContext;
5587 /***********************************************************************
5588 * NdrContextHandleMarshall [internal]
5590 static unsigned char *WINAPI NdrContextHandleMarshall(
5591 PMIDL_STUB_MESSAGE pStubMsg,
5592 unsigned char *pMemory,
5593 PFORMAT_STRING pFormat)
5595 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5597 if (*pFormat != RPC_FC_BIND_CONTEXT)
5599 ERR("invalid format type %x\n", *pFormat);
5600 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5603 if (pFormat[1] & 0x80)
5604 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
5606 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
5611 /***********************************************************************
5612 * NdrContextHandleUnmarshall [internal]
5614 static unsigned char *WINAPI NdrContextHandleUnmarshall(
5615 PMIDL_STUB_MESSAGE pStubMsg,
5616 unsigned char **ppMemory,
5617 PFORMAT_STRING pFormat,
5618 unsigned char fMustAlloc)
5620 if (*pFormat != RPC_FC_BIND_CONTEXT)
5622 ERR("invalid format type %x\n", *pFormat);
5623 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5626 **(NDR_CCONTEXT **)ppMemory = NULL;
5627 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
5632 /***********************************************************************
5633 * NdrClientContextMarshall [RPCRT4.@]
5635 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5636 NDR_CCONTEXT ContextHandle,
5639 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
5641 ALIGN_POINTER(pStubMsg->Buffer, 4);
5643 /* FIXME: what does fCheck do? */
5644 NDRCContextMarshall(ContextHandle,
5647 pStubMsg->Buffer += cbNDRContext;
5650 /***********************************************************************
5651 * NdrClientContextUnmarshall [RPCRT4.@]
5653 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5654 NDR_CCONTEXT * pContextHandle,
5655 RPC_BINDING_HANDLE BindHandle)
5657 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
5659 ALIGN_POINTER(pStubMsg->Buffer, 4);
5661 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
5662 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5664 NDRCContextUnmarshall(pContextHandle,
5667 pStubMsg->RpcMsg->DataRepresentation);
5669 pStubMsg->Buffer += cbNDRContext;
5672 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5673 NDR_SCONTEXT ContextHandle,
5674 NDR_RUNDOWN RundownRoutine )
5676 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
5679 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
5681 FIXME("(%p): stub\n", pStubMsg);
5685 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
5686 unsigned char* pMemory,
5687 PFORMAT_STRING pFormat)
5689 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
5692 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
5693 PFORMAT_STRING pFormat)
5695 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
5699 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5700 NDR_SCONTEXT ContextHandle,
5701 NDR_RUNDOWN RundownRoutine,
5702 PFORMAT_STRING pFormat)
5704 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
5707 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5708 PFORMAT_STRING pFormat)
5710 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
5714 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
5716 typedef struct ndr_context_handle
5720 } ndr_context_handle;
5722 struct context_handle_entry
5726 RPC_BINDING_HANDLE handle;
5727 ndr_context_handle wire_data;
5730 static struct list context_handle_list = LIST_INIT(context_handle_list);
5732 static CRITICAL_SECTION ndr_context_cs;
5733 static CRITICAL_SECTION_DEBUG ndr_context_debug =
5735 0, 0, &ndr_context_cs,
5736 { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
5737 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
5739 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
5741 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
5743 struct context_handle_entry *che = (struct context_handle_entry*) CContext;
5745 if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
5750 static struct context_handle_entry *context_entry_from_guid(LPCGUID uuid)
5752 struct context_handle_entry *che;
5753 LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
5754 if (IsEqualGUID(&che->wire_data.uuid, uuid))
5759 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
5761 struct context_handle_entry *che;
5762 RPC_BINDING_HANDLE handle = NULL;
5764 TRACE("%p\n", CContext);
5766 EnterCriticalSection(&ndr_context_cs);
5767 che = get_context_entry(CContext);
5769 handle = che->handle;
5770 LeaveCriticalSection(&ndr_context_cs);
5773 RpcRaiseException(ERROR_INVALID_HANDLE);
5777 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
5779 struct context_handle_entry *che;
5781 TRACE("%p %p\n", CContext, pBuff);
5785 EnterCriticalSection(&ndr_context_cs);
5786 che = get_context_entry(CContext);
5787 memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
5788 LeaveCriticalSection(&ndr_context_cs);
5792 ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
5793 wire_data->attributes = 0;
5794 wire_data->uuid = GUID_NULL;
5798 /***********************************************************************
5799 * RpcSmDestroyClientContext [RPCRT4.@]
5801 RPC_STATUS WINAPI RpcSmDestroyClientContext(void **ContextHandle)
5803 RPC_STATUS status = RPC_X_SS_CONTEXT_MISMATCH;
5804 struct context_handle_entry *che = NULL;
5806 TRACE("(%p)\n", ContextHandle);
5808 EnterCriticalSection(&ndr_context_cs);
5809 che = get_context_entry(*ContextHandle);
5810 *ContextHandle = NULL;
5814 list_remove(&che->entry);
5817 LeaveCriticalSection(&ndr_context_cs);
5821 RpcBindingFree(&che->handle);
5822 HeapFree(GetProcessHeap(), 0, che);
5828 /***********************************************************************
5829 * RpcSsDestroyClientContext [RPCRT4.@]
5831 void WINAPI RpcSsDestroyClientContext(void **ContextHandle)
5833 RPC_STATUS status = RpcSmDestroyClientContext(ContextHandle);
5834 if (status != RPC_S_OK)
5835 RpcRaiseException(status);
5838 static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
5839 RPC_BINDING_HANDLE hBinding,
5840 const ndr_context_handle *chi)
5842 struct context_handle_entry *che = NULL;
5844 /* a null UUID means we should free the context handle */
5845 if (IsEqualGUID(&chi->uuid, &GUID_NULL))
5849 che = get_context_entry(*CContext);
5851 return ERROR_INVALID_HANDLE;
5852 list_remove(&che->entry);
5853 RpcBindingFree(&che->handle);
5854 HeapFree(GetProcessHeap(), 0, che);
5858 /* if there's no existing entry matching the GUID, allocate one */
5859 else if (!(che = context_entry_from_guid(&chi->uuid)))
5861 che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
5863 return ERROR_NOT_ENOUGH_MEMORY;
5864 che->magic = NDR_CONTEXT_HANDLE_MAGIC;
5865 RpcBindingCopy(hBinding, &che->handle);
5866 list_add_tail(&context_handle_list, &che->entry);
5867 memcpy(&che->wire_data, chi, sizeof *chi);
5872 return ERROR_SUCCESS;
5875 /***********************************************************************
5876 * NDRCContextUnmarshall [RPCRT4.@]
5878 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
5879 RPC_BINDING_HANDLE hBinding,
5880 void *pBuff, ULONG DataRepresentation)
5884 TRACE("*%p=(%p) %p %p %08x\n",
5885 CContext, *CContext, hBinding, pBuff, DataRepresentation);
5887 EnterCriticalSection(&ndr_context_cs);
5888 r = ndr_update_context_handle(CContext, hBinding, pBuff);
5889 LeaveCriticalSection(&ndr_context_cs);
5891 RpcRaiseException(r);
5894 /***********************************************************************
5895 * NDRSContextMarshall [RPCRT4.@]
5897 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
5899 NDR_RUNDOWN userRunDownIn)
5901 FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn);
5904 /***********************************************************************
5905 * NDRSContextMarshallEx [RPCRT4.@]
5907 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
5908 NDR_SCONTEXT CContext,
5910 NDR_RUNDOWN userRunDownIn)
5912 FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn);
5915 /***********************************************************************
5916 * NDRSContextMarshall2 [RPCRT4.@]
5918 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
5919 NDR_SCONTEXT CContext,
5921 NDR_RUNDOWN userRunDownIn,
5922 void *CtxGuard, ULONG Flags)
5924 FIXME("(%p %p %p %p %p %u): stub\n",
5925 hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags);
5928 /***********************************************************************
5929 * NDRSContextUnmarshall [RPCRT4.@]
5931 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
5932 ULONG DataRepresentation)
5934 FIXME("(%p %08x): stub\n", pBuff, DataRepresentation);
5938 /***********************************************************************
5939 * NDRSContextUnmarshallEx [RPCRT4.@]
5941 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
5943 ULONG DataRepresentation)
5945 FIXME("(%p %p %08x): stub\n", hBinding, pBuff, DataRepresentation);
5949 /***********************************************************************
5950 * NDRSContextUnmarshall2 [RPCRT4.@]
5952 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
5954 ULONG DataRepresentation,
5955 void *CtxGuard, ULONG Flags)
5957 FIXME("(%p %p %08x %p %u): stub\n",
5958 hBinding, pBuff, DataRepresentation, CtxGuard, Flags);