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 pPointer = *(unsigned char***)pPointer;
982 TRACE("deref => %p\n", pPointer);
984 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
985 if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
986 else FIXME("no unmarshaller for data type=%02x\n", *desc);
988 if (type == RPC_FC_FP)
989 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
993 TRACE("pointer=%p\n", *pPointer);
996 /***********************************************************************
997 * PointerBufferSize [internal]
999 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1000 unsigned char *Pointer,
1001 PFORMAT_STRING pFormat)
1003 unsigned type = pFormat[0], attr = pFormat[1];
1004 PFORMAT_STRING desc;
1006 int pointer_needs_sizing;
1009 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1010 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1012 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1013 else desc = pFormat + *(const SHORT*)pFormat;
1016 case RPC_FC_RP: /* ref pointer (always non-null) */
1020 /* NULL pointer has no further representation */
1025 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1026 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1027 if (!pointer_needs_sizing)
1031 FIXME("unhandled ptr type=%02x\n", type);
1032 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1036 if (attr & RPC_FC_P_DEREF) {
1037 Pointer = *(unsigned char**)Pointer;
1038 TRACE("deref => %p\n", Pointer);
1041 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1042 if (m) m(pStubMsg, Pointer, desc);
1043 else FIXME("no buffersizer for data type=%02x\n", *desc);
1046 /***********************************************************************
1047 * PointerMemorySize [internal]
1049 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1050 unsigned char *Buffer,
1051 PFORMAT_STRING pFormat)
1053 unsigned type = pFormat[0], attr = pFormat[1];
1054 PFORMAT_STRING desc;
1057 FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat);
1058 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1060 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1061 else desc = pFormat + *(const SHORT*)pFormat;
1064 case RPC_FC_RP: /* ref pointer (always non-null) */
1067 FIXME("unhandled ptr type=%02x\n", type);
1068 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1071 if (attr & RPC_FC_P_DEREF) {
1075 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1076 if (m) m(pStubMsg, desc);
1077 else FIXME("no memorysizer for data type=%02x\n", *desc);
1082 /***********************************************************************
1083 * PointerFree [internal]
1085 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1086 unsigned char *Pointer,
1087 PFORMAT_STRING pFormat)
1089 unsigned type = pFormat[0], attr = pFormat[1];
1090 PFORMAT_STRING desc;
1093 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1094 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1095 if (attr & RPC_FC_P_DONTFREE) return;
1097 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1098 else desc = pFormat + *(const SHORT*)pFormat;
1100 if (!Pointer) return;
1102 if (type == RPC_FC_FP) {
1103 int pointer_needs_freeing = NdrFullPointerFree(
1104 pStubMsg->FullPtrXlatTables, Pointer);
1105 if (!pointer_needs_freeing)
1109 if (attr & RPC_FC_P_DEREF) {
1110 Pointer = *(unsigned char**)Pointer;
1111 TRACE("deref => %p\n", Pointer);
1114 m = NdrFreer[*desc & NDR_TABLE_MASK];
1115 if (m) m(pStubMsg, Pointer, desc);
1117 /* hmm... is this sensible?
1118 * perhaps we should check if the memory comes from NdrAllocate,
1119 * and deallocate only if so - checking if the pointer is between
1120 * BufferStart and BufferEnd is probably no good since the buffer
1121 * may be reallocated when the server wants to marshal the reply */
1123 case RPC_FC_BOGUS_STRUCT:
1124 case RPC_FC_BOGUS_ARRAY:
1125 case RPC_FC_USER_MARSHAL:
1127 case RPC_FC_CVARRAY:
1130 FIXME("unhandled data type=%02x\n", *desc);
1132 case RPC_FC_C_CSTRING:
1133 case RPC_FC_C_WSTRING:
1134 if (pStubMsg->ReuseBuffer) goto notfree;
1140 if (attr & RPC_FC_P_ONSTACK) {
1141 TRACE("not freeing stack ptr %p\n", Pointer);
1144 TRACE("freeing %p\n", Pointer);
1145 NdrFree(pStubMsg, Pointer);
1148 TRACE("not freeing %p\n", Pointer);
1151 /***********************************************************************
1152 * EmbeddedPointerMarshall
1154 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1155 unsigned char *pMemory,
1156 PFORMAT_STRING pFormat)
1158 unsigned char *Mark = pStubMsg->BufferMark;
1159 unsigned long Offset = pStubMsg->Offset;
1160 unsigned ofs, rep, count, stride, xofs;
1162 unsigned char *saved_buffer = NULL;
1164 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1166 if (*pFormat != RPC_FC_PP) return NULL;
1169 if (pStubMsg->PointerBufferMark)
1171 saved_buffer = pStubMsg->Buffer;
1172 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1173 pStubMsg->PointerBufferMark = NULL;
1176 while (pFormat[0] != RPC_FC_END) {
1177 switch (pFormat[0]) {
1179 FIXME("unknown repeat type %d\n", pFormat[0]);
1180 case RPC_FC_NO_REPEAT:
1188 case RPC_FC_FIXED_REPEAT:
1189 rep = *(const WORD*)&pFormat[2];
1190 stride = *(const WORD*)&pFormat[4];
1191 ofs = *(const WORD*)&pFormat[6];
1192 count = *(const WORD*)&pFormat[8];
1196 case RPC_FC_VARIABLE_REPEAT:
1197 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1198 stride = *(const WORD*)&pFormat[2];
1199 ofs = *(const WORD*)&pFormat[4];
1200 count = *(const WORD*)&pFormat[6];
1201 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1205 for (i = 0; i < rep; i++) {
1206 PFORMAT_STRING info = pFormat;
1207 unsigned char *membase = pMemory + ofs + (i * stride);
1208 unsigned char *bufbase = Mark + ofs + (i * stride);
1211 for (u=0; u<count; u++,info+=8) {
1212 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1213 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1214 unsigned char *saved_memory = pStubMsg->Memory;
1216 pStubMsg->Memory = pMemory;
1217 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1218 pStubMsg->Memory = saved_memory;
1221 pFormat += 8 * count;
1226 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1227 pStubMsg->Buffer = saved_buffer;
1230 STD_OVERFLOW_CHECK(pStubMsg);
1235 /***********************************************************************
1236 * EmbeddedPointerUnmarshall
1238 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1239 unsigned char **ppMemory,
1240 PFORMAT_STRING pFormat,
1241 unsigned char fMustAlloc)
1243 unsigned char *Mark = pStubMsg->BufferMark;
1244 unsigned long Offset = pStubMsg->Offset;
1245 unsigned ofs, rep, count, stride, xofs;
1247 unsigned char *saved_buffer = NULL;
1249 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1251 if (*pFormat != RPC_FC_PP) return NULL;
1254 if (pStubMsg->PointerBufferMark)
1256 saved_buffer = pStubMsg->Buffer;
1257 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1258 pStubMsg->PointerBufferMark = NULL;
1261 while (pFormat[0] != RPC_FC_END) {
1262 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1263 switch (pFormat[0]) {
1265 FIXME("unknown repeat type %d\n", pFormat[0]);
1266 case RPC_FC_NO_REPEAT:
1274 case RPC_FC_FIXED_REPEAT:
1275 rep = *(const WORD*)&pFormat[2];
1276 stride = *(const WORD*)&pFormat[4];
1277 ofs = *(const WORD*)&pFormat[6];
1278 count = *(const WORD*)&pFormat[8];
1282 case RPC_FC_VARIABLE_REPEAT:
1283 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1284 stride = *(const WORD*)&pFormat[2];
1285 ofs = *(const WORD*)&pFormat[4];
1286 count = *(const WORD*)&pFormat[6];
1287 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1291 /* ofs doesn't seem to matter in this context */
1292 for (i = 0; i < rep; i++) {
1293 PFORMAT_STRING info = pFormat;
1294 unsigned char *membase = *ppMemory + ofs + (i * stride);
1295 unsigned char *bufbase = Mark + ofs + (i * stride);
1298 for (u=0; u<count; u++,info+=8) {
1299 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1300 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1301 PointerUnmarshall(pStubMsg, bufptr, (unsigned char**)memptr, info+4, TRUE);
1304 pFormat += 8 * count;
1309 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1310 pStubMsg->Buffer = saved_buffer;
1316 /***********************************************************************
1317 * EmbeddedPointerBufferSize
1319 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1320 unsigned char *pMemory,
1321 PFORMAT_STRING pFormat)
1323 unsigned long Offset = pStubMsg->Offset;
1324 unsigned ofs, rep, count, stride, xofs;
1326 ULONG saved_buffer_length = 0;
1328 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1330 if (pStubMsg->IgnoreEmbeddedPointers) return;
1332 if (*pFormat != RPC_FC_PP) return;
1335 if (pStubMsg->PointerLength)
1337 saved_buffer_length = pStubMsg->BufferLength;
1338 pStubMsg->BufferLength = pStubMsg->PointerLength;
1339 pStubMsg->PointerLength = 0;
1342 while (pFormat[0] != RPC_FC_END) {
1343 switch (pFormat[0]) {
1345 FIXME("unknown repeat type %d\n", pFormat[0]);
1346 case RPC_FC_NO_REPEAT:
1354 case RPC_FC_FIXED_REPEAT:
1355 rep = *(const WORD*)&pFormat[2];
1356 stride = *(const WORD*)&pFormat[4];
1357 ofs = *(const WORD*)&pFormat[6];
1358 count = *(const WORD*)&pFormat[8];
1362 case RPC_FC_VARIABLE_REPEAT:
1363 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1364 stride = *(const WORD*)&pFormat[2];
1365 ofs = *(const WORD*)&pFormat[4];
1366 count = *(const WORD*)&pFormat[6];
1367 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1371 for (i = 0; i < rep; i++) {
1372 PFORMAT_STRING info = pFormat;
1373 unsigned char *membase = pMemory + ofs + (i * stride);
1376 for (u=0; u<count; u++,info+=8) {
1377 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1378 unsigned char *saved_memory = pStubMsg->Memory;
1380 pStubMsg->Memory = pMemory;
1381 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1382 pStubMsg->Memory = saved_memory;
1385 pFormat += 8 * count;
1388 if (saved_buffer_length)
1390 pStubMsg->PointerLength = pStubMsg->BufferLength;
1391 pStubMsg->BufferLength = saved_buffer_length;
1395 /***********************************************************************
1396 * EmbeddedPointerMemorySize [internal]
1398 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1399 PFORMAT_STRING pFormat)
1401 unsigned long Offset = pStubMsg->Offset;
1402 unsigned char *Mark = pStubMsg->BufferMark;
1403 unsigned ofs, rep, count, stride, xofs;
1406 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1408 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1410 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1412 if (*pFormat != RPC_FC_PP) return 0;
1415 while (pFormat[0] != RPC_FC_END) {
1416 switch (pFormat[0]) {
1418 FIXME("unknown repeat type %d\n", pFormat[0]);
1419 case RPC_FC_NO_REPEAT:
1427 case RPC_FC_FIXED_REPEAT:
1428 rep = *(const WORD*)&pFormat[2];
1429 stride = *(const WORD*)&pFormat[4];
1430 ofs = *(const WORD*)&pFormat[6];
1431 count = *(const WORD*)&pFormat[8];
1435 case RPC_FC_VARIABLE_REPEAT:
1436 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1437 stride = *(const WORD*)&pFormat[2];
1438 ofs = *(const WORD*)&pFormat[4];
1439 count = *(const WORD*)&pFormat[6];
1440 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1444 /* ofs doesn't seem to matter in this context */
1445 for (i = 0; i < rep; i++) {
1446 PFORMAT_STRING info = pFormat;
1447 unsigned char *bufbase = Mark + ofs + (i * stride);
1449 for (u=0; u<count; u++,info+=8) {
1450 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1451 PointerMemorySize(pStubMsg, bufptr, info+4);
1454 pFormat += 8 * count;
1460 /***********************************************************************
1461 * EmbeddedPointerFree [internal]
1463 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1464 unsigned char *pMemory,
1465 PFORMAT_STRING pFormat)
1467 unsigned long Offset = pStubMsg->Offset;
1468 unsigned ofs, rep, count, stride, xofs;
1471 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1472 if (*pFormat != RPC_FC_PP) return;
1475 while (pFormat[0] != RPC_FC_END) {
1476 switch (pFormat[0]) {
1478 FIXME("unknown repeat type %d\n", pFormat[0]);
1479 case RPC_FC_NO_REPEAT:
1487 case RPC_FC_FIXED_REPEAT:
1488 rep = *(const WORD*)&pFormat[2];
1489 stride = *(const WORD*)&pFormat[4];
1490 ofs = *(const WORD*)&pFormat[6];
1491 count = *(const WORD*)&pFormat[8];
1495 case RPC_FC_VARIABLE_REPEAT:
1496 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1497 stride = *(const WORD*)&pFormat[2];
1498 ofs = *(const WORD*)&pFormat[4];
1499 count = *(const WORD*)&pFormat[6];
1500 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1504 for (i = 0; i < rep; i++) {
1505 PFORMAT_STRING info = pFormat;
1506 unsigned char *membase = pMemory + (i * stride);
1509 for (u=0; u<count; u++,info+=8) {
1510 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1511 unsigned char *saved_memory = pStubMsg->Memory;
1513 pStubMsg->Memory = pMemory;
1514 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1515 pStubMsg->Memory = saved_memory;
1518 pFormat += 8 * count;
1522 /***********************************************************************
1523 * NdrPointerMarshall [RPCRT4.@]
1525 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1526 unsigned char *pMemory,
1527 PFORMAT_STRING pFormat)
1529 unsigned char *Buffer;
1531 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1533 /* incremement the buffer here instead of in PointerMarshall,
1534 * as that is used by embedded pointers which already handle the incrementing
1535 * the buffer, and shouldn't write any additional pointer data to the wire */
1536 if (*pFormat != RPC_FC_RP)
1538 ALIGN_POINTER(pStubMsg->Buffer, 4);
1539 Buffer = pStubMsg->Buffer;
1540 pStubMsg->Buffer += 4;
1543 Buffer = pStubMsg->Buffer;
1545 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1547 STD_OVERFLOW_CHECK(pStubMsg);
1552 /***********************************************************************
1553 * NdrPointerUnmarshall [RPCRT4.@]
1555 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1556 unsigned char **ppMemory,
1557 PFORMAT_STRING pFormat,
1558 unsigned char fMustAlloc)
1560 unsigned char *Buffer;
1562 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1564 /* incremement the buffer here instead of in PointerUnmarshall,
1565 * as that is used by embedded pointers which already handle the incrementing
1566 * the buffer, and shouldn't read any additional pointer data from the
1568 if (*pFormat != RPC_FC_RP)
1570 ALIGN_POINTER(pStubMsg->Buffer, 4);
1571 Buffer = pStubMsg->Buffer;
1572 safe_buffer_increment(pStubMsg, 4);
1575 Buffer = pStubMsg->Buffer;
1577 PointerUnmarshall(pStubMsg, Buffer, ppMemory, pFormat, fMustAlloc);
1582 /***********************************************************************
1583 * NdrPointerBufferSize [RPCRT4.@]
1585 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1586 unsigned char *pMemory,
1587 PFORMAT_STRING pFormat)
1589 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1591 /* incremement the buffer length here instead of in PointerBufferSize,
1592 * as that is used by embedded pointers which already handle the buffer
1593 * length, and shouldn't write anything more to the wire */
1594 if (*pFormat != RPC_FC_RP)
1596 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1597 pStubMsg->BufferLength += 4;
1600 PointerBufferSize(pStubMsg, pMemory, pFormat);
1603 /***********************************************************************
1604 * NdrPointerMemorySize [RPCRT4.@]
1606 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1607 PFORMAT_STRING pFormat)
1609 /* unsigned size = *(LPWORD)(pFormat+2); */
1610 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1611 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1615 /***********************************************************************
1616 * NdrPointerFree [RPCRT4.@]
1618 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1619 unsigned char *pMemory,
1620 PFORMAT_STRING pFormat)
1622 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1623 PointerFree(pStubMsg, pMemory, pFormat);
1626 /***********************************************************************
1627 * NdrSimpleTypeMarshall [RPCRT4.@]
1629 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1630 unsigned char FormatChar )
1632 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1635 /***********************************************************************
1636 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1638 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1639 unsigned char FormatChar )
1641 NdrBaseTypeUnmarshall(pStubMsg, &pMemory, &FormatChar, 0);
1644 /***********************************************************************
1645 * NdrSimpleStructMarshall [RPCRT4.@]
1647 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1648 unsigned char *pMemory,
1649 PFORMAT_STRING pFormat)
1651 unsigned size = *(const WORD*)(pFormat+2);
1652 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1654 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1656 memcpy(pStubMsg->Buffer, pMemory, size);
1657 pStubMsg->BufferMark = pStubMsg->Buffer;
1658 pStubMsg->Buffer += size;
1660 if (pFormat[0] != RPC_FC_STRUCT)
1661 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1663 STD_OVERFLOW_CHECK(pStubMsg);
1668 /***********************************************************************
1669 * NdrSimpleStructUnmarshall [RPCRT4.@]
1671 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1672 unsigned char **ppMemory,
1673 PFORMAT_STRING pFormat,
1674 unsigned char fMustAlloc)
1676 unsigned size = *(const WORD*)(pFormat+2);
1677 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1679 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1682 *ppMemory = NdrAllocate(pStubMsg, size);
1683 memcpy(*ppMemory, pStubMsg->Buffer, size);
1685 if (!pStubMsg->IsClient && !*ppMemory)
1686 /* for servers, we just point straight into the RPC buffer */
1687 *ppMemory = pStubMsg->Buffer;
1689 /* for clients, memory should be provided by caller */
1690 memcpy(*ppMemory, pStubMsg->Buffer, size);
1693 pStubMsg->BufferMark = pStubMsg->Buffer;
1694 pStubMsg->Buffer += size;
1696 if (pFormat[0] != RPC_FC_STRUCT)
1697 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat+4, fMustAlloc);
1702 /***********************************************************************
1703 * NdrSimpleStructBufferSize [RPCRT4.@]
1705 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1706 unsigned char *pMemory,
1707 PFORMAT_STRING pFormat)
1709 unsigned size = *(const WORD*)(pFormat+2);
1710 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1712 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1714 pStubMsg->BufferLength += size;
1715 if (pFormat[0] != RPC_FC_STRUCT)
1716 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1719 /***********************************************************************
1720 * NdrSimpleStructMemorySize [RPCRT4.@]
1722 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1723 PFORMAT_STRING pFormat)
1725 unsigned short size = *(const WORD *)(pFormat+2);
1727 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1729 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1730 pStubMsg->MemorySize += size;
1731 pStubMsg->Buffer += size;
1733 if (pFormat[0] != RPC_FC_STRUCT)
1734 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1738 /***********************************************************************
1739 * NdrSimpleStructFree [RPCRT4.@]
1741 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1742 unsigned char *pMemory,
1743 PFORMAT_STRING pFormat)
1745 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1746 if (pFormat[0] != RPC_FC_STRUCT)
1747 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1751 static unsigned long EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg,
1752 PFORMAT_STRING pFormat)
1756 case RPC_FC_PSTRUCT:
1757 case RPC_FC_CSTRUCT:
1758 case RPC_FC_BOGUS_STRUCT:
1759 case RPC_FC_SMFARRAY:
1760 case RPC_FC_SMVARRAY:
1761 return *(const WORD*)&pFormat[2];
1762 case RPC_FC_USER_MARSHAL:
1763 return *(const WORD*)&pFormat[4];
1764 case RPC_FC_NON_ENCAPSULATED_UNION:
1766 if (pStubMsg->fHasNewCorrDesc)
1771 pFormat += *(const SHORT*)pFormat;
1772 return *(const SHORT*)pFormat;
1774 return sizeof(void *);
1776 FIXME("unhandled embedded type %02x\n", *pFormat);
1782 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1783 PFORMAT_STRING pFormat)
1785 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1789 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1793 return m(pStubMsg, pFormat);
1797 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1798 unsigned char *pMemory,
1799 PFORMAT_STRING pFormat,
1800 PFORMAT_STRING pPointer)
1802 PFORMAT_STRING desc;
1806 while (*pFormat != RPC_FC_END) {
1812 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
1813 memcpy(pStubMsg->Buffer, pMemory, 1);
1814 pStubMsg->Buffer += 1;
1820 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1821 memcpy(pStubMsg->Buffer, pMemory, 2);
1822 pStubMsg->Buffer += 2;
1828 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
1829 memcpy(pStubMsg->Buffer, pMemory, 4);
1830 pStubMsg->Buffer += 4;
1834 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1835 memcpy(pStubMsg->Buffer, pMemory, 8);
1836 pStubMsg->Buffer += 8;
1839 case RPC_FC_POINTER:
1841 unsigned char *saved_buffer;
1842 int pointer_buffer_mark_set = 0;
1843 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1844 saved_buffer = pStubMsg->Buffer;
1845 if (pStubMsg->PointerBufferMark)
1847 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1848 pStubMsg->PointerBufferMark = NULL;
1849 pointer_buffer_mark_set = 1;
1852 pStubMsg->Buffer += 4; /* for pointer ID */
1853 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
1854 if (pointer_buffer_mark_set)
1856 STD_OVERFLOW_CHECK(pStubMsg);
1857 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1858 pStubMsg->Buffer = saved_buffer + 4;
1864 case RPC_FC_ALIGNM4:
1865 ALIGN_POINTER(pMemory, 4);
1867 case RPC_FC_ALIGNM8:
1868 ALIGN_POINTER(pMemory, 8);
1870 case RPC_FC_STRUCTPAD1:
1871 case RPC_FC_STRUCTPAD2:
1872 case RPC_FC_STRUCTPAD3:
1873 case RPC_FC_STRUCTPAD4:
1874 case RPC_FC_STRUCTPAD5:
1875 case RPC_FC_STRUCTPAD6:
1876 case RPC_FC_STRUCTPAD7:
1877 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1879 case RPC_FC_EMBEDDED_COMPLEX:
1880 pMemory += pFormat[1];
1882 desc = pFormat + *(const SHORT*)pFormat;
1883 size = EmbeddedComplexSize(pStubMsg, desc);
1884 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1885 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1888 /* for some reason interface pointers aren't generated as
1889 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
1890 * they still need the derefencing treatment that pointers are
1892 if (*desc == RPC_FC_IP)
1893 m(pStubMsg, *(unsigned char **)pMemory, desc);
1895 m(pStubMsg, pMemory, desc);
1897 else FIXME("no marshaller for embedded type %02x\n", *desc);
1904 FIXME("unhandled format 0x%02x\n", *pFormat);
1912 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1913 unsigned char *pMemory,
1914 PFORMAT_STRING pFormat,
1915 PFORMAT_STRING pPointer)
1917 PFORMAT_STRING desc;
1921 while (*pFormat != RPC_FC_END) {
1927 safe_buffer_copy(pStubMsg, pMemory, 1);
1928 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
1934 safe_buffer_copy(pStubMsg, pMemory, 2);
1935 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1941 safe_buffer_copy(pStubMsg, pMemory, 4);
1942 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
1946 safe_buffer_copy(pStubMsg, pMemory, 8);
1947 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1950 case RPC_FC_POINTER:
1952 unsigned char *saved_buffer;
1953 int pointer_buffer_mark_set = 0;
1954 TRACE("pointer => %p\n", pMemory);
1955 ALIGN_POINTER(pStubMsg->Buffer, 4);
1956 saved_buffer = pStubMsg->Buffer;
1957 if (pStubMsg->PointerBufferMark)
1959 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1960 pStubMsg->PointerBufferMark = NULL;
1961 pointer_buffer_mark_set = 1;
1964 pStubMsg->Buffer += 4; /* for pointer ID */
1966 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, pPointer, TRUE);
1967 if (pointer_buffer_mark_set)
1969 STD_OVERFLOW_CHECK(pStubMsg);
1970 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1971 pStubMsg->Buffer = saved_buffer + 4;
1977 case RPC_FC_ALIGNM4:
1978 ALIGN_POINTER(pMemory, 4);
1980 case RPC_FC_ALIGNM8:
1981 ALIGN_POINTER(pMemory, 8);
1983 case RPC_FC_STRUCTPAD1:
1984 case RPC_FC_STRUCTPAD2:
1985 case RPC_FC_STRUCTPAD3:
1986 case RPC_FC_STRUCTPAD4:
1987 case RPC_FC_STRUCTPAD5:
1988 case RPC_FC_STRUCTPAD6:
1989 case RPC_FC_STRUCTPAD7:
1990 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1992 case RPC_FC_EMBEDDED_COMPLEX:
1993 pMemory += pFormat[1];
1995 desc = pFormat + *(const SHORT*)pFormat;
1996 size = EmbeddedComplexSize(pStubMsg, desc);
1997 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
1998 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1999 memset(pMemory, 0, size); /* just in case */
2002 /* for some reason interface pointers aren't generated as
2003 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2004 * they still need the derefencing treatment that pointers are
2006 if (*desc == RPC_FC_IP)
2007 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2009 m(pStubMsg, &pMemory, desc, FALSE);
2011 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2018 FIXME("unhandled format %d\n", *pFormat);
2026 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2027 unsigned char *pMemory,
2028 PFORMAT_STRING pFormat,
2029 PFORMAT_STRING pPointer)
2031 PFORMAT_STRING desc;
2035 while (*pFormat != RPC_FC_END) {
2041 pStubMsg->BufferLength += 1;
2047 pStubMsg->BufferLength += 2;
2053 pStubMsg->BufferLength += 4;
2057 pStubMsg->BufferLength += 8;
2060 case RPC_FC_POINTER:
2061 if (!pStubMsg->IgnoreEmbeddedPointers)
2063 int saved_buffer_length = pStubMsg->BufferLength;
2064 pStubMsg->BufferLength = pStubMsg->PointerLength;
2065 pStubMsg->PointerLength = 0;
2066 if(!pStubMsg->BufferLength)
2067 ERR("BufferLength == 0??\n");
2068 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2069 pStubMsg->PointerLength = pStubMsg->BufferLength;
2070 pStubMsg->BufferLength = saved_buffer_length;
2072 pStubMsg->BufferLength += 4;
2076 case RPC_FC_ALIGNM4:
2077 ALIGN_POINTER(pMemory, 4);
2079 case RPC_FC_ALIGNM8:
2080 ALIGN_POINTER(pMemory, 8);
2082 case RPC_FC_STRUCTPAD1:
2083 case RPC_FC_STRUCTPAD2:
2084 case RPC_FC_STRUCTPAD3:
2085 case RPC_FC_STRUCTPAD4:
2086 case RPC_FC_STRUCTPAD5:
2087 case RPC_FC_STRUCTPAD6:
2088 case RPC_FC_STRUCTPAD7:
2089 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2091 case RPC_FC_EMBEDDED_COMPLEX:
2092 pMemory += pFormat[1];
2094 desc = pFormat + *(const SHORT*)pFormat;
2095 size = EmbeddedComplexSize(pStubMsg, desc);
2096 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2099 /* for some reason interface pointers aren't generated as
2100 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2101 * they still need the derefencing treatment that pointers are
2103 if (*desc == RPC_FC_IP)
2104 m(pStubMsg, *(unsigned char **)pMemory, desc);
2106 m(pStubMsg, pMemory, desc);
2108 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2115 FIXME("unhandled format 0x%02x\n", *pFormat);
2123 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2124 unsigned char *pMemory,
2125 PFORMAT_STRING pFormat,
2126 PFORMAT_STRING pPointer)
2128 PFORMAT_STRING desc;
2132 while (*pFormat != RPC_FC_END) {
2153 case RPC_FC_POINTER:
2154 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
2158 case RPC_FC_ALIGNM4:
2159 ALIGN_POINTER(pMemory, 4);
2161 case RPC_FC_ALIGNM8:
2162 ALIGN_POINTER(pMemory, 8);
2164 case RPC_FC_STRUCTPAD1:
2165 case RPC_FC_STRUCTPAD2:
2166 case RPC_FC_STRUCTPAD3:
2167 case RPC_FC_STRUCTPAD4:
2168 case RPC_FC_STRUCTPAD5:
2169 case RPC_FC_STRUCTPAD6:
2170 case RPC_FC_STRUCTPAD7:
2171 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2173 case RPC_FC_EMBEDDED_COMPLEX:
2174 pMemory += pFormat[1];
2176 desc = pFormat + *(const SHORT*)pFormat;
2177 size = EmbeddedComplexSize(pStubMsg, desc);
2178 m = NdrFreer[*desc & NDR_TABLE_MASK];
2181 /* for some reason interface pointers aren't generated as
2182 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2183 * they still need the derefencing treatment that pointers are
2185 if (*desc == RPC_FC_IP)
2186 m(pStubMsg, *(unsigned char **)pMemory, desc);
2188 m(pStubMsg, pMemory, desc);
2190 else FIXME("no freer for embedded type %02x\n", *desc);
2197 FIXME("unhandled format 0x%02x\n", *pFormat);
2205 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2206 PFORMAT_STRING pFormat)
2208 PFORMAT_STRING desc;
2209 unsigned long size = 0;
2211 while (*pFormat != RPC_FC_END) {
2218 pStubMsg->Buffer += 1;
2224 pStubMsg->Buffer += 2;
2230 pStubMsg->Buffer += 4;
2234 pStubMsg->Buffer += 8;
2236 case RPC_FC_POINTER:
2238 pStubMsg->Buffer += 4;
2239 if (!pStubMsg->IgnoreEmbeddedPointers)
2240 FIXME("embedded pointers\n");
2242 case RPC_FC_ALIGNM4:
2243 ALIGN_LENGTH(size, 4);
2244 ALIGN_POINTER(pStubMsg->Buffer, 4);
2246 case RPC_FC_ALIGNM8:
2247 ALIGN_LENGTH(size, 8);
2248 ALIGN_POINTER(pStubMsg->Buffer, 8);
2250 case RPC_FC_STRUCTPAD1:
2251 case RPC_FC_STRUCTPAD2:
2252 case RPC_FC_STRUCTPAD3:
2253 case RPC_FC_STRUCTPAD4:
2254 case RPC_FC_STRUCTPAD5:
2255 case RPC_FC_STRUCTPAD6:
2256 case RPC_FC_STRUCTPAD7:
2257 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2259 case RPC_FC_EMBEDDED_COMPLEX:
2262 desc = pFormat + *(const SHORT*)pFormat;
2263 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2269 FIXME("unhandled format 0x%02x\n", *pFormat);
2277 /***********************************************************************
2278 * NdrComplexStructMarshall [RPCRT4.@]
2280 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2281 unsigned char *pMemory,
2282 PFORMAT_STRING pFormat)
2284 PFORMAT_STRING conf_array = NULL;
2285 PFORMAT_STRING pointer_desc = NULL;
2286 unsigned char *OldMemory = pStubMsg->Memory;
2287 int pointer_buffer_mark_set = 0;
2289 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2291 if (!pStubMsg->PointerBufferMark)
2293 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2294 /* save buffer length */
2295 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2297 /* get the buffer pointer after complex array data, but before
2299 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2300 pStubMsg->IgnoreEmbeddedPointers = 1;
2301 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2302 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2304 /* save it for use by embedded pointer code later */
2305 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2306 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
2307 pointer_buffer_mark_set = 1;
2309 /* restore the original buffer length */
2310 pStubMsg->BufferLength = saved_buffer_length;
2313 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2316 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2318 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2321 pStubMsg->Memory = pMemory;
2323 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2326 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2328 pStubMsg->Memory = OldMemory;
2330 if (pointer_buffer_mark_set)
2332 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2333 pStubMsg->PointerBufferMark = NULL;
2336 STD_OVERFLOW_CHECK(pStubMsg);
2341 /***********************************************************************
2342 * NdrComplexStructUnmarshall [RPCRT4.@]
2344 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2345 unsigned char **ppMemory,
2346 PFORMAT_STRING pFormat,
2347 unsigned char fMustAlloc)
2349 unsigned size = *(const WORD*)(pFormat+2);
2350 PFORMAT_STRING conf_array = NULL;
2351 PFORMAT_STRING pointer_desc = NULL;
2352 unsigned char *pMemory;
2353 int pointer_buffer_mark_set = 0;
2355 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2357 if (!pStubMsg->PointerBufferMark)
2359 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2360 /* save buffer pointer */
2361 unsigned char *saved_buffer = pStubMsg->Buffer;
2363 /* get the buffer pointer after complex array data, but before
2365 pStubMsg->IgnoreEmbeddedPointers = 1;
2366 NdrComplexStructMemorySize(pStubMsg, pFormat);
2367 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2369 /* save it for use by embedded pointer code later */
2370 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2371 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
2372 pointer_buffer_mark_set = 1;
2374 /* restore the original buffer */
2375 pStubMsg->Buffer = saved_buffer;
2378 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2380 if (fMustAlloc || !*ppMemory)
2382 *ppMemory = NdrAllocate(pStubMsg, size);
2383 memset(*ppMemory, 0, size);
2387 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2389 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2392 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2395 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2397 if (pointer_buffer_mark_set)
2399 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2400 pStubMsg->PointerBufferMark = NULL;
2406 /***********************************************************************
2407 * NdrComplexStructBufferSize [RPCRT4.@]
2409 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2410 unsigned char *pMemory,
2411 PFORMAT_STRING pFormat)
2413 PFORMAT_STRING conf_array = NULL;
2414 PFORMAT_STRING pointer_desc = NULL;
2415 unsigned char *OldMemory = pStubMsg->Memory;
2416 int pointer_length_set = 0;
2418 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2420 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2422 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2424 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2425 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2427 /* get the buffer length after complex struct data, but before
2429 pStubMsg->IgnoreEmbeddedPointers = 1;
2430 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2431 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2433 /* save it for use by embedded pointer code later */
2434 pStubMsg->PointerLength = pStubMsg->BufferLength;
2435 pointer_length_set = 1;
2436 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
2438 /* restore the original buffer length */
2439 pStubMsg->BufferLength = saved_buffer_length;
2443 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2445 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2448 pStubMsg->Memory = pMemory;
2450 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2453 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2455 pStubMsg->Memory = OldMemory;
2457 if(pointer_length_set)
2459 pStubMsg->BufferLength = pStubMsg->PointerLength;
2460 pStubMsg->PointerLength = 0;
2465 /***********************************************************************
2466 * NdrComplexStructMemorySize [RPCRT4.@]
2468 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2469 PFORMAT_STRING pFormat)
2471 unsigned size = *(const WORD*)(pFormat+2);
2472 PFORMAT_STRING conf_array = NULL;
2473 PFORMAT_STRING pointer_desc = NULL;
2475 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2477 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2480 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2482 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2485 ComplexStructMemorySize(pStubMsg, pFormat);
2488 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2493 /***********************************************************************
2494 * NdrComplexStructFree [RPCRT4.@]
2496 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2497 unsigned char *pMemory,
2498 PFORMAT_STRING pFormat)
2500 PFORMAT_STRING conf_array = NULL;
2501 PFORMAT_STRING pointer_desc = NULL;
2502 unsigned char *OldMemory = pStubMsg->Memory;
2504 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2507 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2509 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2512 pStubMsg->Memory = pMemory;
2514 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2517 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2519 pStubMsg->Memory = OldMemory;
2522 /***********************************************************************
2523 * NdrConformantArrayMarshall [RPCRT4.@]
2525 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2526 unsigned char *pMemory,
2527 PFORMAT_STRING pFormat)
2529 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2530 unsigned char alignment = pFormat[1] + 1;
2532 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2533 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2535 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2537 WriteConformance(pStubMsg);
2539 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2541 size = safe_multiply(esize, pStubMsg->MaxCount);
2542 memcpy(pStubMsg->Buffer, pMemory, size);
2543 pStubMsg->BufferMark = pStubMsg->Buffer;
2544 pStubMsg->Buffer += size;
2546 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2548 STD_OVERFLOW_CHECK(pStubMsg);
2553 /***********************************************************************
2554 * NdrConformantArrayUnmarshall [RPCRT4.@]
2556 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2557 unsigned char **ppMemory,
2558 PFORMAT_STRING pFormat,
2559 unsigned char fMustAlloc)
2561 DWORD size, esize = *(const WORD*)(pFormat+2);
2562 unsigned char alignment = pFormat[1] + 1;
2564 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2565 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2567 pFormat = ReadConformance(pStubMsg, pFormat+4);
2569 size = safe_multiply(esize, pStubMsg->MaxCount);
2571 if (fMustAlloc || !*ppMemory)
2572 *ppMemory = NdrAllocate(pStubMsg, size);
2574 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2576 pStubMsg->BufferMark = pStubMsg->Buffer;
2577 safe_buffer_copy(pStubMsg, *ppMemory, size);
2579 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2584 /***********************************************************************
2585 * NdrConformantArrayBufferSize [RPCRT4.@]
2587 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2588 unsigned char *pMemory,
2589 PFORMAT_STRING pFormat)
2591 DWORD size, esize = *(const WORD*)(pFormat+2);
2592 unsigned char alignment = pFormat[1] + 1;
2594 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2595 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2597 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2599 SizeConformance(pStubMsg);
2601 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2603 size = safe_multiply(esize, pStubMsg->MaxCount);
2604 /* conformance value plus array */
2605 pStubMsg->BufferLength += size;
2607 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2610 /***********************************************************************
2611 * NdrConformantArrayMemorySize [RPCRT4.@]
2613 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2614 PFORMAT_STRING pFormat)
2616 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2617 unsigned char alignment = pFormat[1] + 1;
2619 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2620 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2622 pFormat = ReadConformance(pStubMsg, pFormat+4);
2623 size = safe_multiply(esize, pStubMsg->MaxCount);
2624 pStubMsg->MemorySize += size;
2626 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2627 pStubMsg->BufferMark = pStubMsg->Buffer;
2628 pStubMsg->Buffer += size;
2630 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2632 return pStubMsg->MemorySize;
2635 /***********************************************************************
2636 * NdrConformantArrayFree [RPCRT4.@]
2638 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2639 unsigned char *pMemory,
2640 PFORMAT_STRING pFormat)
2642 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2643 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2645 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2647 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2651 /***********************************************************************
2652 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2654 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2655 unsigned char* pMemory,
2656 PFORMAT_STRING pFormat )
2659 unsigned char alignment = pFormat[1] + 1;
2660 DWORD esize = *(const WORD*)(pFormat+2);
2662 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2664 if (pFormat[0] != RPC_FC_CVARRAY)
2666 ERR("invalid format type %x\n", pFormat[0]);
2667 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2671 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2672 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2674 WriteConformance(pStubMsg);
2675 WriteVariance(pStubMsg);
2677 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2679 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2681 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
2682 pStubMsg->BufferMark = pStubMsg->Buffer;
2683 pStubMsg->Buffer += bufsize;
2685 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2687 STD_OVERFLOW_CHECK(pStubMsg);
2693 /***********************************************************************
2694 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2696 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2697 unsigned char** ppMemory,
2698 PFORMAT_STRING pFormat,
2699 unsigned char fMustAlloc )
2701 ULONG bufsize, memsize;
2702 unsigned char alignment = pFormat[1] + 1;
2703 DWORD esize = *(const WORD*)(pFormat+2);
2705 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2707 if (pFormat[0] != RPC_FC_CVARRAY)
2709 ERR("invalid format type %x\n", pFormat[0]);
2710 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2714 pFormat = ReadConformance(pStubMsg, pFormat+4);
2715 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2717 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2719 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2720 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2722 if (!*ppMemory || fMustAlloc)
2723 *ppMemory = NdrAllocate(pStubMsg, memsize);
2724 safe_buffer_copy(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize);
2726 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2732 /***********************************************************************
2733 * NdrConformantVaryingArrayFree [RPCRT4.@]
2735 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2736 unsigned char* pMemory,
2737 PFORMAT_STRING pFormat )
2739 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2741 if (pFormat[0] != RPC_FC_CVARRAY)
2743 ERR("invalid format type %x\n", pFormat[0]);
2744 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2748 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2749 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2751 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2755 /***********************************************************************
2756 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2758 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2759 unsigned char* pMemory, PFORMAT_STRING pFormat )
2761 unsigned char alignment = pFormat[1] + 1;
2762 DWORD esize = *(const WORD*)(pFormat+2);
2764 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2766 if (pFormat[0] != RPC_FC_CVARRAY)
2768 ERR("invalid format type %x\n", pFormat[0]);
2769 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2774 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2775 /* compute length */
2776 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2778 SizeConformance(pStubMsg);
2779 SizeVariance(pStubMsg);
2781 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2783 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
2785 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2789 /***********************************************************************
2790 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2792 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2793 PFORMAT_STRING pFormat )
2800 /***********************************************************************
2801 * NdrComplexArrayMarshall [RPCRT4.@]
2803 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2804 unsigned char *pMemory,
2805 PFORMAT_STRING pFormat)
2807 ULONG i, count, def;
2808 BOOL variance_present;
2809 unsigned char alignment;
2810 int pointer_buffer_mark_set = 0;
2812 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2814 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2816 ERR("invalid format type %x\n", pFormat[0]);
2817 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2821 alignment = pFormat[1] + 1;
2823 if (!pStubMsg->PointerBufferMark)
2825 /* save buffer fields that may be changed by buffer sizer functions
2826 * and that may be needed later on */
2827 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2828 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2829 unsigned long saved_max_count = pStubMsg->MaxCount;
2830 unsigned long saved_offset = pStubMsg->Offset;
2831 unsigned long saved_actual_count = pStubMsg->ActualCount;
2833 /* get the buffer pointer after complex array data, but before
2835 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2836 pStubMsg->IgnoreEmbeddedPointers = 1;
2837 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
2838 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2840 /* save it for use by embedded pointer code later */
2841 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2842 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
2843 pointer_buffer_mark_set = 1;
2845 /* restore fields */
2846 pStubMsg->ActualCount = saved_actual_count;
2847 pStubMsg->Offset = saved_offset;
2848 pStubMsg->MaxCount = saved_max_count;
2849 pStubMsg->BufferLength = saved_buffer_length;
2852 def = *(const WORD*)&pFormat[2];
2855 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2856 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2858 variance_present = IsConformanceOrVariancePresent(pFormat);
2859 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2860 TRACE("variance = %d\n", pStubMsg->ActualCount);
2862 WriteConformance(pStubMsg);
2863 if (variance_present)
2864 WriteVariance(pStubMsg);
2866 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2868 count = pStubMsg->ActualCount;
2869 for (i = 0; i < count; i++)
2870 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2872 STD_OVERFLOW_CHECK(pStubMsg);
2874 if (pointer_buffer_mark_set)
2876 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2877 pStubMsg->PointerBufferMark = NULL;
2883 /***********************************************************************
2884 * NdrComplexArrayUnmarshall [RPCRT4.@]
2886 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2887 unsigned char **ppMemory,
2888 PFORMAT_STRING pFormat,
2889 unsigned char fMustAlloc)
2891 ULONG i, count, size;
2892 unsigned char alignment;
2893 unsigned char *pMemory;
2894 unsigned char *saved_buffer;
2895 int pointer_buffer_mark_set = 0;
2896 int saved_ignore_embedded;
2898 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2900 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2902 ERR("invalid format type %x\n", pFormat[0]);
2903 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2907 alignment = pFormat[1] + 1;
2909 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2910 /* save buffer pointer */
2911 saved_buffer = pStubMsg->Buffer;
2912 /* get the buffer pointer after complex array data, but before
2914 pStubMsg->IgnoreEmbeddedPointers = 1;
2915 pStubMsg->MemorySize = 0;
2916 NdrComplexArrayMemorySize(pStubMsg, pFormat);
2917 size = pStubMsg->MemorySize;
2918 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2920 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
2921 if (!pStubMsg->PointerBufferMark)
2923 /* save it for use by embedded pointer code later */
2924 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2925 pointer_buffer_mark_set = 1;
2927 /* restore the original buffer */
2928 pStubMsg->Buffer = saved_buffer;
2932 pFormat = ReadConformance(pStubMsg, pFormat);
2933 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2935 if (fMustAlloc || !*ppMemory)
2937 *ppMemory = NdrAllocate(pStubMsg, size);
2938 memset(*ppMemory, 0, size);
2941 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2943 pMemory = *ppMemory;
2944 count = pStubMsg->ActualCount;
2945 for (i = 0; i < count; i++)
2946 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
2948 if (pointer_buffer_mark_set)
2950 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2951 pStubMsg->PointerBufferMark = NULL;
2957 /***********************************************************************
2958 * NdrComplexArrayBufferSize [RPCRT4.@]
2960 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2961 unsigned char *pMemory,
2962 PFORMAT_STRING pFormat)
2964 ULONG i, count, def;
2965 unsigned char alignment;
2966 BOOL variance_present;
2967 int pointer_length_set = 0;
2969 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2971 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2973 ERR("invalid format type %x\n", pFormat[0]);
2974 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2978 alignment = pFormat[1] + 1;
2980 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2982 /* save buffer fields that may be changed by buffer sizer functions
2983 * and that may be needed later on */
2984 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2985 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2986 unsigned long saved_max_count = pStubMsg->MaxCount;
2987 unsigned long saved_offset = pStubMsg->Offset;
2988 unsigned long saved_actual_count = pStubMsg->ActualCount;
2990 /* get the buffer pointer after complex array data, but before
2992 pStubMsg->IgnoreEmbeddedPointers = 1;
2993 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
2994 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2996 /* save it for use by embedded pointer code later */
2997 pStubMsg->PointerLength = pStubMsg->BufferLength;
2998 pointer_length_set = 1;
3000 /* restore fields */
3001 pStubMsg->ActualCount = saved_actual_count;
3002 pStubMsg->Offset = saved_offset;
3003 pStubMsg->MaxCount = saved_max_count;
3004 pStubMsg->BufferLength = saved_buffer_length;
3006 def = *(const WORD*)&pFormat[2];
3009 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3010 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3011 SizeConformance(pStubMsg);
3013 variance_present = IsConformanceOrVariancePresent(pFormat);
3014 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3015 TRACE("variance = %d\n", pStubMsg->ActualCount);
3017 if (variance_present)
3018 SizeVariance(pStubMsg);
3020 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3022 count = pStubMsg->ActualCount;
3023 for (i = 0; i < count; i++)
3024 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
3026 if(pointer_length_set)
3028 pStubMsg->BufferLength = pStubMsg->PointerLength;
3029 pStubMsg->PointerLength = 0;
3033 /***********************************************************************
3034 * NdrComplexArrayMemorySize [RPCRT4.@]
3036 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3037 PFORMAT_STRING pFormat)
3039 ULONG i, count, esize, SavedMemorySize, MemorySize;
3040 unsigned char alignment;
3041 unsigned char *Buffer;
3043 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3045 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3047 ERR("invalid format type %x\n", pFormat[0]);
3048 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3052 alignment = pFormat[1] + 1;
3056 pFormat = ReadConformance(pStubMsg, pFormat);
3057 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3059 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3061 SavedMemorySize = pStubMsg->MemorySize;
3063 Buffer = pStubMsg->Buffer;
3064 pStubMsg->MemorySize = 0;
3065 esize = ComplexStructMemorySize(pStubMsg, pFormat);
3066 pStubMsg->Buffer = Buffer;
3068 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
3070 count = pStubMsg->ActualCount;
3071 for (i = 0; i < count; i++)
3072 ComplexStructMemorySize(pStubMsg, pFormat);
3074 pStubMsg->MemorySize = SavedMemorySize;
3076 pStubMsg->MemorySize += MemorySize;
3080 /***********************************************************************
3081 * NdrComplexArrayFree [RPCRT4.@]
3083 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3084 unsigned char *pMemory,
3085 PFORMAT_STRING pFormat)
3087 ULONG i, count, def;
3089 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3091 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3093 ERR("invalid format type %x\n", pFormat[0]);
3094 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3098 def = *(const WORD*)&pFormat[2];
3101 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3102 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3104 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3105 TRACE("variance = %d\n", pStubMsg->ActualCount);
3107 count = pStubMsg->ActualCount;
3108 for (i = 0; i < count; i++)
3109 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
3112 static ULONG UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
3114 return MAKELONG(pStubMsg->dwDestContext,
3115 pStubMsg->RpcMsg->DataRepresentation);
3118 #define USER_MARSHAL_PTR_PREFIX \
3119 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3120 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3122 /***********************************************************************
3123 * NdrUserMarshalMarshall [RPCRT4.@]
3125 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3126 unsigned char *pMemory,
3127 PFORMAT_STRING pFormat)
3129 unsigned flags = pFormat[1];
3130 unsigned index = *(const WORD*)&pFormat[2];
3131 unsigned char *saved_buffer = NULL;
3132 ULONG uflag = UserMarshalFlags(pStubMsg);
3133 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3134 TRACE("index=%d\n", index);
3136 if (flags & USER_MARSHAL_POINTER)
3138 ALIGN_POINTER(pStubMsg->Buffer, 4);
3139 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
3140 pStubMsg->Buffer += 4;
3141 if (pStubMsg->PointerBufferMark)
3143 saved_buffer = pStubMsg->Buffer;
3144 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3145 pStubMsg->PointerBufferMark = NULL;
3147 ALIGN_POINTER(pStubMsg->Buffer, 8);
3150 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3153 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
3154 &uflag, pStubMsg->Buffer, pMemory);
3158 STD_OVERFLOW_CHECK(pStubMsg);
3159 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3160 pStubMsg->Buffer = saved_buffer;
3163 STD_OVERFLOW_CHECK(pStubMsg);
3168 /***********************************************************************
3169 * NdrUserMarshalUnmarshall [RPCRT4.@]
3171 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3172 unsigned char **ppMemory,
3173 PFORMAT_STRING pFormat,
3174 unsigned char fMustAlloc)
3176 unsigned flags = pFormat[1];
3177 unsigned index = *(const WORD*)&pFormat[2];
3178 DWORD memsize = *(const WORD*)&pFormat[4];
3179 unsigned char *saved_buffer = NULL;
3180 ULONG uflag = UserMarshalFlags(pStubMsg);
3181 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3182 TRACE("index=%d\n", index);
3184 if (flags & USER_MARSHAL_POINTER)
3186 ALIGN_POINTER(pStubMsg->Buffer, 4);
3187 /* skip pointer prefix */
3188 pStubMsg->Buffer += 4;
3189 if (pStubMsg->PointerBufferMark)
3191 saved_buffer = pStubMsg->Buffer;
3192 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3193 pStubMsg->PointerBufferMark = NULL;
3195 ALIGN_POINTER(pStubMsg->Buffer, 8);
3198 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3200 if (fMustAlloc || !*ppMemory)
3201 *ppMemory = NdrAllocate(pStubMsg, memsize);
3204 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
3205 &uflag, pStubMsg->Buffer, *ppMemory);
3209 STD_OVERFLOW_CHECK(pStubMsg);
3210 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3211 pStubMsg->Buffer = saved_buffer;
3217 /***********************************************************************
3218 * NdrUserMarshalBufferSize [RPCRT4.@]
3220 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3221 unsigned char *pMemory,
3222 PFORMAT_STRING pFormat)
3224 unsigned flags = pFormat[1];
3225 unsigned index = *(const WORD*)&pFormat[2];
3226 DWORD bufsize = *(const WORD*)&pFormat[6];
3227 ULONG uflag = UserMarshalFlags(pStubMsg);
3228 unsigned long saved_buffer_length = 0;
3229 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3230 TRACE("index=%d\n", index);
3232 if (flags & USER_MARSHAL_POINTER)
3234 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3235 /* skip pointer prefix */
3236 pStubMsg->BufferLength += 4;
3237 if (pStubMsg->IgnoreEmbeddedPointers)
3239 if (pStubMsg->PointerLength)
3241 saved_buffer_length = pStubMsg->BufferLength;
3242 pStubMsg->BufferLength = pStubMsg->PointerLength;
3243 pStubMsg->PointerLength = 0;
3245 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
3248 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
3251 TRACE("size=%d\n", bufsize);
3252 pStubMsg->BufferLength += bufsize;
3255 pStubMsg->BufferLength =
3256 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
3257 &uflag, pStubMsg->BufferLength, pMemory);
3259 if (saved_buffer_length)
3261 pStubMsg->PointerLength = pStubMsg->BufferLength;
3262 pStubMsg->BufferLength = saved_buffer_length;
3267 /***********************************************************************
3268 * NdrUserMarshalMemorySize [RPCRT4.@]
3270 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3271 PFORMAT_STRING pFormat)
3273 unsigned flags = pFormat[1];
3274 unsigned index = *(const WORD*)&pFormat[2];
3275 DWORD memsize = *(const WORD*)&pFormat[4];
3276 DWORD bufsize = *(const WORD*)&pFormat[6];
3278 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3279 TRACE("index=%d\n", index);
3281 pStubMsg->MemorySize += memsize;
3283 if (flags & USER_MARSHAL_POINTER)
3285 ALIGN_POINTER(pStubMsg->Buffer, 4);
3286 /* skip pointer prefix */
3287 pStubMsg->Buffer += 4;
3288 if (pStubMsg->IgnoreEmbeddedPointers)
3289 return pStubMsg->MemorySize;
3290 ALIGN_POINTER(pStubMsg->Buffer, 8);
3293 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3296 FIXME("not implemented for varying buffer size\n");
3298 pStubMsg->Buffer += bufsize;
3300 return pStubMsg->MemorySize;
3303 /***********************************************************************
3304 * NdrUserMarshalFree [RPCRT4.@]
3306 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
3307 unsigned char *pMemory,
3308 PFORMAT_STRING pFormat)
3310 /* unsigned flags = pFormat[1]; */
3311 unsigned index = *(const WORD*)&pFormat[2];
3312 ULONG uflag = UserMarshalFlags(pStubMsg);
3313 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3314 TRACE("index=%d\n", index);
3316 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
3320 /***********************************************************************
3321 * NdrClearOutParameters [RPCRT4.@]
3323 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
3324 PFORMAT_STRING pFormat,
3327 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
3330 /***********************************************************************
3331 * NdrConvert [RPCRT4.@]
3333 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
3335 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
3336 /* FIXME: since this stub doesn't do any converting, the proper behavior
3337 is to raise an exception */
3340 /***********************************************************************
3341 * NdrConvert2 [RPCRT4.@]
3343 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
3345 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3346 pStubMsg, pFormat, NumberParams);
3347 /* FIXME: since this stub doesn't do any converting, the proper behavior
3348 is to raise an exception */
3351 #include "pshpack1.h"
3352 typedef struct _NDR_CSTRUCT_FORMAT
3355 unsigned char alignment;
3356 unsigned short memory_size;
3357 short offset_to_array_description;
3358 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
3359 #include "poppack.h"
3361 /***********************************************************************
3362 * NdrConformantStructMarshall [RPCRT4.@]
3364 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3365 unsigned char *pMemory,
3366 PFORMAT_STRING pFormat)
3368 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3369 PFORMAT_STRING pCArrayFormat;
3370 ULONG esize, bufsize;
3372 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3374 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3375 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3377 ERR("invalid format type %x\n", pCStructFormat->type);
3378 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3382 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3383 pCStructFormat->offset_to_array_description;
3384 if (*pCArrayFormat != RPC_FC_CARRAY)
3386 ERR("invalid array format type %x\n", pCStructFormat->type);
3387 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3390 esize = *(const WORD*)(pCArrayFormat+2);
3392 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3393 pCArrayFormat + 4, 0);
3395 WriteConformance(pStubMsg);
3397 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3399 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3401 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3402 /* copy constant sized part of struct */
3403 pStubMsg->BufferMark = pStubMsg->Buffer;
3404 memcpy(pStubMsg->Buffer, pMemory, pCStructFormat->memory_size + bufsize);
3405 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
3407 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3408 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3410 STD_OVERFLOW_CHECK(pStubMsg);
3415 /***********************************************************************
3416 * NdrConformantStructUnmarshall [RPCRT4.@]
3418 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3419 unsigned char **ppMemory,
3420 PFORMAT_STRING pFormat,
3421 unsigned char fMustAlloc)
3423 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3424 PFORMAT_STRING pCArrayFormat;
3425 ULONG esize, bufsize;
3427 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3429 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3430 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3432 ERR("invalid format type %x\n", pCStructFormat->type);
3433 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3436 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3437 pCStructFormat->offset_to_array_description;
3438 if (*pCArrayFormat != RPC_FC_CARRAY)
3440 ERR("invalid array format type %x\n", pCStructFormat->type);
3441 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3444 esize = *(const WORD*)(pCArrayFormat+2);
3446 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3448 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3450 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3452 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3453 /* work out how much memory to allocate if we need to do so */
3454 if (!*ppMemory || fMustAlloc)
3456 SIZE_T size = pCStructFormat->memory_size + bufsize;
3457 *ppMemory = NdrAllocate(pStubMsg, size);
3460 /* now copy the data */
3461 pStubMsg->BufferMark = pStubMsg->Buffer;
3462 safe_buffer_copy(pStubMsg, *ppMemory, pCStructFormat->memory_size + bufsize);
3464 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3465 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3470 /***********************************************************************
3471 * NdrConformantStructBufferSize [RPCRT4.@]
3473 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3474 unsigned char *pMemory,
3475 PFORMAT_STRING pFormat)
3477 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3478 PFORMAT_STRING pCArrayFormat;
3481 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3483 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3484 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3486 ERR("invalid format type %x\n", pCStructFormat->type);
3487 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3490 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3491 pCStructFormat->offset_to_array_description;
3492 if (*pCArrayFormat != RPC_FC_CARRAY)
3494 ERR("invalid array format type %x\n", pCStructFormat->type);
3495 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3498 esize = *(const WORD*)(pCArrayFormat+2);
3500 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
3501 SizeConformance(pStubMsg);
3503 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
3505 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3507 pStubMsg->BufferLength += pCStructFormat->memory_size +
3508 safe_multiply(pStubMsg->MaxCount, esize);
3510 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3511 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3514 /***********************************************************************
3515 * NdrConformantStructMemorySize [RPCRT4.@]
3517 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3518 PFORMAT_STRING pFormat)
3524 /***********************************************************************
3525 * NdrConformantStructFree [RPCRT4.@]
3527 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3528 unsigned char *pMemory,
3529 PFORMAT_STRING pFormat)
3534 /***********************************************************************
3535 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3537 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3538 unsigned char *pMemory,
3539 PFORMAT_STRING pFormat)
3541 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3542 PFORMAT_STRING pCVArrayFormat;
3543 ULONG esize, bufsize;
3545 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3547 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3548 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3550 ERR("invalid format type %x\n", pCVStructFormat->type);
3551 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3555 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3556 pCVStructFormat->offset_to_array_description;
3557 switch (*pCVArrayFormat)
3559 case RPC_FC_CVARRAY:
3560 esize = *(const WORD*)(pCVArrayFormat+2);
3562 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3563 pCVArrayFormat + 4, 0);
3564 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3567 case RPC_FC_C_CSTRING:
3568 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3569 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3570 esize = sizeof(char);
3571 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3572 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3573 pCVArrayFormat + 2, 0);
3575 pStubMsg->MaxCount = pStubMsg->ActualCount;
3577 case RPC_FC_C_WSTRING:
3578 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3579 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3580 esize = sizeof(WCHAR);
3581 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3582 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3583 pCVArrayFormat + 2, 0);
3585 pStubMsg->MaxCount = pStubMsg->ActualCount;
3588 ERR("invalid array format type %x\n", *pCVArrayFormat);
3589 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3593 WriteConformance(pStubMsg);
3595 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3597 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3599 /* write constant sized part */
3600 pStubMsg->BufferMark = pStubMsg->Buffer;
3601 memcpy(pStubMsg->Buffer, pMemory, pCVStructFormat->memory_size);
3602 pStubMsg->Buffer += pCVStructFormat->memory_size;
3604 WriteVariance(pStubMsg);
3606 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3608 /* write array part */
3609 memcpy(pStubMsg->Buffer, pMemory + pCVStructFormat->memory_size, bufsize);
3610 pStubMsg->Buffer += bufsize;
3612 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3614 STD_OVERFLOW_CHECK(pStubMsg);
3619 /***********************************************************************
3620 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3622 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3623 unsigned char **ppMemory,
3624 PFORMAT_STRING pFormat,
3625 unsigned char fMustAlloc)
3627 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3628 PFORMAT_STRING pCVArrayFormat;
3629 ULONG esize, bufsize;
3630 unsigned char cvarray_type;
3632 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3634 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3635 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3637 ERR("invalid format type %x\n", pCVStructFormat->type);
3638 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3642 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3643 pCVStructFormat->offset_to_array_description;
3644 cvarray_type = *pCVArrayFormat;
3645 switch (cvarray_type)
3647 case RPC_FC_CVARRAY:
3648 esize = *(const WORD*)(pCVArrayFormat+2);
3649 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3651 case RPC_FC_C_CSTRING:
3652 esize = sizeof(char);
3653 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3654 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3656 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3658 case RPC_FC_C_WSTRING:
3659 esize = sizeof(WCHAR);
3660 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3661 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3663 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3666 ERR("invalid array format type %x\n", *pCVArrayFormat);
3667 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3671 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3673 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3675 /* work out how much memory to allocate if we need to do so */
3676 if (!*ppMemory || fMustAlloc)
3678 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3679 *ppMemory = NdrAllocate(pStubMsg, size);
3682 /* copy the constant data */
3683 pStubMsg->BufferMark = pStubMsg->Buffer;
3684 safe_buffer_copy(pStubMsg, *ppMemory, pCVStructFormat->memory_size);
3686 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3688 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3690 if ((cvarray_type == RPC_FC_C_CSTRING) ||
3691 (cvarray_type == RPC_FC_C_WSTRING))
3694 /* strings must always have null terminating bytes */
3695 if (bufsize < esize)
3697 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
3698 RpcRaiseException(RPC_S_INVALID_BOUND);
3701 for (i = bufsize - esize; i < bufsize; i++)
3702 if (pStubMsg->Buffer[i] != 0)
3704 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3705 i, pStubMsg->Buffer[i]);
3706 RpcRaiseException(RPC_S_INVALID_BOUND);
3711 /* copy the array data */
3712 safe_buffer_copy(pStubMsg, *ppMemory + pCVStructFormat->memory_size, bufsize);
3714 if (cvarray_type == RPC_FC_C_CSTRING)
3715 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3716 else if (cvarray_type == RPC_FC_C_WSTRING)
3717 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3719 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3724 /***********************************************************************
3725 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3727 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3728 unsigned char *pMemory,
3729 PFORMAT_STRING pFormat)
3731 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3732 PFORMAT_STRING pCVArrayFormat;
3735 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3737 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3738 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3740 ERR("invalid format type %x\n", pCVStructFormat->type);
3741 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3745 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3746 pCVStructFormat->offset_to_array_description;
3747 switch (*pCVArrayFormat)
3749 case RPC_FC_CVARRAY:
3750 esize = *(const WORD*)(pCVArrayFormat+2);
3752 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3753 pCVArrayFormat + 4, 0);
3754 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3757 case RPC_FC_C_CSTRING:
3758 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3759 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3760 esize = sizeof(char);
3761 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3762 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3763 pCVArrayFormat + 2, 0);
3765 pStubMsg->MaxCount = pStubMsg->ActualCount;
3767 case RPC_FC_C_WSTRING:
3768 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3769 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3770 esize = sizeof(WCHAR);
3771 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3772 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3773 pCVArrayFormat + 2, 0);
3775 pStubMsg->MaxCount = pStubMsg->ActualCount;
3778 ERR("invalid array format type %x\n", *pCVArrayFormat);
3779 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3783 SizeConformance(pStubMsg);
3785 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
3787 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3789 pStubMsg->BufferLength += pCVStructFormat->memory_size;
3790 SizeVariance(pStubMsg);
3791 pStubMsg->BufferLength += safe_multiply(pStubMsg->MaxCount, esize);
3793 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3796 /***********************************************************************
3797 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3799 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3800 PFORMAT_STRING pFormat)
3802 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3803 PFORMAT_STRING pCVArrayFormat;
3805 unsigned char cvarray_type;
3807 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3809 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3810 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3812 ERR("invalid format type %x\n", pCVStructFormat->type);
3813 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3817 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3818 pCVStructFormat->offset_to_array_description;
3819 cvarray_type = *pCVArrayFormat;
3820 switch (cvarray_type)
3822 case RPC_FC_CVARRAY:
3823 esize = *(const WORD*)(pCVArrayFormat+2);
3824 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3826 case RPC_FC_C_CSTRING:
3827 esize = sizeof(char);
3828 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3829 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3831 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3833 case RPC_FC_C_WSTRING:
3834 esize = sizeof(WCHAR);
3835 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3836 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3838 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3841 ERR("invalid array format type %x\n", *pCVArrayFormat);
3842 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3846 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3848 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3850 pStubMsg->Buffer += pCVStructFormat->memory_size;
3851 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3852 pStubMsg->Buffer += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->ActualCount);
3854 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3856 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3858 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3861 /***********************************************************************
3862 * NdrConformantVaryingStructFree [RPCRT4.@]
3864 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3865 unsigned char *pMemory,
3866 PFORMAT_STRING pFormat)
3868 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3869 PFORMAT_STRING pCVArrayFormat;
3872 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3874 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3875 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3877 ERR("invalid format type %x\n", pCVStructFormat->type);
3878 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3882 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3883 pCVStructFormat->offset_to_array_description;
3884 switch (*pCVArrayFormat)
3886 case RPC_FC_CVARRAY:
3887 esize = *(const WORD*)(pCVArrayFormat+2);
3889 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3890 pCVArrayFormat + 4, 0);
3891 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3894 case RPC_FC_C_CSTRING:
3895 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3896 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3897 esize = sizeof(char);
3898 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3899 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3900 pCVArrayFormat + 2, 0);
3902 pStubMsg->MaxCount = pStubMsg->ActualCount;
3904 case RPC_FC_C_WSTRING:
3905 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3906 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3907 esize = sizeof(WCHAR);
3908 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3909 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3910 pCVArrayFormat + 2, 0);
3912 pStubMsg->MaxCount = pStubMsg->ActualCount;
3915 ERR("invalid array format type %x\n", *pCVArrayFormat);
3916 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3920 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3922 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3925 #include "pshpack1.h"
3929 unsigned char alignment;
3930 unsigned short total_size;
3931 } NDR_SMFARRAY_FORMAT;
3936 unsigned char alignment;
3937 unsigned long total_size;
3938 } NDR_LGFARRAY_FORMAT;
3939 #include "poppack.h"
3941 /***********************************************************************
3942 * NdrFixedArrayMarshall [RPCRT4.@]
3944 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3945 unsigned char *pMemory,
3946 PFORMAT_STRING pFormat)
3948 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3949 unsigned long total_size;
3951 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3953 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3954 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3956 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3957 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3961 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3963 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3965 total_size = pSmFArrayFormat->total_size;
3966 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3970 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3971 total_size = pLgFArrayFormat->total_size;
3972 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3975 memcpy(pStubMsg->Buffer, pMemory, total_size);
3976 pStubMsg->BufferMark = pStubMsg->Buffer;
3977 pStubMsg->Buffer += total_size;
3979 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3984 /***********************************************************************
3985 * NdrFixedArrayUnmarshall [RPCRT4.@]
3987 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3988 unsigned char **ppMemory,
3989 PFORMAT_STRING pFormat,
3990 unsigned char fMustAlloc)
3992 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3993 unsigned long total_size;
3995 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3997 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3998 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4000 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4001 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4005 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4007 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4009 total_size = pSmFArrayFormat->total_size;
4010 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4014 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4015 total_size = pLgFArrayFormat->total_size;
4016 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4019 if (fMustAlloc || !*ppMemory)
4020 *ppMemory = NdrAllocate(pStubMsg, total_size);
4021 pStubMsg->BufferMark = pStubMsg->Buffer;
4022 safe_buffer_copy(pStubMsg, *ppMemory, total_size);
4024 pFormat = EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
4029 /***********************************************************************
4030 * NdrFixedArrayBufferSize [RPCRT4.@]
4032 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4033 unsigned char *pMemory,
4034 PFORMAT_STRING pFormat)
4036 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4037 unsigned long total_size;
4039 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4041 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4042 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4044 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4045 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4049 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4051 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4053 total_size = pSmFArrayFormat->total_size;
4054 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4058 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4059 total_size = pLgFArrayFormat->total_size;
4060 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4062 pStubMsg->BufferLength += total_size;
4064 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4067 /***********************************************************************
4068 * NdrFixedArrayMemorySize [RPCRT4.@]
4070 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4071 PFORMAT_STRING pFormat)
4073 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4076 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4078 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4079 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4081 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4082 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4086 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4088 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4090 total_size = pSmFArrayFormat->total_size;
4091 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4095 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4096 total_size = pLgFArrayFormat->total_size;
4097 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4099 pStubMsg->BufferMark = pStubMsg->Buffer;
4100 pStubMsg->Buffer += total_size;
4101 pStubMsg->MemorySize += total_size;
4103 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4108 /***********************************************************************
4109 * NdrFixedArrayFree [RPCRT4.@]
4111 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4112 unsigned char *pMemory,
4113 PFORMAT_STRING pFormat)
4115 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4117 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4119 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4120 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4122 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4123 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4127 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4128 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4131 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4132 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4135 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4138 /***********************************************************************
4139 * NdrVaryingArrayMarshall [RPCRT4.@]
4141 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4142 unsigned char *pMemory,
4143 PFORMAT_STRING pFormat)
4145 unsigned char alignment;
4146 DWORD elements, esize;
4149 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4151 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4152 (pFormat[0] != RPC_FC_LGVARRAY))
4154 ERR("invalid format type %x\n", pFormat[0]);
4155 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4159 alignment = pFormat[1] + 1;
4161 if (pFormat[0] == RPC_FC_SMVARRAY)
4164 pFormat += sizeof(WORD);
4165 elements = *(const WORD*)pFormat;
4166 pFormat += sizeof(WORD);
4171 pFormat += sizeof(DWORD);
4172 elements = *(const DWORD*)pFormat;
4173 pFormat += sizeof(DWORD);
4176 esize = *(const WORD*)pFormat;
4177 pFormat += sizeof(WORD);
4179 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4180 if ((pStubMsg->ActualCount > elements) ||
4181 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4183 RpcRaiseException(RPC_S_INVALID_BOUND);
4187 WriteVariance(pStubMsg);
4189 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4191 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4192 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
4193 pStubMsg->BufferMark = pStubMsg->Buffer;
4194 pStubMsg->Buffer += bufsize;
4196 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4198 STD_OVERFLOW_CHECK(pStubMsg);
4203 /***********************************************************************
4204 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4206 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4207 unsigned char **ppMemory,
4208 PFORMAT_STRING pFormat,
4209 unsigned char fMustAlloc)
4211 unsigned char alignment;
4212 DWORD size, elements, esize;
4215 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4217 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4218 (pFormat[0] != RPC_FC_LGVARRAY))
4220 ERR("invalid format type %x\n", pFormat[0]);
4221 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4225 alignment = pFormat[1] + 1;
4227 if (pFormat[0] == RPC_FC_SMVARRAY)
4230 size = *(const WORD*)pFormat;
4231 pFormat += sizeof(WORD);
4232 elements = *(const WORD*)pFormat;
4233 pFormat += sizeof(WORD);
4238 size = *(const DWORD*)pFormat;
4239 pFormat += sizeof(DWORD);
4240 elements = *(const DWORD*)pFormat;
4241 pFormat += sizeof(DWORD);
4244 esize = *(const WORD*)pFormat;
4245 pFormat += sizeof(WORD);
4247 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4249 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4251 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4253 if (!*ppMemory || fMustAlloc)
4254 *ppMemory = NdrAllocate(pStubMsg, size);
4255 safe_buffer_copy(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize);
4257 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
4262 /***********************************************************************
4263 * NdrVaryingArrayBufferSize [RPCRT4.@]
4265 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4266 unsigned char *pMemory,
4267 PFORMAT_STRING pFormat)
4269 unsigned char alignment;
4270 DWORD elements, esize;
4272 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4274 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4275 (pFormat[0] != RPC_FC_LGVARRAY))
4277 ERR("invalid format type %x\n", pFormat[0]);
4278 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4282 alignment = pFormat[1] + 1;
4284 if (pFormat[0] == RPC_FC_SMVARRAY)
4287 pFormat += sizeof(WORD);
4288 elements = *(const WORD*)pFormat;
4289 pFormat += sizeof(WORD);
4294 pFormat += sizeof(DWORD);
4295 elements = *(const DWORD*)pFormat;
4296 pFormat += sizeof(DWORD);
4299 esize = *(const WORD*)pFormat;
4300 pFormat += sizeof(WORD);
4302 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4303 if ((pStubMsg->ActualCount > elements) ||
4304 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4306 RpcRaiseException(RPC_S_INVALID_BOUND);
4310 SizeVariance(pStubMsg);
4312 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4314 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
4316 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4319 /***********************************************************************
4320 * NdrVaryingArrayMemorySize [RPCRT4.@]
4322 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4323 PFORMAT_STRING pFormat)
4325 unsigned char alignment;
4326 DWORD size, elements, esize;
4328 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4330 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4331 (pFormat[0] != RPC_FC_LGVARRAY))
4333 ERR("invalid format type %x\n", pFormat[0]);
4334 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4338 alignment = pFormat[1] + 1;
4340 if (pFormat[0] == RPC_FC_SMVARRAY)
4343 size = *(const WORD*)pFormat;
4344 pFormat += sizeof(WORD);
4345 elements = *(const WORD*)pFormat;
4346 pFormat += sizeof(WORD);
4351 size = *(const DWORD*)pFormat;
4352 pFormat += sizeof(DWORD);
4353 elements = *(const DWORD*)pFormat;
4354 pFormat += sizeof(DWORD);
4357 esize = *(const WORD*)pFormat;
4358 pFormat += sizeof(WORD);
4360 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4362 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4364 pStubMsg->Buffer += safe_multiply(esize, pStubMsg->ActualCount);
4365 pStubMsg->MemorySize += size;
4367 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4369 return pStubMsg->MemorySize;
4372 /***********************************************************************
4373 * NdrVaryingArrayFree [RPCRT4.@]
4375 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4376 unsigned char *pMemory,
4377 PFORMAT_STRING pFormat)
4379 unsigned char alignment;
4382 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4384 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4385 (pFormat[0] != RPC_FC_LGVARRAY))
4387 ERR("invalid format type %x\n", pFormat[0]);
4388 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4392 alignment = pFormat[1] + 1;
4394 if (pFormat[0] == RPC_FC_SMVARRAY)
4397 pFormat += sizeof(WORD);
4398 elements = *(const WORD*)pFormat;
4399 pFormat += sizeof(WORD);
4404 pFormat += sizeof(DWORD);
4405 elements = *(const DWORD*)pFormat;
4406 pFormat += sizeof(DWORD);
4409 pFormat += sizeof(WORD);
4411 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4412 if ((pStubMsg->ActualCount > elements) ||
4413 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4415 RpcRaiseException(RPC_S_INVALID_BOUND);
4419 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4422 static ULONG get_discriminant(unsigned char fc, unsigned char *pMemory)
4430 return *(UCHAR *)pMemory;
4435 return *(USHORT *)pMemory;
4439 return *(ULONG *)pMemory;
4441 FIXME("Unhandled base type: 0x%02x\n", fc);
4446 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4447 unsigned long discriminant,
4448 PFORMAT_STRING pFormat)
4450 unsigned short num_arms, arm, type;
4452 num_arms = *(const SHORT*)pFormat & 0x0fff;
4454 for(arm = 0; arm < num_arms; arm++)
4456 if(discriminant == *(const ULONG*)pFormat)
4464 type = *(const unsigned short*)pFormat;
4465 TRACE("type %04x\n", type);
4466 if(arm == num_arms) /* default arm extras */
4470 ERR("no arm for 0x%lx and no default case\n", discriminant);
4471 RpcRaiseException(RPC_S_INVALID_TAG);
4476 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
4483 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
4485 unsigned short type;
4489 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4493 type = *(const unsigned short*)pFormat;
4494 if((type & 0xff00) == 0x8000)
4496 unsigned char basetype = LOBYTE(type);
4497 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
4501 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4502 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
4505 unsigned char *saved_buffer = NULL;
4506 int pointer_buffer_mark_set = 0;
4513 ALIGN_POINTER(pStubMsg->Buffer, 4);
4514 saved_buffer = pStubMsg->Buffer;
4515 if (pStubMsg->PointerBufferMark)
4517 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4518 pStubMsg->PointerBufferMark = NULL;
4519 pointer_buffer_mark_set = 1;
4522 pStubMsg->Buffer += 4; /* for pointer ID */
4524 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
4525 if (pointer_buffer_mark_set)
4527 STD_OVERFLOW_CHECK(pStubMsg);
4528 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4529 pStubMsg->Buffer = saved_buffer + 4;
4533 m(pStubMsg, pMemory, desc);
4536 else FIXME("no marshaller for embedded type %02x\n", *desc);
4541 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4542 unsigned char **ppMemory,
4544 PFORMAT_STRING pFormat,
4545 unsigned char fMustAlloc)
4547 unsigned short type;
4551 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4555 type = *(const unsigned short*)pFormat;
4556 if((type & 0xff00) == 0x8000)
4558 unsigned char basetype = LOBYTE(type);
4559 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
4563 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4564 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
4567 unsigned char *saved_buffer = NULL;
4568 int pointer_buffer_mark_set = 0;
4575 **(void***)ppMemory = NULL;
4576 ALIGN_POINTER(pStubMsg->Buffer, 4);
4577 saved_buffer = pStubMsg->Buffer;
4578 if (pStubMsg->PointerBufferMark)
4580 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4581 pStubMsg->PointerBufferMark = NULL;
4582 pointer_buffer_mark_set = 1;
4585 pStubMsg->Buffer += 4; /* for pointer ID */
4587 if (saved_buffer + 4 > pStubMsg->BufferEnd)
4588 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4590 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, desc, fMustAlloc);
4591 if (pointer_buffer_mark_set)
4593 STD_OVERFLOW_CHECK(pStubMsg);
4594 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4595 pStubMsg->Buffer = saved_buffer + 4;
4599 m(pStubMsg, ppMemory, desc, fMustAlloc);
4602 else FIXME("no marshaller for embedded type %02x\n", *desc);
4607 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
4608 unsigned char *pMemory,
4610 PFORMAT_STRING pFormat)
4612 unsigned short type;
4616 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4620 type = *(const unsigned short*)pFormat;
4621 if((type & 0xff00) == 0x8000)
4623 unsigned char basetype = LOBYTE(type);
4624 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
4628 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4629 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
4638 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4639 pStubMsg->BufferLength += 4; /* for pointer ID */
4640 if (!pStubMsg->IgnoreEmbeddedPointers)
4642 int saved_buffer_length = pStubMsg->BufferLength;
4643 pStubMsg->BufferLength = pStubMsg->PointerLength;
4644 pStubMsg->PointerLength = 0;
4645 if(!pStubMsg->BufferLength)
4646 ERR("BufferLength == 0??\n");
4647 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
4648 pStubMsg->PointerLength = pStubMsg->BufferLength;
4649 pStubMsg->BufferLength = saved_buffer_length;
4653 m(pStubMsg, pMemory, desc);
4656 else FIXME("no buffersizer for embedded type %02x\n", *desc);
4660 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
4662 PFORMAT_STRING pFormat)
4664 unsigned short type, size;
4666 size = *(const unsigned short*)pFormat;
4667 pStubMsg->Memory += size;
4670 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4674 type = *(const unsigned short*)pFormat;
4675 if((type & 0xff00) == 0x8000)
4677 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
4681 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4682 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
4683 unsigned char *saved_buffer;
4692 ALIGN_POINTER(pStubMsg->Buffer, 4);
4693 saved_buffer = pStubMsg->Buffer;
4694 pStubMsg->Buffer += 4;
4695 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
4696 pStubMsg->MemorySize += 4;
4697 if (!pStubMsg->IgnoreEmbeddedPointers)
4698 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
4701 return m(pStubMsg, desc);
4704 else FIXME("no marshaller for embedded type %02x\n", *desc);
4707 TRACE("size %d\n", size);
4711 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
4712 unsigned char *pMemory,
4714 PFORMAT_STRING pFormat)
4716 unsigned short type;
4720 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4724 type = *(const unsigned short*)pFormat;
4725 if((type & 0xff00) != 0x8000)
4727 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4728 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
4737 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
4740 m(pStubMsg, pMemory, desc);
4743 else FIXME("no freer for embedded type %02x\n", *desc);
4747 /***********************************************************************
4748 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4750 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4751 unsigned char *pMemory,
4752 PFORMAT_STRING pFormat)
4754 unsigned char switch_type;
4755 unsigned char increment;
4758 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4761 switch_type = *pFormat & 0xf;
4762 increment = (*pFormat & 0xf0) >> 4;
4765 ALIGN_POINTER(pStubMsg->Buffer, increment);
4767 switch_value = get_discriminant(switch_type, pMemory);
4768 TRACE("got switch value 0x%x\n", switch_value);
4770 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
4771 pMemory += increment;
4773 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
4776 /***********************************************************************
4777 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4779 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4780 unsigned char **ppMemory,
4781 PFORMAT_STRING pFormat,
4782 unsigned char fMustAlloc)
4784 unsigned char switch_type;
4785 unsigned char increment;
4787 unsigned short size;
4788 unsigned char *pMemoryArm;
4790 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4793 switch_type = *pFormat & 0xf;
4794 increment = (*pFormat & 0xf0) >> 4;
4797 ALIGN_POINTER(pStubMsg->Buffer, increment);
4798 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
4799 TRACE("got switch value 0x%x\n", switch_value);
4801 size = *(const unsigned short*)pFormat + increment;
4802 if(!*ppMemory || fMustAlloc)
4803 *ppMemory = NdrAllocate(pStubMsg, size);
4805 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
4806 pMemoryArm = *ppMemory + increment;
4808 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
4811 /***********************************************************************
4812 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4814 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4815 unsigned char *pMemory,
4816 PFORMAT_STRING pFormat)
4818 unsigned char switch_type;
4819 unsigned char increment;
4822 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4825 switch_type = *pFormat & 0xf;
4826 increment = (*pFormat & 0xf0) >> 4;
4829 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
4830 switch_value = get_discriminant(switch_type, pMemory);
4831 TRACE("got switch value 0x%x\n", switch_value);
4833 /* Add discriminant size */
4834 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
4835 pMemory += increment;
4837 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
4840 /***********************************************************************
4841 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4843 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4844 PFORMAT_STRING pFormat)
4846 unsigned char switch_type;
4847 unsigned char increment;
4850 switch_type = *pFormat & 0xf;
4851 increment = (*pFormat & 0xf0) >> 4;
4854 ALIGN_POINTER(pStubMsg->Buffer, increment);
4855 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
4856 TRACE("got switch value 0x%x\n", switch_value);
4858 pStubMsg->Memory += increment;
4860 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
4863 /***********************************************************************
4864 * NdrEncapsulatedUnionFree [RPCRT4.@]
4866 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4867 unsigned char *pMemory,
4868 PFORMAT_STRING pFormat)
4870 unsigned char switch_type;
4871 unsigned char increment;
4874 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4877 switch_type = *pFormat & 0xf;
4878 increment = (*pFormat & 0xf0) >> 4;
4881 switch_value = get_discriminant(switch_type, pMemory);
4882 TRACE("got switch value 0x%x\n", switch_value);
4884 pMemory += increment;
4886 return union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
4889 /***********************************************************************
4890 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
4892 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4893 unsigned char *pMemory,
4894 PFORMAT_STRING pFormat)
4896 unsigned char switch_type;
4898 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4901 switch_type = *pFormat;
4904 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4905 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4906 /* Marshall discriminant */
4907 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4909 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
4912 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
4913 PFORMAT_STRING *ppFormat)
4915 long discriminant = 0;
4925 safe_buffer_copy(pStubMsg, &d, sizeof(d));
4934 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4935 safe_buffer_copy(pStubMsg, &d, sizeof(d));
4943 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4944 safe_buffer_copy(pStubMsg, &d, sizeof(d));
4949 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
4953 if (pStubMsg->fHasNewCorrDesc)
4957 return discriminant;
4960 /**********************************************************************
4961 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
4963 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4964 unsigned char **ppMemory,
4965 PFORMAT_STRING pFormat,
4966 unsigned char fMustAlloc)
4969 unsigned short size;
4971 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4974 /* Unmarshall discriminant */
4975 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4976 TRACE("unmarshalled discriminant %lx\n", discriminant);
4978 pFormat += *(const SHORT*)pFormat;
4980 size = *(const unsigned short*)pFormat;
4982 if(!*ppMemory || fMustAlloc)
4983 *ppMemory = NdrAllocate(pStubMsg, size);
4985 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
4988 /***********************************************************************
4989 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
4991 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4992 unsigned char *pMemory,
4993 PFORMAT_STRING pFormat)
4995 unsigned char switch_type;
4997 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5000 switch_type = *pFormat;
5003 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5004 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5005 /* Add discriminant size */
5006 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5008 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5011 /***********************************************************************
5012 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5014 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5015 PFORMAT_STRING pFormat)
5020 /* Unmarshall discriminant */
5021 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5022 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
5024 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
5027 /***********************************************************************
5028 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5030 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5031 unsigned char *pMemory,
5032 PFORMAT_STRING pFormat)
5034 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5038 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5039 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5041 return union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5044 /***********************************************************************
5045 * NdrByteCountPointerMarshall [RPCRT4.@]
5047 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5048 unsigned char *pMemory,
5049 PFORMAT_STRING pFormat)
5055 /***********************************************************************
5056 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5058 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5059 unsigned char **ppMemory,
5060 PFORMAT_STRING pFormat,
5061 unsigned char fMustAlloc)
5067 /***********************************************************************
5068 * NdrByteCountPointerBufferSize [RPCRT4.@]
5070 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5071 unsigned char *pMemory,
5072 PFORMAT_STRING pFormat)
5077 /***********************************************************************
5078 * NdrByteCountPointerMemorySize [RPCRT4.@]
5080 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5081 PFORMAT_STRING pFormat)
5087 /***********************************************************************
5088 * NdrByteCountPointerFree [RPCRT4.@]
5090 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
5091 unsigned char *pMemory,
5092 PFORMAT_STRING pFormat)
5097 /***********************************************************************
5098 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5100 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5101 unsigned char *pMemory,
5102 PFORMAT_STRING pFormat)
5108 /***********************************************************************
5109 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5111 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5112 unsigned char **ppMemory,
5113 PFORMAT_STRING pFormat,
5114 unsigned char fMustAlloc)
5120 /***********************************************************************
5121 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5123 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5124 unsigned char *pMemory,
5125 PFORMAT_STRING pFormat)
5130 /***********************************************************************
5131 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5133 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5134 PFORMAT_STRING pFormat)
5140 /***********************************************************************
5141 * NdrXmitOrRepAsFree [RPCRT4.@]
5143 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
5144 unsigned char *pMemory,
5145 PFORMAT_STRING pFormat)
5150 #include "pshpack1.h"
5154 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
5158 #include "poppack.h"
5160 /***********************************************************************
5161 * NdrRangeMarshall [internal]
5163 unsigned char *WINAPI NdrRangeMarshall(
5164 PMIDL_STUB_MESSAGE pStubMsg,
5165 unsigned char *pMemory,
5166 PFORMAT_STRING pFormat)
5168 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5169 unsigned char base_type;
5171 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5173 if (pRange->type != RPC_FC_RANGE)
5175 ERR("invalid format type %x\n", pRange->type);
5176 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5180 base_type = pRange->flags_type & 0xf;
5182 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
5185 /***********************************************************************
5186 * NdrRangeUnmarshall
5188 unsigned char *WINAPI NdrRangeUnmarshall(
5189 PMIDL_STUB_MESSAGE pStubMsg,
5190 unsigned char **ppMemory,
5191 PFORMAT_STRING pFormat,
5192 unsigned char fMustAlloc)
5194 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5195 unsigned char base_type;
5197 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5199 if (pRange->type != RPC_FC_RANGE)
5201 ERR("invalid format type %x\n", pRange->type);
5202 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5205 base_type = pRange->flags_type & 0xf;
5207 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5208 base_type, pRange->low_value, pRange->high_value);
5210 #define RANGE_UNMARSHALL(type, format_spec) \
5213 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5214 if (fMustAlloc || !*ppMemory) \
5215 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5216 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5217 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5219 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5220 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5221 (type)pRange->high_value); \
5222 RpcRaiseException(RPC_S_INVALID_BOUND); \
5225 TRACE("*ppMemory: %p\n", *ppMemory); \
5226 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5227 pStubMsg->Buffer += sizeof(type); \
5234 RANGE_UNMARSHALL(UCHAR, "%d");
5235 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5239 RANGE_UNMARSHALL(CHAR, "%u");
5240 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5242 case RPC_FC_WCHAR: /* FIXME: valid? */
5244 RANGE_UNMARSHALL(USHORT, "%u");
5245 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5248 RANGE_UNMARSHALL(SHORT, "%d");
5249 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5252 RANGE_UNMARSHALL(LONG, "%d");
5253 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5256 RANGE_UNMARSHALL(ULONG, "%u");
5257 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5261 FIXME("Unhandled enum type\n");
5263 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
5268 ERR("invalid range base type: 0x%02x\n", base_type);
5269 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5275 /***********************************************************************
5276 * NdrRangeBufferSize [internal]
5278 void WINAPI NdrRangeBufferSize(
5279 PMIDL_STUB_MESSAGE pStubMsg,
5280 unsigned char *pMemory,
5281 PFORMAT_STRING pFormat)
5283 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5284 unsigned char base_type;
5286 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5288 if (pRange->type != RPC_FC_RANGE)
5290 ERR("invalid format type %x\n", pRange->type);
5291 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5293 base_type = pRange->flags_type & 0xf;
5295 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
5298 /***********************************************************************
5299 * NdrRangeMemorySize [internal]
5301 ULONG WINAPI NdrRangeMemorySize(
5302 PMIDL_STUB_MESSAGE pStubMsg,
5303 PFORMAT_STRING pFormat)
5305 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5306 unsigned char base_type;
5308 if (pRange->type != RPC_FC_RANGE)
5310 ERR("invalid format type %x\n", pRange->type);
5311 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5314 base_type = pRange->flags_type & 0xf;
5316 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
5319 /***********************************************************************
5320 * NdrRangeFree [internal]
5322 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
5323 unsigned char *pMemory,
5324 PFORMAT_STRING pFormat)
5326 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5331 /***********************************************************************
5332 * NdrBaseTypeMarshall [internal]
5334 static unsigned char *WINAPI NdrBaseTypeMarshall(
5335 PMIDL_STUB_MESSAGE pStubMsg,
5336 unsigned char *pMemory,
5337 PFORMAT_STRING pFormat)
5339 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5347 *(UCHAR *)pStubMsg->Buffer = *(UCHAR *)pMemory;
5348 pStubMsg->Buffer += sizeof(UCHAR);
5349 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
5354 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5355 *(USHORT *)pStubMsg->Buffer = *(USHORT *)pMemory;
5356 pStubMsg->Buffer += sizeof(USHORT);
5357 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
5361 case RPC_FC_ERROR_STATUS_T:
5363 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5364 *(ULONG *)pStubMsg->Buffer = *(ULONG *)pMemory;
5365 pStubMsg->Buffer += sizeof(ULONG);
5366 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
5369 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
5370 *(float *)pStubMsg->Buffer = *(float *)pMemory;
5371 pStubMsg->Buffer += sizeof(float);
5374 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
5375 *(double *)pStubMsg->Buffer = *(double *)pMemory;
5376 pStubMsg->Buffer += sizeof(double);
5379 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
5380 *(ULONGLONG *)pStubMsg->Buffer = *(ULONGLONG *)pMemory;
5381 pStubMsg->Buffer += sizeof(ULONGLONG);
5382 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
5385 /* only 16-bits on the wire, so do a sanity check */
5386 if (*(UINT *)pMemory > SHRT_MAX)
5387 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
5388 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5389 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
5390 pStubMsg->Buffer += sizeof(USHORT);
5391 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
5394 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5397 STD_OVERFLOW_CHECK(pStubMsg);
5399 /* FIXME: what is the correct return value? */
5403 /***********************************************************************
5404 * NdrBaseTypeUnmarshall [internal]
5406 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
5407 PMIDL_STUB_MESSAGE pStubMsg,
5408 unsigned char **ppMemory,
5409 PFORMAT_STRING pFormat,
5410 unsigned char fMustAlloc)
5412 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5414 #define BASE_TYPE_UNMARSHALL(type) \
5415 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5416 if (fMustAlloc || !*ppMemory) \
5417 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5418 TRACE("*ppMemory: %p\n", *ppMemory); \
5419 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5420 pStubMsg->Buffer += sizeof(type);
5428 BASE_TYPE_UNMARSHALL(UCHAR);
5429 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5434 BASE_TYPE_UNMARSHALL(USHORT);
5435 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5439 case RPC_FC_ERROR_STATUS_T:
5441 BASE_TYPE_UNMARSHALL(ULONG);
5442 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5445 BASE_TYPE_UNMARSHALL(float);
5446 TRACE("value: %f\n", **(float **)ppMemory);
5449 BASE_TYPE_UNMARSHALL(double);
5450 TRACE("value: %f\n", **(double **)ppMemory);
5453 BASE_TYPE_UNMARSHALL(ULONGLONG);
5454 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
5457 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5458 if (fMustAlloc || !*ppMemory)
5459 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
5460 TRACE("*ppMemory: %p\n", *ppMemory);
5461 /* 16-bits on the wire, but int in memory */
5462 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
5463 pStubMsg->Buffer += sizeof(USHORT);
5464 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
5467 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5469 #undef BASE_TYPE_UNMARSHALL
5471 /* FIXME: what is the correct return value? */
5476 /***********************************************************************
5477 * NdrBaseTypeBufferSize [internal]
5479 static void WINAPI NdrBaseTypeBufferSize(
5480 PMIDL_STUB_MESSAGE pStubMsg,
5481 unsigned char *pMemory,
5482 PFORMAT_STRING pFormat)
5484 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5492 pStubMsg->BufferLength += sizeof(UCHAR);
5498 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
5499 pStubMsg->BufferLength += sizeof(USHORT);
5504 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
5505 pStubMsg->BufferLength += sizeof(ULONG);
5508 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
5509 pStubMsg->BufferLength += sizeof(float);
5512 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
5513 pStubMsg->BufferLength += sizeof(double);
5516 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
5517 pStubMsg->BufferLength += sizeof(ULONGLONG);
5519 case RPC_FC_ERROR_STATUS_T:
5520 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
5521 pStubMsg->BufferLength += sizeof(error_status_t);
5524 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5528 /***********************************************************************
5529 * NdrBaseTypeMemorySize [internal]
5531 static ULONG WINAPI NdrBaseTypeMemorySize(
5532 PMIDL_STUB_MESSAGE pStubMsg,
5533 PFORMAT_STRING pFormat)
5541 pStubMsg->Buffer += sizeof(UCHAR);
5542 pStubMsg->MemorySize += sizeof(UCHAR);
5543 return sizeof(UCHAR);
5547 pStubMsg->Buffer += sizeof(USHORT);
5548 pStubMsg->MemorySize += sizeof(USHORT);
5549 return sizeof(USHORT);
5552 pStubMsg->Buffer += sizeof(ULONG);
5553 pStubMsg->MemorySize += sizeof(ULONG);
5554 return sizeof(ULONG);
5556 pStubMsg->Buffer += sizeof(float);
5557 pStubMsg->MemorySize += sizeof(float);
5558 return sizeof(float);
5560 pStubMsg->Buffer += sizeof(double);
5561 pStubMsg->MemorySize += sizeof(double);
5562 return sizeof(double);
5564 pStubMsg->Buffer += sizeof(ULONGLONG);
5565 pStubMsg->MemorySize += sizeof(ULONGLONG);
5566 return sizeof(ULONGLONG);
5567 case RPC_FC_ERROR_STATUS_T:
5568 pStubMsg->Buffer += sizeof(error_status_t);
5569 pStubMsg->MemorySize += sizeof(error_status_t);
5570 return sizeof(error_status_t);
5573 pStubMsg->Buffer += sizeof(INT);
5574 pStubMsg->MemorySize += sizeof(INT);
5577 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5582 /***********************************************************************
5583 * NdrBaseTypeFree [internal]
5585 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
5586 unsigned char *pMemory,
5587 PFORMAT_STRING pFormat)
5589 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5594 /***********************************************************************
5595 * NdrContextHandleBufferSize [internal]
5597 static void WINAPI NdrContextHandleBufferSize(
5598 PMIDL_STUB_MESSAGE pStubMsg,
5599 unsigned char *pMemory,
5600 PFORMAT_STRING pFormat)
5602 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5604 if (*pFormat != RPC_FC_BIND_CONTEXT)
5606 ERR("invalid format type %x\n", *pFormat);
5607 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5609 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5610 pStubMsg->BufferLength += cbNDRContext;
5613 /***********************************************************************
5614 * NdrContextHandleMarshall [internal]
5616 static unsigned char *WINAPI NdrContextHandleMarshall(
5617 PMIDL_STUB_MESSAGE pStubMsg,
5618 unsigned char *pMemory,
5619 PFORMAT_STRING pFormat)
5621 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5623 if (*pFormat != RPC_FC_BIND_CONTEXT)
5625 ERR("invalid format type %x\n", *pFormat);
5626 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5629 if (pFormat[1] & 0x80)
5630 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
5632 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
5637 /***********************************************************************
5638 * NdrContextHandleUnmarshall [internal]
5640 static unsigned char *WINAPI NdrContextHandleUnmarshall(
5641 PMIDL_STUB_MESSAGE pStubMsg,
5642 unsigned char **ppMemory,
5643 PFORMAT_STRING pFormat,
5644 unsigned char fMustAlloc)
5646 if (*pFormat != RPC_FC_BIND_CONTEXT)
5648 ERR("invalid format type %x\n", *pFormat);
5649 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5652 **(NDR_CCONTEXT **)ppMemory = NULL;
5653 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
5658 /***********************************************************************
5659 * NdrClientContextMarshall [RPCRT4.@]
5661 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5662 NDR_CCONTEXT ContextHandle,
5665 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
5667 ALIGN_POINTER(pStubMsg->Buffer, 4);
5669 /* FIXME: what does fCheck do? */
5670 NDRCContextMarshall(ContextHandle,
5673 pStubMsg->Buffer += cbNDRContext;
5676 /***********************************************************************
5677 * NdrClientContextUnmarshall [RPCRT4.@]
5679 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5680 NDR_CCONTEXT * pContextHandle,
5681 RPC_BINDING_HANDLE BindHandle)
5683 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
5685 ALIGN_POINTER(pStubMsg->Buffer, 4);
5687 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
5688 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5690 NDRCContextUnmarshall(pContextHandle,
5693 pStubMsg->RpcMsg->DataRepresentation);
5695 pStubMsg->Buffer += cbNDRContext;
5698 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5699 NDR_SCONTEXT ContextHandle,
5700 NDR_RUNDOWN RundownRoutine )
5702 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
5705 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
5707 FIXME("(%p): stub\n", pStubMsg);
5711 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
5712 unsigned char* pMemory,
5713 PFORMAT_STRING pFormat)
5715 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
5718 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
5719 PFORMAT_STRING pFormat)
5721 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
5725 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5726 NDR_SCONTEXT ContextHandle,
5727 NDR_RUNDOWN RundownRoutine,
5728 PFORMAT_STRING pFormat)
5730 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
5733 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5734 PFORMAT_STRING pFormat)
5736 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
5740 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
5742 typedef struct ndr_context_handle
5746 } ndr_context_handle;
5748 struct context_handle_entry
5752 RPC_BINDING_HANDLE handle;
5753 ndr_context_handle wire_data;
5756 static struct list context_handle_list = LIST_INIT(context_handle_list);
5758 static CRITICAL_SECTION ndr_context_cs;
5759 static CRITICAL_SECTION_DEBUG ndr_context_debug =
5761 0, 0, &ndr_context_cs,
5762 { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
5763 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
5765 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
5767 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
5769 struct context_handle_entry *che = (struct context_handle_entry*) CContext;
5771 if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
5776 static struct context_handle_entry *context_entry_from_guid(LPGUID uuid)
5778 struct context_handle_entry *che;
5779 LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
5780 if (IsEqualGUID(&che->wire_data.uuid, uuid))
5785 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
5787 struct context_handle_entry *che;
5788 RPC_BINDING_HANDLE handle = NULL;
5790 TRACE("%p\n", CContext);
5792 EnterCriticalSection(&ndr_context_cs);
5793 che = get_context_entry(CContext);
5795 handle = che->handle;
5796 LeaveCriticalSection(&ndr_context_cs);
5799 RpcRaiseException(ERROR_INVALID_HANDLE);
5803 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
5805 struct context_handle_entry *che;
5807 TRACE("%p %p\n", CContext, pBuff);
5811 EnterCriticalSection(&ndr_context_cs);
5812 che = get_context_entry(CContext);
5813 memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
5814 LeaveCriticalSection(&ndr_context_cs);
5818 ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
5819 wire_data->attributes = 0;
5820 wire_data->uuid = GUID_NULL;
5824 static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
5825 RPC_BINDING_HANDLE hBinding,
5826 ndr_context_handle *chi)
5828 struct context_handle_entry *che = NULL;
5830 /* a null UUID means we should free the context handle */
5831 if (IsEqualGUID(&chi->uuid, &GUID_NULL))
5835 che = get_context_entry(*CContext);
5837 return ERROR_INVALID_HANDLE;
5838 list_remove(&che->entry);
5839 RpcBindingFree(&che->handle);
5840 HeapFree(GetProcessHeap(), 0, che);
5844 /* if there's no existing entry matching the GUID, allocate one */
5845 else if (!(che = context_entry_from_guid(&chi->uuid)))
5847 che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
5849 return ERROR_NOT_ENOUGH_MEMORY;
5850 che->magic = NDR_CONTEXT_HANDLE_MAGIC;
5851 RpcBindingCopy(hBinding, &che->handle);
5852 list_add_tail(&context_handle_list, &che->entry);
5853 memcpy(&che->wire_data, chi, sizeof *chi);
5858 return ERROR_SUCCESS;
5861 /***********************************************************************
5862 * NDRCContextUnmarshall [RPCRT4.@]
5864 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
5865 RPC_BINDING_HANDLE hBinding,
5866 void *pBuff, ULONG DataRepresentation)
5870 TRACE("*%p=(%p) %p %p %08x\n",
5871 CContext, *CContext, hBinding, pBuff, DataRepresentation);
5873 EnterCriticalSection(&ndr_context_cs);
5874 r = ndr_update_context_handle(CContext, hBinding, pBuff);
5875 LeaveCriticalSection(&ndr_context_cs);
5877 RpcRaiseException(r);
5880 /***********************************************************************
5881 * NDRSContextMarshall [RPCRT4.@]
5883 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
5885 NDR_RUNDOWN userRunDownIn)
5887 FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn);
5890 /***********************************************************************
5891 * NDRSContextMarshallEx [RPCRT4.@]
5893 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
5894 NDR_SCONTEXT CContext,
5896 NDR_RUNDOWN userRunDownIn)
5898 FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn);
5901 /***********************************************************************
5902 * NDRSContextMarshall2 [RPCRT4.@]
5904 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
5905 NDR_SCONTEXT CContext,
5907 NDR_RUNDOWN userRunDownIn,
5908 void *CtxGuard, ULONG Flags)
5910 FIXME("(%p %p %p %p %p %u): stub\n",
5911 hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags);
5914 /***********************************************************************
5915 * NDRSContextUnmarshall [RPCRT4.@]
5917 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
5918 ULONG DataRepresentation)
5920 FIXME("(%p %08x): stub\n", pBuff, DataRepresentation);
5924 /***********************************************************************
5925 * NDRSContextUnmarshallEx [RPCRT4.@]
5927 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
5929 ULONG DataRepresentation)
5931 FIXME("(%p %p %08x): stub\n", hBinding, pBuff, DataRepresentation);
5935 /***********************************************************************
5936 * NDRSContextUnmarshall2 [RPCRT4.@]
5938 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
5940 ULONG DataRepresentation,
5941 void *CtxGuard, ULONG Flags)
5943 FIXME("(%p %p %08x %p %u): stub\n",
5944 hBinding, pBuff, DataRepresentation, CtxGuard, Flags);