4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 * - Non-conformant strings
24 * - Encapsulated unions
25 * - Byte count pointers
26 * - transmit_as/represent as
27 * - Multi-dimensional arrays
28 * - Conversion functions (NdrConvert)
29 * - Checks for integer addition overflow
30 * - Checks for out-of-memory conditions
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/%d\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 ULONG 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 %d\n", pStubMsg->Offset);
348 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
349 pStubMsg->Buffer += 4;
350 TRACE("variance is %d\n", pStubMsg->ActualCount);
352 if ((pStubMsg->ActualCount > MaxValue) ||
353 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
355 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\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_PTR *pCount)
404 BYTE dtype = pFormat[0] & 0xf;
405 short ofs = *(const 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=%d\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;
468 /* the callback function always stores the computed value in MaxCount */
469 *pCount = pStubMsg->MaxCount;
473 ptr = (char *)ptr + ofs;
486 data = *(USHORT*)ptr;
497 FIXME("unknown conformance data type %x\n", dtype);
500 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
503 switch (pFormat[1]) {
504 case RPC_FC_DEREFERENCE: /* already handled */
521 FIXME("unknown conformance op %d\n", pFormat[1]);
526 TRACE("resulting conformance is %ld\n", *pCount);
527 if (pStubMsg->fHasNewCorrDesc)
533 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
534 * the result overflows 32-bits */
535 inline static ULONG safe_multiply(ULONG a, ULONG b)
537 ULONGLONG ret = (ULONGLONG)a * b;
538 if (ret > 0xffffffff)
540 RpcRaiseException(RPC_S_INVALID_BOUND);
548 * NdrConformantString:
550 * What MS calls a ConformantString is, in DCE terminology,
551 * a Varying-Conformant String.
553 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
554 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
555 * into unmarshalled string)
556 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
558 * data: CHARTYPE[maxlen]
560 * ], where CHARTYPE is the appropriate character type (specified externally)
564 /***********************************************************************
565 * NdrConformantStringMarshall [RPCRT4.@]
567 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
568 unsigned char *pszMessage, PFORMAT_STRING pFormat)
572 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
574 if (*pFormat == RPC_FC_C_CSTRING) {
575 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
576 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
579 else if (*pFormat == RPC_FC_C_WSTRING) {
580 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
581 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
585 ERR("Unhandled string type: %#x\n", *pFormat);
586 /* FIXME: raise an exception. */
590 if (pFormat[1] == RPC_FC_STRING_SIZED)
591 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
593 pStubMsg->MaxCount = pStubMsg->ActualCount;
594 pStubMsg->Offset = 0;
595 WriteConformance(pStubMsg);
596 WriteVariance(pStubMsg);
598 size = safe_multiply(esize, pStubMsg->ActualCount);
599 memcpy(pStubMsg->Buffer, pszMessage, size); /* the string itself */
600 pStubMsg->Buffer += size;
602 STD_OVERFLOW_CHECK(pStubMsg);
605 return NULL; /* is this always right? */
608 /***********************************************************************
609 * NdrConformantStringBufferSize [RPCRT4.@]
611 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
612 unsigned char* pMemory, PFORMAT_STRING pFormat)
616 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
618 SizeConformance(pStubMsg);
619 SizeVariance(pStubMsg);
621 if (*pFormat == RPC_FC_C_CSTRING) {
622 TRACE("string=%s\n", debugstr_a((char*)pMemory));
623 pStubMsg->ActualCount = strlen((char*)pMemory)+1;
626 else if (*pFormat == RPC_FC_C_WSTRING) {
627 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
628 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;
632 ERR("Unhandled string type: %#x\n", *pFormat);
633 /* FIXME: raise an exception */
637 if (pFormat[1] == RPC_FC_STRING_SIZED)
638 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
640 pStubMsg->MaxCount = pStubMsg->ActualCount;
642 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
645 /************************************************************************
646 * NdrConformantStringMemorySize [RPCRT4.@]
648 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
649 PFORMAT_STRING pFormat )
653 FIXME("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
655 assert(pStubMsg && pFormat);
657 if (*pFormat == RPC_FC_C_CSTRING) {
658 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
660 else if (*pFormat == RPC_FC_C_WSTRING) {
661 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
664 ERR("Unhandled string type: %#x\n", *pFormat);
665 /* FIXME: raise an exception */
668 if (pFormat[1] != RPC_FC_PAD) {
669 FIXME("sized string format=%d\n", pFormat[1]);
672 TRACE(" --> %u\n", rslt);
676 /************************************************************************
677 * NdrConformantStringUnmarshall [RPCRT4.@]
679 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
680 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
682 ULONG bufsize, memsize, esize, i;
684 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
685 pStubMsg, *ppMemory, pFormat, fMustAlloc);
687 assert(pFormat && ppMemory && pStubMsg);
689 ReadConformance(pStubMsg, NULL);
690 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
692 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
693 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
695 ERR("Unhandled string type: %#x\n", *pFormat);
696 /* FIXME: raise an exception */
700 memsize = safe_multiply(esize, pStubMsg->MaxCount);
701 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
703 /* strings must always have null terminating bytes */
706 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
707 RpcRaiseException(RPC_S_INVALID_BOUND);
710 for (i = bufsize - esize; i < bufsize; i++)
711 if (pStubMsg->Buffer[i] != 0)
713 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
714 i, pStubMsg->Buffer[i]);
715 RpcRaiseException(RPC_S_INVALID_BOUND);
719 if (fMustAlloc || !*ppMemory)
720 *ppMemory = NdrAllocate(pStubMsg, memsize);
722 memcpy(*ppMemory, pStubMsg->Buffer, bufsize);
724 pStubMsg->Buffer += bufsize;
726 if (*pFormat == RPC_FC_C_CSTRING) {
727 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
729 else if (*pFormat == RPC_FC_C_WSTRING) {
730 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
733 return NULL; /* FIXME: is this always right? */
736 /***********************************************************************
737 * NdrNonConformantStringMarshall [RPCRT4.@]
739 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
740 unsigned char *pMemory,
741 PFORMAT_STRING pFormat)
747 /***********************************************************************
748 * NdrNonConformantStringUnmarshall [RPCRT4.@]
750 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
751 unsigned char **ppMemory,
752 PFORMAT_STRING pFormat,
753 unsigned char fMustAlloc)
759 /***********************************************************************
760 * NdrNonConformantStringBufferSize [RPCRT4.@]
762 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
763 unsigned char *pMemory,
764 PFORMAT_STRING pFormat)
769 /***********************************************************************
770 * NdrNonConformantStringMemorySize [RPCRT4.@]
772 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
773 PFORMAT_STRING pFormat)
779 static inline void dump_pointer_attr(unsigned char attr)
781 if (attr & RPC_FC_P_ALLOCALLNODES)
782 TRACE(" RPC_FC_P_ALLOCALLNODES");
783 if (attr & RPC_FC_P_DONTFREE)
784 TRACE(" RPC_FC_P_DONTFREE");
785 if (attr & RPC_FC_P_ONSTACK)
786 TRACE(" RPC_FC_P_ONSTACK");
787 if (attr & RPC_FC_P_SIMPLEPOINTER)
788 TRACE(" RPC_FC_P_SIMPLEPOINTER");
789 if (attr & RPC_FC_P_DEREF)
790 TRACE(" RPC_FC_P_DEREF");
794 /***********************************************************************
795 * PointerMarshall [internal]
797 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
798 unsigned char *Buffer,
799 unsigned char *Pointer,
800 PFORMAT_STRING pFormat)
802 unsigned type = pFormat[0], attr = pFormat[1];
806 int pointer_needs_marshaling;
808 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
809 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
811 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
812 else desc = pFormat + *(const SHORT*)pFormat;
815 case RPC_FC_RP: /* ref pointer (always non-null) */
816 #if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
818 RpcRaiseException(RPC_X_NULL_REF_POINTER);
820 pointer_needs_marshaling = 1;
822 case RPC_FC_UP: /* unique pointer */
823 case RPC_FC_OP: /* object pointer - same as unique here */
825 pointer_needs_marshaling = 1;
827 pointer_needs_marshaling = 0;
828 pointer_id = (ULONG)Pointer;
829 TRACE("writing 0x%08x to buffer\n", pointer_id);
830 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
833 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
834 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
835 TRACE("writing 0x%08x to buffer\n", pointer_id);
836 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
839 FIXME("unhandled ptr type=%02x\n", type);
840 RpcRaiseException(RPC_X_BAD_STUB_DATA);
844 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
846 if (pointer_needs_marshaling) {
847 if (attr & RPC_FC_P_DEREF) {
848 Pointer = *(unsigned char**)Pointer;
849 TRACE("deref => %p\n", Pointer);
851 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
852 if (m) m(pStubMsg, Pointer, desc);
853 else FIXME("no marshaller for data type=%02x\n", *desc);
856 STD_OVERFLOW_CHECK(pStubMsg);
859 /***********************************************************************
860 * PointerUnmarshall [internal]
862 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
863 unsigned char *Buffer,
864 unsigned char **pPointer,
865 PFORMAT_STRING pFormat,
866 unsigned char fMustAlloc)
868 unsigned type = pFormat[0], attr = pFormat[1];
871 DWORD pointer_id = 0;
872 int pointer_needs_unmarshaling;
874 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pFormat, fMustAlloc);
875 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
877 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
878 else desc = pFormat + *(const SHORT*)pFormat;
881 case RPC_FC_RP: /* ref pointer (always non-null) */
882 pointer_needs_unmarshaling = 1;
884 case RPC_FC_UP: /* unique pointer */
885 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
886 TRACE("pointer_id is 0x%08x\n", pointer_id);
888 pointer_needs_unmarshaling = 1;
891 pointer_needs_unmarshaling = 0;
894 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
895 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
896 TRACE("pointer_id is 0x%08x\n", pointer_id);
897 if (!fMustAlloc && *pPointer)
899 FIXME("free object pointer %p\n", *pPointer);
903 pointer_needs_unmarshaling = 1;
905 pointer_needs_unmarshaling = 0;
908 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
909 TRACE("pointer_id is 0x%08x\n", pointer_id);
910 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
911 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
914 FIXME("unhandled ptr type=%02x\n", type);
915 RpcRaiseException(RPC_X_BAD_STUB_DATA);
919 if (pointer_needs_unmarshaling) {
920 if (attr & RPC_FC_P_DEREF) {
921 if (!*pPointer || fMustAlloc)
922 *pPointer = NdrAllocate(pStubMsg, sizeof(void *));
923 pPointer = *(unsigned char***)pPointer;
924 TRACE("deref => %p\n", pPointer);
926 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
927 if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
928 else FIXME("no unmarshaller for data type=%02x\n", *desc);
930 if (type == RPC_FC_FP)
931 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
935 TRACE("pointer=%p\n", *pPointer);
938 /***********************************************************************
939 * PointerBufferSize [internal]
941 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
942 unsigned char *Pointer,
943 PFORMAT_STRING pFormat)
945 unsigned type = pFormat[0], attr = pFormat[1];
948 int pointer_needs_sizing;
951 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
952 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
954 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
955 else desc = pFormat + *(const SHORT*)pFormat;
958 case RPC_FC_RP: /* ref pointer (always non-null) */
962 /* NULL pointer has no further representation */
967 pointer_needs_sizing = !NdrFullPointerQueryPointer(
968 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
969 if (!pointer_needs_sizing)
973 FIXME("unhandled ptr type=%02x\n", type);
974 RpcRaiseException(RPC_X_BAD_STUB_DATA);
978 if (attr & RPC_FC_P_DEREF) {
979 Pointer = *(unsigned char**)Pointer;
980 TRACE("deref => %p\n", Pointer);
983 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
984 if (m) m(pStubMsg, Pointer, desc);
985 else FIXME("no buffersizer for data type=%02x\n", *desc);
988 /***********************************************************************
989 * PointerMemorySize [internal]
991 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
992 unsigned char *Buffer,
993 PFORMAT_STRING pFormat)
995 unsigned type = pFormat[0], attr = pFormat[1];
999 FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat);
1000 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1002 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1003 else desc = pFormat + *(const SHORT*)pFormat;
1006 case RPC_FC_RP: /* ref pointer (always non-null) */
1009 FIXME("unhandled ptr type=%02x\n", type);
1010 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1013 if (attr & RPC_FC_P_DEREF) {
1017 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1018 if (m) m(pStubMsg, desc);
1019 else FIXME("no memorysizer for data type=%02x\n", *desc);
1024 /***********************************************************************
1025 * PointerFree [internal]
1027 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1028 unsigned char *Pointer,
1029 PFORMAT_STRING pFormat)
1031 unsigned type = pFormat[0], attr = pFormat[1];
1032 PFORMAT_STRING desc;
1035 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1036 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1037 if (attr & RPC_FC_P_DONTFREE) return;
1039 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1040 else desc = pFormat + *(const SHORT*)pFormat;
1042 if (!Pointer) return;
1044 if (type == RPC_FC_FP) {
1045 int pointer_needs_freeing = NdrFullPointerFree(
1046 pStubMsg->FullPtrXlatTables, Pointer);
1047 if (!pointer_needs_freeing)
1051 if (attr & RPC_FC_P_DEREF) {
1052 Pointer = *(unsigned char**)Pointer;
1053 TRACE("deref => %p\n", Pointer);
1056 m = NdrFreer[*desc & NDR_TABLE_MASK];
1057 if (m) m(pStubMsg, Pointer, desc);
1059 /* hmm... is this sensible?
1060 * perhaps we should check if the memory comes from NdrAllocate,
1061 * and deallocate only if so - checking if the pointer is between
1062 * BufferStart and BufferEnd is probably no good since the buffer
1063 * may be reallocated when the server wants to marshal the reply */
1065 case RPC_FC_BOGUS_STRUCT:
1066 case RPC_FC_BOGUS_ARRAY:
1067 case RPC_FC_USER_MARSHAL:
1069 case RPC_FC_CVARRAY:
1072 FIXME("unhandled data type=%02x\n", *desc);
1074 case RPC_FC_C_CSTRING:
1075 case RPC_FC_C_WSTRING:
1076 if (pStubMsg->ReuseBuffer) goto notfree;
1082 if (attr & RPC_FC_P_ONSTACK) {
1083 TRACE("not freeing stack ptr %p\n", Pointer);
1086 TRACE("freeing %p\n", Pointer);
1087 NdrFree(pStubMsg, Pointer);
1090 TRACE("not freeing %p\n", Pointer);
1093 /***********************************************************************
1094 * EmbeddedPointerMarshall
1096 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1097 unsigned char *pMemory,
1098 PFORMAT_STRING pFormat)
1100 unsigned char *Mark = pStubMsg->BufferMark;
1101 unsigned long Offset = pStubMsg->Offset;
1102 unsigned ofs, rep, count, stride, xofs;
1105 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1107 if (*pFormat != RPC_FC_PP) return NULL;
1110 while (pFormat[0] != RPC_FC_END) {
1111 switch (pFormat[0]) {
1113 FIXME("unknown repeat type %d\n", pFormat[0]);
1114 case RPC_FC_NO_REPEAT:
1122 case RPC_FC_FIXED_REPEAT:
1123 rep = *(const WORD*)&pFormat[2];
1124 stride = *(const WORD*)&pFormat[4];
1125 ofs = *(const WORD*)&pFormat[6];
1126 count = *(const WORD*)&pFormat[8];
1130 case RPC_FC_VARIABLE_REPEAT:
1131 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1132 stride = *(const WORD*)&pFormat[2];
1133 ofs = *(const WORD*)&pFormat[4];
1134 count = *(const WORD*)&pFormat[6];
1135 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1139 for (i = 0; i < rep; i++) {
1140 PFORMAT_STRING info = pFormat;
1141 unsigned char *membase = pMemory + (i * stride);
1142 unsigned char *bufbase = Mark + (i * stride);
1144 /* ofs doesn't seem to matter in this context */
1145 for (u=0; u<count; u++,info+=8) {
1146 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1147 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1148 unsigned char *saved_memory = pStubMsg->Memory;
1150 pStubMsg->Memory = pMemory;
1151 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1152 pStubMsg->Memory = saved_memory;
1155 pFormat += 8 * count;
1158 STD_OVERFLOW_CHECK(pStubMsg);
1163 /***********************************************************************
1164 * EmbeddedPointerUnmarshall
1166 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1167 unsigned char **ppMemory,
1168 PFORMAT_STRING pFormat,
1169 unsigned char fMustAlloc)
1171 unsigned char *Mark = pStubMsg->BufferMark;
1172 unsigned long Offset = pStubMsg->Offset;
1173 unsigned ofs, rep, count, stride, xofs;
1176 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1178 if (*pFormat != RPC_FC_PP) return NULL;
1181 while (pFormat[0] != RPC_FC_END) {
1182 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1183 switch (pFormat[0]) {
1185 FIXME("unknown repeat type %d\n", pFormat[0]);
1186 case RPC_FC_NO_REPEAT:
1194 case RPC_FC_FIXED_REPEAT:
1195 rep = *(const WORD*)&pFormat[2];
1196 stride = *(const WORD*)&pFormat[4];
1197 ofs = *(const WORD*)&pFormat[6];
1198 count = *(const WORD*)&pFormat[8];
1202 case RPC_FC_VARIABLE_REPEAT:
1203 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1204 stride = *(const WORD*)&pFormat[2];
1205 ofs = *(const WORD*)&pFormat[4];
1206 count = *(const WORD*)&pFormat[6];
1207 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1211 /* ofs doesn't seem to matter in this context */
1212 for (i = 0; i < rep; i++) {
1213 PFORMAT_STRING info = pFormat;
1214 unsigned char *membase = *ppMemory + (i * stride);
1215 unsigned char *bufbase = Mark + (i * stride);
1217 for (u=0; u<count; u++,info+=8) {
1218 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1219 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1220 PointerUnmarshall(pStubMsg, bufptr, (unsigned char**)memptr, info+4, TRUE);
1223 pFormat += 8 * count;
1229 /***********************************************************************
1230 * EmbeddedPointerBufferSize
1232 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1233 unsigned char *pMemory,
1234 PFORMAT_STRING pFormat)
1236 unsigned long Offset = pStubMsg->Offset;
1237 unsigned ofs, rep, count, stride, xofs;
1240 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1242 if (pStubMsg->IgnoreEmbeddedPointers) return;
1244 if (*pFormat != RPC_FC_PP) return;
1247 while (pFormat[0] != RPC_FC_END) {
1248 switch (pFormat[0]) {
1250 FIXME("unknown repeat type %d\n", pFormat[0]);
1251 case RPC_FC_NO_REPEAT:
1259 case RPC_FC_FIXED_REPEAT:
1260 rep = *(const WORD*)&pFormat[2];
1261 stride = *(const WORD*)&pFormat[4];
1262 ofs = *(const WORD*)&pFormat[6];
1263 count = *(const WORD*)&pFormat[8];
1267 case RPC_FC_VARIABLE_REPEAT:
1268 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1269 stride = *(const WORD*)&pFormat[2];
1270 ofs = *(const WORD*)&pFormat[4];
1271 count = *(const WORD*)&pFormat[6];
1272 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1276 /* ofs doesn't seem to matter in this context */
1277 for (i = 0; i < rep; i++) {
1278 PFORMAT_STRING info = pFormat;
1279 unsigned char *membase = pMemory + (i * stride);
1281 for (u=0; u<count; u++,info+=8) {
1282 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1283 unsigned char *saved_memory = pStubMsg->Memory;
1285 pStubMsg->Memory = pMemory;
1286 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1287 pStubMsg->Memory = saved_memory;
1290 pFormat += 8 * count;
1294 /***********************************************************************
1295 * EmbeddedPointerMemorySize [internal]
1297 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1298 PFORMAT_STRING pFormat)
1300 unsigned long Offset = pStubMsg->Offset;
1301 unsigned char *Mark = pStubMsg->BufferMark;
1302 unsigned ofs, rep, count, stride, xofs;
1305 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1307 if (*pFormat != RPC_FC_PP) return 0;
1310 while (pFormat[0] != RPC_FC_END) {
1311 switch (pFormat[0]) {
1313 FIXME("unknown repeat type %d\n", pFormat[0]);
1314 case RPC_FC_NO_REPEAT:
1322 case RPC_FC_FIXED_REPEAT:
1323 rep = *(const WORD*)&pFormat[2];
1324 stride = *(const WORD*)&pFormat[4];
1325 ofs = *(const WORD*)&pFormat[6];
1326 count = *(const WORD*)&pFormat[8];
1330 case RPC_FC_VARIABLE_REPEAT:
1331 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1332 stride = *(const WORD*)&pFormat[2];
1333 ofs = *(const WORD*)&pFormat[4];
1334 count = *(const WORD*)&pFormat[6];
1335 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1339 /* ofs doesn't seem to matter in this context */
1340 for (i = 0; i < rep; i++) {
1341 PFORMAT_STRING info = pFormat;
1342 unsigned char *bufbase = Mark + (i * stride);
1344 for (u=0; u<count; u++,info+=8) {
1345 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1346 PointerMemorySize(pStubMsg, bufptr, info+4);
1349 pFormat += 8 * count;
1355 /***********************************************************************
1356 * EmbeddedPointerFree [internal]
1358 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1359 unsigned char *pMemory,
1360 PFORMAT_STRING pFormat)
1362 unsigned long Offset = pStubMsg->Offset;
1363 unsigned ofs, rep, count, stride, xofs;
1366 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1367 if (*pFormat != RPC_FC_PP) return;
1370 while (pFormat[0] != RPC_FC_END) {
1371 switch (pFormat[0]) {
1373 FIXME("unknown repeat type %d\n", pFormat[0]);
1374 case RPC_FC_NO_REPEAT:
1382 case RPC_FC_FIXED_REPEAT:
1383 rep = *(const WORD*)&pFormat[2];
1384 stride = *(const WORD*)&pFormat[4];
1385 ofs = *(const WORD*)&pFormat[6];
1386 count = *(const WORD*)&pFormat[8];
1390 case RPC_FC_VARIABLE_REPEAT:
1391 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1392 stride = *(const WORD*)&pFormat[2];
1393 ofs = *(const WORD*)&pFormat[4];
1394 count = *(const WORD*)&pFormat[6];
1395 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1399 /* ofs doesn't seem to matter in this context */
1400 for (i = 0; i < rep; i++) {
1401 PFORMAT_STRING info = pFormat;
1402 unsigned char *membase = pMemory + (i * stride);
1404 for (u=0; u<count; u++,info+=8) {
1405 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1406 unsigned char *saved_memory = pStubMsg->Memory;
1408 pStubMsg->Memory = pMemory;
1409 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1410 pStubMsg->Memory = saved_memory;
1413 pFormat += 8 * count;
1417 /***********************************************************************
1418 * NdrPointerMarshall [RPCRT4.@]
1420 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1421 unsigned char *pMemory,
1422 PFORMAT_STRING pFormat)
1424 unsigned char *Buffer;
1426 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1428 /* incremement the buffer here instead of in PointerMarshall,
1429 * as that is used by embedded pointers which already handle the incrementing
1430 * the buffer, and shouldn't write any additional pointer data to the wire */
1431 if (*pFormat != RPC_FC_RP)
1433 ALIGN_POINTER(pStubMsg->Buffer, 4);
1434 Buffer = pStubMsg->Buffer;
1435 pStubMsg->Buffer += 4;
1438 Buffer = pStubMsg->Buffer;
1440 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1442 STD_OVERFLOW_CHECK(pStubMsg);
1447 /***********************************************************************
1448 * NdrPointerUnmarshall [RPCRT4.@]
1450 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1451 unsigned char **ppMemory,
1452 PFORMAT_STRING pFormat,
1453 unsigned char fMustAlloc)
1455 unsigned char *Buffer;
1457 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1459 /* incremement the buffer here instead of in PointerUnmarshall,
1460 * as that is used by embedded pointers which already handle the incrementing
1461 * the buffer, and shouldn't read any additional pointer data from the
1463 if (*pFormat != RPC_FC_RP)
1465 ALIGN_POINTER(pStubMsg->Buffer, 4);
1466 Buffer = pStubMsg->Buffer;
1467 pStubMsg->Buffer += 4;
1470 Buffer = pStubMsg->Buffer;
1472 PointerUnmarshall(pStubMsg, Buffer, ppMemory, pFormat, fMustAlloc);
1477 /***********************************************************************
1478 * NdrPointerBufferSize [RPCRT4.@]
1480 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1481 unsigned char *pMemory,
1482 PFORMAT_STRING pFormat)
1484 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1486 /* incremement the buffer length here instead of in PointerBufferSize,
1487 * as that is used by embedded pointers which already handle the buffer
1488 * length, and shouldn't write anything more to the wire */
1489 if (*pFormat != RPC_FC_RP)
1491 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1492 pStubMsg->BufferLength += 4;
1495 PointerBufferSize(pStubMsg, pMemory, pFormat);
1498 /***********************************************************************
1499 * NdrPointerMemorySize [RPCRT4.@]
1501 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1502 PFORMAT_STRING pFormat)
1504 /* unsigned size = *(LPWORD)(pFormat+2); */
1505 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1506 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1510 /***********************************************************************
1511 * NdrPointerFree [RPCRT4.@]
1513 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1514 unsigned char *pMemory,
1515 PFORMAT_STRING pFormat)
1517 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1518 PointerFree(pStubMsg, pMemory, pFormat);
1521 /***********************************************************************
1522 * NdrSimpleTypeMarshall [RPCRT4.@]
1524 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1525 unsigned char FormatChar )
1530 /***********************************************************************
1531 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1533 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1534 unsigned char FormatChar )
1539 /***********************************************************************
1540 * NdrSimpleStructMarshall [RPCRT4.@]
1542 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1543 unsigned char *pMemory,
1544 PFORMAT_STRING pFormat)
1546 unsigned size = *(const WORD*)(pFormat+2);
1547 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1549 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1551 memcpy(pStubMsg->Buffer, pMemory, size);
1552 pStubMsg->BufferMark = pStubMsg->Buffer;
1553 pStubMsg->Buffer += size;
1555 if (pFormat[0] != RPC_FC_STRUCT)
1556 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1558 STD_OVERFLOW_CHECK(pStubMsg);
1563 /***********************************************************************
1564 * NdrSimpleStructUnmarshall [RPCRT4.@]
1566 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1567 unsigned char **ppMemory,
1568 PFORMAT_STRING pFormat,
1569 unsigned char fMustAlloc)
1571 unsigned size = *(const WORD*)(pFormat+2);
1572 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1574 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1577 *ppMemory = NdrAllocate(pStubMsg, size);
1578 memcpy(*ppMemory, pStubMsg->Buffer, size);
1580 if (!pStubMsg->IsClient && !*ppMemory)
1581 /* for servers, we just point straight into the RPC buffer */
1582 *ppMemory = pStubMsg->Buffer;
1584 /* for clients, memory should be provided by caller */
1585 memcpy(*ppMemory, pStubMsg->Buffer, size);
1588 pStubMsg->BufferMark = pStubMsg->Buffer;
1589 pStubMsg->Buffer += size;
1591 if (pFormat[0] != RPC_FC_STRUCT)
1592 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat+4, fMustAlloc);
1597 /***********************************************************************
1598 * NdrSimpleStructBufferSize [RPCRT4.@]
1600 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1601 unsigned char *pMemory,
1602 PFORMAT_STRING pFormat)
1604 unsigned size = *(const WORD*)(pFormat+2);
1605 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1607 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1609 pStubMsg->BufferLength += size;
1610 if (pFormat[0] != RPC_FC_STRUCT)
1611 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1614 /***********************************************************************
1615 * NdrSimpleStructMemorySize [RPCRT4.@]
1617 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1618 PFORMAT_STRING pFormat)
1620 unsigned short size = *(const WORD *)(pFormat+2);
1622 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1624 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1625 pStubMsg->MemorySize += size;
1626 pStubMsg->Buffer += size;
1628 if (pFormat[0] != RPC_FC_STRUCT)
1629 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1633 /***********************************************************************
1634 * NdrSimpleStructFree [RPCRT4.@]
1636 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1637 unsigned char *pMemory,
1638 PFORMAT_STRING pFormat)
1640 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1641 if (pFormat[0] != RPC_FC_STRUCT)
1642 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1646 static unsigned long EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg,
1647 PFORMAT_STRING pFormat)
1651 case RPC_FC_PSTRUCT:
1652 case RPC_FC_CSTRUCT:
1653 case RPC_FC_BOGUS_STRUCT:
1654 case RPC_FC_SMFARRAY:
1655 case RPC_FC_SMVARRAY:
1656 return *(const WORD*)&pFormat[2];
1657 case RPC_FC_USER_MARSHAL:
1658 return *(const WORD*)&pFormat[4];
1659 case RPC_FC_NON_ENCAPSULATED_UNION:
1661 if (pStubMsg->fHasNewCorrDesc)
1666 pFormat += *(const SHORT*)pFormat;
1667 return *(const SHORT*)pFormat;
1669 return sizeof(void *);
1671 FIXME("unhandled embedded type %02x\n", *pFormat);
1677 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1678 PFORMAT_STRING pFormat)
1680 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1684 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1688 return m(pStubMsg, pFormat);
1692 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1693 unsigned char *pMemory,
1694 PFORMAT_STRING pFormat,
1695 PFORMAT_STRING pPointer)
1697 PFORMAT_STRING desc;
1701 while (*pFormat != RPC_FC_END) {
1707 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
1708 memcpy(pStubMsg->Buffer, pMemory, 1);
1709 pStubMsg->Buffer += 1;
1715 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1716 memcpy(pStubMsg->Buffer, pMemory, 2);
1717 pStubMsg->Buffer += 2;
1723 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
1724 memcpy(pStubMsg->Buffer, pMemory, 4);
1725 pStubMsg->Buffer += 4;
1729 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1730 memcpy(pStubMsg->Buffer, pMemory, 8);
1731 pStubMsg->Buffer += 8;
1734 case RPC_FC_POINTER:
1735 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1736 NdrPointerMarshall(pStubMsg, *(unsigned char**)pMemory, pPointer);
1740 case RPC_FC_ALIGNM4:
1741 ALIGN_POINTER(pMemory, 4);
1743 case RPC_FC_ALIGNM8:
1744 ALIGN_POINTER(pMemory, 8);
1746 case RPC_FC_STRUCTPAD1:
1747 case RPC_FC_STRUCTPAD2:
1748 case RPC_FC_STRUCTPAD3:
1749 case RPC_FC_STRUCTPAD4:
1750 case RPC_FC_STRUCTPAD5:
1751 case RPC_FC_STRUCTPAD6:
1752 case RPC_FC_STRUCTPAD7:
1753 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1755 case RPC_FC_EMBEDDED_COMPLEX:
1756 pMemory += pFormat[1];
1758 desc = pFormat + *(const SHORT*)pFormat;
1759 size = EmbeddedComplexSize(pStubMsg, desc);
1760 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1761 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1762 if (m) m(pStubMsg, pMemory, desc);
1763 else FIXME("no marshaller for embedded type %02x\n", *desc);
1770 FIXME("unhandled format 0x%02x\n", *pFormat);
1778 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1779 unsigned char *pMemory,
1780 PFORMAT_STRING pFormat,
1781 PFORMAT_STRING pPointer)
1783 PFORMAT_STRING desc;
1787 while (*pFormat != RPC_FC_END) {
1793 memcpy(pMemory, pStubMsg->Buffer, 1);
1794 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
1795 pStubMsg->Buffer += 1;
1801 memcpy(pMemory, pStubMsg->Buffer, 2);
1802 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1803 pStubMsg->Buffer += 2;
1809 memcpy(pMemory, pStubMsg->Buffer, 4);
1810 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
1811 pStubMsg->Buffer += 4;
1815 memcpy(pMemory, pStubMsg->Buffer, 8);
1816 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1817 pStubMsg->Buffer += 8;
1820 case RPC_FC_POINTER:
1821 TRACE("pointer => %p\n", pMemory);
1822 NdrPointerUnmarshall(pStubMsg, (unsigned char**)pMemory, pPointer, TRUE);
1826 case RPC_FC_ALIGNM4:
1827 ALIGN_POINTER(pMemory, 4);
1829 case RPC_FC_ALIGNM8:
1830 ALIGN_POINTER(pMemory, 8);
1832 case RPC_FC_STRUCTPAD1:
1833 case RPC_FC_STRUCTPAD2:
1834 case RPC_FC_STRUCTPAD3:
1835 case RPC_FC_STRUCTPAD4:
1836 case RPC_FC_STRUCTPAD5:
1837 case RPC_FC_STRUCTPAD6:
1838 case RPC_FC_STRUCTPAD7:
1839 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1841 case RPC_FC_EMBEDDED_COMPLEX:
1842 pMemory += pFormat[1];
1844 desc = pFormat + *(const SHORT*)pFormat;
1845 size = EmbeddedComplexSize(pStubMsg, desc);
1846 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
1847 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1848 memset(pMemory, 0, size); /* just in case */
1849 if (m) m(pStubMsg, &pMemory, desc, FALSE);
1850 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
1857 FIXME("unhandled format %d\n", *pFormat);
1865 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1866 unsigned char *pMemory,
1867 PFORMAT_STRING pFormat,
1868 PFORMAT_STRING pPointer)
1870 PFORMAT_STRING desc;
1874 while (*pFormat != RPC_FC_END) {
1880 pStubMsg->BufferLength += 1;
1886 pStubMsg->BufferLength += 2;
1892 pStubMsg->BufferLength += 4;
1896 pStubMsg->BufferLength += 8;
1899 case RPC_FC_POINTER:
1900 NdrPointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
1904 case RPC_FC_ALIGNM4:
1905 ALIGN_POINTER(pMemory, 4);
1907 case RPC_FC_ALIGNM8:
1908 ALIGN_POINTER(pMemory, 8);
1910 case RPC_FC_STRUCTPAD1:
1911 case RPC_FC_STRUCTPAD2:
1912 case RPC_FC_STRUCTPAD3:
1913 case RPC_FC_STRUCTPAD4:
1914 case RPC_FC_STRUCTPAD5:
1915 case RPC_FC_STRUCTPAD6:
1916 case RPC_FC_STRUCTPAD7:
1917 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1919 case RPC_FC_EMBEDDED_COMPLEX:
1920 pMemory += pFormat[1];
1922 desc = pFormat + *(const SHORT*)pFormat;
1923 size = EmbeddedComplexSize(pStubMsg, desc);
1924 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1925 if (m) m(pStubMsg, pMemory, desc);
1926 else FIXME("no buffersizer for embedded type %02x\n", *desc);
1933 FIXME("unhandled format 0x%02x\n", *pFormat);
1941 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
1942 unsigned char *pMemory,
1943 PFORMAT_STRING pFormat,
1944 PFORMAT_STRING pPointer)
1946 PFORMAT_STRING desc;
1950 while (*pFormat != RPC_FC_END) {
1971 case RPC_FC_POINTER:
1972 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
1976 case RPC_FC_ALIGNM4:
1977 ALIGN_POINTER(pMemory, 4);
1979 case RPC_FC_ALIGNM8:
1980 ALIGN_POINTER(pMemory, 8);
1982 case RPC_FC_STRUCTPAD1:
1983 case RPC_FC_STRUCTPAD2:
1984 case RPC_FC_STRUCTPAD3:
1985 case RPC_FC_STRUCTPAD4:
1986 case RPC_FC_STRUCTPAD5:
1987 case RPC_FC_STRUCTPAD6:
1988 case RPC_FC_STRUCTPAD7:
1989 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1991 case RPC_FC_EMBEDDED_COMPLEX:
1992 pMemory += pFormat[1];
1994 desc = pFormat + *(const SHORT*)pFormat;
1995 size = EmbeddedComplexSize(pStubMsg, desc);
1996 m = NdrFreer[*desc & NDR_TABLE_MASK];
1997 if (m) m(pStubMsg, pMemory, desc);
1998 else FIXME("no freer for embedded type %02x\n", *desc);
2005 FIXME("unhandled format 0x%02x\n", *pFormat);
2013 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2014 PFORMAT_STRING pFormat)
2016 PFORMAT_STRING desc;
2017 unsigned long size = 0;
2019 while (*pFormat != RPC_FC_END) {
2026 pStubMsg->Buffer += 1;
2032 pStubMsg->Buffer += 2;
2038 pStubMsg->Buffer += 4;
2042 pStubMsg->Buffer += 8;
2044 case RPC_FC_POINTER:
2046 pStubMsg->Buffer += 4;
2048 case RPC_FC_ALIGNM4:
2049 ALIGN_LENGTH(size, 4);
2050 ALIGN_POINTER(pStubMsg->Buffer, 4);
2052 case RPC_FC_ALIGNM8:
2053 ALIGN_LENGTH(size, 8);
2054 ALIGN_POINTER(pStubMsg->Buffer, 8);
2056 case RPC_FC_STRUCTPAD1:
2057 case RPC_FC_STRUCTPAD2:
2058 case RPC_FC_STRUCTPAD3:
2059 case RPC_FC_STRUCTPAD4:
2060 case RPC_FC_STRUCTPAD5:
2061 case RPC_FC_STRUCTPAD6:
2062 case RPC_FC_STRUCTPAD7:
2063 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2065 case RPC_FC_EMBEDDED_COMPLEX:
2068 desc = pFormat + *(const SHORT*)pFormat;
2069 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2075 FIXME("unhandled format 0x%02x\n", *pFormat);
2083 /***********************************************************************
2084 * NdrComplexStructMarshall [RPCRT4.@]
2086 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2087 unsigned char *pMemory,
2088 PFORMAT_STRING pFormat)
2090 PFORMAT_STRING conf_array = NULL;
2091 PFORMAT_STRING pointer_desc = NULL;
2092 unsigned char *OldMemory = pStubMsg->Memory;
2094 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2096 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2099 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2101 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2104 pStubMsg->Memory = pMemory;
2106 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2109 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2111 pStubMsg->Memory = OldMemory;
2113 STD_OVERFLOW_CHECK(pStubMsg);
2118 /***********************************************************************
2119 * NdrComplexStructUnmarshall [RPCRT4.@]
2121 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2122 unsigned char **ppMemory,
2123 PFORMAT_STRING pFormat,
2124 unsigned char fMustAlloc)
2126 unsigned size = *(const WORD*)(pFormat+2);
2127 PFORMAT_STRING conf_array = NULL;
2128 PFORMAT_STRING pointer_desc = NULL;
2129 unsigned char *pMemory;
2131 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2133 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2135 if (fMustAlloc || !*ppMemory)
2137 *ppMemory = NdrAllocate(pStubMsg, size);
2138 memset(*ppMemory, 0, size);
2142 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2144 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2147 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2150 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2155 /***********************************************************************
2156 * NdrComplexStructBufferSize [RPCRT4.@]
2158 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2159 unsigned char *pMemory,
2160 PFORMAT_STRING pFormat)
2162 PFORMAT_STRING conf_array = NULL;
2163 PFORMAT_STRING pointer_desc = NULL;
2164 unsigned char *OldMemory = pStubMsg->Memory;
2166 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2168 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2171 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2173 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2176 pStubMsg->Memory = pMemory;
2178 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2181 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2183 pStubMsg->Memory = OldMemory;
2186 /***********************************************************************
2187 * NdrComplexStructMemorySize [RPCRT4.@]
2189 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2190 PFORMAT_STRING pFormat)
2192 unsigned size = *(const WORD*)(pFormat+2);
2193 PFORMAT_STRING conf_array = NULL;
2194 PFORMAT_STRING pointer_desc = NULL;
2196 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2198 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2201 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2203 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2206 ComplexStructMemorySize(pStubMsg, pFormat);
2209 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2214 /***********************************************************************
2215 * NdrComplexStructFree [RPCRT4.@]
2217 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2218 unsigned char *pMemory,
2219 PFORMAT_STRING pFormat)
2221 PFORMAT_STRING conf_array = NULL;
2222 PFORMAT_STRING pointer_desc = NULL;
2223 unsigned char *OldMemory = pStubMsg->Memory;
2225 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2228 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2230 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2233 pStubMsg->Memory = pMemory;
2235 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2238 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2240 pStubMsg->Memory = OldMemory;
2243 /***********************************************************************
2244 * NdrConformantArrayMarshall [RPCRT4.@]
2246 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2247 unsigned char *pMemory,
2248 PFORMAT_STRING pFormat)
2250 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2251 unsigned char alignment = pFormat[1] + 1;
2253 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2254 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2256 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2258 WriteConformance(pStubMsg);
2260 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2262 size = safe_multiply(esize, pStubMsg->MaxCount);
2263 memcpy(pStubMsg->Buffer, pMemory, size);
2264 pStubMsg->BufferMark = pStubMsg->Buffer;
2265 pStubMsg->Buffer += size;
2267 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2269 STD_OVERFLOW_CHECK(pStubMsg);
2274 /***********************************************************************
2275 * NdrConformantArrayUnmarshall [RPCRT4.@]
2277 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2278 unsigned char **ppMemory,
2279 PFORMAT_STRING pFormat,
2280 unsigned char fMustAlloc)
2282 DWORD size, esize = *(const WORD*)(pFormat+2);
2283 unsigned char alignment = pFormat[1] + 1;
2285 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2286 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2288 pFormat = ReadConformance(pStubMsg, pFormat+4);
2290 size = safe_multiply(esize, pStubMsg->MaxCount);
2292 if (fMustAlloc || !*ppMemory)
2293 *ppMemory = NdrAllocate(pStubMsg, size);
2295 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2297 memcpy(*ppMemory, pStubMsg->Buffer, size);
2299 pStubMsg->BufferMark = pStubMsg->Buffer;
2300 pStubMsg->Buffer += size;
2302 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2307 /***********************************************************************
2308 * NdrConformantArrayBufferSize [RPCRT4.@]
2310 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2311 unsigned char *pMemory,
2312 PFORMAT_STRING pFormat)
2314 DWORD size, esize = *(const WORD*)(pFormat+2);
2315 unsigned char alignment = pFormat[1] + 1;
2317 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2318 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2320 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2322 SizeConformance(pStubMsg);
2324 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2326 size = safe_multiply(esize, pStubMsg->MaxCount);
2327 /* conformance value plus array */
2328 pStubMsg->BufferLength += size;
2330 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2333 /***********************************************************************
2334 * NdrConformantArrayMemorySize [RPCRT4.@]
2336 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2337 PFORMAT_STRING pFormat)
2339 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2340 unsigned char alignment = pFormat[1] + 1;
2342 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2343 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2345 pFormat = ReadConformance(pStubMsg, pFormat+4);
2346 size = safe_multiply(esize, pStubMsg->MaxCount);
2347 pStubMsg->MemorySize += size;
2349 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2350 pStubMsg->BufferMark = pStubMsg->Buffer;
2351 pStubMsg->Buffer += size;
2353 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2355 return pStubMsg->MemorySize;
2358 /***********************************************************************
2359 * NdrConformantArrayFree [RPCRT4.@]
2361 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2362 unsigned char *pMemory,
2363 PFORMAT_STRING pFormat)
2365 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2366 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2368 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2370 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2374 /***********************************************************************
2375 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2377 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2378 unsigned char* pMemory,
2379 PFORMAT_STRING pFormat )
2382 unsigned char alignment = pFormat[1] + 1;
2383 DWORD esize = *(const WORD*)(pFormat+2);
2385 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2387 if (pFormat[0] != RPC_FC_CVARRAY)
2389 ERR("invalid format type %x\n", pFormat[0]);
2390 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2394 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2395 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2397 WriteConformance(pStubMsg);
2398 WriteVariance(pStubMsg);
2400 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2402 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2404 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
2405 pStubMsg->BufferMark = pStubMsg->Buffer;
2406 pStubMsg->Buffer += bufsize;
2408 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2410 STD_OVERFLOW_CHECK(pStubMsg);
2416 /***********************************************************************
2417 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2419 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2420 unsigned char** ppMemory,
2421 PFORMAT_STRING pFormat,
2422 unsigned char fMustAlloc )
2424 ULONG bufsize, memsize;
2425 unsigned char alignment = pFormat[1] + 1;
2426 DWORD esize = *(const WORD*)(pFormat+2);
2428 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2430 if (pFormat[0] != RPC_FC_CVARRAY)
2432 ERR("invalid format type %x\n", pFormat[0]);
2433 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2437 pFormat = ReadConformance(pStubMsg, pFormat+4);
2438 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2440 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2442 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2443 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2445 if (!*ppMemory || fMustAlloc)
2446 *ppMemory = NdrAllocate(pStubMsg, memsize);
2447 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
2448 pStubMsg->Buffer += bufsize;
2450 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2456 /***********************************************************************
2457 * NdrConformantVaryingArrayFree [RPCRT4.@]
2459 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2460 unsigned char* pMemory,
2461 PFORMAT_STRING pFormat )
2463 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2465 if (pFormat[0] != RPC_FC_CVARRAY)
2467 ERR("invalid format type %x\n", pFormat[0]);
2468 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2472 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2473 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2475 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2479 /***********************************************************************
2480 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2482 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2483 unsigned char* pMemory, PFORMAT_STRING pFormat )
2485 unsigned char alignment = pFormat[1] + 1;
2486 DWORD esize = *(const WORD*)(pFormat+2);
2488 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2490 if (pFormat[0] != RPC_FC_CVARRAY)
2492 ERR("invalid format type %x\n", pFormat[0]);
2493 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2498 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2499 /* compute length */
2500 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2502 SizeConformance(pStubMsg);
2503 SizeVariance(pStubMsg);
2505 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2507 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
2509 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2513 /***********************************************************************
2514 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2516 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2517 PFORMAT_STRING pFormat )
2524 /***********************************************************************
2525 * NdrComplexArrayMarshall [RPCRT4.@]
2527 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2528 unsigned char *pMemory,
2529 PFORMAT_STRING pFormat)
2531 ULONG i, count, def;
2532 BOOL variance_present;
2533 unsigned char alignment;
2535 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2537 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2539 ERR("invalid format type %x\n", pFormat[0]);
2540 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2544 alignment = pFormat[1] + 1;
2546 def = *(const WORD*)&pFormat[2];
2549 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2550 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2552 variance_present = IsConformanceOrVariancePresent(pFormat);
2553 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2554 TRACE("variance = %d\n", pStubMsg->ActualCount);
2556 WriteConformance(pStubMsg);
2557 if (variance_present)
2558 WriteVariance(pStubMsg);
2560 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2562 count = pStubMsg->ActualCount;
2563 for (i = 0; i < count; i++)
2564 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2566 STD_OVERFLOW_CHECK(pStubMsg);
2571 /***********************************************************************
2572 * NdrComplexArrayUnmarshall [RPCRT4.@]
2574 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2575 unsigned char **ppMemory,
2576 PFORMAT_STRING pFormat,
2577 unsigned char fMustAlloc)
2579 ULONG i, count, esize, memsize;
2580 unsigned char alignment;
2581 unsigned char *pMemory;
2582 unsigned char *Buffer;
2584 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2586 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2588 ERR("invalid format type %x\n", pFormat[0]);
2589 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2593 alignment = pFormat[1] + 1;
2597 pFormat = ReadConformance(pStubMsg, pFormat);
2598 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2600 Buffer = pStubMsg->Buffer;
2601 pStubMsg->MemorySize = 0;
2602 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2603 pStubMsg->Buffer = Buffer;
2605 /* do multiply here instead of inside if block to verify MaxCount */
2606 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2607 if (fMustAlloc || !*ppMemory)
2609 *ppMemory = NdrAllocate(pStubMsg, memsize);
2610 memset(*ppMemory, 0, memsize);
2613 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2615 pMemory = *ppMemory;
2616 count = pStubMsg->ActualCount;
2617 for (i = 0; i < count; i++)
2618 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
2623 /***********************************************************************
2624 * NdrComplexArrayBufferSize [RPCRT4.@]
2626 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2627 unsigned char *pMemory,
2628 PFORMAT_STRING pFormat)
2630 ULONG i, count, def;
2631 unsigned char alignment;
2632 BOOL variance_present;
2634 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2636 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2638 ERR("invalid format type %x\n", pFormat[0]);
2639 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2643 alignment = pFormat[1] + 1;
2645 def = *(const WORD*)&pFormat[2];
2648 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2649 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2650 SizeConformance(pStubMsg);
2652 variance_present = IsConformanceOrVariancePresent(pFormat);
2653 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2654 TRACE("variance = %d\n", pStubMsg->ActualCount);
2656 if (variance_present)
2657 SizeVariance(pStubMsg);
2659 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2661 count = pStubMsg->ActualCount;
2662 for (i = 0; i < count; i++)
2663 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
2666 /***********************************************************************
2667 * NdrComplexArrayMemorySize [RPCRT4.@]
2669 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2670 PFORMAT_STRING pFormat)
2672 ULONG i, count, esize, SavedMemorySize, MemorySize;
2673 unsigned char alignment;
2674 unsigned char *Buffer;
2676 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2678 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2680 ERR("invalid format type %x\n", pFormat[0]);
2681 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2685 alignment = pFormat[1] + 1;
2689 pFormat = ReadConformance(pStubMsg, pFormat);
2690 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2692 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2694 SavedMemorySize = pStubMsg->MemorySize;
2696 Buffer = pStubMsg->Buffer;
2697 pStubMsg->MemorySize = 0;
2698 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2699 pStubMsg->Buffer = Buffer;
2701 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
2703 count = pStubMsg->ActualCount;
2704 for (i = 0; i < count; i++)
2705 ComplexStructMemorySize(pStubMsg, pFormat);
2707 pStubMsg->MemorySize = SavedMemorySize;
2709 pStubMsg->MemorySize += MemorySize;
2713 /***********************************************************************
2714 * NdrComplexArrayFree [RPCRT4.@]
2716 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2717 unsigned char *pMemory,
2718 PFORMAT_STRING pFormat)
2720 ULONG i, count, def;
2722 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2724 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2726 ERR("invalid format type %x\n", pFormat[0]);
2727 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2731 def = *(const WORD*)&pFormat[2];
2734 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2735 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2737 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2738 TRACE("variance = %d\n", pStubMsg->ActualCount);
2740 count = pStubMsg->ActualCount;
2741 for (i = 0; i < count; i++)
2742 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2745 static ULONG UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
2747 return MAKELONG(pStubMsg->dwDestContext,
2748 pStubMsg->RpcMsg->DataRepresentation);
2751 #define USER_MARSHAL_PTR_PREFIX \
2752 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
2753 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
2755 /***********************************************************************
2756 * NdrUserMarshalMarshall [RPCRT4.@]
2758 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2759 unsigned char *pMemory,
2760 PFORMAT_STRING pFormat)
2762 unsigned flags = pFormat[1];
2763 unsigned index = *(const WORD*)&pFormat[2];
2764 ULONG uflag = UserMarshalFlags(pStubMsg);
2765 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2766 TRACE("index=%d\n", index);
2768 if (flags & USER_MARSHAL_POINTER)
2770 ALIGN_POINTER(pStubMsg->Buffer, 4);
2771 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
2772 pStubMsg->Buffer += 4;
2773 ALIGN_POINTER(pStubMsg->Buffer, 8);
2776 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2779 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
2780 &uflag, pStubMsg->Buffer, pMemory);
2782 STD_OVERFLOW_CHECK(pStubMsg);
2787 /***********************************************************************
2788 * NdrUserMarshalUnmarshall [RPCRT4.@]
2790 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2791 unsigned char **ppMemory,
2792 PFORMAT_STRING pFormat,
2793 unsigned char fMustAlloc)
2795 unsigned flags = pFormat[1];
2796 unsigned index = *(const WORD*)&pFormat[2];
2797 DWORD memsize = *(const WORD*)&pFormat[4];
2798 ULONG uflag = UserMarshalFlags(pStubMsg);
2799 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2800 TRACE("index=%d\n", index);
2802 if (flags & USER_MARSHAL_POINTER)
2804 ALIGN_POINTER(pStubMsg->Buffer, 4);
2805 /* skip pointer prefix */
2806 pStubMsg->Buffer += 4;
2807 ALIGN_POINTER(pStubMsg->Buffer, 8);
2810 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2812 if (fMustAlloc || !*ppMemory)
2813 *ppMemory = NdrAllocate(pStubMsg, memsize);
2816 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
2817 &uflag, pStubMsg->Buffer, *ppMemory);
2822 /***********************************************************************
2823 * NdrUserMarshalBufferSize [RPCRT4.@]
2825 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2826 unsigned char *pMemory,
2827 PFORMAT_STRING pFormat)
2829 unsigned flags = pFormat[1];
2830 unsigned index = *(const WORD*)&pFormat[2];
2831 DWORD bufsize = *(const WORD*)&pFormat[6];
2832 ULONG uflag = UserMarshalFlags(pStubMsg);
2833 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2834 TRACE("index=%d\n", index);
2836 if (flags & USER_MARSHAL_POINTER)
2838 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2839 /* skip pointer prefix */
2840 pStubMsg->BufferLength += 4;
2841 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
2844 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
2847 TRACE("size=%d\n", bufsize);
2848 pStubMsg->BufferLength += bufsize;
2852 pStubMsg->BufferLength =
2853 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
2854 &uflag, pStubMsg->BufferLength, pMemory);
2857 /***********************************************************************
2858 * NdrUserMarshalMemorySize [RPCRT4.@]
2860 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2861 PFORMAT_STRING pFormat)
2863 unsigned flags = pFormat[1];
2864 unsigned index = *(const WORD*)&pFormat[2];
2865 DWORD memsize = *(const WORD*)&pFormat[4];
2866 DWORD bufsize = *(const WORD*)&pFormat[6];
2868 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2869 TRACE("index=%d\n", index);
2871 pStubMsg->MemorySize += memsize;
2873 if (flags & USER_MARSHAL_POINTER)
2875 ALIGN_POINTER(pStubMsg->Buffer, 4);
2876 /* skip pointer prefix */
2877 pStubMsg->Buffer += 4;
2878 ALIGN_POINTER(pStubMsg->Buffer, 8);
2881 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2883 pStubMsg->Buffer += bufsize;
2885 return pStubMsg->MemorySize;
2888 /***********************************************************************
2889 * NdrUserMarshalFree [RPCRT4.@]
2891 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
2892 unsigned char *pMemory,
2893 PFORMAT_STRING pFormat)
2895 /* unsigned flags = pFormat[1]; */
2896 unsigned index = *(const WORD*)&pFormat[2];
2897 ULONG uflag = UserMarshalFlags(pStubMsg);
2898 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2899 TRACE("index=%d\n", index);
2901 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
2905 /***********************************************************************
2906 * NdrClearOutParameters [RPCRT4.@]
2908 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
2909 PFORMAT_STRING pFormat,
2912 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
2915 /***********************************************************************
2916 * NdrConvert [RPCRT4.@]
2918 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
2920 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
2921 /* FIXME: since this stub doesn't do any converting, the proper behavior
2922 is to raise an exception */
2925 /***********************************************************************
2926 * NdrConvert2 [RPCRT4.@]
2928 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
2930 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
2931 pStubMsg, pFormat, NumberParams);
2932 /* FIXME: since this stub doesn't do any converting, the proper behavior
2933 is to raise an exception */
2936 typedef struct _NDR_CSTRUCT_FORMAT
2939 unsigned char alignment;
2940 unsigned short memory_size;
2941 short offset_to_array_description;
2942 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
2944 /***********************************************************************
2945 * NdrConformantStructMarshall [RPCRT4.@]
2947 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2948 unsigned char *pMemory,
2949 PFORMAT_STRING pFormat)
2951 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
2952 PFORMAT_STRING pCArrayFormat;
2953 ULONG esize, bufsize;
2955 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2957 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2958 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2960 ERR("invalid format type %x\n", pCStructFormat->type);
2961 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2965 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
2966 pCStructFormat->offset_to_array_description;
2967 if (*pCArrayFormat != RPC_FC_CARRAY)
2969 ERR("invalid array format type %x\n", pCStructFormat->type);
2970 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2973 esize = *(const WORD*)(pCArrayFormat+2);
2975 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
2976 pCArrayFormat + 4, 0);
2978 WriteConformance(pStubMsg);
2980 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
2982 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2984 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
2985 /* copy constant sized part of struct */
2986 pStubMsg->BufferMark = pStubMsg->Buffer;
2987 memcpy(pStubMsg->Buffer, pMemory, pCStructFormat->memory_size + bufsize);
2988 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
2990 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2991 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2993 STD_OVERFLOW_CHECK(pStubMsg);
2998 /***********************************************************************
2999 * NdrConformantStructUnmarshall [RPCRT4.@]
3001 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3002 unsigned char **ppMemory,
3003 PFORMAT_STRING pFormat,
3004 unsigned char fMustAlloc)
3006 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3007 PFORMAT_STRING pCArrayFormat;
3008 ULONG esize, bufsize;
3010 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3012 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3013 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3015 ERR("invalid format type %x\n", pCStructFormat->type);
3016 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3019 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3020 pCStructFormat->offset_to_array_description;
3021 if (*pCArrayFormat != RPC_FC_CARRAY)
3023 ERR("invalid array format type %x\n", pCStructFormat->type);
3024 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3027 esize = *(const WORD*)(pCArrayFormat+2);
3029 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3031 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3033 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3035 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3036 /* work out how much memory to allocate if we need to do so */
3037 if (!*ppMemory || fMustAlloc)
3039 SIZE_T size = pCStructFormat->memory_size + bufsize;
3040 *ppMemory = NdrAllocate(pStubMsg, size);
3043 /* now copy the data */
3044 pStubMsg->BufferMark = pStubMsg->Buffer;
3045 memcpy(*ppMemory, pStubMsg->Buffer, pCStructFormat->memory_size + bufsize);
3046 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
3048 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3049 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3054 /***********************************************************************
3055 * NdrConformantStructBufferSize [RPCRT4.@]
3057 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3058 unsigned char *pMemory,
3059 PFORMAT_STRING pFormat)
3061 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3062 PFORMAT_STRING pCArrayFormat;
3065 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3067 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3068 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3070 ERR("invalid format type %x\n", pCStructFormat->type);
3071 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3074 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3075 pCStructFormat->offset_to_array_description;
3076 if (*pCArrayFormat != RPC_FC_CARRAY)
3078 ERR("invalid array format type %x\n", pCStructFormat->type);
3079 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3082 esize = *(const WORD*)(pCArrayFormat+2);
3084 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
3085 SizeConformance(pStubMsg);
3087 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
3089 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3091 pStubMsg->BufferLength += pCStructFormat->memory_size +
3092 safe_multiply(pStubMsg->MaxCount, esize);
3094 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3095 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3098 /***********************************************************************
3099 * NdrConformantStructMemorySize [RPCRT4.@]
3101 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3102 PFORMAT_STRING pFormat)
3108 /***********************************************************************
3109 * NdrConformantStructFree [RPCRT4.@]
3111 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3112 unsigned char *pMemory,
3113 PFORMAT_STRING pFormat)
3118 /***********************************************************************
3119 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3121 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3122 unsigned char *pMemory,
3123 PFORMAT_STRING pFormat)
3125 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3126 PFORMAT_STRING pCVArrayFormat;
3127 ULONG esize, bufsize;
3129 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3131 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3132 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3134 ERR("invalid format type %x\n", pCVStructFormat->type);
3135 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3139 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3140 pCVStructFormat->offset_to_array_description;
3141 switch (*pCVArrayFormat)
3143 case RPC_FC_CVARRAY:
3144 esize = *(const WORD*)(pCVArrayFormat+2);
3146 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3147 pCVArrayFormat + 4, 0);
3148 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3151 case RPC_FC_C_CSTRING:
3152 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3153 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3154 esize = sizeof(char);
3155 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3156 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3157 pCVArrayFormat + 2, 0);
3159 pStubMsg->MaxCount = pStubMsg->ActualCount;
3161 case RPC_FC_C_WSTRING:
3162 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3163 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3164 esize = sizeof(WCHAR);
3165 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3166 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3167 pCVArrayFormat + 2, 0);
3169 pStubMsg->MaxCount = pStubMsg->ActualCount;
3172 ERR("invalid array format type %x\n", *pCVArrayFormat);
3173 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3177 WriteConformance(pStubMsg);
3179 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3181 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3183 /* write constant sized part */
3184 pStubMsg->BufferMark = pStubMsg->Buffer;
3185 memcpy(pStubMsg->Buffer, pMemory, pCVStructFormat->memory_size);
3186 pStubMsg->Buffer += pCVStructFormat->memory_size;
3188 WriteVariance(pStubMsg);
3190 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3192 /* write array part */
3193 memcpy(pStubMsg->Buffer, pMemory + pCVStructFormat->memory_size, bufsize);
3194 pStubMsg->Buffer += bufsize;
3196 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3198 STD_OVERFLOW_CHECK(pStubMsg);
3203 /***********************************************************************
3204 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3206 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3207 unsigned char **ppMemory,
3208 PFORMAT_STRING pFormat,
3209 unsigned char fMustAlloc)
3211 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3212 PFORMAT_STRING pCVArrayFormat;
3213 ULONG esize, bufsize;
3214 unsigned char cvarray_type;
3216 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3218 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3219 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3221 ERR("invalid format type %x\n", pCVStructFormat->type);
3222 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3226 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3227 pCVStructFormat->offset_to_array_description;
3228 cvarray_type = *pCVArrayFormat;
3229 switch (cvarray_type)
3231 case RPC_FC_CVARRAY:
3232 esize = *(const WORD*)(pCVArrayFormat+2);
3233 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3235 case RPC_FC_C_CSTRING:
3236 esize = sizeof(char);
3237 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3238 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3240 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3242 case RPC_FC_C_WSTRING:
3243 esize = sizeof(WCHAR);
3244 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3245 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3247 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3250 ERR("invalid array format type %x\n", *pCVArrayFormat);
3251 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3255 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3257 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3259 /* work out how much memory to allocate if we need to do so */
3260 if (!*ppMemory || fMustAlloc)
3262 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3263 *ppMemory = NdrAllocate(pStubMsg, size);
3266 /* copy the constant data */
3267 pStubMsg->BufferMark = pStubMsg->Buffer;
3268 memcpy(*ppMemory, pStubMsg->Buffer, pCVStructFormat->memory_size);
3269 pStubMsg->Buffer += pCVStructFormat->memory_size;
3271 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3273 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3275 if ((cvarray_type == RPC_FC_C_CSTRING) ||
3276 (cvarray_type == RPC_FC_C_WSTRING))
3279 /* strings must always have null terminating bytes */
3280 if (bufsize < esize)
3282 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
3283 RpcRaiseException(RPC_S_INVALID_BOUND);
3286 for (i = bufsize - esize; i < bufsize; i++)
3287 if (pStubMsg->Buffer[i] != 0)
3289 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3290 i, pStubMsg->Buffer[i]);
3291 RpcRaiseException(RPC_S_INVALID_BOUND);
3296 /* copy the array data */
3297 memcpy(*ppMemory + pCVStructFormat->memory_size, pStubMsg->Buffer,
3299 pStubMsg->Buffer += bufsize;
3301 if (cvarray_type == RPC_FC_C_CSTRING)
3302 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3303 else if (cvarray_type == RPC_FC_C_WSTRING)
3304 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3306 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3311 /***********************************************************************
3312 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3314 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3315 unsigned char *pMemory,
3316 PFORMAT_STRING pFormat)
3318 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3319 PFORMAT_STRING pCVArrayFormat;
3322 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3324 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3325 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3327 ERR("invalid format type %x\n", pCVStructFormat->type);
3328 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3332 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3333 pCVStructFormat->offset_to_array_description;
3334 switch (*pCVArrayFormat)
3336 case RPC_FC_CVARRAY:
3337 esize = *(const WORD*)(pCVArrayFormat+2);
3339 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3340 pCVArrayFormat + 4, 0);
3341 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3344 case RPC_FC_C_CSTRING:
3345 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3346 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3347 esize = sizeof(char);
3348 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3349 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3350 pCVArrayFormat + 2, 0);
3352 pStubMsg->MaxCount = pStubMsg->ActualCount;
3354 case RPC_FC_C_WSTRING:
3355 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3356 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3357 esize = sizeof(WCHAR);
3358 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3359 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3360 pCVArrayFormat + 2, 0);
3362 pStubMsg->MaxCount = pStubMsg->ActualCount;
3365 ERR("invalid array format type %x\n", *pCVArrayFormat);
3366 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3370 SizeConformance(pStubMsg);
3372 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
3374 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3376 pStubMsg->BufferLength += pCVStructFormat->memory_size;
3377 SizeVariance(pStubMsg);
3378 pStubMsg->BufferLength += safe_multiply(pStubMsg->MaxCount, esize);
3380 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3383 /***********************************************************************
3384 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3386 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3387 PFORMAT_STRING pFormat)
3389 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3390 PFORMAT_STRING pCVArrayFormat;
3392 unsigned char cvarray_type;
3394 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3396 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3397 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3399 ERR("invalid format type %x\n", pCVStructFormat->type);
3400 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3404 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3405 pCVStructFormat->offset_to_array_description;
3406 cvarray_type = *pCVArrayFormat;
3407 switch (cvarray_type)
3409 case RPC_FC_CVARRAY:
3410 esize = *(const WORD*)(pCVArrayFormat+2);
3411 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3413 case RPC_FC_C_CSTRING:
3414 esize = sizeof(char);
3415 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3416 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3418 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3420 case RPC_FC_C_WSTRING:
3421 esize = sizeof(WCHAR);
3422 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3423 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3425 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3428 ERR("invalid array format type %x\n", *pCVArrayFormat);
3429 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3433 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3435 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3437 pStubMsg->Buffer += pCVStructFormat->memory_size;
3438 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3439 pStubMsg->Buffer += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->ActualCount);
3441 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3443 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3445 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3448 /***********************************************************************
3449 * NdrConformantVaryingStructFree [RPCRT4.@]
3451 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3452 unsigned char *pMemory,
3453 PFORMAT_STRING pFormat)
3455 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3456 PFORMAT_STRING pCVArrayFormat;
3459 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3461 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3462 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3464 ERR("invalid format type %x\n", pCVStructFormat->type);
3465 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3469 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3470 pCVStructFormat->offset_to_array_description;
3471 switch (*pCVArrayFormat)
3473 case RPC_FC_CVARRAY:
3474 esize = *(const WORD*)(pCVArrayFormat+2);
3476 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3477 pCVArrayFormat + 4, 0);
3478 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3481 case RPC_FC_C_CSTRING:
3482 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3483 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3484 esize = sizeof(char);
3485 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3486 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3487 pCVArrayFormat + 2, 0);
3489 pStubMsg->MaxCount = pStubMsg->ActualCount;
3491 case RPC_FC_C_WSTRING:
3492 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3493 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3494 esize = sizeof(WCHAR);
3495 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3496 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3497 pCVArrayFormat + 2, 0);
3499 pStubMsg->MaxCount = pStubMsg->ActualCount;
3502 ERR("invalid array format type %x\n", *pCVArrayFormat);
3503 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3507 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3509 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3515 unsigned char alignment;
3516 unsigned short total_size;
3517 } NDR_SMFARRAY_FORMAT;
3522 unsigned char alignment;
3523 unsigned long total_size;
3524 } NDR_LGFARRAY_FORMAT;
3526 /***********************************************************************
3527 * NdrFixedArrayMarshall [RPCRT4.@]
3529 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3530 unsigned char *pMemory,
3531 PFORMAT_STRING pFormat)
3533 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3534 unsigned long total_size;
3536 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3538 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3539 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3541 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3542 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3546 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3548 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3550 total_size = pSmFArrayFormat->total_size;
3551 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3555 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3556 total_size = pLgFArrayFormat->total_size;
3557 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3560 memcpy(pStubMsg->Buffer, pMemory, total_size);
3561 pStubMsg->BufferMark = pStubMsg->Buffer;
3562 pStubMsg->Buffer += total_size;
3564 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3569 /***********************************************************************
3570 * NdrFixedArrayUnmarshall [RPCRT4.@]
3572 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3573 unsigned char **ppMemory,
3574 PFORMAT_STRING pFormat,
3575 unsigned char fMustAlloc)
3577 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3578 unsigned long total_size;
3580 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3582 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3583 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3585 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3586 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3590 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3592 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3594 total_size = pSmFArrayFormat->total_size;
3595 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3599 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3600 total_size = pLgFArrayFormat->total_size;
3601 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3604 if (fMustAlloc || !*ppMemory)
3605 *ppMemory = NdrAllocate(pStubMsg, total_size);
3606 memcpy(*ppMemory, pStubMsg->Buffer, total_size);
3607 pStubMsg->BufferMark = pStubMsg->Buffer;
3608 pStubMsg->Buffer += total_size;
3610 pFormat = EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3615 /***********************************************************************
3616 * NdrFixedArrayBufferSize [RPCRT4.@]
3618 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3619 unsigned char *pMemory,
3620 PFORMAT_STRING pFormat)
3622 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3623 unsigned long total_size;
3625 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3627 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3628 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3630 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3631 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3635 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
3637 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3639 total_size = pSmFArrayFormat->total_size;
3640 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3644 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3645 total_size = pLgFArrayFormat->total_size;
3646 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3648 pStubMsg->BufferLength += total_size;
3650 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3653 /***********************************************************************
3654 * NdrFixedArrayMemorySize [RPCRT4.@]
3656 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3657 PFORMAT_STRING pFormat)
3659 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3662 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3664 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3665 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3667 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3668 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3672 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3674 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3676 total_size = pSmFArrayFormat->total_size;
3677 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3681 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3682 total_size = pLgFArrayFormat->total_size;
3683 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3685 pStubMsg->BufferMark = pStubMsg->Buffer;
3686 pStubMsg->Buffer += total_size;
3687 pStubMsg->MemorySize += total_size;
3689 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3694 /***********************************************************************
3695 * NdrFixedArrayFree [RPCRT4.@]
3697 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3698 unsigned char *pMemory,
3699 PFORMAT_STRING pFormat)
3701 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3703 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3705 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3706 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3708 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3709 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3713 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3714 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3717 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3718 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3721 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3724 /***********************************************************************
3725 * NdrVaryingArrayMarshall [RPCRT4.@]
3727 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3728 unsigned char *pMemory,
3729 PFORMAT_STRING pFormat)
3731 unsigned char alignment;
3732 DWORD elements, esize;
3735 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3737 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3738 (pFormat[0] != RPC_FC_LGVARRAY))
3740 ERR("invalid format type %x\n", pFormat[0]);
3741 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3745 alignment = pFormat[1] + 1;
3747 if (pFormat[0] == RPC_FC_SMVARRAY)
3750 pFormat += sizeof(WORD);
3751 elements = *(const WORD*)pFormat;
3752 pFormat += sizeof(WORD);
3757 pFormat += sizeof(DWORD);
3758 elements = *(const DWORD*)pFormat;
3759 pFormat += sizeof(DWORD);
3762 esize = *(const WORD*)pFormat;
3763 pFormat += sizeof(WORD);
3765 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3766 if ((pStubMsg->ActualCount > elements) ||
3767 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3769 RpcRaiseException(RPC_S_INVALID_BOUND);
3773 WriteVariance(pStubMsg);
3775 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3777 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3778 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
3779 pStubMsg->BufferMark = pStubMsg->Buffer;
3780 pStubMsg->Buffer += bufsize;
3782 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3784 STD_OVERFLOW_CHECK(pStubMsg);
3789 /***********************************************************************
3790 * NdrVaryingArrayUnmarshall [RPCRT4.@]
3792 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3793 unsigned char **ppMemory,
3794 PFORMAT_STRING pFormat,
3795 unsigned char fMustAlloc)
3797 unsigned char alignment;
3798 DWORD size, elements, esize;
3801 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3803 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3804 (pFormat[0] != RPC_FC_LGVARRAY))
3806 ERR("invalid format type %x\n", pFormat[0]);
3807 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3811 alignment = pFormat[1] + 1;
3813 if (pFormat[0] == RPC_FC_SMVARRAY)
3816 size = *(const WORD*)pFormat;
3817 pFormat += sizeof(WORD);
3818 elements = *(const WORD*)pFormat;
3819 pFormat += sizeof(WORD);
3824 size = *(const DWORD*)pFormat;
3825 pFormat += sizeof(DWORD);
3826 elements = *(const DWORD*)pFormat;
3827 pFormat += sizeof(DWORD);
3830 esize = *(const WORD*)pFormat;
3831 pFormat += sizeof(WORD);
3833 pFormat = ReadVariance(pStubMsg, pFormat, elements);
3835 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3837 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3839 if (!*ppMemory || fMustAlloc)
3840 *ppMemory = NdrAllocate(pStubMsg, size);
3841 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
3842 pStubMsg->Buffer += bufsize;
3844 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3849 /***********************************************************************
3850 * NdrVaryingArrayBufferSize [RPCRT4.@]
3852 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3853 unsigned char *pMemory,
3854 PFORMAT_STRING pFormat)
3856 unsigned char alignment;
3857 DWORD elements, esize;
3859 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3861 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3862 (pFormat[0] != RPC_FC_LGVARRAY))
3864 ERR("invalid format type %x\n", pFormat[0]);
3865 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3869 alignment = pFormat[1] + 1;
3871 if (pFormat[0] == RPC_FC_SMVARRAY)
3874 pFormat += sizeof(WORD);
3875 elements = *(const WORD*)pFormat;
3876 pFormat += sizeof(WORD);
3881 pFormat += sizeof(DWORD);
3882 elements = *(const DWORD*)pFormat;
3883 pFormat += sizeof(DWORD);
3886 esize = *(const WORD*)pFormat;
3887 pFormat += sizeof(WORD);
3889 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3890 if ((pStubMsg->ActualCount > elements) ||
3891 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3893 RpcRaiseException(RPC_S_INVALID_BOUND);
3897 SizeVariance(pStubMsg);
3899 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3901 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
3903 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3906 /***********************************************************************
3907 * NdrVaryingArrayMemorySize [RPCRT4.@]
3909 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3910 PFORMAT_STRING pFormat)
3912 unsigned char alignment;
3913 DWORD size, elements, esize;
3915 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3917 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3918 (pFormat[0] != RPC_FC_LGVARRAY))
3920 ERR("invalid format type %x\n", pFormat[0]);
3921 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3925 alignment = pFormat[1] + 1;
3927 if (pFormat[0] == RPC_FC_SMVARRAY)
3930 size = *(const WORD*)pFormat;
3931 pFormat += sizeof(WORD);
3932 elements = *(const WORD*)pFormat;
3933 pFormat += sizeof(WORD);
3938 size = *(const DWORD*)pFormat;
3939 pFormat += sizeof(DWORD);
3940 elements = *(const DWORD*)pFormat;
3941 pFormat += sizeof(DWORD);
3944 esize = *(const WORD*)pFormat;
3945 pFormat += sizeof(WORD);
3947 pFormat = ReadVariance(pStubMsg, pFormat, elements);
3949 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3951 pStubMsg->Buffer += safe_multiply(esize, pStubMsg->ActualCount);
3952 pStubMsg->MemorySize += size;
3954 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3956 return pStubMsg->MemorySize;
3959 /***********************************************************************
3960 * NdrVaryingArrayFree [RPCRT4.@]
3962 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3963 unsigned char *pMemory,
3964 PFORMAT_STRING pFormat)
3966 unsigned char alignment;
3969 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3971 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3972 (pFormat[0] != RPC_FC_LGVARRAY))
3974 ERR("invalid format type %x\n", pFormat[0]);
3975 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3979 alignment = pFormat[1] + 1;
3981 if (pFormat[0] == RPC_FC_SMVARRAY)
3984 pFormat += sizeof(WORD);
3985 elements = *(const WORD*)pFormat;
3986 pFormat += sizeof(WORD);
3991 pFormat += sizeof(DWORD);
3992 elements = *(const DWORD*)pFormat;
3993 pFormat += sizeof(DWORD);
3996 pFormat += sizeof(WORD);
3998 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3999 if ((pStubMsg->ActualCount > elements) ||
4000 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4002 RpcRaiseException(RPC_S_INVALID_BOUND);
4006 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4009 /***********************************************************************
4010 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4012 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4013 unsigned char *pMemory,
4014 PFORMAT_STRING pFormat)
4020 /***********************************************************************
4021 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4023 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4024 unsigned char **ppMemory,
4025 PFORMAT_STRING pFormat,
4026 unsigned char fMustAlloc)
4032 /***********************************************************************
4033 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4035 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4036 unsigned char *pMemory,
4037 PFORMAT_STRING pFormat)
4042 /***********************************************************************
4043 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4045 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4046 PFORMAT_STRING pFormat)
4052 /***********************************************************************
4053 * NdrEncapsulatedUnionFree [RPCRT4.@]
4055 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4056 unsigned char *pMemory,
4057 PFORMAT_STRING pFormat)
4062 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4063 unsigned long discriminant,
4064 PFORMAT_STRING pFormat)
4066 unsigned short num_arms, arm, type;
4068 num_arms = *(const SHORT*)pFormat & 0x0fff;
4070 for(arm = 0; arm < num_arms; arm++)
4072 if(discriminant == *(const ULONG*)pFormat)
4080 type = *(const unsigned short*)pFormat;
4081 TRACE("type %04x\n", type);
4082 if(arm == num_arms) /* default arm extras */
4086 ERR("no arm for 0x%lx and no default case\n", discriminant);
4087 RpcRaiseException(RPC_S_INVALID_TAG);
4092 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
4099 static PFORMAT_STRING get_non_encapsulated_union_arm(PMIDL_STUB_MESSAGE pStubMsg,
4101 PFORMAT_STRING pFormat)
4103 pFormat += *(const SHORT*)pFormat;
4106 return get_arm_offset_from_union_arm_selector(pStubMsg, value, pFormat);
4109 /***********************************************************************
4110 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
4112 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4113 unsigned char *pMemory,
4114 PFORMAT_STRING pFormat)
4116 unsigned short type;
4117 unsigned char switch_type;
4119 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4122 switch_type = *pFormat;
4125 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4126 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4127 /* Marshall discriminant */
4128 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4130 pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
4134 type = *(const unsigned short*)pFormat;
4135 if((type & 0xff00) == 0x8000)
4137 unsigned char basetype = LOBYTE(type);
4138 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
4142 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4143 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
4146 unsigned char *saved_buffer = NULL;
4153 saved_buffer = pStubMsg->Buffer;
4154 pStubMsg->Buffer += 4; /* for pointer ID */
4155 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
4158 m(pStubMsg, pMemory, desc);
4161 else FIXME("no marshaller for embedded type %02x\n", *desc);
4166 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
4167 PFORMAT_STRING *ppFormat)
4169 long discriminant = 0;
4177 discriminant = *(UCHAR *)pStubMsg->Buffer;
4178 pStubMsg->Buffer += sizeof(UCHAR);
4183 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4184 discriminant = *(USHORT *)pStubMsg->Buffer;
4185 pStubMsg->Buffer += sizeof(USHORT);
4189 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4190 discriminant = *(ULONG *)pStubMsg->Buffer;
4191 pStubMsg->Buffer += sizeof(ULONG);
4194 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
4198 if (pStubMsg->fHasNewCorrDesc)
4202 return discriminant;
4205 /**********************************************************************
4206 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
4208 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4209 unsigned char **ppMemory,
4210 PFORMAT_STRING pFormat,
4211 unsigned char fMustAlloc)
4214 unsigned short type, size;
4216 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4219 /* Unmarshall discriminant */
4220 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4221 TRACE("unmarshalled discriminant %lx\n", discriminant);
4223 pFormat += *(const SHORT*)pFormat;
4225 size = *(const unsigned short*)pFormat;
4228 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4232 if(!*ppMemory || fMustAlloc)
4233 *ppMemory = NdrAllocate(pStubMsg, size);
4235 type = *(const unsigned short*)pFormat;
4236 if((type & 0xff00) == 0x8000)
4238 unsigned char basetype = LOBYTE(type);
4239 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, fMustAlloc);
4243 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4244 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
4247 unsigned char *saved_buffer = NULL;
4254 ALIGN_POINTER(pStubMsg->Buffer, 4);
4255 saved_buffer = pStubMsg->Buffer;
4256 pStubMsg->Buffer += 4; /* for pointer ID */
4257 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, desc, TRUE);
4260 m(pStubMsg, ppMemory, desc, fMustAlloc);
4263 else FIXME("no marshaller for embedded type %02x\n", *desc);
4268 /***********************************************************************
4269 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
4271 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4272 unsigned char *pMemory,
4273 PFORMAT_STRING pFormat)
4275 unsigned short type;
4276 unsigned char switch_type;
4278 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4281 switch_type = *pFormat;
4284 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4285 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4286 /* Add discriminant size */
4287 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4289 pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
4293 type = *(const unsigned short*)pFormat;
4294 if((type & 0xff00) == 0x8000)
4296 unsigned char basetype = LOBYTE(type);
4297 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
4301 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4302 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
4311 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4312 pStubMsg->BufferLength += 4; /* for pointer ID */
4313 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
4316 m(pStubMsg, pMemory, desc);
4319 else FIXME("no buffersizer for embedded type %02x\n", *desc);
4324 /***********************************************************************
4325 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
4327 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4328 PFORMAT_STRING pFormat)
4331 unsigned short type, size;
4334 /* Unmarshall discriminant */
4335 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4336 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
4338 pFormat += *(const SHORT*)pFormat;
4340 size = *(const unsigned short*)pFormat;
4343 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4347 pStubMsg->Memory += size;
4349 type = *(const unsigned short*)pFormat;
4350 if((type & 0xff00) == 0x8000)
4352 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
4356 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4357 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
4358 unsigned char *saved_buffer;
4367 ALIGN_POINTER(pStubMsg->Buffer, 4);
4368 saved_buffer = pStubMsg->Buffer;
4369 pStubMsg->Buffer += 4;
4370 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
4371 pStubMsg->MemorySize += 4;
4372 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
4375 return m(pStubMsg, desc);
4378 else FIXME("no marshaller for embedded type %02x\n", *desc);
4381 TRACE("size %d\n", size);
4385 /***********************************************************************
4386 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
4388 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4389 unsigned char *pMemory,
4390 PFORMAT_STRING pFormat)
4395 /***********************************************************************
4396 * NdrByteCountPointerMarshall [RPCRT4.@]
4398 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4399 unsigned char *pMemory,
4400 PFORMAT_STRING pFormat)
4406 /***********************************************************************
4407 * NdrByteCountPointerUnmarshall [RPCRT4.@]
4409 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4410 unsigned char **ppMemory,
4411 PFORMAT_STRING pFormat,
4412 unsigned char fMustAlloc)
4418 /***********************************************************************
4419 * NdrByteCountPointerBufferSize [RPCRT4.@]
4421 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4422 unsigned char *pMemory,
4423 PFORMAT_STRING pFormat)
4428 /***********************************************************************
4429 * NdrByteCountPointerMemorySize [RPCRT4.@]
4431 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4432 PFORMAT_STRING pFormat)
4438 /***********************************************************************
4439 * NdrByteCountPointerFree [RPCRT4.@]
4441 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
4442 unsigned char *pMemory,
4443 PFORMAT_STRING pFormat)
4448 /***********************************************************************
4449 * NdrXmitOrRepAsMarshall [RPCRT4.@]
4451 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4452 unsigned char *pMemory,
4453 PFORMAT_STRING pFormat)
4459 /***********************************************************************
4460 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
4462 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4463 unsigned char **ppMemory,
4464 PFORMAT_STRING pFormat,
4465 unsigned char fMustAlloc)
4471 /***********************************************************************
4472 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
4474 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4475 unsigned char *pMemory,
4476 PFORMAT_STRING pFormat)
4481 /***********************************************************************
4482 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
4484 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4485 PFORMAT_STRING pFormat)
4491 /***********************************************************************
4492 * NdrXmitOrRepAsFree [RPCRT4.@]
4494 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
4495 unsigned char *pMemory,
4496 PFORMAT_STRING pFormat)
4501 /***********************************************************************
4502 * NdrBaseTypeMarshall [internal]
4504 static unsigned char *WINAPI NdrBaseTypeMarshall(
4505 PMIDL_STUB_MESSAGE pStubMsg,
4506 unsigned char *pMemory,
4507 PFORMAT_STRING pFormat)
4509 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4517 *(UCHAR *)pStubMsg->Buffer = *(UCHAR *)pMemory;
4518 pStubMsg->Buffer += sizeof(UCHAR);
4519 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
4524 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4525 *(USHORT *)pStubMsg->Buffer = *(USHORT *)pMemory;
4526 pStubMsg->Buffer += sizeof(USHORT);
4527 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
4531 case RPC_FC_ERROR_STATUS_T:
4533 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4534 *(ULONG *)pStubMsg->Buffer = *(ULONG *)pMemory;
4535 pStubMsg->Buffer += sizeof(ULONG);
4536 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
4539 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
4540 *(float *)pStubMsg->Buffer = *(float *)pMemory;
4541 pStubMsg->Buffer += sizeof(float);
4544 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
4545 *(double *)pStubMsg->Buffer = *(double *)pMemory;
4546 pStubMsg->Buffer += sizeof(double);
4549 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
4550 *(ULONGLONG *)pStubMsg->Buffer = *(ULONGLONG *)pMemory;
4551 pStubMsg->Buffer += sizeof(ULONGLONG);
4552 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
4555 /* only 16-bits on the wire, so do a sanity check */
4556 if (*(UINT *)pMemory > USHRT_MAX)
4557 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
4558 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4559 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
4560 pStubMsg->Buffer += sizeof(USHORT);
4561 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
4564 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4567 STD_OVERFLOW_CHECK(pStubMsg);
4569 /* FIXME: what is the correct return value? */
4573 /***********************************************************************
4574 * NdrBaseTypeUnmarshall [internal]
4576 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
4577 PMIDL_STUB_MESSAGE pStubMsg,
4578 unsigned char **ppMemory,
4579 PFORMAT_STRING pFormat,
4580 unsigned char fMustAlloc)
4582 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
4584 #define BASE_TYPE_UNMARSHALL(type) \
4585 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
4586 if (fMustAlloc || !*ppMemory) \
4587 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
4588 TRACE("*ppMemory: %p\n", *ppMemory); \
4589 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
4590 pStubMsg->Buffer += sizeof(type);
4598 BASE_TYPE_UNMARSHALL(UCHAR);
4599 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
4604 BASE_TYPE_UNMARSHALL(USHORT);
4605 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
4609 case RPC_FC_ERROR_STATUS_T:
4611 BASE_TYPE_UNMARSHALL(ULONG);
4612 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
4615 BASE_TYPE_UNMARSHALL(float);
4616 TRACE("value: %f\n", **(float **)ppMemory);
4619 BASE_TYPE_UNMARSHALL(double);
4620 TRACE("value: %f\n", **(double **)ppMemory);
4623 BASE_TYPE_UNMARSHALL(ULONGLONG);
4624 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
4627 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4628 if (fMustAlloc || !*ppMemory)
4629 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
4630 TRACE("*ppMemory: %p\n", *ppMemory);
4631 /* 16-bits on the wire, but int in memory */
4632 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
4633 pStubMsg->Buffer += sizeof(USHORT);
4634 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
4637 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4639 #undef BASE_TYPE_UNMARSHALL
4641 /* FIXME: what is the correct return value? */
4646 /***********************************************************************
4647 * NdrBaseTypeBufferSize [internal]
4649 static void WINAPI NdrBaseTypeBufferSize(
4650 PMIDL_STUB_MESSAGE pStubMsg,
4651 unsigned char *pMemory,
4652 PFORMAT_STRING pFormat)
4654 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4662 pStubMsg->BufferLength += sizeof(UCHAR);
4668 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
4669 pStubMsg->BufferLength += sizeof(USHORT);
4674 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
4675 pStubMsg->BufferLength += sizeof(ULONG);
4678 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
4679 pStubMsg->BufferLength += sizeof(float);
4682 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
4683 pStubMsg->BufferLength += sizeof(double);
4686 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
4687 pStubMsg->BufferLength += sizeof(ULONGLONG);
4689 case RPC_FC_ERROR_STATUS_T:
4690 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
4691 pStubMsg->BufferLength += sizeof(error_status_t);
4694 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4698 /***********************************************************************
4699 * NdrBaseTypeMemorySize [internal]
4701 static ULONG WINAPI NdrBaseTypeMemorySize(
4702 PMIDL_STUB_MESSAGE pStubMsg,
4703 PFORMAT_STRING pFormat)
4711 pStubMsg->Buffer += sizeof(UCHAR);
4712 pStubMsg->MemorySize += sizeof(UCHAR);
4713 return sizeof(UCHAR);
4717 pStubMsg->Buffer += sizeof(USHORT);
4718 pStubMsg->MemorySize += sizeof(USHORT);
4719 return sizeof(USHORT);
4722 pStubMsg->Buffer += sizeof(ULONG);
4723 pStubMsg->MemorySize += sizeof(ULONG);
4724 return sizeof(ULONG);
4726 pStubMsg->Buffer += sizeof(float);
4727 pStubMsg->MemorySize += sizeof(float);
4728 return sizeof(float);
4730 pStubMsg->Buffer += sizeof(double);
4731 pStubMsg->MemorySize += sizeof(double);
4732 return sizeof(double);
4734 pStubMsg->Buffer += sizeof(ULONGLONG);
4735 pStubMsg->MemorySize += sizeof(ULONGLONG);
4736 return sizeof(ULONGLONG);
4737 case RPC_FC_ERROR_STATUS_T:
4738 pStubMsg->Buffer += sizeof(error_status_t);
4739 pStubMsg->MemorySize += sizeof(error_status_t);
4740 return sizeof(error_status_t);
4743 pStubMsg->Buffer += sizeof(INT);
4744 pStubMsg->MemorySize += sizeof(INT);
4747 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4752 /***********************************************************************
4753 * NdrBaseTypeFree [internal]
4755 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
4756 unsigned char *pMemory,
4757 PFORMAT_STRING pFormat)
4759 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4764 /***********************************************************************
4765 * NdrClientContextMarshall [RPCRT4.@]
4767 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4768 NDR_CCONTEXT ContextHandle,
4771 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
4773 ALIGN_POINTER(pStubMsg->Buffer, 4);
4775 /* FIXME: what does fCheck do? */
4776 NDRCContextMarshall(ContextHandle,
4779 pStubMsg->Buffer += cbNDRContext;
4782 /***********************************************************************
4783 * NdrClientContextUnmarshall [RPCRT4.@]
4785 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4786 NDR_CCONTEXT * pContextHandle,
4787 RPC_BINDING_HANDLE BindHandle)
4789 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
4791 ALIGN_POINTER(pStubMsg->Buffer, 4);
4793 NDRCContextUnmarshall(pContextHandle,
4796 pStubMsg->RpcMsg->DataRepresentation);
4798 pStubMsg->Buffer += cbNDRContext;
4801 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4802 NDR_SCONTEXT ContextHandle,
4803 NDR_RUNDOWN RundownRoutine )
4805 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
4808 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
4810 FIXME("(%p): stub\n", pStubMsg);
4814 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
4815 unsigned char* pMemory,
4816 PFORMAT_STRING pFormat)
4818 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
4821 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
4822 PFORMAT_STRING pFormat)
4824 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
4828 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4829 NDR_SCONTEXT ContextHandle,
4830 NDR_RUNDOWN RundownRoutine,
4831 PFORMAT_STRING pFormat)
4833 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
4836 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4837 PFORMAT_STRING pFormat)
4839 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
4843 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
4845 typedef struct ndr_context_handle
4849 } ndr_context_handle;
4851 struct context_handle_entry
4855 RPC_BINDING_HANDLE handle;
4856 ndr_context_handle wire_data;
4859 static struct list context_handle_list = LIST_INIT(context_handle_list);
4861 static CRITICAL_SECTION ndr_context_cs;
4862 static CRITICAL_SECTION_DEBUG ndr_context_debug =
4864 0, 0, &ndr_context_cs,
4865 { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
4866 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
4868 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
4870 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
4872 struct context_handle_entry *che = (struct context_handle_entry*) CContext;
4874 if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
4879 static struct context_handle_entry *context_entry_from_guid(LPGUID uuid)
4881 struct context_handle_entry *che;
4882 LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
4883 if (IsEqualGUID(&che->wire_data.uuid, uuid))
4888 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
4890 struct context_handle_entry *che;
4891 RPC_BINDING_HANDLE handle = NULL;
4893 TRACE("%p\n", CContext);
4895 EnterCriticalSection(&ndr_context_cs);
4896 che = get_context_entry(CContext);
4898 handle = che->handle;
4899 LeaveCriticalSection(&ndr_context_cs);
4902 RpcRaiseException(ERROR_INVALID_HANDLE);
4906 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
4908 struct context_handle_entry *che;
4910 TRACE("%p %p\n", CContext, pBuff);
4914 EnterCriticalSection(&ndr_context_cs);
4915 che = get_context_entry(CContext);
4916 memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
4917 LeaveCriticalSection(&ndr_context_cs);
4921 ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
4922 wire_data->attributes = 0;
4923 wire_data->uuid = GUID_NULL;
4927 static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
4928 RPC_BINDING_HANDLE hBinding,
4929 ndr_context_handle *chi)
4931 struct context_handle_entry *che = NULL;
4933 /* a null UUID means we should free the context handle */
4934 if (IsEqualGUID(&chi->uuid, &GUID_NULL))
4938 che = get_context_entry(*CContext);
4940 return ERROR_INVALID_HANDLE;
4941 list_remove(&che->entry);
4942 RpcBindingFree(&che->handle);
4943 HeapFree(GetProcessHeap(), 0, che);
4947 /* if there's no existing entry matching the GUID, allocate one */
4948 else if (!(che = context_entry_from_guid(&chi->uuid)))
4950 che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
4952 return ERROR_NOT_ENOUGH_MEMORY;
4953 che->magic = NDR_CONTEXT_HANDLE_MAGIC;
4954 RpcBindingCopy(hBinding, &che->handle);
4955 list_add_tail(&context_handle_list, &che->entry);
4956 memcpy(&che->wire_data, chi, sizeof *chi);
4961 return ERROR_SUCCESS;
4964 /***********************************************************************
4965 * NDRCContextUnmarshall [RPCRT4.@]
4967 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
4968 RPC_BINDING_HANDLE hBinding,
4969 void *pBuff, ULONG DataRepresentation)
4973 TRACE("*%p=(%p) %p %p %08x\n",
4974 CContext, *CContext, hBinding, pBuff, DataRepresentation);
4976 EnterCriticalSection(&ndr_context_cs);
4977 r = ndr_update_context_handle(CContext, hBinding, pBuff);
4978 LeaveCriticalSection(&ndr_context_cs);
4980 RpcRaiseException(r);
4983 /***********************************************************************
4984 * NDRSContextMarshall [RPCRT4.@]
4986 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
4988 NDR_RUNDOWN userRunDownIn)
4990 FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn);
4993 /***********************************************************************
4994 * NDRSContextMarshallEx [RPCRT4.@]
4996 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
4997 NDR_SCONTEXT CContext,
4999 NDR_RUNDOWN userRunDownIn)
5001 FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn);
5004 /***********************************************************************
5005 * NDRSContextMarshall2 [RPCRT4.@]
5007 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
5008 NDR_SCONTEXT CContext,
5010 NDR_RUNDOWN userRunDownIn,
5011 void *CtxGuard, ULONG Flags)
5013 FIXME("(%p %p %p %p %p %u): stub\n",
5014 hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags);
5017 /***********************************************************************
5018 * NDRSContextUnmarshall [RPCRT4.@]
5020 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
5021 ULONG DataRepresentation)
5023 FIXME("(%p %08x): stub\n", pBuff, DataRepresentation);
5027 /***********************************************************************
5028 * NDRSContextUnmarshallEx [RPCRT4.@]
5030 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
5032 ULONG DataRepresentation)
5034 FIXME("(%p %p %08x): stub\n", hBinding, pBuff, DataRepresentation);
5038 /***********************************************************************
5039 * NDRSContextUnmarshall2 [RPCRT4.@]
5041 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
5043 ULONG DataRepresentation,
5044 void *CtxGuard, ULONG Flags)
5046 FIXME("(%p %p %08x %p %u): stub\n",
5047 hBinding, pBuff, DataRepresentation, CtxGuard, Flags);