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 + ofs + (i * stride);
1141 unsigned char *bufbase = Mark + ofs + (i * stride);
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 + ofs + (i * stride);
1214 unsigned char *bufbase = Mark + ofs + (i * stride);
1217 for (u=0; u<count; u++,info+=8) {
1218 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1219 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1220 PointerUnmarshall(pStubMsg, bufptr, (unsigned char**)memptr, info+4, TRUE);
1223 pFormat += 8 * count;
1229 /***********************************************************************
1230 * EmbeddedPointerBufferSize
1232 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1233 unsigned char *pMemory,
1234 PFORMAT_STRING pFormat)
1236 unsigned long Offset = pStubMsg->Offset;
1237 unsigned ofs, rep, count, stride, xofs;
1240 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1242 if (pStubMsg->IgnoreEmbeddedPointers) return;
1244 if (*pFormat != RPC_FC_PP) return;
1247 while (pFormat[0] != RPC_FC_END) {
1248 switch (pFormat[0]) {
1250 FIXME("unknown repeat type %d\n", pFormat[0]);
1251 case RPC_FC_NO_REPEAT:
1259 case RPC_FC_FIXED_REPEAT:
1260 rep = *(const WORD*)&pFormat[2];
1261 stride = *(const WORD*)&pFormat[4];
1262 ofs = *(const WORD*)&pFormat[6];
1263 count = *(const WORD*)&pFormat[8];
1267 case RPC_FC_VARIABLE_REPEAT:
1268 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1269 stride = *(const WORD*)&pFormat[2];
1270 ofs = *(const WORD*)&pFormat[4];
1271 count = *(const WORD*)&pFormat[6];
1272 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1276 for (i = 0; i < rep; i++) {
1277 PFORMAT_STRING info = pFormat;
1278 unsigned char *membase = pMemory + ofs + (i * stride);
1281 for (u=0; u<count; u++,info+=8) {
1282 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1283 unsigned char *saved_memory = pStubMsg->Memory;
1285 pStubMsg->Memory = pMemory;
1286 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1287 pStubMsg->Memory = saved_memory;
1290 pFormat += 8 * count;
1294 /***********************************************************************
1295 * EmbeddedPointerMemorySize [internal]
1297 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1298 PFORMAT_STRING pFormat)
1300 unsigned long Offset = pStubMsg->Offset;
1301 unsigned char *Mark = pStubMsg->BufferMark;
1302 unsigned ofs, rep, count, stride, xofs;
1305 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1307 if (*pFormat != RPC_FC_PP) return 0;
1310 while (pFormat[0] != RPC_FC_END) {
1311 switch (pFormat[0]) {
1313 FIXME("unknown repeat type %d\n", pFormat[0]);
1314 case RPC_FC_NO_REPEAT:
1322 case RPC_FC_FIXED_REPEAT:
1323 rep = *(const WORD*)&pFormat[2];
1324 stride = *(const WORD*)&pFormat[4];
1325 ofs = *(const WORD*)&pFormat[6];
1326 count = *(const WORD*)&pFormat[8];
1330 case RPC_FC_VARIABLE_REPEAT:
1331 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1332 stride = *(const WORD*)&pFormat[2];
1333 ofs = *(const WORD*)&pFormat[4];
1334 count = *(const WORD*)&pFormat[6];
1335 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1339 /* ofs doesn't seem to matter in this context */
1340 for (i = 0; i < rep; i++) {
1341 PFORMAT_STRING info = pFormat;
1342 unsigned char *bufbase = Mark + ofs + (i * stride);
1344 for (u=0; u<count; u++,info+=8) {
1345 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1346 PointerMemorySize(pStubMsg, bufptr, info+4);
1349 pFormat += 8 * count;
1355 /***********************************************************************
1356 * EmbeddedPointerFree [internal]
1358 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1359 unsigned char *pMemory,
1360 PFORMAT_STRING pFormat)
1362 unsigned long Offset = pStubMsg->Offset;
1363 unsigned ofs, rep, count, stride, xofs;
1366 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1367 if (*pFormat != RPC_FC_PP) return;
1370 while (pFormat[0] != RPC_FC_END) {
1371 switch (pFormat[0]) {
1373 FIXME("unknown repeat type %d\n", pFormat[0]);
1374 case RPC_FC_NO_REPEAT:
1382 case RPC_FC_FIXED_REPEAT:
1383 rep = *(const WORD*)&pFormat[2];
1384 stride = *(const WORD*)&pFormat[4];
1385 ofs = *(const WORD*)&pFormat[6];
1386 count = *(const WORD*)&pFormat[8];
1390 case RPC_FC_VARIABLE_REPEAT:
1391 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1392 stride = *(const WORD*)&pFormat[2];
1393 ofs = *(const WORD*)&pFormat[4];
1394 count = *(const WORD*)&pFormat[6];
1395 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1399 for (i = 0; i < rep; i++) {
1400 PFORMAT_STRING info = pFormat;
1401 unsigned char *membase = pMemory + (i * stride);
1404 for (u=0; u<count; u++,info+=8) {
1405 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1406 unsigned char *saved_memory = pStubMsg->Memory;
1408 pStubMsg->Memory = pMemory;
1409 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1410 pStubMsg->Memory = saved_memory;
1413 pFormat += 8 * count;
1417 /***********************************************************************
1418 * NdrPointerMarshall [RPCRT4.@]
1420 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1421 unsigned char *pMemory,
1422 PFORMAT_STRING pFormat)
1424 unsigned char *Buffer;
1426 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1428 /* incremement the buffer here instead of in PointerMarshall,
1429 * as that is used by embedded pointers which already handle the incrementing
1430 * the buffer, and shouldn't write any additional pointer data to the wire */
1431 if (*pFormat != RPC_FC_RP)
1433 ALIGN_POINTER(pStubMsg->Buffer, 4);
1434 Buffer = pStubMsg->Buffer;
1435 pStubMsg->Buffer += 4;
1438 Buffer = pStubMsg->Buffer;
1440 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1442 STD_OVERFLOW_CHECK(pStubMsg);
1447 /***********************************************************************
1448 * NdrPointerUnmarshall [RPCRT4.@]
1450 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1451 unsigned char **ppMemory,
1452 PFORMAT_STRING pFormat,
1453 unsigned char fMustAlloc)
1455 unsigned char *Buffer;
1457 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1459 /* incremement the buffer here instead of in PointerUnmarshall,
1460 * as that is used by embedded pointers which already handle the incrementing
1461 * the buffer, and shouldn't read any additional pointer data from the
1463 if (*pFormat != RPC_FC_RP)
1465 ALIGN_POINTER(pStubMsg->Buffer, 4);
1466 Buffer = pStubMsg->Buffer;
1467 pStubMsg->Buffer += 4;
1470 Buffer = pStubMsg->Buffer;
1472 PointerUnmarshall(pStubMsg, Buffer, ppMemory, pFormat, fMustAlloc);
1477 /***********************************************************************
1478 * NdrPointerBufferSize [RPCRT4.@]
1480 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1481 unsigned char *pMemory,
1482 PFORMAT_STRING pFormat)
1484 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1486 /* incremement the buffer length here instead of in PointerBufferSize,
1487 * as that is used by embedded pointers which already handle the buffer
1488 * length, and shouldn't write anything more to the wire */
1489 if (*pFormat != RPC_FC_RP)
1491 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1492 pStubMsg->BufferLength += 4;
1495 PointerBufferSize(pStubMsg, pMemory, pFormat);
1498 /***********************************************************************
1499 * NdrPointerMemorySize [RPCRT4.@]
1501 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1502 PFORMAT_STRING pFormat)
1504 /* unsigned size = *(LPWORD)(pFormat+2); */
1505 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1506 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1510 /***********************************************************************
1511 * NdrPointerFree [RPCRT4.@]
1513 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1514 unsigned char *pMemory,
1515 PFORMAT_STRING pFormat)
1517 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1518 PointerFree(pStubMsg, pMemory, pFormat);
1521 /***********************************************************************
1522 * NdrSimpleTypeMarshall [RPCRT4.@]
1524 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1525 unsigned char FormatChar )
1527 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1530 /***********************************************************************
1531 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1533 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1534 unsigned char FormatChar )
1536 NdrBaseTypeUnmarshall(pStubMsg, &pMemory, &FormatChar, 0);
1539 /***********************************************************************
1540 * NdrSimpleStructMarshall [RPCRT4.@]
1542 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1543 unsigned char *pMemory,
1544 PFORMAT_STRING pFormat)
1546 unsigned size = *(const WORD*)(pFormat+2);
1547 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1549 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1551 memcpy(pStubMsg->Buffer, pMemory, size);
1552 pStubMsg->BufferMark = pStubMsg->Buffer;
1553 pStubMsg->Buffer += size;
1555 if (pFormat[0] != RPC_FC_STRUCT)
1556 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1558 STD_OVERFLOW_CHECK(pStubMsg);
1563 /***********************************************************************
1564 * NdrSimpleStructUnmarshall [RPCRT4.@]
1566 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1567 unsigned char **ppMemory,
1568 PFORMAT_STRING pFormat,
1569 unsigned char fMustAlloc)
1571 unsigned size = *(const WORD*)(pFormat+2);
1572 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1574 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1577 *ppMemory = NdrAllocate(pStubMsg, size);
1578 memcpy(*ppMemory, pStubMsg->Buffer, size);
1580 if (!pStubMsg->IsClient && !*ppMemory)
1581 /* for servers, we just point straight into the RPC buffer */
1582 *ppMemory = pStubMsg->Buffer;
1584 /* for clients, memory should be provided by caller */
1585 memcpy(*ppMemory, pStubMsg->Buffer, size);
1588 pStubMsg->BufferMark = pStubMsg->Buffer;
1589 pStubMsg->Buffer += size;
1591 if (pFormat[0] != RPC_FC_STRUCT)
1592 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat+4, fMustAlloc);
1597 /***********************************************************************
1598 * NdrSimpleStructBufferSize [RPCRT4.@]
1600 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1601 unsigned char *pMemory,
1602 PFORMAT_STRING pFormat)
1604 unsigned size = *(const WORD*)(pFormat+2);
1605 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1607 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1609 pStubMsg->BufferLength += size;
1610 if (pFormat[0] != RPC_FC_STRUCT)
1611 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1614 /***********************************************************************
1615 * NdrSimpleStructMemorySize [RPCRT4.@]
1617 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1618 PFORMAT_STRING pFormat)
1620 unsigned short size = *(const WORD *)(pFormat+2);
1622 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1624 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1625 pStubMsg->MemorySize += size;
1626 pStubMsg->Buffer += size;
1628 if (pFormat[0] != RPC_FC_STRUCT)
1629 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1633 /***********************************************************************
1634 * NdrSimpleStructFree [RPCRT4.@]
1636 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1637 unsigned char *pMemory,
1638 PFORMAT_STRING pFormat)
1640 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1641 if (pFormat[0] != RPC_FC_STRUCT)
1642 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1646 static unsigned long EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg,
1647 PFORMAT_STRING pFormat)
1651 case RPC_FC_PSTRUCT:
1652 case RPC_FC_CSTRUCT:
1653 case RPC_FC_BOGUS_STRUCT:
1654 case RPC_FC_SMFARRAY:
1655 case RPC_FC_SMVARRAY:
1656 return *(const WORD*)&pFormat[2];
1657 case RPC_FC_USER_MARSHAL:
1658 return *(const WORD*)&pFormat[4];
1659 case RPC_FC_NON_ENCAPSULATED_UNION:
1661 if (pStubMsg->fHasNewCorrDesc)
1666 pFormat += *(const SHORT*)pFormat;
1667 return *(const SHORT*)pFormat;
1669 return sizeof(void *);
1671 FIXME("unhandled embedded type %02x\n", *pFormat);
1677 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1678 PFORMAT_STRING pFormat)
1680 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1684 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1688 return m(pStubMsg, pFormat);
1692 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1693 unsigned char *pMemory,
1694 PFORMAT_STRING pFormat,
1695 PFORMAT_STRING pPointer)
1697 PFORMAT_STRING desc;
1701 while (*pFormat != RPC_FC_END) {
1707 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
1708 memcpy(pStubMsg->Buffer, pMemory, 1);
1709 pStubMsg->Buffer += 1;
1715 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1716 memcpy(pStubMsg->Buffer, pMemory, 2);
1717 pStubMsg->Buffer += 2;
1723 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
1724 memcpy(pStubMsg->Buffer, pMemory, 4);
1725 pStubMsg->Buffer += 4;
1729 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1730 memcpy(pStubMsg->Buffer, pMemory, 8);
1731 pStubMsg->Buffer += 8;
1734 case RPC_FC_POINTER:
1735 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1736 NdrPointerMarshall(pStubMsg, *(unsigned char**)pMemory, pPointer);
1740 case RPC_FC_ALIGNM4:
1741 ALIGN_POINTER(pMemory, 4);
1743 case RPC_FC_ALIGNM8:
1744 ALIGN_POINTER(pMemory, 8);
1746 case RPC_FC_STRUCTPAD1:
1747 case RPC_FC_STRUCTPAD2:
1748 case RPC_FC_STRUCTPAD3:
1749 case RPC_FC_STRUCTPAD4:
1750 case RPC_FC_STRUCTPAD5:
1751 case RPC_FC_STRUCTPAD6:
1752 case RPC_FC_STRUCTPAD7:
1753 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1755 case RPC_FC_EMBEDDED_COMPLEX:
1756 pMemory += pFormat[1];
1758 desc = pFormat + *(const SHORT*)pFormat;
1759 size = EmbeddedComplexSize(pStubMsg, desc);
1760 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1761 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1762 if (m) m(pStubMsg, pMemory, desc);
1763 else FIXME("no marshaller for embedded type %02x\n", *desc);
1770 FIXME("unhandled format 0x%02x\n", *pFormat);
1778 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1779 unsigned char *pMemory,
1780 PFORMAT_STRING pFormat,
1781 PFORMAT_STRING pPointer)
1783 PFORMAT_STRING desc;
1787 while (*pFormat != RPC_FC_END) {
1793 memcpy(pMemory, pStubMsg->Buffer, 1);
1794 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
1795 pStubMsg->Buffer += 1;
1801 memcpy(pMemory, pStubMsg->Buffer, 2);
1802 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1803 pStubMsg->Buffer += 2;
1809 memcpy(pMemory, pStubMsg->Buffer, 4);
1810 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
1811 pStubMsg->Buffer += 4;
1815 memcpy(pMemory, pStubMsg->Buffer, 8);
1816 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1817 pStubMsg->Buffer += 8;
1820 case RPC_FC_POINTER:
1821 TRACE("pointer => %p\n", pMemory);
1822 NdrPointerUnmarshall(pStubMsg, (unsigned char**)pMemory, pPointer, TRUE);
1826 case RPC_FC_ALIGNM4:
1827 ALIGN_POINTER(pMemory, 4);
1829 case RPC_FC_ALIGNM8:
1830 ALIGN_POINTER(pMemory, 8);
1832 case RPC_FC_STRUCTPAD1:
1833 case RPC_FC_STRUCTPAD2:
1834 case RPC_FC_STRUCTPAD3:
1835 case RPC_FC_STRUCTPAD4:
1836 case RPC_FC_STRUCTPAD5:
1837 case RPC_FC_STRUCTPAD6:
1838 case RPC_FC_STRUCTPAD7:
1839 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1841 case RPC_FC_EMBEDDED_COMPLEX:
1842 pMemory += pFormat[1];
1844 desc = pFormat + *(const SHORT*)pFormat;
1845 size = EmbeddedComplexSize(pStubMsg, desc);
1846 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
1847 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1848 memset(pMemory, 0, size); /* just in case */
1849 if (m) m(pStubMsg, &pMemory, desc, FALSE);
1850 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
1857 FIXME("unhandled format %d\n", *pFormat);
1865 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1866 unsigned char *pMemory,
1867 PFORMAT_STRING pFormat,
1868 PFORMAT_STRING pPointer)
1870 PFORMAT_STRING desc;
1874 while (*pFormat != RPC_FC_END) {
1880 pStubMsg->BufferLength += 1;
1886 pStubMsg->BufferLength += 2;
1892 pStubMsg->BufferLength += 4;
1896 pStubMsg->BufferLength += 8;
1899 case RPC_FC_POINTER:
1900 NdrPointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
1904 case RPC_FC_ALIGNM4:
1905 ALIGN_POINTER(pMemory, 4);
1907 case RPC_FC_ALIGNM8:
1908 ALIGN_POINTER(pMemory, 8);
1910 case RPC_FC_STRUCTPAD1:
1911 case RPC_FC_STRUCTPAD2:
1912 case RPC_FC_STRUCTPAD3:
1913 case RPC_FC_STRUCTPAD4:
1914 case RPC_FC_STRUCTPAD5:
1915 case RPC_FC_STRUCTPAD6:
1916 case RPC_FC_STRUCTPAD7:
1917 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1919 case RPC_FC_EMBEDDED_COMPLEX:
1920 pMemory += pFormat[1];
1922 desc = pFormat + *(const SHORT*)pFormat;
1923 size = EmbeddedComplexSize(pStubMsg, desc);
1924 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1925 if (m) m(pStubMsg, pMemory, desc);
1926 else FIXME("no buffersizer for embedded type %02x\n", *desc);
1933 FIXME("unhandled format 0x%02x\n", *pFormat);
1941 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
1942 unsigned char *pMemory,
1943 PFORMAT_STRING pFormat,
1944 PFORMAT_STRING pPointer)
1946 PFORMAT_STRING desc;
1950 while (*pFormat != RPC_FC_END) {
1971 case RPC_FC_POINTER:
1972 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
1976 case RPC_FC_ALIGNM4:
1977 ALIGN_POINTER(pMemory, 4);
1979 case RPC_FC_ALIGNM8:
1980 ALIGN_POINTER(pMemory, 8);
1982 case RPC_FC_STRUCTPAD1:
1983 case RPC_FC_STRUCTPAD2:
1984 case RPC_FC_STRUCTPAD3:
1985 case RPC_FC_STRUCTPAD4:
1986 case RPC_FC_STRUCTPAD5:
1987 case RPC_FC_STRUCTPAD6:
1988 case RPC_FC_STRUCTPAD7:
1989 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1991 case RPC_FC_EMBEDDED_COMPLEX:
1992 pMemory += pFormat[1];
1994 desc = pFormat + *(const SHORT*)pFormat;
1995 size = EmbeddedComplexSize(pStubMsg, desc);
1996 m = NdrFreer[*desc & NDR_TABLE_MASK];
1997 if (m) m(pStubMsg, pMemory, desc);
1998 else FIXME("no freer for embedded type %02x\n", *desc);
2005 FIXME("unhandled format 0x%02x\n", *pFormat);
2013 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2014 PFORMAT_STRING pFormat)
2016 PFORMAT_STRING desc;
2017 unsigned long size = 0;
2019 while (*pFormat != RPC_FC_END) {
2026 pStubMsg->Buffer += 1;
2032 pStubMsg->Buffer += 2;
2038 pStubMsg->Buffer += 4;
2042 pStubMsg->Buffer += 8;
2044 case RPC_FC_POINTER:
2046 pStubMsg->Buffer += 4;
2048 case RPC_FC_ALIGNM4:
2049 ALIGN_LENGTH(size, 4);
2050 ALIGN_POINTER(pStubMsg->Buffer, 4);
2052 case RPC_FC_ALIGNM8:
2053 ALIGN_LENGTH(size, 8);
2054 ALIGN_POINTER(pStubMsg->Buffer, 8);
2056 case RPC_FC_STRUCTPAD1:
2057 case RPC_FC_STRUCTPAD2:
2058 case RPC_FC_STRUCTPAD3:
2059 case RPC_FC_STRUCTPAD4:
2060 case RPC_FC_STRUCTPAD5:
2061 case RPC_FC_STRUCTPAD6:
2062 case RPC_FC_STRUCTPAD7:
2063 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2065 case RPC_FC_EMBEDDED_COMPLEX:
2068 desc = pFormat + *(const SHORT*)pFormat;
2069 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2075 FIXME("unhandled format 0x%02x\n", *pFormat);
2083 /***********************************************************************
2084 * NdrComplexStructMarshall [RPCRT4.@]
2086 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2087 unsigned char *pMemory,
2088 PFORMAT_STRING pFormat)
2090 PFORMAT_STRING conf_array = NULL;
2091 PFORMAT_STRING pointer_desc = NULL;
2092 unsigned char *OldMemory = pStubMsg->Memory;
2094 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2096 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2099 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2101 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2104 pStubMsg->Memory = pMemory;
2106 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2109 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2111 pStubMsg->Memory = OldMemory;
2113 STD_OVERFLOW_CHECK(pStubMsg);
2118 /***********************************************************************
2119 * NdrComplexStructUnmarshall [RPCRT4.@]
2121 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2122 unsigned char **ppMemory,
2123 PFORMAT_STRING pFormat,
2124 unsigned char fMustAlloc)
2126 unsigned size = *(const WORD*)(pFormat+2);
2127 PFORMAT_STRING conf_array = NULL;
2128 PFORMAT_STRING pointer_desc = NULL;
2129 unsigned char *pMemory;
2131 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2133 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2135 if (fMustAlloc || !*ppMemory)
2137 *ppMemory = NdrAllocate(pStubMsg, size);
2138 memset(*ppMemory, 0, size);
2142 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2144 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2147 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2150 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2155 /***********************************************************************
2156 * NdrComplexStructBufferSize [RPCRT4.@]
2158 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2159 unsigned char *pMemory,
2160 PFORMAT_STRING pFormat)
2162 PFORMAT_STRING conf_array = NULL;
2163 PFORMAT_STRING pointer_desc = NULL;
2164 unsigned char *OldMemory = pStubMsg->Memory;
2166 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2168 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2171 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2173 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2176 pStubMsg->Memory = pMemory;
2178 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2181 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2183 pStubMsg->Memory = OldMemory;
2186 /***********************************************************************
2187 * NdrComplexStructMemorySize [RPCRT4.@]
2189 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2190 PFORMAT_STRING pFormat)
2192 unsigned size = *(const WORD*)(pFormat+2);
2193 PFORMAT_STRING conf_array = NULL;
2194 PFORMAT_STRING pointer_desc = NULL;
2196 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2198 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2201 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2203 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2206 ComplexStructMemorySize(pStubMsg, pFormat);
2209 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2214 /***********************************************************************
2215 * NdrComplexStructFree [RPCRT4.@]
2217 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2218 unsigned char *pMemory,
2219 PFORMAT_STRING pFormat)
2221 PFORMAT_STRING conf_array = NULL;
2222 PFORMAT_STRING pointer_desc = NULL;
2223 unsigned char *OldMemory = pStubMsg->Memory;
2225 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2228 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2230 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2233 pStubMsg->Memory = pMemory;
2235 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2238 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2240 pStubMsg->Memory = OldMemory;
2243 /***********************************************************************
2244 * NdrConformantArrayMarshall [RPCRT4.@]
2246 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2247 unsigned char *pMemory,
2248 PFORMAT_STRING pFormat)
2250 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2251 unsigned char alignment = pFormat[1] + 1;
2253 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2254 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2256 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2258 WriteConformance(pStubMsg);
2260 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2262 size = safe_multiply(esize, pStubMsg->MaxCount);
2263 memcpy(pStubMsg->Buffer, pMemory, size);
2264 pStubMsg->BufferMark = pStubMsg->Buffer;
2265 pStubMsg->Buffer += size;
2267 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2269 STD_OVERFLOW_CHECK(pStubMsg);
2274 /***********************************************************************
2275 * NdrConformantArrayUnmarshall [RPCRT4.@]
2277 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2278 unsigned char **ppMemory,
2279 PFORMAT_STRING pFormat,
2280 unsigned char fMustAlloc)
2282 DWORD size, esize = *(const WORD*)(pFormat+2);
2283 unsigned char alignment = pFormat[1] + 1;
2285 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2286 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2288 pFormat = ReadConformance(pStubMsg, pFormat+4);
2290 size = safe_multiply(esize, pStubMsg->MaxCount);
2292 if (fMustAlloc || !*ppMemory)
2293 *ppMemory = NdrAllocate(pStubMsg, size);
2295 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2297 memcpy(*ppMemory, pStubMsg->Buffer, size);
2299 pStubMsg->BufferMark = pStubMsg->Buffer;
2300 pStubMsg->Buffer += size;
2302 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2307 /***********************************************************************
2308 * NdrConformantArrayBufferSize [RPCRT4.@]
2310 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2311 unsigned char *pMemory,
2312 PFORMAT_STRING pFormat)
2314 DWORD size, esize = *(const WORD*)(pFormat+2);
2315 unsigned char alignment = pFormat[1] + 1;
2317 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2318 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2320 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2322 SizeConformance(pStubMsg);
2324 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2326 size = safe_multiply(esize, pStubMsg->MaxCount);
2327 /* conformance value plus array */
2328 pStubMsg->BufferLength += size;
2330 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2333 /***********************************************************************
2334 * NdrConformantArrayMemorySize [RPCRT4.@]
2336 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2337 PFORMAT_STRING pFormat)
2339 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2340 unsigned char alignment = pFormat[1] + 1;
2342 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2343 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2345 pFormat = ReadConformance(pStubMsg, pFormat+4);
2346 size = safe_multiply(esize, pStubMsg->MaxCount);
2347 pStubMsg->MemorySize += size;
2349 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2350 pStubMsg->BufferMark = pStubMsg->Buffer;
2351 pStubMsg->Buffer += size;
2353 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2355 return pStubMsg->MemorySize;
2358 /***********************************************************************
2359 * NdrConformantArrayFree [RPCRT4.@]
2361 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2362 unsigned char *pMemory,
2363 PFORMAT_STRING pFormat)
2365 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2366 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2368 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2370 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2374 /***********************************************************************
2375 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2377 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2378 unsigned char* pMemory,
2379 PFORMAT_STRING pFormat )
2382 unsigned char alignment = pFormat[1] + 1;
2383 DWORD esize = *(const WORD*)(pFormat+2);
2385 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2387 if (pFormat[0] != RPC_FC_CVARRAY)
2389 ERR("invalid format type %x\n", pFormat[0]);
2390 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2394 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2395 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2397 WriteConformance(pStubMsg);
2398 WriteVariance(pStubMsg);
2400 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2402 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2404 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
2405 pStubMsg->BufferMark = pStubMsg->Buffer;
2406 pStubMsg->Buffer += bufsize;
2408 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2410 STD_OVERFLOW_CHECK(pStubMsg);
2416 /***********************************************************************
2417 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2419 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2420 unsigned char** ppMemory,
2421 PFORMAT_STRING pFormat,
2422 unsigned char fMustAlloc )
2424 ULONG bufsize, memsize;
2425 unsigned char alignment = pFormat[1] + 1;
2426 DWORD esize = *(const WORD*)(pFormat+2);
2428 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2430 if (pFormat[0] != RPC_FC_CVARRAY)
2432 ERR("invalid format type %x\n", pFormat[0]);
2433 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2437 pFormat = ReadConformance(pStubMsg, pFormat+4);
2438 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2440 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2442 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2443 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2445 if (!*ppMemory || fMustAlloc)
2446 *ppMemory = NdrAllocate(pStubMsg, memsize);
2447 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
2448 pStubMsg->Buffer += bufsize;
2450 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2456 /***********************************************************************
2457 * NdrConformantVaryingArrayFree [RPCRT4.@]
2459 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2460 unsigned char* pMemory,
2461 PFORMAT_STRING pFormat )
2463 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2465 if (pFormat[0] != RPC_FC_CVARRAY)
2467 ERR("invalid format type %x\n", pFormat[0]);
2468 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2472 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2473 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2475 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2479 /***********************************************************************
2480 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2482 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2483 unsigned char* pMemory, PFORMAT_STRING pFormat )
2485 unsigned char alignment = pFormat[1] + 1;
2486 DWORD esize = *(const WORD*)(pFormat+2);
2488 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2490 if (pFormat[0] != RPC_FC_CVARRAY)
2492 ERR("invalid format type %x\n", pFormat[0]);
2493 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2498 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2499 /* compute length */
2500 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2502 SizeConformance(pStubMsg);
2503 SizeVariance(pStubMsg);
2505 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2507 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
2509 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2513 /***********************************************************************
2514 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2516 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2517 PFORMAT_STRING pFormat )
2524 /***********************************************************************
2525 * NdrComplexArrayMarshall [RPCRT4.@]
2527 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2528 unsigned char *pMemory,
2529 PFORMAT_STRING pFormat)
2531 ULONG i, count, def;
2532 BOOL variance_present;
2533 unsigned char alignment;
2535 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2537 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2539 ERR("invalid format type %x\n", pFormat[0]);
2540 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2544 alignment = pFormat[1] + 1;
2546 def = *(const WORD*)&pFormat[2];
2549 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2550 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2552 variance_present = IsConformanceOrVariancePresent(pFormat);
2553 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2554 TRACE("variance = %d\n", pStubMsg->ActualCount);
2556 WriteConformance(pStubMsg);
2557 if (variance_present)
2558 WriteVariance(pStubMsg);
2560 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2562 count = pStubMsg->ActualCount;
2563 for (i = 0; i < count; i++)
2564 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2566 STD_OVERFLOW_CHECK(pStubMsg);
2571 /***********************************************************************
2572 * NdrComplexArrayUnmarshall [RPCRT4.@]
2574 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2575 unsigned char **ppMemory,
2576 PFORMAT_STRING pFormat,
2577 unsigned char fMustAlloc)
2579 ULONG i, count, esize, memsize;
2580 unsigned char alignment;
2581 unsigned char *pMemory;
2582 unsigned char *Buffer;
2584 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2586 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2588 ERR("invalid format type %x\n", pFormat[0]);
2589 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2593 alignment = pFormat[1] + 1;
2597 pFormat = ReadConformance(pStubMsg, pFormat);
2598 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2600 Buffer = pStubMsg->Buffer;
2601 pStubMsg->MemorySize = 0;
2602 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2603 pStubMsg->Buffer = Buffer;
2605 /* do multiply here instead of inside if block to verify MaxCount */
2606 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2607 if (fMustAlloc || !*ppMemory)
2609 *ppMemory = NdrAllocate(pStubMsg, memsize);
2610 memset(*ppMemory, 0, memsize);
2613 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2615 pMemory = *ppMemory;
2616 count = pStubMsg->ActualCount;
2617 for (i = 0; i < count; i++)
2618 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
2623 /***********************************************************************
2624 * NdrComplexArrayBufferSize [RPCRT4.@]
2626 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2627 unsigned char *pMemory,
2628 PFORMAT_STRING pFormat)
2630 ULONG i, count, def;
2631 unsigned char alignment;
2632 BOOL variance_present;
2634 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2636 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2638 ERR("invalid format type %x\n", pFormat[0]);
2639 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2643 alignment = pFormat[1] + 1;
2645 def = *(const WORD*)&pFormat[2];
2648 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2649 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2650 SizeConformance(pStubMsg);
2652 variance_present = IsConformanceOrVariancePresent(pFormat);
2653 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2654 TRACE("variance = %d\n", pStubMsg->ActualCount);
2656 if (variance_present)
2657 SizeVariance(pStubMsg);
2659 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2661 count = pStubMsg->ActualCount;
2662 for (i = 0; i < count; i++)
2663 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
2666 /***********************************************************************
2667 * NdrComplexArrayMemorySize [RPCRT4.@]
2669 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2670 PFORMAT_STRING pFormat)
2672 ULONG i, count, esize, SavedMemorySize, MemorySize;
2673 unsigned char alignment;
2674 unsigned char *Buffer;
2676 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2678 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2680 ERR("invalid format type %x\n", pFormat[0]);
2681 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2685 alignment = pFormat[1] + 1;
2689 pFormat = ReadConformance(pStubMsg, pFormat);
2690 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2692 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2694 SavedMemorySize = pStubMsg->MemorySize;
2696 Buffer = pStubMsg->Buffer;
2697 pStubMsg->MemorySize = 0;
2698 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2699 pStubMsg->Buffer = Buffer;
2701 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
2703 count = pStubMsg->ActualCount;
2704 for (i = 0; i < count; i++)
2705 ComplexStructMemorySize(pStubMsg, pFormat);
2707 pStubMsg->MemorySize = SavedMemorySize;
2709 pStubMsg->MemorySize += MemorySize;
2713 /***********************************************************************
2714 * NdrComplexArrayFree [RPCRT4.@]
2716 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2717 unsigned char *pMemory,
2718 PFORMAT_STRING pFormat)
2720 ULONG i, count, def;
2722 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2724 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2726 ERR("invalid format type %x\n", pFormat[0]);
2727 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2731 def = *(const WORD*)&pFormat[2];
2734 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2735 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2737 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2738 TRACE("variance = %d\n", pStubMsg->ActualCount);
2740 count = pStubMsg->ActualCount;
2741 for (i = 0; i < count; i++)
2742 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2745 static ULONG UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
2747 return MAKELONG(pStubMsg->dwDestContext,
2748 pStubMsg->RpcMsg->DataRepresentation);
2751 #define USER_MARSHAL_PTR_PREFIX \
2752 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
2753 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
2755 /***********************************************************************
2756 * NdrUserMarshalMarshall [RPCRT4.@]
2758 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2759 unsigned char *pMemory,
2760 PFORMAT_STRING pFormat)
2762 unsigned flags = pFormat[1];
2763 unsigned index = *(const WORD*)&pFormat[2];
2764 ULONG uflag = UserMarshalFlags(pStubMsg);
2765 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2766 TRACE("index=%d\n", index);
2768 if (flags & USER_MARSHAL_POINTER)
2770 ALIGN_POINTER(pStubMsg->Buffer, 4);
2771 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
2772 pStubMsg->Buffer += 4;
2773 ALIGN_POINTER(pStubMsg->Buffer, 8);
2776 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2779 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
2780 &uflag, pStubMsg->Buffer, pMemory);
2782 STD_OVERFLOW_CHECK(pStubMsg);
2787 /***********************************************************************
2788 * NdrUserMarshalUnmarshall [RPCRT4.@]
2790 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2791 unsigned char **ppMemory,
2792 PFORMAT_STRING pFormat,
2793 unsigned char fMustAlloc)
2795 unsigned flags = pFormat[1];
2796 unsigned index = *(const WORD*)&pFormat[2];
2797 DWORD memsize = *(const WORD*)&pFormat[4];
2798 ULONG uflag = UserMarshalFlags(pStubMsg);
2799 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2800 TRACE("index=%d\n", index);
2802 if (flags & USER_MARSHAL_POINTER)
2804 ALIGN_POINTER(pStubMsg->Buffer, 4);
2805 /* skip pointer prefix */
2806 pStubMsg->Buffer += 4;
2807 ALIGN_POINTER(pStubMsg->Buffer, 8);
2810 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2812 if (fMustAlloc || !*ppMemory)
2813 *ppMemory = NdrAllocate(pStubMsg, memsize);
2816 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
2817 &uflag, pStubMsg->Buffer, *ppMemory);
2822 /***********************************************************************
2823 * NdrUserMarshalBufferSize [RPCRT4.@]
2825 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2826 unsigned char *pMemory,
2827 PFORMAT_STRING pFormat)
2829 unsigned flags = pFormat[1];
2830 unsigned index = *(const WORD*)&pFormat[2];
2831 DWORD bufsize = *(const WORD*)&pFormat[6];
2832 ULONG uflag = UserMarshalFlags(pStubMsg);
2833 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2834 TRACE("index=%d\n", index);
2836 if (flags & USER_MARSHAL_POINTER)
2838 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2839 /* skip pointer prefix */
2840 pStubMsg->BufferLength += 4;
2841 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
2844 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
2847 TRACE("size=%d\n", bufsize);
2848 pStubMsg->BufferLength += bufsize;
2852 pStubMsg->BufferLength =
2853 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
2854 &uflag, pStubMsg->BufferLength, pMemory);
2857 /***********************************************************************
2858 * NdrUserMarshalMemorySize [RPCRT4.@]
2860 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2861 PFORMAT_STRING pFormat)
2863 unsigned flags = pFormat[1];
2864 unsigned index = *(const WORD*)&pFormat[2];
2865 DWORD memsize = *(const WORD*)&pFormat[4];
2866 DWORD bufsize = *(const WORD*)&pFormat[6];
2868 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2869 TRACE("index=%d\n", index);
2871 pStubMsg->MemorySize += memsize;
2873 if (flags & USER_MARSHAL_POINTER)
2875 ALIGN_POINTER(pStubMsg->Buffer, 4);
2876 /* skip pointer prefix */
2877 pStubMsg->Buffer += 4;
2878 ALIGN_POINTER(pStubMsg->Buffer, 8);
2881 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2883 pStubMsg->Buffer += bufsize;
2885 return pStubMsg->MemorySize;
2888 /***********************************************************************
2889 * NdrUserMarshalFree [RPCRT4.@]
2891 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
2892 unsigned char *pMemory,
2893 PFORMAT_STRING pFormat)
2895 /* unsigned flags = pFormat[1]; */
2896 unsigned index = *(const WORD*)&pFormat[2];
2897 ULONG uflag = UserMarshalFlags(pStubMsg);
2898 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2899 TRACE("index=%d\n", index);
2901 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
2905 /***********************************************************************
2906 * NdrClearOutParameters [RPCRT4.@]
2908 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
2909 PFORMAT_STRING pFormat,
2912 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
2915 /***********************************************************************
2916 * NdrConvert [RPCRT4.@]
2918 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
2920 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
2921 /* FIXME: since this stub doesn't do any converting, the proper behavior
2922 is to raise an exception */
2925 /***********************************************************************
2926 * NdrConvert2 [RPCRT4.@]
2928 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
2930 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
2931 pStubMsg, pFormat, NumberParams);
2932 /* FIXME: since this stub doesn't do any converting, the proper behavior
2933 is to raise an exception */
2936 #include "pshpack1.h"
2937 typedef struct _NDR_CSTRUCT_FORMAT
2940 unsigned char alignment;
2941 unsigned short memory_size;
2942 short offset_to_array_description;
2943 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
2944 #include "poppack.h"
2946 /***********************************************************************
2947 * NdrConformantStructMarshall [RPCRT4.@]
2949 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2950 unsigned char *pMemory,
2951 PFORMAT_STRING pFormat)
2953 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
2954 PFORMAT_STRING pCArrayFormat;
2955 ULONG esize, bufsize;
2957 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2959 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2960 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2962 ERR("invalid format type %x\n", pCStructFormat->type);
2963 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2967 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
2968 pCStructFormat->offset_to_array_description;
2969 if (*pCArrayFormat != RPC_FC_CARRAY)
2971 ERR("invalid array format type %x\n", pCStructFormat->type);
2972 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2975 esize = *(const WORD*)(pCArrayFormat+2);
2977 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
2978 pCArrayFormat + 4, 0);
2980 WriteConformance(pStubMsg);
2982 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
2984 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2986 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
2987 /* copy constant sized part of struct */
2988 pStubMsg->BufferMark = pStubMsg->Buffer;
2989 memcpy(pStubMsg->Buffer, pMemory, pCStructFormat->memory_size + bufsize);
2990 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
2992 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2993 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2995 STD_OVERFLOW_CHECK(pStubMsg);
3000 /***********************************************************************
3001 * NdrConformantStructUnmarshall [RPCRT4.@]
3003 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3004 unsigned char **ppMemory,
3005 PFORMAT_STRING pFormat,
3006 unsigned char fMustAlloc)
3008 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3009 PFORMAT_STRING pCArrayFormat;
3010 ULONG esize, bufsize;
3012 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3014 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3015 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3017 ERR("invalid format type %x\n", pCStructFormat->type);
3018 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3021 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3022 pCStructFormat->offset_to_array_description;
3023 if (*pCArrayFormat != RPC_FC_CARRAY)
3025 ERR("invalid array format type %x\n", pCStructFormat->type);
3026 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3029 esize = *(const WORD*)(pCArrayFormat+2);
3031 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3033 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3035 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3037 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3038 /* work out how much memory to allocate if we need to do so */
3039 if (!*ppMemory || fMustAlloc)
3041 SIZE_T size = pCStructFormat->memory_size + bufsize;
3042 *ppMemory = NdrAllocate(pStubMsg, size);
3045 /* now copy the data */
3046 pStubMsg->BufferMark = pStubMsg->Buffer;
3047 memcpy(*ppMemory, pStubMsg->Buffer, pCStructFormat->memory_size + bufsize);
3048 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
3050 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3051 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3056 /***********************************************************************
3057 * NdrConformantStructBufferSize [RPCRT4.@]
3059 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3060 unsigned char *pMemory,
3061 PFORMAT_STRING pFormat)
3063 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3064 PFORMAT_STRING pCArrayFormat;
3067 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3069 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3070 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3072 ERR("invalid format type %x\n", pCStructFormat->type);
3073 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3076 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3077 pCStructFormat->offset_to_array_description;
3078 if (*pCArrayFormat != RPC_FC_CARRAY)
3080 ERR("invalid array format type %x\n", pCStructFormat->type);
3081 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3084 esize = *(const WORD*)(pCArrayFormat+2);
3086 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
3087 SizeConformance(pStubMsg);
3089 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
3091 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3093 pStubMsg->BufferLength += pCStructFormat->memory_size +
3094 safe_multiply(pStubMsg->MaxCount, esize);
3096 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3097 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3100 /***********************************************************************
3101 * NdrConformantStructMemorySize [RPCRT4.@]
3103 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3104 PFORMAT_STRING pFormat)
3110 /***********************************************************************
3111 * NdrConformantStructFree [RPCRT4.@]
3113 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3114 unsigned char *pMemory,
3115 PFORMAT_STRING pFormat)
3120 /***********************************************************************
3121 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3123 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3124 unsigned char *pMemory,
3125 PFORMAT_STRING pFormat)
3127 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3128 PFORMAT_STRING pCVArrayFormat;
3129 ULONG esize, bufsize;
3131 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3133 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3134 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3136 ERR("invalid format type %x\n", pCVStructFormat->type);
3137 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3141 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3142 pCVStructFormat->offset_to_array_description;
3143 switch (*pCVArrayFormat)
3145 case RPC_FC_CVARRAY:
3146 esize = *(const WORD*)(pCVArrayFormat+2);
3148 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3149 pCVArrayFormat + 4, 0);
3150 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3153 case RPC_FC_C_CSTRING:
3154 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3155 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3156 esize = sizeof(char);
3157 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3158 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3159 pCVArrayFormat + 2, 0);
3161 pStubMsg->MaxCount = pStubMsg->ActualCount;
3163 case RPC_FC_C_WSTRING:
3164 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3165 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3166 esize = sizeof(WCHAR);
3167 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3168 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3169 pCVArrayFormat + 2, 0);
3171 pStubMsg->MaxCount = pStubMsg->ActualCount;
3174 ERR("invalid array format type %x\n", *pCVArrayFormat);
3175 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3179 WriteConformance(pStubMsg);
3181 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3183 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3185 /* write constant sized part */
3186 pStubMsg->BufferMark = pStubMsg->Buffer;
3187 memcpy(pStubMsg->Buffer, pMemory, pCVStructFormat->memory_size);
3188 pStubMsg->Buffer += pCVStructFormat->memory_size;
3190 WriteVariance(pStubMsg);
3192 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3194 /* write array part */
3195 memcpy(pStubMsg->Buffer, pMemory + pCVStructFormat->memory_size, bufsize);
3196 pStubMsg->Buffer += bufsize;
3198 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3200 STD_OVERFLOW_CHECK(pStubMsg);
3205 /***********************************************************************
3206 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3208 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3209 unsigned char **ppMemory,
3210 PFORMAT_STRING pFormat,
3211 unsigned char fMustAlloc)
3213 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3214 PFORMAT_STRING pCVArrayFormat;
3215 ULONG esize, bufsize;
3216 unsigned char cvarray_type;
3218 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3220 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3221 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3223 ERR("invalid format type %x\n", pCVStructFormat->type);
3224 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3228 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3229 pCVStructFormat->offset_to_array_description;
3230 cvarray_type = *pCVArrayFormat;
3231 switch (cvarray_type)
3233 case RPC_FC_CVARRAY:
3234 esize = *(const WORD*)(pCVArrayFormat+2);
3235 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3237 case RPC_FC_C_CSTRING:
3238 esize = sizeof(char);
3239 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3240 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3242 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3244 case RPC_FC_C_WSTRING:
3245 esize = sizeof(WCHAR);
3246 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3247 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3249 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3252 ERR("invalid array format type %x\n", *pCVArrayFormat);
3253 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3257 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3259 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3261 /* work out how much memory to allocate if we need to do so */
3262 if (!*ppMemory || fMustAlloc)
3264 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3265 *ppMemory = NdrAllocate(pStubMsg, size);
3268 /* copy the constant data */
3269 pStubMsg->BufferMark = pStubMsg->Buffer;
3270 memcpy(*ppMemory, pStubMsg->Buffer, pCVStructFormat->memory_size);
3271 pStubMsg->Buffer += pCVStructFormat->memory_size;
3273 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3275 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3277 if ((cvarray_type == RPC_FC_C_CSTRING) ||
3278 (cvarray_type == RPC_FC_C_WSTRING))
3281 /* strings must always have null terminating bytes */
3282 if (bufsize < esize)
3284 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
3285 RpcRaiseException(RPC_S_INVALID_BOUND);
3288 for (i = bufsize - esize; i < bufsize; i++)
3289 if (pStubMsg->Buffer[i] != 0)
3291 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3292 i, pStubMsg->Buffer[i]);
3293 RpcRaiseException(RPC_S_INVALID_BOUND);
3298 /* copy the array data */
3299 memcpy(*ppMemory + pCVStructFormat->memory_size, pStubMsg->Buffer,
3301 pStubMsg->Buffer += bufsize;
3303 if (cvarray_type == RPC_FC_C_CSTRING)
3304 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3305 else if (cvarray_type == RPC_FC_C_WSTRING)
3306 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3308 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3313 /***********************************************************************
3314 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3316 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3317 unsigned char *pMemory,
3318 PFORMAT_STRING pFormat)
3320 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3321 PFORMAT_STRING pCVArrayFormat;
3324 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3326 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3327 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3329 ERR("invalid format type %x\n", pCVStructFormat->type);
3330 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3334 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3335 pCVStructFormat->offset_to_array_description;
3336 switch (*pCVArrayFormat)
3338 case RPC_FC_CVARRAY:
3339 esize = *(const WORD*)(pCVArrayFormat+2);
3341 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3342 pCVArrayFormat + 4, 0);
3343 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3346 case RPC_FC_C_CSTRING:
3347 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3348 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3349 esize = sizeof(char);
3350 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3351 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3352 pCVArrayFormat + 2, 0);
3354 pStubMsg->MaxCount = pStubMsg->ActualCount;
3356 case RPC_FC_C_WSTRING:
3357 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3358 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3359 esize = sizeof(WCHAR);
3360 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3361 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3362 pCVArrayFormat + 2, 0);
3364 pStubMsg->MaxCount = pStubMsg->ActualCount;
3367 ERR("invalid array format type %x\n", *pCVArrayFormat);
3368 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3372 SizeConformance(pStubMsg);
3374 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
3376 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3378 pStubMsg->BufferLength += pCVStructFormat->memory_size;
3379 SizeVariance(pStubMsg);
3380 pStubMsg->BufferLength += safe_multiply(pStubMsg->MaxCount, esize);
3382 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3385 /***********************************************************************
3386 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3388 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3389 PFORMAT_STRING pFormat)
3391 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3392 PFORMAT_STRING pCVArrayFormat;
3394 unsigned char cvarray_type;
3396 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3398 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3399 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3401 ERR("invalid format type %x\n", pCVStructFormat->type);
3402 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3406 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3407 pCVStructFormat->offset_to_array_description;
3408 cvarray_type = *pCVArrayFormat;
3409 switch (cvarray_type)
3411 case RPC_FC_CVARRAY:
3412 esize = *(const WORD*)(pCVArrayFormat+2);
3413 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3415 case RPC_FC_C_CSTRING:
3416 esize = sizeof(char);
3417 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3418 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3420 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3422 case RPC_FC_C_WSTRING:
3423 esize = sizeof(WCHAR);
3424 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3425 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3427 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3430 ERR("invalid array format type %x\n", *pCVArrayFormat);
3431 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3435 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3437 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3439 pStubMsg->Buffer += pCVStructFormat->memory_size;
3440 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3441 pStubMsg->Buffer += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->ActualCount);
3443 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3445 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3447 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3450 /***********************************************************************
3451 * NdrConformantVaryingStructFree [RPCRT4.@]
3453 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3454 unsigned char *pMemory,
3455 PFORMAT_STRING pFormat)
3457 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3458 PFORMAT_STRING pCVArrayFormat;
3461 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3463 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3464 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3466 ERR("invalid format type %x\n", pCVStructFormat->type);
3467 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3471 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3472 pCVStructFormat->offset_to_array_description;
3473 switch (*pCVArrayFormat)
3475 case RPC_FC_CVARRAY:
3476 esize = *(const WORD*)(pCVArrayFormat+2);
3478 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3479 pCVArrayFormat + 4, 0);
3480 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3483 case RPC_FC_C_CSTRING:
3484 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3485 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3486 esize = sizeof(char);
3487 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3488 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3489 pCVArrayFormat + 2, 0);
3491 pStubMsg->MaxCount = pStubMsg->ActualCount;
3493 case RPC_FC_C_WSTRING:
3494 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3495 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3496 esize = sizeof(WCHAR);
3497 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3498 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3499 pCVArrayFormat + 2, 0);
3501 pStubMsg->MaxCount = pStubMsg->ActualCount;
3504 ERR("invalid array format type %x\n", *pCVArrayFormat);
3505 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3509 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3511 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3514 #include "pshpack1.h"
3518 unsigned char alignment;
3519 unsigned short total_size;
3520 } NDR_SMFARRAY_FORMAT;
3525 unsigned char alignment;
3526 unsigned long total_size;
3527 } NDR_LGFARRAY_FORMAT;
3528 #include "poppack.h"
3530 /***********************************************************************
3531 * NdrFixedArrayMarshall [RPCRT4.@]
3533 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3534 unsigned char *pMemory,
3535 PFORMAT_STRING pFormat)
3537 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3538 unsigned long total_size;
3540 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3542 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3543 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3545 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3546 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3550 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3552 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3554 total_size = pSmFArrayFormat->total_size;
3555 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3559 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3560 total_size = pLgFArrayFormat->total_size;
3561 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3564 memcpy(pStubMsg->Buffer, pMemory, total_size);
3565 pStubMsg->BufferMark = pStubMsg->Buffer;
3566 pStubMsg->Buffer += total_size;
3568 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3573 /***********************************************************************
3574 * NdrFixedArrayUnmarshall [RPCRT4.@]
3576 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3577 unsigned char **ppMemory,
3578 PFORMAT_STRING pFormat,
3579 unsigned char fMustAlloc)
3581 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3582 unsigned long total_size;
3584 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3586 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3587 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3589 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3590 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3594 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3596 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3598 total_size = pSmFArrayFormat->total_size;
3599 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3603 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3604 total_size = pLgFArrayFormat->total_size;
3605 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3608 if (fMustAlloc || !*ppMemory)
3609 *ppMemory = NdrAllocate(pStubMsg, total_size);
3610 memcpy(*ppMemory, pStubMsg->Buffer, total_size);
3611 pStubMsg->BufferMark = pStubMsg->Buffer;
3612 pStubMsg->Buffer += total_size;
3614 pFormat = EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3619 /***********************************************************************
3620 * NdrFixedArrayBufferSize [RPCRT4.@]
3622 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3623 unsigned char *pMemory,
3624 PFORMAT_STRING pFormat)
3626 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3627 unsigned long total_size;
3629 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3631 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3632 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3634 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3635 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3639 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
3641 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3643 total_size = pSmFArrayFormat->total_size;
3644 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3648 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3649 total_size = pLgFArrayFormat->total_size;
3650 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3652 pStubMsg->BufferLength += total_size;
3654 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3657 /***********************************************************************
3658 * NdrFixedArrayMemorySize [RPCRT4.@]
3660 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3661 PFORMAT_STRING pFormat)
3663 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3666 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3668 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3669 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3671 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3672 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3676 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3678 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3680 total_size = pSmFArrayFormat->total_size;
3681 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3685 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3686 total_size = pLgFArrayFormat->total_size;
3687 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3689 pStubMsg->BufferMark = pStubMsg->Buffer;
3690 pStubMsg->Buffer += total_size;
3691 pStubMsg->MemorySize += total_size;
3693 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3698 /***********************************************************************
3699 * NdrFixedArrayFree [RPCRT4.@]
3701 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3702 unsigned char *pMemory,
3703 PFORMAT_STRING pFormat)
3705 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3707 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3709 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3710 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3712 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3713 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3717 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3718 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3721 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3722 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3725 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3728 /***********************************************************************
3729 * NdrVaryingArrayMarshall [RPCRT4.@]
3731 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3732 unsigned char *pMemory,
3733 PFORMAT_STRING pFormat)
3735 unsigned char alignment;
3736 DWORD elements, esize;
3739 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3741 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3742 (pFormat[0] != RPC_FC_LGVARRAY))
3744 ERR("invalid format type %x\n", pFormat[0]);
3745 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3749 alignment = pFormat[1] + 1;
3751 if (pFormat[0] == RPC_FC_SMVARRAY)
3754 pFormat += sizeof(WORD);
3755 elements = *(const WORD*)pFormat;
3756 pFormat += sizeof(WORD);
3761 pFormat += sizeof(DWORD);
3762 elements = *(const DWORD*)pFormat;
3763 pFormat += sizeof(DWORD);
3766 esize = *(const WORD*)pFormat;
3767 pFormat += sizeof(WORD);
3769 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3770 if ((pStubMsg->ActualCount > elements) ||
3771 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3773 RpcRaiseException(RPC_S_INVALID_BOUND);
3777 WriteVariance(pStubMsg);
3779 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3781 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3782 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
3783 pStubMsg->BufferMark = pStubMsg->Buffer;
3784 pStubMsg->Buffer += bufsize;
3786 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3788 STD_OVERFLOW_CHECK(pStubMsg);
3793 /***********************************************************************
3794 * NdrVaryingArrayUnmarshall [RPCRT4.@]
3796 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3797 unsigned char **ppMemory,
3798 PFORMAT_STRING pFormat,
3799 unsigned char fMustAlloc)
3801 unsigned char alignment;
3802 DWORD size, elements, esize;
3805 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3807 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3808 (pFormat[0] != RPC_FC_LGVARRAY))
3810 ERR("invalid format type %x\n", pFormat[0]);
3811 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3815 alignment = pFormat[1] + 1;
3817 if (pFormat[0] == RPC_FC_SMVARRAY)
3820 size = *(const WORD*)pFormat;
3821 pFormat += sizeof(WORD);
3822 elements = *(const WORD*)pFormat;
3823 pFormat += sizeof(WORD);
3828 size = *(const DWORD*)pFormat;
3829 pFormat += sizeof(DWORD);
3830 elements = *(const DWORD*)pFormat;
3831 pFormat += sizeof(DWORD);
3834 esize = *(const WORD*)pFormat;
3835 pFormat += sizeof(WORD);
3837 pFormat = ReadVariance(pStubMsg, pFormat, elements);
3839 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3841 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3843 if (!*ppMemory || fMustAlloc)
3844 *ppMemory = NdrAllocate(pStubMsg, size);
3845 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
3846 pStubMsg->Buffer += bufsize;
3848 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3853 /***********************************************************************
3854 * NdrVaryingArrayBufferSize [RPCRT4.@]
3856 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3857 unsigned char *pMemory,
3858 PFORMAT_STRING pFormat)
3860 unsigned char alignment;
3861 DWORD elements, esize;
3863 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3865 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3866 (pFormat[0] != RPC_FC_LGVARRAY))
3868 ERR("invalid format type %x\n", pFormat[0]);
3869 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3873 alignment = pFormat[1] + 1;
3875 if (pFormat[0] == RPC_FC_SMVARRAY)
3878 pFormat += sizeof(WORD);
3879 elements = *(const WORD*)pFormat;
3880 pFormat += sizeof(WORD);
3885 pFormat += sizeof(DWORD);
3886 elements = *(const DWORD*)pFormat;
3887 pFormat += sizeof(DWORD);
3890 esize = *(const WORD*)pFormat;
3891 pFormat += sizeof(WORD);
3893 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3894 if ((pStubMsg->ActualCount > elements) ||
3895 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3897 RpcRaiseException(RPC_S_INVALID_BOUND);
3901 SizeVariance(pStubMsg);
3903 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3905 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
3907 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3910 /***********************************************************************
3911 * NdrVaryingArrayMemorySize [RPCRT4.@]
3913 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3914 PFORMAT_STRING pFormat)
3916 unsigned char alignment;
3917 DWORD size, elements, esize;
3919 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3921 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3922 (pFormat[0] != RPC_FC_LGVARRAY))
3924 ERR("invalid format type %x\n", pFormat[0]);
3925 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3929 alignment = pFormat[1] + 1;
3931 if (pFormat[0] == RPC_FC_SMVARRAY)
3934 size = *(const WORD*)pFormat;
3935 pFormat += sizeof(WORD);
3936 elements = *(const WORD*)pFormat;
3937 pFormat += sizeof(WORD);
3942 size = *(const DWORD*)pFormat;
3943 pFormat += sizeof(DWORD);
3944 elements = *(const DWORD*)pFormat;
3945 pFormat += sizeof(DWORD);
3948 esize = *(const WORD*)pFormat;
3949 pFormat += sizeof(WORD);
3951 pFormat = ReadVariance(pStubMsg, pFormat, elements);
3953 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3955 pStubMsg->Buffer += safe_multiply(esize, pStubMsg->ActualCount);
3956 pStubMsg->MemorySize += size;
3958 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3960 return pStubMsg->MemorySize;
3963 /***********************************************************************
3964 * NdrVaryingArrayFree [RPCRT4.@]
3966 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3967 unsigned char *pMemory,
3968 PFORMAT_STRING pFormat)
3970 unsigned char alignment;
3973 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3975 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3976 (pFormat[0] != RPC_FC_LGVARRAY))
3978 ERR("invalid format type %x\n", pFormat[0]);
3979 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3983 alignment = pFormat[1] + 1;
3985 if (pFormat[0] == RPC_FC_SMVARRAY)
3988 pFormat += sizeof(WORD);
3989 elements = *(const WORD*)pFormat;
3990 pFormat += sizeof(WORD);
3995 pFormat += sizeof(DWORD);
3996 elements = *(const DWORD*)pFormat;
3997 pFormat += sizeof(DWORD);
4000 pFormat += sizeof(WORD);
4002 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4003 if ((pStubMsg->ActualCount > elements) ||
4004 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4006 RpcRaiseException(RPC_S_INVALID_BOUND);
4010 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4013 static ULONG get_discriminant(unsigned char fc, unsigned char *pMemory)
4021 return *(UCHAR *)pMemory;
4025 return *(USHORT *)pMemory;
4028 return *(ULONG *)pMemory;
4030 FIXME("Unhandled base type: 0x%02x\n", fc);
4035 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4036 unsigned long discriminant,
4037 PFORMAT_STRING pFormat)
4039 unsigned short num_arms, arm, type;
4041 num_arms = *(const SHORT*)pFormat & 0x0fff;
4043 for(arm = 0; arm < num_arms; arm++)
4045 if(discriminant == *(const ULONG*)pFormat)
4053 type = *(const unsigned short*)pFormat;
4054 TRACE("type %04x\n", type);
4055 if(arm == num_arms) /* default arm extras */
4059 ERR("no arm for 0x%lx and no default case\n", discriminant);
4060 RpcRaiseException(RPC_S_INVALID_TAG);
4065 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
4072 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
4074 unsigned short type;
4078 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4082 type = *(const unsigned short*)pFormat;
4083 if((type & 0xff00) == 0x8000)
4085 unsigned char basetype = LOBYTE(type);
4086 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
4090 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4091 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
4094 unsigned char *saved_buffer = NULL;
4101 saved_buffer = pStubMsg->Buffer;
4102 pStubMsg->Buffer += 4; /* for pointer ID */
4103 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
4106 m(pStubMsg, pMemory, desc);
4109 else FIXME("no marshaller for embedded type %02x\n", *desc);
4114 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4115 unsigned char **ppMemory,
4117 PFORMAT_STRING pFormat,
4118 unsigned char fMustAlloc)
4120 unsigned short type;
4124 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4128 type = *(const unsigned short*)pFormat;
4129 if((type & 0xff00) == 0x8000)
4131 unsigned char basetype = LOBYTE(type);
4132 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, fMustAlloc);
4136 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4137 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
4140 unsigned char *saved_buffer = NULL;
4147 ALIGN_POINTER(pStubMsg->Buffer, 4);
4148 saved_buffer = pStubMsg->Buffer;
4149 pStubMsg->Buffer += 4; /* for pointer ID */
4150 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, desc, TRUE);
4153 m(pStubMsg, ppMemory, desc, fMustAlloc);
4156 else FIXME("no marshaller for embedded type %02x\n", *desc);
4161 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
4162 unsigned char *pMemory,
4164 PFORMAT_STRING pFormat)
4166 unsigned short type;
4170 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4174 type = *(const unsigned short*)pFormat;
4175 if((type & 0xff00) == 0x8000)
4177 unsigned char basetype = LOBYTE(type);
4178 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
4182 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4183 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
4192 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4193 pStubMsg->BufferLength += 4; /* for pointer ID */
4194 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
4197 m(pStubMsg, pMemory, desc);
4200 else FIXME("no buffersizer for embedded type %02x\n", *desc);
4204 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
4206 PFORMAT_STRING pFormat)
4208 unsigned short type, size;
4210 size = *(const unsigned short*)pFormat;
4211 pStubMsg->Memory += size;
4214 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4218 type = *(const unsigned short*)pFormat;
4219 if((type & 0xff00) == 0x8000)
4221 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
4225 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4226 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
4227 unsigned char *saved_buffer;
4236 ALIGN_POINTER(pStubMsg->Buffer, 4);
4237 saved_buffer = pStubMsg->Buffer;
4238 pStubMsg->Buffer += 4;
4239 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
4240 pStubMsg->MemorySize += 4;
4241 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
4244 return m(pStubMsg, desc);
4247 else FIXME("no marshaller for embedded type %02x\n", *desc);
4250 TRACE("size %d\n", size);
4254 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
4255 unsigned char *pMemory,
4257 PFORMAT_STRING pFormat)
4259 unsigned short type;
4263 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4267 type = *(const unsigned short*)pFormat;
4268 if((type & 0xff00) != 0x8000)
4270 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4271 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
4280 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
4283 m(pStubMsg, pMemory, desc);
4286 else FIXME("no freer for embedded type %02x\n", *desc);
4290 /***********************************************************************
4291 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4293 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4294 unsigned char *pMemory,
4295 PFORMAT_STRING pFormat)
4297 unsigned char switch_type;
4298 unsigned char increment;
4301 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4304 switch_type = *pFormat & 0xf;
4305 increment = (*pFormat & 0xf0) >> 4;
4308 ALIGN_POINTER(pStubMsg->Buffer, increment);
4310 switch_value = get_discriminant(switch_type, pMemory);
4311 TRACE("got switch value 0x%x\n", switch_value);
4313 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
4314 pMemory += increment;
4316 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
4319 /***********************************************************************
4320 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4322 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4323 unsigned char **ppMemory,
4324 PFORMAT_STRING pFormat,
4325 unsigned char fMustAlloc)
4327 unsigned char switch_type;
4328 unsigned char increment;
4330 unsigned short size;
4331 unsigned char *pMemoryArm;
4333 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4336 switch_type = *pFormat & 0xf;
4337 increment = (*pFormat & 0xf0) >> 4;
4340 ALIGN_POINTER(pStubMsg->Buffer, increment);
4341 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
4342 TRACE("got switch value 0x%x\n", switch_value);
4344 size = *(const unsigned short*)pFormat + increment;
4345 if(!*ppMemory || fMustAlloc)
4346 *ppMemory = NdrAllocate(pStubMsg, size);
4348 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
4349 pMemoryArm = *ppMemory + increment;
4351 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
4354 /***********************************************************************
4355 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4357 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4358 unsigned char *pMemory,
4359 PFORMAT_STRING pFormat)
4361 unsigned char switch_type;
4362 unsigned char increment;
4365 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4368 switch_type = *pFormat & 0xf;
4369 increment = (*pFormat & 0xf0) >> 4;
4372 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
4373 switch_value = get_discriminant(switch_type, pMemory);
4374 TRACE("got switch value 0x%x\n", switch_value);
4376 /* Add discriminant size */
4377 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
4378 pMemory += increment;
4380 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
4383 /***********************************************************************
4384 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4386 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4387 PFORMAT_STRING pFormat)
4389 unsigned char switch_type;
4390 unsigned char increment;
4393 switch_type = *pFormat & 0xf;
4394 increment = (*pFormat & 0xf0) >> 4;
4397 ALIGN_POINTER(pStubMsg->Buffer, increment);
4398 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
4399 TRACE("got switch value 0x%x\n", switch_value);
4401 pStubMsg->Memory += increment;
4403 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
4406 /***********************************************************************
4407 * NdrEncapsulatedUnionFree [RPCRT4.@]
4409 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4410 unsigned char *pMemory,
4411 PFORMAT_STRING pFormat)
4413 unsigned char switch_type;
4414 unsigned char increment;
4417 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4420 switch_type = *pFormat & 0xf;
4421 increment = (*pFormat & 0xf0) >> 4;
4424 switch_value = get_discriminant(switch_type, pMemory);
4425 TRACE("got switch value 0x%x\n", switch_value);
4427 pMemory += increment;
4429 return union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
4432 /***********************************************************************
4433 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
4435 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4436 unsigned char *pMemory,
4437 PFORMAT_STRING pFormat)
4439 unsigned char switch_type;
4441 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4444 switch_type = *pFormat;
4447 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4448 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4449 /* Marshall discriminant */
4450 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4452 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
4455 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
4456 PFORMAT_STRING *ppFormat)
4458 long discriminant = 0;
4466 discriminant = *(UCHAR *)pStubMsg->Buffer;
4467 pStubMsg->Buffer += sizeof(UCHAR);
4472 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4473 discriminant = *(USHORT *)pStubMsg->Buffer;
4474 pStubMsg->Buffer += sizeof(USHORT);
4478 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4479 discriminant = *(ULONG *)pStubMsg->Buffer;
4480 pStubMsg->Buffer += sizeof(ULONG);
4483 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
4487 if (pStubMsg->fHasNewCorrDesc)
4491 return discriminant;
4494 /**********************************************************************
4495 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
4497 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4498 unsigned char **ppMemory,
4499 PFORMAT_STRING pFormat,
4500 unsigned char fMustAlloc)
4503 unsigned short size;
4505 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4508 /* Unmarshall discriminant */
4509 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4510 TRACE("unmarshalled discriminant %lx\n", discriminant);
4512 pFormat += *(const SHORT*)pFormat;
4514 size = *(const unsigned short*)pFormat;
4516 if(!*ppMemory || fMustAlloc)
4517 *ppMemory = NdrAllocate(pStubMsg, size);
4519 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
4522 /***********************************************************************
4523 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
4525 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4526 unsigned char *pMemory,
4527 PFORMAT_STRING pFormat)
4529 unsigned char switch_type;
4531 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4534 switch_type = *pFormat;
4537 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4538 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4539 /* Add discriminant size */
4540 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4542 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
4545 /***********************************************************************
4546 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
4548 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4549 PFORMAT_STRING pFormat)
4554 /* Unmarshall discriminant */
4555 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4556 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
4558 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
4561 /***********************************************************************
4562 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
4564 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4565 unsigned char *pMemory,
4566 PFORMAT_STRING pFormat)
4568 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4572 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4573 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4575 return union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
4578 /***********************************************************************
4579 * NdrByteCountPointerMarshall [RPCRT4.@]
4581 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4582 unsigned char *pMemory,
4583 PFORMAT_STRING pFormat)
4589 /***********************************************************************
4590 * NdrByteCountPointerUnmarshall [RPCRT4.@]
4592 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4593 unsigned char **ppMemory,
4594 PFORMAT_STRING pFormat,
4595 unsigned char fMustAlloc)
4601 /***********************************************************************
4602 * NdrByteCountPointerBufferSize [RPCRT4.@]
4604 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4605 unsigned char *pMemory,
4606 PFORMAT_STRING pFormat)
4611 /***********************************************************************
4612 * NdrByteCountPointerMemorySize [RPCRT4.@]
4614 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4615 PFORMAT_STRING pFormat)
4621 /***********************************************************************
4622 * NdrByteCountPointerFree [RPCRT4.@]
4624 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
4625 unsigned char *pMemory,
4626 PFORMAT_STRING pFormat)
4631 /***********************************************************************
4632 * NdrXmitOrRepAsMarshall [RPCRT4.@]
4634 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4635 unsigned char *pMemory,
4636 PFORMAT_STRING pFormat)
4642 /***********************************************************************
4643 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
4645 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4646 unsigned char **ppMemory,
4647 PFORMAT_STRING pFormat,
4648 unsigned char fMustAlloc)
4654 /***********************************************************************
4655 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
4657 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4658 unsigned char *pMemory,
4659 PFORMAT_STRING pFormat)
4664 /***********************************************************************
4665 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
4667 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4668 PFORMAT_STRING pFormat)
4674 /***********************************************************************
4675 * NdrXmitOrRepAsFree [RPCRT4.@]
4677 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
4678 unsigned char *pMemory,
4679 PFORMAT_STRING pFormat)
4684 /***********************************************************************
4685 * NdrBaseTypeMarshall [internal]
4687 static unsigned char *WINAPI NdrBaseTypeMarshall(
4688 PMIDL_STUB_MESSAGE pStubMsg,
4689 unsigned char *pMemory,
4690 PFORMAT_STRING pFormat)
4692 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4700 *(UCHAR *)pStubMsg->Buffer = *(UCHAR *)pMemory;
4701 pStubMsg->Buffer += sizeof(UCHAR);
4702 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
4707 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4708 *(USHORT *)pStubMsg->Buffer = *(USHORT *)pMemory;
4709 pStubMsg->Buffer += sizeof(USHORT);
4710 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
4714 case RPC_FC_ERROR_STATUS_T:
4716 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4717 *(ULONG *)pStubMsg->Buffer = *(ULONG *)pMemory;
4718 pStubMsg->Buffer += sizeof(ULONG);
4719 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
4722 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
4723 *(float *)pStubMsg->Buffer = *(float *)pMemory;
4724 pStubMsg->Buffer += sizeof(float);
4727 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
4728 *(double *)pStubMsg->Buffer = *(double *)pMemory;
4729 pStubMsg->Buffer += sizeof(double);
4732 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
4733 *(ULONGLONG *)pStubMsg->Buffer = *(ULONGLONG *)pMemory;
4734 pStubMsg->Buffer += sizeof(ULONGLONG);
4735 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
4738 /* only 16-bits on the wire, so do a sanity check */
4739 if (*(UINT *)pMemory > USHRT_MAX)
4740 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
4741 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4742 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
4743 pStubMsg->Buffer += sizeof(USHORT);
4744 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
4747 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4750 STD_OVERFLOW_CHECK(pStubMsg);
4752 /* FIXME: what is the correct return value? */
4756 /***********************************************************************
4757 * NdrBaseTypeUnmarshall [internal]
4759 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
4760 PMIDL_STUB_MESSAGE pStubMsg,
4761 unsigned char **ppMemory,
4762 PFORMAT_STRING pFormat,
4763 unsigned char fMustAlloc)
4765 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
4767 #define BASE_TYPE_UNMARSHALL(type) \
4768 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
4769 if (fMustAlloc || !*ppMemory) \
4770 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
4771 TRACE("*ppMemory: %p\n", *ppMemory); \
4772 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
4773 pStubMsg->Buffer += sizeof(type);
4781 BASE_TYPE_UNMARSHALL(UCHAR);
4782 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
4787 BASE_TYPE_UNMARSHALL(USHORT);
4788 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
4792 case RPC_FC_ERROR_STATUS_T:
4794 BASE_TYPE_UNMARSHALL(ULONG);
4795 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
4798 BASE_TYPE_UNMARSHALL(float);
4799 TRACE("value: %f\n", **(float **)ppMemory);
4802 BASE_TYPE_UNMARSHALL(double);
4803 TRACE("value: %f\n", **(double **)ppMemory);
4806 BASE_TYPE_UNMARSHALL(ULONGLONG);
4807 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
4810 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4811 if (fMustAlloc || !*ppMemory)
4812 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
4813 TRACE("*ppMemory: %p\n", *ppMemory);
4814 /* 16-bits on the wire, but int in memory */
4815 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
4816 pStubMsg->Buffer += sizeof(USHORT);
4817 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
4820 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4822 #undef BASE_TYPE_UNMARSHALL
4824 /* FIXME: what is the correct return value? */
4829 /***********************************************************************
4830 * NdrBaseTypeBufferSize [internal]
4832 static void WINAPI NdrBaseTypeBufferSize(
4833 PMIDL_STUB_MESSAGE pStubMsg,
4834 unsigned char *pMemory,
4835 PFORMAT_STRING pFormat)
4837 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4845 pStubMsg->BufferLength += sizeof(UCHAR);
4851 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
4852 pStubMsg->BufferLength += sizeof(USHORT);
4857 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
4858 pStubMsg->BufferLength += sizeof(ULONG);
4861 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
4862 pStubMsg->BufferLength += sizeof(float);
4865 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
4866 pStubMsg->BufferLength += sizeof(double);
4869 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
4870 pStubMsg->BufferLength += sizeof(ULONGLONG);
4872 case RPC_FC_ERROR_STATUS_T:
4873 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
4874 pStubMsg->BufferLength += sizeof(error_status_t);
4877 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4881 /***********************************************************************
4882 * NdrBaseTypeMemorySize [internal]
4884 static ULONG WINAPI NdrBaseTypeMemorySize(
4885 PMIDL_STUB_MESSAGE pStubMsg,
4886 PFORMAT_STRING pFormat)
4894 pStubMsg->Buffer += sizeof(UCHAR);
4895 pStubMsg->MemorySize += sizeof(UCHAR);
4896 return sizeof(UCHAR);
4900 pStubMsg->Buffer += sizeof(USHORT);
4901 pStubMsg->MemorySize += sizeof(USHORT);
4902 return sizeof(USHORT);
4905 pStubMsg->Buffer += sizeof(ULONG);
4906 pStubMsg->MemorySize += sizeof(ULONG);
4907 return sizeof(ULONG);
4909 pStubMsg->Buffer += sizeof(float);
4910 pStubMsg->MemorySize += sizeof(float);
4911 return sizeof(float);
4913 pStubMsg->Buffer += sizeof(double);
4914 pStubMsg->MemorySize += sizeof(double);
4915 return sizeof(double);
4917 pStubMsg->Buffer += sizeof(ULONGLONG);
4918 pStubMsg->MemorySize += sizeof(ULONGLONG);
4919 return sizeof(ULONGLONG);
4920 case RPC_FC_ERROR_STATUS_T:
4921 pStubMsg->Buffer += sizeof(error_status_t);
4922 pStubMsg->MemorySize += sizeof(error_status_t);
4923 return sizeof(error_status_t);
4926 pStubMsg->Buffer += sizeof(INT);
4927 pStubMsg->MemorySize += sizeof(INT);
4930 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4935 /***********************************************************************
4936 * NdrBaseTypeFree [internal]
4938 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
4939 unsigned char *pMemory,
4940 PFORMAT_STRING pFormat)
4942 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4947 /***********************************************************************
4948 * NdrClientContextMarshall [RPCRT4.@]
4950 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4951 NDR_CCONTEXT ContextHandle,
4954 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
4956 ALIGN_POINTER(pStubMsg->Buffer, 4);
4958 /* FIXME: what does fCheck do? */
4959 NDRCContextMarshall(ContextHandle,
4962 pStubMsg->Buffer += cbNDRContext;
4965 /***********************************************************************
4966 * NdrClientContextUnmarshall [RPCRT4.@]
4968 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4969 NDR_CCONTEXT * pContextHandle,
4970 RPC_BINDING_HANDLE BindHandle)
4972 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
4974 ALIGN_POINTER(pStubMsg->Buffer, 4);
4976 NDRCContextUnmarshall(pContextHandle,
4979 pStubMsg->RpcMsg->DataRepresentation);
4981 pStubMsg->Buffer += cbNDRContext;
4984 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4985 NDR_SCONTEXT ContextHandle,
4986 NDR_RUNDOWN RundownRoutine )
4988 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
4991 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
4993 FIXME("(%p): stub\n", pStubMsg);
4997 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
4998 unsigned char* pMemory,
4999 PFORMAT_STRING pFormat)
5001 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
5004 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
5005 PFORMAT_STRING pFormat)
5007 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
5011 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5012 NDR_SCONTEXT ContextHandle,
5013 NDR_RUNDOWN RundownRoutine,
5014 PFORMAT_STRING pFormat)
5016 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
5019 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5020 PFORMAT_STRING pFormat)
5022 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
5026 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
5028 typedef struct ndr_context_handle
5032 } ndr_context_handle;
5034 struct context_handle_entry
5038 RPC_BINDING_HANDLE handle;
5039 ndr_context_handle wire_data;
5042 static struct list context_handle_list = LIST_INIT(context_handle_list);
5044 static CRITICAL_SECTION ndr_context_cs;
5045 static CRITICAL_SECTION_DEBUG ndr_context_debug =
5047 0, 0, &ndr_context_cs,
5048 { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
5049 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
5051 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
5053 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
5055 struct context_handle_entry *che = (struct context_handle_entry*) CContext;
5057 if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
5062 static struct context_handle_entry *context_entry_from_guid(LPGUID uuid)
5064 struct context_handle_entry *che;
5065 LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
5066 if (IsEqualGUID(&che->wire_data.uuid, uuid))
5071 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
5073 struct context_handle_entry *che;
5074 RPC_BINDING_HANDLE handle = NULL;
5076 TRACE("%p\n", CContext);
5078 EnterCriticalSection(&ndr_context_cs);
5079 che = get_context_entry(CContext);
5081 handle = che->handle;
5082 LeaveCriticalSection(&ndr_context_cs);
5085 RpcRaiseException(ERROR_INVALID_HANDLE);
5089 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
5091 struct context_handle_entry *che;
5093 TRACE("%p %p\n", CContext, pBuff);
5097 EnterCriticalSection(&ndr_context_cs);
5098 che = get_context_entry(CContext);
5099 memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
5100 LeaveCriticalSection(&ndr_context_cs);
5104 ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
5105 wire_data->attributes = 0;
5106 wire_data->uuid = GUID_NULL;
5110 static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
5111 RPC_BINDING_HANDLE hBinding,
5112 ndr_context_handle *chi)
5114 struct context_handle_entry *che = NULL;
5116 /* a null UUID means we should free the context handle */
5117 if (IsEqualGUID(&chi->uuid, &GUID_NULL))
5121 che = get_context_entry(*CContext);
5123 return ERROR_INVALID_HANDLE;
5124 list_remove(&che->entry);
5125 RpcBindingFree(&che->handle);
5126 HeapFree(GetProcessHeap(), 0, che);
5130 /* if there's no existing entry matching the GUID, allocate one */
5131 else if (!(che = context_entry_from_guid(&chi->uuid)))
5133 che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
5135 return ERROR_NOT_ENOUGH_MEMORY;
5136 che->magic = NDR_CONTEXT_HANDLE_MAGIC;
5137 RpcBindingCopy(hBinding, &che->handle);
5138 list_add_tail(&context_handle_list, &che->entry);
5139 memcpy(&che->wire_data, chi, sizeof *chi);
5144 return ERROR_SUCCESS;
5147 /***********************************************************************
5148 * NDRCContextUnmarshall [RPCRT4.@]
5150 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
5151 RPC_BINDING_HANDLE hBinding,
5152 void *pBuff, ULONG DataRepresentation)
5156 TRACE("*%p=(%p) %p %p %08x\n",
5157 CContext, *CContext, hBinding, pBuff, DataRepresentation);
5159 EnterCriticalSection(&ndr_context_cs);
5160 r = ndr_update_context_handle(CContext, hBinding, pBuff);
5161 LeaveCriticalSection(&ndr_context_cs);
5163 RpcRaiseException(r);
5166 /***********************************************************************
5167 * NDRSContextMarshall [RPCRT4.@]
5169 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
5171 NDR_RUNDOWN userRunDownIn)
5173 FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn);
5176 /***********************************************************************
5177 * NDRSContextMarshallEx [RPCRT4.@]
5179 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
5180 NDR_SCONTEXT CContext,
5182 NDR_RUNDOWN userRunDownIn)
5184 FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn);
5187 /***********************************************************************
5188 * NDRSContextMarshall2 [RPCRT4.@]
5190 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
5191 NDR_SCONTEXT CContext,
5193 NDR_RUNDOWN userRunDownIn,
5194 void *CtxGuard, ULONG Flags)
5196 FIXME("(%p %p %p %p %p %u): stub\n",
5197 hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags);
5200 /***********************************************************************
5201 * NDRSContextUnmarshall [RPCRT4.@]
5203 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
5204 ULONG DataRepresentation)
5206 FIXME("(%p %08x): stub\n", pBuff, DataRepresentation);
5210 /***********************************************************************
5211 * NDRSContextUnmarshallEx [RPCRT4.@]
5213 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
5215 ULONG DataRepresentation)
5217 FIXME("(%p %p %08x): stub\n", hBinding, pBuff, DataRepresentation);
5221 /***********************************************************************
5222 * NDRSContextUnmarshall2 [RPCRT4.@]
5224 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
5226 ULONG DataRepresentation,
5227 void *CtxGuard, ULONG Flags)
5229 FIXME("(%p %p %08x %p %u): stub\n",
5230 hBinding, pBuff, DataRepresentation, CtxGuard, Flags);