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 static inline 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 )
1527 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1530 /***********************************************************************
1531 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1533 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1534 unsigned char FormatChar )
1536 NdrBaseTypeUnmarshall(pStubMsg, &pMemory, &FormatChar, 0);
1539 /***********************************************************************
1540 * NdrSimpleStructMarshall [RPCRT4.@]
1542 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1543 unsigned char *pMemory,
1544 PFORMAT_STRING pFormat)
1546 unsigned size = *(const WORD*)(pFormat+2);
1547 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1549 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1551 memcpy(pStubMsg->Buffer, pMemory, size);
1552 pStubMsg->BufferMark = pStubMsg->Buffer;
1553 pStubMsg->Buffer += size;
1555 if (pFormat[0] != RPC_FC_STRUCT)
1556 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1558 STD_OVERFLOW_CHECK(pStubMsg);
1563 /***********************************************************************
1564 * NdrSimpleStructUnmarshall [RPCRT4.@]
1566 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1567 unsigned char **ppMemory,
1568 PFORMAT_STRING pFormat,
1569 unsigned char fMustAlloc)
1571 unsigned size = *(const WORD*)(pFormat+2);
1572 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1574 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1577 *ppMemory = NdrAllocate(pStubMsg, size);
1578 memcpy(*ppMemory, pStubMsg->Buffer, size);
1580 if (!pStubMsg->IsClient && !*ppMemory)
1581 /* for servers, we just point straight into the RPC buffer */
1582 *ppMemory = pStubMsg->Buffer;
1584 /* for clients, memory should be provided by caller */
1585 memcpy(*ppMemory, pStubMsg->Buffer, size);
1588 pStubMsg->BufferMark = pStubMsg->Buffer;
1589 pStubMsg->Buffer += size;
1591 if (pFormat[0] != RPC_FC_STRUCT)
1592 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat+4, fMustAlloc);
1597 /***********************************************************************
1598 * NdrSimpleStructBufferSize [RPCRT4.@]
1600 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1601 unsigned char *pMemory,
1602 PFORMAT_STRING pFormat)
1604 unsigned size = *(const WORD*)(pFormat+2);
1605 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1607 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1609 pStubMsg->BufferLength += size;
1610 if (pFormat[0] != RPC_FC_STRUCT)
1611 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1614 /***********************************************************************
1615 * NdrSimpleStructMemorySize [RPCRT4.@]
1617 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1618 PFORMAT_STRING pFormat)
1620 unsigned short size = *(const WORD *)(pFormat+2);
1622 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1624 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1625 pStubMsg->MemorySize += size;
1626 pStubMsg->Buffer += size;
1628 if (pFormat[0] != RPC_FC_STRUCT)
1629 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1633 /***********************************************************************
1634 * NdrSimpleStructFree [RPCRT4.@]
1636 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1637 unsigned char *pMemory,
1638 PFORMAT_STRING pFormat)
1640 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1641 if (pFormat[0] != RPC_FC_STRUCT)
1642 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1646 static unsigned long EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg,
1647 PFORMAT_STRING pFormat)
1651 case RPC_FC_PSTRUCT:
1652 case RPC_FC_CSTRUCT:
1653 case RPC_FC_BOGUS_STRUCT:
1654 case RPC_FC_SMFARRAY:
1655 case RPC_FC_SMVARRAY:
1656 return *(const WORD*)&pFormat[2];
1657 case RPC_FC_USER_MARSHAL:
1658 return *(const WORD*)&pFormat[4];
1659 case RPC_FC_NON_ENCAPSULATED_UNION:
1661 if (pStubMsg->fHasNewCorrDesc)
1666 pFormat += *(const SHORT*)pFormat;
1667 return *(const SHORT*)pFormat;
1669 return sizeof(void *);
1671 FIXME("unhandled embedded type %02x\n", *pFormat);
1677 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1678 PFORMAT_STRING pFormat)
1680 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1684 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1688 return m(pStubMsg, pFormat);
1692 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1693 unsigned char *pMemory,
1694 PFORMAT_STRING pFormat,
1695 PFORMAT_STRING pPointer)
1697 PFORMAT_STRING desc;
1701 while (*pFormat != RPC_FC_END) {
1707 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
1708 memcpy(pStubMsg->Buffer, pMemory, 1);
1709 pStubMsg->Buffer += 1;
1715 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1716 memcpy(pStubMsg->Buffer, pMemory, 2);
1717 pStubMsg->Buffer += 2;
1723 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
1724 memcpy(pStubMsg->Buffer, pMemory, 4);
1725 pStubMsg->Buffer += 4;
1729 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1730 memcpy(pStubMsg->Buffer, pMemory, 8);
1731 pStubMsg->Buffer += 8;
1734 case RPC_FC_POINTER:
1735 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1736 NdrPointerMarshall(pStubMsg, *(unsigned char**)pMemory, pPointer);
1740 case RPC_FC_ALIGNM4:
1741 ALIGN_POINTER(pMemory, 4);
1743 case RPC_FC_ALIGNM8:
1744 ALIGN_POINTER(pMemory, 8);
1746 case RPC_FC_STRUCTPAD1:
1747 case RPC_FC_STRUCTPAD2:
1748 case RPC_FC_STRUCTPAD3:
1749 case RPC_FC_STRUCTPAD4:
1750 case RPC_FC_STRUCTPAD5:
1751 case RPC_FC_STRUCTPAD6:
1752 case RPC_FC_STRUCTPAD7:
1753 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1755 case RPC_FC_EMBEDDED_COMPLEX:
1756 pMemory += pFormat[1];
1758 desc = pFormat + *(const SHORT*)pFormat;
1759 size = EmbeddedComplexSize(pStubMsg, desc);
1760 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1761 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1762 if (m) m(pStubMsg, pMemory, desc);
1763 else FIXME("no marshaller for embedded type %02x\n", *desc);
1770 FIXME("unhandled format 0x%02x\n", *pFormat);
1778 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1779 unsigned char *pMemory,
1780 PFORMAT_STRING pFormat,
1781 PFORMAT_STRING pPointer)
1783 PFORMAT_STRING desc;
1787 while (*pFormat != RPC_FC_END) {
1793 memcpy(pMemory, pStubMsg->Buffer, 1);
1794 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
1795 pStubMsg->Buffer += 1;
1801 memcpy(pMemory, pStubMsg->Buffer, 2);
1802 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1803 pStubMsg->Buffer += 2;
1809 memcpy(pMemory, pStubMsg->Buffer, 4);
1810 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
1811 pStubMsg->Buffer += 4;
1815 memcpy(pMemory, pStubMsg->Buffer, 8);
1816 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1817 pStubMsg->Buffer += 8;
1820 case RPC_FC_POINTER:
1821 TRACE("pointer => %p\n", pMemory);
1822 NdrPointerUnmarshall(pStubMsg, (unsigned char**)pMemory, pPointer, TRUE);
1826 case RPC_FC_ALIGNM4:
1827 ALIGN_POINTER(pMemory, 4);
1829 case RPC_FC_ALIGNM8:
1830 ALIGN_POINTER(pMemory, 8);
1832 case RPC_FC_STRUCTPAD1:
1833 case RPC_FC_STRUCTPAD2:
1834 case RPC_FC_STRUCTPAD3:
1835 case RPC_FC_STRUCTPAD4:
1836 case RPC_FC_STRUCTPAD5:
1837 case RPC_FC_STRUCTPAD6:
1838 case RPC_FC_STRUCTPAD7:
1839 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1841 case RPC_FC_EMBEDDED_COMPLEX:
1842 pMemory += pFormat[1];
1844 desc = pFormat + *(const SHORT*)pFormat;
1845 size = EmbeddedComplexSize(pStubMsg, desc);
1846 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
1847 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1848 memset(pMemory, 0, size); /* just in case */
1849 if (m) m(pStubMsg, &pMemory, desc, FALSE);
1850 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
1857 FIXME("unhandled format %d\n", *pFormat);
1865 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1866 unsigned char *pMemory,
1867 PFORMAT_STRING pFormat,
1868 PFORMAT_STRING pPointer)
1870 PFORMAT_STRING desc;
1874 while (*pFormat != RPC_FC_END) {
1880 pStubMsg->BufferLength += 1;
1886 pStubMsg->BufferLength += 2;
1892 pStubMsg->BufferLength += 4;
1896 pStubMsg->BufferLength += 8;
1899 case RPC_FC_POINTER:
1900 NdrPointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
1904 case RPC_FC_ALIGNM4:
1905 ALIGN_POINTER(pMemory, 4);
1907 case RPC_FC_ALIGNM8:
1908 ALIGN_POINTER(pMemory, 8);
1910 case RPC_FC_STRUCTPAD1:
1911 case RPC_FC_STRUCTPAD2:
1912 case RPC_FC_STRUCTPAD3:
1913 case RPC_FC_STRUCTPAD4:
1914 case RPC_FC_STRUCTPAD5:
1915 case RPC_FC_STRUCTPAD6:
1916 case RPC_FC_STRUCTPAD7:
1917 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1919 case RPC_FC_EMBEDDED_COMPLEX:
1920 pMemory += pFormat[1];
1922 desc = pFormat + *(const SHORT*)pFormat;
1923 size = EmbeddedComplexSize(pStubMsg, desc);
1924 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1925 if (m) m(pStubMsg, pMemory, desc);
1926 else FIXME("no buffersizer for embedded type %02x\n", *desc);
1933 FIXME("unhandled format 0x%02x\n", *pFormat);
1941 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
1942 unsigned char *pMemory,
1943 PFORMAT_STRING pFormat,
1944 PFORMAT_STRING pPointer)
1946 PFORMAT_STRING desc;
1950 while (*pFormat != RPC_FC_END) {
1971 case RPC_FC_POINTER:
1972 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
1976 case RPC_FC_ALIGNM4:
1977 ALIGN_POINTER(pMemory, 4);
1979 case RPC_FC_ALIGNM8:
1980 ALIGN_POINTER(pMemory, 8);
1982 case RPC_FC_STRUCTPAD1:
1983 case RPC_FC_STRUCTPAD2:
1984 case RPC_FC_STRUCTPAD3:
1985 case RPC_FC_STRUCTPAD4:
1986 case RPC_FC_STRUCTPAD5:
1987 case RPC_FC_STRUCTPAD6:
1988 case RPC_FC_STRUCTPAD7:
1989 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1991 case RPC_FC_EMBEDDED_COMPLEX:
1992 pMemory += pFormat[1];
1994 desc = pFormat + *(const SHORT*)pFormat;
1995 size = EmbeddedComplexSize(pStubMsg, desc);
1996 m = NdrFreer[*desc & NDR_TABLE_MASK];
1997 if (m) m(pStubMsg, pMemory, desc);
1998 else FIXME("no freer for embedded type %02x\n", *desc);
2005 FIXME("unhandled format 0x%02x\n", *pFormat);
2013 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2014 PFORMAT_STRING pFormat)
2016 PFORMAT_STRING desc;
2017 unsigned long size = 0;
2019 while (*pFormat != RPC_FC_END) {
2026 pStubMsg->Buffer += 1;
2032 pStubMsg->Buffer += 2;
2038 pStubMsg->Buffer += 4;
2042 pStubMsg->Buffer += 8;
2044 case RPC_FC_POINTER:
2046 pStubMsg->Buffer += 4;
2048 case RPC_FC_ALIGNM4:
2049 ALIGN_LENGTH(size, 4);
2050 ALIGN_POINTER(pStubMsg->Buffer, 4);
2052 case RPC_FC_ALIGNM8:
2053 ALIGN_LENGTH(size, 8);
2054 ALIGN_POINTER(pStubMsg->Buffer, 8);
2056 case RPC_FC_STRUCTPAD1:
2057 case RPC_FC_STRUCTPAD2:
2058 case RPC_FC_STRUCTPAD3:
2059 case RPC_FC_STRUCTPAD4:
2060 case RPC_FC_STRUCTPAD5:
2061 case RPC_FC_STRUCTPAD6:
2062 case RPC_FC_STRUCTPAD7:
2063 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2065 case RPC_FC_EMBEDDED_COMPLEX:
2068 desc = pFormat + *(const SHORT*)pFormat;
2069 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2075 FIXME("unhandled format 0x%02x\n", *pFormat);
2083 /***********************************************************************
2084 * NdrComplexStructMarshall [RPCRT4.@]
2086 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2087 unsigned char *pMemory,
2088 PFORMAT_STRING pFormat)
2090 PFORMAT_STRING conf_array = NULL;
2091 PFORMAT_STRING pointer_desc = NULL;
2092 unsigned char *OldMemory = pStubMsg->Memory;
2094 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2096 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2099 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2101 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2104 pStubMsg->Memory = pMemory;
2106 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2109 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2111 pStubMsg->Memory = OldMemory;
2113 STD_OVERFLOW_CHECK(pStubMsg);
2118 /***********************************************************************
2119 * NdrComplexStructUnmarshall [RPCRT4.@]
2121 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2122 unsigned char **ppMemory,
2123 PFORMAT_STRING pFormat,
2124 unsigned char fMustAlloc)
2126 unsigned size = *(const WORD*)(pFormat+2);
2127 PFORMAT_STRING conf_array = NULL;
2128 PFORMAT_STRING pointer_desc = NULL;
2129 unsigned char *pMemory;
2131 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2133 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2135 if (fMustAlloc || !*ppMemory)
2137 *ppMemory = NdrAllocate(pStubMsg, size);
2138 memset(*ppMemory, 0, size);
2142 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2144 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2147 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2150 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2155 /***********************************************************************
2156 * NdrComplexStructBufferSize [RPCRT4.@]
2158 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2159 unsigned char *pMemory,
2160 PFORMAT_STRING pFormat)
2162 PFORMAT_STRING conf_array = NULL;
2163 PFORMAT_STRING pointer_desc = NULL;
2164 unsigned char *OldMemory = pStubMsg->Memory;
2166 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2168 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2171 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2173 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2176 pStubMsg->Memory = pMemory;
2178 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2181 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2183 pStubMsg->Memory = OldMemory;
2186 /***********************************************************************
2187 * NdrComplexStructMemorySize [RPCRT4.@]
2189 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2190 PFORMAT_STRING pFormat)
2192 unsigned size = *(const WORD*)(pFormat+2);
2193 PFORMAT_STRING conf_array = NULL;
2194 PFORMAT_STRING pointer_desc = NULL;
2196 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2198 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2201 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2203 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2206 ComplexStructMemorySize(pStubMsg, pFormat);
2209 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2214 /***********************************************************************
2215 * NdrComplexStructFree [RPCRT4.@]
2217 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2218 unsigned char *pMemory,
2219 PFORMAT_STRING pFormat)
2221 PFORMAT_STRING conf_array = NULL;
2222 PFORMAT_STRING pointer_desc = NULL;
2223 unsigned char *OldMemory = pStubMsg->Memory;
2225 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2228 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2230 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2233 pStubMsg->Memory = pMemory;
2235 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2238 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2240 pStubMsg->Memory = OldMemory;
2243 /***********************************************************************
2244 * NdrConformantArrayMarshall [RPCRT4.@]
2246 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2247 unsigned char *pMemory,
2248 PFORMAT_STRING pFormat)
2250 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2251 unsigned char alignment = pFormat[1] + 1;
2253 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2254 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2256 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2258 WriteConformance(pStubMsg);
2260 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2262 size = safe_multiply(esize, pStubMsg->MaxCount);
2263 memcpy(pStubMsg->Buffer, pMemory, size);
2264 pStubMsg->BufferMark = pStubMsg->Buffer;
2265 pStubMsg->Buffer += size;
2267 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2269 STD_OVERFLOW_CHECK(pStubMsg);
2274 /***********************************************************************
2275 * NdrConformantArrayUnmarshall [RPCRT4.@]
2277 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2278 unsigned char **ppMemory,
2279 PFORMAT_STRING pFormat,
2280 unsigned char fMustAlloc)
2282 DWORD size, esize = *(const WORD*)(pFormat+2);
2283 unsigned char alignment = pFormat[1] + 1;
2285 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2286 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2288 pFormat = ReadConformance(pStubMsg, pFormat+4);
2290 size = safe_multiply(esize, pStubMsg->MaxCount);
2292 if (fMustAlloc || !*ppMemory)
2293 *ppMemory = NdrAllocate(pStubMsg, size);
2295 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2297 memcpy(*ppMemory, pStubMsg->Buffer, size);
2299 pStubMsg->BufferMark = pStubMsg->Buffer;
2300 pStubMsg->Buffer += size;
2302 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2307 /***********************************************************************
2308 * NdrConformantArrayBufferSize [RPCRT4.@]
2310 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2311 unsigned char *pMemory,
2312 PFORMAT_STRING pFormat)
2314 DWORD size, esize = *(const WORD*)(pFormat+2);
2315 unsigned char alignment = pFormat[1] + 1;
2317 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2318 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2320 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2322 SizeConformance(pStubMsg);
2324 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2326 size = safe_multiply(esize, pStubMsg->MaxCount);
2327 /* conformance value plus array */
2328 pStubMsg->BufferLength += size;
2330 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2333 /***********************************************************************
2334 * NdrConformantArrayMemorySize [RPCRT4.@]
2336 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2337 PFORMAT_STRING pFormat)
2339 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2340 unsigned char alignment = pFormat[1] + 1;
2342 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2343 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2345 pFormat = ReadConformance(pStubMsg, pFormat+4);
2346 size = safe_multiply(esize, pStubMsg->MaxCount);
2347 pStubMsg->MemorySize += size;
2349 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2350 pStubMsg->BufferMark = pStubMsg->Buffer;
2351 pStubMsg->Buffer += size;
2353 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2355 return pStubMsg->MemorySize;
2358 /***********************************************************************
2359 * NdrConformantArrayFree [RPCRT4.@]
2361 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2362 unsigned char *pMemory,
2363 PFORMAT_STRING pFormat)
2365 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2366 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2368 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2370 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2374 /***********************************************************************
2375 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2377 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2378 unsigned char* pMemory,
2379 PFORMAT_STRING pFormat )
2382 unsigned char alignment = pFormat[1] + 1;
2383 DWORD esize = *(const WORD*)(pFormat+2);
2385 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2387 if (pFormat[0] != RPC_FC_CVARRAY)
2389 ERR("invalid format type %x\n", pFormat[0]);
2390 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2394 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2395 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2397 WriteConformance(pStubMsg);
2398 WriteVariance(pStubMsg);
2400 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2402 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2404 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
2405 pStubMsg->BufferMark = pStubMsg->Buffer;
2406 pStubMsg->Buffer += bufsize;
2408 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2410 STD_OVERFLOW_CHECK(pStubMsg);
2416 /***********************************************************************
2417 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2419 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2420 unsigned char** ppMemory,
2421 PFORMAT_STRING pFormat,
2422 unsigned char fMustAlloc )
2424 ULONG bufsize, memsize;
2425 unsigned char alignment = pFormat[1] + 1;
2426 DWORD esize = *(const WORD*)(pFormat+2);
2428 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2430 if (pFormat[0] != RPC_FC_CVARRAY)
2432 ERR("invalid format type %x\n", pFormat[0]);
2433 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2437 pFormat = ReadConformance(pStubMsg, pFormat+4);
2438 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2440 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2442 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2443 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2445 if (!*ppMemory || fMustAlloc)
2446 *ppMemory = NdrAllocate(pStubMsg, memsize);
2447 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
2448 pStubMsg->Buffer += bufsize;
2450 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2456 /***********************************************************************
2457 * NdrConformantVaryingArrayFree [RPCRT4.@]
2459 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2460 unsigned char* pMemory,
2461 PFORMAT_STRING pFormat )
2463 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2465 if (pFormat[0] != RPC_FC_CVARRAY)
2467 ERR("invalid format type %x\n", pFormat[0]);
2468 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2472 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2473 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2475 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2479 /***********************************************************************
2480 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2482 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2483 unsigned char* pMemory, PFORMAT_STRING pFormat )
2485 unsigned char alignment = pFormat[1] + 1;
2486 DWORD esize = *(const WORD*)(pFormat+2);
2488 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2490 if (pFormat[0] != RPC_FC_CVARRAY)
2492 ERR("invalid format type %x\n", pFormat[0]);
2493 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2498 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2499 /* compute length */
2500 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2502 SizeConformance(pStubMsg);
2503 SizeVariance(pStubMsg);
2505 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2507 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
2509 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2513 /***********************************************************************
2514 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2516 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2517 PFORMAT_STRING pFormat )
2524 /***********************************************************************
2525 * NdrComplexArrayMarshall [RPCRT4.@]
2527 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2528 unsigned char *pMemory,
2529 PFORMAT_STRING pFormat)
2531 ULONG i, count, def;
2532 BOOL variance_present;
2533 unsigned char alignment;
2535 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2537 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2539 ERR("invalid format type %x\n", pFormat[0]);
2540 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2544 alignment = pFormat[1] + 1;
2546 def = *(const WORD*)&pFormat[2];
2549 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2550 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2552 variance_present = IsConformanceOrVariancePresent(pFormat);
2553 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2554 TRACE("variance = %d\n", pStubMsg->ActualCount);
2556 WriteConformance(pStubMsg);
2557 if (variance_present)
2558 WriteVariance(pStubMsg);
2560 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2562 count = pStubMsg->ActualCount;
2563 for (i = 0; i < count; i++)
2564 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2566 STD_OVERFLOW_CHECK(pStubMsg);
2571 /***********************************************************************
2572 * NdrComplexArrayUnmarshall [RPCRT4.@]
2574 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2575 unsigned char **ppMemory,
2576 PFORMAT_STRING pFormat,
2577 unsigned char fMustAlloc)
2579 ULONG i, count, esize, memsize;
2580 unsigned char alignment;
2581 unsigned char *pMemory;
2582 unsigned char *Buffer;
2584 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2586 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2588 ERR("invalid format type %x\n", pFormat[0]);
2589 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2593 alignment = pFormat[1] + 1;
2597 pFormat = ReadConformance(pStubMsg, pFormat);
2598 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2600 Buffer = pStubMsg->Buffer;
2601 pStubMsg->MemorySize = 0;
2602 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2603 pStubMsg->Buffer = Buffer;
2605 /* do multiply here instead of inside if block to verify MaxCount */
2606 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2607 if (fMustAlloc || !*ppMemory)
2609 *ppMemory = NdrAllocate(pStubMsg, memsize);
2610 memset(*ppMemory, 0, memsize);
2613 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2615 pMemory = *ppMemory;
2616 count = pStubMsg->ActualCount;
2617 for (i = 0; i < count; i++)
2618 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
2623 /***********************************************************************
2624 * NdrComplexArrayBufferSize [RPCRT4.@]
2626 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2627 unsigned char *pMemory,
2628 PFORMAT_STRING pFormat)
2630 ULONG i, count, def;
2631 unsigned char alignment;
2632 BOOL variance_present;
2634 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2636 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2638 ERR("invalid format type %x\n", pFormat[0]);
2639 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2643 alignment = pFormat[1] + 1;
2645 def = *(const WORD*)&pFormat[2];
2648 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2649 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2650 SizeConformance(pStubMsg);
2652 variance_present = IsConformanceOrVariancePresent(pFormat);
2653 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2654 TRACE("variance = %d\n", pStubMsg->ActualCount);
2656 if (variance_present)
2657 SizeVariance(pStubMsg);
2659 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2661 count = pStubMsg->ActualCount;
2662 for (i = 0; i < count; i++)
2663 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
2666 /***********************************************************************
2667 * NdrComplexArrayMemorySize [RPCRT4.@]
2669 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2670 PFORMAT_STRING pFormat)
2672 ULONG i, count, esize, SavedMemorySize, MemorySize;
2673 unsigned char alignment;
2674 unsigned char *Buffer;
2676 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2678 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2680 ERR("invalid format type %x\n", pFormat[0]);
2681 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2685 alignment = pFormat[1] + 1;
2689 pFormat = ReadConformance(pStubMsg, pFormat);
2690 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2692 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2694 SavedMemorySize = pStubMsg->MemorySize;
2696 Buffer = pStubMsg->Buffer;
2697 pStubMsg->MemorySize = 0;
2698 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2699 pStubMsg->Buffer = Buffer;
2701 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
2703 count = pStubMsg->ActualCount;
2704 for (i = 0; i < count; i++)
2705 ComplexStructMemorySize(pStubMsg, pFormat);
2707 pStubMsg->MemorySize = SavedMemorySize;
2709 pStubMsg->MemorySize += MemorySize;
2713 /***********************************************************************
2714 * NdrComplexArrayFree [RPCRT4.@]
2716 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2717 unsigned char *pMemory,
2718 PFORMAT_STRING pFormat)
2720 ULONG i, count, def;
2722 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2724 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2726 ERR("invalid format type %x\n", pFormat[0]);
2727 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2731 def = *(const WORD*)&pFormat[2];
2734 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2735 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2737 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2738 TRACE("variance = %d\n", pStubMsg->ActualCount);
2740 count = pStubMsg->ActualCount;
2741 for (i = 0; i < count; i++)
2742 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2745 static ULONG UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
2747 return MAKELONG(pStubMsg->dwDestContext,
2748 pStubMsg->RpcMsg->DataRepresentation);
2751 #define USER_MARSHAL_PTR_PREFIX \
2752 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
2753 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
2755 /***********************************************************************
2756 * NdrUserMarshalMarshall [RPCRT4.@]
2758 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2759 unsigned char *pMemory,
2760 PFORMAT_STRING pFormat)
2762 unsigned flags = pFormat[1];
2763 unsigned index = *(const WORD*)&pFormat[2];
2764 ULONG uflag = UserMarshalFlags(pStubMsg);
2765 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2766 TRACE("index=%d\n", index);
2768 if (flags & USER_MARSHAL_POINTER)
2770 ALIGN_POINTER(pStubMsg->Buffer, 4);
2771 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
2772 pStubMsg->Buffer += 4;
2773 ALIGN_POINTER(pStubMsg->Buffer, 8);
2776 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2779 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
2780 &uflag, pStubMsg->Buffer, pMemory);
2782 STD_OVERFLOW_CHECK(pStubMsg);
2787 /***********************************************************************
2788 * NdrUserMarshalUnmarshall [RPCRT4.@]
2790 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2791 unsigned char **ppMemory,
2792 PFORMAT_STRING pFormat,
2793 unsigned char fMustAlloc)
2795 unsigned flags = pFormat[1];
2796 unsigned index = *(const WORD*)&pFormat[2];
2797 DWORD memsize = *(const WORD*)&pFormat[4];
2798 ULONG uflag = UserMarshalFlags(pStubMsg);
2799 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2800 TRACE("index=%d\n", index);
2802 if (flags & USER_MARSHAL_POINTER)
2804 ALIGN_POINTER(pStubMsg->Buffer, 4);
2805 /* skip pointer prefix */
2806 pStubMsg->Buffer += 4;
2807 ALIGN_POINTER(pStubMsg->Buffer, 8);
2810 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2812 if (fMustAlloc || !*ppMemory)
2813 *ppMemory = NdrAllocate(pStubMsg, memsize);
2816 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
2817 &uflag, pStubMsg->Buffer, *ppMemory);
2822 /***********************************************************************
2823 * NdrUserMarshalBufferSize [RPCRT4.@]
2825 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2826 unsigned char *pMemory,
2827 PFORMAT_STRING pFormat)
2829 unsigned flags = pFormat[1];
2830 unsigned index = *(const WORD*)&pFormat[2];
2831 DWORD bufsize = *(const WORD*)&pFormat[6];
2832 ULONG uflag = UserMarshalFlags(pStubMsg);
2833 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2834 TRACE("index=%d\n", index);
2836 if (flags & USER_MARSHAL_POINTER)
2838 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2839 /* skip pointer prefix */
2840 pStubMsg->BufferLength += 4;
2841 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
2844 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
2847 TRACE("size=%d\n", bufsize);
2848 pStubMsg->BufferLength += bufsize;
2852 pStubMsg->BufferLength =
2853 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
2854 &uflag, pStubMsg->BufferLength, pMemory);
2857 /***********************************************************************
2858 * NdrUserMarshalMemorySize [RPCRT4.@]
2860 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2861 PFORMAT_STRING pFormat)
2863 unsigned flags = pFormat[1];
2864 unsigned index = *(const WORD*)&pFormat[2];
2865 DWORD memsize = *(const WORD*)&pFormat[4];
2866 DWORD bufsize = *(const WORD*)&pFormat[6];
2868 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2869 TRACE("index=%d\n", index);
2871 pStubMsg->MemorySize += memsize;
2873 if (flags & USER_MARSHAL_POINTER)
2875 ALIGN_POINTER(pStubMsg->Buffer, 4);
2876 /* skip pointer prefix */
2877 pStubMsg->Buffer += 4;
2878 ALIGN_POINTER(pStubMsg->Buffer, 8);
2881 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2883 pStubMsg->Buffer += bufsize;
2885 return pStubMsg->MemorySize;
2888 /***********************************************************************
2889 * NdrUserMarshalFree [RPCRT4.@]
2891 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
2892 unsigned char *pMemory,
2893 PFORMAT_STRING pFormat)
2895 /* unsigned flags = pFormat[1]; */
2896 unsigned index = *(const WORD*)&pFormat[2];
2897 ULONG uflag = UserMarshalFlags(pStubMsg);
2898 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2899 TRACE("index=%d\n", index);
2901 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
2905 /***********************************************************************
2906 * NdrClearOutParameters [RPCRT4.@]
2908 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
2909 PFORMAT_STRING pFormat,
2912 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
2915 /***********************************************************************
2916 * NdrConvert [RPCRT4.@]
2918 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
2920 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
2921 /* FIXME: since this stub doesn't do any converting, the proper behavior
2922 is to raise an exception */
2925 /***********************************************************************
2926 * NdrConvert2 [RPCRT4.@]
2928 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
2930 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
2931 pStubMsg, pFormat, NumberParams);
2932 /* FIXME: since this stub doesn't do any converting, the proper behavior
2933 is to raise an exception */
2936 #include "pshpack1.h"
2937 typedef struct _NDR_CSTRUCT_FORMAT
2940 unsigned char alignment;
2941 unsigned short memory_size;
2942 short offset_to_array_description;
2943 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
2944 #include "poppack.h"
2946 /***********************************************************************
2947 * NdrConformantStructMarshall [RPCRT4.@]
2949 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2950 unsigned char *pMemory,
2951 PFORMAT_STRING pFormat)
2953 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
2954 PFORMAT_STRING pCArrayFormat;
2955 ULONG esize, bufsize;
2957 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2959 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2960 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2962 ERR("invalid format type %x\n", pCStructFormat->type);
2963 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2967 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
2968 pCStructFormat->offset_to_array_description;
2969 if (*pCArrayFormat != RPC_FC_CARRAY)
2971 ERR("invalid array format type %x\n", pCStructFormat->type);
2972 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2975 esize = *(const WORD*)(pCArrayFormat+2);
2977 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
2978 pCArrayFormat + 4, 0);
2980 WriteConformance(pStubMsg);
2982 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
2984 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2986 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
2987 /* copy constant sized part of struct */
2988 pStubMsg->BufferMark = pStubMsg->Buffer;
2989 memcpy(pStubMsg->Buffer, pMemory, pCStructFormat->memory_size + bufsize);
2990 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
2992 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2993 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2995 STD_OVERFLOW_CHECK(pStubMsg);
3000 /***********************************************************************
3001 * NdrConformantStructUnmarshall [RPCRT4.@]
3003 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3004 unsigned char **ppMemory,
3005 PFORMAT_STRING pFormat,
3006 unsigned char fMustAlloc)
3008 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3009 PFORMAT_STRING pCArrayFormat;
3010 ULONG esize, bufsize;
3012 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3014 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3015 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3017 ERR("invalid format type %x\n", pCStructFormat->type);
3018 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3021 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3022 pCStructFormat->offset_to_array_description;
3023 if (*pCArrayFormat != RPC_FC_CARRAY)
3025 ERR("invalid array format type %x\n", pCStructFormat->type);
3026 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3029 esize = *(const WORD*)(pCArrayFormat+2);
3031 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3033 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3035 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3037 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3038 /* work out how much memory to allocate if we need to do so */
3039 if (!*ppMemory || fMustAlloc)
3041 SIZE_T size = pCStructFormat->memory_size + bufsize;
3042 *ppMemory = NdrAllocate(pStubMsg, size);
3045 /* now copy the data */
3046 pStubMsg->BufferMark = pStubMsg->Buffer;
3047 memcpy(*ppMemory, pStubMsg->Buffer, pCStructFormat->memory_size + bufsize);
3048 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
3050 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3051 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3056 /***********************************************************************
3057 * NdrConformantStructBufferSize [RPCRT4.@]
3059 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3060 unsigned char *pMemory,
3061 PFORMAT_STRING pFormat)
3063 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3064 PFORMAT_STRING pCArrayFormat;
3067 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3069 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3070 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3072 ERR("invalid format type %x\n", pCStructFormat->type);
3073 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3076 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3077 pCStructFormat->offset_to_array_description;
3078 if (*pCArrayFormat != RPC_FC_CARRAY)
3080 ERR("invalid array format type %x\n", pCStructFormat->type);
3081 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3084 esize = *(const WORD*)(pCArrayFormat+2);
3086 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
3087 SizeConformance(pStubMsg);
3089 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
3091 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3093 pStubMsg->BufferLength += pCStructFormat->memory_size +
3094 safe_multiply(pStubMsg->MaxCount, esize);
3096 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3097 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3100 /***********************************************************************
3101 * NdrConformantStructMemorySize [RPCRT4.@]
3103 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3104 PFORMAT_STRING pFormat)
3110 /***********************************************************************
3111 * NdrConformantStructFree [RPCRT4.@]
3113 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3114 unsigned char *pMemory,
3115 PFORMAT_STRING pFormat)
3120 /***********************************************************************
3121 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3123 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3124 unsigned char *pMemory,
3125 PFORMAT_STRING pFormat)
3127 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3128 PFORMAT_STRING pCVArrayFormat;
3129 ULONG esize, bufsize;
3131 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3133 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3134 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3136 ERR("invalid format type %x\n", pCVStructFormat->type);
3137 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3141 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3142 pCVStructFormat->offset_to_array_description;
3143 switch (*pCVArrayFormat)
3145 case RPC_FC_CVARRAY:
3146 esize = *(const WORD*)(pCVArrayFormat+2);
3148 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3149 pCVArrayFormat + 4, 0);
3150 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3153 case RPC_FC_C_CSTRING:
3154 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3155 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3156 esize = sizeof(char);
3157 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3158 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3159 pCVArrayFormat + 2, 0);
3161 pStubMsg->MaxCount = pStubMsg->ActualCount;
3163 case RPC_FC_C_WSTRING:
3164 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3165 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3166 esize = sizeof(WCHAR);
3167 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3168 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3169 pCVArrayFormat + 2, 0);
3171 pStubMsg->MaxCount = pStubMsg->ActualCount;
3174 ERR("invalid array format type %x\n", *pCVArrayFormat);
3175 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3179 WriteConformance(pStubMsg);
3181 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3183 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3185 /* write constant sized part */
3186 pStubMsg->BufferMark = pStubMsg->Buffer;
3187 memcpy(pStubMsg->Buffer, pMemory, pCVStructFormat->memory_size);
3188 pStubMsg->Buffer += pCVStructFormat->memory_size;
3190 WriteVariance(pStubMsg);
3192 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3194 /* write array part */
3195 memcpy(pStubMsg->Buffer, pMemory + pCVStructFormat->memory_size, bufsize);
3196 pStubMsg->Buffer += bufsize;
3198 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3200 STD_OVERFLOW_CHECK(pStubMsg);
3205 /***********************************************************************
3206 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3208 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3209 unsigned char **ppMemory,
3210 PFORMAT_STRING pFormat,
3211 unsigned char fMustAlloc)
3213 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3214 PFORMAT_STRING pCVArrayFormat;
3215 ULONG esize, bufsize;
3216 unsigned char cvarray_type;
3218 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3220 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3221 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3223 ERR("invalid format type %x\n", pCVStructFormat->type);
3224 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3228 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3229 pCVStructFormat->offset_to_array_description;
3230 cvarray_type = *pCVArrayFormat;
3231 switch (cvarray_type)
3233 case RPC_FC_CVARRAY:
3234 esize = *(const WORD*)(pCVArrayFormat+2);
3235 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3237 case RPC_FC_C_CSTRING:
3238 esize = sizeof(char);
3239 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3240 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3242 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3244 case RPC_FC_C_WSTRING:
3245 esize = sizeof(WCHAR);
3246 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3247 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3249 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3252 ERR("invalid array format type %x\n", *pCVArrayFormat);
3253 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3257 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3259 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3261 /* work out how much memory to allocate if we need to do so */
3262 if (!*ppMemory || fMustAlloc)
3264 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3265 *ppMemory = NdrAllocate(pStubMsg, size);
3268 /* copy the constant data */
3269 pStubMsg->BufferMark = pStubMsg->Buffer;
3270 memcpy(*ppMemory, pStubMsg->Buffer, pCVStructFormat->memory_size);
3271 pStubMsg->Buffer += pCVStructFormat->memory_size;
3273 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3275 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3277 if ((cvarray_type == RPC_FC_C_CSTRING) ||
3278 (cvarray_type == RPC_FC_C_WSTRING))
3281 /* strings must always have null terminating bytes */
3282 if (bufsize < esize)
3284 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
3285 RpcRaiseException(RPC_S_INVALID_BOUND);
3288 for (i = bufsize - esize; i < bufsize; i++)
3289 if (pStubMsg->Buffer[i] != 0)
3291 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3292 i, pStubMsg->Buffer[i]);
3293 RpcRaiseException(RPC_S_INVALID_BOUND);
3298 /* copy the array data */
3299 memcpy(*ppMemory + pCVStructFormat->memory_size, pStubMsg->Buffer,
3301 pStubMsg->Buffer += bufsize;
3303 if (cvarray_type == RPC_FC_C_CSTRING)
3304 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3305 else if (cvarray_type == RPC_FC_C_WSTRING)
3306 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3308 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3313 /***********************************************************************
3314 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3316 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3317 unsigned char *pMemory,
3318 PFORMAT_STRING pFormat)
3320 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3321 PFORMAT_STRING pCVArrayFormat;
3324 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3326 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3327 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3329 ERR("invalid format type %x\n", pCVStructFormat->type);
3330 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3334 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3335 pCVStructFormat->offset_to_array_description;
3336 switch (*pCVArrayFormat)
3338 case RPC_FC_CVARRAY:
3339 esize = *(const WORD*)(pCVArrayFormat+2);
3341 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3342 pCVArrayFormat + 4, 0);
3343 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3346 case RPC_FC_C_CSTRING:
3347 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3348 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3349 esize = sizeof(char);
3350 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3351 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3352 pCVArrayFormat + 2, 0);
3354 pStubMsg->MaxCount = pStubMsg->ActualCount;
3356 case RPC_FC_C_WSTRING:
3357 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3358 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3359 esize = sizeof(WCHAR);
3360 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3361 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3362 pCVArrayFormat + 2, 0);
3364 pStubMsg->MaxCount = pStubMsg->ActualCount;
3367 ERR("invalid array format type %x\n", *pCVArrayFormat);
3368 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3372 SizeConformance(pStubMsg);
3374 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
3376 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3378 pStubMsg->BufferLength += pCVStructFormat->memory_size;
3379 SizeVariance(pStubMsg);
3380 pStubMsg->BufferLength += safe_multiply(pStubMsg->MaxCount, esize);
3382 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3385 /***********************************************************************
3386 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3388 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3389 PFORMAT_STRING pFormat)
3391 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3392 PFORMAT_STRING pCVArrayFormat;
3394 unsigned char cvarray_type;
3396 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3398 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3399 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3401 ERR("invalid format type %x\n", pCVStructFormat->type);
3402 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3406 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3407 pCVStructFormat->offset_to_array_description;
3408 cvarray_type = *pCVArrayFormat;
3409 switch (cvarray_type)
3411 case RPC_FC_CVARRAY:
3412 esize = *(const WORD*)(pCVArrayFormat+2);
3413 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3415 case RPC_FC_C_CSTRING:
3416 esize = sizeof(char);
3417 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3418 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3420 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3422 case RPC_FC_C_WSTRING:
3423 esize = sizeof(WCHAR);
3424 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3425 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3427 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3430 ERR("invalid array format type %x\n", *pCVArrayFormat);
3431 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3435 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3437 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3439 pStubMsg->Buffer += pCVStructFormat->memory_size;
3440 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3441 pStubMsg->Buffer += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->ActualCount);
3443 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3445 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3447 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3450 /***********************************************************************
3451 * NdrConformantVaryingStructFree [RPCRT4.@]
3453 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3454 unsigned char *pMemory,
3455 PFORMAT_STRING pFormat)
3457 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3458 PFORMAT_STRING pCVArrayFormat;
3461 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3463 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3464 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3466 ERR("invalid format type %x\n", pCVStructFormat->type);
3467 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3471 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3472 pCVStructFormat->offset_to_array_description;
3473 switch (*pCVArrayFormat)
3475 case RPC_FC_CVARRAY:
3476 esize = *(const WORD*)(pCVArrayFormat+2);
3478 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3479 pCVArrayFormat + 4, 0);
3480 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3483 case RPC_FC_C_CSTRING:
3484 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3485 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3486 esize = sizeof(char);
3487 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3488 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3489 pCVArrayFormat + 2, 0);
3491 pStubMsg->MaxCount = pStubMsg->ActualCount;
3493 case RPC_FC_C_WSTRING:
3494 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3495 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3496 esize = sizeof(WCHAR);
3497 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3498 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3499 pCVArrayFormat + 2, 0);
3501 pStubMsg->MaxCount = pStubMsg->ActualCount;
3504 ERR("invalid array format type %x\n", *pCVArrayFormat);
3505 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3509 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3511 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3514 #include "pshpack1.h"
3518 unsigned char alignment;
3519 unsigned short total_size;
3520 } NDR_SMFARRAY_FORMAT;
3525 unsigned char alignment;
3526 unsigned long total_size;
3527 } NDR_LGFARRAY_FORMAT;
3528 #include "poppack.h"
3530 /***********************************************************************
3531 * NdrFixedArrayMarshall [RPCRT4.@]
3533 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3534 unsigned char *pMemory,
3535 PFORMAT_STRING pFormat)
3537 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3538 unsigned long total_size;
3540 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3542 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3543 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3545 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3546 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3550 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3552 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3554 total_size = pSmFArrayFormat->total_size;
3555 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3559 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3560 total_size = pLgFArrayFormat->total_size;
3561 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3564 memcpy(pStubMsg->Buffer, pMemory, total_size);
3565 pStubMsg->BufferMark = pStubMsg->Buffer;
3566 pStubMsg->Buffer += total_size;
3568 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3573 /***********************************************************************
3574 * NdrFixedArrayUnmarshall [RPCRT4.@]
3576 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3577 unsigned char **ppMemory,
3578 PFORMAT_STRING pFormat,
3579 unsigned char fMustAlloc)
3581 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3582 unsigned long total_size;
3584 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3586 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3587 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3589 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3590 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3594 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3596 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3598 total_size = pSmFArrayFormat->total_size;
3599 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3603 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3604 total_size = pLgFArrayFormat->total_size;
3605 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3608 if (fMustAlloc || !*ppMemory)
3609 *ppMemory = NdrAllocate(pStubMsg, total_size);
3610 memcpy(*ppMemory, pStubMsg->Buffer, total_size);
3611 pStubMsg->BufferMark = pStubMsg->Buffer;
3612 pStubMsg->Buffer += total_size;
3614 pFormat = EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3619 /***********************************************************************
3620 * NdrFixedArrayBufferSize [RPCRT4.@]
3622 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3623 unsigned char *pMemory,
3624 PFORMAT_STRING pFormat)
3626 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3627 unsigned long total_size;
3629 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3631 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3632 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3634 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3635 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3639 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
3641 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3643 total_size = pSmFArrayFormat->total_size;
3644 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3648 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3649 total_size = pLgFArrayFormat->total_size;
3650 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3652 pStubMsg->BufferLength += total_size;
3654 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3657 /***********************************************************************
3658 * NdrFixedArrayMemorySize [RPCRT4.@]
3660 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3661 PFORMAT_STRING pFormat)
3663 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3666 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3668 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3669 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3671 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3672 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3676 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3678 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3680 total_size = pSmFArrayFormat->total_size;
3681 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3685 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3686 total_size = pLgFArrayFormat->total_size;
3687 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3689 pStubMsg->BufferMark = pStubMsg->Buffer;
3690 pStubMsg->Buffer += total_size;
3691 pStubMsg->MemorySize += total_size;
3693 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3698 /***********************************************************************
3699 * NdrFixedArrayFree [RPCRT4.@]
3701 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3702 unsigned char *pMemory,
3703 PFORMAT_STRING pFormat)
3705 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3707 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3709 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3710 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3712 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3713 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3717 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3718 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3721 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3722 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3725 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3728 /***********************************************************************
3729 * NdrVaryingArrayMarshall [RPCRT4.@]
3731 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3732 unsigned char *pMemory,
3733 PFORMAT_STRING pFormat)
3735 unsigned char alignment;
3736 DWORD elements, esize;
3739 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3741 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3742 (pFormat[0] != RPC_FC_LGVARRAY))
3744 ERR("invalid format type %x\n", pFormat[0]);
3745 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3749 alignment = pFormat[1] + 1;
3751 if (pFormat[0] == RPC_FC_SMVARRAY)
3754 pFormat += sizeof(WORD);
3755 elements = *(const WORD*)pFormat;
3756 pFormat += sizeof(WORD);
3761 pFormat += sizeof(DWORD);
3762 elements = *(const DWORD*)pFormat;
3763 pFormat += sizeof(DWORD);
3766 esize = *(const WORD*)pFormat;
3767 pFormat += sizeof(WORD);
3769 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3770 if ((pStubMsg->ActualCount > elements) ||
3771 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3773 RpcRaiseException(RPC_S_INVALID_BOUND);
3777 WriteVariance(pStubMsg);
3779 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3781 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3782 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
3783 pStubMsg->BufferMark = pStubMsg->Buffer;
3784 pStubMsg->Buffer += bufsize;
3786 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3788 STD_OVERFLOW_CHECK(pStubMsg);
3793 /***********************************************************************
3794 * NdrVaryingArrayUnmarshall [RPCRT4.@]
3796 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3797 unsigned char **ppMemory,
3798 PFORMAT_STRING pFormat,
3799 unsigned char fMustAlloc)
3801 unsigned char alignment;
3802 DWORD size, elements, esize;
3805 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3807 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3808 (pFormat[0] != RPC_FC_LGVARRAY))
3810 ERR("invalid format type %x\n", pFormat[0]);
3811 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3815 alignment = pFormat[1] + 1;
3817 if (pFormat[0] == RPC_FC_SMVARRAY)
3820 size = *(const WORD*)pFormat;
3821 pFormat += sizeof(WORD);
3822 elements = *(const WORD*)pFormat;
3823 pFormat += sizeof(WORD);
3828 size = *(const DWORD*)pFormat;
3829 pFormat += sizeof(DWORD);
3830 elements = *(const DWORD*)pFormat;
3831 pFormat += sizeof(DWORD);
3834 esize = *(const WORD*)pFormat;
3835 pFormat += sizeof(WORD);
3837 pFormat = ReadVariance(pStubMsg, pFormat, elements);
3839 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3841 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3843 if (!*ppMemory || fMustAlloc)
3844 *ppMemory = NdrAllocate(pStubMsg, size);
3845 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
3846 pStubMsg->Buffer += bufsize;
3848 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3853 /***********************************************************************
3854 * NdrVaryingArrayBufferSize [RPCRT4.@]
3856 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3857 unsigned char *pMemory,
3858 PFORMAT_STRING pFormat)
3860 unsigned char alignment;
3861 DWORD elements, esize;
3863 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3865 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3866 (pFormat[0] != RPC_FC_LGVARRAY))
3868 ERR("invalid format type %x\n", pFormat[0]);
3869 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3873 alignment = pFormat[1] + 1;
3875 if (pFormat[0] == RPC_FC_SMVARRAY)
3878 pFormat += sizeof(WORD);
3879 elements = *(const WORD*)pFormat;
3880 pFormat += sizeof(WORD);
3885 pFormat += sizeof(DWORD);
3886 elements = *(const DWORD*)pFormat;
3887 pFormat += sizeof(DWORD);
3890 esize = *(const WORD*)pFormat;
3891 pFormat += sizeof(WORD);
3893 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3894 if ((pStubMsg->ActualCount > elements) ||
3895 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3897 RpcRaiseException(RPC_S_INVALID_BOUND);
3901 SizeVariance(pStubMsg);
3903 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3905 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
3907 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3910 /***********************************************************************
3911 * NdrVaryingArrayMemorySize [RPCRT4.@]
3913 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3914 PFORMAT_STRING pFormat)
3916 unsigned char alignment;
3917 DWORD size, elements, esize;
3919 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3921 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3922 (pFormat[0] != RPC_FC_LGVARRAY))
3924 ERR("invalid format type %x\n", pFormat[0]);
3925 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3929 alignment = pFormat[1] + 1;
3931 if (pFormat[0] == RPC_FC_SMVARRAY)
3934 size = *(const WORD*)pFormat;
3935 pFormat += sizeof(WORD);
3936 elements = *(const WORD*)pFormat;
3937 pFormat += sizeof(WORD);
3942 size = *(const DWORD*)pFormat;
3943 pFormat += sizeof(DWORD);
3944 elements = *(const DWORD*)pFormat;
3945 pFormat += sizeof(DWORD);
3948 esize = *(const WORD*)pFormat;
3949 pFormat += sizeof(WORD);
3951 pFormat = ReadVariance(pStubMsg, pFormat, elements);
3953 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3955 pStubMsg->Buffer += safe_multiply(esize, pStubMsg->ActualCount);
3956 pStubMsg->MemorySize += size;
3958 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3960 return pStubMsg->MemorySize;
3963 /***********************************************************************
3964 * NdrVaryingArrayFree [RPCRT4.@]
3966 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3967 unsigned char *pMemory,
3968 PFORMAT_STRING pFormat)
3970 unsigned char alignment;
3973 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3975 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3976 (pFormat[0] != RPC_FC_LGVARRAY))
3978 ERR("invalid format type %x\n", pFormat[0]);
3979 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3983 alignment = pFormat[1] + 1;
3985 if (pFormat[0] == RPC_FC_SMVARRAY)
3988 pFormat += sizeof(WORD);
3989 elements = *(const WORD*)pFormat;
3990 pFormat += sizeof(WORD);
3995 pFormat += sizeof(DWORD);
3996 elements = *(const DWORD*)pFormat;
3997 pFormat += sizeof(DWORD);
4000 pFormat += sizeof(WORD);
4002 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4003 if ((pStubMsg->ActualCount > elements) ||
4004 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4006 RpcRaiseException(RPC_S_INVALID_BOUND);
4010 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4013 /***********************************************************************
4014 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4016 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4017 unsigned char *pMemory,
4018 PFORMAT_STRING pFormat)
4024 /***********************************************************************
4025 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4027 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4028 unsigned char **ppMemory,
4029 PFORMAT_STRING pFormat,
4030 unsigned char fMustAlloc)
4036 /***********************************************************************
4037 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4039 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4040 unsigned char *pMemory,
4041 PFORMAT_STRING pFormat)
4046 /***********************************************************************
4047 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4049 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4050 PFORMAT_STRING pFormat)
4056 /***********************************************************************
4057 * NdrEncapsulatedUnionFree [RPCRT4.@]
4059 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4060 unsigned char *pMemory,
4061 PFORMAT_STRING pFormat)
4066 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4067 unsigned long discriminant,
4068 PFORMAT_STRING pFormat)
4070 unsigned short num_arms, arm, type;
4072 num_arms = *(const SHORT*)pFormat & 0x0fff;
4074 for(arm = 0; arm < num_arms; arm++)
4076 if(discriminant == *(const ULONG*)pFormat)
4084 type = *(const unsigned short*)pFormat;
4085 TRACE("type %04x\n", type);
4086 if(arm == num_arms) /* default arm extras */
4090 ERR("no arm for 0x%lx and no default case\n", discriminant);
4091 RpcRaiseException(RPC_S_INVALID_TAG);
4096 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
4103 static PFORMAT_STRING get_non_encapsulated_union_arm(PMIDL_STUB_MESSAGE pStubMsg,
4105 PFORMAT_STRING pFormat)
4107 pFormat += *(const SHORT*)pFormat;
4110 return get_arm_offset_from_union_arm_selector(pStubMsg, value, pFormat);
4113 /***********************************************************************
4114 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
4116 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4117 unsigned char *pMemory,
4118 PFORMAT_STRING pFormat)
4120 unsigned short type;
4121 unsigned char switch_type;
4123 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4126 switch_type = *pFormat;
4129 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4130 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4131 /* Marshall discriminant */
4132 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4134 pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
4138 type = *(const unsigned short*)pFormat;
4139 if((type & 0xff00) == 0x8000)
4141 unsigned char basetype = LOBYTE(type);
4142 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
4146 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4147 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
4150 unsigned char *saved_buffer = NULL;
4157 saved_buffer = pStubMsg->Buffer;
4158 pStubMsg->Buffer += 4; /* for pointer ID */
4159 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
4162 m(pStubMsg, pMemory, desc);
4165 else FIXME("no marshaller for embedded type %02x\n", *desc);
4170 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
4171 PFORMAT_STRING *ppFormat)
4173 long discriminant = 0;
4181 discriminant = *(UCHAR *)pStubMsg->Buffer;
4182 pStubMsg->Buffer += sizeof(UCHAR);
4187 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4188 discriminant = *(USHORT *)pStubMsg->Buffer;
4189 pStubMsg->Buffer += sizeof(USHORT);
4193 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4194 discriminant = *(ULONG *)pStubMsg->Buffer;
4195 pStubMsg->Buffer += sizeof(ULONG);
4198 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
4202 if (pStubMsg->fHasNewCorrDesc)
4206 return discriminant;
4209 /**********************************************************************
4210 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
4212 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4213 unsigned char **ppMemory,
4214 PFORMAT_STRING pFormat,
4215 unsigned char fMustAlloc)
4218 unsigned short type, size;
4220 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4223 /* Unmarshall discriminant */
4224 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4225 TRACE("unmarshalled discriminant %lx\n", discriminant);
4227 pFormat += *(const SHORT*)pFormat;
4229 size = *(const unsigned short*)pFormat;
4232 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4236 if(!*ppMemory || fMustAlloc)
4237 *ppMemory = NdrAllocate(pStubMsg, size);
4239 type = *(const unsigned short*)pFormat;
4240 if((type & 0xff00) == 0x8000)
4242 unsigned char basetype = LOBYTE(type);
4243 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, fMustAlloc);
4247 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4248 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
4251 unsigned char *saved_buffer = NULL;
4258 ALIGN_POINTER(pStubMsg->Buffer, 4);
4259 saved_buffer = pStubMsg->Buffer;
4260 pStubMsg->Buffer += 4; /* for pointer ID */
4261 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, desc, TRUE);
4264 m(pStubMsg, ppMemory, desc, fMustAlloc);
4267 else FIXME("no marshaller for embedded type %02x\n", *desc);
4272 /***********************************************************************
4273 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
4275 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4276 unsigned char *pMemory,
4277 PFORMAT_STRING pFormat)
4279 unsigned short type;
4280 unsigned char switch_type;
4282 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4285 switch_type = *pFormat;
4288 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4289 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4290 /* Add discriminant size */
4291 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4293 pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
4297 type = *(const unsigned short*)pFormat;
4298 if((type & 0xff00) == 0x8000)
4300 unsigned char basetype = LOBYTE(type);
4301 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
4305 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4306 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
4315 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4316 pStubMsg->BufferLength += 4; /* for pointer ID */
4317 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
4320 m(pStubMsg, pMemory, desc);
4323 else FIXME("no buffersizer for embedded type %02x\n", *desc);
4328 /***********************************************************************
4329 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
4331 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4332 PFORMAT_STRING pFormat)
4335 unsigned short type, size;
4338 /* Unmarshall discriminant */
4339 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4340 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
4342 pFormat += *(const SHORT*)pFormat;
4344 size = *(const unsigned short*)pFormat;
4347 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4351 pStubMsg->Memory += size;
4353 type = *(const unsigned short*)pFormat;
4354 if((type & 0xff00) == 0x8000)
4356 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
4360 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4361 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
4362 unsigned char *saved_buffer;
4371 ALIGN_POINTER(pStubMsg->Buffer, 4);
4372 saved_buffer = pStubMsg->Buffer;
4373 pStubMsg->Buffer += 4;
4374 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
4375 pStubMsg->MemorySize += 4;
4376 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
4379 return m(pStubMsg, desc);
4382 else FIXME("no marshaller for embedded type %02x\n", *desc);
4385 TRACE("size %d\n", size);
4389 /***********************************************************************
4390 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
4392 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4393 unsigned char *pMemory,
4394 PFORMAT_STRING pFormat)
4399 /***********************************************************************
4400 * NdrByteCountPointerMarshall [RPCRT4.@]
4402 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4403 unsigned char *pMemory,
4404 PFORMAT_STRING pFormat)
4410 /***********************************************************************
4411 * NdrByteCountPointerUnmarshall [RPCRT4.@]
4413 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4414 unsigned char **ppMemory,
4415 PFORMAT_STRING pFormat,
4416 unsigned char fMustAlloc)
4422 /***********************************************************************
4423 * NdrByteCountPointerBufferSize [RPCRT4.@]
4425 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4426 unsigned char *pMemory,
4427 PFORMAT_STRING pFormat)
4432 /***********************************************************************
4433 * NdrByteCountPointerMemorySize [RPCRT4.@]
4435 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4436 PFORMAT_STRING pFormat)
4442 /***********************************************************************
4443 * NdrByteCountPointerFree [RPCRT4.@]
4445 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
4446 unsigned char *pMemory,
4447 PFORMAT_STRING pFormat)
4452 /***********************************************************************
4453 * NdrXmitOrRepAsMarshall [RPCRT4.@]
4455 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4456 unsigned char *pMemory,
4457 PFORMAT_STRING pFormat)
4463 /***********************************************************************
4464 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
4466 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4467 unsigned char **ppMemory,
4468 PFORMAT_STRING pFormat,
4469 unsigned char fMustAlloc)
4475 /***********************************************************************
4476 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
4478 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4479 unsigned char *pMemory,
4480 PFORMAT_STRING pFormat)
4485 /***********************************************************************
4486 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
4488 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4489 PFORMAT_STRING pFormat)
4495 /***********************************************************************
4496 * NdrXmitOrRepAsFree [RPCRT4.@]
4498 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
4499 unsigned char *pMemory,
4500 PFORMAT_STRING pFormat)
4505 /***********************************************************************
4506 * NdrBaseTypeMarshall [internal]
4508 static unsigned char *WINAPI NdrBaseTypeMarshall(
4509 PMIDL_STUB_MESSAGE pStubMsg,
4510 unsigned char *pMemory,
4511 PFORMAT_STRING pFormat)
4513 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4521 *(UCHAR *)pStubMsg->Buffer = *(UCHAR *)pMemory;
4522 pStubMsg->Buffer += sizeof(UCHAR);
4523 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
4528 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4529 *(USHORT *)pStubMsg->Buffer = *(USHORT *)pMemory;
4530 pStubMsg->Buffer += sizeof(USHORT);
4531 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
4535 case RPC_FC_ERROR_STATUS_T:
4537 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4538 *(ULONG *)pStubMsg->Buffer = *(ULONG *)pMemory;
4539 pStubMsg->Buffer += sizeof(ULONG);
4540 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
4543 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
4544 *(float *)pStubMsg->Buffer = *(float *)pMemory;
4545 pStubMsg->Buffer += sizeof(float);
4548 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
4549 *(double *)pStubMsg->Buffer = *(double *)pMemory;
4550 pStubMsg->Buffer += sizeof(double);
4553 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
4554 *(ULONGLONG *)pStubMsg->Buffer = *(ULONGLONG *)pMemory;
4555 pStubMsg->Buffer += sizeof(ULONGLONG);
4556 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
4559 /* only 16-bits on the wire, so do a sanity check */
4560 if (*(UINT *)pMemory > USHRT_MAX)
4561 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
4562 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4563 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
4564 pStubMsg->Buffer += sizeof(USHORT);
4565 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
4568 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4571 STD_OVERFLOW_CHECK(pStubMsg);
4573 /* FIXME: what is the correct return value? */
4577 /***********************************************************************
4578 * NdrBaseTypeUnmarshall [internal]
4580 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
4581 PMIDL_STUB_MESSAGE pStubMsg,
4582 unsigned char **ppMemory,
4583 PFORMAT_STRING pFormat,
4584 unsigned char fMustAlloc)
4586 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
4588 #define BASE_TYPE_UNMARSHALL(type) \
4589 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
4590 if (fMustAlloc || !*ppMemory) \
4591 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
4592 TRACE("*ppMemory: %p\n", *ppMemory); \
4593 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
4594 pStubMsg->Buffer += sizeof(type);
4602 BASE_TYPE_UNMARSHALL(UCHAR);
4603 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
4608 BASE_TYPE_UNMARSHALL(USHORT);
4609 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
4613 case RPC_FC_ERROR_STATUS_T:
4615 BASE_TYPE_UNMARSHALL(ULONG);
4616 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
4619 BASE_TYPE_UNMARSHALL(float);
4620 TRACE("value: %f\n", **(float **)ppMemory);
4623 BASE_TYPE_UNMARSHALL(double);
4624 TRACE("value: %f\n", **(double **)ppMemory);
4627 BASE_TYPE_UNMARSHALL(ULONGLONG);
4628 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
4631 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4632 if (fMustAlloc || !*ppMemory)
4633 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
4634 TRACE("*ppMemory: %p\n", *ppMemory);
4635 /* 16-bits on the wire, but int in memory */
4636 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
4637 pStubMsg->Buffer += sizeof(USHORT);
4638 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
4641 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4643 #undef BASE_TYPE_UNMARSHALL
4645 /* FIXME: what is the correct return value? */
4650 /***********************************************************************
4651 * NdrBaseTypeBufferSize [internal]
4653 static void WINAPI NdrBaseTypeBufferSize(
4654 PMIDL_STUB_MESSAGE pStubMsg,
4655 unsigned char *pMemory,
4656 PFORMAT_STRING pFormat)
4658 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4666 pStubMsg->BufferLength += sizeof(UCHAR);
4672 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
4673 pStubMsg->BufferLength += sizeof(USHORT);
4678 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
4679 pStubMsg->BufferLength += sizeof(ULONG);
4682 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
4683 pStubMsg->BufferLength += sizeof(float);
4686 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
4687 pStubMsg->BufferLength += sizeof(double);
4690 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
4691 pStubMsg->BufferLength += sizeof(ULONGLONG);
4693 case RPC_FC_ERROR_STATUS_T:
4694 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
4695 pStubMsg->BufferLength += sizeof(error_status_t);
4698 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4702 /***********************************************************************
4703 * NdrBaseTypeMemorySize [internal]
4705 static ULONG WINAPI NdrBaseTypeMemorySize(
4706 PMIDL_STUB_MESSAGE pStubMsg,
4707 PFORMAT_STRING pFormat)
4715 pStubMsg->Buffer += sizeof(UCHAR);
4716 pStubMsg->MemorySize += sizeof(UCHAR);
4717 return sizeof(UCHAR);
4721 pStubMsg->Buffer += sizeof(USHORT);
4722 pStubMsg->MemorySize += sizeof(USHORT);
4723 return sizeof(USHORT);
4726 pStubMsg->Buffer += sizeof(ULONG);
4727 pStubMsg->MemorySize += sizeof(ULONG);
4728 return sizeof(ULONG);
4730 pStubMsg->Buffer += sizeof(float);
4731 pStubMsg->MemorySize += sizeof(float);
4732 return sizeof(float);
4734 pStubMsg->Buffer += sizeof(double);
4735 pStubMsg->MemorySize += sizeof(double);
4736 return sizeof(double);
4738 pStubMsg->Buffer += sizeof(ULONGLONG);
4739 pStubMsg->MemorySize += sizeof(ULONGLONG);
4740 return sizeof(ULONGLONG);
4741 case RPC_FC_ERROR_STATUS_T:
4742 pStubMsg->Buffer += sizeof(error_status_t);
4743 pStubMsg->MemorySize += sizeof(error_status_t);
4744 return sizeof(error_status_t);
4747 pStubMsg->Buffer += sizeof(INT);
4748 pStubMsg->MemorySize += sizeof(INT);
4751 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4756 /***********************************************************************
4757 * NdrBaseTypeFree [internal]
4759 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
4760 unsigned char *pMemory,
4761 PFORMAT_STRING pFormat)
4763 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4768 /***********************************************************************
4769 * NdrClientContextMarshall [RPCRT4.@]
4771 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4772 NDR_CCONTEXT ContextHandle,
4775 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
4777 ALIGN_POINTER(pStubMsg->Buffer, 4);
4779 /* FIXME: what does fCheck do? */
4780 NDRCContextMarshall(ContextHandle,
4783 pStubMsg->Buffer += cbNDRContext;
4786 /***********************************************************************
4787 * NdrClientContextUnmarshall [RPCRT4.@]
4789 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4790 NDR_CCONTEXT * pContextHandle,
4791 RPC_BINDING_HANDLE BindHandle)
4793 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
4795 ALIGN_POINTER(pStubMsg->Buffer, 4);
4797 NDRCContextUnmarshall(pContextHandle,
4800 pStubMsg->RpcMsg->DataRepresentation);
4802 pStubMsg->Buffer += cbNDRContext;
4805 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4806 NDR_SCONTEXT ContextHandle,
4807 NDR_RUNDOWN RundownRoutine )
4809 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
4812 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
4814 FIXME("(%p): stub\n", pStubMsg);
4818 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
4819 unsigned char* pMemory,
4820 PFORMAT_STRING pFormat)
4822 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
4825 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
4826 PFORMAT_STRING pFormat)
4828 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
4832 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4833 NDR_SCONTEXT ContextHandle,
4834 NDR_RUNDOWN RundownRoutine,
4835 PFORMAT_STRING pFormat)
4837 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
4840 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4841 PFORMAT_STRING pFormat)
4843 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
4847 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
4849 typedef struct ndr_context_handle
4853 } ndr_context_handle;
4855 struct context_handle_entry
4859 RPC_BINDING_HANDLE handle;
4860 ndr_context_handle wire_data;
4863 static struct list context_handle_list = LIST_INIT(context_handle_list);
4865 static CRITICAL_SECTION ndr_context_cs;
4866 static CRITICAL_SECTION_DEBUG ndr_context_debug =
4868 0, 0, &ndr_context_cs,
4869 { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
4870 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
4872 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
4874 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
4876 struct context_handle_entry *che = (struct context_handle_entry*) CContext;
4878 if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
4883 static struct context_handle_entry *context_entry_from_guid(LPGUID uuid)
4885 struct context_handle_entry *che;
4886 LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
4887 if (IsEqualGUID(&che->wire_data.uuid, uuid))
4892 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
4894 struct context_handle_entry *che;
4895 RPC_BINDING_HANDLE handle = NULL;
4897 TRACE("%p\n", CContext);
4899 EnterCriticalSection(&ndr_context_cs);
4900 che = get_context_entry(CContext);
4902 handle = che->handle;
4903 LeaveCriticalSection(&ndr_context_cs);
4906 RpcRaiseException(ERROR_INVALID_HANDLE);
4910 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
4912 struct context_handle_entry *che;
4914 TRACE("%p %p\n", CContext, pBuff);
4918 EnterCriticalSection(&ndr_context_cs);
4919 che = get_context_entry(CContext);
4920 memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
4921 LeaveCriticalSection(&ndr_context_cs);
4925 ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
4926 wire_data->attributes = 0;
4927 wire_data->uuid = GUID_NULL;
4931 static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
4932 RPC_BINDING_HANDLE hBinding,
4933 ndr_context_handle *chi)
4935 struct context_handle_entry *che = NULL;
4937 /* a null UUID means we should free the context handle */
4938 if (IsEqualGUID(&chi->uuid, &GUID_NULL))
4942 che = get_context_entry(*CContext);
4944 return ERROR_INVALID_HANDLE;
4945 list_remove(&che->entry);
4946 RpcBindingFree(&che->handle);
4947 HeapFree(GetProcessHeap(), 0, che);
4951 /* if there's no existing entry matching the GUID, allocate one */
4952 else if (!(che = context_entry_from_guid(&chi->uuid)))
4954 che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
4956 return ERROR_NOT_ENOUGH_MEMORY;
4957 che->magic = NDR_CONTEXT_HANDLE_MAGIC;
4958 RpcBindingCopy(hBinding, &che->handle);
4959 list_add_tail(&context_handle_list, &che->entry);
4960 memcpy(&che->wire_data, chi, sizeof *chi);
4965 return ERROR_SUCCESS;
4968 /***********************************************************************
4969 * NDRCContextUnmarshall [RPCRT4.@]
4971 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
4972 RPC_BINDING_HANDLE hBinding,
4973 void *pBuff, ULONG DataRepresentation)
4977 TRACE("*%p=(%p) %p %p %08x\n",
4978 CContext, *CContext, hBinding, pBuff, DataRepresentation);
4980 EnterCriticalSection(&ndr_context_cs);
4981 r = ndr_update_context_handle(CContext, hBinding, pBuff);
4982 LeaveCriticalSection(&ndr_context_cs);
4984 RpcRaiseException(r);
4987 /***********************************************************************
4988 * NDRSContextMarshall [RPCRT4.@]
4990 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
4992 NDR_RUNDOWN userRunDownIn)
4994 FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn);
4997 /***********************************************************************
4998 * NDRSContextMarshallEx [RPCRT4.@]
5000 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
5001 NDR_SCONTEXT CContext,
5003 NDR_RUNDOWN userRunDownIn)
5005 FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn);
5008 /***********************************************************************
5009 * NDRSContextMarshall2 [RPCRT4.@]
5011 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
5012 NDR_SCONTEXT CContext,
5014 NDR_RUNDOWN userRunDownIn,
5015 void *CtxGuard, ULONG Flags)
5017 FIXME("(%p %p %p %p %p %u): stub\n",
5018 hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags);
5021 /***********************************************************************
5022 * NDRSContextUnmarshall [RPCRT4.@]
5024 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
5025 ULONG DataRepresentation)
5027 FIXME("(%p %08x): stub\n", pBuff, DataRepresentation);
5031 /***********************************************************************
5032 * NDRSContextUnmarshallEx [RPCRT4.@]
5034 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
5036 ULONG DataRepresentation)
5038 FIXME("(%p %p %08x): stub\n", hBinding, pBuff, DataRepresentation);
5042 /***********************************************************************
5043 * NDRSContextUnmarshall2 [RPCRT4.@]
5045 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
5047 ULONG DataRepresentation,
5048 void *CtxGuard, ULONG Flags)
5050 FIXME("(%p %p %08x %p %u): stub\n",
5051 hBinding, pBuff, DataRepresentation, CtxGuard, Flags);