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 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
123 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
124 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
125 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
126 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
130 NdrPointerMarshall, NdrPointerMarshall,
131 NdrPointerMarshall, NdrPointerMarshall,
133 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
134 NdrConformantStructMarshall, NdrConformantStructMarshall,
135 NdrConformantVaryingStructMarshall,
136 NdrComplexStructMarshall,
138 NdrConformantArrayMarshall,
139 NdrConformantVaryingArrayMarshall,
140 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
141 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
142 NdrComplexArrayMarshall,
144 NdrConformantStringMarshall, 0, 0,
145 NdrConformantStringMarshall,
146 NdrNonConformantStringMarshall, 0, 0, 0,
148 NdrEncapsulatedUnionMarshall,
149 NdrNonEncapsulatedUnionMarshall,
150 NdrByteCountPointerMarshall,
151 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
153 NdrInterfacePointerMarshall,
156 NdrUserMarshalMarshall
158 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
160 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
161 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
162 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
163 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
165 NdrBaseTypeUnmarshall,
167 NdrPointerUnmarshall, NdrPointerUnmarshall,
168 NdrPointerUnmarshall, NdrPointerUnmarshall,
170 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
171 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
172 NdrConformantVaryingStructUnmarshall,
173 NdrComplexStructUnmarshall,
175 NdrConformantArrayUnmarshall,
176 NdrConformantVaryingArrayUnmarshall,
177 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
178 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
179 NdrComplexArrayUnmarshall,
181 NdrConformantStringUnmarshall, 0, 0,
182 NdrConformantStringUnmarshall,
183 NdrNonConformantStringUnmarshall, 0, 0, 0,
185 NdrEncapsulatedUnionUnmarshall,
186 NdrNonEncapsulatedUnionUnmarshall,
187 NdrByteCountPointerUnmarshall,
188 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
190 NdrInterfacePointerUnmarshall,
193 NdrUserMarshalUnmarshall
195 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
197 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
198 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
199 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
200 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
202 NdrBaseTypeBufferSize,
204 NdrPointerBufferSize, NdrPointerBufferSize,
205 NdrPointerBufferSize, NdrPointerBufferSize,
207 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
208 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
209 NdrConformantVaryingStructBufferSize,
210 NdrComplexStructBufferSize,
212 NdrConformantArrayBufferSize,
213 NdrConformantVaryingArrayBufferSize,
214 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
215 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
216 NdrComplexArrayBufferSize,
218 NdrConformantStringBufferSize, 0, 0,
219 NdrConformantStringBufferSize,
220 NdrNonConformantStringBufferSize, 0, 0, 0,
222 NdrEncapsulatedUnionBufferSize,
223 NdrNonEncapsulatedUnionBufferSize,
224 NdrByteCountPointerBufferSize,
225 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
227 NdrInterfacePointerBufferSize,
230 NdrUserMarshalBufferSize
232 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
234 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
235 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
236 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
237 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
239 NdrBaseTypeMemorySize,
241 NdrPointerMemorySize, NdrPointerMemorySize,
242 NdrPointerMemorySize, NdrPointerMemorySize,
244 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
245 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
246 NdrConformantVaryingStructMemorySize,
247 NdrComplexStructMemorySize,
249 NdrConformantArrayMemorySize,
250 NdrConformantVaryingArrayMemorySize,
251 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
252 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
253 NdrComplexArrayMemorySize,
255 NdrConformantStringMemorySize, 0, 0,
256 NdrConformantStringMemorySize,
257 NdrNonConformantStringMemorySize, 0, 0, 0,
259 NdrEncapsulatedUnionMemorySize,
260 NdrNonEncapsulatedUnionMemorySize,
261 NdrByteCountPointerMemorySize,
262 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
264 NdrInterfacePointerMemorySize,
267 NdrUserMarshalMemorySize
269 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
271 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
272 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
273 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
274 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
278 NdrPointerFree, NdrPointerFree,
279 NdrPointerFree, NdrPointerFree,
281 NdrSimpleStructFree, NdrSimpleStructFree,
282 NdrConformantStructFree, NdrConformantStructFree,
283 NdrConformantVaryingStructFree,
284 NdrComplexStructFree,
286 NdrConformantArrayFree,
287 NdrConformantVaryingArrayFree,
288 NdrFixedArrayFree, NdrFixedArrayFree,
289 NdrVaryingArrayFree, NdrVaryingArrayFree,
295 NdrEncapsulatedUnionFree,
296 NdrNonEncapsulatedUnionFree,
298 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
300 NdrInterfacePointerFree,
306 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
308 /* hmm, this is probably supposed to do more? */
309 return pStubMsg->pfnAllocate(len);
312 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
314 pStubMsg->pfnFree(Pointer);
317 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
319 return (*(const ULONG *)pFormat != -1);
322 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
324 ALIGN_POINTER(pStubMsg->Buffer, 4);
325 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
326 pStubMsg->Buffer += 4;
327 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
328 if (pStubMsg->fHasNewCorrDesc)
334 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
336 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
338 pStubMsg->Offset = 0;
339 pStubMsg->ActualCount = pStubMsg->MaxCount;
343 ALIGN_POINTER(pStubMsg->Buffer, 4);
344 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
345 pStubMsg->Buffer += 4;
346 TRACE("offset is %d\n", pStubMsg->Offset);
347 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
348 pStubMsg->Buffer += 4;
349 TRACE("variance is %d\n", pStubMsg->ActualCount);
351 if ((pStubMsg->ActualCount > MaxValue) ||
352 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
354 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
355 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
356 RpcRaiseException(RPC_S_INVALID_BOUND);
361 if (pStubMsg->fHasNewCorrDesc)
367 /* writes the conformance value to the buffer */
368 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
370 ALIGN_POINTER(pStubMsg->Buffer, 4);
371 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
372 pStubMsg->Buffer += 4;
375 /* writes the variance values to the buffer */
376 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
378 ALIGN_POINTER(pStubMsg->Buffer, 4);
379 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
380 pStubMsg->Buffer += 4;
381 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
382 pStubMsg->Buffer += 4;
385 /* requests buffer space for the conformance value */
386 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
388 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
389 pStubMsg->BufferLength += 4;
392 /* requests buffer space for the variance values */
393 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
395 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
396 pStubMsg->BufferLength += 8;
399 PFORMAT_STRING ComputeConformanceOrVariance(
400 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
401 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
403 BYTE dtype = pFormat[0] & 0xf;
404 short ofs = *(const short *)&pFormat[2];
408 if (!IsConformanceOrVariancePresent(pFormat)) {
409 /* null descriptor */
414 switch (pFormat[0] & 0xf0) {
415 case RPC_FC_NORMAL_CONFORMANCE:
416 TRACE("normal conformance, ofs=%d\n", ofs);
419 case RPC_FC_POINTER_CONFORMANCE:
420 TRACE("pointer conformance, ofs=%d\n", ofs);
421 ptr = pStubMsg->Memory;
423 case RPC_FC_TOP_LEVEL_CONFORMANCE:
424 TRACE("toplevel conformance, ofs=%d\n", ofs);
425 if (pStubMsg->StackTop) {
426 ptr = pStubMsg->StackTop;
429 /* -Os mode, *pCount is already set */
433 case RPC_FC_CONSTANT_CONFORMANCE:
434 data = ofs | ((DWORD)pFormat[1] << 16);
435 TRACE("constant conformance, val=%d\n", data);
438 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
439 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
440 if (pStubMsg->StackTop) {
441 ptr = pStubMsg->StackTop;
449 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
452 switch (pFormat[1]) {
453 case RPC_FC_DEREFERENCE:
454 ptr = *(LPVOID*)((char *)ptr + ofs);
456 case RPC_FC_CALLBACK:
458 unsigned char *old_stack_top = pStubMsg->StackTop;
459 pStubMsg->StackTop = ptr;
461 /* ofs is index into StubDesc->apfnExprEval */
462 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
463 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
465 pStubMsg->StackTop = old_stack_top;
467 /* the callback function always stores the computed value in MaxCount */
468 *pCount = pStubMsg->MaxCount;
472 ptr = (char *)ptr + ofs;
485 data = *(USHORT*)ptr;
496 FIXME("unknown conformance data type %x\n", dtype);
499 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
502 switch (pFormat[1]) {
503 case RPC_FC_DEREFERENCE: /* already handled */
520 FIXME("unknown conformance op %d\n", pFormat[1]);
525 TRACE("resulting conformance is %ld\n", *pCount);
526 if (pStubMsg->fHasNewCorrDesc)
532 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
533 * the result overflows 32-bits */
534 static inline ULONG safe_multiply(ULONG a, ULONG b)
536 ULONGLONG ret = (ULONGLONG)a * b;
537 if (ret > 0xffffffff)
539 RpcRaiseException(RPC_S_INVALID_BOUND);
547 * NdrConformantString:
549 * What MS calls a ConformantString is, in DCE terminology,
550 * a Varying-Conformant String.
552 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
553 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
554 * into unmarshalled string)
555 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
557 * data: CHARTYPE[maxlen]
559 * ], where CHARTYPE is the appropriate character type (specified externally)
563 /***********************************************************************
564 * NdrConformantStringMarshall [RPCRT4.@]
566 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
567 unsigned char *pszMessage, PFORMAT_STRING pFormat)
571 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
573 if (*pFormat == RPC_FC_C_CSTRING) {
574 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
575 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
578 else if (*pFormat == RPC_FC_C_WSTRING) {
579 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
580 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
584 ERR("Unhandled string type: %#x\n", *pFormat);
585 /* FIXME: raise an exception. */
589 if (pFormat[1] == RPC_FC_STRING_SIZED)
590 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
592 pStubMsg->MaxCount = pStubMsg->ActualCount;
593 pStubMsg->Offset = 0;
594 WriteConformance(pStubMsg);
595 WriteVariance(pStubMsg);
597 size = safe_multiply(esize, pStubMsg->ActualCount);
598 memcpy(pStubMsg->Buffer, pszMessage, size); /* the string itself */
599 pStubMsg->Buffer += size;
601 STD_OVERFLOW_CHECK(pStubMsg);
604 return NULL; /* is this always right? */
607 /***********************************************************************
608 * NdrConformantStringBufferSize [RPCRT4.@]
610 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
611 unsigned char* pMemory, PFORMAT_STRING pFormat)
615 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
617 SizeConformance(pStubMsg);
618 SizeVariance(pStubMsg);
620 if (*pFormat == RPC_FC_C_CSTRING) {
621 TRACE("string=%s\n", debugstr_a((char*)pMemory));
622 pStubMsg->ActualCount = strlen((char*)pMemory)+1;
625 else if (*pFormat == RPC_FC_C_WSTRING) {
626 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
627 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;
631 ERR("Unhandled string type: %#x\n", *pFormat);
632 /* FIXME: raise an exception */
636 if (pFormat[1] == RPC_FC_STRING_SIZED)
637 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
639 pStubMsg->MaxCount = pStubMsg->ActualCount;
641 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
644 /************************************************************************
645 * NdrConformantStringMemorySize [RPCRT4.@]
647 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
648 PFORMAT_STRING pFormat )
652 FIXME("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
654 assert(pStubMsg && pFormat);
656 if (*pFormat == RPC_FC_C_CSTRING) {
657 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
659 else if (*pFormat == RPC_FC_C_WSTRING) {
660 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
663 ERR("Unhandled string type: %#x\n", *pFormat);
664 /* FIXME: raise an exception */
667 if (pFormat[1] != RPC_FC_PAD) {
668 FIXME("sized string format=%d\n", pFormat[1]);
671 TRACE(" --> %u\n", rslt);
675 /************************************************************************
676 * NdrConformantStringUnmarshall [RPCRT4.@]
678 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
679 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
681 ULONG bufsize, memsize, esize, i;
683 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
684 pStubMsg, *ppMemory, pFormat, fMustAlloc);
686 assert(pFormat && ppMemory && pStubMsg);
688 ReadConformance(pStubMsg, NULL);
689 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
691 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
692 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
694 ERR("Unhandled string type: %#x\n", *pFormat);
695 /* FIXME: raise an exception */
699 memsize = safe_multiply(esize, pStubMsg->MaxCount);
700 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
702 /* strings must always have null terminating bytes */
705 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
706 RpcRaiseException(RPC_S_INVALID_BOUND);
709 for (i = bufsize - esize; i < bufsize; i++)
710 if (pStubMsg->Buffer[i] != 0)
712 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
713 i, pStubMsg->Buffer[i]);
714 RpcRaiseException(RPC_S_INVALID_BOUND);
718 if (fMustAlloc || !*ppMemory)
719 *ppMemory = NdrAllocate(pStubMsg, memsize);
721 memcpy(*ppMemory, pStubMsg->Buffer, bufsize);
723 pStubMsg->Buffer += bufsize;
725 if (*pFormat == RPC_FC_C_CSTRING) {
726 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
728 else if (*pFormat == RPC_FC_C_WSTRING) {
729 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
732 return NULL; /* FIXME: is this always right? */
735 /***********************************************************************
736 * NdrNonConformantStringMarshall [RPCRT4.@]
738 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
739 unsigned char *pMemory,
740 PFORMAT_STRING pFormat)
746 /***********************************************************************
747 * NdrNonConformantStringUnmarshall [RPCRT4.@]
749 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
750 unsigned char **ppMemory,
751 PFORMAT_STRING pFormat,
752 unsigned char fMustAlloc)
758 /***********************************************************************
759 * NdrNonConformantStringBufferSize [RPCRT4.@]
761 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
762 unsigned char *pMemory,
763 PFORMAT_STRING pFormat)
768 /***********************************************************************
769 * NdrNonConformantStringMemorySize [RPCRT4.@]
771 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
772 PFORMAT_STRING pFormat)
778 static inline void dump_pointer_attr(unsigned char attr)
780 if (attr & RPC_FC_P_ALLOCALLNODES)
781 TRACE(" RPC_FC_P_ALLOCALLNODES");
782 if (attr & RPC_FC_P_DONTFREE)
783 TRACE(" RPC_FC_P_DONTFREE");
784 if (attr & RPC_FC_P_ONSTACK)
785 TRACE(" RPC_FC_P_ONSTACK");
786 if (attr & RPC_FC_P_SIMPLEPOINTER)
787 TRACE(" RPC_FC_P_SIMPLEPOINTER");
788 if (attr & RPC_FC_P_DEREF)
789 TRACE(" RPC_FC_P_DEREF");
793 /***********************************************************************
794 * PointerMarshall [internal]
796 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
797 unsigned char *Buffer,
798 unsigned char *Pointer,
799 PFORMAT_STRING pFormat)
801 unsigned type = pFormat[0], attr = pFormat[1];
805 int pointer_needs_marshaling;
807 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
808 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
810 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
811 else desc = pFormat + *(const SHORT*)pFormat;
814 case RPC_FC_RP: /* ref pointer (always non-null) */
815 #if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
817 RpcRaiseException(RPC_X_NULL_REF_POINTER);
819 pointer_needs_marshaling = 1;
821 case RPC_FC_UP: /* unique pointer */
822 case RPC_FC_OP: /* object pointer - same as unique here */
824 pointer_needs_marshaling = 1;
826 pointer_needs_marshaling = 0;
827 pointer_id = (ULONG)Pointer;
828 TRACE("writing 0x%08x to buffer\n", pointer_id);
829 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
832 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
833 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
834 TRACE("writing 0x%08x to buffer\n", pointer_id);
835 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
838 FIXME("unhandled ptr type=%02x\n", type);
839 RpcRaiseException(RPC_X_BAD_STUB_DATA);
843 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
845 if (pointer_needs_marshaling) {
846 if (attr & RPC_FC_P_DEREF) {
847 Pointer = *(unsigned char**)Pointer;
848 TRACE("deref => %p\n", Pointer);
850 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
851 if (m) m(pStubMsg, Pointer, desc);
852 else FIXME("no marshaller for data type=%02x\n", *desc);
855 STD_OVERFLOW_CHECK(pStubMsg);
858 /***********************************************************************
859 * PointerUnmarshall [internal]
861 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
862 unsigned char *Buffer,
863 unsigned char **pPointer,
864 PFORMAT_STRING pFormat,
865 unsigned char fMustAlloc)
867 unsigned type = pFormat[0], attr = pFormat[1];
870 DWORD pointer_id = 0;
871 int pointer_needs_unmarshaling;
873 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pFormat, fMustAlloc);
874 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
876 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
877 else desc = pFormat + *(const SHORT*)pFormat;
880 case RPC_FC_RP: /* ref pointer (always non-null) */
881 pointer_needs_unmarshaling = 1;
883 case RPC_FC_UP: /* unique pointer */
884 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
885 TRACE("pointer_id is 0x%08x\n", pointer_id);
887 pointer_needs_unmarshaling = 1;
890 pointer_needs_unmarshaling = 0;
893 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
894 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
895 TRACE("pointer_id is 0x%08x\n", pointer_id);
896 if (!fMustAlloc && *pPointer)
898 FIXME("free object pointer %p\n", *pPointer);
902 pointer_needs_unmarshaling = 1;
904 pointer_needs_unmarshaling = 0;
907 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
908 TRACE("pointer_id is 0x%08x\n", pointer_id);
909 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
910 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
913 FIXME("unhandled ptr type=%02x\n", type);
914 RpcRaiseException(RPC_X_BAD_STUB_DATA);
918 if (pointer_needs_unmarshaling) {
919 if (attr & RPC_FC_P_DEREF) {
920 if (!*pPointer || fMustAlloc)
921 *pPointer = NdrAllocate(pStubMsg, sizeof(void *));
922 pPointer = *(unsigned char***)pPointer;
923 TRACE("deref => %p\n", pPointer);
925 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
926 if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
927 else FIXME("no unmarshaller for data type=%02x\n", *desc);
929 if (type == RPC_FC_FP)
930 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
934 TRACE("pointer=%p\n", *pPointer);
937 /***********************************************************************
938 * PointerBufferSize [internal]
940 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
941 unsigned char *Pointer,
942 PFORMAT_STRING pFormat)
944 unsigned type = pFormat[0], attr = pFormat[1];
947 int pointer_needs_sizing;
950 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
951 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
953 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
954 else desc = pFormat + *(const SHORT*)pFormat;
957 case RPC_FC_RP: /* ref pointer (always non-null) */
961 /* NULL pointer has no further representation */
966 pointer_needs_sizing = !NdrFullPointerQueryPointer(
967 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
968 if (!pointer_needs_sizing)
972 FIXME("unhandled ptr type=%02x\n", type);
973 RpcRaiseException(RPC_X_BAD_STUB_DATA);
977 if (attr & RPC_FC_P_DEREF) {
978 Pointer = *(unsigned char**)Pointer;
979 TRACE("deref => %p\n", Pointer);
982 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
983 if (m) m(pStubMsg, Pointer, desc);
984 else FIXME("no buffersizer for data type=%02x\n", *desc);
987 /***********************************************************************
988 * PointerMemorySize [internal]
990 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
991 unsigned char *Buffer,
992 PFORMAT_STRING pFormat)
994 unsigned type = pFormat[0], attr = pFormat[1];
998 FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat);
999 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1001 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1002 else desc = pFormat + *(const SHORT*)pFormat;
1005 case RPC_FC_RP: /* ref pointer (always non-null) */
1008 FIXME("unhandled ptr type=%02x\n", type);
1009 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1012 if (attr & RPC_FC_P_DEREF) {
1016 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1017 if (m) m(pStubMsg, desc);
1018 else FIXME("no memorysizer for data type=%02x\n", *desc);
1023 /***********************************************************************
1024 * PointerFree [internal]
1026 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1027 unsigned char *Pointer,
1028 PFORMAT_STRING pFormat)
1030 unsigned type = pFormat[0], attr = pFormat[1];
1031 PFORMAT_STRING desc;
1034 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1035 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1036 if (attr & RPC_FC_P_DONTFREE) return;
1038 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1039 else desc = pFormat + *(const SHORT*)pFormat;
1041 if (!Pointer) return;
1043 if (type == RPC_FC_FP) {
1044 int pointer_needs_freeing = NdrFullPointerFree(
1045 pStubMsg->FullPtrXlatTables, Pointer);
1046 if (!pointer_needs_freeing)
1050 if (attr & RPC_FC_P_DEREF) {
1051 Pointer = *(unsigned char**)Pointer;
1052 TRACE("deref => %p\n", Pointer);
1055 m = NdrFreer[*desc & NDR_TABLE_MASK];
1056 if (m) m(pStubMsg, Pointer, desc);
1058 /* hmm... is this sensible?
1059 * perhaps we should check if the memory comes from NdrAllocate,
1060 * and deallocate only if so - checking if the pointer is between
1061 * BufferStart and BufferEnd is probably no good since the buffer
1062 * may be reallocated when the server wants to marshal the reply */
1064 case RPC_FC_BOGUS_STRUCT:
1065 case RPC_FC_BOGUS_ARRAY:
1066 case RPC_FC_USER_MARSHAL:
1068 case RPC_FC_CVARRAY:
1071 FIXME("unhandled data type=%02x\n", *desc);
1073 case RPC_FC_C_CSTRING:
1074 case RPC_FC_C_WSTRING:
1075 if (pStubMsg->ReuseBuffer) goto notfree;
1081 if (attr & RPC_FC_P_ONSTACK) {
1082 TRACE("not freeing stack ptr %p\n", Pointer);
1085 TRACE("freeing %p\n", Pointer);
1086 NdrFree(pStubMsg, Pointer);
1089 TRACE("not freeing %p\n", Pointer);
1092 /***********************************************************************
1093 * EmbeddedPointerMarshall
1095 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1096 unsigned char *pMemory,
1097 PFORMAT_STRING pFormat)
1099 unsigned char *Mark = pStubMsg->BufferMark;
1100 unsigned long Offset = pStubMsg->Offset;
1101 unsigned ofs, rep, count, stride, xofs;
1104 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1106 if (*pFormat != RPC_FC_PP) return NULL;
1109 while (pFormat[0] != RPC_FC_END) {
1110 switch (pFormat[0]) {
1112 FIXME("unknown repeat type %d\n", pFormat[0]);
1113 case RPC_FC_NO_REPEAT:
1121 case RPC_FC_FIXED_REPEAT:
1122 rep = *(const WORD*)&pFormat[2];
1123 stride = *(const WORD*)&pFormat[4];
1124 ofs = *(const WORD*)&pFormat[6];
1125 count = *(const WORD*)&pFormat[8];
1129 case RPC_FC_VARIABLE_REPEAT:
1130 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1131 stride = *(const WORD*)&pFormat[2];
1132 ofs = *(const WORD*)&pFormat[4];
1133 count = *(const WORD*)&pFormat[6];
1134 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1138 for (i = 0; i < rep; i++) {
1139 PFORMAT_STRING info = pFormat;
1140 unsigned char *membase = pMemory + (i * stride);
1141 unsigned char *bufbase = Mark + (i * stride);
1143 /* ofs doesn't seem to matter in this context */
1144 for (u=0; u<count; u++,info+=8) {
1145 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1146 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1147 unsigned char *saved_memory = pStubMsg->Memory;
1149 pStubMsg->Memory = pMemory;
1150 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1151 pStubMsg->Memory = saved_memory;
1154 pFormat += 8 * count;
1157 STD_OVERFLOW_CHECK(pStubMsg);
1162 /***********************************************************************
1163 * EmbeddedPointerUnmarshall
1165 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1166 unsigned char **ppMemory,
1167 PFORMAT_STRING pFormat,
1168 unsigned char fMustAlloc)
1170 unsigned char *Mark = pStubMsg->BufferMark;
1171 unsigned long Offset = pStubMsg->Offset;
1172 unsigned ofs, rep, count, stride, xofs;
1175 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1177 if (*pFormat != RPC_FC_PP) return NULL;
1180 while (pFormat[0] != RPC_FC_END) {
1181 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1182 switch (pFormat[0]) {
1184 FIXME("unknown repeat type %d\n", pFormat[0]);
1185 case RPC_FC_NO_REPEAT:
1193 case RPC_FC_FIXED_REPEAT:
1194 rep = *(const WORD*)&pFormat[2];
1195 stride = *(const WORD*)&pFormat[4];
1196 ofs = *(const WORD*)&pFormat[6];
1197 count = *(const WORD*)&pFormat[8];
1201 case RPC_FC_VARIABLE_REPEAT:
1202 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1203 stride = *(const WORD*)&pFormat[2];
1204 ofs = *(const WORD*)&pFormat[4];
1205 count = *(const WORD*)&pFormat[6];
1206 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1210 /* ofs doesn't seem to matter in this context */
1211 for (i = 0; i < rep; i++) {
1212 PFORMAT_STRING info = pFormat;
1213 unsigned char *membase = *ppMemory + (i * stride);
1214 unsigned char *bufbase = Mark + (i * stride);
1216 for (u=0; u<count; u++,info+=8) {
1217 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1218 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1219 PointerUnmarshall(pStubMsg, bufptr, (unsigned char**)memptr, info+4, TRUE);
1222 pFormat += 8 * count;
1228 /***********************************************************************
1229 * EmbeddedPointerBufferSize
1231 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1232 unsigned char *pMemory,
1233 PFORMAT_STRING pFormat)
1235 unsigned long Offset = pStubMsg->Offset;
1236 unsigned ofs, rep, count, stride, xofs;
1239 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1241 if (pStubMsg->IgnoreEmbeddedPointers) return;
1243 if (*pFormat != RPC_FC_PP) return;
1246 while (pFormat[0] != RPC_FC_END) {
1247 switch (pFormat[0]) {
1249 FIXME("unknown repeat type %d\n", pFormat[0]);
1250 case RPC_FC_NO_REPEAT:
1258 case RPC_FC_FIXED_REPEAT:
1259 rep = *(const WORD*)&pFormat[2];
1260 stride = *(const WORD*)&pFormat[4];
1261 ofs = *(const WORD*)&pFormat[6];
1262 count = *(const WORD*)&pFormat[8];
1266 case RPC_FC_VARIABLE_REPEAT:
1267 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1268 stride = *(const WORD*)&pFormat[2];
1269 ofs = *(const WORD*)&pFormat[4];
1270 count = *(const WORD*)&pFormat[6];
1271 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1275 /* ofs doesn't seem to matter in this context */
1276 for (i = 0; i < rep; i++) {
1277 PFORMAT_STRING info = pFormat;
1278 unsigned char *membase = pMemory + (i * stride);
1280 for (u=0; u<count; u++,info+=8) {
1281 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1282 unsigned char *saved_memory = pStubMsg->Memory;
1284 pStubMsg->Memory = pMemory;
1285 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1286 pStubMsg->Memory = saved_memory;
1289 pFormat += 8 * count;
1293 /***********************************************************************
1294 * EmbeddedPointerMemorySize [internal]
1296 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1297 PFORMAT_STRING pFormat)
1299 unsigned long Offset = pStubMsg->Offset;
1300 unsigned char *Mark = pStubMsg->BufferMark;
1301 unsigned ofs, rep, count, stride, xofs;
1304 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1306 if (*pFormat != RPC_FC_PP) return 0;
1309 while (pFormat[0] != RPC_FC_END) {
1310 switch (pFormat[0]) {
1312 FIXME("unknown repeat type %d\n", pFormat[0]);
1313 case RPC_FC_NO_REPEAT:
1321 case RPC_FC_FIXED_REPEAT:
1322 rep = *(const WORD*)&pFormat[2];
1323 stride = *(const WORD*)&pFormat[4];
1324 ofs = *(const WORD*)&pFormat[6];
1325 count = *(const WORD*)&pFormat[8];
1329 case RPC_FC_VARIABLE_REPEAT:
1330 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1331 stride = *(const WORD*)&pFormat[2];
1332 ofs = *(const WORD*)&pFormat[4];
1333 count = *(const WORD*)&pFormat[6];
1334 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1338 /* ofs doesn't seem to matter in this context */
1339 for (i = 0; i < rep; i++) {
1340 PFORMAT_STRING info = pFormat;
1341 unsigned char *bufbase = Mark + (i * stride);
1343 for (u=0; u<count; u++,info+=8) {
1344 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1345 PointerMemorySize(pStubMsg, bufptr, info+4);
1348 pFormat += 8 * count;
1354 /***********************************************************************
1355 * EmbeddedPointerFree [internal]
1357 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1358 unsigned char *pMemory,
1359 PFORMAT_STRING pFormat)
1361 unsigned long Offset = pStubMsg->Offset;
1362 unsigned ofs, rep, count, stride, xofs;
1365 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1366 if (*pFormat != RPC_FC_PP) return;
1369 while (pFormat[0] != RPC_FC_END) {
1370 switch (pFormat[0]) {
1372 FIXME("unknown repeat type %d\n", pFormat[0]);
1373 case RPC_FC_NO_REPEAT:
1381 case RPC_FC_FIXED_REPEAT:
1382 rep = *(const WORD*)&pFormat[2];
1383 stride = *(const WORD*)&pFormat[4];
1384 ofs = *(const WORD*)&pFormat[6];
1385 count = *(const WORD*)&pFormat[8];
1389 case RPC_FC_VARIABLE_REPEAT:
1390 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1391 stride = *(const WORD*)&pFormat[2];
1392 ofs = *(const WORD*)&pFormat[4];
1393 count = *(const WORD*)&pFormat[6];
1394 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1398 /* ofs doesn't seem to matter in this context */
1399 for (i = 0; i < rep; i++) {
1400 PFORMAT_STRING info = pFormat;
1401 unsigned char *membase = pMemory + (i * stride);
1403 for (u=0; u<count; u++,info+=8) {
1404 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1405 unsigned char *saved_memory = pStubMsg->Memory;
1407 pStubMsg->Memory = pMemory;
1408 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1409 pStubMsg->Memory = saved_memory;
1412 pFormat += 8 * count;
1416 /***********************************************************************
1417 * NdrPointerMarshall [RPCRT4.@]
1419 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1420 unsigned char *pMemory,
1421 PFORMAT_STRING pFormat)
1423 unsigned char *Buffer;
1425 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1427 /* incremement the buffer here instead of in PointerMarshall,
1428 * as that is used by embedded pointers which already handle the incrementing
1429 * the buffer, and shouldn't write any additional pointer data to the wire */
1430 if (*pFormat != RPC_FC_RP)
1432 ALIGN_POINTER(pStubMsg->Buffer, 4);
1433 Buffer = pStubMsg->Buffer;
1434 pStubMsg->Buffer += 4;
1437 Buffer = pStubMsg->Buffer;
1439 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1441 STD_OVERFLOW_CHECK(pStubMsg);
1446 /***********************************************************************
1447 * NdrPointerUnmarshall [RPCRT4.@]
1449 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1450 unsigned char **ppMemory,
1451 PFORMAT_STRING pFormat,
1452 unsigned char fMustAlloc)
1454 unsigned char *Buffer;
1456 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1458 /* incremement the buffer here instead of in PointerUnmarshall,
1459 * as that is used by embedded pointers which already handle the incrementing
1460 * the buffer, and shouldn't read any additional pointer data from the
1462 if (*pFormat != RPC_FC_RP)
1464 ALIGN_POINTER(pStubMsg->Buffer, 4);
1465 Buffer = pStubMsg->Buffer;
1466 pStubMsg->Buffer += 4;
1469 Buffer = pStubMsg->Buffer;
1471 PointerUnmarshall(pStubMsg, Buffer, ppMemory, pFormat, fMustAlloc);
1476 /***********************************************************************
1477 * NdrPointerBufferSize [RPCRT4.@]
1479 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1480 unsigned char *pMemory,
1481 PFORMAT_STRING pFormat)
1483 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1485 /* incremement the buffer length here instead of in PointerBufferSize,
1486 * as that is used by embedded pointers which already handle the buffer
1487 * length, and shouldn't write anything more to the wire */
1488 if (*pFormat != RPC_FC_RP)
1490 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1491 pStubMsg->BufferLength += 4;
1494 PointerBufferSize(pStubMsg, pMemory, pFormat);
1497 /***********************************************************************
1498 * NdrPointerMemorySize [RPCRT4.@]
1500 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1501 PFORMAT_STRING pFormat)
1503 /* unsigned size = *(LPWORD)(pFormat+2); */
1504 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1505 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1509 /***********************************************************************
1510 * NdrPointerFree [RPCRT4.@]
1512 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1513 unsigned char *pMemory,
1514 PFORMAT_STRING pFormat)
1516 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1517 PointerFree(pStubMsg, pMemory, pFormat);
1520 /***********************************************************************
1521 * NdrSimpleTypeMarshall [RPCRT4.@]
1523 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1524 unsigned char FormatChar )
1526 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1529 /***********************************************************************
1530 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1532 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1533 unsigned char FormatChar )
1535 NdrBaseTypeUnmarshall(pStubMsg, &pMemory, &FormatChar, 0);
1538 /***********************************************************************
1539 * NdrSimpleStructMarshall [RPCRT4.@]
1541 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1542 unsigned char *pMemory,
1543 PFORMAT_STRING pFormat)
1545 unsigned size = *(const WORD*)(pFormat+2);
1546 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1548 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1550 memcpy(pStubMsg->Buffer, pMemory, size);
1551 pStubMsg->BufferMark = pStubMsg->Buffer;
1552 pStubMsg->Buffer += size;
1554 if (pFormat[0] != RPC_FC_STRUCT)
1555 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1557 STD_OVERFLOW_CHECK(pStubMsg);
1562 /***********************************************************************
1563 * NdrSimpleStructUnmarshall [RPCRT4.@]
1565 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1566 unsigned char **ppMemory,
1567 PFORMAT_STRING pFormat,
1568 unsigned char fMustAlloc)
1570 unsigned size = *(const WORD*)(pFormat+2);
1571 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1573 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1576 *ppMemory = NdrAllocate(pStubMsg, size);
1577 memcpy(*ppMemory, pStubMsg->Buffer, size);
1579 if (!pStubMsg->IsClient && !*ppMemory)
1580 /* for servers, we just point straight into the RPC buffer */
1581 *ppMemory = pStubMsg->Buffer;
1583 /* for clients, memory should be provided by caller */
1584 memcpy(*ppMemory, pStubMsg->Buffer, size);
1587 pStubMsg->BufferMark = pStubMsg->Buffer;
1588 pStubMsg->Buffer += size;
1590 if (pFormat[0] != RPC_FC_STRUCT)
1591 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat+4, fMustAlloc);
1596 /***********************************************************************
1597 * NdrSimpleStructBufferSize [RPCRT4.@]
1599 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1600 unsigned char *pMemory,
1601 PFORMAT_STRING pFormat)
1603 unsigned size = *(const WORD*)(pFormat+2);
1604 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1606 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1608 pStubMsg->BufferLength += size;
1609 if (pFormat[0] != RPC_FC_STRUCT)
1610 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1613 /***********************************************************************
1614 * NdrSimpleStructMemorySize [RPCRT4.@]
1616 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1617 PFORMAT_STRING pFormat)
1619 unsigned short size = *(const WORD *)(pFormat+2);
1621 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1623 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1624 pStubMsg->MemorySize += size;
1625 pStubMsg->Buffer += size;
1627 if (pFormat[0] != RPC_FC_STRUCT)
1628 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1632 /***********************************************************************
1633 * NdrSimpleStructFree [RPCRT4.@]
1635 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1636 unsigned char *pMemory,
1637 PFORMAT_STRING pFormat)
1639 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1640 if (pFormat[0] != RPC_FC_STRUCT)
1641 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1645 static unsigned long EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg,
1646 PFORMAT_STRING pFormat)
1650 case RPC_FC_PSTRUCT:
1651 case RPC_FC_CSTRUCT:
1652 case RPC_FC_BOGUS_STRUCT:
1653 case RPC_FC_SMFARRAY:
1654 case RPC_FC_SMVARRAY:
1655 return *(const WORD*)&pFormat[2];
1656 case RPC_FC_USER_MARSHAL:
1657 return *(const WORD*)&pFormat[4];
1658 case RPC_FC_NON_ENCAPSULATED_UNION:
1660 if (pStubMsg->fHasNewCorrDesc)
1665 pFormat += *(const SHORT*)pFormat;
1666 return *(const SHORT*)pFormat;
1668 return sizeof(void *);
1670 FIXME("unhandled embedded type %02x\n", *pFormat);
1676 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1677 PFORMAT_STRING pFormat)
1679 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1683 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1687 return m(pStubMsg, pFormat);
1691 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1692 unsigned char *pMemory,
1693 PFORMAT_STRING pFormat,
1694 PFORMAT_STRING pPointer)
1696 PFORMAT_STRING desc;
1700 while (*pFormat != RPC_FC_END) {
1706 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
1707 memcpy(pStubMsg->Buffer, pMemory, 1);
1708 pStubMsg->Buffer += 1;
1714 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1715 memcpy(pStubMsg->Buffer, pMemory, 2);
1716 pStubMsg->Buffer += 2;
1722 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
1723 memcpy(pStubMsg->Buffer, pMemory, 4);
1724 pStubMsg->Buffer += 4;
1728 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1729 memcpy(pStubMsg->Buffer, pMemory, 8);
1730 pStubMsg->Buffer += 8;
1733 case RPC_FC_POINTER:
1734 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1735 NdrPointerMarshall(pStubMsg, *(unsigned char**)pMemory, pPointer);
1739 case RPC_FC_ALIGNM4:
1740 ALIGN_POINTER(pMemory, 4);
1742 case RPC_FC_ALIGNM8:
1743 ALIGN_POINTER(pMemory, 8);
1745 case RPC_FC_STRUCTPAD1:
1746 case RPC_FC_STRUCTPAD2:
1747 case RPC_FC_STRUCTPAD3:
1748 case RPC_FC_STRUCTPAD4:
1749 case RPC_FC_STRUCTPAD5:
1750 case RPC_FC_STRUCTPAD6:
1751 case RPC_FC_STRUCTPAD7:
1752 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1754 case RPC_FC_EMBEDDED_COMPLEX:
1755 pMemory += pFormat[1];
1757 desc = pFormat + *(const SHORT*)pFormat;
1758 size = EmbeddedComplexSize(pStubMsg, desc);
1759 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1760 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1761 if (m) m(pStubMsg, pMemory, desc);
1762 else FIXME("no marshaller for embedded type %02x\n", *desc);
1769 FIXME("unhandled format 0x%02x\n", *pFormat);
1777 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1778 unsigned char *pMemory,
1779 PFORMAT_STRING pFormat,
1780 PFORMAT_STRING pPointer)
1782 PFORMAT_STRING desc;
1786 while (*pFormat != RPC_FC_END) {
1792 memcpy(pMemory, pStubMsg->Buffer, 1);
1793 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
1794 pStubMsg->Buffer += 1;
1800 memcpy(pMemory, pStubMsg->Buffer, 2);
1801 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1802 pStubMsg->Buffer += 2;
1808 memcpy(pMemory, pStubMsg->Buffer, 4);
1809 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
1810 pStubMsg->Buffer += 4;
1814 memcpy(pMemory, pStubMsg->Buffer, 8);
1815 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1816 pStubMsg->Buffer += 8;
1819 case RPC_FC_POINTER:
1820 TRACE("pointer => %p\n", pMemory);
1821 NdrPointerUnmarshall(pStubMsg, (unsigned char**)pMemory, pPointer, TRUE);
1825 case RPC_FC_ALIGNM4:
1826 ALIGN_POINTER(pMemory, 4);
1828 case RPC_FC_ALIGNM8:
1829 ALIGN_POINTER(pMemory, 8);
1831 case RPC_FC_STRUCTPAD1:
1832 case RPC_FC_STRUCTPAD2:
1833 case RPC_FC_STRUCTPAD3:
1834 case RPC_FC_STRUCTPAD4:
1835 case RPC_FC_STRUCTPAD5:
1836 case RPC_FC_STRUCTPAD6:
1837 case RPC_FC_STRUCTPAD7:
1838 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1840 case RPC_FC_EMBEDDED_COMPLEX:
1841 pMemory += pFormat[1];
1843 desc = pFormat + *(const SHORT*)pFormat;
1844 size = EmbeddedComplexSize(pStubMsg, desc);
1845 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
1846 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1847 memset(pMemory, 0, size); /* just in case */
1848 if (m) m(pStubMsg, &pMemory, desc, FALSE);
1849 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
1856 FIXME("unhandled format %d\n", *pFormat);
1864 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1865 unsigned char *pMemory,
1866 PFORMAT_STRING pFormat,
1867 PFORMAT_STRING pPointer)
1869 PFORMAT_STRING desc;
1873 while (*pFormat != RPC_FC_END) {
1879 pStubMsg->BufferLength += 1;
1885 pStubMsg->BufferLength += 2;
1891 pStubMsg->BufferLength += 4;
1895 pStubMsg->BufferLength += 8;
1898 case RPC_FC_POINTER:
1899 NdrPointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
1903 case RPC_FC_ALIGNM4:
1904 ALIGN_POINTER(pMemory, 4);
1906 case RPC_FC_ALIGNM8:
1907 ALIGN_POINTER(pMemory, 8);
1909 case RPC_FC_STRUCTPAD1:
1910 case RPC_FC_STRUCTPAD2:
1911 case RPC_FC_STRUCTPAD3:
1912 case RPC_FC_STRUCTPAD4:
1913 case RPC_FC_STRUCTPAD5:
1914 case RPC_FC_STRUCTPAD6:
1915 case RPC_FC_STRUCTPAD7:
1916 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1918 case RPC_FC_EMBEDDED_COMPLEX:
1919 pMemory += pFormat[1];
1921 desc = pFormat + *(const SHORT*)pFormat;
1922 size = EmbeddedComplexSize(pStubMsg, desc);
1923 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1924 if (m) m(pStubMsg, pMemory, desc);
1925 else FIXME("no buffersizer for embedded type %02x\n", *desc);
1932 FIXME("unhandled format 0x%02x\n", *pFormat);
1940 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
1941 unsigned char *pMemory,
1942 PFORMAT_STRING pFormat,
1943 PFORMAT_STRING pPointer)
1945 PFORMAT_STRING desc;
1949 while (*pFormat != RPC_FC_END) {
1970 case RPC_FC_POINTER:
1971 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
1975 case RPC_FC_ALIGNM4:
1976 ALIGN_POINTER(pMemory, 4);
1978 case RPC_FC_ALIGNM8:
1979 ALIGN_POINTER(pMemory, 8);
1981 case RPC_FC_STRUCTPAD1:
1982 case RPC_FC_STRUCTPAD2:
1983 case RPC_FC_STRUCTPAD3:
1984 case RPC_FC_STRUCTPAD4:
1985 case RPC_FC_STRUCTPAD5:
1986 case RPC_FC_STRUCTPAD6:
1987 case RPC_FC_STRUCTPAD7:
1988 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1990 case RPC_FC_EMBEDDED_COMPLEX:
1991 pMemory += pFormat[1];
1993 desc = pFormat + *(const SHORT*)pFormat;
1994 size = EmbeddedComplexSize(pStubMsg, desc);
1995 m = NdrFreer[*desc & NDR_TABLE_MASK];
1996 if (m) m(pStubMsg, pMemory, desc);
1997 else FIXME("no freer for embedded type %02x\n", *desc);
2004 FIXME("unhandled format 0x%02x\n", *pFormat);
2012 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2013 PFORMAT_STRING pFormat)
2015 PFORMAT_STRING desc;
2016 unsigned long size = 0;
2018 while (*pFormat != RPC_FC_END) {
2025 pStubMsg->Buffer += 1;
2031 pStubMsg->Buffer += 2;
2037 pStubMsg->Buffer += 4;
2041 pStubMsg->Buffer += 8;
2043 case RPC_FC_POINTER:
2045 pStubMsg->Buffer += 4;
2047 case RPC_FC_ALIGNM4:
2048 ALIGN_LENGTH(size, 4);
2049 ALIGN_POINTER(pStubMsg->Buffer, 4);
2051 case RPC_FC_ALIGNM8:
2052 ALIGN_LENGTH(size, 8);
2053 ALIGN_POINTER(pStubMsg->Buffer, 8);
2055 case RPC_FC_STRUCTPAD1:
2056 case RPC_FC_STRUCTPAD2:
2057 case RPC_FC_STRUCTPAD3:
2058 case RPC_FC_STRUCTPAD4:
2059 case RPC_FC_STRUCTPAD5:
2060 case RPC_FC_STRUCTPAD6:
2061 case RPC_FC_STRUCTPAD7:
2062 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2064 case RPC_FC_EMBEDDED_COMPLEX:
2067 desc = pFormat + *(const SHORT*)pFormat;
2068 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2074 FIXME("unhandled format 0x%02x\n", *pFormat);
2082 /***********************************************************************
2083 * NdrComplexStructMarshall [RPCRT4.@]
2085 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2086 unsigned char *pMemory,
2087 PFORMAT_STRING pFormat)
2089 PFORMAT_STRING conf_array = NULL;
2090 PFORMAT_STRING pointer_desc = NULL;
2091 unsigned char *OldMemory = pStubMsg->Memory;
2093 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2095 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2098 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2100 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2103 pStubMsg->Memory = pMemory;
2105 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2108 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2110 pStubMsg->Memory = OldMemory;
2112 STD_OVERFLOW_CHECK(pStubMsg);
2117 /***********************************************************************
2118 * NdrComplexStructUnmarshall [RPCRT4.@]
2120 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2121 unsigned char **ppMemory,
2122 PFORMAT_STRING pFormat,
2123 unsigned char fMustAlloc)
2125 unsigned size = *(const WORD*)(pFormat+2);
2126 PFORMAT_STRING conf_array = NULL;
2127 PFORMAT_STRING pointer_desc = NULL;
2128 unsigned char *pMemory;
2130 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2132 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2134 if (fMustAlloc || !*ppMemory)
2136 *ppMemory = NdrAllocate(pStubMsg, size);
2137 memset(*ppMemory, 0, size);
2141 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2143 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2146 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2149 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2154 /***********************************************************************
2155 * NdrComplexStructBufferSize [RPCRT4.@]
2157 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2158 unsigned char *pMemory,
2159 PFORMAT_STRING pFormat)
2161 PFORMAT_STRING conf_array = NULL;
2162 PFORMAT_STRING pointer_desc = NULL;
2163 unsigned char *OldMemory = pStubMsg->Memory;
2165 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2167 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2170 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2172 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2175 pStubMsg->Memory = pMemory;
2177 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2180 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2182 pStubMsg->Memory = OldMemory;
2185 /***********************************************************************
2186 * NdrComplexStructMemorySize [RPCRT4.@]
2188 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2189 PFORMAT_STRING pFormat)
2191 unsigned size = *(const WORD*)(pFormat+2);
2192 PFORMAT_STRING conf_array = NULL;
2193 PFORMAT_STRING pointer_desc = NULL;
2195 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2197 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2200 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2202 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2205 ComplexStructMemorySize(pStubMsg, pFormat);
2208 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2213 /***********************************************************************
2214 * NdrComplexStructFree [RPCRT4.@]
2216 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2217 unsigned char *pMemory,
2218 PFORMAT_STRING pFormat)
2220 PFORMAT_STRING conf_array = NULL;
2221 PFORMAT_STRING pointer_desc = NULL;
2222 unsigned char *OldMemory = pStubMsg->Memory;
2224 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2227 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2229 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2232 pStubMsg->Memory = pMemory;
2234 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2237 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2239 pStubMsg->Memory = OldMemory;
2242 /***********************************************************************
2243 * NdrConformantArrayMarshall [RPCRT4.@]
2245 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2246 unsigned char *pMemory,
2247 PFORMAT_STRING pFormat)
2249 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2250 unsigned char alignment = pFormat[1] + 1;
2252 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2253 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2255 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2257 WriteConformance(pStubMsg);
2259 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2261 size = safe_multiply(esize, pStubMsg->MaxCount);
2262 memcpy(pStubMsg->Buffer, pMemory, size);
2263 pStubMsg->BufferMark = pStubMsg->Buffer;
2264 pStubMsg->Buffer += size;
2266 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2268 STD_OVERFLOW_CHECK(pStubMsg);
2273 /***********************************************************************
2274 * NdrConformantArrayUnmarshall [RPCRT4.@]
2276 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2277 unsigned char **ppMemory,
2278 PFORMAT_STRING pFormat,
2279 unsigned char fMustAlloc)
2281 DWORD size, esize = *(const WORD*)(pFormat+2);
2282 unsigned char alignment = pFormat[1] + 1;
2284 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2285 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2287 pFormat = ReadConformance(pStubMsg, pFormat+4);
2289 size = safe_multiply(esize, pStubMsg->MaxCount);
2291 if (fMustAlloc || !*ppMemory)
2292 *ppMemory = NdrAllocate(pStubMsg, size);
2294 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2296 memcpy(*ppMemory, pStubMsg->Buffer, size);
2298 pStubMsg->BufferMark = pStubMsg->Buffer;
2299 pStubMsg->Buffer += size;
2301 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2306 /***********************************************************************
2307 * NdrConformantArrayBufferSize [RPCRT4.@]
2309 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2310 unsigned char *pMemory,
2311 PFORMAT_STRING pFormat)
2313 DWORD size, esize = *(const WORD*)(pFormat+2);
2314 unsigned char alignment = pFormat[1] + 1;
2316 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2317 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2319 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2321 SizeConformance(pStubMsg);
2323 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2325 size = safe_multiply(esize, pStubMsg->MaxCount);
2326 /* conformance value plus array */
2327 pStubMsg->BufferLength += size;
2329 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2332 /***********************************************************************
2333 * NdrConformantArrayMemorySize [RPCRT4.@]
2335 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2336 PFORMAT_STRING pFormat)
2338 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2339 unsigned char alignment = pFormat[1] + 1;
2341 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2342 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2344 pFormat = ReadConformance(pStubMsg, pFormat+4);
2345 size = safe_multiply(esize, pStubMsg->MaxCount);
2346 pStubMsg->MemorySize += size;
2348 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2349 pStubMsg->BufferMark = pStubMsg->Buffer;
2350 pStubMsg->Buffer += size;
2352 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2354 return pStubMsg->MemorySize;
2357 /***********************************************************************
2358 * NdrConformantArrayFree [RPCRT4.@]
2360 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2361 unsigned char *pMemory,
2362 PFORMAT_STRING pFormat)
2364 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2365 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2367 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2369 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2373 /***********************************************************************
2374 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2376 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2377 unsigned char* pMemory,
2378 PFORMAT_STRING pFormat )
2381 unsigned char alignment = pFormat[1] + 1;
2382 DWORD esize = *(const WORD*)(pFormat+2);
2384 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2386 if (pFormat[0] != RPC_FC_CVARRAY)
2388 ERR("invalid format type %x\n", pFormat[0]);
2389 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2393 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2394 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2396 WriteConformance(pStubMsg);
2397 WriteVariance(pStubMsg);
2399 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2401 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2403 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
2404 pStubMsg->BufferMark = pStubMsg->Buffer;
2405 pStubMsg->Buffer += bufsize;
2407 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2409 STD_OVERFLOW_CHECK(pStubMsg);
2415 /***********************************************************************
2416 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2418 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2419 unsigned char** ppMemory,
2420 PFORMAT_STRING pFormat,
2421 unsigned char fMustAlloc )
2423 ULONG bufsize, memsize;
2424 unsigned char alignment = pFormat[1] + 1;
2425 DWORD esize = *(const WORD*)(pFormat+2);
2427 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2429 if (pFormat[0] != RPC_FC_CVARRAY)
2431 ERR("invalid format type %x\n", pFormat[0]);
2432 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2436 pFormat = ReadConformance(pStubMsg, pFormat+4);
2437 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2439 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2441 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2442 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2444 if (!*ppMemory || fMustAlloc)
2445 *ppMemory = NdrAllocate(pStubMsg, memsize);
2446 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
2447 pStubMsg->Buffer += bufsize;
2449 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2455 /***********************************************************************
2456 * NdrConformantVaryingArrayFree [RPCRT4.@]
2458 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2459 unsigned char* pMemory,
2460 PFORMAT_STRING pFormat )
2462 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2464 if (pFormat[0] != RPC_FC_CVARRAY)
2466 ERR("invalid format type %x\n", pFormat[0]);
2467 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2471 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2472 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2474 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2478 /***********************************************************************
2479 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2481 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2482 unsigned char* pMemory, PFORMAT_STRING pFormat )
2484 unsigned char alignment = pFormat[1] + 1;
2485 DWORD esize = *(const WORD*)(pFormat+2);
2487 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2489 if (pFormat[0] != RPC_FC_CVARRAY)
2491 ERR("invalid format type %x\n", pFormat[0]);
2492 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2497 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2498 /* compute length */
2499 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2501 SizeConformance(pStubMsg);
2502 SizeVariance(pStubMsg);
2504 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2506 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
2508 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2512 /***********************************************************************
2513 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2515 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2516 PFORMAT_STRING pFormat )
2523 /***********************************************************************
2524 * NdrComplexArrayMarshall [RPCRT4.@]
2526 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2527 unsigned char *pMemory,
2528 PFORMAT_STRING pFormat)
2530 ULONG i, count, def;
2531 BOOL variance_present;
2532 unsigned char alignment;
2534 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2536 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2538 ERR("invalid format type %x\n", pFormat[0]);
2539 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2543 alignment = pFormat[1] + 1;
2545 def = *(const WORD*)&pFormat[2];
2548 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2549 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2551 variance_present = IsConformanceOrVariancePresent(pFormat);
2552 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2553 TRACE("variance = %d\n", pStubMsg->ActualCount);
2555 WriteConformance(pStubMsg);
2556 if (variance_present)
2557 WriteVariance(pStubMsg);
2559 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2561 count = pStubMsg->ActualCount;
2562 for (i = 0; i < count; i++)
2563 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2565 STD_OVERFLOW_CHECK(pStubMsg);
2570 /***********************************************************************
2571 * NdrComplexArrayUnmarshall [RPCRT4.@]
2573 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2574 unsigned char **ppMemory,
2575 PFORMAT_STRING pFormat,
2576 unsigned char fMustAlloc)
2578 ULONG i, count, esize, memsize;
2579 unsigned char alignment;
2580 unsigned char *pMemory;
2581 unsigned char *Buffer;
2583 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2585 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2587 ERR("invalid format type %x\n", pFormat[0]);
2588 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2592 alignment = pFormat[1] + 1;
2596 pFormat = ReadConformance(pStubMsg, pFormat);
2597 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2599 Buffer = pStubMsg->Buffer;
2600 pStubMsg->MemorySize = 0;
2601 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2602 pStubMsg->Buffer = Buffer;
2604 /* do multiply here instead of inside if block to verify MaxCount */
2605 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2606 if (fMustAlloc || !*ppMemory)
2608 *ppMemory = NdrAllocate(pStubMsg, memsize);
2609 memset(*ppMemory, 0, memsize);
2612 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2614 pMemory = *ppMemory;
2615 count = pStubMsg->ActualCount;
2616 for (i = 0; i < count; i++)
2617 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
2622 /***********************************************************************
2623 * NdrComplexArrayBufferSize [RPCRT4.@]
2625 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2626 unsigned char *pMemory,
2627 PFORMAT_STRING pFormat)
2629 ULONG i, count, def;
2630 unsigned char alignment;
2631 BOOL variance_present;
2633 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2635 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2637 ERR("invalid format type %x\n", pFormat[0]);
2638 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2642 alignment = pFormat[1] + 1;
2644 def = *(const WORD*)&pFormat[2];
2647 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2648 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2649 SizeConformance(pStubMsg);
2651 variance_present = IsConformanceOrVariancePresent(pFormat);
2652 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2653 TRACE("variance = %d\n", pStubMsg->ActualCount);
2655 if (variance_present)
2656 SizeVariance(pStubMsg);
2658 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2660 count = pStubMsg->ActualCount;
2661 for (i = 0; i < count; i++)
2662 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
2665 /***********************************************************************
2666 * NdrComplexArrayMemorySize [RPCRT4.@]
2668 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2669 PFORMAT_STRING pFormat)
2671 ULONG i, count, esize, SavedMemorySize, MemorySize;
2672 unsigned char alignment;
2673 unsigned char *Buffer;
2675 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2677 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2679 ERR("invalid format type %x\n", pFormat[0]);
2680 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2684 alignment = pFormat[1] + 1;
2688 pFormat = ReadConformance(pStubMsg, pFormat);
2689 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2691 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2693 SavedMemorySize = pStubMsg->MemorySize;
2695 Buffer = pStubMsg->Buffer;
2696 pStubMsg->MemorySize = 0;
2697 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2698 pStubMsg->Buffer = Buffer;
2700 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
2702 count = pStubMsg->ActualCount;
2703 for (i = 0; i < count; i++)
2704 ComplexStructMemorySize(pStubMsg, pFormat);
2706 pStubMsg->MemorySize = SavedMemorySize;
2708 pStubMsg->MemorySize += MemorySize;
2712 /***********************************************************************
2713 * NdrComplexArrayFree [RPCRT4.@]
2715 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2716 unsigned char *pMemory,
2717 PFORMAT_STRING pFormat)
2719 ULONG i, count, def;
2721 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2723 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2725 ERR("invalid format type %x\n", pFormat[0]);
2726 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2730 def = *(const WORD*)&pFormat[2];
2733 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2734 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2736 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2737 TRACE("variance = %d\n", pStubMsg->ActualCount);
2739 count = pStubMsg->ActualCount;
2740 for (i = 0; i < count; i++)
2741 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2744 static ULONG UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
2746 return MAKELONG(pStubMsg->dwDestContext,
2747 pStubMsg->RpcMsg->DataRepresentation);
2750 #define USER_MARSHAL_PTR_PREFIX \
2751 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
2752 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
2754 /***********************************************************************
2755 * NdrUserMarshalMarshall [RPCRT4.@]
2757 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2758 unsigned char *pMemory,
2759 PFORMAT_STRING pFormat)
2761 unsigned flags = pFormat[1];
2762 unsigned index = *(const WORD*)&pFormat[2];
2763 ULONG uflag = UserMarshalFlags(pStubMsg);
2764 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2765 TRACE("index=%d\n", index);
2767 if (flags & USER_MARSHAL_POINTER)
2769 ALIGN_POINTER(pStubMsg->Buffer, 4);
2770 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
2771 pStubMsg->Buffer += 4;
2772 ALIGN_POINTER(pStubMsg->Buffer, 8);
2775 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2778 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
2779 &uflag, pStubMsg->Buffer, pMemory);
2781 STD_OVERFLOW_CHECK(pStubMsg);
2786 /***********************************************************************
2787 * NdrUserMarshalUnmarshall [RPCRT4.@]
2789 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2790 unsigned char **ppMemory,
2791 PFORMAT_STRING pFormat,
2792 unsigned char fMustAlloc)
2794 unsigned flags = pFormat[1];
2795 unsigned index = *(const WORD*)&pFormat[2];
2796 DWORD memsize = *(const WORD*)&pFormat[4];
2797 ULONG uflag = UserMarshalFlags(pStubMsg);
2798 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2799 TRACE("index=%d\n", index);
2801 if (flags & USER_MARSHAL_POINTER)
2803 ALIGN_POINTER(pStubMsg->Buffer, 4);
2804 /* skip pointer prefix */
2805 pStubMsg->Buffer += 4;
2806 ALIGN_POINTER(pStubMsg->Buffer, 8);
2809 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2811 if (fMustAlloc || !*ppMemory)
2812 *ppMemory = NdrAllocate(pStubMsg, memsize);
2815 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
2816 &uflag, pStubMsg->Buffer, *ppMemory);
2821 /***********************************************************************
2822 * NdrUserMarshalBufferSize [RPCRT4.@]
2824 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2825 unsigned char *pMemory,
2826 PFORMAT_STRING pFormat)
2828 unsigned flags = pFormat[1];
2829 unsigned index = *(const WORD*)&pFormat[2];
2830 DWORD bufsize = *(const WORD*)&pFormat[6];
2831 ULONG uflag = UserMarshalFlags(pStubMsg);
2832 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2833 TRACE("index=%d\n", index);
2835 if (flags & USER_MARSHAL_POINTER)
2837 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2838 /* skip pointer prefix */
2839 pStubMsg->BufferLength += 4;
2840 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
2843 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
2846 TRACE("size=%d\n", bufsize);
2847 pStubMsg->BufferLength += bufsize;
2851 pStubMsg->BufferLength =
2852 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
2853 &uflag, pStubMsg->BufferLength, pMemory);
2856 /***********************************************************************
2857 * NdrUserMarshalMemorySize [RPCRT4.@]
2859 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2860 PFORMAT_STRING pFormat)
2862 unsigned flags = pFormat[1];
2863 unsigned index = *(const WORD*)&pFormat[2];
2864 DWORD memsize = *(const WORD*)&pFormat[4];
2865 DWORD bufsize = *(const WORD*)&pFormat[6];
2867 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2868 TRACE("index=%d\n", index);
2870 pStubMsg->MemorySize += memsize;
2872 if (flags & USER_MARSHAL_POINTER)
2874 ALIGN_POINTER(pStubMsg->Buffer, 4);
2875 /* skip pointer prefix */
2876 pStubMsg->Buffer += 4;
2877 ALIGN_POINTER(pStubMsg->Buffer, 8);
2880 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2882 pStubMsg->Buffer += bufsize;
2884 return pStubMsg->MemorySize;
2887 /***********************************************************************
2888 * NdrUserMarshalFree [RPCRT4.@]
2890 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
2891 unsigned char *pMemory,
2892 PFORMAT_STRING pFormat)
2894 /* unsigned flags = pFormat[1]; */
2895 unsigned index = *(const WORD*)&pFormat[2];
2896 ULONG uflag = UserMarshalFlags(pStubMsg);
2897 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2898 TRACE("index=%d\n", index);
2900 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
2904 /***********************************************************************
2905 * NdrClearOutParameters [RPCRT4.@]
2907 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
2908 PFORMAT_STRING pFormat,
2911 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
2914 /***********************************************************************
2915 * NdrConvert [RPCRT4.@]
2917 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
2919 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
2920 /* FIXME: since this stub doesn't do any converting, the proper behavior
2921 is to raise an exception */
2924 /***********************************************************************
2925 * NdrConvert2 [RPCRT4.@]
2927 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
2929 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
2930 pStubMsg, pFormat, NumberParams);
2931 /* FIXME: since this stub doesn't do any converting, the proper behavior
2932 is to raise an exception */
2935 #include "pshpack1.h"
2936 typedef struct _NDR_CSTRUCT_FORMAT
2939 unsigned char alignment;
2940 unsigned short memory_size;
2941 short offset_to_array_description;
2942 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
2943 #include "poppack.h"
2945 /***********************************************************************
2946 * NdrConformantStructMarshall [RPCRT4.@]
2948 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2949 unsigned char *pMemory,
2950 PFORMAT_STRING pFormat)
2952 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
2953 PFORMAT_STRING pCArrayFormat;
2954 ULONG esize, bufsize;
2956 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2958 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2959 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2961 ERR("invalid format type %x\n", pCStructFormat->type);
2962 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2966 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
2967 pCStructFormat->offset_to_array_description;
2968 if (*pCArrayFormat != RPC_FC_CARRAY)
2970 ERR("invalid array format type %x\n", pCStructFormat->type);
2971 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2974 esize = *(const WORD*)(pCArrayFormat+2);
2976 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
2977 pCArrayFormat + 4, 0);
2979 WriteConformance(pStubMsg);
2981 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
2983 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2985 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
2986 /* copy constant sized part of struct */
2987 pStubMsg->BufferMark = pStubMsg->Buffer;
2988 memcpy(pStubMsg->Buffer, pMemory, pCStructFormat->memory_size + bufsize);
2989 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
2991 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2992 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2994 STD_OVERFLOW_CHECK(pStubMsg);
2999 /***********************************************************************
3000 * NdrConformantStructUnmarshall [RPCRT4.@]
3002 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3003 unsigned char **ppMemory,
3004 PFORMAT_STRING pFormat,
3005 unsigned char fMustAlloc)
3007 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3008 PFORMAT_STRING pCArrayFormat;
3009 ULONG esize, bufsize;
3011 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3013 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3014 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3016 ERR("invalid format type %x\n", pCStructFormat->type);
3017 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3020 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3021 pCStructFormat->offset_to_array_description;
3022 if (*pCArrayFormat != RPC_FC_CARRAY)
3024 ERR("invalid array format type %x\n", pCStructFormat->type);
3025 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3028 esize = *(const WORD*)(pCArrayFormat+2);
3030 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3032 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3034 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3036 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3037 /* work out how much memory to allocate if we need to do so */
3038 if (!*ppMemory || fMustAlloc)
3040 SIZE_T size = pCStructFormat->memory_size + bufsize;
3041 *ppMemory = NdrAllocate(pStubMsg, size);
3044 /* now copy the data */
3045 pStubMsg->BufferMark = pStubMsg->Buffer;
3046 memcpy(*ppMemory, pStubMsg->Buffer, pCStructFormat->memory_size + bufsize);
3047 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
3049 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3050 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3055 /***********************************************************************
3056 * NdrConformantStructBufferSize [RPCRT4.@]
3058 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3059 unsigned char *pMemory,
3060 PFORMAT_STRING pFormat)
3062 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3063 PFORMAT_STRING pCArrayFormat;
3066 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3068 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3069 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3071 ERR("invalid format type %x\n", pCStructFormat->type);
3072 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3075 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3076 pCStructFormat->offset_to_array_description;
3077 if (*pCArrayFormat != RPC_FC_CARRAY)
3079 ERR("invalid array format type %x\n", pCStructFormat->type);
3080 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3083 esize = *(const WORD*)(pCArrayFormat+2);
3085 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
3086 SizeConformance(pStubMsg);
3088 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
3090 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3092 pStubMsg->BufferLength += pCStructFormat->memory_size +
3093 safe_multiply(pStubMsg->MaxCount, esize);
3095 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3096 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3099 /***********************************************************************
3100 * NdrConformantStructMemorySize [RPCRT4.@]
3102 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3103 PFORMAT_STRING pFormat)
3109 /***********************************************************************
3110 * NdrConformantStructFree [RPCRT4.@]
3112 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3113 unsigned char *pMemory,
3114 PFORMAT_STRING pFormat)
3119 /***********************************************************************
3120 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3122 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3123 unsigned char *pMemory,
3124 PFORMAT_STRING pFormat)
3126 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3127 PFORMAT_STRING pCVArrayFormat;
3128 ULONG esize, bufsize;
3130 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3132 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3133 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3135 ERR("invalid format type %x\n", pCVStructFormat->type);
3136 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3140 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3141 pCVStructFormat->offset_to_array_description;
3142 switch (*pCVArrayFormat)
3144 case RPC_FC_CVARRAY:
3145 esize = *(const WORD*)(pCVArrayFormat+2);
3147 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3148 pCVArrayFormat + 4, 0);
3149 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3152 case RPC_FC_C_CSTRING:
3153 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3154 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3155 esize = sizeof(char);
3156 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3157 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3158 pCVArrayFormat + 2, 0);
3160 pStubMsg->MaxCount = pStubMsg->ActualCount;
3162 case RPC_FC_C_WSTRING:
3163 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3164 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3165 esize = sizeof(WCHAR);
3166 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3167 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3168 pCVArrayFormat + 2, 0);
3170 pStubMsg->MaxCount = pStubMsg->ActualCount;
3173 ERR("invalid array format type %x\n", *pCVArrayFormat);
3174 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3178 WriteConformance(pStubMsg);
3180 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3182 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3184 /* write constant sized part */
3185 pStubMsg->BufferMark = pStubMsg->Buffer;
3186 memcpy(pStubMsg->Buffer, pMemory, pCVStructFormat->memory_size);
3187 pStubMsg->Buffer += pCVStructFormat->memory_size;
3189 WriteVariance(pStubMsg);
3191 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3193 /* write array part */
3194 memcpy(pStubMsg->Buffer, pMemory + pCVStructFormat->memory_size, bufsize);
3195 pStubMsg->Buffer += bufsize;
3197 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3199 STD_OVERFLOW_CHECK(pStubMsg);
3204 /***********************************************************************
3205 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3207 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3208 unsigned char **ppMemory,
3209 PFORMAT_STRING pFormat,
3210 unsigned char fMustAlloc)
3212 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3213 PFORMAT_STRING pCVArrayFormat;
3214 ULONG esize, bufsize;
3215 unsigned char cvarray_type;
3217 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3219 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3220 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3222 ERR("invalid format type %x\n", pCVStructFormat->type);
3223 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3227 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3228 pCVStructFormat->offset_to_array_description;
3229 cvarray_type = *pCVArrayFormat;
3230 switch (cvarray_type)
3232 case RPC_FC_CVARRAY:
3233 esize = *(const WORD*)(pCVArrayFormat+2);
3234 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3236 case RPC_FC_C_CSTRING:
3237 esize = sizeof(char);
3238 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3239 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3241 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3243 case RPC_FC_C_WSTRING:
3244 esize = sizeof(WCHAR);
3245 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3246 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3248 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3251 ERR("invalid array format type %x\n", *pCVArrayFormat);
3252 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3256 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3258 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3260 /* work out how much memory to allocate if we need to do so */
3261 if (!*ppMemory || fMustAlloc)
3263 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3264 *ppMemory = NdrAllocate(pStubMsg, size);
3267 /* copy the constant data */
3268 pStubMsg->BufferMark = pStubMsg->Buffer;
3269 memcpy(*ppMemory, pStubMsg->Buffer, pCVStructFormat->memory_size);
3270 pStubMsg->Buffer += pCVStructFormat->memory_size;
3272 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3274 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3276 if ((cvarray_type == RPC_FC_C_CSTRING) ||
3277 (cvarray_type == RPC_FC_C_WSTRING))
3280 /* strings must always have null terminating bytes */
3281 if (bufsize < esize)
3283 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
3284 RpcRaiseException(RPC_S_INVALID_BOUND);
3287 for (i = bufsize - esize; i < bufsize; i++)
3288 if (pStubMsg->Buffer[i] != 0)
3290 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3291 i, pStubMsg->Buffer[i]);
3292 RpcRaiseException(RPC_S_INVALID_BOUND);
3297 /* copy the array data */
3298 memcpy(*ppMemory + pCVStructFormat->memory_size, pStubMsg->Buffer,
3300 pStubMsg->Buffer += bufsize;
3302 if (cvarray_type == RPC_FC_C_CSTRING)
3303 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3304 else if (cvarray_type == RPC_FC_C_WSTRING)
3305 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3307 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3312 /***********************************************************************
3313 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3315 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3316 unsigned char *pMemory,
3317 PFORMAT_STRING pFormat)
3319 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3320 PFORMAT_STRING pCVArrayFormat;
3323 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3325 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3326 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3328 ERR("invalid format type %x\n", pCVStructFormat->type);
3329 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3333 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3334 pCVStructFormat->offset_to_array_description;
3335 switch (*pCVArrayFormat)
3337 case RPC_FC_CVARRAY:
3338 esize = *(const WORD*)(pCVArrayFormat+2);
3340 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3341 pCVArrayFormat + 4, 0);
3342 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3345 case RPC_FC_C_CSTRING:
3346 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3347 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3348 esize = sizeof(char);
3349 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3350 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3351 pCVArrayFormat + 2, 0);
3353 pStubMsg->MaxCount = pStubMsg->ActualCount;
3355 case RPC_FC_C_WSTRING:
3356 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3357 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3358 esize = sizeof(WCHAR);
3359 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3360 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3361 pCVArrayFormat + 2, 0);
3363 pStubMsg->MaxCount = pStubMsg->ActualCount;
3366 ERR("invalid array format type %x\n", *pCVArrayFormat);
3367 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3371 SizeConformance(pStubMsg);
3373 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
3375 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3377 pStubMsg->BufferLength += pCVStructFormat->memory_size;
3378 SizeVariance(pStubMsg);
3379 pStubMsg->BufferLength += safe_multiply(pStubMsg->MaxCount, esize);
3381 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3384 /***********************************************************************
3385 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3387 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3388 PFORMAT_STRING pFormat)
3390 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3391 PFORMAT_STRING pCVArrayFormat;
3393 unsigned char cvarray_type;
3395 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3397 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3398 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3400 ERR("invalid format type %x\n", pCVStructFormat->type);
3401 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3405 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3406 pCVStructFormat->offset_to_array_description;
3407 cvarray_type = *pCVArrayFormat;
3408 switch (cvarray_type)
3410 case RPC_FC_CVARRAY:
3411 esize = *(const WORD*)(pCVArrayFormat+2);
3412 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3414 case RPC_FC_C_CSTRING:
3415 esize = sizeof(char);
3416 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3417 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3419 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3421 case RPC_FC_C_WSTRING:
3422 esize = sizeof(WCHAR);
3423 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3424 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3426 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3429 ERR("invalid array format type %x\n", *pCVArrayFormat);
3430 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3434 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3436 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3438 pStubMsg->Buffer += pCVStructFormat->memory_size;
3439 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3440 pStubMsg->Buffer += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->ActualCount);
3442 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3444 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3446 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3449 /***********************************************************************
3450 * NdrConformantVaryingStructFree [RPCRT4.@]
3452 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3453 unsigned char *pMemory,
3454 PFORMAT_STRING pFormat)
3456 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3457 PFORMAT_STRING pCVArrayFormat;
3460 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3462 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3463 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3465 ERR("invalid format type %x\n", pCVStructFormat->type);
3466 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3470 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3471 pCVStructFormat->offset_to_array_description;
3472 switch (*pCVArrayFormat)
3474 case RPC_FC_CVARRAY:
3475 esize = *(const WORD*)(pCVArrayFormat+2);
3477 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3478 pCVArrayFormat + 4, 0);
3479 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3482 case RPC_FC_C_CSTRING:
3483 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3484 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3485 esize = sizeof(char);
3486 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3487 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3488 pCVArrayFormat + 2, 0);
3490 pStubMsg->MaxCount = pStubMsg->ActualCount;
3492 case RPC_FC_C_WSTRING:
3493 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3494 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3495 esize = sizeof(WCHAR);
3496 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3497 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3498 pCVArrayFormat + 2, 0);
3500 pStubMsg->MaxCount = pStubMsg->ActualCount;
3503 ERR("invalid array format type %x\n", *pCVArrayFormat);
3504 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3508 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3510 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3513 #include "pshpack1.h"
3517 unsigned char alignment;
3518 unsigned short total_size;
3519 } NDR_SMFARRAY_FORMAT;
3524 unsigned char alignment;
3525 unsigned long total_size;
3526 } NDR_LGFARRAY_FORMAT;
3527 #include "poppack.h"
3529 /***********************************************************************
3530 * NdrFixedArrayMarshall [RPCRT4.@]
3532 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3533 unsigned char *pMemory,
3534 PFORMAT_STRING pFormat)
3536 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3537 unsigned long total_size;
3539 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3541 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3542 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3544 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3545 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3549 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3551 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3553 total_size = pSmFArrayFormat->total_size;
3554 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3558 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3559 total_size = pLgFArrayFormat->total_size;
3560 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3563 memcpy(pStubMsg->Buffer, pMemory, total_size);
3564 pStubMsg->BufferMark = pStubMsg->Buffer;
3565 pStubMsg->Buffer += total_size;
3567 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3572 /***********************************************************************
3573 * NdrFixedArrayUnmarshall [RPCRT4.@]
3575 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3576 unsigned char **ppMemory,
3577 PFORMAT_STRING pFormat,
3578 unsigned char fMustAlloc)
3580 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3581 unsigned long total_size;
3583 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3585 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3586 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3588 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3589 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3593 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3595 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3597 total_size = pSmFArrayFormat->total_size;
3598 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3602 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3603 total_size = pLgFArrayFormat->total_size;
3604 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3607 if (fMustAlloc || !*ppMemory)
3608 *ppMemory = NdrAllocate(pStubMsg, total_size);
3609 memcpy(*ppMemory, pStubMsg->Buffer, total_size);
3610 pStubMsg->BufferMark = pStubMsg->Buffer;
3611 pStubMsg->Buffer += total_size;
3613 pFormat = EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3618 /***********************************************************************
3619 * NdrFixedArrayBufferSize [RPCRT4.@]
3621 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3622 unsigned char *pMemory,
3623 PFORMAT_STRING pFormat)
3625 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3626 unsigned long total_size;
3628 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3630 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3631 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3633 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3634 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3638 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
3640 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3642 total_size = pSmFArrayFormat->total_size;
3643 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3647 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3648 total_size = pLgFArrayFormat->total_size;
3649 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3651 pStubMsg->BufferLength += total_size;
3653 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3656 /***********************************************************************
3657 * NdrFixedArrayMemorySize [RPCRT4.@]
3659 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3660 PFORMAT_STRING pFormat)
3662 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3665 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3667 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3668 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3670 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3671 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3675 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3677 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3679 total_size = pSmFArrayFormat->total_size;
3680 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3684 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3685 total_size = pLgFArrayFormat->total_size;
3686 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3688 pStubMsg->BufferMark = pStubMsg->Buffer;
3689 pStubMsg->Buffer += total_size;
3690 pStubMsg->MemorySize += total_size;
3692 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3697 /***********************************************************************
3698 * NdrFixedArrayFree [RPCRT4.@]
3700 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3701 unsigned char *pMemory,
3702 PFORMAT_STRING pFormat)
3704 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3706 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3708 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3709 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3711 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3712 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3716 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3717 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3720 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3721 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3724 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3727 /***********************************************************************
3728 * NdrVaryingArrayMarshall [RPCRT4.@]
3730 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3731 unsigned char *pMemory,
3732 PFORMAT_STRING pFormat)
3734 unsigned char alignment;
3735 DWORD elements, esize;
3738 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3740 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3741 (pFormat[0] != RPC_FC_LGVARRAY))
3743 ERR("invalid format type %x\n", pFormat[0]);
3744 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3748 alignment = pFormat[1] + 1;
3750 if (pFormat[0] == RPC_FC_SMVARRAY)
3753 pFormat += sizeof(WORD);
3754 elements = *(const WORD*)pFormat;
3755 pFormat += sizeof(WORD);
3760 pFormat += sizeof(DWORD);
3761 elements = *(const DWORD*)pFormat;
3762 pFormat += sizeof(DWORD);
3765 esize = *(const WORD*)pFormat;
3766 pFormat += sizeof(WORD);
3768 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3769 if ((pStubMsg->ActualCount > elements) ||
3770 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3772 RpcRaiseException(RPC_S_INVALID_BOUND);
3776 WriteVariance(pStubMsg);
3778 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3780 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3781 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
3782 pStubMsg->BufferMark = pStubMsg->Buffer;
3783 pStubMsg->Buffer += bufsize;
3785 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3787 STD_OVERFLOW_CHECK(pStubMsg);
3792 /***********************************************************************
3793 * NdrVaryingArrayUnmarshall [RPCRT4.@]
3795 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3796 unsigned char **ppMemory,
3797 PFORMAT_STRING pFormat,
3798 unsigned char fMustAlloc)
3800 unsigned char alignment;
3801 DWORD size, elements, esize;
3804 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3806 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3807 (pFormat[0] != RPC_FC_LGVARRAY))
3809 ERR("invalid format type %x\n", pFormat[0]);
3810 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3814 alignment = pFormat[1] + 1;
3816 if (pFormat[0] == RPC_FC_SMVARRAY)
3819 size = *(const WORD*)pFormat;
3820 pFormat += sizeof(WORD);
3821 elements = *(const WORD*)pFormat;
3822 pFormat += sizeof(WORD);
3827 size = *(const DWORD*)pFormat;
3828 pFormat += sizeof(DWORD);
3829 elements = *(const DWORD*)pFormat;
3830 pFormat += sizeof(DWORD);
3833 esize = *(const WORD*)pFormat;
3834 pFormat += sizeof(WORD);
3836 pFormat = ReadVariance(pStubMsg, pFormat, elements);
3838 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3840 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3842 if (!*ppMemory || fMustAlloc)
3843 *ppMemory = NdrAllocate(pStubMsg, size);
3844 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
3845 pStubMsg->Buffer += bufsize;
3847 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3852 /***********************************************************************
3853 * NdrVaryingArrayBufferSize [RPCRT4.@]
3855 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3856 unsigned char *pMemory,
3857 PFORMAT_STRING pFormat)
3859 unsigned char alignment;
3860 DWORD elements, esize;
3862 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3864 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3865 (pFormat[0] != RPC_FC_LGVARRAY))
3867 ERR("invalid format type %x\n", pFormat[0]);
3868 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3872 alignment = pFormat[1] + 1;
3874 if (pFormat[0] == RPC_FC_SMVARRAY)
3877 pFormat += sizeof(WORD);
3878 elements = *(const WORD*)pFormat;
3879 pFormat += sizeof(WORD);
3884 pFormat += sizeof(DWORD);
3885 elements = *(const DWORD*)pFormat;
3886 pFormat += sizeof(DWORD);
3889 esize = *(const WORD*)pFormat;
3890 pFormat += sizeof(WORD);
3892 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3893 if ((pStubMsg->ActualCount > elements) ||
3894 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3896 RpcRaiseException(RPC_S_INVALID_BOUND);
3900 SizeVariance(pStubMsg);
3902 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3904 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
3906 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3909 /***********************************************************************
3910 * NdrVaryingArrayMemorySize [RPCRT4.@]
3912 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3913 PFORMAT_STRING pFormat)
3915 unsigned char alignment;
3916 DWORD size, elements, esize;
3918 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3920 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3921 (pFormat[0] != RPC_FC_LGVARRAY))
3923 ERR("invalid format type %x\n", pFormat[0]);
3924 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3928 alignment = pFormat[1] + 1;
3930 if (pFormat[0] == RPC_FC_SMVARRAY)
3933 size = *(const WORD*)pFormat;
3934 pFormat += sizeof(WORD);
3935 elements = *(const WORD*)pFormat;
3936 pFormat += sizeof(WORD);
3941 size = *(const DWORD*)pFormat;
3942 pFormat += sizeof(DWORD);
3943 elements = *(const DWORD*)pFormat;
3944 pFormat += sizeof(DWORD);
3947 esize = *(const WORD*)pFormat;
3948 pFormat += sizeof(WORD);
3950 pFormat = ReadVariance(pStubMsg, pFormat, elements);
3952 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3954 pStubMsg->Buffer += safe_multiply(esize, pStubMsg->ActualCount);
3955 pStubMsg->MemorySize += size;
3957 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3959 return pStubMsg->MemorySize;
3962 /***********************************************************************
3963 * NdrVaryingArrayFree [RPCRT4.@]
3965 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3966 unsigned char *pMemory,
3967 PFORMAT_STRING pFormat)
3969 unsigned char alignment;
3972 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3974 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3975 (pFormat[0] != RPC_FC_LGVARRAY))
3977 ERR("invalid format type %x\n", pFormat[0]);
3978 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3982 alignment = pFormat[1] + 1;
3984 if (pFormat[0] == RPC_FC_SMVARRAY)
3987 pFormat += sizeof(WORD);
3988 elements = *(const WORD*)pFormat;
3989 pFormat += sizeof(WORD);
3994 pFormat += sizeof(DWORD);
3995 elements = *(const DWORD*)pFormat;
3996 pFormat += sizeof(DWORD);
3999 pFormat += sizeof(WORD);
4001 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4002 if ((pStubMsg->ActualCount > elements) ||
4003 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4005 RpcRaiseException(RPC_S_INVALID_BOUND);
4009 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4012 static ULONG get_discriminant(unsigned char fc, unsigned char *pMemory)
4020 return *(UCHAR *)pMemory;
4024 return *(USHORT *)pMemory;
4027 return *(ULONG *)pMemory;
4029 FIXME("Unhandled base type: 0x%02x\n", fc);
4034 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4035 unsigned long discriminant,
4036 PFORMAT_STRING pFormat)
4038 unsigned short num_arms, arm, type;
4040 num_arms = *(const SHORT*)pFormat & 0x0fff;
4042 for(arm = 0; arm < num_arms; arm++)
4044 if(discriminant == *(const ULONG*)pFormat)
4052 type = *(const unsigned short*)pFormat;
4053 TRACE("type %04x\n", type);
4054 if(arm == num_arms) /* default arm extras */
4058 ERR("no arm for 0x%lx and no default case\n", discriminant);
4059 RpcRaiseException(RPC_S_INVALID_TAG);
4064 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
4071 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
4073 unsigned short type;
4077 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4081 type = *(const unsigned short*)pFormat;
4082 if((type & 0xff00) == 0x8000)
4084 unsigned char basetype = LOBYTE(type);
4085 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
4089 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4090 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
4093 unsigned char *saved_buffer = NULL;
4100 saved_buffer = pStubMsg->Buffer;
4101 pStubMsg->Buffer += 4; /* for pointer ID */
4102 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
4105 m(pStubMsg, pMemory, desc);
4108 else FIXME("no marshaller for embedded type %02x\n", *desc);
4113 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4114 unsigned char **ppMemory,
4116 PFORMAT_STRING pFormat,
4117 unsigned char fMustAlloc)
4119 unsigned short type;
4123 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4127 type = *(const unsigned short*)pFormat;
4128 if((type & 0xff00) == 0x8000)
4130 unsigned char basetype = LOBYTE(type);
4131 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, fMustAlloc);
4135 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4136 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
4139 unsigned char *saved_buffer = NULL;
4146 ALIGN_POINTER(pStubMsg->Buffer, 4);
4147 saved_buffer = pStubMsg->Buffer;
4148 pStubMsg->Buffer += 4; /* for pointer ID */
4149 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, desc, TRUE);
4152 m(pStubMsg, ppMemory, desc, fMustAlloc);
4155 else FIXME("no marshaller for embedded type %02x\n", *desc);
4160 /***********************************************************************
4161 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4163 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
4164 unsigned char *pMemory,
4166 PFORMAT_STRING pFormat)
4168 unsigned short type;
4172 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4176 type = *(const unsigned short*)pFormat;
4177 if((type & 0xff00) == 0x8000)
4179 unsigned char basetype = LOBYTE(type);
4180 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
4184 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4185 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
4194 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4195 pStubMsg->BufferLength += 4; /* for pointer ID */
4196 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
4199 m(pStubMsg, pMemory, desc);
4202 else FIXME("no buffersizer for embedded type %02x\n", *desc);
4206 /***********************************************************************
4207 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4209 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
4211 PFORMAT_STRING pFormat)
4213 unsigned short type, size;
4215 size = *(const unsigned short*)pFormat;
4216 pStubMsg->Memory += size;
4219 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4223 type = *(const unsigned short*)pFormat;
4224 if((type & 0xff00) == 0x8000)
4226 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
4230 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4231 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
4232 unsigned char *saved_buffer;
4241 ALIGN_POINTER(pStubMsg->Buffer, 4);
4242 saved_buffer = pStubMsg->Buffer;
4243 pStubMsg->Buffer += 4;
4244 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
4245 pStubMsg->MemorySize += 4;
4246 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
4249 return m(pStubMsg, desc);
4252 else FIXME("no marshaller for embedded type %02x\n", *desc);
4255 TRACE("size %d\n", size);
4259 /***********************************************************************
4260 * NdrEncapsulatedUnionFree [RPCRT4.@]
4262 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
4263 unsigned char *pMemory,
4265 PFORMAT_STRING pFormat)
4267 unsigned short type;
4271 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4275 type = *(const unsigned short*)pFormat;
4276 if((type & 0xff00) != 0x8000)
4278 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4279 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
4288 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
4291 m(pStubMsg, pMemory, desc);
4294 else FIXME("no freer for embedded type %02x\n", *desc);
4298 /***********************************************************************
4299 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4301 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4302 unsigned char *pMemory,
4303 PFORMAT_STRING pFormat)
4305 unsigned char switch_type;
4306 unsigned char increment;
4309 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4312 switch_type = *pFormat & 0xf;
4313 increment = *pFormat & 0xf0 >> 4;
4316 ALIGN_POINTER(pStubMsg->Buffer, increment);
4318 switch_value = get_discriminant(switch_type, pMemory);
4319 TRACE("got switch value 0x%x\n", switch_value);
4321 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
4322 pMemory += increment;
4324 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
4327 /***********************************************************************
4328 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4330 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4331 unsigned char **ppMemory,
4332 PFORMAT_STRING pFormat,
4333 unsigned char fMustAlloc)
4335 unsigned char switch_type;
4336 unsigned char increment;
4338 unsigned short size;
4339 unsigned char *pMemoryArm;
4341 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4344 switch_type = *pFormat & 0xf;
4345 increment = *pFormat & 0xf0 >> 4;
4348 ALIGN_POINTER(pStubMsg->Buffer, increment);
4349 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
4350 TRACE("got switch value 0x%x\n", switch_value);
4352 size = *(const unsigned short*)pFormat + increment;
4353 if(!*ppMemory || fMustAlloc)
4354 *ppMemory = NdrAllocate(pStubMsg, size);
4356 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
4357 pMemoryArm = *ppMemory + increment;
4359 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
4362 /***********************************************************************
4363 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4365 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4366 unsigned char *pMemory,
4367 PFORMAT_STRING pFormat)
4369 unsigned char switch_type;
4370 unsigned char increment;
4373 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4376 switch_type = *pFormat & 0xf;
4377 increment = *pFormat & 0xf0 >> 4;
4380 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
4381 switch_value = get_discriminant(switch_value, pMemory);
4382 TRACE("got switch value 0x%x\n", switch_value);
4384 /* Add discriminant size */
4385 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
4386 pMemory += increment;
4388 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
4391 /***********************************************************************
4392 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4394 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4395 PFORMAT_STRING pFormat)
4397 unsigned char switch_type;
4398 unsigned char increment;
4401 switch_type = *pFormat & 0xf;
4402 increment = *pFormat & 0xf0 >> 4;
4405 ALIGN_POINTER(pStubMsg->Buffer, increment);
4406 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
4407 TRACE("got switch value 0x%x\n", switch_value);
4409 pStubMsg->Memory += increment;
4411 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
4414 /***********************************************************************
4415 * NdrEncapsulatedUnionFree [RPCRT4.@]
4417 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4418 unsigned char *pMemory,
4419 PFORMAT_STRING pFormat)
4421 unsigned char switch_type;
4422 unsigned char increment;
4425 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4428 switch_type = *pFormat & 0xf;
4429 increment = *pFormat & 0xf0 >> 4;
4432 switch_value = get_discriminant(switch_type, pMemory);
4433 TRACE("got switch value 0x%x\n", switch_value);
4435 pMemory += increment;
4437 return union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
4440 /***********************************************************************
4441 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
4443 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4444 unsigned char *pMemory,
4445 PFORMAT_STRING pFormat)
4447 unsigned char switch_type;
4449 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4452 switch_type = *pFormat;
4455 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4456 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4457 /* Marshall discriminant */
4458 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4460 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
4463 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
4464 PFORMAT_STRING *ppFormat)
4466 long discriminant = 0;
4474 discriminant = *(UCHAR *)pStubMsg->Buffer;
4475 pStubMsg->Buffer += sizeof(UCHAR);
4480 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4481 discriminant = *(USHORT *)pStubMsg->Buffer;
4482 pStubMsg->Buffer += sizeof(USHORT);
4486 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4487 discriminant = *(ULONG *)pStubMsg->Buffer;
4488 pStubMsg->Buffer += sizeof(ULONG);
4491 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
4495 if (pStubMsg->fHasNewCorrDesc)
4499 return discriminant;
4502 /**********************************************************************
4503 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
4505 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4506 unsigned char **ppMemory,
4507 PFORMAT_STRING pFormat,
4508 unsigned char fMustAlloc)
4511 unsigned short size;
4513 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4516 /* Unmarshall discriminant */
4517 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4518 TRACE("unmarshalled discriminant %lx\n", discriminant);
4520 pFormat += *(const SHORT*)pFormat;
4522 size = *(const unsigned short*)pFormat;
4524 if(!*ppMemory || fMustAlloc)
4525 *ppMemory = NdrAllocate(pStubMsg, size);
4527 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
4530 /***********************************************************************
4531 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
4533 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4534 unsigned char *pMemory,
4535 PFORMAT_STRING pFormat)
4537 unsigned char switch_type;
4539 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4542 switch_type = *pFormat;
4545 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4546 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4547 /* Add discriminant size */
4548 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4550 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
4553 /***********************************************************************
4554 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
4556 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4557 PFORMAT_STRING pFormat)
4562 /* Unmarshall discriminant */
4563 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4564 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
4566 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
4569 /***********************************************************************
4570 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
4572 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4573 unsigned char *pMemory,
4574 PFORMAT_STRING pFormat)
4576 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4580 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4581 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4583 return union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
4586 /***********************************************************************
4587 * NdrByteCountPointerMarshall [RPCRT4.@]
4589 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4590 unsigned char *pMemory,
4591 PFORMAT_STRING pFormat)
4597 /***********************************************************************
4598 * NdrByteCountPointerUnmarshall [RPCRT4.@]
4600 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4601 unsigned char **ppMemory,
4602 PFORMAT_STRING pFormat,
4603 unsigned char fMustAlloc)
4609 /***********************************************************************
4610 * NdrByteCountPointerBufferSize [RPCRT4.@]
4612 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4613 unsigned char *pMemory,
4614 PFORMAT_STRING pFormat)
4619 /***********************************************************************
4620 * NdrByteCountPointerMemorySize [RPCRT4.@]
4622 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4623 PFORMAT_STRING pFormat)
4629 /***********************************************************************
4630 * NdrByteCountPointerFree [RPCRT4.@]
4632 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
4633 unsigned char *pMemory,
4634 PFORMAT_STRING pFormat)
4639 /***********************************************************************
4640 * NdrXmitOrRepAsMarshall [RPCRT4.@]
4642 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4643 unsigned char *pMemory,
4644 PFORMAT_STRING pFormat)
4650 /***********************************************************************
4651 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
4653 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4654 unsigned char **ppMemory,
4655 PFORMAT_STRING pFormat,
4656 unsigned char fMustAlloc)
4662 /***********************************************************************
4663 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
4665 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4666 unsigned char *pMemory,
4667 PFORMAT_STRING pFormat)
4672 /***********************************************************************
4673 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
4675 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4676 PFORMAT_STRING pFormat)
4682 /***********************************************************************
4683 * NdrXmitOrRepAsFree [RPCRT4.@]
4685 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
4686 unsigned char *pMemory,
4687 PFORMAT_STRING pFormat)
4692 /***********************************************************************
4693 * NdrBaseTypeMarshall [internal]
4695 static unsigned char *WINAPI NdrBaseTypeMarshall(
4696 PMIDL_STUB_MESSAGE pStubMsg,
4697 unsigned char *pMemory,
4698 PFORMAT_STRING pFormat)
4700 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4708 *(UCHAR *)pStubMsg->Buffer = *(UCHAR *)pMemory;
4709 pStubMsg->Buffer += sizeof(UCHAR);
4710 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
4715 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4716 *(USHORT *)pStubMsg->Buffer = *(USHORT *)pMemory;
4717 pStubMsg->Buffer += sizeof(USHORT);
4718 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
4722 case RPC_FC_ERROR_STATUS_T:
4724 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4725 *(ULONG *)pStubMsg->Buffer = *(ULONG *)pMemory;
4726 pStubMsg->Buffer += sizeof(ULONG);
4727 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
4730 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
4731 *(float *)pStubMsg->Buffer = *(float *)pMemory;
4732 pStubMsg->Buffer += sizeof(float);
4735 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
4736 *(double *)pStubMsg->Buffer = *(double *)pMemory;
4737 pStubMsg->Buffer += sizeof(double);
4740 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
4741 *(ULONGLONG *)pStubMsg->Buffer = *(ULONGLONG *)pMemory;
4742 pStubMsg->Buffer += sizeof(ULONGLONG);
4743 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
4746 /* only 16-bits on the wire, so do a sanity check */
4747 if (*(UINT *)pMemory > USHRT_MAX)
4748 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
4749 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4750 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
4751 pStubMsg->Buffer += sizeof(USHORT);
4752 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
4755 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4758 STD_OVERFLOW_CHECK(pStubMsg);
4760 /* FIXME: what is the correct return value? */
4764 /***********************************************************************
4765 * NdrBaseTypeUnmarshall [internal]
4767 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
4768 PMIDL_STUB_MESSAGE pStubMsg,
4769 unsigned char **ppMemory,
4770 PFORMAT_STRING pFormat,
4771 unsigned char fMustAlloc)
4773 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
4775 #define BASE_TYPE_UNMARSHALL(type) \
4776 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
4777 if (fMustAlloc || !*ppMemory) \
4778 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
4779 TRACE("*ppMemory: %p\n", *ppMemory); \
4780 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
4781 pStubMsg->Buffer += sizeof(type);
4789 BASE_TYPE_UNMARSHALL(UCHAR);
4790 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
4795 BASE_TYPE_UNMARSHALL(USHORT);
4796 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
4800 case RPC_FC_ERROR_STATUS_T:
4802 BASE_TYPE_UNMARSHALL(ULONG);
4803 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
4806 BASE_TYPE_UNMARSHALL(float);
4807 TRACE("value: %f\n", **(float **)ppMemory);
4810 BASE_TYPE_UNMARSHALL(double);
4811 TRACE("value: %f\n", **(double **)ppMemory);
4814 BASE_TYPE_UNMARSHALL(ULONGLONG);
4815 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
4818 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4819 if (fMustAlloc || !*ppMemory)
4820 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
4821 TRACE("*ppMemory: %p\n", *ppMemory);
4822 /* 16-bits on the wire, but int in memory */
4823 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
4824 pStubMsg->Buffer += sizeof(USHORT);
4825 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
4828 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4830 #undef BASE_TYPE_UNMARSHALL
4832 /* FIXME: what is the correct return value? */
4837 /***********************************************************************
4838 * NdrBaseTypeBufferSize [internal]
4840 static void WINAPI NdrBaseTypeBufferSize(
4841 PMIDL_STUB_MESSAGE pStubMsg,
4842 unsigned char *pMemory,
4843 PFORMAT_STRING pFormat)
4845 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4853 pStubMsg->BufferLength += sizeof(UCHAR);
4859 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
4860 pStubMsg->BufferLength += sizeof(USHORT);
4865 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
4866 pStubMsg->BufferLength += sizeof(ULONG);
4869 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
4870 pStubMsg->BufferLength += sizeof(float);
4873 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
4874 pStubMsg->BufferLength += sizeof(double);
4877 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
4878 pStubMsg->BufferLength += sizeof(ULONGLONG);
4880 case RPC_FC_ERROR_STATUS_T:
4881 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
4882 pStubMsg->BufferLength += sizeof(error_status_t);
4885 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4889 /***********************************************************************
4890 * NdrBaseTypeMemorySize [internal]
4892 static ULONG WINAPI NdrBaseTypeMemorySize(
4893 PMIDL_STUB_MESSAGE pStubMsg,
4894 PFORMAT_STRING pFormat)
4902 pStubMsg->Buffer += sizeof(UCHAR);
4903 pStubMsg->MemorySize += sizeof(UCHAR);
4904 return sizeof(UCHAR);
4908 pStubMsg->Buffer += sizeof(USHORT);
4909 pStubMsg->MemorySize += sizeof(USHORT);
4910 return sizeof(USHORT);
4913 pStubMsg->Buffer += sizeof(ULONG);
4914 pStubMsg->MemorySize += sizeof(ULONG);
4915 return sizeof(ULONG);
4917 pStubMsg->Buffer += sizeof(float);
4918 pStubMsg->MemorySize += sizeof(float);
4919 return sizeof(float);
4921 pStubMsg->Buffer += sizeof(double);
4922 pStubMsg->MemorySize += sizeof(double);
4923 return sizeof(double);
4925 pStubMsg->Buffer += sizeof(ULONGLONG);
4926 pStubMsg->MemorySize += sizeof(ULONGLONG);
4927 return sizeof(ULONGLONG);
4928 case RPC_FC_ERROR_STATUS_T:
4929 pStubMsg->Buffer += sizeof(error_status_t);
4930 pStubMsg->MemorySize += sizeof(error_status_t);
4931 return sizeof(error_status_t);
4934 pStubMsg->Buffer += sizeof(INT);
4935 pStubMsg->MemorySize += sizeof(INT);
4938 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4943 /***********************************************************************
4944 * NdrBaseTypeFree [internal]
4946 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
4947 unsigned char *pMemory,
4948 PFORMAT_STRING pFormat)
4950 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4955 /***********************************************************************
4956 * NdrClientContextMarshall [RPCRT4.@]
4958 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4959 NDR_CCONTEXT ContextHandle,
4962 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
4964 ALIGN_POINTER(pStubMsg->Buffer, 4);
4966 /* FIXME: what does fCheck do? */
4967 NDRCContextMarshall(ContextHandle,
4970 pStubMsg->Buffer += cbNDRContext;
4973 /***********************************************************************
4974 * NdrClientContextUnmarshall [RPCRT4.@]
4976 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4977 NDR_CCONTEXT * pContextHandle,
4978 RPC_BINDING_HANDLE BindHandle)
4980 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
4982 ALIGN_POINTER(pStubMsg->Buffer, 4);
4984 NDRCContextUnmarshall(pContextHandle,
4987 pStubMsg->RpcMsg->DataRepresentation);
4989 pStubMsg->Buffer += cbNDRContext;
4992 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4993 NDR_SCONTEXT ContextHandle,
4994 NDR_RUNDOWN RundownRoutine )
4996 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
4999 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
5001 FIXME("(%p): stub\n", pStubMsg);
5005 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
5006 unsigned char* pMemory,
5007 PFORMAT_STRING pFormat)
5009 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
5012 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
5013 PFORMAT_STRING pFormat)
5015 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
5019 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5020 NDR_SCONTEXT ContextHandle,
5021 NDR_RUNDOWN RundownRoutine,
5022 PFORMAT_STRING pFormat)
5024 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
5027 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5028 PFORMAT_STRING pFormat)
5030 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
5034 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
5036 typedef struct ndr_context_handle
5040 } ndr_context_handle;
5042 struct context_handle_entry
5046 RPC_BINDING_HANDLE handle;
5047 ndr_context_handle wire_data;
5050 static struct list context_handle_list = LIST_INIT(context_handle_list);
5052 static CRITICAL_SECTION ndr_context_cs;
5053 static CRITICAL_SECTION_DEBUG ndr_context_debug =
5055 0, 0, &ndr_context_cs,
5056 { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
5057 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
5059 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
5061 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
5063 struct context_handle_entry *che = (struct context_handle_entry*) CContext;
5065 if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
5070 static struct context_handle_entry *context_entry_from_guid(LPGUID uuid)
5072 struct context_handle_entry *che;
5073 LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
5074 if (IsEqualGUID(&che->wire_data.uuid, uuid))
5079 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
5081 struct context_handle_entry *che;
5082 RPC_BINDING_HANDLE handle = NULL;
5084 TRACE("%p\n", CContext);
5086 EnterCriticalSection(&ndr_context_cs);
5087 che = get_context_entry(CContext);
5089 handle = che->handle;
5090 LeaveCriticalSection(&ndr_context_cs);
5093 RpcRaiseException(ERROR_INVALID_HANDLE);
5097 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
5099 struct context_handle_entry *che;
5101 TRACE("%p %p\n", CContext, pBuff);
5105 EnterCriticalSection(&ndr_context_cs);
5106 che = get_context_entry(CContext);
5107 memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
5108 LeaveCriticalSection(&ndr_context_cs);
5112 ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
5113 wire_data->attributes = 0;
5114 wire_data->uuid = GUID_NULL;
5118 static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
5119 RPC_BINDING_HANDLE hBinding,
5120 ndr_context_handle *chi)
5122 struct context_handle_entry *che = NULL;
5124 /* a null UUID means we should free the context handle */
5125 if (IsEqualGUID(&chi->uuid, &GUID_NULL))
5129 che = get_context_entry(*CContext);
5131 return ERROR_INVALID_HANDLE;
5132 list_remove(&che->entry);
5133 RpcBindingFree(&che->handle);
5134 HeapFree(GetProcessHeap(), 0, che);
5138 /* if there's no existing entry matching the GUID, allocate one */
5139 else if (!(che = context_entry_from_guid(&chi->uuid)))
5141 che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
5143 return ERROR_NOT_ENOUGH_MEMORY;
5144 che->magic = NDR_CONTEXT_HANDLE_MAGIC;
5145 RpcBindingCopy(hBinding, &che->handle);
5146 list_add_tail(&context_handle_list, &che->entry);
5147 memcpy(&che->wire_data, chi, sizeof *chi);
5152 return ERROR_SUCCESS;
5155 /***********************************************************************
5156 * NDRCContextUnmarshall [RPCRT4.@]
5158 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
5159 RPC_BINDING_HANDLE hBinding,
5160 void *pBuff, ULONG DataRepresentation)
5164 TRACE("*%p=(%p) %p %p %08x\n",
5165 CContext, *CContext, hBinding, pBuff, DataRepresentation);
5167 EnterCriticalSection(&ndr_context_cs);
5168 r = ndr_update_context_handle(CContext, hBinding, pBuff);
5169 LeaveCriticalSection(&ndr_context_cs);
5171 RpcRaiseException(r);
5174 /***********************************************************************
5175 * NDRSContextMarshall [RPCRT4.@]
5177 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
5179 NDR_RUNDOWN userRunDownIn)
5181 FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn);
5184 /***********************************************************************
5185 * NDRSContextMarshallEx [RPCRT4.@]
5187 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
5188 NDR_SCONTEXT CContext,
5190 NDR_RUNDOWN userRunDownIn)
5192 FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn);
5195 /***********************************************************************
5196 * NDRSContextMarshall2 [RPCRT4.@]
5198 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
5199 NDR_SCONTEXT CContext,
5201 NDR_RUNDOWN userRunDownIn,
5202 void *CtxGuard, ULONG Flags)
5204 FIXME("(%p %p %p %p %p %u): stub\n",
5205 hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags);
5208 /***********************************************************************
5209 * NDRSContextUnmarshall [RPCRT4.@]
5211 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
5212 ULONG DataRepresentation)
5214 FIXME("(%p %08x): stub\n", pBuff, DataRepresentation);
5218 /***********************************************************************
5219 * NDRSContextUnmarshallEx [RPCRT4.@]
5221 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
5223 ULONG DataRepresentation)
5225 FIXME("(%p %p %08x): stub\n", hBinding, pBuff, DataRepresentation);
5229 /***********************************************************************
5230 * NDRSContextUnmarshall2 [RPCRT4.@]
5232 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
5234 ULONG DataRepresentation,
5235 void *CtxGuard, ULONG Flags)
5237 FIXME("(%p %p %08x %p %u): stub\n",
5238 hBinding, pBuff, DataRepresentation, CtxGuard, Flags);