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 overflow when calculating array sizes
30 * - Checks for out-of-memory conditions
47 #include "wine/unicode.h"
48 #include "wine/rpcfc.h"
50 #include "wine/debug.h"
51 #include "wine/list.h"
53 WINE_DEFAULT_DEBUG_CHANNEL(ole);
56 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
57 (*((UINT32 *)(pchar)) = (uint32))
59 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
60 (*((UINT32 *)(pchar)))
62 /* these would work for i386 too, but less efficient */
63 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
64 (*(pchar) = LOBYTE(LOWORD(uint32)), \
65 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
66 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
67 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
68 (uint32)) /* allow as r-value */
70 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
72 MAKEWORD(*(pchar), *((pchar)+1)), \
73 MAKEWORD(*((pchar)+2), *((pchar)+3))))
76 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
77 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
78 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
79 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
80 *(pchar) = HIBYTE(HIWORD(uint32)), \
81 (uint32)) /* allow as r-value */
83 #define BIG_ENDIAN_UINT32_READ(pchar) \
85 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
86 MAKEWORD(*((pchar)+1), *(pchar))))
88 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
89 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
90 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
91 # define NDR_LOCAL_UINT32_READ(pchar) \
92 BIG_ENDIAN_UINT32_READ(pchar)
94 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
95 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
96 # define NDR_LOCAL_UINT32_READ(pchar) \
97 LITTLE_ENDIAN_UINT32_READ(pchar)
100 /* _Align must be the desired alignment,
101 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
102 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
103 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
104 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
105 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
107 #define STD_OVERFLOW_CHECK(_Msg) do { \
108 TRACE("buffer=%d/%ld\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
109 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
110 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
113 #define NDR_TABLE_SIZE 128
114 #define NDR_TABLE_MASK 127
116 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
117 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
118 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
119 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
120 static unsigned long WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
122 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
124 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
125 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
126 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
127 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
131 NdrPointerMarshall, NdrPointerMarshall,
132 NdrPointerMarshall, NdrPointerMarshall,
134 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
135 NdrConformantStructMarshall, NdrConformantStructMarshall,
136 NdrConformantVaryingStructMarshall,
137 NdrComplexStructMarshall,
139 NdrConformantArrayMarshall,
140 NdrConformantVaryingArrayMarshall,
141 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
142 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
143 NdrComplexArrayMarshall,
145 NdrConformantStringMarshall, 0, 0,
146 NdrConformantStringMarshall,
147 NdrNonConformantStringMarshall, 0, 0, 0,
149 NdrEncapsulatedUnionMarshall,
150 NdrNonEncapsulatedUnionMarshall,
151 NdrByteCountPointerMarshall,
152 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
154 NdrInterfacePointerMarshall,
157 NdrUserMarshalMarshall
159 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
161 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
162 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
163 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
164 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
166 NdrBaseTypeUnmarshall,
168 NdrPointerUnmarshall, NdrPointerUnmarshall,
169 NdrPointerUnmarshall, NdrPointerUnmarshall,
171 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
172 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
173 NdrConformantVaryingStructUnmarshall,
174 NdrComplexStructUnmarshall,
176 NdrConformantArrayUnmarshall,
177 NdrConformantVaryingArrayUnmarshall,
178 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
179 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
180 NdrComplexArrayUnmarshall,
182 NdrConformantStringUnmarshall, 0, 0,
183 NdrConformantStringUnmarshall,
184 NdrNonConformantStringUnmarshall, 0, 0, 0,
186 NdrEncapsulatedUnionUnmarshall,
187 NdrNonEncapsulatedUnionUnmarshall,
188 NdrByteCountPointerUnmarshall,
189 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
191 NdrInterfacePointerUnmarshall,
194 NdrUserMarshalUnmarshall
196 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
198 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
199 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
200 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
201 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
203 NdrBaseTypeBufferSize,
205 NdrPointerBufferSize, NdrPointerBufferSize,
206 NdrPointerBufferSize, NdrPointerBufferSize,
208 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
209 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
210 NdrConformantVaryingStructBufferSize,
211 NdrComplexStructBufferSize,
213 NdrConformantArrayBufferSize,
214 NdrConformantVaryingArrayBufferSize,
215 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
216 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
217 NdrComplexArrayBufferSize,
219 NdrConformantStringBufferSize, 0, 0,
220 NdrConformantStringBufferSize,
221 NdrNonConformantStringBufferSize, 0, 0, 0,
223 NdrEncapsulatedUnionBufferSize,
224 NdrNonEncapsulatedUnionBufferSize,
225 NdrByteCountPointerBufferSize,
226 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
228 NdrInterfacePointerBufferSize,
231 NdrUserMarshalBufferSize
233 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
235 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
236 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
237 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
238 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
240 NdrBaseTypeMemorySize,
242 NdrPointerMemorySize, NdrPointerMemorySize,
243 NdrPointerMemorySize, NdrPointerMemorySize,
245 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
246 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
247 NdrConformantVaryingStructMemorySize,
248 NdrComplexStructMemorySize,
250 NdrConformantArrayMemorySize,
251 NdrConformantVaryingArrayMemorySize,
252 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
253 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
254 NdrComplexArrayMemorySize,
256 NdrConformantStringMemorySize, 0, 0,
257 NdrConformantStringMemorySize,
258 NdrNonConformantStringMemorySize, 0, 0, 0,
260 NdrEncapsulatedUnionMemorySize,
261 NdrNonEncapsulatedUnionMemorySize,
262 NdrByteCountPointerMemorySize,
263 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
265 NdrInterfacePointerMemorySize,
268 NdrUserMarshalMemorySize
270 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
272 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
273 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
274 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
275 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
279 NdrPointerFree, NdrPointerFree,
280 NdrPointerFree, NdrPointerFree,
282 NdrSimpleStructFree, NdrSimpleStructFree,
283 NdrConformantStructFree, NdrConformantStructFree,
284 NdrConformantVaryingStructFree,
285 NdrComplexStructFree,
287 NdrConformantArrayFree,
288 NdrConformantVaryingArrayFree,
289 NdrFixedArrayFree, NdrFixedArrayFree,
290 NdrVaryingArrayFree, NdrVaryingArrayFree,
296 NdrEncapsulatedUnionFree,
297 NdrNonEncapsulatedUnionFree,
299 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
301 NdrInterfacePointerFree,
307 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
309 /* hmm, this is probably supposed to do more? */
310 return pStubMsg->pfnAllocate(len);
313 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
315 pStubMsg->pfnFree(Pointer);
318 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
320 return (*(const ULONG *)pFormat != -1);
323 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
325 ALIGN_POINTER(pStubMsg->Buffer, 4);
326 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
327 pStubMsg->Buffer += 4;
328 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
329 if (pStubMsg->fHasNewCorrDesc)
335 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
337 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
339 pStubMsg->Offset = 0;
340 pStubMsg->ActualCount = pStubMsg->MaxCount;
344 ALIGN_POINTER(pStubMsg->Buffer, 4);
345 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
346 pStubMsg->Buffer += 4;
347 TRACE("offset is %ld\n", pStubMsg->Offset);
348 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
349 pStubMsg->Buffer += 4;
350 TRACE("variance is %ld\n", pStubMsg->ActualCount);
352 if ((pStubMsg->ActualCount > MaxValue) ||
353 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
355 ERR("invalid array bound(s): ActualCount = %ld, Offset = %ld, MaxValue = %ld\n",
356 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
357 RpcRaiseException(RPC_S_INVALID_BOUND);
362 if (pStubMsg->fHasNewCorrDesc)
368 /* writes the conformance value to the buffer */
369 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
371 ALIGN_POINTER(pStubMsg->Buffer, 4);
372 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
373 pStubMsg->Buffer += 4;
376 /* writes the variance values to the buffer */
377 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
379 ALIGN_POINTER(pStubMsg->Buffer, 4);
380 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
381 pStubMsg->Buffer += 4;
382 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
383 pStubMsg->Buffer += 4;
386 /* requests buffer space for the conformance value */
387 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
389 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
390 pStubMsg->BufferLength += 4;
393 /* requests buffer space for the variance values */
394 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
396 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
397 pStubMsg->BufferLength += 8;
400 PFORMAT_STRING ComputeConformanceOrVariance(
401 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
402 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG *pCount)
404 BYTE dtype = pFormat[0] & 0xf;
405 short ofs = *(short *)&pFormat[2];
409 if (!IsConformanceOrVariancePresent(pFormat)) {
410 /* null descriptor */
415 switch (pFormat[0] & 0xf0) {
416 case RPC_FC_NORMAL_CONFORMANCE:
417 TRACE("normal conformance, ofs=%d\n", ofs);
420 case RPC_FC_POINTER_CONFORMANCE:
421 TRACE("pointer conformance, ofs=%d\n", ofs);
422 ptr = pStubMsg->Memory;
424 case RPC_FC_TOP_LEVEL_CONFORMANCE:
425 TRACE("toplevel conformance, ofs=%d\n", ofs);
426 if (pStubMsg->StackTop) {
427 ptr = pStubMsg->StackTop;
430 /* -Os mode, *pCount is already set */
434 case RPC_FC_CONSTANT_CONFORMANCE:
435 data = ofs | ((DWORD)pFormat[1] << 16);
436 TRACE("constant conformance, val=%ld\n", data);
439 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
440 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
441 if (pStubMsg->StackTop) {
442 ptr = pStubMsg->StackTop;
450 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
453 switch (pFormat[1]) {
454 case RPC_FC_DEREFERENCE:
455 ptr = *(LPVOID*)((char *)ptr + ofs);
457 case RPC_FC_CALLBACK:
459 unsigned char *old_stack_top = pStubMsg->StackTop;
460 pStubMsg->StackTop = ptr;
462 /* ofs is index into StubDesc->apfnExprEval */
463 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
464 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
466 pStubMsg->StackTop = old_stack_top;
470 ptr = (char *)ptr + ofs;
483 data = *(USHORT*)ptr;
494 FIXME("unknown conformance data type %x\n", dtype);
497 TRACE("dereferenced data type %x at %p, got %ld\n", dtype, ptr, data);
500 switch (pFormat[1]) {
501 case RPC_FC_DEREFERENCE: /* already handled */
518 FIXME("unknown conformance op %d\n", pFormat[1]);
523 TRACE("resulting conformance is %ld\n", *pCount);
524 if (pStubMsg->fHasNewCorrDesc)
530 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
531 * the result overflows 32-bits */
532 static ULONG inline safe_multiply(ULONG a, ULONG b)
534 ULONGLONG ret = (ULONGLONG)a * b;
535 if (ret > 0xffffffff)
537 RpcRaiseException(RPC_S_INVALID_BOUND);
545 * NdrConformantString:
547 * What MS calls a ConformantString is, in DCE terminology,
548 * a Varying-Conformant String.
550 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
551 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
552 * into unmarshalled string)
553 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
555 * data: CHARTYPE[maxlen]
557 * ], where CHARTYPE is the appropriate character type (specified externally)
561 /***********************************************************************
562 * NdrConformantStringMarshall [RPCRT4.@]
564 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
565 unsigned char *pszMessage, PFORMAT_STRING pFormat)
569 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
571 if (*pFormat == RPC_FC_C_CSTRING) {
572 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
573 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
576 else if (*pFormat == RPC_FC_C_WSTRING) {
577 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
578 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
582 ERR("Unhandled string type: %#x\n", *pFormat);
583 /* FIXME: raise an exception. */
587 if (pFormat[1] == RPC_FC_STRING_SIZED)
588 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
590 pStubMsg->MaxCount = pStubMsg->ActualCount;
591 pStubMsg->Offset = 0;
592 WriteConformance(pStubMsg);
593 WriteVariance(pStubMsg);
595 size = safe_multiply(esize, pStubMsg->ActualCount);
596 memcpy(pStubMsg->Buffer, pszMessage, size); /* the string itself */
597 pStubMsg->Buffer += size;
599 STD_OVERFLOW_CHECK(pStubMsg);
602 return NULL; /* is this always right? */
605 /***********************************************************************
606 * NdrConformantStringBufferSize [RPCRT4.@]
608 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
609 unsigned char* pMemory, PFORMAT_STRING pFormat)
613 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
615 SizeConformance(pStubMsg);
616 SizeVariance(pStubMsg);
618 if (*pFormat == RPC_FC_C_CSTRING) {
619 TRACE("string=%s\n", debugstr_a((char*)pMemory));
620 pStubMsg->ActualCount = strlen((char*)pMemory)+1;
623 else if (*pFormat == RPC_FC_C_WSTRING) {
624 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
625 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;
629 ERR("Unhandled string type: %#x\n", *pFormat);
630 /* FIXME: raise an exception */
634 if (pFormat[1] == RPC_FC_STRING_SIZED)
635 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
637 pStubMsg->MaxCount = pStubMsg->ActualCount;
639 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
642 /************************************************************************
643 * NdrConformantStringMemorySize [RPCRT4.@]
645 unsigned long WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
646 PFORMAT_STRING pFormat )
648 unsigned long rslt = 0;
650 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
652 assert(pStubMsg && pFormat);
654 if (*pFormat == RPC_FC_C_CSTRING) {
655 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
657 else if (*pFormat == RPC_FC_C_WSTRING) {
658 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
661 ERR("Unhandled string type: %#x\n", *pFormat);
662 /* FIXME: raise an exception */
665 if (pFormat[1] != RPC_FC_PAD) {
666 FIXME("sized string format=%d\n", pFormat[1]);
669 TRACE(" --> %lu\n", rslt);
673 /************************************************************************
674 * NdrConformantStringUnmarshall [RPCRT4.@]
676 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
677 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
679 ULONG size, esize, i;
681 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
682 pStubMsg, *ppMemory, pFormat, fMustAlloc);
684 assert(pFormat && ppMemory && pStubMsg);
686 ReadConformance(pStubMsg, NULL);
687 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
689 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
690 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
692 ERR("Unhandled string type: %#x\n", *pFormat);
693 /* FIXME: raise an exception */
697 size = safe_multiply(esize, pStubMsg->ActualCount);
699 /* strings must always have null terminating bytes */
702 ERR("invalid string length of %ld\n", pStubMsg->ActualCount);
703 RpcRaiseException(RPC_S_INVALID_BOUND);
706 for (i = size - esize; i < size; i++)
707 if (pStubMsg->Buffer[i] != 0)
709 ERR("string not null-terminated at byte position %ld, data is 0x%x\n",
710 i, pStubMsg->Buffer[i]);
711 RpcRaiseException(RPC_S_INVALID_BOUND);
715 if (fMustAlloc || !*ppMemory)
716 *ppMemory = NdrAllocate(pStubMsg, size);
718 memcpy(*ppMemory, pStubMsg->Buffer, size);
720 pStubMsg->Buffer += size;
722 if (*pFormat == RPC_FC_C_CSTRING) {
723 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
725 else if (*pFormat == RPC_FC_C_WSTRING) {
726 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
729 return NULL; /* FIXME: is this always right? */
732 /***********************************************************************
733 * NdrNonConformantStringMarshall [RPCRT4.@]
735 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
736 unsigned char *pMemory,
737 PFORMAT_STRING pFormat)
743 /***********************************************************************
744 * NdrNonConformantStringUnmarshall [RPCRT4.@]
746 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
747 unsigned char **ppMemory,
748 PFORMAT_STRING pFormat,
749 unsigned char fMustAlloc)
755 /***********************************************************************
756 * NdrNonConformantStringBufferSize [RPCRT4.@]
758 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
759 unsigned char *pMemory,
760 PFORMAT_STRING pFormat)
765 /***********************************************************************
766 * NdrNonConformantStringMemorySize [RPCRT4.@]
768 unsigned long WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
769 PFORMAT_STRING pFormat)
775 static inline void dump_pointer_attr(unsigned char attr)
777 if (attr & RPC_FC_P_ALLOCALLNODES)
778 TRACE(" RPC_FC_P_ALLOCALLNODES");
779 if (attr & RPC_FC_P_DONTFREE)
780 TRACE(" RPC_FC_P_DONTFREE");
781 if (attr & RPC_FC_P_ONSTACK)
782 TRACE(" RPC_FC_P_ONSTACK");
783 if (attr & RPC_FC_P_SIMPLEPOINTER)
784 TRACE(" RPC_FC_P_SIMPLEPOINTER");
785 if (attr & RPC_FC_P_DEREF)
786 TRACE(" RPC_FC_P_DEREF");
790 /***********************************************************************
793 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
794 unsigned char *Buffer,
795 unsigned char *Pointer,
796 PFORMAT_STRING pFormat)
798 unsigned type = pFormat[0], attr = pFormat[1];
801 unsigned long pointer_id;
802 int pointer_needs_marshaling;
804 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
805 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
807 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
808 else desc = pFormat + *(const SHORT*)pFormat;
811 case RPC_FC_RP: /* ref pointer (always non-null) */
812 #if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
814 RpcRaiseException(RPC_X_NULL_REF_POINTER);
816 pointer_needs_marshaling = 1;
818 case RPC_FC_UP: /* unique pointer */
819 case RPC_FC_OP: /* object pointer - same as unique here */
821 pointer_needs_marshaling = 1;
823 pointer_needs_marshaling = 0;
824 pointer_id = (unsigned long)Pointer;
825 TRACE("writing 0x%08lx to buffer\n", pointer_id);
826 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
829 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
830 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
831 TRACE("writing 0x%08lx to buffer\n", pointer_id);
832 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
835 FIXME("unhandled ptr type=%02x\n", type);
836 RpcRaiseException(RPC_X_BAD_STUB_DATA);
840 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
842 if (pointer_needs_marshaling) {
843 if (attr & RPC_FC_P_DEREF) {
844 Pointer = *(unsigned char**)Pointer;
845 TRACE("deref => %p\n", Pointer);
847 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
848 if (m) m(pStubMsg, Pointer, desc);
849 else FIXME("no marshaller for data type=%02x\n", *desc);
852 STD_OVERFLOW_CHECK(pStubMsg);
855 /***********************************************************************
858 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
859 unsigned char *Buffer,
860 unsigned char **pPointer,
861 PFORMAT_STRING pFormat,
862 unsigned char fMustAlloc)
864 unsigned type = pFormat[0], attr = pFormat[1];
867 DWORD pointer_id = 0;
868 int pointer_needs_unmarshaling;
870 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pFormat, fMustAlloc);
871 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
873 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
874 else desc = pFormat + *(const SHORT*)pFormat;
877 case RPC_FC_RP: /* ref pointer (always non-null) */
878 pointer_needs_unmarshaling = 1;
880 case RPC_FC_UP: /* unique pointer */
881 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
882 TRACE("pointer_id is 0x%08lx\n", pointer_id);
884 pointer_needs_unmarshaling = 1;
887 pointer_needs_unmarshaling = 0;
890 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
891 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
892 TRACE("pointer_id is 0x%08lx\n", pointer_id);
893 if (!fMustAlloc && *pPointer)
895 FIXME("free object pointer %p\n", *pPointer);
899 pointer_needs_unmarshaling = 1;
901 pointer_needs_unmarshaling = 0;
904 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
905 TRACE("pointer_id is 0x%08lx\n", pointer_id);
906 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
907 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
910 FIXME("unhandled ptr type=%02x\n", type);
911 RpcRaiseException(RPC_X_BAD_STUB_DATA);
915 if (pointer_needs_unmarshaling) {
916 if (attr & RPC_FC_P_DEREF) {
917 if (!*pPointer || fMustAlloc)
918 *pPointer = NdrAllocate(pStubMsg, sizeof(void *));
919 pPointer = *(unsigned char***)pPointer;
920 TRACE("deref => %p\n", pPointer);
922 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
923 if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
924 else FIXME("no unmarshaller for data type=%02x\n", *desc);
926 if (type == RPC_FC_FP)
927 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
931 TRACE("pointer=%p\n", *pPointer);
934 /***********************************************************************
937 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
938 unsigned char *Pointer,
939 PFORMAT_STRING pFormat)
941 unsigned type = pFormat[0], attr = pFormat[1];
944 int pointer_needs_sizing;
945 unsigned long pointer_id;
947 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
948 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
950 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
951 else desc = pFormat + *(const SHORT*)pFormat;
954 case RPC_FC_RP: /* ref pointer (always non-null) */
958 /* NULL pointer has no further representation */
963 pointer_needs_sizing = !NdrFullPointerQueryPointer(
964 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
965 if (!pointer_needs_sizing)
969 FIXME("unhandled ptr type=%02x\n", type);
970 RpcRaiseException(RPC_X_BAD_STUB_DATA);
974 if (attr & RPC_FC_P_DEREF) {
975 Pointer = *(unsigned char**)Pointer;
976 TRACE("deref => %p\n", Pointer);
979 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
980 if (m) m(pStubMsg, Pointer, desc);
981 else FIXME("no buffersizer for data type=%02x\n", *desc);
984 /***********************************************************************
985 * PointerMemorySize [RPCRT4.@]
987 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
988 unsigned char *Buffer,
989 PFORMAT_STRING pFormat)
991 unsigned type = pFormat[0], attr = pFormat[1];
995 FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat);
996 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
998 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
999 else desc = pFormat + *(const SHORT*)pFormat;
1002 case RPC_FC_RP: /* ref pointer (always non-null) */
1005 FIXME("unhandled ptr type=%02x\n", type);
1006 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1009 if (attr & RPC_FC_P_DEREF) {
1013 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1014 if (m) m(pStubMsg, desc);
1015 else FIXME("no memorysizer for data type=%02x\n", *desc);
1020 /***********************************************************************
1021 * PointerFree [RPCRT4.@]
1023 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1024 unsigned char *Pointer,
1025 PFORMAT_STRING pFormat)
1027 unsigned type = pFormat[0], attr = pFormat[1];
1028 PFORMAT_STRING desc;
1031 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1032 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1033 if (attr & RPC_FC_P_DONTFREE) return;
1035 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1036 else desc = pFormat + *(const SHORT*)pFormat;
1038 if (!Pointer) return;
1040 if (type == RPC_FC_FP) {
1041 int pointer_needs_freeing = NdrFullPointerFree(
1042 pStubMsg->FullPtrXlatTables, Pointer);
1043 if (!pointer_needs_freeing)
1047 if (attr & RPC_FC_P_DEREF) {
1048 Pointer = *(unsigned char**)Pointer;
1049 TRACE("deref => %p\n", Pointer);
1052 m = NdrFreer[*desc & NDR_TABLE_MASK];
1053 if (m) m(pStubMsg, Pointer, desc);
1055 /* hmm... is this sensible?
1056 * perhaps we should check if the memory comes from NdrAllocate,
1057 * and deallocate only if so - checking if the pointer is between
1058 * BufferStart and BufferEnd is probably no good since the buffer
1059 * may be reallocated when the server wants to marshal the reply */
1061 case RPC_FC_BOGUS_STRUCT:
1062 case RPC_FC_BOGUS_ARRAY:
1063 case RPC_FC_USER_MARSHAL:
1065 case RPC_FC_CVARRAY:
1068 FIXME("unhandled data type=%02x\n", *desc);
1070 case RPC_FC_C_CSTRING:
1071 case RPC_FC_C_WSTRING:
1072 if (pStubMsg->ReuseBuffer) goto notfree;
1078 if (attr & RPC_FC_P_ONSTACK) {
1079 TRACE("not freeing stack ptr %p\n", Pointer);
1082 TRACE("freeing %p\n", Pointer);
1083 NdrFree(pStubMsg, Pointer);
1086 TRACE("not freeing %p\n", Pointer);
1089 /***********************************************************************
1090 * EmbeddedPointerMarshall
1092 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1093 unsigned char *pMemory,
1094 PFORMAT_STRING pFormat)
1096 unsigned char *Mark = pStubMsg->BufferMark;
1097 unsigned long Offset = pStubMsg->Offset;
1098 unsigned ofs, rep, count, stride, xofs;
1101 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1103 if (*pFormat != RPC_FC_PP) return NULL;
1106 while (pFormat[0] != RPC_FC_END) {
1107 switch (pFormat[0]) {
1109 FIXME("unknown repeat type %d\n", pFormat[0]);
1110 case RPC_FC_NO_REPEAT:
1118 case RPC_FC_FIXED_REPEAT:
1119 rep = *(const WORD*)&pFormat[2];
1120 stride = *(const WORD*)&pFormat[4];
1121 ofs = *(const WORD*)&pFormat[6];
1122 count = *(const WORD*)&pFormat[8];
1126 case RPC_FC_VARIABLE_REPEAT:
1127 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1128 stride = *(const WORD*)&pFormat[2];
1129 ofs = *(const WORD*)&pFormat[4];
1130 count = *(const WORD*)&pFormat[6];
1131 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1135 for (i = 0; i < rep; i++) {
1136 PFORMAT_STRING info = pFormat;
1137 unsigned char *membase = pMemory + (i * stride);
1138 unsigned char *bufbase = Mark + (i * stride);
1140 /* ofs doesn't seem to matter in this context */
1141 for (u=0; u<count; u++,info+=8) {
1142 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1143 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1144 unsigned char *saved_memory = pStubMsg->Memory;
1146 pStubMsg->Memory = pMemory;
1147 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1148 pStubMsg->Memory = saved_memory;
1151 pFormat += 8 * count;
1154 STD_OVERFLOW_CHECK(pStubMsg);
1159 /***********************************************************************
1160 * EmbeddedPointerUnmarshall
1162 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1163 unsigned char **ppMemory,
1164 PFORMAT_STRING pFormat,
1165 unsigned char fMustAlloc)
1167 unsigned char *Mark = pStubMsg->BufferMark;
1168 unsigned long Offset = pStubMsg->Offset;
1169 unsigned ofs, rep, count, stride, xofs;
1172 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1174 if (*pFormat != RPC_FC_PP) return NULL;
1177 while (pFormat[0] != RPC_FC_END) {
1178 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1179 switch (pFormat[0]) {
1181 FIXME("unknown repeat type %d\n", pFormat[0]);
1182 case RPC_FC_NO_REPEAT:
1190 case RPC_FC_FIXED_REPEAT:
1191 rep = *(const WORD*)&pFormat[2];
1192 stride = *(const WORD*)&pFormat[4];
1193 ofs = *(const WORD*)&pFormat[6];
1194 count = *(const WORD*)&pFormat[8];
1198 case RPC_FC_VARIABLE_REPEAT:
1199 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1200 stride = *(const WORD*)&pFormat[2];
1201 ofs = *(const WORD*)&pFormat[4];
1202 count = *(const WORD*)&pFormat[6];
1203 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1207 /* ofs doesn't seem to matter in this context */
1208 for (i = 0; i < rep; i++) {
1209 PFORMAT_STRING info = pFormat;
1210 unsigned char *membase = *ppMemory + (i * stride);
1211 unsigned char *bufbase = Mark + (i * stride);
1213 for (u=0; u<count; u++,info+=8) {
1214 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1215 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1216 PointerUnmarshall(pStubMsg, bufptr, (unsigned char**)memptr, info+4, TRUE);
1219 pFormat += 8 * count;
1225 /***********************************************************************
1226 * EmbeddedPointerBufferSize
1228 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1229 unsigned char *pMemory,
1230 PFORMAT_STRING pFormat)
1232 unsigned long Offset = pStubMsg->Offset;
1233 unsigned ofs, rep, count, stride, xofs;
1236 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1238 if (pStubMsg->IgnoreEmbeddedPointers) return;
1240 if (*pFormat != RPC_FC_PP) return;
1243 while (pFormat[0] != RPC_FC_END) {
1244 switch (pFormat[0]) {
1246 FIXME("unknown repeat type %d\n", pFormat[0]);
1247 case RPC_FC_NO_REPEAT:
1255 case RPC_FC_FIXED_REPEAT:
1256 rep = *(const WORD*)&pFormat[2];
1257 stride = *(const WORD*)&pFormat[4];
1258 ofs = *(const WORD*)&pFormat[6];
1259 count = *(const WORD*)&pFormat[8];
1263 case RPC_FC_VARIABLE_REPEAT:
1264 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1265 stride = *(const WORD*)&pFormat[2];
1266 ofs = *(const WORD*)&pFormat[4];
1267 count = *(const WORD*)&pFormat[6];
1268 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1272 /* ofs doesn't seem to matter in this context */
1273 for (i = 0; i < rep; i++) {
1274 PFORMAT_STRING info = pFormat;
1275 unsigned char *membase = pMemory + (i * stride);
1277 for (u=0; u<count; u++,info+=8) {
1278 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1279 unsigned char *saved_memory = pStubMsg->Memory;
1281 pStubMsg->Memory = pMemory;
1282 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1283 pStubMsg->Memory = saved_memory;
1286 pFormat += 8 * count;
1290 /***********************************************************************
1291 * EmbeddedPointerMemorySize
1293 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1294 PFORMAT_STRING pFormat)
1296 unsigned long Offset = pStubMsg->Offset;
1297 unsigned char *Mark = pStubMsg->BufferMark;
1298 unsigned ofs, rep, count, stride, xofs;
1301 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1303 if (*pFormat != RPC_FC_PP) return 0;
1306 while (pFormat[0] != RPC_FC_END) {
1307 switch (pFormat[0]) {
1309 FIXME("unknown repeat type %d\n", pFormat[0]);
1310 case RPC_FC_NO_REPEAT:
1318 case RPC_FC_FIXED_REPEAT:
1319 rep = *(const WORD*)&pFormat[2];
1320 stride = *(const WORD*)&pFormat[4];
1321 ofs = *(const WORD*)&pFormat[6];
1322 count = *(const WORD*)&pFormat[8];
1326 case RPC_FC_VARIABLE_REPEAT:
1327 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1328 stride = *(const WORD*)&pFormat[2];
1329 ofs = *(const WORD*)&pFormat[4];
1330 count = *(const WORD*)&pFormat[6];
1331 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1335 /* ofs doesn't seem to matter in this context */
1336 for (i = 0; i < rep; i++) {
1337 PFORMAT_STRING info = pFormat;
1338 unsigned char *bufbase = Mark + (i * stride);
1340 for (u=0; u<count; u++,info+=8) {
1341 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1342 PointerMemorySize(pStubMsg, bufptr, info+4);
1345 pFormat += 8 * count;
1351 /***********************************************************************
1352 * EmbeddedPointerFree
1354 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1355 unsigned char *pMemory,
1356 PFORMAT_STRING pFormat)
1358 unsigned long Offset = pStubMsg->Offset;
1359 unsigned ofs, rep, count, stride, xofs;
1362 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1363 if (*pFormat != RPC_FC_PP) return;
1366 while (pFormat[0] != RPC_FC_END) {
1367 switch (pFormat[0]) {
1369 FIXME("unknown repeat type %d\n", pFormat[0]);
1370 case RPC_FC_NO_REPEAT:
1378 case RPC_FC_FIXED_REPEAT:
1379 rep = *(const WORD*)&pFormat[2];
1380 stride = *(const WORD*)&pFormat[4];
1381 ofs = *(const WORD*)&pFormat[6];
1382 count = *(const WORD*)&pFormat[8];
1386 case RPC_FC_VARIABLE_REPEAT:
1387 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1388 stride = *(const WORD*)&pFormat[2];
1389 ofs = *(const WORD*)&pFormat[4];
1390 count = *(const WORD*)&pFormat[6];
1391 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1395 /* ofs doesn't seem to matter in this context */
1396 for (i = 0; i < rep; i++) {
1397 PFORMAT_STRING info = pFormat;
1398 unsigned char *membase = pMemory + (i * stride);
1400 for (u=0; u<count; u++,info+=8) {
1401 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1402 unsigned char *saved_memory = pStubMsg->Memory;
1404 pStubMsg->Memory = pMemory;
1405 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1406 pStubMsg->Memory = saved_memory;
1409 pFormat += 8 * count;
1413 /***********************************************************************
1414 * NdrPointerMarshall [RPCRT4.@]
1416 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1417 unsigned char *pMemory,
1418 PFORMAT_STRING pFormat)
1420 unsigned char *Buffer;
1422 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1424 /* incremement the buffer here instead of in PointerMarshall,
1425 * as that is used by embedded pointers which already handle the incrementing
1426 * the buffer, and shouldn't write any additional pointer data to the wire */
1427 if (*pFormat != RPC_FC_RP)
1429 ALIGN_POINTER(pStubMsg->Buffer, 4);
1430 Buffer = pStubMsg->Buffer;
1431 pStubMsg->Buffer += 4;
1434 Buffer = pStubMsg->Buffer;
1436 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1438 STD_OVERFLOW_CHECK(pStubMsg);
1443 /***********************************************************************
1444 * NdrPointerUnmarshall [RPCRT4.@]
1446 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1447 unsigned char **ppMemory,
1448 PFORMAT_STRING pFormat,
1449 unsigned char fMustAlloc)
1451 unsigned char *Buffer;
1453 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1455 /* incremement the buffer here instead of in PointerUnmarshall,
1456 * as that is used by embedded pointers which already handle the incrementing
1457 * the buffer, and shouldn't read any additional pointer data from the
1459 if (*pFormat != RPC_FC_RP)
1461 ALIGN_POINTER(pStubMsg->Buffer, 4);
1462 Buffer = pStubMsg->Buffer;
1463 pStubMsg->Buffer += 4;
1466 Buffer = pStubMsg->Buffer;
1468 PointerUnmarshall(pStubMsg, Buffer, ppMemory, pFormat, fMustAlloc);
1473 /***********************************************************************
1474 * NdrPointerBufferSize [RPCRT4.@]
1476 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1477 unsigned char *pMemory,
1478 PFORMAT_STRING pFormat)
1480 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1482 /* incremement the buffer length here instead of in PointerBufferSize,
1483 * as that is used by embedded pointers which already handle the buffer
1484 * length, and shouldn't write anything more to the wire */
1485 if (*pFormat != RPC_FC_RP)
1487 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1488 pStubMsg->BufferLength += 4;
1491 PointerBufferSize(pStubMsg, pMemory, pFormat);
1494 /***********************************************************************
1495 * NdrPointerMemorySize [RPCRT4.@]
1497 unsigned long WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1498 PFORMAT_STRING pFormat)
1500 /* unsigned size = *(LPWORD)(pFormat+2); */
1501 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1502 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1506 /***********************************************************************
1507 * NdrPointerFree [RPCRT4.@]
1509 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1510 unsigned char *pMemory,
1511 PFORMAT_STRING pFormat)
1513 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1514 PointerFree(pStubMsg, pMemory, pFormat);
1517 /***********************************************************************
1518 * NdrSimpleTypeMarshall [RPCRT4.@]
1520 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1521 unsigned char FormatChar )
1526 /***********************************************************************
1527 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1529 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1530 unsigned char FormatChar )
1535 /***********************************************************************
1536 * NdrSimpleStructMarshall [RPCRT4.@]
1538 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1539 unsigned char *pMemory,
1540 PFORMAT_STRING pFormat)
1542 unsigned size = *(const WORD*)(pFormat+2);
1543 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1545 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1547 memcpy(pStubMsg->Buffer, pMemory, size);
1548 pStubMsg->BufferMark = pStubMsg->Buffer;
1549 pStubMsg->Buffer += size;
1551 if (pFormat[0] != RPC_FC_STRUCT)
1552 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1554 STD_OVERFLOW_CHECK(pStubMsg);
1559 /***********************************************************************
1560 * NdrSimpleStructUnmarshall [RPCRT4.@]
1562 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1563 unsigned char **ppMemory,
1564 PFORMAT_STRING pFormat,
1565 unsigned char fMustAlloc)
1567 unsigned size = *(const WORD*)(pFormat+2);
1568 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1570 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1573 *ppMemory = NdrAllocate(pStubMsg, size);
1574 memcpy(*ppMemory, pStubMsg->Buffer, size);
1576 if (!pStubMsg->IsClient && !*ppMemory)
1577 /* for servers, we just point straight into the RPC buffer */
1578 *ppMemory = pStubMsg->Buffer;
1580 /* for clients, memory should be provided by caller */
1581 memcpy(*ppMemory, pStubMsg->Buffer, size);
1584 pStubMsg->BufferMark = pStubMsg->Buffer;
1585 pStubMsg->Buffer += size;
1587 if (pFormat[0] != RPC_FC_STRUCT)
1588 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat+4, fMustAlloc);
1593 /***********************************************************************
1594 * NdrSimpleStructBufferSize [RPCRT4.@]
1596 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1597 unsigned char *pMemory,
1598 PFORMAT_STRING pFormat)
1600 unsigned size = *(const WORD*)(pFormat+2);
1601 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1603 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1605 pStubMsg->BufferLength += size;
1606 if (pFormat[0] != RPC_FC_STRUCT)
1607 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1610 /***********************************************************************
1611 * NdrSimpleStructMemorySize [RPCRT4.@]
1613 unsigned long WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1614 PFORMAT_STRING pFormat)
1616 unsigned short size = *(LPWORD)(pFormat+2);
1618 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1620 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1621 pStubMsg->MemorySize += size;
1622 pStubMsg->Buffer += size;
1624 if (pFormat[0] != RPC_FC_STRUCT)
1625 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1629 /***********************************************************************
1630 * NdrSimpleStructFree [RPCRT4.@]
1632 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1633 unsigned char *pMemory,
1634 PFORMAT_STRING pFormat)
1636 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1637 if (pFormat[0] != RPC_FC_STRUCT)
1638 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1642 static unsigned long EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg,
1643 PFORMAT_STRING pFormat)
1647 case RPC_FC_PSTRUCT:
1648 case RPC_FC_CSTRUCT:
1649 case RPC_FC_BOGUS_STRUCT:
1650 return *(const WORD*)&pFormat[2];
1651 case RPC_FC_USER_MARSHAL:
1652 return *(const WORD*)&pFormat[4];
1653 case RPC_FC_NON_ENCAPSULATED_UNION:
1655 if (pStubMsg->fHasNewCorrDesc)
1660 pFormat += *(const SHORT*)pFormat;
1661 return *(const SHORT*)pFormat;
1663 return sizeof(void *);
1665 FIXME("unhandled embedded type %02x\n", *pFormat);
1671 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1672 PFORMAT_STRING pFormat)
1674 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1678 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1682 return m(pStubMsg, pFormat);
1686 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1687 unsigned char *pMemory,
1688 PFORMAT_STRING pFormat,
1689 PFORMAT_STRING pPointer)
1691 PFORMAT_STRING desc;
1695 while (*pFormat != RPC_FC_END) {
1701 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
1702 memcpy(pStubMsg->Buffer, pMemory, 1);
1703 pStubMsg->Buffer += 1;
1709 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1710 memcpy(pStubMsg->Buffer, pMemory, 2);
1711 pStubMsg->Buffer += 2;
1717 TRACE("long=%ld <= %p\n", *(DWORD*)pMemory, pMemory);
1718 memcpy(pStubMsg->Buffer, pMemory, 4);
1719 pStubMsg->Buffer += 4;
1722 case RPC_FC_POINTER:
1723 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1724 NdrPointerMarshall(pStubMsg, *(unsigned char**)pMemory, pPointer);
1728 case RPC_FC_ALIGNM4:
1729 ALIGN_POINTER(pMemory, 4);
1731 case RPC_FC_ALIGNM8:
1732 ALIGN_POINTER(pMemory, 8);
1734 case RPC_FC_STRUCTPAD2:
1737 case RPC_FC_EMBEDDED_COMPLEX:
1738 pMemory += pFormat[1];
1740 desc = pFormat + *(const SHORT*)pFormat;
1741 size = EmbeddedComplexSize(pStubMsg, desc);
1742 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1743 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1744 if (m) m(pStubMsg, pMemory, desc);
1745 else FIXME("no marshaller for embedded type %02x\n", *desc);
1752 FIXME("unhandled format %02x\n", *pFormat);
1760 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1761 unsigned char *pMemory,
1762 PFORMAT_STRING pFormat,
1763 PFORMAT_STRING pPointer)
1765 PFORMAT_STRING desc;
1769 while (*pFormat != RPC_FC_END) {
1775 memcpy(pMemory, pStubMsg->Buffer, 1);
1776 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
1777 pStubMsg->Buffer += 1;
1783 memcpy(pMemory, pStubMsg->Buffer, 2);
1784 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1785 pStubMsg->Buffer += 2;
1791 memcpy(pMemory, pStubMsg->Buffer, 4);
1792 TRACE("long=%ld => %p\n", *(DWORD*)pMemory, pMemory);
1793 pStubMsg->Buffer += 4;
1796 case RPC_FC_POINTER:
1797 TRACE("pointer => %p\n", pMemory);
1798 NdrPointerUnmarshall(pStubMsg, (unsigned char**)pMemory, pPointer, TRUE);
1802 case RPC_FC_ALIGNM4:
1803 ALIGN_POINTER(pMemory, 4);
1805 case RPC_FC_ALIGNM8:
1806 ALIGN_POINTER(pMemory, 8);
1808 case RPC_FC_STRUCTPAD2:
1811 case RPC_FC_EMBEDDED_COMPLEX:
1812 pMemory += pFormat[1];
1814 desc = pFormat + *(const SHORT*)pFormat;
1815 size = EmbeddedComplexSize(pStubMsg, desc);
1816 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
1817 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1818 memset(pMemory, 0, size); /* just in case */
1819 if (m) m(pStubMsg, &pMemory, desc, FALSE);
1820 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
1827 FIXME("unhandled format %d\n", *pFormat);
1835 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1836 unsigned char *pMemory,
1837 PFORMAT_STRING pFormat,
1838 PFORMAT_STRING pPointer)
1840 PFORMAT_STRING desc;
1844 while (*pFormat != RPC_FC_END) {
1850 pStubMsg->BufferLength += 1;
1856 pStubMsg->BufferLength += 2;
1862 pStubMsg->BufferLength += 4;
1865 case RPC_FC_POINTER:
1866 NdrPointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
1870 case RPC_FC_ALIGNM4:
1871 ALIGN_POINTER(pMemory, 4);
1873 case RPC_FC_ALIGNM8:
1874 ALIGN_POINTER(pMemory, 8);
1876 case RPC_FC_STRUCTPAD2:
1879 case RPC_FC_EMBEDDED_COMPLEX:
1880 pMemory += pFormat[1];
1882 desc = pFormat + *(const SHORT*)pFormat;
1883 size = EmbeddedComplexSize(pStubMsg, desc);
1884 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1885 if (m) m(pStubMsg, pMemory, desc);
1886 else FIXME("no buffersizer for embedded type %02x\n", *desc);
1893 FIXME("unhandled format %d\n", *pFormat);
1901 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
1902 unsigned char *pMemory,
1903 PFORMAT_STRING pFormat,
1904 PFORMAT_STRING pPointer)
1906 PFORMAT_STRING desc;
1910 while (*pFormat != RPC_FC_END) {
1928 case RPC_FC_POINTER:
1929 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
1933 case RPC_FC_ALIGNM4:
1934 ALIGN_POINTER(pMemory, 4);
1936 case RPC_FC_ALIGNM8:
1937 ALIGN_POINTER(pMemory, 8);
1939 case RPC_FC_STRUCTPAD2:
1942 case RPC_FC_EMBEDDED_COMPLEX:
1943 pMemory += pFormat[1];
1945 desc = pFormat + *(const SHORT*)pFormat;
1946 size = EmbeddedComplexSize(pStubMsg, desc);
1947 m = NdrFreer[*desc & NDR_TABLE_MASK];
1948 if (m) m(pStubMsg, pMemory, desc);
1949 else FIXME("no freer for embedded type %02x\n", *desc);
1956 FIXME("unhandled format %d\n", *pFormat);
1964 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1965 PFORMAT_STRING pFormat)
1967 PFORMAT_STRING desc;
1968 unsigned long size = 0;
1970 while (*pFormat != RPC_FC_END) {
1977 pStubMsg->Buffer += 1;
1983 pStubMsg->Buffer += 2;
1989 pStubMsg->Buffer += 4;
1991 case RPC_FC_POINTER:
1993 pStubMsg->Buffer += 4;
1995 case RPC_FC_ALIGNM4:
1996 ALIGN_LENGTH(size, 4);
1997 ALIGN_POINTER(pStubMsg->Buffer, 4);
1999 case RPC_FC_ALIGNM8:
2000 ALIGN_LENGTH(size, 8);
2001 ALIGN_POINTER(pStubMsg->Buffer, 8);
2003 case RPC_FC_STRUCTPAD2:
2005 pStubMsg->Buffer += 2;
2007 case RPC_FC_EMBEDDED_COMPLEX:
2010 desc = pFormat + *(const SHORT*)pFormat;
2011 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2017 FIXME("unhandled format %d\n", *pFormat);
2025 /***********************************************************************
2026 * NdrComplexStructMarshall [RPCRT4.@]
2028 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2029 unsigned char *pMemory,
2030 PFORMAT_STRING pFormat)
2032 PFORMAT_STRING conf_array = NULL;
2033 PFORMAT_STRING pointer_desc = NULL;
2034 unsigned char *OldMemory = pStubMsg->Memory;
2036 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2038 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2041 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2043 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2046 pStubMsg->Memory = pMemory;
2048 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2051 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2053 pStubMsg->Memory = OldMemory;
2055 STD_OVERFLOW_CHECK(pStubMsg);
2060 /***********************************************************************
2061 * NdrComplexStructUnmarshall [RPCRT4.@]
2063 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2064 unsigned char **ppMemory,
2065 PFORMAT_STRING pFormat,
2066 unsigned char fMustAlloc)
2068 unsigned size = *(const WORD*)(pFormat+2);
2069 PFORMAT_STRING conf_array = NULL;
2070 PFORMAT_STRING pointer_desc = NULL;
2071 unsigned char *pMemory;
2073 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2075 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2077 if (fMustAlloc || !*ppMemory)
2079 *ppMemory = NdrAllocate(pStubMsg, size);
2080 memset(*ppMemory, 0, size);
2084 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2086 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2089 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2092 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2097 /***********************************************************************
2098 * NdrComplexStructBufferSize [RPCRT4.@]
2100 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2101 unsigned char *pMemory,
2102 PFORMAT_STRING pFormat)
2104 PFORMAT_STRING conf_array = NULL;
2105 PFORMAT_STRING pointer_desc = NULL;
2106 unsigned char *OldMemory = pStubMsg->Memory;
2108 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2110 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2113 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2115 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2118 pStubMsg->Memory = pMemory;
2120 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2123 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2125 pStubMsg->Memory = OldMemory;
2128 /***********************************************************************
2129 * NdrComplexStructMemorySize [RPCRT4.@]
2131 unsigned long WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2132 PFORMAT_STRING pFormat)
2134 unsigned size = *(const WORD*)(pFormat+2);
2135 PFORMAT_STRING conf_array = NULL;
2136 PFORMAT_STRING pointer_desc = NULL;
2138 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2140 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2143 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2145 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2148 ComplexStructMemorySize(pStubMsg, pFormat);
2151 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2156 /***********************************************************************
2157 * NdrComplexStructFree [RPCRT4.@]
2159 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2160 unsigned char *pMemory,
2161 PFORMAT_STRING pFormat)
2163 PFORMAT_STRING conf_array = NULL;
2164 PFORMAT_STRING pointer_desc = NULL;
2165 unsigned char *OldMemory = pStubMsg->Memory;
2167 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2170 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2172 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2175 pStubMsg->Memory = pMemory;
2177 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2180 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2182 pStubMsg->Memory = OldMemory;
2185 /***********************************************************************
2186 * NdrConformantArrayMarshall [RPCRT4.@]
2188 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2189 unsigned char *pMemory,
2190 PFORMAT_STRING pFormat)
2192 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2193 unsigned char alignment = pFormat[1] + 1;
2195 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2196 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2198 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2199 size = pStubMsg->MaxCount;
2201 WriteConformance(pStubMsg);
2203 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2205 memcpy(pStubMsg->Buffer, pMemory, size*esize);
2206 pStubMsg->BufferMark = pStubMsg->Buffer;
2207 pStubMsg->Buffer += size*esize;
2209 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2211 STD_OVERFLOW_CHECK(pStubMsg);
2216 /***********************************************************************
2217 * NdrConformantArrayUnmarshall [RPCRT4.@]
2219 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2220 unsigned char **ppMemory,
2221 PFORMAT_STRING pFormat,
2222 unsigned char fMustAlloc)
2224 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2225 unsigned char alignment = pFormat[1] + 1;
2227 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2228 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2230 pFormat = ReadConformance(pStubMsg, pFormat+4);
2231 size = pStubMsg->MaxCount;
2233 if (fMustAlloc || !*ppMemory)
2234 *ppMemory = NdrAllocate(pStubMsg, size*esize);
2236 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2238 memcpy(*ppMemory, pStubMsg->Buffer, size*esize);
2240 pStubMsg->BufferMark = pStubMsg->Buffer;
2241 pStubMsg->Buffer += size*esize;
2243 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2248 /***********************************************************************
2249 * NdrConformantArrayBufferSize [RPCRT4.@]
2251 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2252 unsigned char *pMemory,
2253 PFORMAT_STRING pFormat)
2255 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2256 unsigned char alignment = pFormat[1] + 1;
2258 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2259 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2261 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2262 size = pStubMsg->MaxCount;
2264 SizeConformance(pStubMsg);
2266 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2268 /* conformance value plus array */
2269 pStubMsg->BufferLength += size*esize;
2271 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2274 /***********************************************************************
2275 * NdrConformantArrayMemorySize [RPCRT4.@]
2277 unsigned long WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2278 PFORMAT_STRING pFormat)
2280 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2281 unsigned char alignment = pFormat[1] + 1;
2283 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2284 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2286 pFormat = ReadConformance(pStubMsg, pFormat+4);
2287 size = pStubMsg->MaxCount;
2288 pStubMsg->MemorySize += size*esize;
2290 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2291 pStubMsg->BufferMark = pStubMsg->Buffer;
2292 pStubMsg->Buffer += size*esize;
2294 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2296 return pStubMsg->MemorySize;
2299 /***********************************************************************
2300 * NdrConformantArrayFree [RPCRT4.@]
2302 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2303 unsigned char *pMemory,
2304 PFORMAT_STRING pFormat)
2306 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2307 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2309 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2313 /***********************************************************************
2314 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2316 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2317 unsigned char* pMemory,
2318 PFORMAT_STRING pFormat )
2321 unsigned char alignment = pFormat[1] + 1;
2322 DWORD esize = *(const WORD*)(pFormat+2);
2324 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2326 if (pFormat[0] != RPC_FC_CVARRAY)
2328 ERR("invalid format type %x\n", pFormat[0]);
2329 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2333 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2334 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2336 WriteConformance(pStubMsg);
2337 WriteVariance(pStubMsg);
2339 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2341 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2343 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
2344 pStubMsg->BufferMark = pStubMsg->Buffer;
2345 pStubMsg->Buffer += bufsize;
2347 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2349 STD_OVERFLOW_CHECK(pStubMsg);
2355 /***********************************************************************
2356 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2358 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2359 unsigned char** ppMemory,
2360 PFORMAT_STRING pFormat,
2361 unsigned char fMustAlloc )
2363 ULONG bufsize, memsize;
2364 unsigned char alignment = pFormat[1] + 1;
2365 DWORD esize = *(const WORD*)(pFormat+2);
2367 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2369 if (pFormat[0] != RPC_FC_CVARRAY)
2371 ERR("invalid format type %x\n", pFormat[0]);
2372 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2376 pFormat = ReadConformance(pStubMsg, pFormat+4);
2377 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2379 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2381 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2382 TRACE("esize = %ld, pStubMsg->MaxCount = %ld, result = %ld\n", esize, pStubMsg->MaxCount, esize * pStubMsg->MaxCount);
2383 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2385 if (!*ppMemory || fMustAlloc)
2386 *ppMemory = NdrAllocate(pStubMsg, memsize);
2387 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
2388 pStubMsg->Buffer += bufsize;
2390 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2396 /***********************************************************************
2397 * NdrConformantVaryingArrayFree [RPCRT4.@]
2399 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2400 unsigned char* pMemory,
2401 PFORMAT_STRING pFormat )
2403 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2405 if (pFormat[0] != RPC_FC_CVARRAY)
2407 ERR("invalid format type %x\n", pFormat[0]);
2408 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2412 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2413 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2415 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2419 /***********************************************************************
2420 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2422 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2423 unsigned char* pMemory, PFORMAT_STRING pFormat )
2425 unsigned char alignment = pFormat[1] + 1;
2426 DWORD esize = *(const WORD*)(pFormat+2);
2428 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2430 if (pFormat[0] != RPC_FC_CVARRAY)
2432 ERR("invalid format type %x\n", pFormat[0]);
2433 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2438 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2439 /* compute length */
2440 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2442 SizeConformance(pStubMsg);
2443 SizeVariance(pStubMsg);
2445 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2447 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
2449 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2453 /***********************************************************************
2454 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2456 unsigned long WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2457 PFORMAT_STRING pFormat )
2464 /***********************************************************************
2465 * NdrComplexArrayMarshall [RPCRT4.@]
2467 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2468 unsigned char *pMemory,
2469 PFORMAT_STRING pFormat)
2471 ULONG i, count, def;
2472 BOOL variance_present;
2473 unsigned char alignment;
2475 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2477 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2479 ERR("invalid format type %x\n", pFormat[0]);
2480 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2484 alignment = pFormat[1] + 1;
2486 def = *(const WORD*)&pFormat[2];
2489 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2490 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2492 variance_present = IsConformanceOrVariancePresent(pFormat);
2493 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2494 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2496 WriteConformance(pStubMsg);
2497 if (variance_present)
2498 WriteVariance(pStubMsg);
2500 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2502 count = pStubMsg->ActualCount;
2503 for (i = 0; i < count; i++)
2504 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2506 STD_OVERFLOW_CHECK(pStubMsg);
2511 /***********************************************************************
2512 * NdrComplexArrayUnmarshall [RPCRT4.@]
2514 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2515 unsigned char **ppMemory,
2516 PFORMAT_STRING pFormat,
2517 unsigned char fMustAlloc)
2519 ULONG i, count, esize, memsize;
2520 unsigned char alignment;
2521 unsigned char *pMemory;
2522 unsigned char *Buffer;
2524 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2526 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2528 ERR("invalid format type %x\n", pFormat[0]);
2529 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2533 alignment = pFormat[1] + 1;
2537 pFormat = ReadConformance(pStubMsg, pFormat);
2538 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2540 Buffer = pStubMsg->Buffer;
2541 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2542 pStubMsg->Buffer = Buffer;
2544 /* do multiply here instead of inside if block to verify MaxCount */
2545 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2546 if (fMustAlloc || !*ppMemory)
2548 *ppMemory = NdrAllocate(pStubMsg, memsize);
2549 memset(*ppMemory, 0, memsize);
2552 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2554 pMemory = *ppMemory;
2555 count = pStubMsg->ActualCount;
2556 for (i = 0; i < count; i++)
2557 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
2562 /***********************************************************************
2563 * NdrComplexArrayBufferSize [RPCRT4.@]
2565 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2566 unsigned char *pMemory,
2567 PFORMAT_STRING pFormat)
2569 ULONG i, count, def;
2570 unsigned char alignment;
2571 BOOL variance_present;
2573 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2575 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2577 ERR("invalid format type %x\n", pFormat[0]);
2578 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2582 alignment = pFormat[1] + 1;
2584 def = *(const WORD*)&pFormat[2];
2587 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2588 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2589 SizeConformance(pStubMsg);
2591 variance_present = IsConformanceOrVariancePresent(pFormat);
2592 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2593 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2595 if (variance_present)
2596 SizeVariance(pStubMsg);
2598 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2600 count = pStubMsg->ActualCount;
2601 for (i = 0; i < count; i++)
2602 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
2605 /***********************************************************************
2606 * NdrComplexArrayMemorySize [RPCRT4.@]
2608 unsigned long WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2609 PFORMAT_STRING pFormat)
2611 ULONG i, count, esize;
2612 unsigned char alignment;
2613 unsigned char *Buffer;
2614 unsigned long SavedMemorySize;
2615 unsigned long MemorySize;
2617 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2619 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2621 ERR("invalid format type %x\n", pFormat[0]);
2622 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2626 alignment = pFormat[1] + 1;
2630 pFormat = ReadConformance(pStubMsg, pFormat);
2631 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2633 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2635 SavedMemorySize = pStubMsg->MemorySize;
2637 Buffer = pStubMsg->Buffer;
2638 pStubMsg->MemorySize = 0;
2639 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2640 pStubMsg->Buffer = Buffer;
2642 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
2644 count = pStubMsg->ActualCount;
2645 for (i = 0; i < count; i++)
2646 ComplexStructMemorySize(pStubMsg, pFormat);
2648 pStubMsg->MemorySize = SavedMemorySize;
2650 pStubMsg->MemorySize += MemorySize;
2654 /***********************************************************************
2655 * NdrComplexArrayFree [RPCRT4.@]
2657 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2658 unsigned char *pMemory,
2659 PFORMAT_STRING pFormat)
2661 ULONG i, count, def;
2663 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2665 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2667 ERR("invalid format type %x\n", pFormat[0]);
2668 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2672 def = *(const WORD*)&pFormat[2];
2675 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2676 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2678 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2679 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2681 count = pStubMsg->ActualCount;
2682 for (i = 0; i < count; i++)
2683 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2686 static unsigned long UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
2688 return MAKELONG(pStubMsg->dwDestContext,
2689 pStubMsg->RpcMsg->DataRepresentation);
2692 #define USER_MARSHAL_PTR_PREFIX \
2693 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
2694 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
2696 /***********************************************************************
2697 * NdrUserMarshalMarshall [RPCRT4.@]
2699 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2700 unsigned char *pMemory,
2701 PFORMAT_STRING pFormat)
2703 unsigned flags = pFormat[1];
2704 unsigned index = *(const WORD*)&pFormat[2];
2705 unsigned long uflag = UserMarshalFlags(pStubMsg);
2706 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2707 TRACE("index=%d\n", index);
2709 if (flags & USER_MARSHAL_POINTER)
2711 ALIGN_POINTER(pStubMsg->Buffer, 4);
2712 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
2713 pStubMsg->Buffer += 4;
2714 ALIGN_POINTER(pStubMsg->Buffer, 8);
2717 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2720 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
2721 &uflag, pStubMsg->Buffer, pMemory);
2723 STD_OVERFLOW_CHECK(pStubMsg);
2728 /***********************************************************************
2729 * NdrUserMarshalUnmarshall [RPCRT4.@]
2731 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2732 unsigned char **ppMemory,
2733 PFORMAT_STRING pFormat,
2734 unsigned char fMustAlloc)
2736 unsigned flags = pFormat[1];
2737 unsigned index = *(const WORD*)&pFormat[2];
2738 DWORD memsize = *(const WORD*)&pFormat[4];
2739 unsigned long uflag = UserMarshalFlags(pStubMsg);
2740 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2741 TRACE("index=%d\n", index);
2743 if (flags & USER_MARSHAL_POINTER)
2745 ALIGN_POINTER(pStubMsg->Buffer, 4);
2746 /* skip pointer prefix */
2747 pStubMsg->Buffer += 4;
2748 ALIGN_POINTER(pStubMsg->Buffer, 8);
2751 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2753 if (fMustAlloc || !*ppMemory)
2754 *ppMemory = NdrAllocate(pStubMsg, memsize);
2757 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
2758 &uflag, pStubMsg->Buffer, *ppMemory);
2763 /***********************************************************************
2764 * NdrUserMarshalBufferSize [RPCRT4.@]
2766 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2767 unsigned char *pMemory,
2768 PFORMAT_STRING pFormat)
2770 unsigned flags = pFormat[1];
2771 unsigned index = *(const WORD*)&pFormat[2];
2772 DWORD bufsize = *(const WORD*)&pFormat[6];
2773 unsigned long uflag = UserMarshalFlags(pStubMsg);
2774 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2775 TRACE("index=%d\n", index);
2777 if (flags & USER_MARSHAL_POINTER)
2779 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2780 /* skip pointer prefix */
2781 pStubMsg->BufferLength += 4;
2782 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
2785 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
2788 TRACE("size=%ld\n", bufsize);
2789 pStubMsg->BufferLength += bufsize;
2793 pStubMsg->BufferLength =
2794 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
2795 &uflag, pStubMsg->BufferLength, pMemory);
2798 /***********************************************************************
2799 * NdrUserMarshalMemorySize [RPCRT4.@]
2801 unsigned long WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2802 PFORMAT_STRING pFormat)
2804 unsigned flags = pFormat[1];
2805 unsigned index = *(const WORD*)&pFormat[2];
2806 DWORD memsize = *(const WORD*)&pFormat[4];
2807 DWORD bufsize = *(const WORD*)&pFormat[6];
2809 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2810 TRACE("index=%d\n", index);
2812 pStubMsg->MemorySize += memsize;
2814 if (flags & USER_MARSHAL_POINTER)
2816 ALIGN_POINTER(pStubMsg->Buffer, 4);
2817 /* skip pointer prefix */
2818 pStubMsg->Buffer += 4;
2819 ALIGN_POINTER(pStubMsg->Buffer, 8);
2822 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2824 pStubMsg->Buffer += bufsize;
2826 return pStubMsg->MemorySize;
2829 /***********************************************************************
2830 * NdrUserMarshalFree [RPCRT4.@]
2832 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
2833 unsigned char *pMemory,
2834 PFORMAT_STRING pFormat)
2836 /* unsigned flags = pFormat[1]; */
2837 unsigned index = *(const WORD*)&pFormat[2];
2838 unsigned long uflag = UserMarshalFlags(pStubMsg);
2839 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2840 TRACE("index=%d\n", index);
2842 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
2846 /***********************************************************************
2847 * NdrClearOutParameters [RPCRT4.@]
2849 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
2850 PFORMAT_STRING pFormat,
2853 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
2856 /***********************************************************************
2857 * NdrConvert [RPCRT4.@]
2859 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
2861 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
2862 /* FIXME: since this stub doesn't do any converting, the proper behavior
2863 is to raise an exception */
2866 /***********************************************************************
2867 * NdrConvert2 [RPCRT4.@]
2869 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, long NumberParams )
2871 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %ld): stub.\n",
2872 pStubMsg, pFormat, NumberParams);
2873 /* FIXME: since this stub doesn't do any converting, the proper behavior
2874 is to raise an exception */
2877 typedef struct _NDR_CSTRUCT_FORMAT
2880 unsigned char alignment;
2881 unsigned short memory_size;
2882 short offset_to_array_description;
2883 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
2885 /***********************************************************************
2886 * NdrConformantStructMarshall [RPCRT4.@]
2888 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2889 unsigned char *pMemory,
2890 PFORMAT_STRING pFormat)
2892 const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
2893 PFORMAT_STRING pCArrayFormat;
2894 ULONG esize, bufsize;
2896 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2898 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2899 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2901 ERR("invalid format type %x\n", pCStructFormat->type);
2902 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2906 pCArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
2907 pCStructFormat->offset_to_array_description;
2908 if (*pCArrayFormat != RPC_FC_CARRAY)
2910 ERR("invalid array format type %x\n", pCStructFormat->type);
2911 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2914 esize = *(const WORD*)(pCArrayFormat+2);
2916 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
2917 pCArrayFormat + 4, 0);
2919 WriteConformance(pStubMsg);
2921 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
2923 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2925 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
2926 /* copy constant sized part of struct */
2927 pStubMsg->BufferMark = pStubMsg->Buffer;
2928 memcpy(pStubMsg->Buffer, pMemory, pCStructFormat->memory_size + bufsize);
2929 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
2931 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2932 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2934 STD_OVERFLOW_CHECK(pStubMsg);
2939 /***********************************************************************
2940 * NdrConformantStructUnmarshall [RPCRT4.@]
2942 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2943 unsigned char **ppMemory,
2944 PFORMAT_STRING pFormat,
2945 unsigned char fMustAlloc)
2947 const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
2948 PFORMAT_STRING pCArrayFormat;
2949 ULONG esize, bufsize;
2951 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2953 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2954 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2956 ERR("invalid format type %x\n", pCStructFormat->type);
2957 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2960 pCArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
2961 pCStructFormat->offset_to_array_description;
2962 if (*pCArrayFormat != RPC_FC_CARRAY)
2964 ERR("invalid array format type %x\n", pCStructFormat->type);
2965 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2968 esize = *(const WORD*)(pCArrayFormat+2);
2970 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
2972 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
2974 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2976 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
2977 /* work out how much memory to allocate if we need to do so */
2978 if (!*ppMemory || fMustAlloc)
2980 SIZE_T size = pCStructFormat->memory_size + bufsize;
2981 *ppMemory = NdrAllocate(pStubMsg, size);
2984 /* now copy the data */
2985 pStubMsg->BufferMark = pStubMsg->Buffer;
2986 memcpy(*ppMemory, pStubMsg->Buffer, pCStructFormat->memory_size + bufsize);
2987 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
2989 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2990 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2995 /***********************************************************************
2996 * NdrConformantStructBufferSize [RPCRT4.@]
2998 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2999 unsigned char *pMemory,
3000 PFORMAT_STRING pFormat)
3002 const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
3003 PFORMAT_STRING pCArrayFormat;
3006 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3008 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3009 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3011 ERR("invalid format type %x\n", pCStructFormat->type);
3012 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3015 pCArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
3016 pCStructFormat->offset_to_array_description;
3017 if (*pCArrayFormat != RPC_FC_CARRAY)
3019 ERR("invalid array format type %x\n", pCStructFormat->type);
3020 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3023 esize = *(const WORD*)(pCArrayFormat+2);
3025 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
3026 SizeConformance(pStubMsg);
3028 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
3030 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3032 pStubMsg->BufferLength += pCStructFormat->memory_size +
3033 safe_multiply(pStubMsg->MaxCount, esize);
3035 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3036 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3039 /***********************************************************************
3040 * NdrConformantStructMemorySize [RPCRT4.@]
3042 unsigned long WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3043 PFORMAT_STRING pFormat)
3049 /***********************************************************************
3050 * NdrConformantStructFree [RPCRT4.@]
3052 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3053 unsigned char *pMemory,
3054 PFORMAT_STRING pFormat)
3059 /***********************************************************************
3060 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3062 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3063 unsigned char *pMemory,
3064 PFORMAT_STRING pFormat)
3066 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3067 PFORMAT_STRING pCVArrayFormat;
3068 ULONG esize, bufsize;
3070 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3072 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3073 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3075 ERR("invalid format type %x\n", pCVStructFormat->type);
3076 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3080 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3081 pCVStructFormat->offset_to_array_description;
3082 switch (*pCVArrayFormat)
3084 case RPC_FC_CVARRAY:
3085 esize = *(const WORD*)(pCVArrayFormat+2);
3087 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3088 pCVArrayFormat + 4, 0);
3089 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3092 case RPC_FC_C_CSTRING:
3093 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3094 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3095 esize = sizeof(char);
3096 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3097 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3098 pCVArrayFormat + 2, 0);
3100 pStubMsg->MaxCount = pStubMsg->ActualCount;
3102 case RPC_FC_C_WSTRING:
3103 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3104 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3105 esize = sizeof(WCHAR);
3106 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3107 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3108 pCVArrayFormat + 2, 0);
3110 pStubMsg->MaxCount = pStubMsg->ActualCount;
3113 ERR("invalid array format type %x\n", *pCVArrayFormat);
3114 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3118 WriteConformance(pStubMsg);
3120 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3122 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3124 /* write constant sized part */
3125 pStubMsg->BufferMark = pStubMsg->Buffer;
3126 memcpy(pStubMsg->Buffer, pMemory, pCVStructFormat->memory_size);
3127 pStubMsg->Buffer += pCVStructFormat->memory_size;
3129 WriteVariance(pStubMsg);
3131 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3133 /* write array part */
3134 memcpy(pStubMsg->Buffer, pMemory + pCVStructFormat->memory_size, bufsize);
3135 pStubMsg->Buffer += bufsize;
3137 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3139 STD_OVERFLOW_CHECK(pStubMsg);
3144 /***********************************************************************
3145 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3147 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3148 unsigned char **ppMemory,
3149 PFORMAT_STRING pFormat,
3150 unsigned char fMustAlloc)
3152 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3153 PFORMAT_STRING pCVArrayFormat;
3154 ULONG esize, bufsize;
3155 unsigned char cvarray_type;
3157 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3159 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3160 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3162 ERR("invalid format type %x\n", pCVStructFormat->type);
3163 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3167 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3168 pCVStructFormat->offset_to_array_description;
3169 cvarray_type = *pCVArrayFormat;
3170 switch (cvarray_type)
3172 case RPC_FC_CVARRAY:
3173 esize = *(const WORD*)(pCVArrayFormat+2);
3174 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3176 case RPC_FC_C_CSTRING:
3177 esize = sizeof(char);
3178 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3179 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3181 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3183 case RPC_FC_C_WSTRING:
3184 esize = sizeof(WCHAR);
3185 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3186 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3188 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3191 ERR("invalid array format type %x\n", *pCVArrayFormat);
3192 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3196 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3198 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3200 /* work out how much memory to allocate if we need to do so */
3201 if (!*ppMemory || fMustAlloc)
3203 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3204 *ppMemory = NdrAllocate(pStubMsg, size);
3207 /* copy the constant data */
3208 pStubMsg->BufferMark = pStubMsg->Buffer;
3209 memcpy(*ppMemory, pStubMsg->Buffer, pCVStructFormat->memory_size);
3210 pStubMsg->Buffer += pCVStructFormat->memory_size;
3212 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3214 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3216 if ((cvarray_type == RPC_FC_C_CSTRING) ||
3217 (cvarray_type == RPC_FC_C_WSTRING))
3220 /* strings must always have null terminating bytes */
3221 if (bufsize < esize)
3223 ERR("invalid string length of %ld\n", pStubMsg->ActualCount);
3224 RpcRaiseException(RPC_S_INVALID_BOUND);
3227 for (i = bufsize - esize; i < bufsize; i++)
3228 if (pStubMsg->Buffer[i] != 0)
3230 ERR("string not null-terminated at byte position %ld, data is 0x%x\n",
3231 i, pStubMsg->Buffer[i]);
3232 RpcRaiseException(RPC_S_INVALID_BOUND);
3237 /* copy the array data */
3238 memcpy(*ppMemory + pCVStructFormat->memory_size, pStubMsg->Buffer,
3240 pStubMsg->Buffer += bufsize;
3242 if (cvarray_type == RPC_FC_C_CSTRING)
3243 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3244 else if (cvarray_type == RPC_FC_C_WSTRING)
3245 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3247 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3252 /***********************************************************************
3253 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3255 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3256 unsigned char *pMemory,
3257 PFORMAT_STRING pFormat)
3259 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3260 PFORMAT_STRING pCVArrayFormat;
3263 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3265 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3266 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3268 ERR("invalid format type %x\n", pCVStructFormat->type);
3269 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3273 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3274 pCVStructFormat->offset_to_array_description;
3275 switch (*pCVArrayFormat)
3277 case RPC_FC_CVARRAY:
3278 esize = *(const WORD*)(pCVArrayFormat+2);
3280 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3281 pCVArrayFormat + 4, 0);
3282 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3285 case RPC_FC_C_CSTRING:
3286 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3287 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3288 esize = sizeof(char);
3289 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3290 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3291 pCVArrayFormat + 2, 0);
3293 pStubMsg->MaxCount = pStubMsg->ActualCount;
3295 case RPC_FC_C_WSTRING:
3296 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3297 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3298 esize = sizeof(WCHAR);
3299 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3300 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3301 pCVArrayFormat + 2, 0);
3303 pStubMsg->MaxCount = pStubMsg->ActualCount;
3306 ERR("invalid array format type %x\n", *pCVArrayFormat);
3307 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3311 SizeConformance(pStubMsg);
3313 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
3315 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3317 pStubMsg->BufferLength += pCVStructFormat->memory_size;
3318 SizeVariance(pStubMsg);
3319 pStubMsg->BufferLength += safe_multiply(pStubMsg->MaxCount, esize);
3321 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3324 /***********************************************************************
3325 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3327 unsigned long WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3328 PFORMAT_STRING pFormat)
3330 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3331 PFORMAT_STRING pCVArrayFormat;
3333 unsigned char cvarray_type;
3335 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3337 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3338 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3340 ERR("invalid format type %x\n", pCVStructFormat->type);
3341 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3345 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3346 pCVStructFormat->offset_to_array_description;
3347 cvarray_type = *pCVArrayFormat;
3348 switch (cvarray_type)
3350 case RPC_FC_CVARRAY:
3351 esize = *(const WORD*)(pCVArrayFormat+2);
3352 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3354 case RPC_FC_C_CSTRING:
3355 esize = sizeof(char);
3356 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3357 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3359 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3361 case RPC_FC_C_WSTRING:
3362 esize = sizeof(WCHAR);
3363 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3364 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3366 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3369 ERR("invalid array format type %x\n", *pCVArrayFormat);
3370 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3374 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3376 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3378 pStubMsg->Buffer += pCVStructFormat->memory_size;
3379 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3380 pStubMsg->Buffer += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->ActualCount);
3382 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3384 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3386 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3389 /***********************************************************************
3390 * NdrConformantVaryingStructFree [RPCRT4.@]
3392 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3393 unsigned char *pMemory,
3394 PFORMAT_STRING pFormat)
3396 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3397 PFORMAT_STRING pCVArrayFormat;
3400 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3402 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3403 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3405 ERR("invalid format type %x\n", pCVStructFormat->type);
3406 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3410 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3411 pCVStructFormat->offset_to_array_description;
3412 switch (*pCVArrayFormat)
3414 case RPC_FC_CVARRAY:
3415 esize = *(const WORD*)(pCVArrayFormat+2);
3417 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3418 pCVArrayFormat + 4, 0);
3419 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3422 case RPC_FC_C_CSTRING:
3423 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3424 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3425 esize = sizeof(char);
3426 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3427 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3428 pCVArrayFormat + 2, 0);
3430 pStubMsg->MaxCount = pStubMsg->ActualCount;
3432 case RPC_FC_C_WSTRING:
3433 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3434 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3435 esize = sizeof(WCHAR);
3436 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3437 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3438 pCVArrayFormat + 2, 0);
3440 pStubMsg->MaxCount = pStubMsg->ActualCount;
3443 ERR("invalid array format type %x\n", *pCVArrayFormat);
3444 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3448 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3450 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3456 unsigned char alignment;
3457 unsigned short total_size;
3458 } NDR_SMFARRAY_FORMAT;
3463 unsigned char alignment;
3464 unsigned long total_size;
3465 } NDR_LGFARRAY_FORMAT;
3467 /***********************************************************************
3468 * NdrFixedArrayMarshall [RPCRT4.@]
3470 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3471 unsigned char *pMemory,
3472 PFORMAT_STRING pFormat)
3474 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3475 unsigned long total_size;
3477 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3479 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3480 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3482 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3483 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3487 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3489 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3491 total_size = pSmFArrayFormat->total_size;
3492 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3496 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3497 total_size = pLgFArrayFormat->total_size;
3498 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3500 memcpy(pStubMsg->Buffer, pMemory, total_size);
3501 pStubMsg->Buffer += total_size;
3503 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3508 /***********************************************************************
3509 * NdrFixedArrayUnmarshall [RPCRT4.@]
3511 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3512 unsigned char **ppMemory,
3513 PFORMAT_STRING pFormat,
3514 unsigned char fMustAlloc)
3516 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3517 unsigned long total_size;
3519 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3521 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3522 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3524 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3525 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3529 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3531 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3533 total_size = pSmFArrayFormat->total_size;
3534 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3538 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3539 total_size = pLgFArrayFormat->total_size;
3540 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3543 if (fMustAlloc || !*ppMemory)
3544 *ppMemory = NdrAllocate(pStubMsg, total_size);
3545 memcpy(*ppMemory, pStubMsg->Buffer, total_size);
3546 pStubMsg->Buffer += total_size;
3548 pFormat = EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3553 /***********************************************************************
3554 * NdrFixedArrayBufferSize [RPCRT4.@]
3556 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3557 unsigned char *pMemory,
3558 PFORMAT_STRING pFormat)
3560 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3561 unsigned long total_size;
3563 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3565 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3566 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3568 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3569 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3573 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
3575 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3577 total_size = pSmFArrayFormat->total_size;
3578 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3582 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3583 total_size = pLgFArrayFormat->total_size;
3584 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3586 pStubMsg->BufferLength += total_size;
3588 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3591 /***********************************************************************
3592 * NdrFixedArrayMemorySize [RPCRT4.@]
3594 unsigned long WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3595 PFORMAT_STRING pFormat)
3597 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3598 unsigned long total_size;
3600 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3602 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3603 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3605 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3606 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3610 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3612 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3614 total_size = pSmFArrayFormat->total_size;
3615 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3619 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3620 total_size = pLgFArrayFormat->total_size;
3621 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3623 pStubMsg->Buffer += total_size;
3624 pStubMsg->MemorySize += total_size;
3626 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3631 /***********************************************************************
3632 * NdrFixedArrayFree [RPCRT4.@]
3634 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3635 unsigned char *pMemory,
3636 PFORMAT_STRING pFormat)
3638 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3640 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3642 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3643 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3645 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3646 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3650 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3651 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3654 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3655 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3658 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3661 /***********************************************************************
3662 * NdrVaryingArrayMarshall [RPCRT4.@]
3664 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3665 unsigned char *pMemory,
3666 PFORMAT_STRING pFormat)
3668 unsigned char alignment;
3669 DWORD elements, esize;
3672 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3674 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3675 (pFormat[0] != RPC_FC_LGVARRAY))
3677 ERR("invalid format type %x\n", pFormat[0]);
3678 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3682 alignment = pFormat[1] + 1;
3684 if (pFormat[0] == RPC_FC_SMVARRAY)
3687 pFormat += sizeof(WORD);
3688 elements = *(const WORD*)pFormat;
3689 pFormat += sizeof(WORD);
3694 pFormat += sizeof(DWORD);
3695 elements = *(const DWORD*)pFormat;
3696 pFormat += sizeof(DWORD);
3699 esize = *(const WORD*)pFormat;
3700 pFormat += sizeof(WORD);
3702 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3703 if ((pStubMsg->ActualCount > elements) ||
3704 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3706 RpcRaiseException(RPC_S_INVALID_BOUND);
3710 WriteVariance(pStubMsg);
3712 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3714 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3715 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
3716 pStubMsg->BufferMark = pStubMsg->Buffer;
3717 pStubMsg->Buffer += bufsize;
3719 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3721 STD_OVERFLOW_CHECK(pStubMsg);
3726 /***********************************************************************
3727 * NdrVaryingArrayUnmarshall [RPCRT4.@]
3729 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3730 unsigned char **ppMemory,
3731 PFORMAT_STRING pFormat,
3732 unsigned char fMustAlloc)
3734 unsigned char alignment;
3735 DWORD size, elements, esize;
3738 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3740 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3741 (pFormat[0] != RPC_FC_LGVARRAY))
3743 ERR("invalid format type %x\n", pFormat[0]);
3744 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3748 alignment = pFormat[1] + 1;
3750 if (pFormat[0] == RPC_FC_SMVARRAY)
3753 size = *(const WORD*)pFormat;
3754 pFormat += sizeof(WORD);
3755 elements = *(const WORD*)pFormat;
3756 pFormat += sizeof(WORD);
3761 size = *(const DWORD*)pFormat;
3762 pFormat += sizeof(DWORD);
3763 elements = *(const DWORD*)pFormat;
3764 pFormat += sizeof(DWORD);
3767 esize = *(const WORD*)pFormat;
3768 pFormat += sizeof(WORD);
3770 pFormat = ReadVariance(pStubMsg, pFormat, elements);
3772 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3774 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3776 if (!*ppMemory || fMustAlloc)
3777 *ppMemory = NdrAllocate(pStubMsg, size);
3778 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
3779 pStubMsg->Buffer += bufsize;
3781 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3786 /***********************************************************************
3787 * NdrVaryingArrayBufferSize [RPCRT4.@]
3789 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3790 unsigned char *pMemory,
3791 PFORMAT_STRING pFormat)
3793 unsigned char alignment;
3794 DWORD elements, esize;
3796 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3798 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3799 (pFormat[0] != RPC_FC_LGVARRAY))
3801 ERR("invalid format type %x\n", pFormat[0]);
3802 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3806 alignment = pFormat[1] + 1;
3808 if (pFormat[0] == RPC_FC_SMVARRAY)
3811 pFormat += sizeof(WORD);
3812 elements = *(const WORD*)pFormat;
3813 pFormat += sizeof(WORD);
3818 pFormat += sizeof(DWORD);
3819 elements = *(const DWORD*)pFormat;
3820 pFormat += sizeof(DWORD);
3823 esize = *(const WORD*)pFormat;
3824 pFormat += sizeof(WORD);
3826 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3827 if ((pStubMsg->ActualCount > elements) ||
3828 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3830 RpcRaiseException(RPC_S_INVALID_BOUND);
3834 SizeVariance(pStubMsg);
3836 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3838 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
3840 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3843 /***********************************************************************
3844 * NdrVaryingArrayMemorySize [RPCRT4.@]
3846 unsigned long WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3847 PFORMAT_STRING pFormat)
3849 unsigned char alignment;
3850 DWORD size, elements, esize;
3852 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3854 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3855 (pFormat[0] != RPC_FC_LGVARRAY))
3857 ERR("invalid format type %x\n", pFormat[0]);
3858 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3862 alignment = pFormat[1] + 1;
3864 if (pFormat[0] == RPC_FC_SMVARRAY)
3867 size = *(const WORD*)pFormat;
3868 pFormat += sizeof(WORD);
3869 elements = *(const WORD*)pFormat;
3870 pFormat += sizeof(WORD);
3875 size = *(const DWORD*)pFormat;
3876 pFormat += sizeof(DWORD);
3877 elements = *(const DWORD*)pFormat;
3878 pFormat += sizeof(DWORD);
3881 esize = *(const WORD*)pFormat;
3882 pFormat += sizeof(WORD);
3884 pFormat = ReadVariance(pStubMsg, pFormat, elements);
3886 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3888 pStubMsg->Buffer += safe_multiply(esize, pStubMsg->ActualCount);
3889 pStubMsg->MemorySize += size;
3891 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3893 return pStubMsg->MemorySize;
3896 /***********************************************************************
3897 * NdrVaryingArrayFree [RPCRT4.@]
3899 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3900 unsigned char *pMemory,
3901 PFORMAT_STRING pFormat)
3903 unsigned char alignment;
3906 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3908 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3909 (pFormat[0] != RPC_FC_LGVARRAY))
3911 ERR("invalid format type %x\n", pFormat[0]);
3912 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3916 alignment = pFormat[1] + 1;
3918 if (pFormat[0] == RPC_FC_SMVARRAY)
3921 pFormat += sizeof(WORD);
3922 elements = *(const WORD*)pFormat;
3923 pFormat += sizeof(WORD);
3928 pFormat += sizeof(DWORD);
3929 elements = *(const DWORD*)pFormat;
3930 pFormat += sizeof(DWORD);
3933 pFormat += sizeof(WORD);
3935 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3936 if ((pStubMsg->ActualCount > elements) ||
3937 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3939 RpcRaiseException(RPC_S_INVALID_BOUND);
3943 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3946 /***********************************************************************
3947 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
3949 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3950 unsigned char *pMemory,
3951 PFORMAT_STRING pFormat)
3957 /***********************************************************************
3958 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
3960 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3961 unsigned char **ppMemory,
3962 PFORMAT_STRING pFormat,
3963 unsigned char fMustAlloc)
3969 /***********************************************************************
3970 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
3972 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3973 unsigned char *pMemory,
3974 PFORMAT_STRING pFormat)
3979 /***********************************************************************
3980 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
3982 unsigned long WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3983 PFORMAT_STRING pFormat)
3989 /***********************************************************************
3990 * NdrEncapsulatedUnionFree [RPCRT4.@]
3992 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
3993 unsigned char *pMemory,
3994 PFORMAT_STRING pFormat)
3999 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4000 unsigned long discriminant,
4001 PFORMAT_STRING pFormat)
4003 unsigned short num_arms, arm, type;
4005 num_arms = *(const SHORT*)pFormat & 0x0fff;
4007 for(arm = 0; arm < num_arms; arm++)
4009 if(discriminant == *(const ULONG*)pFormat)
4017 type = *(const unsigned short*)pFormat;
4018 TRACE("type %04x\n", type);
4019 if(arm == num_arms) /* default arm extras */
4023 ERR("no arm for 0x%lx and no default case\n", discriminant);
4024 RpcRaiseException(RPC_S_INVALID_TAG);
4029 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
4036 static PFORMAT_STRING get_non_encapsulated_union_arm(PMIDL_STUB_MESSAGE pStubMsg,
4038 PFORMAT_STRING pFormat)
4040 pFormat += *(const SHORT*)pFormat;
4043 return get_arm_offset_from_union_arm_selector(pStubMsg, value, pFormat);
4046 /***********************************************************************
4047 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
4049 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4050 unsigned char *pMemory,
4051 PFORMAT_STRING pFormat)
4053 unsigned short type;
4054 unsigned char switch_type;
4056 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4059 switch_type = *pFormat;
4062 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4063 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4064 /* Marshall discriminant */
4065 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4067 pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
4071 type = *(const unsigned short*)pFormat;
4072 if((type & 0xff00) == 0x8000)
4074 unsigned char basetype = LOBYTE(type);
4075 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
4079 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4080 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
4083 unsigned char *saved_buffer = NULL;
4090 saved_buffer = pStubMsg->Buffer;
4091 pStubMsg->Buffer += 4; /* for pointer ID */
4092 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
4095 m(pStubMsg, pMemory, desc);
4098 else FIXME("no marshaller for embedded type %02x\n", *desc);
4103 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
4104 PFORMAT_STRING *ppFormat)
4106 long discriminant = 0;
4114 discriminant = *(UCHAR *)pStubMsg->Buffer;
4115 pStubMsg->Buffer += sizeof(UCHAR);
4120 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4121 discriminant = *(USHORT *)pStubMsg->Buffer;
4122 pStubMsg->Buffer += sizeof(USHORT);
4126 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4127 discriminant = *(ULONG *)pStubMsg->Buffer;
4128 pStubMsg->Buffer += sizeof(ULONG);
4131 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
4135 if (pStubMsg->fHasNewCorrDesc)
4139 return discriminant;
4142 /**********************************************************************
4143 * NdrNonEncapsulatedUnionUnmarshall[RPCRT4.@]
4145 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4146 unsigned char **ppMemory,
4147 PFORMAT_STRING pFormat,
4148 unsigned char fMustAlloc)
4151 unsigned short type, size;
4153 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4156 /* Unmarshall discriminant */
4157 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4158 TRACE("unmarshalled discriminant %lx\n", discriminant);
4160 pFormat += *(const SHORT*)pFormat;
4162 size = *(const unsigned short*)pFormat;
4165 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4169 if(!*ppMemory || fMustAlloc)
4170 *ppMemory = NdrAllocate(pStubMsg, size);
4172 type = *(const unsigned short*)pFormat;
4173 if((type & 0xff00) == 0x8000)
4175 unsigned char basetype = LOBYTE(type);
4176 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, fMustAlloc);
4180 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4181 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
4184 unsigned char *saved_buffer = NULL;
4191 ALIGN_POINTER(pStubMsg->Buffer, 4);
4192 saved_buffer = pStubMsg->Buffer;
4193 pStubMsg->Buffer += 4; /* for pointer ID */
4194 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, desc, TRUE);
4197 m(pStubMsg, ppMemory, desc, fMustAlloc);
4200 else FIXME("no marshaller for embedded type %02x\n", *desc);
4205 /***********************************************************************
4206 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
4208 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4209 unsigned char *pMemory,
4210 PFORMAT_STRING pFormat)
4212 unsigned short type;
4213 unsigned char switch_type;
4215 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4218 switch_type = *pFormat;
4221 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4222 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4223 /* Add discriminant size */
4224 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4226 pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
4230 type = *(const unsigned short*)pFormat;
4231 if((type & 0xff00) == 0x8000)
4233 unsigned char basetype = LOBYTE(type);
4234 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
4238 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4239 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
4248 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4249 pStubMsg->BufferLength += 4; /* for pointer ID */
4250 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
4253 m(pStubMsg, pMemory, desc);
4256 else FIXME("no buffersizer for embedded type %02x\n", *desc);
4261 /***********************************************************************
4262 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
4264 unsigned long WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4265 PFORMAT_STRING pFormat)
4267 unsigned long discriminant;
4268 unsigned short type, size;
4271 /* Unmarshall discriminant */
4272 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4273 TRACE("unmarshalled discriminant 0x%lx\n", discriminant);
4275 pFormat += *(const SHORT*)pFormat;
4277 size = *(const unsigned short*)pFormat;
4280 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4284 pStubMsg->Memory += size;
4286 type = *(const unsigned short*)pFormat;
4287 if((type & 0xff00) == 0x8000)
4289 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
4293 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4294 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
4295 unsigned char *saved_buffer;
4304 ALIGN_POINTER(pStubMsg->Buffer, 4);
4305 saved_buffer = pStubMsg->Buffer;
4306 pStubMsg->Buffer += 4;
4307 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
4308 pStubMsg->MemorySize += 4;
4309 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
4312 return m(pStubMsg, desc);
4315 else FIXME("no marshaller for embedded type %02x\n", *desc);
4318 TRACE("size %d\n", size);
4322 /***********************************************************************
4323 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
4325 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4326 unsigned char *pMemory,
4327 PFORMAT_STRING pFormat)
4332 /***********************************************************************
4333 * NdrByteCountPointerMarshall [RPCRT4.@]
4335 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4336 unsigned char *pMemory,
4337 PFORMAT_STRING pFormat)
4343 /***********************************************************************
4344 * NdrByteCountPointerUnmarshall [RPCRT4.@]
4346 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4347 unsigned char **ppMemory,
4348 PFORMAT_STRING pFormat,
4349 unsigned char fMustAlloc)
4355 /***********************************************************************
4356 * NdrByteCountPointerBufferSize [RPCRT4.@]
4358 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4359 unsigned char *pMemory,
4360 PFORMAT_STRING pFormat)
4365 /***********************************************************************
4366 * NdrByteCountPointerMemorySize [RPCRT4.@]
4368 unsigned long WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4369 PFORMAT_STRING pFormat)
4375 /***********************************************************************
4376 * NdrByteCountPointerFree [RPCRT4.@]
4378 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
4379 unsigned char *pMemory,
4380 PFORMAT_STRING pFormat)
4385 /***********************************************************************
4386 * NdrXmitOrRepAsMarshall [RPCRT4.@]
4388 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4389 unsigned char *pMemory,
4390 PFORMAT_STRING pFormat)
4396 /***********************************************************************
4397 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
4399 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4400 unsigned char **ppMemory,
4401 PFORMAT_STRING pFormat,
4402 unsigned char fMustAlloc)
4408 /***********************************************************************
4409 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
4411 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4412 unsigned char *pMemory,
4413 PFORMAT_STRING pFormat)
4418 /***********************************************************************
4419 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
4421 unsigned long WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4422 PFORMAT_STRING pFormat)
4428 /***********************************************************************
4429 * NdrXmitOrRepAsFree [RPCRT4.@]
4431 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
4432 unsigned char *pMemory,
4433 PFORMAT_STRING pFormat)
4438 /***********************************************************************
4439 * NdrBaseTypeMarshall [internal]
4441 static unsigned char *WINAPI NdrBaseTypeMarshall(
4442 PMIDL_STUB_MESSAGE pStubMsg,
4443 unsigned char *pMemory,
4444 PFORMAT_STRING pFormat)
4446 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4454 *(UCHAR *)pStubMsg->Buffer = *(UCHAR *)pMemory;
4455 pStubMsg->Buffer += sizeof(UCHAR);
4456 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
4461 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4462 *(USHORT *)pStubMsg->Buffer = *(USHORT *)pMemory;
4463 pStubMsg->Buffer += sizeof(USHORT);
4464 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
4468 case RPC_FC_ERROR_STATUS_T:
4470 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4471 *(ULONG *)pStubMsg->Buffer = *(ULONG *)pMemory;
4472 pStubMsg->Buffer += sizeof(ULONG);
4473 TRACE("value: 0x%08lx\n", *(ULONG *)pMemory);
4476 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
4477 *(float *)pStubMsg->Buffer = *(float *)pMemory;
4478 pStubMsg->Buffer += sizeof(float);
4481 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
4482 *(double *)pStubMsg->Buffer = *(double *)pMemory;
4483 pStubMsg->Buffer += sizeof(double);
4486 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
4487 *(ULONGLONG *)pStubMsg->Buffer = *(ULONGLONG *)pMemory;
4488 pStubMsg->Buffer += sizeof(ULONGLONG);
4489 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
4492 /* only 16-bits on the wire, so do a sanity check */
4493 if (*(UINT *)pMemory > USHRT_MAX)
4494 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
4495 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4496 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
4497 pStubMsg->Buffer += sizeof(USHORT);
4498 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
4501 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4504 STD_OVERFLOW_CHECK(pStubMsg);
4506 /* FIXME: what is the correct return value? */
4510 /***********************************************************************
4511 * NdrBaseTypeUnmarshall [internal]
4513 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
4514 PMIDL_STUB_MESSAGE pStubMsg,
4515 unsigned char **ppMemory,
4516 PFORMAT_STRING pFormat,
4517 unsigned char fMustAlloc)
4519 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
4521 #define BASE_TYPE_UNMARSHALL(type) \
4522 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
4523 if (fMustAlloc || !*ppMemory) \
4524 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
4525 TRACE("*ppMemory: %p\n", *ppMemory); \
4526 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
4527 pStubMsg->Buffer += sizeof(type);
4535 BASE_TYPE_UNMARSHALL(UCHAR);
4536 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
4541 BASE_TYPE_UNMARSHALL(USHORT);
4542 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
4546 case RPC_FC_ERROR_STATUS_T:
4548 BASE_TYPE_UNMARSHALL(ULONG);
4549 TRACE("value: 0x%08lx\n", **(ULONG **)ppMemory);
4552 BASE_TYPE_UNMARSHALL(float);
4553 TRACE("value: %f\n", **(float **)ppMemory);
4556 BASE_TYPE_UNMARSHALL(double);
4557 TRACE("value: %f\n", **(double **)ppMemory);
4560 BASE_TYPE_UNMARSHALL(ULONGLONG);
4561 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
4564 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4565 if (fMustAlloc || !*ppMemory)
4566 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
4567 TRACE("*ppMemory: %p\n", *ppMemory);
4568 /* 16-bits on the wire, but int in memory */
4569 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
4570 pStubMsg->Buffer += sizeof(USHORT);
4571 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
4574 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4576 #undef BASE_TYPE_UNMARSHALL
4578 /* FIXME: what is the correct return value? */
4583 /***********************************************************************
4584 * NdrBaseTypeBufferSize [internal]
4586 static void WINAPI NdrBaseTypeBufferSize(
4587 PMIDL_STUB_MESSAGE pStubMsg,
4588 unsigned char *pMemory,
4589 PFORMAT_STRING pFormat)
4591 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4599 pStubMsg->BufferLength += sizeof(UCHAR);
4605 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
4606 pStubMsg->BufferLength += sizeof(USHORT);
4611 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
4612 pStubMsg->BufferLength += sizeof(ULONG);
4615 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
4616 pStubMsg->BufferLength += sizeof(float);
4619 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
4620 pStubMsg->BufferLength += sizeof(double);
4623 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
4624 pStubMsg->BufferLength += sizeof(ULONGLONG);
4626 case RPC_FC_ERROR_STATUS_T:
4627 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
4628 pStubMsg->BufferLength += sizeof(error_status_t);
4631 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4635 /***********************************************************************
4636 * NdrBaseTypeMemorySize [internal]
4638 static unsigned long WINAPI NdrBaseTypeMemorySize(
4639 PMIDL_STUB_MESSAGE pStubMsg,
4640 PFORMAT_STRING pFormat)
4648 pStubMsg->Buffer += sizeof(UCHAR);
4649 pStubMsg->MemorySize += sizeof(UCHAR);
4650 return sizeof(UCHAR);
4654 pStubMsg->Buffer += sizeof(USHORT);
4655 pStubMsg->MemorySize += sizeof(USHORT);
4656 return sizeof(USHORT);
4659 pStubMsg->Buffer += sizeof(ULONG);
4660 pStubMsg->MemorySize += sizeof(ULONG);
4661 return sizeof(ULONG);
4663 pStubMsg->Buffer += sizeof(float);
4664 pStubMsg->MemorySize += sizeof(float);
4665 return sizeof(float);
4667 pStubMsg->Buffer += sizeof(double);
4668 pStubMsg->MemorySize += sizeof(double);
4669 return sizeof(double);
4671 pStubMsg->Buffer += sizeof(ULONGLONG);
4672 pStubMsg->MemorySize += sizeof(ULONGLONG);
4673 return sizeof(ULONGLONG);
4674 case RPC_FC_ERROR_STATUS_T:
4675 pStubMsg->Buffer += sizeof(error_status_t);
4676 pStubMsg->MemorySize += sizeof(error_status_t);
4677 return sizeof(error_status_t);
4680 pStubMsg->Buffer += sizeof(INT);
4681 pStubMsg->MemorySize += sizeof(INT);
4684 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4689 /***********************************************************************
4690 * NdrBaseTypeFree [internal]
4692 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
4693 unsigned char *pMemory,
4694 PFORMAT_STRING pFormat)
4696 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4701 /***********************************************************************
4702 * NdrClientContextMarshall
4704 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4705 NDR_CCONTEXT ContextHandle,
4708 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
4710 ALIGN_POINTER(pStubMsg->Buffer, 4);
4712 /* FIXME: what does fCheck do? */
4713 NDRCContextMarshall(ContextHandle,
4716 pStubMsg->Buffer += cbNDRContext;
4719 /***********************************************************************
4720 * NdrClientContextUnmarshall
4722 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4723 NDR_CCONTEXT * pContextHandle,
4724 RPC_BINDING_HANDLE BindHandle)
4726 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
4728 ALIGN_POINTER(pStubMsg->Buffer, 4);
4730 NDRCContextUnmarshall(pContextHandle,
4733 pStubMsg->RpcMsg->DataRepresentation);
4735 pStubMsg->Buffer += cbNDRContext;
4738 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4739 NDR_SCONTEXT ContextHandle,
4740 NDR_RUNDOWN RundownRoutine )
4742 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
4745 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
4747 FIXME("(%p): stub\n", pStubMsg);
4751 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
4752 unsigned char* pMemory,
4753 PFORMAT_STRING pFormat)
4755 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
4758 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
4759 PFORMAT_STRING pFormat)
4761 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
4765 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4766 NDR_SCONTEXT ContextHandle,
4767 NDR_RUNDOWN RundownRoutine,
4768 PFORMAT_STRING pFormat)
4770 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
4773 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4774 PFORMAT_STRING pFormat)
4776 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
4780 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
4782 typedef struct ndr_context_handle
4786 } ndr_context_handle;
4788 struct context_handle_entry
4792 RPC_BINDING_HANDLE handle;
4793 ndr_context_handle wire_data;
4796 static struct list context_handle_list = LIST_INIT(context_handle_list);
4798 static CRITICAL_SECTION ndr_context_cs;
4799 static CRITICAL_SECTION_DEBUG ndr_context_debug =
4801 0, 0, &ndr_context_cs,
4802 { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
4803 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
4805 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
4807 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
4809 struct context_handle_entry *che = (struct context_handle_entry*) CContext;
4811 if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
4816 static struct context_handle_entry *context_entry_from_guid(LPGUID uuid)
4818 struct context_handle_entry *che;
4819 LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
4820 if (IsEqualGUID(&che->wire_data.uuid, uuid))
4825 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
4827 struct context_handle_entry *che;
4828 RPC_BINDING_HANDLE handle = NULL;
4830 TRACE("%p\n", CContext);
4832 EnterCriticalSection(&ndr_context_cs);
4833 che = get_context_entry(CContext);
4835 handle = che->handle;
4836 LeaveCriticalSection(&ndr_context_cs);
4839 RpcRaiseException(ERROR_INVALID_HANDLE);
4843 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
4845 struct context_handle_entry *che;
4847 TRACE("%p %p\n", CContext, pBuff);
4851 EnterCriticalSection(&ndr_context_cs);
4852 che = get_context_entry(CContext);
4853 memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
4854 LeaveCriticalSection(&ndr_context_cs);
4858 ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
4859 wire_data->attributes = 0;
4860 wire_data->uuid = GUID_NULL;
4864 static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
4865 RPC_BINDING_HANDLE hBinding,
4866 ndr_context_handle *chi)
4868 struct context_handle_entry *che = NULL;
4870 /* a null UUID means we should free the context handle */
4871 if (IsEqualGUID(&chi->uuid, &GUID_NULL))
4875 che = get_context_entry(*CContext);
4877 return ERROR_INVALID_HANDLE;
4878 list_remove(&che->entry);
4879 RpcBindingFree(&che->handle);
4880 HeapFree(GetProcessHeap(), 0, che);
4884 /* if there's no existing entry matching the GUID, allocate one */
4885 else if (!(che = context_entry_from_guid(&chi->uuid)))
4887 che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
4889 return ERROR_NOT_ENOUGH_MEMORY;
4890 che->magic = NDR_CONTEXT_HANDLE_MAGIC;
4891 RpcBindingCopy(hBinding, &che->handle);
4892 list_add_tail(&context_handle_list, &che->entry);
4893 memcpy(&che->wire_data, chi, sizeof *chi);
4898 return ERROR_SUCCESS;
4901 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
4902 RPC_BINDING_HANDLE hBinding,
4904 unsigned long DataRepresentation)
4908 TRACE("*%p=(%p) %p %p %08lx\n",
4909 CContext, *CContext, hBinding, pBuff, DataRepresentation);
4911 EnterCriticalSection(&ndr_context_cs);
4912 r = ndr_update_context_handle(CContext, hBinding, pBuff);
4913 LeaveCriticalSection(&ndr_context_cs);
4915 RpcRaiseException(r);
4918 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
4920 NDR_RUNDOWN userRunDownIn)
4922 FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn);
4925 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
4926 NDR_SCONTEXT CContext,
4928 NDR_RUNDOWN userRunDownIn)
4930 FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn);
4933 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
4934 NDR_SCONTEXT CContext,
4936 NDR_RUNDOWN userRunDownIn,
4938 unsigned long Flags)
4940 FIXME("(%p %p %p %p %p %lu): stub\n",
4941 hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags);
4944 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
4945 unsigned long DataRepresentation)
4947 FIXME("(%p %08lx): stub\n", pBuff, DataRepresentation);
4951 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
4953 unsigned long DataRepresentation)
4955 FIXME("(%p %p %08lx): stub\n", hBinding, pBuff, DataRepresentation);
4959 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
4961 unsigned long DataRepresentation,
4963 unsigned long Flags)
4965 FIXME("(%p %p %08lx %p %lu): stub\n",
4966 hBinding, pBuff, DataRepresentation, CtxGuard, Flags);