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 * - Encapsulated unions
25 * - Byte count pointers
26 * - transmit_as/represent as
27 * - Multi-dimensional arrays
28 * - Conversion functions (NdrConvert)
29 * - Checks for integer addition overflow
30 * - Checks for out-of-memory conditions
46 #include "wine/unicode.h"
47 #include "wine/rpcfc.h"
49 #include "wine/debug.h"
50 #include "wine/list.h"
52 WINE_DEFAULT_DEBUG_CHANNEL(ole);
55 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
56 (*((UINT32 *)(pchar)) = (uint32))
58 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
59 (*((UINT32 *)(pchar)))
61 /* these would work for i386 too, but less efficient */
62 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
63 (*(pchar) = LOBYTE(LOWORD(uint32)), \
64 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
65 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
66 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
67 (uint32)) /* allow as r-value */
69 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
71 MAKEWORD(*(pchar), *((pchar)+1)), \
72 MAKEWORD(*((pchar)+2), *((pchar)+3))))
75 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
76 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
77 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
78 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
79 *(pchar) = HIBYTE(HIWORD(uint32)), \
80 (uint32)) /* allow as r-value */
82 #define BIG_ENDIAN_UINT32_READ(pchar) \
84 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
85 MAKEWORD(*((pchar)+1), *(pchar))))
87 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
88 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
89 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
90 # define NDR_LOCAL_UINT32_READ(pchar) \
91 BIG_ENDIAN_UINT32_READ(pchar)
93 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
94 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
95 # define NDR_LOCAL_UINT32_READ(pchar) \
96 LITTLE_ENDIAN_UINT32_READ(pchar)
99 /* _Align must be the desired alignment,
100 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
101 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
102 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
103 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
104 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
106 #define STD_OVERFLOW_CHECK(_Msg) do { \
107 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
108 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
109 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
112 #define NDR_TABLE_SIZE 128
113 #define NDR_TABLE_MASK 127
115 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
116 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
117 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
118 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
119 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
121 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
122 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
123 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
125 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
127 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
128 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
129 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
130 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
134 NdrPointerMarshall, NdrPointerMarshall,
135 NdrPointerMarshall, NdrPointerMarshall,
137 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
138 NdrConformantStructMarshall, NdrConformantStructMarshall,
139 NdrConformantVaryingStructMarshall,
140 NdrComplexStructMarshall,
142 NdrConformantArrayMarshall,
143 NdrConformantVaryingArrayMarshall,
144 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
145 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
146 NdrComplexArrayMarshall,
148 NdrConformantStringMarshall, 0, 0,
149 NdrConformantStringMarshall,
150 NdrNonConformantStringMarshall, 0, 0, 0,
152 NdrEncapsulatedUnionMarshall,
153 NdrNonEncapsulatedUnionMarshall,
154 NdrByteCountPointerMarshall,
155 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
157 NdrInterfacePointerMarshall,
159 NdrContextHandleMarshall,
162 NdrUserMarshalMarshall,
167 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
169 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
170 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
171 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
172 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
174 NdrBaseTypeUnmarshall,
176 NdrPointerUnmarshall, NdrPointerUnmarshall,
177 NdrPointerUnmarshall, NdrPointerUnmarshall,
179 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
180 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
181 NdrConformantVaryingStructUnmarshall,
182 NdrComplexStructUnmarshall,
184 NdrConformantArrayUnmarshall,
185 NdrConformantVaryingArrayUnmarshall,
186 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
187 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
188 NdrComplexArrayUnmarshall,
190 NdrConformantStringUnmarshall, 0, 0,
191 NdrConformantStringUnmarshall,
192 NdrNonConformantStringUnmarshall, 0, 0, 0,
194 NdrEncapsulatedUnionUnmarshall,
195 NdrNonEncapsulatedUnionUnmarshall,
196 NdrByteCountPointerUnmarshall,
197 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
199 NdrInterfacePointerUnmarshall,
201 NdrContextHandleUnmarshall,
204 NdrUserMarshalUnmarshall,
209 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
211 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
212 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
213 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
214 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
216 NdrBaseTypeBufferSize,
218 NdrPointerBufferSize, NdrPointerBufferSize,
219 NdrPointerBufferSize, NdrPointerBufferSize,
221 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
222 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
223 NdrConformantVaryingStructBufferSize,
224 NdrComplexStructBufferSize,
226 NdrConformantArrayBufferSize,
227 NdrConformantVaryingArrayBufferSize,
228 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
229 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
230 NdrComplexArrayBufferSize,
232 NdrConformantStringBufferSize, 0, 0,
233 NdrConformantStringBufferSize,
234 NdrNonConformantStringBufferSize, 0, 0, 0,
236 NdrEncapsulatedUnionBufferSize,
237 NdrNonEncapsulatedUnionBufferSize,
238 NdrByteCountPointerBufferSize,
239 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
241 NdrInterfacePointerBufferSize,
243 NdrContextHandleBufferSize,
246 NdrUserMarshalBufferSize,
251 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
253 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
254 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
255 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
256 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
258 NdrBaseTypeMemorySize,
260 NdrPointerMemorySize, NdrPointerMemorySize,
261 NdrPointerMemorySize, NdrPointerMemorySize,
263 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
264 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
265 NdrConformantVaryingStructMemorySize,
266 NdrComplexStructMemorySize,
268 NdrConformantArrayMemorySize,
269 NdrConformantVaryingArrayMemorySize,
270 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
271 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
272 NdrComplexArrayMemorySize,
274 NdrConformantStringMemorySize, 0, 0,
275 NdrConformantStringMemorySize,
276 NdrNonConformantStringMemorySize, 0, 0, 0,
278 NdrEncapsulatedUnionMemorySize,
279 NdrNonEncapsulatedUnionMemorySize,
280 NdrByteCountPointerMemorySize,
281 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
283 NdrInterfacePointerMemorySize,
288 NdrUserMarshalMemorySize,
293 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
295 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
296 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
297 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
298 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
302 NdrPointerFree, NdrPointerFree,
303 NdrPointerFree, NdrPointerFree,
305 NdrSimpleStructFree, NdrSimpleStructFree,
306 NdrConformantStructFree, NdrConformantStructFree,
307 NdrConformantVaryingStructFree,
308 NdrComplexStructFree,
310 NdrConformantArrayFree,
311 NdrConformantVaryingArrayFree,
312 NdrFixedArrayFree, NdrFixedArrayFree,
313 NdrVaryingArrayFree, NdrVaryingArrayFree,
319 NdrEncapsulatedUnionFree,
320 NdrNonEncapsulatedUnionFree,
322 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
324 NdrInterfacePointerFree,
335 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
337 /* hmm, this is probably supposed to do more? */
338 return pStubMsg->pfnAllocate(len);
341 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
343 pStubMsg->pfnFree(Pointer);
346 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
348 return (*(const ULONG *)pFormat != -1);
351 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
353 ALIGN_POINTER(pStubMsg->Buffer, 4);
354 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
355 pStubMsg->Buffer += 4;
356 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
357 if (pStubMsg->fHasNewCorrDesc)
363 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
365 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
367 pStubMsg->Offset = 0;
368 pStubMsg->ActualCount = pStubMsg->MaxCount;
372 ALIGN_POINTER(pStubMsg->Buffer, 4);
373 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
374 pStubMsg->Buffer += 4;
375 TRACE("offset is %d\n", pStubMsg->Offset);
376 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
377 pStubMsg->Buffer += 4;
378 TRACE("variance is %d\n", pStubMsg->ActualCount);
380 if ((pStubMsg->ActualCount > MaxValue) ||
381 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
383 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
384 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
385 RpcRaiseException(RPC_S_INVALID_BOUND);
390 if (pStubMsg->fHasNewCorrDesc)
396 /* writes the conformance value to the buffer */
397 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
399 ALIGN_POINTER(pStubMsg->Buffer, 4);
400 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
401 pStubMsg->Buffer += 4;
404 /* writes the variance values to the buffer */
405 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
407 ALIGN_POINTER(pStubMsg->Buffer, 4);
408 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
409 pStubMsg->Buffer += 4;
410 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
411 pStubMsg->Buffer += 4;
414 /* requests buffer space for the conformance value */
415 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
417 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
418 pStubMsg->BufferLength += 4;
421 /* requests buffer space for the variance values */
422 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
424 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
425 pStubMsg->BufferLength += 8;
428 PFORMAT_STRING ComputeConformanceOrVariance(
429 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
430 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
432 BYTE dtype = pFormat[0] & 0xf;
433 short ofs = *(const short *)&pFormat[2];
437 if (!IsConformanceOrVariancePresent(pFormat)) {
438 /* null descriptor */
443 switch (pFormat[0] & 0xf0) {
444 case RPC_FC_NORMAL_CONFORMANCE:
445 TRACE("normal conformance, ofs=%d\n", ofs);
448 case RPC_FC_POINTER_CONFORMANCE:
449 TRACE("pointer conformance, ofs=%d\n", ofs);
450 ptr = pStubMsg->Memory;
452 case RPC_FC_TOP_LEVEL_CONFORMANCE:
453 TRACE("toplevel conformance, ofs=%d\n", ofs);
454 if (pStubMsg->StackTop) {
455 ptr = pStubMsg->StackTop;
458 /* -Os mode, *pCount is already set */
462 case RPC_FC_CONSTANT_CONFORMANCE:
463 data = ofs | ((DWORD)pFormat[1] << 16);
464 TRACE("constant conformance, val=%d\n", data);
467 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
468 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
469 if (pStubMsg->StackTop) {
470 ptr = pStubMsg->StackTop;
478 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
481 switch (pFormat[1]) {
482 case RPC_FC_DEREFERENCE:
483 ptr = *(LPVOID*)((char *)ptr + ofs);
485 case RPC_FC_CALLBACK:
487 unsigned char *old_stack_top = pStubMsg->StackTop;
488 pStubMsg->StackTop = ptr;
490 /* ofs is index into StubDesc->apfnExprEval */
491 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
492 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
494 pStubMsg->StackTop = old_stack_top;
496 /* the callback function always stores the computed value in MaxCount */
497 *pCount = pStubMsg->MaxCount;
501 ptr = (char *)ptr + ofs;
514 data = *(USHORT*)ptr;
525 FIXME("unknown conformance data type %x\n", dtype);
528 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
531 switch (pFormat[1]) {
532 case RPC_FC_DEREFERENCE: /* already handled */
549 FIXME("unknown conformance op %d\n", pFormat[1]);
554 TRACE("resulting conformance is %ld\n", *pCount);
555 if (pStubMsg->fHasNewCorrDesc)
561 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
562 * the result overflows 32-bits */
563 static inline ULONG safe_multiply(ULONG a, ULONG b)
565 ULONGLONG ret = (ULONGLONG)a * b;
566 if (ret > 0xffffffff)
568 RpcRaiseException(RPC_S_INVALID_BOUND);
576 * NdrConformantString:
578 * What MS calls a ConformantString is, in DCE terminology,
579 * a Varying-Conformant String.
581 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
582 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
583 * into unmarshalled string)
584 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
586 * data: CHARTYPE[maxlen]
588 * ], where CHARTYPE is the appropriate character type (specified externally)
592 /***********************************************************************
593 * NdrConformantStringMarshall [RPCRT4.@]
595 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
596 unsigned char *pszMessage, PFORMAT_STRING pFormat)
600 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
602 if (*pFormat == RPC_FC_C_CSTRING) {
603 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
604 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
607 else if (*pFormat == RPC_FC_C_WSTRING) {
608 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
609 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
613 ERR("Unhandled string type: %#x\n", *pFormat);
614 /* FIXME: raise an exception. */
618 if (pFormat[1] == RPC_FC_STRING_SIZED)
619 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
621 pStubMsg->MaxCount = pStubMsg->ActualCount;
622 pStubMsg->Offset = 0;
623 WriteConformance(pStubMsg);
624 WriteVariance(pStubMsg);
626 size = safe_multiply(esize, pStubMsg->ActualCount);
627 memcpy(pStubMsg->Buffer, pszMessage, size); /* the string itself */
628 pStubMsg->Buffer += size;
630 STD_OVERFLOW_CHECK(pStubMsg);
633 return NULL; /* is this always right? */
636 /***********************************************************************
637 * NdrConformantStringBufferSize [RPCRT4.@]
639 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
640 unsigned char* pMemory, PFORMAT_STRING pFormat)
644 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
646 SizeConformance(pStubMsg);
647 SizeVariance(pStubMsg);
649 if (*pFormat == RPC_FC_C_CSTRING) {
650 TRACE("string=%s\n", debugstr_a((char*)pMemory));
651 pStubMsg->ActualCount = strlen((char*)pMemory)+1;
654 else if (*pFormat == RPC_FC_C_WSTRING) {
655 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
656 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;
660 ERR("Unhandled string type: %#x\n", *pFormat);
661 /* FIXME: raise an exception */
665 if (pFormat[1] == RPC_FC_STRING_SIZED)
666 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
668 pStubMsg->MaxCount = pStubMsg->ActualCount;
670 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
673 /************************************************************************
674 * NdrConformantStringMemorySize [RPCRT4.@]
676 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
677 PFORMAT_STRING pFormat )
681 FIXME("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
683 assert(pStubMsg && pFormat);
685 if (*pFormat == RPC_FC_C_CSTRING) {
686 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
688 else if (*pFormat == RPC_FC_C_WSTRING) {
689 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
692 ERR("Unhandled string type: %#x\n", *pFormat);
693 /* FIXME: raise an exception */
696 if (pFormat[1] != RPC_FC_PAD) {
697 FIXME("sized string format=%d\n", pFormat[1]);
700 TRACE(" --> %u\n", rslt);
704 /************************************************************************
705 * NdrConformantStringUnmarshall [RPCRT4.@]
707 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
708 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
710 ULONG bufsize, memsize, esize, i;
712 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
713 pStubMsg, *ppMemory, pFormat, fMustAlloc);
715 assert(pFormat && ppMemory && pStubMsg);
717 ReadConformance(pStubMsg, NULL);
718 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
720 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
721 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
723 ERR("Unhandled string type: %#x\n", *pFormat);
724 /* FIXME: raise an exception */
728 memsize = safe_multiply(esize, pStubMsg->MaxCount);
729 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
731 /* strings must always have null terminating bytes */
734 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
735 RpcRaiseException(RPC_S_INVALID_BOUND);
738 for (i = bufsize - esize; i < bufsize; i++)
739 if (pStubMsg->Buffer[i] != 0)
741 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
742 i, pStubMsg->Buffer[i]);
743 RpcRaiseException(RPC_S_INVALID_BOUND);
747 if (fMustAlloc || !*ppMemory)
748 *ppMemory = NdrAllocate(pStubMsg, memsize);
750 memcpy(*ppMemory, pStubMsg->Buffer, bufsize);
752 pStubMsg->Buffer += bufsize;
754 if (*pFormat == RPC_FC_C_CSTRING) {
755 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
757 else if (*pFormat == RPC_FC_C_WSTRING) {
758 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
761 return NULL; /* FIXME: is this always right? */
764 /***********************************************************************
765 * NdrNonConformantStringMarshall [RPCRT4.@]
767 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
768 unsigned char *pMemory,
769 PFORMAT_STRING pFormat)
775 /***********************************************************************
776 * NdrNonConformantStringUnmarshall [RPCRT4.@]
778 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
779 unsigned char **ppMemory,
780 PFORMAT_STRING pFormat,
781 unsigned char fMustAlloc)
787 /***********************************************************************
788 * NdrNonConformantStringBufferSize [RPCRT4.@]
790 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
791 unsigned char *pMemory,
792 PFORMAT_STRING pFormat)
797 /***********************************************************************
798 * NdrNonConformantStringMemorySize [RPCRT4.@]
800 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
801 PFORMAT_STRING pFormat)
807 static inline void dump_pointer_attr(unsigned char attr)
809 if (attr & RPC_FC_P_ALLOCALLNODES)
810 TRACE(" RPC_FC_P_ALLOCALLNODES");
811 if (attr & RPC_FC_P_DONTFREE)
812 TRACE(" RPC_FC_P_DONTFREE");
813 if (attr & RPC_FC_P_ONSTACK)
814 TRACE(" RPC_FC_P_ONSTACK");
815 if (attr & RPC_FC_P_SIMPLEPOINTER)
816 TRACE(" RPC_FC_P_SIMPLEPOINTER");
817 if (attr & RPC_FC_P_DEREF)
818 TRACE(" RPC_FC_P_DEREF");
822 /***********************************************************************
823 * PointerMarshall [internal]
825 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
826 unsigned char *Buffer,
827 unsigned char *Pointer,
828 PFORMAT_STRING pFormat)
830 unsigned type = pFormat[0], attr = pFormat[1];
834 int pointer_needs_marshaling;
836 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
837 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
839 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
840 else desc = pFormat + *(const SHORT*)pFormat;
843 case RPC_FC_RP: /* ref pointer (always non-null) */
844 #if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
846 RpcRaiseException(RPC_X_NULL_REF_POINTER);
848 pointer_needs_marshaling = 1;
850 case RPC_FC_UP: /* unique pointer */
851 case RPC_FC_OP: /* object pointer - same as unique here */
853 pointer_needs_marshaling = 1;
855 pointer_needs_marshaling = 0;
856 pointer_id = (ULONG)Pointer;
857 TRACE("writing 0x%08x to buffer\n", pointer_id);
858 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
861 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
862 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
863 TRACE("writing 0x%08x to buffer\n", pointer_id);
864 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
867 FIXME("unhandled ptr type=%02x\n", type);
868 RpcRaiseException(RPC_X_BAD_STUB_DATA);
872 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
874 if (pointer_needs_marshaling) {
875 if (attr & RPC_FC_P_DEREF) {
876 Pointer = *(unsigned char**)Pointer;
877 TRACE("deref => %p\n", Pointer);
879 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
880 if (m) m(pStubMsg, Pointer, desc);
881 else FIXME("no marshaller for data type=%02x\n", *desc);
884 STD_OVERFLOW_CHECK(pStubMsg);
887 /***********************************************************************
888 * PointerUnmarshall [internal]
890 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
891 unsigned char *Buffer,
892 unsigned char **pPointer,
893 PFORMAT_STRING pFormat,
894 unsigned char fMustAlloc)
896 unsigned type = pFormat[0], attr = pFormat[1];
899 DWORD pointer_id = 0;
900 int pointer_needs_unmarshaling;
902 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pFormat, fMustAlloc);
903 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
905 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
906 else desc = pFormat + *(const SHORT*)pFormat;
909 case RPC_FC_RP: /* ref pointer (always non-null) */
910 pointer_needs_unmarshaling = 1;
912 case RPC_FC_UP: /* unique pointer */
913 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
914 TRACE("pointer_id is 0x%08x\n", pointer_id);
916 pointer_needs_unmarshaling = 1;
919 pointer_needs_unmarshaling = 0;
922 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
923 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
924 TRACE("pointer_id is 0x%08x\n", pointer_id);
925 if (!fMustAlloc && *pPointer)
927 FIXME("free object pointer %p\n", *pPointer);
931 pointer_needs_unmarshaling = 1;
933 pointer_needs_unmarshaling = 0;
936 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
937 TRACE("pointer_id is 0x%08x\n", pointer_id);
938 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
939 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
942 FIXME("unhandled ptr type=%02x\n", type);
943 RpcRaiseException(RPC_X_BAD_STUB_DATA);
947 if (pointer_needs_unmarshaling) {
948 if (attr & RPC_FC_P_DEREF) {
949 if (!*pPointer || fMustAlloc)
950 *pPointer = NdrAllocate(pStubMsg, sizeof(void *));
951 pPointer = *(unsigned char***)pPointer;
952 TRACE("deref => %p\n", pPointer);
954 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
955 if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
956 else FIXME("no unmarshaller for data type=%02x\n", *desc);
958 if (type == RPC_FC_FP)
959 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
963 TRACE("pointer=%p\n", *pPointer);
966 /***********************************************************************
967 * PointerBufferSize [internal]
969 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
970 unsigned char *Pointer,
971 PFORMAT_STRING pFormat)
973 unsigned type = pFormat[0], attr = pFormat[1];
976 int pointer_needs_sizing;
979 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
980 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
982 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
983 else desc = pFormat + *(const SHORT*)pFormat;
986 case RPC_FC_RP: /* ref pointer (always non-null) */
990 /* NULL pointer has no further representation */
995 pointer_needs_sizing = !NdrFullPointerQueryPointer(
996 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
997 if (!pointer_needs_sizing)
1001 FIXME("unhandled ptr type=%02x\n", type);
1002 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1006 if (attr & RPC_FC_P_DEREF) {
1007 Pointer = *(unsigned char**)Pointer;
1008 TRACE("deref => %p\n", Pointer);
1011 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1012 if (m) m(pStubMsg, Pointer, desc);
1013 else FIXME("no buffersizer for data type=%02x\n", *desc);
1016 /***********************************************************************
1017 * PointerMemorySize [internal]
1019 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1020 unsigned char *Buffer,
1021 PFORMAT_STRING pFormat)
1023 unsigned type = pFormat[0], attr = pFormat[1];
1024 PFORMAT_STRING desc;
1027 FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat);
1028 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1030 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1031 else desc = pFormat + *(const SHORT*)pFormat;
1034 case RPC_FC_RP: /* ref pointer (always non-null) */
1037 FIXME("unhandled ptr type=%02x\n", type);
1038 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1041 if (attr & RPC_FC_P_DEREF) {
1045 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1046 if (m) m(pStubMsg, desc);
1047 else FIXME("no memorysizer for data type=%02x\n", *desc);
1052 /***********************************************************************
1053 * PointerFree [internal]
1055 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1056 unsigned char *Pointer,
1057 PFORMAT_STRING pFormat)
1059 unsigned type = pFormat[0], attr = pFormat[1];
1060 PFORMAT_STRING desc;
1063 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1064 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1065 if (attr & RPC_FC_P_DONTFREE) return;
1067 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1068 else desc = pFormat + *(const SHORT*)pFormat;
1070 if (!Pointer) return;
1072 if (type == RPC_FC_FP) {
1073 int pointer_needs_freeing = NdrFullPointerFree(
1074 pStubMsg->FullPtrXlatTables, Pointer);
1075 if (!pointer_needs_freeing)
1079 if (attr & RPC_FC_P_DEREF) {
1080 Pointer = *(unsigned char**)Pointer;
1081 TRACE("deref => %p\n", Pointer);
1084 m = NdrFreer[*desc & NDR_TABLE_MASK];
1085 if (m) m(pStubMsg, Pointer, desc);
1087 /* hmm... is this sensible?
1088 * perhaps we should check if the memory comes from NdrAllocate,
1089 * and deallocate only if so - checking if the pointer is between
1090 * BufferStart and BufferEnd is probably no good since the buffer
1091 * may be reallocated when the server wants to marshal the reply */
1093 case RPC_FC_BOGUS_STRUCT:
1094 case RPC_FC_BOGUS_ARRAY:
1095 case RPC_FC_USER_MARSHAL:
1097 case RPC_FC_CVARRAY:
1100 FIXME("unhandled data type=%02x\n", *desc);
1102 case RPC_FC_C_CSTRING:
1103 case RPC_FC_C_WSTRING:
1104 if (pStubMsg->ReuseBuffer) goto notfree;
1110 if (attr & RPC_FC_P_ONSTACK) {
1111 TRACE("not freeing stack ptr %p\n", Pointer);
1114 TRACE("freeing %p\n", Pointer);
1115 NdrFree(pStubMsg, Pointer);
1118 TRACE("not freeing %p\n", Pointer);
1121 /***********************************************************************
1122 * EmbeddedPointerMarshall
1124 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1125 unsigned char *pMemory,
1126 PFORMAT_STRING pFormat)
1128 unsigned char *Mark = pStubMsg->BufferMark;
1129 unsigned long Offset = pStubMsg->Offset;
1130 unsigned ofs, rep, count, stride, xofs;
1132 unsigned char *saved_buffer = NULL;
1134 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1136 if (*pFormat != RPC_FC_PP) return NULL;
1139 if (pStubMsg->PointerBufferMark)
1141 saved_buffer = pStubMsg->Buffer;
1142 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1143 pStubMsg->PointerBufferMark = NULL;
1146 while (pFormat[0] != RPC_FC_END) {
1147 switch (pFormat[0]) {
1149 FIXME("unknown repeat type %d\n", pFormat[0]);
1150 case RPC_FC_NO_REPEAT:
1158 case RPC_FC_FIXED_REPEAT:
1159 rep = *(const WORD*)&pFormat[2];
1160 stride = *(const WORD*)&pFormat[4];
1161 ofs = *(const WORD*)&pFormat[6];
1162 count = *(const WORD*)&pFormat[8];
1166 case RPC_FC_VARIABLE_REPEAT:
1167 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1168 stride = *(const WORD*)&pFormat[2];
1169 ofs = *(const WORD*)&pFormat[4];
1170 count = *(const WORD*)&pFormat[6];
1171 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1175 for (i = 0; i < rep; i++) {
1176 PFORMAT_STRING info = pFormat;
1177 unsigned char *membase = pMemory + ofs + (i * stride);
1178 unsigned char *bufbase = Mark + ofs + (i * stride);
1181 for (u=0; u<count; u++,info+=8) {
1182 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1183 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1184 unsigned char *saved_memory = pStubMsg->Memory;
1186 pStubMsg->Memory = pMemory;
1187 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1188 pStubMsg->Memory = saved_memory;
1191 pFormat += 8 * count;
1196 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1197 pStubMsg->Buffer = saved_buffer;
1200 STD_OVERFLOW_CHECK(pStubMsg);
1205 /***********************************************************************
1206 * EmbeddedPointerUnmarshall
1208 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1209 unsigned char **ppMemory,
1210 PFORMAT_STRING pFormat,
1211 unsigned char fMustAlloc)
1213 unsigned char *Mark = pStubMsg->BufferMark;
1214 unsigned long Offset = pStubMsg->Offset;
1215 unsigned ofs, rep, count, stride, xofs;
1217 unsigned char *saved_buffer = NULL;
1219 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1221 if (*pFormat != RPC_FC_PP) return NULL;
1224 if (pStubMsg->PointerBufferMark)
1226 saved_buffer = pStubMsg->Buffer;
1227 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1228 pStubMsg->PointerBufferMark = NULL;
1231 while (pFormat[0] != RPC_FC_END) {
1232 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1233 switch (pFormat[0]) {
1235 FIXME("unknown repeat type %d\n", pFormat[0]);
1236 case RPC_FC_NO_REPEAT:
1244 case RPC_FC_FIXED_REPEAT:
1245 rep = *(const WORD*)&pFormat[2];
1246 stride = *(const WORD*)&pFormat[4];
1247 ofs = *(const WORD*)&pFormat[6];
1248 count = *(const WORD*)&pFormat[8];
1252 case RPC_FC_VARIABLE_REPEAT:
1253 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1254 stride = *(const WORD*)&pFormat[2];
1255 ofs = *(const WORD*)&pFormat[4];
1256 count = *(const WORD*)&pFormat[6];
1257 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1261 /* ofs doesn't seem to matter in this context */
1262 for (i = 0; i < rep; i++) {
1263 PFORMAT_STRING info = pFormat;
1264 unsigned char *membase = *ppMemory + ofs + (i * stride);
1265 unsigned char *bufbase = Mark + ofs + (i * stride);
1268 for (u=0; u<count; u++,info+=8) {
1269 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1270 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1271 PointerUnmarshall(pStubMsg, bufptr, (unsigned char**)memptr, info+4, TRUE);
1274 pFormat += 8 * count;
1279 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1280 pStubMsg->Buffer = saved_buffer;
1286 /***********************************************************************
1287 * EmbeddedPointerBufferSize
1289 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1290 unsigned char *pMemory,
1291 PFORMAT_STRING pFormat)
1293 unsigned long Offset = pStubMsg->Offset;
1294 unsigned ofs, rep, count, stride, xofs;
1296 ULONG saved_buffer_length = 0;
1298 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1300 if (pStubMsg->IgnoreEmbeddedPointers) return;
1302 if (*pFormat != RPC_FC_PP) return;
1305 if (pStubMsg->PointerLength)
1307 saved_buffer_length = pStubMsg->BufferLength;
1308 pStubMsg->BufferLength = pStubMsg->PointerLength;
1309 pStubMsg->PointerLength = 0;
1312 while (pFormat[0] != RPC_FC_END) {
1313 switch (pFormat[0]) {
1315 FIXME("unknown repeat type %d\n", pFormat[0]);
1316 case RPC_FC_NO_REPEAT:
1324 case RPC_FC_FIXED_REPEAT:
1325 rep = *(const WORD*)&pFormat[2];
1326 stride = *(const WORD*)&pFormat[4];
1327 ofs = *(const WORD*)&pFormat[6];
1328 count = *(const WORD*)&pFormat[8];
1332 case RPC_FC_VARIABLE_REPEAT:
1333 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1334 stride = *(const WORD*)&pFormat[2];
1335 ofs = *(const WORD*)&pFormat[4];
1336 count = *(const WORD*)&pFormat[6];
1337 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1341 for (i = 0; i < rep; i++) {
1342 PFORMAT_STRING info = pFormat;
1343 unsigned char *membase = pMemory + ofs + (i * stride);
1346 for (u=0; u<count; u++,info+=8) {
1347 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1348 unsigned char *saved_memory = pStubMsg->Memory;
1350 pStubMsg->Memory = pMemory;
1351 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1352 pStubMsg->Memory = saved_memory;
1355 pFormat += 8 * count;
1358 if (saved_buffer_length)
1360 pStubMsg->PointerLength = pStubMsg->BufferLength;
1361 pStubMsg->BufferLength = saved_buffer_length;
1365 /***********************************************************************
1366 * EmbeddedPointerMemorySize [internal]
1368 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1369 PFORMAT_STRING pFormat)
1371 unsigned long Offset = pStubMsg->Offset;
1372 unsigned char *Mark = pStubMsg->BufferMark;
1373 unsigned ofs, rep, count, stride, xofs;
1376 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1378 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1380 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1382 if (*pFormat != RPC_FC_PP) return 0;
1385 while (pFormat[0] != RPC_FC_END) {
1386 switch (pFormat[0]) {
1388 FIXME("unknown repeat type %d\n", pFormat[0]);
1389 case RPC_FC_NO_REPEAT:
1397 case RPC_FC_FIXED_REPEAT:
1398 rep = *(const WORD*)&pFormat[2];
1399 stride = *(const WORD*)&pFormat[4];
1400 ofs = *(const WORD*)&pFormat[6];
1401 count = *(const WORD*)&pFormat[8];
1405 case RPC_FC_VARIABLE_REPEAT:
1406 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1407 stride = *(const WORD*)&pFormat[2];
1408 ofs = *(const WORD*)&pFormat[4];
1409 count = *(const WORD*)&pFormat[6];
1410 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1414 /* ofs doesn't seem to matter in this context */
1415 for (i = 0; i < rep; i++) {
1416 PFORMAT_STRING info = pFormat;
1417 unsigned char *bufbase = Mark + ofs + (i * stride);
1419 for (u=0; u<count; u++,info+=8) {
1420 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1421 PointerMemorySize(pStubMsg, bufptr, info+4);
1424 pFormat += 8 * count;
1430 /***********************************************************************
1431 * EmbeddedPointerFree [internal]
1433 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1434 unsigned char *pMemory,
1435 PFORMAT_STRING pFormat)
1437 unsigned long Offset = pStubMsg->Offset;
1438 unsigned ofs, rep, count, stride, xofs;
1441 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1442 if (*pFormat != RPC_FC_PP) return;
1445 while (pFormat[0] != RPC_FC_END) {
1446 switch (pFormat[0]) {
1448 FIXME("unknown repeat type %d\n", pFormat[0]);
1449 case RPC_FC_NO_REPEAT:
1457 case RPC_FC_FIXED_REPEAT:
1458 rep = *(const WORD*)&pFormat[2];
1459 stride = *(const WORD*)&pFormat[4];
1460 ofs = *(const WORD*)&pFormat[6];
1461 count = *(const WORD*)&pFormat[8];
1465 case RPC_FC_VARIABLE_REPEAT:
1466 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1467 stride = *(const WORD*)&pFormat[2];
1468 ofs = *(const WORD*)&pFormat[4];
1469 count = *(const WORD*)&pFormat[6];
1470 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1474 for (i = 0; i < rep; i++) {
1475 PFORMAT_STRING info = pFormat;
1476 unsigned char *membase = pMemory + (i * stride);
1479 for (u=0; u<count; u++,info+=8) {
1480 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1481 unsigned char *saved_memory = pStubMsg->Memory;
1483 pStubMsg->Memory = pMemory;
1484 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1485 pStubMsg->Memory = saved_memory;
1488 pFormat += 8 * count;
1492 /***********************************************************************
1493 * NdrPointerMarshall [RPCRT4.@]
1495 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1496 unsigned char *pMemory,
1497 PFORMAT_STRING pFormat)
1499 unsigned char *Buffer;
1501 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1503 /* incremement the buffer here instead of in PointerMarshall,
1504 * as that is used by embedded pointers which already handle the incrementing
1505 * the buffer, and shouldn't write any additional pointer data to the wire */
1506 if (*pFormat != RPC_FC_RP)
1508 ALIGN_POINTER(pStubMsg->Buffer, 4);
1509 Buffer = pStubMsg->Buffer;
1510 pStubMsg->Buffer += 4;
1513 Buffer = pStubMsg->Buffer;
1515 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1517 STD_OVERFLOW_CHECK(pStubMsg);
1522 /***********************************************************************
1523 * NdrPointerUnmarshall [RPCRT4.@]
1525 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1526 unsigned char **ppMemory,
1527 PFORMAT_STRING pFormat,
1528 unsigned char fMustAlloc)
1530 unsigned char *Buffer;
1532 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1534 /* incremement the buffer here instead of in PointerUnmarshall,
1535 * as that is used by embedded pointers which already handle the incrementing
1536 * the buffer, and shouldn't read any additional pointer data from the
1538 if (*pFormat != RPC_FC_RP)
1540 ALIGN_POINTER(pStubMsg->Buffer, 4);
1541 Buffer = pStubMsg->Buffer;
1542 pStubMsg->Buffer += 4;
1545 Buffer = pStubMsg->Buffer;
1547 PointerUnmarshall(pStubMsg, Buffer, ppMemory, pFormat, fMustAlloc);
1552 /***********************************************************************
1553 * NdrPointerBufferSize [RPCRT4.@]
1555 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1556 unsigned char *pMemory,
1557 PFORMAT_STRING pFormat)
1559 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1561 /* incremement the buffer length here instead of in PointerBufferSize,
1562 * as that is used by embedded pointers which already handle the buffer
1563 * length, and shouldn't write anything more to the wire */
1564 if (*pFormat != RPC_FC_RP)
1566 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1567 pStubMsg->BufferLength += 4;
1570 PointerBufferSize(pStubMsg, pMemory, pFormat);
1573 /***********************************************************************
1574 * NdrPointerMemorySize [RPCRT4.@]
1576 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1577 PFORMAT_STRING pFormat)
1579 /* unsigned size = *(LPWORD)(pFormat+2); */
1580 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1581 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1585 /***********************************************************************
1586 * NdrPointerFree [RPCRT4.@]
1588 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1589 unsigned char *pMemory,
1590 PFORMAT_STRING pFormat)
1592 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1593 PointerFree(pStubMsg, pMemory, pFormat);
1596 /***********************************************************************
1597 * NdrSimpleTypeMarshall [RPCRT4.@]
1599 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1600 unsigned char FormatChar )
1602 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1605 /***********************************************************************
1606 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1608 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1609 unsigned char FormatChar )
1611 NdrBaseTypeUnmarshall(pStubMsg, &pMemory, &FormatChar, 0);
1614 /***********************************************************************
1615 * NdrSimpleStructMarshall [RPCRT4.@]
1617 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1618 unsigned char *pMemory,
1619 PFORMAT_STRING pFormat)
1621 unsigned size = *(const WORD*)(pFormat+2);
1622 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1624 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1626 memcpy(pStubMsg->Buffer, pMemory, size);
1627 pStubMsg->BufferMark = pStubMsg->Buffer;
1628 pStubMsg->Buffer += size;
1630 if (pFormat[0] != RPC_FC_STRUCT)
1631 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1633 STD_OVERFLOW_CHECK(pStubMsg);
1638 /***********************************************************************
1639 * NdrSimpleStructUnmarshall [RPCRT4.@]
1641 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1642 unsigned char **ppMemory,
1643 PFORMAT_STRING pFormat,
1644 unsigned char fMustAlloc)
1646 unsigned size = *(const WORD*)(pFormat+2);
1647 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1649 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1652 *ppMemory = NdrAllocate(pStubMsg, size);
1653 memcpy(*ppMemory, pStubMsg->Buffer, size);
1655 if (!pStubMsg->IsClient && !*ppMemory)
1656 /* for servers, we just point straight into the RPC buffer */
1657 *ppMemory = pStubMsg->Buffer;
1659 /* for clients, memory should be provided by caller */
1660 memcpy(*ppMemory, pStubMsg->Buffer, size);
1663 pStubMsg->BufferMark = pStubMsg->Buffer;
1664 pStubMsg->Buffer += size;
1666 if (pFormat[0] != RPC_FC_STRUCT)
1667 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat+4, fMustAlloc);
1672 /***********************************************************************
1673 * NdrSimpleStructBufferSize [RPCRT4.@]
1675 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1676 unsigned char *pMemory,
1677 PFORMAT_STRING pFormat)
1679 unsigned size = *(const WORD*)(pFormat+2);
1680 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1682 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1684 pStubMsg->BufferLength += size;
1685 if (pFormat[0] != RPC_FC_STRUCT)
1686 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1689 /***********************************************************************
1690 * NdrSimpleStructMemorySize [RPCRT4.@]
1692 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1693 PFORMAT_STRING pFormat)
1695 unsigned short size = *(const WORD *)(pFormat+2);
1697 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1699 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1700 pStubMsg->MemorySize += size;
1701 pStubMsg->Buffer += size;
1703 if (pFormat[0] != RPC_FC_STRUCT)
1704 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1708 /***********************************************************************
1709 * NdrSimpleStructFree [RPCRT4.@]
1711 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1712 unsigned char *pMemory,
1713 PFORMAT_STRING pFormat)
1715 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1716 if (pFormat[0] != RPC_FC_STRUCT)
1717 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1721 static unsigned long EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg,
1722 PFORMAT_STRING pFormat)
1726 case RPC_FC_PSTRUCT:
1727 case RPC_FC_CSTRUCT:
1728 case RPC_FC_BOGUS_STRUCT:
1729 case RPC_FC_SMFARRAY:
1730 case RPC_FC_SMVARRAY:
1731 return *(const WORD*)&pFormat[2];
1732 case RPC_FC_USER_MARSHAL:
1733 return *(const WORD*)&pFormat[4];
1734 case RPC_FC_NON_ENCAPSULATED_UNION:
1736 if (pStubMsg->fHasNewCorrDesc)
1741 pFormat += *(const SHORT*)pFormat;
1742 return *(const SHORT*)pFormat;
1744 return sizeof(void *);
1746 FIXME("unhandled embedded type %02x\n", *pFormat);
1752 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1753 PFORMAT_STRING pFormat)
1755 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1759 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1763 return m(pStubMsg, pFormat);
1767 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1768 unsigned char *pMemory,
1769 PFORMAT_STRING pFormat,
1770 PFORMAT_STRING pPointer)
1772 PFORMAT_STRING desc;
1776 while (*pFormat != RPC_FC_END) {
1782 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
1783 memcpy(pStubMsg->Buffer, pMemory, 1);
1784 pStubMsg->Buffer += 1;
1790 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1791 memcpy(pStubMsg->Buffer, pMemory, 2);
1792 pStubMsg->Buffer += 2;
1798 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
1799 memcpy(pStubMsg->Buffer, pMemory, 4);
1800 pStubMsg->Buffer += 4;
1804 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1805 memcpy(pStubMsg->Buffer, pMemory, 8);
1806 pStubMsg->Buffer += 8;
1809 case RPC_FC_POINTER:
1811 unsigned char *saved_buffer;
1812 int pointer_buffer_mark_set = 0;
1813 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1814 saved_buffer = pStubMsg->Buffer;
1815 if (pStubMsg->PointerBufferMark)
1817 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1818 pStubMsg->PointerBufferMark = NULL;
1819 pointer_buffer_mark_set = 1;
1822 pStubMsg->Buffer += 4; /* for pointer ID */
1823 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
1824 if (pointer_buffer_mark_set)
1826 STD_OVERFLOW_CHECK(pStubMsg);
1827 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1828 pStubMsg->Buffer = saved_buffer + 4;
1834 case RPC_FC_ALIGNM4:
1835 ALIGN_POINTER(pMemory, 4);
1837 case RPC_FC_ALIGNM8:
1838 ALIGN_POINTER(pMemory, 8);
1840 case RPC_FC_STRUCTPAD1:
1841 case RPC_FC_STRUCTPAD2:
1842 case RPC_FC_STRUCTPAD3:
1843 case RPC_FC_STRUCTPAD4:
1844 case RPC_FC_STRUCTPAD5:
1845 case RPC_FC_STRUCTPAD6:
1846 case RPC_FC_STRUCTPAD7:
1847 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1849 case RPC_FC_EMBEDDED_COMPLEX:
1850 pMemory += pFormat[1];
1852 desc = pFormat + *(const SHORT*)pFormat;
1853 size = EmbeddedComplexSize(pStubMsg, desc);
1854 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1855 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1858 /* for some reason interface pointers aren't generated as
1859 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
1860 * they still need the derefencing treatment that pointers are
1862 if (*desc == RPC_FC_IP)
1863 m(pStubMsg, *(unsigned char **)pMemory, desc);
1865 m(pStubMsg, pMemory, desc);
1867 else FIXME("no marshaller for embedded type %02x\n", *desc);
1874 FIXME("unhandled format 0x%02x\n", *pFormat);
1882 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1883 unsigned char *pMemory,
1884 PFORMAT_STRING pFormat,
1885 PFORMAT_STRING pPointer)
1887 PFORMAT_STRING desc;
1891 while (*pFormat != RPC_FC_END) {
1897 memcpy(pMemory, pStubMsg->Buffer, 1);
1898 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
1899 pStubMsg->Buffer += 1;
1905 memcpy(pMemory, pStubMsg->Buffer, 2);
1906 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1907 pStubMsg->Buffer += 2;
1913 memcpy(pMemory, pStubMsg->Buffer, 4);
1914 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
1915 pStubMsg->Buffer += 4;
1919 memcpy(pMemory, pStubMsg->Buffer, 8);
1920 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1921 pStubMsg->Buffer += 8;
1924 case RPC_FC_POINTER:
1926 unsigned char *saved_buffer;
1927 int pointer_buffer_mark_set = 0;
1928 TRACE("pointer => %p\n", pMemory);
1929 ALIGN_POINTER(pStubMsg->Buffer, 4);
1930 saved_buffer = pStubMsg->Buffer;
1931 if (pStubMsg->PointerBufferMark)
1933 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1934 pStubMsg->PointerBufferMark = NULL;
1935 pointer_buffer_mark_set = 1;
1938 pStubMsg->Buffer += 4; /* for pointer ID */
1940 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, pPointer, TRUE);
1941 if (pointer_buffer_mark_set)
1943 STD_OVERFLOW_CHECK(pStubMsg);
1944 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1945 pStubMsg->Buffer = saved_buffer + 4;
1951 case RPC_FC_ALIGNM4:
1952 ALIGN_POINTER(pMemory, 4);
1954 case RPC_FC_ALIGNM8:
1955 ALIGN_POINTER(pMemory, 8);
1957 case RPC_FC_STRUCTPAD1:
1958 case RPC_FC_STRUCTPAD2:
1959 case RPC_FC_STRUCTPAD3:
1960 case RPC_FC_STRUCTPAD4:
1961 case RPC_FC_STRUCTPAD5:
1962 case RPC_FC_STRUCTPAD6:
1963 case RPC_FC_STRUCTPAD7:
1964 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1966 case RPC_FC_EMBEDDED_COMPLEX:
1967 pMemory += pFormat[1];
1969 desc = pFormat + *(const SHORT*)pFormat;
1970 size = EmbeddedComplexSize(pStubMsg, desc);
1971 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
1972 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1973 memset(pMemory, 0, size); /* just in case */
1976 /* for some reason interface pointers aren't generated as
1977 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
1978 * they still need the derefencing treatment that pointers are
1980 if (*desc == RPC_FC_IP)
1981 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
1983 m(pStubMsg, &pMemory, desc, FALSE);
1985 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
1992 FIXME("unhandled format %d\n", *pFormat);
2000 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2001 unsigned char *pMemory,
2002 PFORMAT_STRING pFormat,
2003 PFORMAT_STRING pPointer)
2005 PFORMAT_STRING desc;
2009 while (*pFormat != RPC_FC_END) {
2015 pStubMsg->BufferLength += 1;
2021 pStubMsg->BufferLength += 2;
2027 pStubMsg->BufferLength += 4;
2031 pStubMsg->BufferLength += 8;
2034 case RPC_FC_POINTER:
2035 if (!pStubMsg->IgnoreEmbeddedPointers)
2037 int saved_buffer_length = pStubMsg->BufferLength;
2038 pStubMsg->BufferLength = pStubMsg->PointerLength;
2039 pStubMsg->PointerLength = 0;
2040 if(!pStubMsg->BufferLength)
2041 ERR("BufferLength == 0??\n");
2042 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2043 pStubMsg->PointerLength = pStubMsg->BufferLength;
2044 pStubMsg->BufferLength = saved_buffer_length;
2046 pStubMsg->BufferLength += 4;
2050 case RPC_FC_ALIGNM4:
2051 ALIGN_POINTER(pMemory, 4);
2053 case RPC_FC_ALIGNM8:
2054 ALIGN_POINTER(pMemory, 8);
2056 case RPC_FC_STRUCTPAD1:
2057 case RPC_FC_STRUCTPAD2:
2058 case RPC_FC_STRUCTPAD3:
2059 case RPC_FC_STRUCTPAD4:
2060 case RPC_FC_STRUCTPAD5:
2061 case RPC_FC_STRUCTPAD6:
2062 case RPC_FC_STRUCTPAD7:
2063 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2065 case RPC_FC_EMBEDDED_COMPLEX:
2066 pMemory += pFormat[1];
2068 desc = pFormat + *(const SHORT*)pFormat;
2069 size = EmbeddedComplexSize(pStubMsg, desc);
2070 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2073 /* for some reason interface pointers aren't generated as
2074 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2075 * they still need the derefencing treatment that pointers are
2077 if (*desc == RPC_FC_IP)
2078 m(pStubMsg, *(unsigned char **)pMemory, desc);
2080 m(pStubMsg, pMemory, desc);
2082 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2089 FIXME("unhandled format 0x%02x\n", *pFormat);
2097 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2098 unsigned char *pMemory,
2099 PFORMAT_STRING pFormat,
2100 PFORMAT_STRING pPointer)
2102 PFORMAT_STRING desc;
2106 while (*pFormat != RPC_FC_END) {
2127 case RPC_FC_POINTER:
2128 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
2132 case RPC_FC_ALIGNM4:
2133 ALIGN_POINTER(pMemory, 4);
2135 case RPC_FC_ALIGNM8:
2136 ALIGN_POINTER(pMemory, 8);
2138 case RPC_FC_STRUCTPAD1:
2139 case RPC_FC_STRUCTPAD2:
2140 case RPC_FC_STRUCTPAD3:
2141 case RPC_FC_STRUCTPAD4:
2142 case RPC_FC_STRUCTPAD5:
2143 case RPC_FC_STRUCTPAD6:
2144 case RPC_FC_STRUCTPAD7:
2145 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2147 case RPC_FC_EMBEDDED_COMPLEX:
2148 pMemory += pFormat[1];
2150 desc = pFormat + *(const SHORT*)pFormat;
2151 size = EmbeddedComplexSize(pStubMsg, desc);
2152 m = NdrFreer[*desc & NDR_TABLE_MASK];
2155 /* for some reason interface pointers aren't generated as
2156 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2157 * they still need the derefencing treatment that pointers are
2159 if (*desc == RPC_FC_IP)
2160 m(pStubMsg, *(unsigned char **)pMemory, desc);
2162 m(pStubMsg, pMemory, desc);
2164 else FIXME("no freer for embedded type %02x\n", *desc);
2171 FIXME("unhandled format 0x%02x\n", *pFormat);
2179 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2180 PFORMAT_STRING pFormat)
2182 PFORMAT_STRING desc;
2183 unsigned long size = 0;
2185 while (*pFormat != RPC_FC_END) {
2192 pStubMsg->Buffer += 1;
2198 pStubMsg->Buffer += 2;
2204 pStubMsg->Buffer += 4;
2208 pStubMsg->Buffer += 8;
2210 case RPC_FC_POINTER:
2212 pStubMsg->Buffer += 4;
2213 if (!pStubMsg->IgnoreEmbeddedPointers)
2214 FIXME("embedded pointers\n");
2216 case RPC_FC_ALIGNM4:
2217 ALIGN_LENGTH(size, 4);
2218 ALIGN_POINTER(pStubMsg->Buffer, 4);
2220 case RPC_FC_ALIGNM8:
2221 ALIGN_LENGTH(size, 8);
2222 ALIGN_POINTER(pStubMsg->Buffer, 8);
2224 case RPC_FC_STRUCTPAD1:
2225 case RPC_FC_STRUCTPAD2:
2226 case RPC_FC_STRUCTPAD3:
2227 case RPC_FC_STRUCTPAD4:
2228 case RPC_FC_STRUCTPAD5:
2229 case RPC_FC_STRUCTPAD6:
2230 case RPC_FC_STRUCTPAD7:
2231 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2233 case RPC_FC_EMBEDDED_COMPLEX:
2236 desc = pFormat + *(const SHORT*)pFormat;
2237 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2243 FIXME("unhandled format 0x%02x\n", *pFormat);
2251 /***********************************************************************
2252 * NdrComplexStructMarshall [RPCRT4.@]
2254 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2255 unsigned char *pMemory,
2256 PFORMAT_STRING pFormat)
2258 PFORMAT_STRING conf_array = NULL;
2259 PFORMAT_STRING pointer_desc = NULL;
2260 unsigned char *OldMemory = pStubMsg->Memory;
2261 int pointer_buffer_mark_set = 0;
2263 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2265 if (!pStubMsg->PointerBufferMark)
2267 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2268 /* save buffer length */
2269 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2271 /* get the buffer pointer after complex array data, but before
2273 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2274 pStubMsg->IgnoreEmbeddedPointers = 1;
2275 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2276 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2278 /* save it for use by embedded pointer code later */
2279 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2280 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
2281 pointer_buffer_mark_set = 1;
2283 /* restore the original buffer length */
2284 pStubMsg->BufferLength = saved_buffer_length;
2287 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2290 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2292 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2295 pStubMsg->Memory = pMemory;
2297 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2300 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2302 pStubMsg->Memory = OldMemory;
2304 if (pointer_buffer_mark_set)
2306 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2307 pStubMsg->PointerBufferMark = NULL;
2310 STD_OVERFLOW_CHECK(pStubMsg);
2315 /***********************************************************************
2316 * NdrComplexStructUnmarshall [RPCRT4.@]
2318 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2319 unsigned char **ppMemory,
2320 PFORMAT_STRING pFormat,
2321 unsigned char fMustAlloc)
2323 unsigned size = *(const WORD*)(pFormat+2);
2324 PFORMAT_STRING conf_array = NULL;
2325 PFORMAT_STRING pointer_desc = NULL;
2326 unsigned char *pMemory;
2327 int pointer_buffer_mark_set = 0;
2329 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2331 if (!pStubMsg->PointerBufferMark)
2333 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2334 /* save buffer pointer */
2335 unsigned char *saved_buffer = pStubMsg->Buffer;
2337 /* get the buffer pointer after complex array data, but before
2339 pStubMsg->IgnoreEmbeddedPointers = 1;
2340 NdrComplexStructMemorySize(pStubMsg, pFormat);
2341 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2343 /* save it for use by embedded pointer code later */
2344 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2345 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
2346 pointer_buffer_mark_set = 1;
2348 /* restore the original buffer */
2349 pStubMsg->Buffer = saved_buffer;
2352 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2354 if (fMustAlloc || !*ppMemory)
2356 *ppMemory = NdrAllocate(pStubMsg, size);
2357 memset(*ppMemory, 0, size);
2361 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2363 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2366 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2369 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2371 if (pointer_buffer_mark_set)
2373 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2374 pStubMsg->PointerBufferMark = NULL;
2380 /***********************************************************************
2381 * NdrComplexStructBufferSize [RPCRT4.@]
2383 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2384 unsigned char *pMemory,
2385 PFORMAT_STRING pFormat)
2387 PFORMAT_STRING conf_array = NULL;
2388 PFORMAT_STRING pointer_desc = NULL;
2389 unsigned char *OldMemory = pStubMsg->Memory;
2390 int pointer_length_set = 0;
2392 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2394 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2396 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2398 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2399 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2401 /* get the buffer length after complex struct data, but before
2403 pStubMsg->IgnoreEmbeddedPointers = 1;
2404 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2405 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2407 /* save it for use by embedded pointer code later */
2408 pStubMsg->PointerLength = pStubMsg->BufferLength;
2409 pointer_length_set = 1;
2410 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
2412 /* restore the original buffer length */
2413 pStubMsg->BufferLength = saved_buffer_length;
2417 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2419 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2422 pStubMsg->Memory = pMemory;
2424 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2427 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2429 pStubMsg->Memory = OldMemory;
2431 if(pointer_length_set)
2433 pStubMsg->BufferLength = pStubMsg->PointerLength;
2434 pStubMsg->PointerLength = 0;
2439 /***********************************************************************
2440 * NdrComplexStructMemorySize [RPCRT4.@]
2442 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2443 PFORMAT_STRING pFormat)
2445 unsigned size = *(const WORD*)(pFormat+2);
2446 PFORMAT_STRING conf_array = NULL;
2447 PFORMAT_STRING pointer_desc = NULL;
2449 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2451 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2454 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2456 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2459 ComplexStructMemorySize(pStubMsg, pFormat);
2462 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2467 /***********************************************************************
2468 * NdrComplexStructFree [RPCRT4.@]
2470 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2471 unsigned char *pMemory,
2472 PFORMAT_STRING pFormat)
2474 PFORMAT_STRING conf_array = NULL;
2475 PFORMAT_STRING pointer_desc = NULL;
2476 unsigned char *OldMemory = pStubMsg->Memory;
2478 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2481 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2483 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2486 pStubMsg->Memory = pMemory;
2488 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2491 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2493 pStubMsg->Memory = OldMemory;
2496 /***********************************************************************
2497 * NdrConformantArrayMarshall [RPCRT4.@]
2499 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2500 unsigned char *pMemory,
2501 PFORMAT_STRING pFormat)
2503 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2504 unsigned char alignment = pFormat[1] + 1;
2506 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2507 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2509 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2511 WriteConformance(pStubMsg);
2513 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2515 size = safe_multiply(esize, pStubMsg->MaxCount);
2516 memcpy(pStubMsg->Buffer, pMemory, size);
2517 pStubMsg->BufferMark = pStubMsg->Buffer;
2518 pStubMsg->Buffer += size;
2520 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2522 STD_OVERFLOW_CHECK(pStubMsg);
2527 /***********************************************************************
2528 * NdrConformantArrayUnmarshall [RPCRT4.@]
2530 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2531 unsigned char **ppMemory,
2532 PFORMAT_STRING pFormat,
2533 unsigned char fMustAlloc)
2535 DWORD size, esize = *(const WORD*)(pFormat+2);
2536 unsigned char alignment = pFormat[1] + 1;
2538 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2539 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2541 pFormat = ReadConformance(pStubMsg, pFormat+4);
2543 size = safe_multiply(esize, pStubMsg->MaxCount);
2545 if (fMustAlloc || !*ppMemory)
2546 *ppMemory = NdrAllocate(pStubMsg, size);
2548 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2550 memcpy(*ppMemory, pStubMsg->Buffer, size);
2552 pStubMsg->BufferMark = pStubMsg->Buffer;
2553 pStubMsg->Buffer += size;
2555 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2560 /***********************************************************************
2561 * NdrConformantArrayBufferSize [RPCRT4.@]
2563 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2564 unsigned char *pMemory,
2565 PFORMAT_STRING pFormat)
2567 DWORD size, esize = *(const WORD*)(pFormat+2);
2568 unsigned char alignment = pFormat[1] + 1;
2570 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2571 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2573 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2575 SizeConformance(pStubMsg);
2577 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2579 size = safe_multiply(esize, pStubMsg->MaxCount);
2580 /* conformance value plus array */
2581 pStubMsg->BufferLength += size;
2583 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2586 /***********************************************************************
2587 * NdrConformantArrayMemorySize [RPCRT4.@]
2589 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2590 PFORMAT_STRING pFormat)
2592 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2593 unsigned char alignment = pFormat[1] + 1;
2595 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2596 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2598 pFormat = ReadConformance(pStubMsg, pFormat+4);
2599 size = safe_multiply(esize, pStubMsg->MaxCount);
2600 pStubMsg->MemorySize += size;
2602 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2603 pStubMsg->BufferMark = pStubMsg->Buffer;
2604 pStubMsg->Buffer += size;
2606 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2608 return pStubMsg->MemorySize;
2611 /***********************************************************************
2612 * NdrConformantArrayFree [RPCRT4.@]
2614 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2615 unsigned char *pMemory,
2616 PFORMAT_STRING pFormat)
2618 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2619 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2621 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2623 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2627 /***********************************************************************
2628 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2630 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2631 unsigned char* pMemory,
2632 PFORMAT_STRING pFormat )
2635 unsigned char alignment = pFormat[1] + 1;
2636 DWORD esize = *(const WORD*)(pFormat+2);
2638 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2640 if (pFormat[0] != RPC_FC_CVARRAY)
2642 ERR("invalid format type %x\n", pFormat[0]);
2643 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2647 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2648 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2650 WriteConformance(pStubMsg);
2651 WriteVariance(pStubMsg);
2653 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2655 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2657 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
2658 pStubMsg->BufferMark = pStubMsg->Buffer;
2659 pStubMsg->Buffer += bufsize;
2661 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2663 STD_OVERFLOW_CHECK(pStubMsg);
2669 /***********************************************************************
2670 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2672 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2673 unsigned char** ppMemory,
2674 PFORMAT_STRING pFormat,
2675 unsigned char fMustAlloc )
2677 ULONG bufsize, memsize;
2678 unsigned char alignment = pFormat[1] + 1;
2679 DWORD esize = *(const WORD*)(pFormat+2);
2681 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2683 if (pFormat[0] != RPC_FC_CVARRAY)
2685 ERR("invalid format type %x\n", pFormat[0]);
2686 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2690 pFormat = ReadConformance(pStubMsg, pFormat+4);
2691 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2693 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2695 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2696 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2698 if (!*ppMemory || fMustAlloc)
2699 *ppMemory = NdrAllocate(pStubMsg, memsize);
2700 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
2701 pStubMsg->Buffer += bufsize;
2703 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2709 /***********************************************************************
2710 * NdrConformantVaryingArrayFree [RPCRT4.@]
2712 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2713 unsigned char* pMemory,
2714 PFORMAT_STRING pFormat )
2716 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2718 if (pFormat[0] != RPC_FC_CVARRAY)
2720 ERR("invalid format type %x\n", pFormat[0]);
2721 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2725 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2726 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2728 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2732 /***********************************************************************
2733 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2735 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2736 unsigned char* pMemory, PFORMAT_STRING pFormat )
2738 unsigned char alignment = pFormat[1] + 1;
2739 DWORD esize = *(const WORD*)(pFormat+2);
2741 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2743 if (pFormat[0] != RPC_FC_CVARRAY)
2745 ERR("invalid format type %x\n", pFormat[0]);
2746 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2751 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2752 /* compute length */
2753 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2755 SizeConformance(pStubMsg);
2756 SizeVariance(pStubMsg);
2758 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2760 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
2762 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2766 /***********************************************************************
2767 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2769 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2770 PFORMAT_STRING pFormat )
2777 /***********************************************************************
2778 * NdrComplexArrayMarshall [RPCRT4.@]
2780 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2781 unsigned char *pMemory,
2782 PFORMAT_STRING pFormat)
2784 ULONG i, count, def;
2785 BOOL variance_present;
2786 unsigned char alignment;
2787 int pointer_buffer_mark_set = 0;
2789 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2791 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2793 ERR("invalid format type %x\n", pFormat[0]);
2794 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2798 alignment = pFormat[1] + 1;
2800 if (!pStubMsg->PointerBufferMark)
2802 /* save buffer fields that may be changed by buffer sizer functions
2803 * and that may be needed later on */
2804 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2805 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2806 unsigned long saved_max_count = pStubMsg->MaxCount;
2807 unsigned long saved_offset = pStubMsg->Offset;
2808 unsigned long saved_actual_count = pStubMsg->ActualCount;
2810 /* get the buffer pointer after complex array data, but before
2812 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2813 pStubMsg->IgnoreEmbeddedPointers = 1;
2814 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
2815 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2817 /* save it for use by embedded pointer code later */
2818 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2819 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
2820 pointer_buffer_mark_set = 1;
2822 /* restore fields */
2823 pStubMsg->ActualCount = saved_actual_count;
2824 pStubMsg->Offset = saved_offset;
2825 pStubMsg->MaxCount = saved_max_count;
2826 pStubMsg->BufferLength = saved_buffer_length;
2829 def = *(const WORD*)&pFormat[2];
2832 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2833 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2835 variance_present = IsConformanceOrVariancePresent(pFormat);
2836 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2837 TRACE("variance = %d\n", pStubMsg->ActualCount);
2839 WriteConformance(pStubMsg);
2840 if (variance_present)
2841 WriteVariance(pStubMsg);
2843 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2845 count = pStubMsg->ActualCount;
2846 for (i = 0; i < count; i++)
2847 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2849 STD_OVERFLOW_CHECK(pStubMsg);
2851 if (pointer_buffer_mark_set)
2853 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2854 pStubMsg->PointerBufferMark = NULL;
2860 /***********************************************************************
2861 * NdrComplexArrayUnmarshall [RPCRT4.@]
2863 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2864 unsigned char **ppMemory,
2865 PFORMAT_STRING pFormat,
2866 unsigned char fMustAlloc)
2868 ULONG i, count, size;
2869 unsigned char alignment;
2870 unsigned char *pMemory;
2871 unsigned char *saved_buffer;
2872 int pointer_buffer_mark_set = 0;
2873 int saved_ignore_embedded;
2875 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2877 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2879 ERR("invalid format type %x\n", pFormat[0]);
2880 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2884 alignment = pFormat[1] + 1;
2886 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2887 /* save buffer pointer */
2888 saved_buffer = pStubMsg->Buffer;
2889 /* get the buffer pointer after complex array data, but before
2891 pStubMsg->IgnoreEmbeddedPointers = 1;
2892 pStubMsg->MemorySize = 0;
2893 NdrComplexArrayMemorySize(pStubMsg, pFormat);
2894 size = pStubMsg->MemorySize;
2895 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2897 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
2898 if (!pStubMsg->PointerBufferMark)
2900 /* save it for use by embedded pointer code later */
2901 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2902 pointer_buffer_mark_set = 1;
2904 /* restore the original buffer */
2905 pStubMsg->Buffer = saved_buffer;
2909 pFormat = ReadConformance(pStubMsg, pFormat);
2910 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2912 if (fMustAlloc || !*ppMemory)
2914 *ppMemory = NdrAllocate(pStubMsg, size);
2915 memset(*ppMemory, 0, size);
2918 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2920 pMemory = *ppMemory;
2921 count = pStubMsg->ActualCount;
2922 for (i = 0; i < count; i++)
2923 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
2925 if (pointer_buffer_mark_set)
2927 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2928 pStubMsg->PointerBufferMark = NULL;
2934 /***********************************************************************
2935 * NdrComplexArrayBufferSize [RPCRT4.@]
2937 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2938 unsigned char *pMemory,
2939 PFORMAT_STRING pFormat)
2941 ULONG i, count, def;
2942 unsigned char alignment;
2943 BOOL variance_present;
2944 int pointer_length_set = 0;
2946 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2948 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2950 ERR("invalid format type %x\n", pFormat[0]);
2951 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2955 alignment = pFormat[1] + 1;
2957 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2959 /* save buffer fields that may be changed by buffer sizer functions
2960 * and that may be needed later on */
2961 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2962 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2963 unsigned long saved_max_count = pStubMsg->MaxCount;
2964 unsigned long saved_offset = pStubMsg->Offset;
2965 unsigned long saved_actual_count = pStubMsg->ActualCount;
2967 /* get the buffer pointer after complex array data, but before
2969 pStubMsg->IgnoreEmbeddedPointers = 1;
2970 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
2971 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2973 /* save it for use by embedded pointer code later */
2974 pStubMsg->PointerLength = pStubMsg->BufferLength;
2975 pointer_length_set = 1;
2977 /* restore fields */
2978 pStubMsg->ActualCount = saved_actual_count;
2979 pStubMsg->Offset = saved_offset;
2980 pStubMsg->MaxCount = saved_max_count;
2981 pStubMsg->BufferLength = saved_buffer_length;
2983 def = *(const WORD*)&pFormat[2];
2986 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2987 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2988 SizeConformance(pStubMsg);
2990 variance_present = IsConformanceOrVariancePresent(pFormat);
2991 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2992 TRACE("variance = %d\n", pStubMsg->ActualCount);
2994 if (variance_present)
2995 SizeVariance(pStubMsg);
2997 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2999 count = pStubMsg->ActualCount;
3000 for (i = 0; i < count; i++)
3001 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
3003 if(pointer_length_set)
3005 pStubMsg->BufferLength = pStubMsg->PointerLength;
3006 pStubMsg->PointerLength = 0;
3010 /***********************************************************************
3011 * NdrComplexArrayMemorySize [RPCRT4.@]
3013 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3014 PFORMAT_STRING pFormat)
3016 ULONG i, count, esize, SavedMemorySize, MemorySize;
3017 unsigned char alignment;
3018 unsigned char *Buffer;
3020 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3022 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3024 ERR("invalid format type %x\n", pFormat[0]);
3025 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3029 alignment = pFormat[1] + 1;
3033 pFormat = ReadConformance(pStubMsg, pFormat);
3034 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3036 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3038 SavedMemorySize = pStubMsg->MemorySize;
3040 Buffer = pStubMsg->Buffer;
3041 pStubMsg->MemorySize = 0;
3042 esize = ComplexStructMemorySize(pStubMsg, pFormat);
3043 pStubMsg->Buffer = Buffer;
3045 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
3047 count = pStubMsg->ActualCount;
3048 for (i = 0; i < count; i++)
3049 ComplexStructMemorySize(pStubMsg, pFormat);
3051 pStubMsg->MemorySize = SavedMemorySize;
3053 pStubMsg->MemorySize += MemorySize;
3057 /***********************************************************************
3058 * NdrComplexArrayFree [RPCRT4.@]
3060 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3061 unsigned char *pMemory,
3062 PFORMAT_STRING pFormat)
3064 ULONG i, count, def;
3066 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3068 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3070 ERR("invalid format type %x\n", pFormat[0]);
3071 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3075 def = *(const WORD*)&pFormat[2];
3078 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3079 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3081 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3082 TRACE("variance = %d\n", pStubMsg->ActualCount);
3084 count = pStubMsg->ActualCount;
3085 for (i = 0; i < count; i++)
3086 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
3089 static ULONG UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
3091 return MAKELONG(pStubMsg->dwDestContext,
3092 pStubMsg->RpcMsg->DataRepresentation);
3095 #define USER_MARSHAL_PTR_PREFIX \
3096 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3097 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3099 /***********************************************************************
3100 * NdrUserMarshalMarshall [RPCRT4.@]
3102 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3103 unsigned char *pMemory,
3104 PFORMAT_STRING pFormat)
3106 unsigned flags = pFormat[1];
3107 unsigned index = *(const WORD*)&pFormat[2];
3108 unsigned char *saved_buffer = NULL;
3109 ULONG uflag = UserMarshalFlags(pStubMsg);
3110 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3111 TRACE("index=%d\n", index);
3113 if (flags & USER_MARSHAL_POINTER)
3115 ALIGN_POINTER(pStubMsg->Buffer, 4);
3116 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
3117 pStubMsg->Buffer += 4;
3118 if (pStubMsg->PointerBufferMark)
3120 saved_buffer = pStubMsg->Buffer;
3121 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3122 pStubMsg->PointerBufferMark = NULL;
3124 ALIGN_POINTER(pStubMsg->Buffer, 8);
3127 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3130 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
3131 &uflag, pStubMsg->Buffer, pMemory);
3135 STD_OVERFLOW_CHECK(pStubMsg);
3136 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3137 pStubMsg->Buffer = saved_buffer;
3140 STD_OVERFLOW_CHECK(pStubMsg);
3145 /***********************************************************************
3146 * NdrUserMarshalUnmarshall [RPCRT4.@]
3148 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3149 unsigned char **ppMemory,
3150 PFORMAT_STRING pFormat,
3151 unsigned char fMustAlloc)
3153 unsigned flags = pFormat[1];
3154 unsigned index = *(const WORD*)&pFormat[2];
3155 DWORD memsize = *(const WORD*)&pFormat[4];
3156 unsigned char *saved_buffer = NULL;
3157 ULONG uflag = UserMarshalFlags(pStubMsg);
3158 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3159 TRACE("index=%d\n", index);
3161 if (flags & USER_MARSHAL_POINTER)
3163 ALIGN_POINTER(pStubMsg->Buffer, 4);
3164 /* skip pointer prefix */
3165 pStubMsg->Buffer += 4;
3166 if (pStubMsg->PointerBufferMark)
3168 saved_buffer = pStubMsg->Buffer;
3169 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3170 pStubMsg->PointerBufferMark = NULL;
3172 ALIGN_POINTER(pStubMsg->Buffer, 8);
3175 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3177 if (fMustAlloc || !*ppMemory)
3178 *ppMemory = NdrAllocate(pStubMsg, memsize);
3181 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
3182 &uflag, pStubMsg->Buffer, *ppMemory);
3186 STD_OVERFLOW_CHECK(pStubMsg);
3187 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3188 pStubMsg->Buffer = saved_buffer;
3194 /***********************************************************************
3195 * NdrUserMarshalBufferSize [RPCRT4.@]
3197 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3198 unsigned char *pMemory,
3199 PFORMAT_STRING pFormat)
3201 unsigned flags = pFormat[1];
3202 unsigned index = *(const WORD*)&pFormat[2];
3203 DWORD bufsize = *(const WORD*)&pFormat[6];
3204 ULONG uflag = UserMarshalFlags(pStubMsg);
3205 unsigned long saved_buffer_length = 0;
3206 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3207 TRACE("index=%d\n", index);
3209 if (flags & USER_MARSHAL_POINTER)
3211 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3212 /* skip pointer prefix */
3213 pStubMsg->BufferLength += 4;
3214 if (pStubMsg->IgnoreEmbeddedPointers)
3216 if (pStubMsg->PointerLength)
3218 saved_buffer_length = pStubMsg->BufferLength;
3219 pStubMsg->BufferLength = pStubMsg->PointerLength;
3220 pStubMsg->PointerLength = 0;
3222 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
3225 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
3228 TRACE("size=%d\n", bufsize);
3229 pStubMsg->BufferLength += bufsize;
3232 pStubMsg->BufferLength =
3233 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
3234 &uflag, pStubMsg->BufferLength, pMemory);
3236 if (saved_buffer_length)
3238 pStubMsg->PointerLength = pStubMsg->BufferLength;
3239 pStubMsg->BufferLength = saved_buffer_length;
3244 /***********************************************************************
3245 * NdrUserMarshalMemorySize [RPCRT4.@]
3247 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3248 PFORMAT_STRING pFormat)
3250 unsigned flags = pFormat[1];
3251 unsigned index = *(const WORD*)&pFormat[2];
3252 DWORD memsize = *(const WORD*)&pFormat[4];
3253 DWORD bufsize = *(const WORD*)&pFormat[6];
3255 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3256 TRACE("index=%d\n", index);
3258 pStubMsg->MemorySize += memsize;
3260 if (flags & USER_MARSHAL_POINTER)
3262 ALIGN_POINTER(pStubMsg->Buffer, 4);
3263 /* skip pointer prefix */
3264 pStubMsg->Buffer += 4;
3265 if (pStubMsg->IgnoreEmbeddedPointers)
3266 return pStubMsg->MemorySize;
3267 ALIGN_POINTER(pStubMsg->Buffer, 8);
3270 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3273 FIXME("not implemented for varying buffer size\n");
3275 pStubMsg->Buffer += bufsize;
3277 return pStubMsg->MemorySize;
3280 /***********************************************************************
3281 * NdrUserMarshalFree [RPCRT4.@]
3283 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
3284 unsigned char *pMemory,
3285 PFORMAT_STRING pFormat)
3287 /* unsigned flags = pFormat[1]; */
3288 unsigned index = *(const WORD*)&pFormat[2];
3289 ULONG uflag = UserMarshalFlags(pStubMsg);
3290 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3291 TRACE("index=%d\n", index);
3293 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
3297 /***********************************************************************
3298 * NdrClearOutParameters [RPCRT4.@]
3300 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
3301 PFORMAT_STRING pFormat,
3304 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
3307 /***********************************************************************
3308 * NdrConvert [RPCRT4.@]
3310 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
3312 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
3313 /* FIXME: since this stub doesn't do any converting, the proper behavior
3314 is to raise an exception */
3317 /***********************************************************************
3318 * NdrConvert2 [RPCRT4.@]
3320 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
3322 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3323 pStubMsg, pFormat, NumberParams);
3324 /* FIXME: since this stub doesn't do any converting, the proper behavior
3325 is to raise an exception */
3328 #include "pshpack1.h"
3329 typedef struct _NDR_CSTRUCT_FORMAT
3332 unsigned char alignment;
3333 unsigned short memory_size;
3334 short offset_to_array_description;
3335 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
3336 #include "poppack.h"
3338 /***********************************************************************
3339 * NdrConformantStructMarshall [RPCRT4.@]
3341 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3342 unsigned char *pMemory,
3343 PFORMAT_STRING pFormat)
3345 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3346 PFORMAT_STRING pCArrayFormat;
3347 ULONG esize, bufsize;
3349 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3351 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3352 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3354 ERR("invalid format type %x\n", pCStructFormat->type);
3355 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3359 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3360 pCStructFormat->offset_to_array_description;
3361 if (*pCArrayFormat != RPC_FC_CARRAY)
3363 ERR("invalid array format type %x\n", pCStructFormat->type);
3364 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3367 esize = *(const WORD*)(pCArrayFormat+2);
3369 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3370 pCArrayFormat + 4, 0);
3372 WriteConformance(pStubMsg);
3374 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3376 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3378 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3379 /* copy constant sized part of struct */
3380 pStubMsg->BufferMark = pStubMsg->Buffer;
3381 memcpy(pStubMsg->Buffer, pMemory, pCStructFormat->memory_size + bufsize);
3382 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
3384 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3385 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3387 STD_OVERFLOW_CHECK(pStubMsg);
3392 /***********************************************************************
3393 * NdrConformantStructUnmarshall [RPCRT4.@]
3395 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3396 unsigned char **ppMemory,
3397 PFORMAT_STRING pFormat,
3398 unsigned char fMustAlloc)
3400 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3401 PFORMAT_STRING pCArrayFormat;
3402 ULONG esize, bufsize;
3404 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3406 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3407 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3409 ERR("invalid format type %x\n", pCStructFormat->type);
3410 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3413 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3414 pCStructFormat->offset_to_array_description;
3415 if (*pCArrayFormat != RPC_FC_CARRAY)
3417 ERR("invalid array format type %x\n", pCStructFormat->type);
3418 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3421 esize = *(const WORD*)(pCArrayFormat+2);
3423 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3425 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3427 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3429 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3430 /* work out how much memory to allocate if we need to do so */
3431 if (!*ppMemory || fMustAlloc)
3433 SIZE_T size = pCStructFormat->memory_size + bufsize;
3434 *ppMemory = NdrAllocate(pStubMsg, size);
3437 /* now copy the data */
3438 pStubMsg->BufferMark = pStubMsg->Buffer;
3439 memcpy(*ppMemory, pStubMsg->Buffer, pCStructFormat->memory_size + bufsize);
3440 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
3442 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3443 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3448 /***********************************************************************
3449 * NdrConformantStructBufferSize [RPCRT4.@]
3451 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3452 unsigned char *pMemory,
3453 PFORMAT_STRING pFormat)
3455 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3456 PFORMAT_STRING pCArrayFormat;
3459 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3461 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3462 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3464 ERR("invalid format type %x\n", pCStructFormat->type);
3465 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3468 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3469 pCStructFormat->offset_to_array_description;
3470 if (*pCArrayFormat != RPC_FC_CARRAY)
3472 ERR("invalid array format type %x\n", pCStructFormat->type);
3473 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3476 esize = *(const WORD*)(pCArrayFormat+2);
3478 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
3479 SizeConformance(pStubMsg);
3481 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
3483 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3485 pStubMsg->BufferLength += pCStructFormat->memory_size +
3486 safe_multiply(pStubMsg->MaxCount, esize);
3488 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3489 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3492 /***********************************************************************
3493 * NdrConformantStructMemorySize [RPCRT4.@]
3495 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3496 PFORMAT_STRING pFormat)
3502 /***********************************************************************
3503 * NdrConformantStructFree [RPCRT4.@]
3505 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3506 unsigned char *pMemory,
3507 PFORMAT_STRING pFormat)
3512 /***********************************************************************
3513 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3515 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3516 unsigned char *pMemory,
3517 PFORMAT_STRING pFormat)
3519 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3520 PFORMAT_STRING pCVArrayFormat;
3521 ULONG esize, bufsize;
3523 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3525 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3526 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3528 ERR("invalid format type %x\n", pCVStructFormat->type);
3529 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3533 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3534 pCVStructFormat->offset_to_array_description;
3535 switch (*pCVArrayFormat)
3537 case RPC_FC_CVARRAY:
3538 esize = *(const WORD*)(pCVArrayFormat+2);
3540 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3541 pCVArrayFormat + 4, 0);
3542 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3545 case RPC_FC_C_CSTRING:
3546 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3547 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3548 esize = sizeof(char);
3549 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3550 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3551 pCVArrayFormat + 2, 0);
3553 pStubMsg->MaxCount = pStubMsg->ActualCount;
3555 case RPC_FC_C_WSTRING:
3556 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3557 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3558 esize = sizeof(WCHAR);
3559 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3560 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3561 pCVArrayFormat + 2, 0);
3563 pStubMsg->MaxCount = pStubMsg->ActualCount;
3566 ERR("invalid array format type %x\n", *pCVArrayFormat);
3567 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3571 WriteConformance(pStubMsg);
3573 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3575 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3577 /* write constant sized part */
3578 pStubMsg->BufferMark = pStubMsg->Buffer;
3579 memcpy(pStubMsg->Buffer, pMemory, pCVStructFormat->memory_size);
3580 pStubMsg->Buffer += pCVStructFormat->memory_size;
3582 WriteVariance(pStubMsg);
3584 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3586 /* write array part */
3587 memcpy(pStubMsg->Buffer, pMemory + pCVStructFormat->memory_size, bufsize);
3588 pStubMsg->Buffer += bufsize;
3590 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3592 STD_OVERFLOW_CHECK(pStubMsg);
3597 /***********************************************************************
3598 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3600 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3601 unsigned char **ppMemory,
3602 PFORMAT_STRING pFormat,
3603 unsigned char fMustAlloc)
3605 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3606 PFORMAT_STRING pCVArrayFormat;
3607 ULONG esize, bufsize;
3608 unsigned char cvarray_type;
3610 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3612 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3613 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3615 ERR("invalid format type %x\n", pCVStructFormat->type);
3616 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3620 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3621 pCVStructFormat->offset_to_array_description;
3622 cvarray_type = *pCVArrayFormat;
3623 switch (cvarray_type)
3625 case RPC_FC_CVARRAY:
3626 esize = *(const WORD*)(pCVArrayFormat+2);
3627 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3629 case RPC_FC_C_CSTRING:
3630 esize = sizeof(char);
3631 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3632 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3634 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3636 case RPC_FC_C_WSTRING:
3637 esize = sizeof(WCHAR);
3638 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3639 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3641 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3644 ERR("invalid array format type %x\n", *pCVArrayFormat);
3645 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3649 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3651 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3653 /* work out how much memory to allocate if we need to do so */
3654 if (!*ppMemory || fMustAlloc)
3656 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3657 *ppMemory = NdrAllocate(pStubMsg, size);
3660 /* copy the constant data */
3661 pStubMsg->BufferMark = pStubMsg->Buffer;
3662 memcpy(*ppMemory, pStubMsg->Buffer, pCVStructFormat->memory_size);
3663 pStubMsg->Buffer += pCVStructFormat->memory_size;
3665 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3667 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3669 if ((cvarray_type == RPC_FC_C_CSTRING) ||
3670 (cvarray_type == RPC_FC_C_WSTRING))
3673 /* strings must always have null terminating bytes */
3674 if (bufsize < esize)
3676 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
3677 RpcRaiseException(RPC_S_INVALID_BOUND);
3680 for (i = bufsize - esize; i < bufsize; i++)
3681 if (pStubMsg->Buffer[i] != 0)
3683 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3684 i, pStubMsg->Buffer[i]);
3685 RpcRaiseException(RPC_S_INVALID_BOUND);
3690 /* copy the array data */
3691 memcpy(*ppMemory + pCVStructFormat->memory_size, pStubMsg->Buffer,
3693 pStubMsg->Buffer += bufsize;
3695 if (cvarray_type == RPC_FC_C_CSTRING)
3696 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3697 else if (cvarray_type == RPC_FC_C_WSTRING)
3698 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3700 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3705 /***********************************************************************
3706 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3708 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3709 unsigned char *pMemory,
3710 PFORMAT_STRING pFormat)
3712 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3713 PFORMAT_STRING pCVArrayFormat;
3716 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3718 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3719 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3721 ERR("invalid format type %x\n", pCVStructFormat->type);
3722 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3726 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3727 pCVStructFormat->offset_to_array_description;
3728 switch (*pCVArrayFormat)
3730 case RPC_FC_CVARRAY:
3731 esize = *(const WORD*)(pCVArrayFormat+2);
3733 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3734 pCVArrayFormat + 4, 0);
3735 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3738 case RPC_FC_C_CSTRING:
3739 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3740 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3741 esize = sizeof(char);
3742 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3743 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3744 pCVArrayFormat + 2, 0);
3746 pStubMsg->MaxCount = pStubMsg->ActualCount;
3748 case RPC_FC_C_WSTRING:
3749 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3750 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3751 esize = sizeof(WCHAR);
3752 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3753 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3754 pCVArrayFormat + 2, 0);
3756 pStubMsg->MaxCount = pStubMsg->ActualCount;
3759 ERR("invalid array format type %x\n", *pCVArrayFormat);
3760 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3764 SizeConformance(pStubMsg);
3766 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
3768 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3770 pStubMsg->BufferLength += pCVStructFormat->memory_size;
3771 SizeVariance(pStubMsg);
3772 pStubMsg->BufferLength += safe_multiply(pStubMsg->MaxCount, esize);
3774 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3777 /***********************************************************************
3778 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3780 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3781 PFORMAT_STRING pFormat)
3783 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3784 PFORMAT_STRING pCVArrayFormat;
3786 unsigned char cvarray_type;
3788 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3790 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3791 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3793 ERR("invalid format type %x\n", pCVStructFormat->type);
3794 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3798 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3799 pCVStructFormat->offset_to_array_description;
3800 cvarray_type = *pCVArrayFormat;
3801 switch (cvarray_type)
3803 case RPC_FC_CVARRAY:
3804 esize = *(const WORD*)(pCVArrayFormat+2);
3805 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3807 case RPC_FC_C_CSTRING:
3808 esize = sizeof(char);
3809 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3810 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3812 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3814 case RPC_FC_C_WSTRING:
3815 esize = sizeof(WCHAR);
3816 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3817 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3819 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3822 ERR("invalid array format type %x\n", *pCVArrayFormat);
3823 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3827 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3829 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3831 pStubMsg->Buffer += pCVStructFormat->memory_size;
3832 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3833 pStubMsg->Buffer += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->ActualCount);
3835 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3837 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3839 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3842 /***********************************************************************
3843 * NdrConformantVaryingStructFree [RPCRT4.@]
3845 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3846 unsigned char *pMemory,
3847 PFORMAT_STRING pFormat)
3849 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3850 PFORMAT_STRING pCVArrayFormat;
3853 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3855 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3856 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3858 ERR("invalid format type %x\n", pCVStructFormat->type);
3859 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3863 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3864 pCVStructFormat->offset_to_array_description;
3865 switch (*pCVArrayFormat)
3867 case RPC_FC_CVARRAY:
3868 esize = *(const WORD*)(pCVArrayFormat+2);
3870 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3871 pCVArrayFormat + 4, 0);
3872 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3875 case RPC_FC_C_CSTRING:
3876 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3877 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3878 esize = sizeof(char);
3879 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3880 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3881 pCVArrayFormat + 2, 0);
3883 pStubMsg->MaxCount = pStubMsg->ActualCount;
3885 case RPC_FC_C_WSTRING:
3886 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3887 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3888 esize = sizeof(WCHAR);
3889 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3890 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3891 pCVArrayFormat + 2, 0);
3893 pStubMsg->MaxCount = pStubMsg->ActualCount;
3896 ERR("invalid array format type %x\n", *pCVArrayFormat);
3897 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3901 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3903 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3906 #include "pshpack1.h"
3910 unsigned char alignment;
3911 unsigned short total_size;
3912 } NDR_SMFARRAY_FORMAT;
3917 unsigned char alignment;
3918 unsigned long total_size;
3919 } NDR_LGFARRAY_FORMAT;
3920 #include "poppack.h"
3922 /***********************************************************************
3923 * NdrFixedArrayMarshall [RPCRT4.@]
3925 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3926 unsigned char *pMemory,
3927 PFORMAT_STRING pFormat)
3929 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3930 unsigned long total_size;
3932 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3934 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3935 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3937 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3938 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3942 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3944 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3946 total_size = pSmFArrayFormat->total_size;
3947 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3951 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3952 total_size = pLgFArrayFormat->total_size;
3953 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3956 memcpy(pStubMsg->Buffer, pMemory, total_size);
3957 pStubMsg->BufferMark = pStubMsg->Buffer;
3958 pStubMsg->Buffer += total_size;
3960 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3965 /***********************************************************************
3966 * NdrFixedArrayUnmarshall [RPCRT4.@]
3968 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3969 unsigned char **ppMemory,
3970 PFORMAT_STRING pFormat,
3971 unsigned char fMustAlloc)
3973 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3974 unsigned long total_size;
3976 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3978 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3979 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3981 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3982 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3986 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3988 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3990 total_size = pSmFArrayFormat->total_size;
3991 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3995 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3996 total_size = pLgFArrayFormat->total_size;
3997 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4000 if (fMustAlloc || !*ppMemory)
4001 *ppMemory = NdrAllocate(pStubMsg, total_size);
4002 memcpy(*ppMemory, pStubMsg->Buffer, total_size);
4003 pStubMsg->BufferMark = pStubMsg->Buffer;
4004 pStubMsg->Buffer += total_size;
4006 pFormat = EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
4011 /***********************************************************************
4012 * NdrFixedArrayBufferSize [RPCRT4.@]
4014 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4015 unsigned char *pMemory,
4016 PFORMAT_STRING pFormat)
4018 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4019 unsigned long total_size;
4021 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4023 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4024 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4026 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4027 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4031 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4033 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4035 total_size = pSmFArrayFormat->total_size;
4036 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4040 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4041 total_size = pLgFArrayFormat->total_size;
4042 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4044 pStubMsg->BufferLength += total_size;
4046 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4049 /***********************************************************************
4050 * NdrFixedArrayMemorySize [RPCRT4.@]
4052 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4053 PFORMAT_STRING pFormat)
4055 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4058 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4060 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4061 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4063 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4064 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4068 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4070 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4072 total_size = pSmFArrayFormat->total_size;
4073 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4077 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4078 total_size = pLgFArrayFormat->total_size;
4079 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4081 pStubMsg->BufferMark = pStubMsg->Buffer;
4082 pStubMsg->Buffer += total_size;
4083 pStubMsg->MemorySize += total_size;
4085 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4090 /***********************************************************************
4091 * NdrFixedArrayFree [RPCRT4.@]
4093 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4094 unsigned char *pMemory,
4095 PFORMAT_STRING pFormat)
4097 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4099 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4101 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4102 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4104 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4105 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4109 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4110 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4113 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4114 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4117 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4120 /***********************************************************************
4121 * NdrVaryingArrayMarshall [RPCRT4.@]
4123 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4124 unsigned char *pMemory,
4125 PFORMAT_STRING pFormat)
4127 unsigned char alignment;
4128 DWORD elements, esize;
4131 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4133 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4134 (pFormat[0] != RPC_FC_LGVARRAY))
4136 ERR("invalid format type %x\n", pFormat[0]);
4137 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4141 alignment = pFormat[1] + 1;
4143 if (pFormat[0] == RPC_FC_SMVARRAY)
4146 pFormat += sizeof(WORD);
4147 elements = *(const WORD*)pFormat;
4148 pFormat += sizeof(WORD);
4153 pFormat += sizeof(DWORD);
4154 elements = *(const DWORD*)pFormat;
4155 pFormat += sizeof(DWORD);
4158 esize = *(const WORD*)pFormat;
4159 pFormat += sizeof(WORD);
4161 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4162 if ((pStubMsg->ActualCount > elements) ||
4163 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4165 RpcRaiseException(RPC_S_INVALID_BOUND);
4169 WriteVariance(pStubMsg);
4171 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4173 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4174 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
4175 pStubMsg->BufferMark = pStubMsg->Buffer;
4176 pStubMsg->Buffer += bufsize;
4178 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4180 STD_OVERFLOW_CHECK(pStubMsg);
4185 /***********************************************************************
4186 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4188 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4189 unsigned char **ppMemory,
4190 PFORMAT_STRING pFormat,
4191 unsigned char fMustAlloc)
4193 unsigned char alignment;
4194 DWORD size, elements, esize;
4197 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4199 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4200 (pFormat[0] != RPC_FC_LGVARRAY))
4202 ERR("invalid format type %x\n", pFormat[0]);
4203 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4207 alignment = pFormat[1] + 1;
4209 if (pFormat[0] == RPC_FC_SMVARRAY)
4212 size = *(const WORD*)pFormat;
4213 pFormat += sizeof(WORD);
4214 elements = *(const WORD*)pFormat;
4215 pFormat += sizeof(WORD);
4220 size = *(const DWORD*)pFormat;
4221 pFormat += sizeof(DWORD);
4222 elements = *(const DWORD*)pFormat;
4223 pFormat += sizeof(DWORD);
4226 esize = *(const WORD*)pFormat;
4227 pFormat += sizeof(WORD);
4229 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4231 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4233 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4235 if (!*ppMemory || fMustAlloc)
4236 *ppMemory = NdrAllocate(pStubMsg, size);
4237 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
4238 pStubMsg->Buffer += bufsize;
4240 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
4245 /***********************************************************************
4246 * NdrVaryingArrayBufferSize [RPCRT4.@]
4248 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4249 unsigned char *pMemory,
4250 PFORMAT_STRING pFormat)
4252 unsigned char alignment;
4253 DWORD elements, esize;
4255 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4257 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4258 (pFormat[0] != RPC_FC_LGVARRAY))
4260 ERR("invalid format type %x\n", pFormat[0]);
4261 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4265 alignment = pFormat[1] + 1;
4267 if (pFormat[0] == RPC_FC_SMVARRAY)
4270 pFormat += sizeof(WORD);
4271 elements = *(const WORD*)pFormat;
4272 pFormat += sizeof(WORD);
4277 pFormat += sizeof(DWORD);
4278 elements = *(const DWORD*)pFormat;
4279 pFormat += sizeof(DWORD);
4282 esize = *(const WORD*)pFormat;
4283 pFormat += sizeof(WORD);
4285 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4286 if ((pStubMsg->ActualCount > elements) ||
4287 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4289 RpcRaiseException(RPC_S_INVALID_BOUND);
4293 SizeVariance(pStubMsg);
4295 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4297 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
4299 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4302 /***********************************************************************
4303 * NdrVaryingArrayMemorySize [RPCRT4.@]
4305 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4306 PFORMAT_STRING pFormat)
4308 unsigned char alignment;
4309 DWORD size, elements, esize;
4311 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4313 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4314 (pFormat[0] != RPC_FC_LGVARRAY))
4316 ERR("invalid format type %x\n", pFormat[0]);
4317 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4321 alignment = pFormat[1] + 1;
4323 if (pFormat[0] == RPC_FC_SMVARRAY)
4326 size = *(const WORD*)pFormat;
4327 pFormat += sizeof(WORD);
4328 elements = *(const WORD*)pFormat;
4329 pFormat += sizeof(WORD);
4334 size = *(const DWORD*)pFormat;
4335 pFormat += sizeof(DWORD);
4336 elements = *(const DWORD*)pFormat;
4337 pFormat += sizeof(DWORD);
4340 esize = *(const WORD*)pFormat;
4341 pFormat += sizeof(WORD);
4343 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4345 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4347 pStubMsg->Buffer += safe_multiply(esize, pStubMsg->ActualCount);
4348 pStubMsg->MemorySize += size;
4350 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4352 return pStubMsg->MemorySize;
4355 /***********************************************************************
4356 * NdrVaryingArrayFree [RPCRT4.@]
4358 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4359 unsigned char *pMemory,
4360 PFORMAT_STRING pFormat)
4362 unsigned char alignment;
4365 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4367 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4368 (pFormat[0] != RPC_FC_LGVARRAY))
4370 ERR("invalid format type %x\n", pFormat[0]);
4371 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4375 alignment = pFormat[1] + 1;
4377 if (pFormat[0] == RPC_FC_SMVARRAY)
4380 pFormat += sizeof(WORD);
4381 elements = *(const WORD*)pFormat;
4382 pFormat += sizeof(WORD);
4387 pFormat += sizeof(DWORD);
4388 elements = *(const DWORD*)pFormat;
4389 pFormat += sizeof(DWORD);
4392 pFormat += sizeof(WORD);
4394 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4395 if ((pStubMsg->ActualCount > elements) ||
4396 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4398 RpcRaiseException(RPC_S_INVALID_BOUND);
4402 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4405 static ULONG get_discriminant(unsigned char fc, unsigned char *pMemory)
4413 return *(UCHAR *)pMemory;
4418 return *(USHORT *)pMemory;
4422 return *(ULONG *)pMemory;
4424 FIXME("Unhandled base type: 0x%02x\n", fc);
4429 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4430 unsigned long discriminant,
4431 PFORMAT_STRING pFormat)
4433 unsigned short num_arms, arm, type;
4435 num_arms = *(const SHORT*)pFormat & 0x0fff;
4437 for(arm = 0; arm < num_arms; arm++)
4439 if(discriminant == *(const ULONG*)pFormat)
4447 type = *(const unsigned short*)pFormat;
4448 TRACE("type %04x\n", type);
4449 if(arm == num_arms) /* default arm extras */
4453 ERR("no arm for 0x%lx and no default case\n", discriminant);
4454 RpcRaiseException(RPC_S_INVALID_TAG);
4459 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
4466 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
4468 unsigned short type;
4472 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4476 type = *(const unsigned short*)pFormat;
4477 if((type & 0xff00) == 0x8000)
4479 unsigned char basetype = LOBYTE(type);
4480 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
4484 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4485 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
4488 unsigned char *saved_buffer = NULL;
4489 int pointer_buffer_mark_set = 0;
4496 ALIGN_POINTER(pStubMsg->Buffer, 4);
4497 saved_buffer = pStubMsg->Buffer;
4498 if (pStubMsg->PointerBufferMark)
4500 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4501 pStubMsg->PointerBufferMark = NULL;
4502 pointer_buffer_mark_set = 1;
4505 pStubMsg->Buffer += 4; /* for pointer ID */
4507 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
4508 if (pointer_buffer_mark_set)
4510 STD_OVERFLOW_CHECK(pStubMsg);
4511 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4512 pStubMsg->Buffer = saved_buffer + 4;
4516 m(pStubMsg, pMemory, desc);
4519 else FIXME("no marshaller for embedded type %02x\n", *desc);
4524 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4525 unsigned char **ppMemory,
4527 PFORMAT_STRING pFormat,
4528 unsigned char fMustAlloc)
4530 unsigned short type;
4534 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4538 type = *(const unsigned short*)pFormat;
4539 if((type & 0xff00) == 0x8000)
4541 unsigned char basetype = LOBYTE(type);
4542 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, fMustAlloc);
4546 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4547 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
4550 unsigned char *saved_buffer = NULL;
4551 int pointer_buffer_mark_set = 0;
4558 **(void***)ppMemory = NULL;
4559 ALIGN_POINTER(pStubMsg->Buffer, 4);
4560 saved_buffer = pStubMsg->Buffer;
4561 if (pStubMsg->PointerBufferMark)
4563 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4564 pStubMsg->PointerBufferMark = NULL;
4565 pointer_buffer_mark_set = 1;
4568 pStubMsg->Buffer += 4; /* for pointer ID */
4570 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, desc, fMustAlloc);
4571 if (pointer_buffer_mark_set)
4573 STD_OVERFLOW_CHECK(pStubMsg);
4574 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4575 pStubMsg->Buffer = saved_buffer + 4;
4579 m(pStubMsg, ppMemory, desc, fMustAlloc);
4582 else FIXME("no marshaller for embedded type %02x\n", *desc);
4587 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
4588 unsigned char *pMemory,
4590 PFORMAT_STRING pFormat)
4592 unsigned short type;
4596 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4600 type = *(const unsigned short*)pFormat;
4601 if((type & 0xff00) == 0x8000)
4603 unsigned char basetype = LOBYTE(type);
4604 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
4608 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4609 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
4618 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4619 pStubMsg->BufferLength += 4; /* for pointer ID */
4620 if (!pStubMsg->IgnoreEmbeddedPointers)
4622 int saved_buffer_length = pStubMsg->BufferLength;
4623 pStubMsg->BufferLength = pStubMsg->PointerLength;
4624 pStubMsg->PointerLength = 0;
4625 if(!pStubMsg->BufferLength)
4626 ERR("BufferLength == 0??\n");
4627 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
4628 pStubMsg->PointerLength = pStubMsg->BufferLength;
4629 pStubMsg->BufferLength = saved_buffer_length;
4633 m(pStubMsg, pMemory, desc);
4636 else FIXME("no buffersizer for embedded type %02x\n", *desc);
4640 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
4642 PFORMAT_STRING pFormat)
4644 unsigned short type, size;
4646 size = *(const unsigned short*)pFormat;
4647 pStubMsg->Memory += size;
4650 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4654 type = *(const unsigned short*)pFormat;
4655 if((type & 0xff00) == 0x8000)
4657 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
4661 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4662 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
4663 unsigned char *saved_buffer;
4672 ALIGN_POINTER(pStubMsg->Buffer, 4);
4673 saved_buffer = pStubMsg->Buffer;
4674 pStubMsg->Buffer += 4;
4675 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
4676 pStubMsg->MemorySize += 4;
4677 if (!pStubMsg->IgnoreEmbeddedPointers)
4678 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
4681 return m(pStubMsg, desc);
4684 else FIXME("no marshaller for embedded type %02x\n", *desc);
4687 TRACE("size %d\n", size);
4691 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
4692 unsigned char *pMemory,
4694 PFORMAT_STRING pFormat)
4696 unsigned short type;
4700 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4704 type = *(const unsigned short*)pFormat;
4705 if((type & 0xff00) != 0x8000)
4707 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4708 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
4717 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
4720 m(pStubMsg, pMemory, desc);
4723 else FIXME("no freer for embedded type %02x\n", *desc);
4727 /***********************************************************************
4728 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4730 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4731 unsigned char *pMemory,
4732 PFORMAT_STRING pFormat)
4734 unsigned char switch_type;
4735 unsigned char increment;
4738 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4741 switch_type = *pFormat & 0xf;
4742 increment = (*pFormat & 0xf0) >> 4;
4745 ALIGN_POINTER(pStubMsg->Buffer, increment);
4747 switch_value = get_discriminant(switch_type, pMemory);
4748 TRACE("got switch value 0x%x\n", switch_value);
4750 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
4751 pMemory += increment;
4753 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
4756 /***********************************************************************
4757 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4759 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4760 unsigned char **ppMemory,
4761 PFORMAT_STRING pFormat,
4762 unsigned char fMustAlloc)
4764 unsigned char switch_type;
4765 unsigned char increment;
4767 unsigned short size;
4768 unsigned char *pMemoryArm;
4770 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4773 switch_type = *pFormat & 0xf;
4774 increment = (*pFormat & 0xf0) >> 4;
4777 ALIGN_POINTER(pStubMsg->Buffer, increment);
4778 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
4779 TRACE("got switch value 0x%x\n", switch_value);
4781 size = *(const unsigned short*)pFormat + increment;
4782 if(!*ppMemory || fMustAlloc)
4783 *ppMemory = NdrAllocate(pStubMsg, size);
4785 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
4786 pMemoryArm = *ppMemory + increment;
4788 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
4791 /***********************************************************************
4792 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4794 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4795 unsigned char *pMemory,
4796 PFORMAT_STRING pFormat)
4798 unsigned char switch_type;
4799 unsigned char increment;
4802 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4805 switch_type = *pFormat & 0xf;
4806 increment = (*pFormat & 0xf0) >> 4;
4809 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
4810 switch_value = get_discriminant(switch_type, pMemory);
4811 TRACE("got switch value 0x%x\n", switch_value);
4813 /* Add discriminant size */
4814 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
4815 pMemory += increment;
4817 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
4820 /***********************************************************************
4821 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4823 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4824 PFORMAT_STRING pFormat)
4826 unsigned char switch_type;
4827 unsigned char increment;
4830 switch_type = *pFormat & 0xf;
4831 increment = (*pFormat & 0xf0) >> 4;
4834 ALIGN_POINTER(pStubMsg->Buffer, increment);
4835 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
4836 TRACE("got switch value 0x%x\n", switch_value);
4838 pStubMsg->Memory += increment;
4840 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
4843 /***********************************************************************
4844 * NdrEncapsulatedUnionFree [RPCRT4.@]
4846 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4847 unsigned char *pMemory,
4848 PFORMAT_STRING pFormat)
4850 unsigned char switch_type;
4851 unsigned char increment;
4854 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4857 switch_type = *pFormat & 0xf;
4858 increment = (*pFormat & 0xf0) >> 4;
4861 switch_value = get_discriminant(switch_type, pMemory);
4862 TRACE("got switch value 0x%x\n", switch_value);
4864 pMemory += increment;
4866 return union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
4869 /***********************************************************************
4870 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
4872 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4873 unsigned char *pMemory,
4874 PFORMAT_STRING pFormat)
4876 unsigned char switch_type;
4878 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4881 switch_type = *pFormat;
4884 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4885 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4886 /* Marshall discriminant */
4887 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4889 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
4892 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
4893 PFORMAT_STRING *ppFormat)
4895 long discriminant = 0;
4903 discriminant = *(UCHAR *)pStubMsg->Buffer;
4904 pStubMsg->Buffer += sizeof(UCHAR);
4909 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4910 discriminant = *(USHORT *)pStubMsg->Buffer;
4911 pStubMsg->Buffer += sizeof(USHORT);
4915 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4916 discriminant = *(ULONG *)pStubMsg->Buffer;
4917 pStubMsg->Buffer += sizeof(ULONG);
4920 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
4924 if (pStubMsg->fHasNewCorrDesc)
4928 return discriminant;
4931 /**********************************************************************
4932 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
4934 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4935 unsigned char **ppMemory,
4936 PFORMAT_STRING pFormat,
4937 unsigned char fMustAlloc)
4940 unsigned short size;
4942 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4945 /* Unmarshall discriminant */
4946 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4947 TRACE("unmarshalled discriminant %lx\n", discriminant);
4949 pFormat += *(const SHORT*)pFormat;
4951 size = *(const unsigned short*)pFormat;
4953 if(!*ppMemory || fMustAlloc)
4954 *ppMemory = NdrAllocate(pStubMsg, size);
4956 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
4959 /***********************************************************************
4960 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
4962 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4963 unsigned char *pMemory,
4964 PFORMAT_STRING pFormat)
4966 unsigned char switch_type;
4968 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4971 switch_type = *pFormat;
4974 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4975 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4976 /* Add discriminant size */
4977 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4979 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
4982 /***********************************************************************
4983 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
4985 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4986 PFORMAT_STRING pFormat)
4991 /* Unmarshall discriminant */
4992 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4993 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
4995 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
4998 /***********************************************************************
4999 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5001 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5002 unsigned char *pMemory,
5003 PFORMAT_STRING pFormat)
5005 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5009 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5010 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5012 return union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5015 /***********************************************************************
5016 * NdrByteCountPointerMarshall [RPCRT4.@]
5018 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5019 unsigned char *pMemory,
5020 PFORMAT_STRING pFormat)
5026 /***********************************************************************
5027 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5029 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5030 unsigned char **ppMemory,
5031 PFORMAT_STRING pFormat,
5032 unsigned char fMustAlloc)
5038 /***********************************************************************
5039 * NdrByteCountPointerBufferSize [RPCRT4.@]
5041 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5042 unsigned char *pMemory,
5043 PFORMAT_STRING pFormat)
5048 /***********************************************************************
5049 * NdrByteCountPointerMemorySize [RPCRT4.@]
5051 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5052 PFORMAT_STRING pFormat)
5058 /***********************************************************************
5059 * NdrByteCountPointerFree [RPCRT4.@]
5061 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
5062 unsigned char *pMemory,
5063 PFORMAT_STRING pFormat)
5068 /***********************************************************************
5069 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5071 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5072 unsigned char *pMemory,
5073 PFORMAT_STRING pFormat)
5079 /***********************************************************************
5080 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5082 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5083 unsigned char **ppMemory,
5084 PFORMAT_STRING pFormat,
5085 unsigned char fMustAlloc)
5091 /***********************************************************************
5092 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5094 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5095 unsigned char *pMemory,
5096 PFORMAT_STRING pFormat)
5101 /***********************************************************************
5102 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5104 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5105 PFORMAT_STRING pFormat)
5111 /***********************************************************************
5112 * NdrXmitOrRepAsFree [RPCRT4.@]
5114 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
5115 unsigned char *pMemory,
5116 PFORMAT_STRING pFormat)
5121 #include "pshpack1.h"
5125 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
5129 #include "poppack.h"
5131 /***********************************************************************
5132 * NdrRangeMarshall [internal]
5134 unsigned char *WINAPI NdrRangeMarshall(
5135 PMIDL_STUB_MESSAGE pStubMsg,
5136 unsigned char *pMemory,
5137 PFORMAT_STRING pFormat)
5139 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5140 unsigned char base_type;
5142 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5144 if (pRange->type != RPC_FC_RANGE)
5146 ERR("invalid format type %x\n", pRange->type);
5147 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5151 base_type = pRange->flags_type & 0xf;
5153 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
5156 /***********************************************************************
5157 * NdrRangeUnmarshall
5159 unsigned char *WINAPI NdrRangeUnmarshall(
5160 PMIDL_STUB_MESSAGE pStubMsg,
5161 unsigned char **ppMemory,
5162 PFORMAT_STRING pFormat,
5163 unsigned char fMustAlloc)
5165 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5166 unsigned char base_type;
5168 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5170 if (pRange->type != RPC_FC_RANGE)
5172 ERR("invalid format type %x\n", pRange->type);
5173 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5176 base_type = pRange->flags_type & 0xf;
5178 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5179 base_type, pRange->low_value, pRange->high_value);
5181 #define RANGE_UNMARSHALL(type, format_spec) \
5184 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5185 if (fMustAlloc || !*ppMemory) \
5186 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5187 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5188 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5190 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5191 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5192 (type)pRange->high_value); \
5193 RpcRaiseException(RPC_S_INVALID_BOUND); \
5196 TRACE("*ppMemory: %p\n", *ppMemory); \
5197 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5198 pStubMsg->Buffer += sizeof(type); \
5205 RANGE_UNMARSHALL(UCHAR, "%d");
5206 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5210 RANGE_UNMARSHALL(CHAR, "%u");
5211 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5213 case RPC_FC_WCHAR: /* FIXME: valid? */
5215 RANGE_UNMARSHALL(USHORT, "%u");
5216 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5219 RANGE_UNMARSHALL(SHORT, "%d");
5220 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5223 RANGE_UNMARSHALL(LONG, "%d");
5224 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5227 RANGE_UNMARSHALL(ULONG, "%u");
5228 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5232 FIXME("Unhandled enum type\n");
5234 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
5239 ERR("invalid range base type: 0x%02x\n", base_type);
5240 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5246 /***********************************************************************
5247 * NdrRangeBufferSize [internal]
5249 void WINAPI NdrRangeBufferSize(
5250 PMIDL_STUB_MESSAGE pStubMsg,
5251 unsigned char *pMemory,
5252 PFORMAT_STRING pFormat)
5254 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5255 unsigned char base_type;
5257 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5259 if (pRange->type != RPC_FC_RANGE)
5261 ERR("invalid format type %x\n", pRange->type);
5262 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5264 base_type = pRange->flags_type & 0xf;
5266 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
5269 /***********************************************************************
5270 * NdrRangeMemorySize [internal]
5272 ULONG WINAPI NdrRangeMemorySize(
5273 PMIDL_STUB_MESSAGE pStubMsg,
5274 PFORMAT_STRING pFormat)
5276 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5277 unsigned char base_type;
5279 if (pRange->type != RPC_FC_RANGE)
5281 ERR("invalid format type %x\n", pRange->type);
5282 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5285 base_type = pRange->flags_type & 0xf;
5287 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
5290 /***********************************************************************
5291 * NdrRangeFree [internal]
5293 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
5294 unsigned char *pMemory,
5295 PFORMAT_STRING pFormat)
5297 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5302 /***********************************************************************
5303 * NdrBaseTypeMarshall [internal]
5305 static unsigned char *WINAPI NdrBaseTypeMarshall(
5306 PMIDL_STUB_MESSAGE pStubMsg,
5307 unsigned char *pMemory,
5308 PFORMAT_STRING pFormat)
5310 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5318 *(UCHAR *)pStubMsg->Buffer = *(UCHAR *)pMemory;
5319 pStubMsg->Buffer += sizeof(UCHAR);
5320 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
5325 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5326 *(USHORT *)pStubMsg->Buffer = *(USHORT *)pMemory;
5327 pStubMsg->Buffer += sizeof(USHORT);
5328 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
5332 case RPC_FC_ERROR_STATUS_T:
5334 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5335 *(ULONG *)pStubMsg->Buffer = *(ULONG *)pMemory;
5336 pStubMsg->Buffer += sizeof(ULONG);
5337 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
5340 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
5341 *(float *)pStubMsg->Buffer = *(float *)pMemory;
5342 pStubMsg->Buffer += sizeof(float);
5345 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
5346 *(double *)pStubMsg->Buffer = *(double *)pMemory;
5347 pStubMsg->Buffer += sizeof(double);
5350 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
5351 *(ULONGLONG *)pStubMsg->Buffer = *(ULONGLONG *)pMemory;
5352 pStubMsg->Buffer += sizeof(ULONGLONG);
5353 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
5356 /* only 16-bits on the wire, so do a sanity check */
5357 if (*(UINT *)pMemory > USHRT_MAX)
5358 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
5359 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5360 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
5361 pStubMsg->Buffer += sizeof(USHORT);
5362 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
5365 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5368 STD_OVERFLOW_CHECK(pStubMsg);
5370 /* FIXME: what is the correct return value? */
5374 /***********************************************************************
5375 * NdrBaseTypeUnmarshall [internal]
5377 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
5378 PMIDL_STUB_MESSAGE pStubMsg,
5379 unsigned char **ppMemory,
5380 PFORMAT_STRING pFormat,
5381 unsigned char fMustAlloc)
5383 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5385 #define BASE_TYPE_UNMARSHALL(type) \
5386 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5387 if (fMustAlloc || !*ppMemory) \
5388 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5389 TRACE("*ppMemory: %p\n", *ppMemory); \
5390 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5391 pStubMsg->Buffer += sizeof(type);
5399 BASE_TYPE_UNMARSHALL(UCHAR);
5400 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5405 BASE_TYPE_UNMARSHALL(USHORT);
5406 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5410 case RPC_FC_ERROR_STATUS_T:
5412 BASE_TYPE_UNMARSHALL(ULONG);
5413 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5416 BASE_TYPE_UNMARSHALL(float);
5417 TRACE("value: %f\n", **(float **)ppMemory);
5420 BASE_TYPE_UNMARSHALL(double);
5421 TRACE("value: %f\n", **(double **)ppMemory);
5424 BASE_TYPE_UNMARSHALL(ULONGLONG);
5425 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
5428 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5429 if (fMustAlloc || !*ppMemory)
5430 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
5431 TRACE("*ppMemory: %p\n", *ppMemory);
5432 /* 16-bits on the wire, but int in memory */
5433 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
5434 pStubMsg->Buffer += sizeof(USHORT);
5435 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
5438 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5440 #undef BASE_TYPE_UNMARSHALL
5442 /* FIXME: what is the correct return value? */
5447 /***********************************************************************
5448 * NdrBaseTypeBufferSize [internal]
5450 static void WINAPI NdrBaseTypeBufferSize(
5451 PMIDL_STUB_MESSAGE pStubMsg,
5452 unsigned char *pMemory,
5453 PFORMAT_STRING pFormat)
5455 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5463 pStubMsg->BufferLength += sizeof(UCHAR);
5469 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
5470 pStubMsg->BufferLength += sizeof(USHORT);
5475 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
5476 pStubMsg->BufferLength += sizeof(ULONG);
5479 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
5480 pStubMsg->BufferLength += sizeof(float);
5483 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
5484 pStubMsg->BufferLength += sizeof(double);
5487 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
5488 pStubMsg->BufferLength += sizeof(ULONGLONG);
5490 case RPC_FC_ERROR_STATUS_T:
5491 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
5492 pStubMsg->BufferLength += sizeof(error_status_t);
5495 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5499 /***********************************************************************
5500 * NdrBaseTypeMemorySize [internal]
5502 static ULONG WINAPI NdrBaseTypeMemorySize(
5503 PMIDL_STUB_MESSAGE pStubMsg,
5504 PFORMAT_STRING pFormat)
5512 pStubMsg->Buffer += sizeof(UCHAR);
5513 pStubMsg->MemorySize += sizeof(UCHAR);
5514 return sizeof(UCHAR);
5518 pStubMsg->Buffer += sizeof(USHORT);
5519 pStubMsg->MemorySize += sizeof(USHORT);
5520 return sizeof(USHORT);
5523 pStubMsg->Buffer += sizeof(ULONG);
5524 pStubMsg->MemorySize += sizeof(ULONG);
5525 return sizeof(ULONG);
5527 pStubMsg->Buffer += sizeof(float);
5528 pStubMsg->MemorySize += sizeof(float);
5529 return sizeof(float);
5531 pStubMsg->Buffer += sizeof(double);
5532 pStubMsg->MemorySize += sizeof(double);
5533 return sizeof(double);
5535 pStubMsg->Buffer += sizeof(ULONGLONG);
5536 pStubMsg->MemorySize += sizeof(ULONGLONG);
5537 return sizeof(ULONGLONG);
5538 case RPC_FC_ERROR_STATUS_T:
5539 pStubMsg->Buffer += sizeof(error_status_t);
5540 pStubMsg->MemorySize += sizeof(error_status_t);
5541 return sizeof(error_status_t);
5544 pStubMsg->Buffer += sizeof(INT);
5545 pStubMsg->MemorySize += sizeof(INT);
5548 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5553 /***********************************************************************
5554 * NdrBaseTypeFree [internal]
5556 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
5557 unsigned char *pMemory,
5558 PFORMAT_STRING pFormat)
5560 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5565 /***********************************************************************
5566 * NdrContextHandleBufferSize [internal]
5568 static void WINAPI NdrContextHandleBufferSize(
5569 PMIDL_STUB_MESSAGE pStubMsg,
5570 unsigned char *pMemory,
5571 PFORMAT_STRING pFormat)
5573 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5575 if (*pFormat != RPC_FC_BIND_CONTEXT)
5577 ERR("invalid format type %x\n", *pFormat);
5578 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5580 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5581 pStubMsg->BufferLength += cbNDRContext;
5584 /***********************************************************************
5585 * NdrContextHandleMarshall [internal]
5587 static unsigned char *WINAPI NdrContextHandleMarshall(
5588 PMIDL_STUB_MESSAGE pStubMsg,
5589 unsigned char *pMemory,
5590 PFORMAT_STRING pFormat)
5592 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5594 if (*pFormat != RPC_FC_BIND_CONTEXT)
5596 ERR("invalid format type %x\n", *pFormat);
5597 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5600 if (pFormat[1] & 0x80)
5601 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
5603 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
5608 /***********************************************************************
5609 * NdrContextHandleUnmarshall [internal]
5611 static unsigned char *WINAPI NdrContextHandleUnmarshall(
5612 PMIDL_STUB_MESSAGE pStubMsg,
5613 unsigned char **ppMemory,
5614 PFORMAT_STRING pFormat,
5615 unsigned char fMustAlloc)
5617 if (*pFormat != RPC_FC_BIND_CONTEXT)
5619 ERR("invalid format type %x\n", *pFormat);
5620 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5623 **(NDR_CCONTEXT **)ppMemory = NULL;
5624 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
5629 /***********************************************************************
5630 * NdrClientContextMarshall [RPCRT4.@]
5632 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5633 NDR_CCONTEXT ContextHandle,
5636 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
5638 ALIGN_POINTER(pStubMsg->Buffer, 4);
5640 /* FIXME: what does fCheck do? */
5641 NDRCContextMarshall(ContextHandle,
5644 pStubMsg->Buffer += cbNDRContext;
5647 /***********************************************************************
5648 * NdrClientContextUnmarshall [RPCRT4.@]
5650 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5651 NDR_CCONTEXT * pContextHandle,
5652 RPC_BINDING_HANDLE BindHandle)
5654 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
5656 ALIGN_POINTER(pStubMsg->Buffer, 4);
5658 NDRCContextUnmarshall(pContextHandle,
5661 pStubMsg->RpcMsg->DataRepresentation);
5663 pStubMsg->Buffer += cbNDRContext;
5666 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5667 NDR_SCONTEXT ContextHandle,
5668 NDR_RUNDOWN RundownRoutine )
5670 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
5673 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
5675 FIXME("(%p): stub\n", pStubMsg);
5679 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
5680 unsigned char* pMemory,
5681 PFORMAT_STRING pFormat)
5683 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
5686 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
5687 PFORMAT_STRING pFormat)
5689 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
5693 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5694 NDR_SCONTEXT ContextHandle,
5695 NDR_RUNDOWN RundownRoutine,
5696 PFORMAT_STRING pFormat)
5698 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
5701 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5702 PFORMAT_STRING pFormat)
5704 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
5708 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
5710 typedef struct ndr_context_handle
5714 } ndr_context_handle;
5716 struct context_handle_entry
5720 RPC_BINDING_HANDLE handle;
5721 ndr_context_handle wire_data;
5724 static struct list context_handle_list = LIST_INIT(context_handle_list);
5726 static CRITICAL_SECTION ndr_context_cs;
5727 static CRITICAL_SECTION_DEBUG ndr_context_debug =
5729 0, 0, &ndr_context_cs,
5730 { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
5731 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
5733 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
5735 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
5737 struct context_handle_entry *che = (struct context_handle_entry*) CContext;
5739 if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
5744 static struct context_handle_entry *context_entry_from_guid(LPGUID uuid)
5746 struct context_handle_entry *che;
5747 LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
5748 if (IsEqualGUID(&che->wire_data.uuid, uuid))
5753 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
5755 struct context_handle_entry *che;
5756 RPC_BINDING_HANDLE handle = NULL;
5758 TRACE("%p\n", CContext);
5760 EnterCriticalSection(&ndr_context_cs);
5761 che = get_context_entry(CContext);
5763 handle = che->handle;
5764 LeaveCriticalSection(&ndr_context_cs);
5767 RpcRaiseException(ERROR_INVALID_HANDLE);
5771 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
5773 struct context_handle_entry *che;
5775 TRACE("%p %p\n", CContext, pBuff);
5779 EnterCriticalSection(&ndr_context_cs);
5780 che = get_context_entry(CContext);
5781 memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
5782 LeaveCriticalSection(&ndr_context_cs);
5786 ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
5787 wire_data->attributes = 0;
5788 wire_data->uuid = GUID_NULL;
5792 static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
5793 RPC_BINDING_HANDLE hBinding,
5794 ndr_context_handle *chi)
5796 struct context_handle_entry *che = NULL;
5798 /* a null UUID means we should free the context handle */
5799 if (IsEqualGUID(&chi->uuid, &GUID_NULL))
5803 che = get_context_entry(*CContext);
5805 return ERROR_INVALID_HANDLE;
5806 list_remove(&che->entry);
5807 RpcBindingFree(&che->handle);
5808 HeapFree(GetProcessHeap(), 0, che);
5812 /* if there's no existing entry matching the GUID, allocate one */
5813 else if (!(che = context_entry_from_guid(&chi->uuid)))
5815 che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
5817 return ERROR_NOT_ENOUGH_MEMORY;
5818 che->magic = NDR_CONTEXT_HANDLE_MAGIC;
5819 RpcBindingCopy(hBinding, &che->handle);
5820 list_add_tail(&context_handle_list, &che->entry);
5821 memcpy(&che->wire_data, chi, sizeof *chi);
5826 return ERROR_SUCCESS;
5829 /***********************************************************************
5830 * NDRCContextUnmarshall [RPCRT4.@]
5832 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
5833 RPC_BINDING_HANDLE hBinding,
5834 void *pBuff, ULONG DataRepresentation)
5838 TRACE("*%p=(%p) %p %p %08x\n",
5839 CContext, *CContext, hBinding, pBuff, DataRepresentation);
5841 EnterCriticalSection(&ndr_context_cs);
5842 r = ndr_update_context_handle(CContext, hBinding, pBuff);
5843 LeaveCriticalSection(&ndr_context_cs);
5845 RpcRaiseException(r);
5848 /***********************************************************************
5849 * NDRSContextMarshall [RPCRT4.@]
5851 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
5853 NDR_RUNDOWN userRunDownIn)
5855 FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn);
5858 /***********************************************************************
5859 * NDRSContextMarshallEx [RPCRT4.@]
5861 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
5862 NDR_SCONTEXT CContext,
5864 NDR_RUNDOWN userRunDownIn)
5866 FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn);
5869 /***********************************************************************
5870 * NDRSContextMarshall2 [RPCRT4.@]
5872 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
5873 NDR_SCONTEXT CContext,
5875 NDR_RUNDOWN userRunDownIn,
5876 void *CtxGuard, ULONG Flags)
5878 FIXME("(%p %p %p %p %p %u): stub\n",
5879 hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags);
5882 /***********************************************************************
5883 * NDRSContextUnmarshall [RPCRT4.@]
5885 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
5886 ULONG DataRepresentation)
5888 FIXME("(%p %08x): stub\n", pBuff, DataRepresentation);
5892 /***********************************************************************
5893 * NDRSContextUnmarshallEx [RPCRT4.@]
5895 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
5897 ULONG DataRepresentation)
5899 FIXME("(%p %p %08x): stub\n", hBinding, pBuff, DataRepresentation);
5903 /***********************************************************************
5904 * NDRSContextUnmarshall2 [RPCRT4.@]
5906 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
5908 ULONG DataRepresentation,
5909 void *CtxGuard, ULONG Flags)
5911 FIXME("(%p %p %08x %p %u): stub\n",
5912 hBinding, pBuff, DataRepresentation, CtxGuard, Flags);