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/%ld\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
109 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
110 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
113 #define NDR_TABLE_SIZE 128
114 #define NDR_TABLE_MASK 127
116 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
117 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
118 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
119 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
120 static unsigned long WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
122 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
124 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
125 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
126 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
127 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
131 NdrPointerMarshall, NdrPointerMarshall,
132 NdrPointerMarshall, NdrPointerMarshall,
134 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
135 NdrConformantStructMarshall, NdrConformantStructMarshall,
136 NdrConformantVaryingStructMarshall,
137 NdrComplexStructMarshall,
139 NdrConformantArrayMarshall,
140 NdrConformantVaryingArrayMarshall,
141 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
142 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
143 NdrComplexArrayMarshall,
145 NdrConformantStringMarshall, 0, 0,
146 NdrConformantStringMarshall,
147 NdrNonConformantStringMarshall, 0, 0, 0,
149 NdrEncapsulatedUnionMarshall,
150 NdrNonEncapsulatedUnionMarshall,
151 NdrByteCountPointerMarshall,
152 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
154 NdrInterfacePointerMarshall,
157 NdrUserMarshalMarshall
159 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
161 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
162 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
163 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
164 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
166 NdrBaseTypeUnmarshall,
168 NdrPointerUnmarshall, NdrPointerUnmarshall,
169 NdrPointerUnmarshall, NdrPointerUnmarshall,
171 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
172 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
173 NdrConformantVaryingStructUnmarshall,
174 NdrComplexStructUnmarshall,
176 NdrConformantArrayUnmarshall,
177 NdrConformantVaryingArrayUnmarshall,
178 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
179 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
180 NdrComplexArrayUnmarshall,
182 NdrConformantStringUnmarshall, 0, 0,
183 NdrConformantStringUnmarshall,
184 NdrNonConformantStringUnmarshall, 0, 0, 0,
186 NdrEncapsulatedUnionUnmarshall,
187 NdrNonEncapsulatedUnionUnmarshall,
188 NdrByteCountPointerUnmarshall,
189 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
191 NdrInterfacePointerUnmarshall,
194 NdrUserMarshalUnmarshall
196 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
198 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
199 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
200 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
201 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
203 NdrBaseTypeBufferSize,
205 NdrPointerBufferSize, NdrPointerBufferSize,
206 NdrPointerBufferSize, NdrPointerBufferSize,
208 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
209 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
210 NdrConformantVaryingStructBufferSize,
211 NdrComplexStructBufferSize,
213 NdrConformantArrayBufferSize,
214 NdrConformantVaryingArrayBufferSize,
215 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
216 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
217 NdrComplexArrayBufferSize,
219 NdrConformantStringBufferSize, 0, 0,
220 NdrConformantStringBufferSize,
221 NdrNonConformantStringBufferSize, 0, 0, 0,
223 NdrEncapsulatedUnionBufferSize,
224 NdrNonEncapsulatedUnionBufferSize,
225 NdrByteCountPointerBufferSize,
226 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
228 NdrInterfacePointerBufferSize,
231 NdrUserMarshalBufferSize
233 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
235 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
236 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
237 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
238 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
240 NdrBaseTypeMemorySize,
242 NdrPointerMemorySize, NdrPointerMemorySize,
243 NdrPointerMemorySize, NdrPointerMemorySize,
245 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
246 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
247 NdrConformantVaryingStructMemorySize,
248 NdrComplexStructMemorySize,
250 NdrConformantArrayMemorySize,
251 NdrConformantVaryingArrayMemorySize,
252 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
253 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
254 NdrComplexArrayMemorySize,
256 NdrConformantStringMemorySize, 0, 0,
257 NdrConformantStringMemorySize,
258 NdrNonConformantStringMemorySize, 0, 0, 0,
260 NdrEncapsulatedUnionMemorySize,
261 NdrNonEncapsulatedUnionMemorySize,
262 NdrByteCountPointerMemorySize,
263 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
265 NdrInterfacePointerMemorySize,
268 NdrUserMarshalMemorySize
270 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
272 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
273 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
274 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
275 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
279 NdrPointerFree, NdrPointerFree,
280 NdrPointerFree, NdrPointerFree,
282 NdrSimpleStructFree, NdrSimpleStructFree,
283 NdrConformantStructFree, NdrConformantStructFree,
284 NdrConformantVaryingStructFree,
285 NdrComplexStructFree,
287 NdrConformantArrayFree,
288 NdrConformantVaryingArrayFree,
289 NdrFixedArrayFree, NdrFixedArrayFree,
290 NdrVaryingArrayFree, NdrVaryingArrayFree,
296 NdrEncapsulatedUnionFree,
297 NdrNonEncapsulatedUnionFree,
299 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
301 NdrInterfacePointerFree,
307 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
309 /* hmm, this is probably supposed to do more? */
310 return pStubMsg->pfnAllocate(len);
313 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
315 pStubMsg->pfnFree(Pointer);
318 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
320 return (*(const ULONG *)pFormat != -1);
323 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
325 ALIGN_POINTER(pStubMsg->Buffer, 4);
326 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
327 pStubMsg->Buffer += 4;
328 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
329 if (pStubMsg->fHasNewCorrDesc)
335 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
337 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
339 pStubMsg->Offset = 0;
340 pStubMsg->ActualCount = pStubMsg->MaxCount;
344 ALIGN_POINTER(pStubMsg->Buffer, 4);
345 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
346 pStubMsg->Buffer += 4;
347 TRACE("offset is %ld\n", pStubMsg->Offset);
348 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
349 pStubMsg->Buffer += 4;
350 TRACE("variance is %ld\n", pStubMsg->ActualCount);
352 if ((pStubMsg->ActualCount > MaxValue) ||
353 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
355 ERR("invalid array bound(s): ActualCount = %ld, Offset = %ld, MaxValue = %ld\n",
356 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
357 RpcRaiseException(RPC_S_INVALID_BOUND);
362 if (pStubMsg->fHasNewCorrDesc)
368 /* writes the conformance value to the buffer */
369 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
371 ALIGN_POINTER(pStubMsg->Buffer, 4);
372 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
373 pStubMsg->Buffer += 4;
376 /* writes the variance values to the buffer */
377 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
379 ALIGN_POINTER(pStubMsg->Buffer, 4);
380 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
381 pStubMsg->Buffer += 4;
382 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
383 pStubMsg->Buffer += 4;
386 /* requests buffer space for the conformance value */
387 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
389 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
390 pStubMsg->BufferLength += 4;
393 /* requests buffer space for the variance values */
394 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
396 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
397 pStubMsg->BufferLength += 8;
400 PFORMAT_STRING ComputeConformanceOrVariance(
401 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
402 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG *pCount)
404 BYTE dtype = pFormat[0] & 0xf;
405 short ofs = *(short *)&pFormat[2];
409 if (!IsConformanceOrVariancePresent(pFormat)) {
410 /* null descriptor */
415 switch (pFormat[0] & 0xf0) {
416 case RPC_FC_NORMAL_CONFORMANCE:
417 TRACE("normal conformance, ofs=%d\n", ofs);
420 case RPC_FC_POINTER_CONFORMANCE:
421 TRACE("pointer conformance, ofs=%d\n", ofs);
422 ptr = pStubMsg->Memory;
424 case RPC_FC_TOP_LEVEL_CONFORMANCE:
425 TRACE("toplevel conformance, ofs=%d\n", ofs);
426 if (pStubMsg->StackTop) {
427 ptr = pStubMsg->StackTop;
430 /* -Os mode, *pCount is already set */
434 case RPC_FC_CONSTANT_CONFORMANCE:
435 data = ofs | ((DWORD)pFormat[1] << 16);
436 TRACE("constant conformance, val=%ld\n", data);
439 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
440 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
441 if (pStubMsg->StackTop) {
442 ptr = pStubMsg->StackTop;
450 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
453 switch (pFormat[1]) {
454 case RPC_FC_DEREFERENCE:
455 ptr = *(LPVOID*)((char *)ptr + ofs);
457 case RPC_FC_CALLBACK:
459 unsigned char *old_stack_top = pStubMsg->StackTop;
460 pStubMsg->StackTop = ptr;
462 /* ofs is index into StubDesc->apfnExprEval */
463 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
464 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
466 pStubMsg->StackTop = old_stack_top;
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 %ld\n", dtype, ptr, data);
503 switch (pFormat[1]) {
504 case RPC_FC_DEREFERENCE: /* already handled */
521 FIXME("unknown conformance op %d\n", pFormat[1]);
526 TRACE("resulting conformance is %ld\n", *pCount);
527 if (pStubMsg->fHasNewCorrDesc)
533 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
534 * the result overflows 32-bits */
535 inline static ULONG safe_multiply(ULONG a, ULONG b)
537 ULONGLONG ret = (ULONGLONG)a * b;
538 if (ret > 0xffffffff)
540 RpcRaiseException(RPC_S_INVALID_BOUND);
548 * NdrConformantString:
550 * What MS calls a ConformantString is, in DCE terminology,
551 * a Varying-Conformant String.
553 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
554 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
555 * into unmarshalled string)
556 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
558 * data: CHARTYPE[maxlen]
560 * ], where CHARTYPE is the appropriate character type (specified externally)
564 /***********************************************************************
565 * NdrConformantStringMarshall [RPCRT4.@]
567 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
568 unsigned char *pszMessage, PFORMAT_STRING pFormat)
572 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
574 if (*pFormat == RPC_FC_C_CSTRING) {
575 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
576 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
579 else if (*pFormat == RPC_FC_C_WSTRING) {
580 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
581 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
585 ERR("Unhandled string type: %#x\n", *pFormat);
586 /* FIXME: raise an exception. */
590 if (pFormat[1] == RPC_FC_STRING_SIZED)
591 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
593 pStubMsg->MaxCount = pStubMsg->ActualCount;
594 pStubMsg->Offset = 0;
595 WriteConformance(pStubMsg);
596 WriteVariance(pStubMsg);
598 size = safe_multiply(esize, pStubMsg->ActualCount);
599 memcpy(pStubMsg->Buffer, pszMessage, size); /* the string itself */
600 pStubMsg->Buffer += size;
602 STD_OVERFLOW_CHECK(pStubMsg);
605 return NULL; /* is this always right? */
608 /***********************************************************************
609 * NdrConformantStringBufferSize [RPCRT4.@]
611 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
612 unsigned char* pMemory, PFORMAT_STRING pFormat)
616 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
618 SizeConformance(pStubMsg);
619 SizeVariance(pStubMsg);
621 if (*pFormat == RPC_FC_C_CSTRING) {
622 TRACE("string=%s\n", debugstr_a((char*)pMemory));
623 pStubMsg->ActualCount = strlen((char*)pMemory)+1;
626 else if (*pFormat == RPC_FC_C_WSTRING) {
627 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
628 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;
632 ERR("Unhandled string type: %#x\n", *pFormat);
633 /* FIXME: raise an exception */
637 if (pFormat[1] == RPC_FC_STRING_SIZED)
638 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
640 pStubMsg->MaxCount = pStubMsg->ActualCount;
642 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
645 /************************************************************************
646 * NdrConformantStringMemorySize [RPCRT4.@]
648 unsigned long WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
649 PFORMAT_STRING pFormat )
651 unsigned long rslt = 0;
653 TRACE("(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(" --> %lu\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 size, 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 size = safe_multiply(esize, pStubMsg->ActualCount);
702 /* strings must always have null terminating bytes */
705 ERR("invalid string length of %ld\n", pStubMsg->ActualCount);
706 RpcRaiseException(RPC_S_INVALID_BOUND);
709 for (i = size - esize; i < size; i++)
710 if (pStubMsg->Buffer[i] != 0)
712 ERR("string not null-terminated at byte position %ld, data is 0x%x\n",
713 i, pStubMsg->Buffer[i]);
714 RpcRaiseException(RPC_S_INVALID_BOUND);
718 if (fMustAlloc || !*ppMemory)
719 *ppMemory = NdrAllocate(pStubMsg, size);
721 memcpy(*ppMemory, pStubMsg->Buffer, size);
723 pStubMsg->Buffer += size;
725 if (*pFormat == RPC_FC_C_CSTRING) {
726 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
728 else if (*pFormat == RPC_FC_C_WSTRING) {
729 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
732 return NULL; /* FIXME: is this always right? */
735 /***********************************************************************
736 * NdrNonConformantStringMarshall [RPCRT4.@]
738 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
739 unsigned char *pMemory,
740 PFORMAT_STRING pFormat)
746 /***********************************************************************
747 * NdrNonConformantStringUnmarshall [RPCRT4.@]
749 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
750 unsigned char **ppMemory,
751 PFORMAT_STRING pFormat,
752 unsigned char fMustAlloc)
758 /***********************************************************************
759 * NdrNonConformantStringBufferSize [RPCRT4.@]
761 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
762 unsigned char *pMemory,
763 PFORMAT_STRING pFormat)
768 /***********************************************************************
769 * NdrNonConformantStringMemorySize [RPCRT4.@]
771 unsigned long WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
772 PFORMAT_STRING pFormat)
778 static inline void dump_pointer_attr(unsigned char attr)
780 if (attr & RPC_FC_P_ALLOCALLNODES)
781 TRACE(" RPC_FC_P_ALLOCALLNODES");
782 if (attr & RPC_FC_P_DONTFREE)
783 TRACE(" RPC_FC_P_DONTFREE");
784 if (attr & RPC_FC_P_ONSTACK)
785 TRACE(" RPC_FC_P_ONSTACK");
786 if (attr & RPC_FC_P_SIMPLEPOINTER)
787 TRACE(" RPC_FC_P_SIMPLEPOINTER");
788 if (attr & RPC_FC_P_DEREF)
789 TRACE(" RPC_FC_P_DEREF");
793 /***********************************************************************
796 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
797 unsigned char *Buffer,
798 unsigned char *Pointer,
799 PFORMAT_STRING pFormat)
801 unsigned type = pFormat[0], attr = pFormat[1];
804 unsigned long pointer_id;
805 int pointer_needs_marshaling;
807 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
808 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
810 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
811 else desc = pFormat + *(const SHORT*)pFormat;
814 case RPC_FC_RP: /* ref pointer (always non-null) */
815 #if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
817 RpcRaiseException(RPC_X_NULL_REF_POINTER);
819 pointer_needs_marshaling = 1;
821 case RPC_FC_UP: /* unique pointer */
822 case RPC_FC_OP: /* object pointer - same as unique here */
824 pointer_needs_marshaling = 1;
826 pointer_needs_marshaling = 0;
827 pointer_id = (unsigned long)Pointer;
828 TRACE("writing 0x%08lx to buffer\n", pointer_id);
829 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
832 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
833 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
834 TRACE("writing 0x%08lx to buffer\n", pointer_id);
835 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
838 FIXME("unhandled ptr type=%02x\n", type);
839 RpcRaiseException(RPC_X_BAD_STUB_DATA);
843 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
845 if (pointer_needs_marshaling) {
846 if (attr & RPC_FC_P_DEREF) {
847 Pointer = *(unsigned char**)Pointer;
848 TRACE("deref => %p\n", Pointer);
850 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
851 if (m) m(pStubMsg, Pointer, desc);
852 else FIXME("no marshaller for data type=%02x\n", *desc);
855 STD_OVERFLOW_CHECK(pStubMsg);
858 /***********************************************************************
861 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
862 unsigned char *Buffer,
863 unsigned char **pPointer,
864 PFORMAT_STRING pFormat,
865 unsigned char fMustAlloc)
867 unsigned type = pFormat[0], attr = pFormat[1];
870 DWORD pointer_id = 0;
871 int pointer_needs_unmarshaling;
873 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pFormat, fMustAlloc);
874 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
876 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
877 else desc = pFormat + *(const SHORT*)pFormat;
880 case RPC_FC_RP: /* ref pointer (always non-null) */
881 pointer_needs_unmarshaling = 1;
883 case RPC_FC_UP: /* unique pointer */
884 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
885 TRACE("pointer_id is 0x%08lx\n", pointer_id);
887 pointer_needs_unmarshaling = 1;
890 pointer_needs_unmarshaling = 0;
893 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
894 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
895 TRACE("pointer_id is 0x%08lx\n", pointer_id);
896 if (!fMustAlloc && *pPointer)
898 FIXME("free object pointer %p\n", *pPointer);
902 pointer_needs_unmarshaling = 1;
904 pointer_needs_unmarshaling = 0;
907 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
908 TRACE("pointer_id is 0x%08lx\n", pointer_id);
909 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
910 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
913 FIXME("unhandled ptr type=%02x\n", type);
914 RpcRaiseException(RPC_X_BAD_STUB_DATA);
918 if (pointer_needs_unmarshaling) {
919 if (attr & RPC_FC_P_DEREF) {
920 if (!*pPointer || fMustAlloc)
921 *pPointer = NdrAllocate(pStubMsg, sizeof(void *));
922 pPointer = *(unsigned char***)pPointer;
923 TRACE("deref => %p\n", pPointer);
925 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
926 if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
927 else FIXME("no unmarshaller for data type=%02x\n", *desc);
929 if (type == RPC_FC_FP)
930 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
934 TRACE("pointer=%p\n", *pPointer);
937 /***********************************************************************
940 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
941 unsigned char *Pointer,
942 PFORMAT_STRING pFormat)
944 unsigned type = pFormat[0], attr = pFormat[1];
947 int pointer_needs_sizing;
948 unsigned long pointer_id;
950 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
951 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
953 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
954 else desc = pFormat + *(const SHORT*)pFormat;
957 case RPC_FC_RP: /* ref pointer (always non-null) */
961 /* NULL pointer has no further representation */
966 pointer_needs_sizing = !NdrFullPointerQueryPointer(
967 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
968 if (!pointer_needs_sizing)
972 FIXME("unhandled ptr type=%02x\n", type);
973 RpcRaiseException(RPC_X_BAD_STUB_DATA);
977 if (attr & RPC_FC_P_DEREF) {
978 Pointer = *(unsigned char**)Pointer;
979 TRACE("deref => %p\n", Pointer);
982 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
983 if (m) m(pStubMsg, Pointer, desc);
984 else FIXME("no buffersizer for data type=%02x\n", *desc);
987 /***********************************************************************
988 * PointerMemorySize [RPCRT4.@]
990 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
991 unsigned char *Buffer,
992 PFORMAT_STRING pFormat)
994 unsigned type = pFormat[0], attr = pFormat[1];
998 FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat);
999 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1001 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1002 else desc = pFormat + *(const SHORT*)pFormat;
1005 case RPC_FC_RP: /* ref pointer (always non-null) */
1008 FIXME("unhandled ptr type=%02x\n", type);
1009 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1012 if (attr & RPC_FC_P_DEREF) {
1016 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1017 if (m) m(pStubMsg, desc);
1018 else FIXME("no memorysizer for data type=%02x\n", *desc);
1023 /***********************************************************************
1024 * PointerFree [RPCRT4.@]
1026 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1027 unsigned char *Pointer,
1028 PFORMAT_STRING pFormat)
1030 unsigned type = pFormat[0], attr = pFormat[1];
1031 PFORMAT_STRING desc;
1034 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1035 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1036 if (attr & RPC_FC_P_DONTFREE) return;
1038 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1039 else desc = pFormat + *(const SHORT*)pFormat;
1041 if (!Pointer) return;
1043 if (type == RPC_FC_FP) {
1044 int pointer_needs_freeing = NdrFullPointerFree(
1045 pStubMsg->FullPtrXlatTables, Pointer);
1046 if (!pointer_needs_freeing)
1050 if (attr & RPC_FC_P_DEREF) {
1051 Pointer = *(unsigned char**)Pointer;
1052 TRACE("deref => %p\n", Pointer);
1055 m = NdrFreer[*desc & NDR_TABLE_MASK];
1056 if (m) m(pStubMsg, Pointer, desc);
1058 /* hmm... is this sensible?
1059 * perhaps we should check if the memory comes from NdrAllocate,
1060 * and deallocate only if so - checking if the pointer is between
1061 * BufferStart and BufferEnd is probably no good since the buffer
1062 * may be reallocated when the server wants to marshal the reply */
1064 case RPC_FC_BOGUS_STRUCT:
1065 case RPC_FC_BOGUS_ARRAY:
1066 case RPC_FC_USER_MARSHAL:
1068 case RPC_FC_CVARRAY:
1071 FIXME("unhandled data type=%02x\n", *desc);
1073 case RPC_FC_C_CSTRING:
1074 case RPC_FC_C_WSTRING:
1075 if (pStubMsg->ReuseBuffer) goto notfree;
1081 if (attr & RPC_FC_P_ONSTACK) {
1082 TRACE("not freeing stack ptr %p\n", Pointer);
1085 TRACE("freeing %p\n", Pointer);
1086 NdrFree(pStubMsg, Pointer);
1089 TRACE("not freeing %p\n", Pointer);
1092 /***********************************************************************
1093 * EmbeddedPointerMarshall
1095 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1096 unsigned char *pMemory,
1097 PFORMAT_STRING pFormat)
1099 unsigned char *Mark = pStubMsg->BufferMark;
1100 unsigned long Offset = pStubMsg->Offset;
1101 unsigned ofs, rep, count, stride, xofs;
1104 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1106 if (*pFormat != RPC_FC_PP) return NULL;
1109 while (pFormat[0] != RPC_FC_END) {
1110 switch (pFormat[0]) {
1112 FIXME("unknown repeat type %d\n", pFormat[0]);
1113 case RPC_FC_NO_REPEAT:
1121 case RPC_FC_FIXED_REPEAT:
1122 rep = *(const WORD*)&pFormat[2];
1123 stride = *(const WORD*)&pFormat[4];
1124 ofs = *(const WORD*)&pFormat[6];
1125 count = *(const WORD*)&pFormat[8];
1129 case RPC_FC_VARIABLE_REPEAT:
1130 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1131 stride = *(const WORD*)&pFormat[2];
1132 ofs = *(const WORD*)&pFormat[4];
1133 count = *(const WORD*)&pFormat[6];
1134 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1138 for (i = 0; i < rep; i++) {
1139 PFORMAT_STRING info = pFormat;
1140 unsigned char *membase = pMemory + (i * stride);
1141 unsigned char *bufbase = Mark + (i * stride);
1143 /* ofs doesn't seem to matter in this context */
1144 for (u=0; u<count; u++,info+=8) {
1145 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1146 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1147 unsigned char *saved_memory = pStubMsg->Memory;
1149 pStubMsg->Memory = pMemory;
1150 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1151 pStubMsg->Memory = saved_memory;
1154 pFormat += 8 * count;
1157 STD_OVERFLOW_CHECK(pStubMsg);
1162 /***********************************************************************
1163 * EmbeddedPointerUnmarshall
1165 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1166 unsigned char **ppMemory,
1167 PFORMAT_STRING pFormat,
1168 unsigned char fMustAlloc)
1170 unsigned char *Mark = pStubMsg->BufferMark;
1171 unsigned long Offset = pStubMsg->Offset;
1172 unsigned ofs, rep, count, stride, xofs;
1175 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1177 if (*pFormat != RPC_FC_PP) return NULL;
1180 while (pFormat[0] != RPC_FC_END) {
1181 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1182 switch (pFormat[0]) {
1184 FIXME("unknown repeat type %d\n", pFormat[0]);
1185 case RPC_FC_NO_REPEAT:
1193 case RPC_FC_FIXED_REPEAT:
1194 rep = *(const WORD*)&pFormat[2];
1195 stride = *(const WORD*)&pFormat[4];
1196 ofs = *(const WORD*)&pFormat[6];
1197 count = *(const WORD*)&pFormat[8];
1201 case RPC_FC_VARIABLE_REPEAT:
1202 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1203 stride = *(const WORD*)&pFormat[2];
1204 ofs = *(const WORD*)&pFormat[4];
1205 count = *(const WORD*)&pFormat[6];
1206 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1210 /* ofs doesn't seem to matter in this context */
1211 for (i = 0; i < rep; i++) {
1212 PFORMAT_STRING info = pFormat;
1213 unsigned char *membase = *ppMemory + (i * stride);
1214 unsigned char *bufbase = Mark + (i * stride);
1216 for (u=0; u<count; u++,info+=8) {
1217 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1218 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1219 PointerUnmarshall(pStubMsg, bufptr, (unsigned char**)memptr, info+4, TRUE);
1222 pFormat += 8 * count;
1228 /***********************************************************************
1229 * EmbeddedPointerBufferSize
1231 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1232 unsigned char *pMemory,
1233 PFORMAT_STRING pFormat)
1235 unsigned long Offset = pStubMsg->Offset;
1236 unsigned ofs, rep, count, stride, xofs;
1239 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1241 if (pStubMsg->IgnoreEmbeddedPointers) return;
1243 if (*pFormat != RPC_FC_PP) return;
1246 while (pFormat[0] != RPC_FC_END) {
1247 switch (pFormat[0]) {
1249 FIXME("unknown repeat type %d\n", pFormat[0]);
1250 case RPC_FC_NO_REPEAT:
1258 case RPC_FC_FIXED_REPEAT:
1259 rep = *(const WORD*)&pFormat[2];
1260 stride = *(const WORD*)&pFormat[4];
1261 ofs = *(const WORD*)&pFormat[6];
1262 count = *(const WORD*)&pFormat[8];
1266 case RPC_FC_VARIABLE_REPEAT:
1267 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1268 stride = *(const WORD*)&pFormat[2];
1269 ofs = *(const WORD*)&pFormat[4];
1270 count = *(const WORD*)&pFormat[6];
1271 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1275 /* ofs doesn't seem to matter in this context */
1276 for (i = 0; i < rep; i++) {
1277 PFORMAT_STRING info = pFormat;
1278 unsigned char *membase = pMemory + (i * stride);
1280 for (u=0; u<count; u++,info+=8) {
1281 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1282 unsigned char *saved_memory = pStubMsg->Memory;
1284 pStubMsg->Memory = pMemory;
1285 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1286 pStubMsg->Memory = saved_memory;
1289 pFormat += 8 * count;
1293 /***********************************************************************
1294 * EmbeddedPointerMemorySize
1296 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1297 PFORMAT_STRING pFormat)
1299 unsigned long Offset = pStubMsg->Offset;
1300 unsigned char *Mark = pStubMsg->BufferMark;
1301 unsigned ofs, rep, count, stride, xofs;
1304 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1306 if (*pFormat != RPC_FC_PP) return 0;
1309 while (pFormat[0] != RPC_FC_END) {
1310 switch (pFormat[0]) {
1312 FIXME("unknown repeat type %d\n", pFormat[0]);
1313 case RPC_FC_NO_REPEAT:
1321 case RPC_FC_FIXED_REPEAT:
1322 rep = *(const WORD*)&pFormat[2];
1323 stride = *(const WORD*)&pFormat[4];
1324 ofs = *(const WORD*)&pFormat[6];
1325 count = *(const WORD*)&pFormat[8];
1329 case RPC_FC_VARIABLE_REPEAT:
1330 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1331 stride = *(const WORD*)&pFormat[2];
1332 ofs = *(const WORD*)&pFormat[4];
1333 count = *(const WORD*)&pFormat[6];
1334 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1338 /* ofs doesn't seem to matter in this context */
1339 for (i = 0; i < rep; i++) {
1340 PFORMAT_STRING info = pFormat;
1341 unsigned char *bufbase = Mark + (i * stride);
1343 for (u=0; u<count; u++,info+=8) {
1344 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1345 PointerMemorySize(pStubMsg, bufptr, info+4);
1348 pFormat += 8 * count;
1354 /***********************************************************************
1355 * EmbeddedPointerFree
1357 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1358 unsigned char *pMemory,
1359 PFORMAT_STRING pFormat)
1361 unsigned long Offset = pStubMsg->Offset;
1362 unsigned ofs, rep, count, stride, xofs;
1365 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1366 if (*pFormat != RPC_FC_PP) return;
1369 while (pFormat[0] != RPC_FC_END) {
1370 switch (pFormat[0]) {
1372 FIXME("unknown repeat type %d\n", pFormat[0]);
1373 case RPC_FC_NO_REPEAT:
1381 case RPC_FC_FIXED_REPEAT:
1382 rep = *(const WORD*)&pFormat[2];
1383 stride = *(const WORD*)&pFormat[4];
1384 ofs = *(const WORD*)&pFormat[6];
1385 count = *(const WORD*)&pFormat[8];
1389 case RPC_FC_VARIABLE_REPEAT:
1390 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1391 stride = *(const WORD*)&pFormat[2];
1392 ofs = *(const WORD*)&pFormat[4];
1393 count = *(const WORD*)&pFormat[6];
1394 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1398 /* ofs doesn't seem to matter in this context */
1399 for (i = 0; i < rep; i++) {
1400 PFORMAT_STRING info = pFormat;
1401 unsigned char *membase = pMemory + (i * stride);
1403 for (u=0; u<count; u++,info+=8) {
1404 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1405 unsigned char *saved_memory = pStubMsg->Memory;
1407 pStubMsg->Memory = pMemory;
1408 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1409 pStubMsg->Memory = saved_memory;
1412 pFormat += 8 * count;
1416 /***********************************************************************
1417 * NdrPointerMarshall [RPCRT4.@]
1419 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1420 unsigned char *pMemory,
1421 PFORMAT_STRING pFormat)
1423 unsigned char *Buffer;
1425 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1427 /* incremement the buffer here instead of in PointerMarshall,
1428 * as that is used by embedded pointers which already handle the incrementing
1429 * the buffer, and shouldn't write any additional pointer data to the wire */
1430 if (*pFormat != RPC_FC_RP)
1432 ALIGN_POINTER(pStubMsg->Buffer, 4);
1433 Buffer = pStubMsg->Buffer;
1434 pStubMsg->Buffer += 4;
1437 Buffer = pStubMsg->Buffer;
1439 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1441 STD_OVERFLOW_CHECK(pStubMsg);
1446 /***********************************************************************
1447 * NdrPointerUnmarshall [RPCRT4.@]
1449 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1450 unsigned char **ppMemory,
1451 PFORMAT_STRING pFormat,
1452 unsigned char fMustAlloc)
1454 unsigned char *Buffer;
1456 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1458 /* incremement the buffer here instead of in PointerUnmarshall,
1459 * as that is used by embedded pointers which already handle the incrementing
1460 * the buffer, and shouldn't read any additional pointer data from the
1462 if (*pFormat != RPC_FC_RP)
1464 ALIGN_POINTER(pStubMsg->Buffer, 4);
1465 Buffer = pStubMsg->Buffer;
1466 pStubMsg->Buffer += 4;
1469 Buffer = pStubMsg->Buffer;
1471 PointerUnmarshall(pStubMsg, Buffer, ppMemory, pFormat, fMustAlloc);
1476 /***********************************************************************
1477 * NdrPointerBufferSize [RPCRT4.@]
1479 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1480 unsigned char *pMemory,
1481 PFORMAT_STRING pFormat)
1483 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1485 /* incremement the buffer length here instead of in PointerBufferSize,
1486 * as that is used by embedded pointers which already handle the buffer
1487 * length, and shouldn't write anything more to the wire */
1488 if (*pFormat != RPC_FC_RP)
1490 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1491 pStubMsg->BufferLength += 4;
1494 PointerBufferSize(pStubMsg, pMemory, pFormat);
1497 /***********************************************************************
1498 * NdrPointerMemorySize [RPCRT4.@]
1500 unsigned long WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1501 PFORMAT_STRING pFormat)
1503 /* unsigned size = *(LPWORD)(pFormat+2); */
1504 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1505 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1509 /***********************************************************************
1510 * NdrPointerFree [RPCRT4.@]
1512 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1513 unsigned char *pMemory,
1514 PFORMAT_STRING pFormat)
1516 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1517 PointerFree(pStubMsg, pMemory, pFormat);
1520 /***********************************************************************
1521 * NdrSimpleTypeMarshall [RPCRT4.@]
1523 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1524 unsigned char FormatChar )
1529 /***********************************************************************
1530 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1532 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1533 unsigned char FormatChar )
1538 /***********************************************************************
1539 * NdrSimpleStructMarshall [RPCRT4.@]
1541 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1542 unsigned char *pMemory,
1543 PFORMAT_STRING pFormat)
1545 unsigned size = *(const WORD*)(pFormat+2);
1546 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1548 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1550 memcpy(pStubMsg->Buffer, pMemory, size);
1551 pStubMsg->BufferMark = pStubMsg->Buffer;
1552 pStubMsg->Buffer += size;
1554 if (pFormat[0] != RPC_FC_STRUCT)
1555 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1557 STD_OVERFLOW_CHECK(pStubMsg);
1562 /***********************************************************************
1563 * NdrSimpleStructUnmarshall [RPCRT4.@]
1565 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1566 unsigned char **ppMemory,
1567 PFORMAT_STRING pFormat,
1568 unsigned char fMustAlloc)
1570 unsigned size = *(const WORD*)(pFormat+2);
1571 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1573 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1576 *ppMemory = NdrAllocate(pStubMsg, size);
1577 memcpy(*ppMemory, pStubMsg->Buffer, size);
1579 if (!pStubMsg->IsClient && !*ppMemory)
1580 /* for servers, we just point straight into the RPC buffer */
1581 *ppMemory = pStubMsg->Buffer;
1583 /* for clients, memory should be provided by caller */
1584 memcpy(*ppMemory, pStubMsg->Buffer, size);
1587 pStubMsg->BufferMark = pStubMsg->Buffer;
1588 pStubMsg->Buffer += size;
1590 if (pFormat[0] != RPC_FC_STRUCT)
1591 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat+4, fMustAlloc);
1596 /***********************************************************************
1597 * NdrSimpleStructBufferSize [RPCRT4.@]
1599 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1600 unsigned char *pMemory,
1601 PFORMAT_STRING pFormat)
1603 unsigned size = *(const WORD*)(pFormat+2);
1604 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1606 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1608 pStubMsg->BufferLength += size;
1609 if (pFormat[0] != RPC_FC_STRUCT)
1610 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1613 /***********************************************************************
1614 * NdrSimpleStructMemorySize [RPCRT4.@]
1616 unsigned long WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1617 PFORMAT_STRING pFormat)
1619 unsigned short size = *(LPWORD)(pFormat+2);
1621 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1623 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1624 pStubMsg->MemorySize += size;
1625 pStubMsg->Buffer += size;
1627 if (pFormat[0] != RPC_FC_STRUCT)
1628 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1632 /***********************************************************************
1633 * NdrSimpleStructFree [RPCRT4.@]
1635 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1636 unsigned char *pMemory,
1637 PFORMAT_STRING pFormat)
1639 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1640 if (pFormat[0] != RPC_FC_STRUCT)
1641 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1645 static unsigned long EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg,
1646 PFORMAT_STRING pFormat)
1650 case RPC_FC_PSTRUCT:
1651 case RPC_FC_CSTRUCT:
1652 case RPC_FC_BOGUS_STRUCT:
1653 return *(const WORD*)&pFormat[2];
1654 case RPC_FC_USER_MARSHAL:
1655 return *(const WORD*)&pFormat[4];
1656 case RPC_FC_NON_ENCAPSULATED_UNION:
1658 if (pStubMsg->fHasNewCorrDesc)
1663 pFormat += *(const SHORT*)pFormat;
1664 return *(const SHORT*)pFormat;
1666 return sizeof(void *);
1668 FIXME("unhandled embedded type %02x\n", *pFormat);
1674 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1675 PFORMAT_STRING pFormat)
1677 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1681 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1685 return m(pStubMsg, pFormat);
1689 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1690 unsigned char *pMemory,
1691 PFORMAT_STRING pFormat,
1692 PFORMAT_STRING pPointer)
1694 PFORMAT_STRING desc;
1698 while (*pFormat != RPC_FC_END) {
1704 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
1705 memcpy(pStubMsg->Buffer, pMemory, 1);
1706 pStubMsg->Buffer += 1;
1712 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1713 memcpy(pStubMsg->Buffer, pMemory, 2);
1714 pStubMsg->Buffer += 2;
1720 TRACE("long=%ld <= %p\n", *(DWORD*)pMemory, pMemory);
1721 memcpy(pStubMsg->Buffer, pMemory, 4);
1722 pStubMsg->Buffer += 4;
1725 case RPC_FC_POINTER:
1726 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1727 NdrPointerMarshall(pStubMsg, *(unsigned char**)pMemory, pPointer);
1731 case RPC_FC_ALIGNM4:
1732 ALIGN_POINTER(pMemory, 4);
1734 case RPC_FC_ALIGNM8:
1735 ALIGN_POINTER(pMemory, 8);
1737 case RPC_FC_STRUCTPAD1:
1738 case RPC_FC_STRUCTPAD2:
1739 case RPC_FC_STRUCTPAD3:
1740 case RPC_FC_STRUCTPAD4:
1741 case RPC_FC_STRUCTPAD5:
1742 case RPC_FC_STRUCTPAD6:
1743 case RPC_FC_STRUCTPAD7:
1744 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1746 case RPC_FC_EMBEDDED_COMPLEX:
1747 pMemory += pFormat[1];
1749 desc = pFormat + *(const SHORT*)pFormat;
1750 size = EmbeddedComplexSize(pStubMsg, desc);
1751 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1752 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1753 if (m) m(pStubMsg, pMemory, desc);
1754 else FIXME("no marshaller for embedded type %02x\n", *desc);
1761 FIXME("unhandled format %02x\n", *pFormat);
1769 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1770 unsigned char *pMemory,
1771 PFORMAT_STRING pFormat,
1772 PFORMAT_STRING pPointer)
1774 PFORMAT_STRING desc;
1778 while (*pFormat != RPC_FC_END) {
1784 memcpy(pMemory, pStubMsg->Buffer, 1);
1785 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
1786 pStubMsg->Buffer += 1;
1792 memcpy(pMemory, pStubMsg->Buffer, 2);
1793 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1794 pStubMsg->Buffer += 2;
1800 memcpy(pMemory, pStubMsg->Buffer, 4);
1801 TRACE("long=%ld => %p\n", *(DWORD*)pMemory, pMemory);
1802 pStubMsg->Buffer += 4;
1805 case RPC_FC_POINTER:
1806 TRACE("pointer => %p\n", pMemory);
1807 NdrPointerUnmarshall(pStubMsg, (unsigned char**)pMemory, pPointer, TRUE);
1811 case RPC_FC_ALIGNM4:
1812 ALIGN_POINTER(pMemory, 4);
1814 case RPC_FC_ALIGNM8:
1815 ALIGN_POINTER(pMemory, 8);
1817 case RPC_FC_STRUCTPAD1:
1818 case RPC_FC_STRUCTPAD2:
1819 case RPC_FC_STRUCTPAD3:
1820 case RPC_FC_STRUCTPAD4:
1821 case RPC_FC_STRUCTPAD5:
1822 case RPC_FC_STRUCTPAD6:
1823 case RPC_FC_STRUCTPAD7:
1824 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1826 case RPC_FC_EMBEDDED_COMPLEX:
1827 pMemory += pFormat[1];
1829 desc = pFormat + *(const SHORT*)pFormat;
1830 size = EmbeddedComplexSize(pStubMsg, desc);
1831 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
1832 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1833 memset(pMemory, 0, size); /* just in case */
1834 if (m) m(pStubMsg, &pMemory, desc, FALSE);
1835 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
1842 FIXME("unhandled format %d\n", *pFormat);
1850 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1851 unsigned char *pMemory,
1852 PFORMAT_STRING pFormat,
1853 PFORMAT_STRING pPointer)
1855 PFORMAT_STRING desc;
1859 while (*pFormat != RPC_FC_END) {
1865 pStubMsg->BufferLength += 1;
1871 pStubMsg->BufferLength += 2;
1877 pStubMsg->BufferLength += 4;
1880 case RPC_FC_POINTER:
1881 NdrPointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
1885 case RPC_FC_ALIGNM4:
1886 ALIGN_POINTER(pMemory, 4);
1888 case RPC_FC_ALIGNM8:
1889 ALIGN_POINTER(pMemory, 8);
1891 case RPC_FC_STRUCTPAD1:
1892 case RPC_FC_STRUCTPAD2:
1893 case RPC_FC_STRUCTPAD3:
1894 case RPC_FC_STRUCTPAD4:
1895 case RPC_FC_STRUCTPAD5:
1896 case RPC_FC_STRUCTPAD6:
1897 case RPC_FC_STRUCTPAD7:
1898 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1900 case RPC_FC_EMBEDDED_COMPLEX:
1901 pMemory += pFormat[1];
1903 desc = pFormat + *(const SHORT*)pFormat;
1904 size = EmbeddedComplexSize(pStubMsg, desc);
1905 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1906 if (m) m(pStubMsg, pMemory, desc);
1907 else FIXME("no buffersizer for embedded type %02x\n", *desc);
1914 FIXME("unhandled format %d\n", *pFormat);
1922 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
1923 unsigned char *pMemory,
1924 PFORMAT_STRING pFormat,
1925 PFORMAT_STRING pPointer)
1927 PFORMAT_STRING desc;
1931 while (*pFormat != RPC_FC_END) {
1949 case RPC_FC_POINTER:
1950 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
1954 case RPC_FC_ALIGNM4:
1955 ALIGN_POINTER(pMemory, 4);
1957 case RPC_FC_ALIGNM8:
1958 ALIGN_POINTER(pMemory, 8);
1960 case RPC_FC_STRUCTPAD1:
1961 case RPC_FC_STRUCTPAD2:
1962 case RPC_FC_STRUCTPAD3:
1963 case RPC_FC_STRUCTPAD4:
1964 case RPC_FC_STRUCTPAD5:
1965 case RPC_FC_STRUCTPAD6:
1966 case RPC_FC_STRUCTPAD7:
1967 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1969 case RPC_FC_EMBEDDED_COMPLEX:
1970 pMemory += pFormat[1];
1972 desc = pFormat + *(const SHORT*)pFormat;
1973 size = EmbeddedComplexSize(pStubMsg, desc);
1974 m = NdrFreer[*desc & NDR_TABLE_MASK];
1975 if (m) m(pStubMsg, pMemory, desc);
1976 else FIXME("no freer for embedded type %02x\n", *desc);
1983 FIXME("unhandled format %d\n", *pFormat);
1991 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1992 PFORMAT_STRING pFormat)
1994 PFORMAT_STRING desc;
1995 unsigned long size = 0;
1997 while (*pFormat != RPC_FC_END) {
2004 pStubMsg->Buffer += 1;
2010 pStubMsg->Buffer += 2;
2016 pStubMsg->Buffer += 4;
2018 case RPC_FC_POINTER:
2020 pStubMsg->Buffer += 4;
2022 case RPC_FC_ALIGNM4:
2023 ALIGN_LENGTH(size, 4);
2024 ALIGN_POINTER(pStubMsg->Buffer, 4);
2026 case RPC_FC_ALIGNM8:
2027 ALIGN_LENGTH(size, 8);
2028 ALIGN_POINTER(pStubMsg->Buffer, 8);
2030 case RPC_FC_STRUCTPAD1:
2031 case RPC_FC_STRUCTPAD2:
2032 case RPC_FC_STRUCTPAD3:
2033 case RPC_FC_STRUCTPAD4:
2034 case RPC_FC_STRUCTPAD5:
2035 case RPC_FC_STRUCTPAD6:
2036 case RPC_FC_STRUCTPAD7:
2037 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2039 case RPC_FC_EMBEDDED_COMPLEX:
2042 desc = pFormat + *(const SHORT*)pFormat;
2043 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2049 FIXME("unhandled format %d\n", *pFormat);
2057 /***********************************************************************
2058 * NdrComplexStructMarshall [RPCRT4.@]
2060 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2061 unsigned char *pMemory,
2062 PFORMAT_STRING pFormat)
2064 PFORMAT_STRING conf_array = NULL;
2065 PFORMAT_STRING pointer_desc = NULL;
2066 unsigned char *OldMemory = pStubMsg->Memory;
2068 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2070 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2073 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2075 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2078 pStubMsg->Memory = pMemory;
2080 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2083 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2085 pStubMsg->Memory = OldMemory;
2087 STD_OVERFLOW_CHECK(pStubMsg);
2092 /***********************************************************************
2093 * NdrComplexStructUnmarshall [RPCRT4.@]
2095 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2096 unsigned char **ppMemory,
2097 PFORMAT_STRING pFormat,
2098 unsigned char fMustAlloc)
2100 unsigned size = *(const WORD*)(pFormat+2);
2101 PFORMAT_STRING conf_array = NULL;
2102 PFORMAT_STRING pointer_desc = NULL;
2103 unsigned char *pMemory;
2105 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2107 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2109 if (fMustAlloc || !*ppMemory)
2111 *ppMemory = NdrAllocate(pStubMsg, size);
2112 memset(*ppMemory, 0, size);
2116 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2118 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2121 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2124 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2129 /***********************************************************************
2130 * NdrComplexStructBufferSize [RPCRT4.@]
2132 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2133 unsigned char *pMemory,
2134 PFORMAT_STRING pFormat)
2136 PFORMAT_STRING conf_array = NULL;
2137 PFORMAT_STRING pointer_desc = NULL;
2138 unsigned char *OldMemory = pStubMsg->Memory;
2140 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2142 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2145 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2147 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2150 pStubMsg->Memory = pMemory;
2152 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2155 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2157 pStubMsg->Memory = OldMemory;
2160 /***********************************************************************
2161 * NdrComplexStructMemorySize [RPCRT4.@]
2163 unsigned long WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2164 PFORMAT_STRING pFormat)
2166 unsigned size = *(const WORD*)(pFormat+2);
2167 PFORMAT_STRING conf_array = NULL;
2168 PFORMAT_STRING pointer_desc = NULL;
2170 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2172 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2175 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2177 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2180 ComplexStructMemorySize(pStubMsg, pFormat);
2183 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2188 /***********************************************************************
2189 * NdrComplexStructFree [RPCRT4.@]
2191 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2192 unsigned char *pMemory,
2193 PFORMAT_STRING pFormat)
2195 PFORMAT_STRING conf_array = NULL;
2196 PFORMAT_STRING pointer_desc = NULL;
2197 unsigned char *OldMemory = pStubMsg->Memory;
2199 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2202 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2204 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2207 pStubMsg->Memory = pMemory;
2209 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2212 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2214 pStubMsg->Memory = OldMemory;
2217 /***********************************************************************
2218 * NdrConformantArrayMarshall [RPCRT4.@]
2220 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2221 unsigned char *pMemory,
2222 PFORMAT_STRING pFormat)
2224 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2225 unsigned char alignment = pFormat[1] + 1;
2227 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2228 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2230 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2232 WriteConformance(pStubMsg);
2234 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2236 size = safe_multiply(esize, pStubMsg->MaxCount);
2237 memcpy(pStubMsg->Buffer, pMemory, size);
2238 pStubMsg->BufferMark = pStubMsg->Buffer;
2239 pStubMsg->Buffer += size;
2241 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2243 STD_OVERFLOW_CHECK(pStubMsg);
2248 /***********************************************************************
2249 * NdrConformantArrayUnmarshall [RPCRT4.@]
2251 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2252 unsigned char **ppMemory,
2253 PFORMAT_STRING pFormat,
2254 unsigned char fMustAlloc)
2256 DWORD size, esize = *(const WORD*)(pFormat+2);
2257 unsigned char alignment = pFormat[1] + 1;
2259 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2260 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2262 pFormat = ReadConformance(pStubMsg, pFormat+4);
2264 size = safe_multiply(esize, pStubMsg->MaxCount);
2266 if (fMustAlloc || !*ppMemory)
2267 *ppMemory = NdrAllocate(pStubMsg, size);
2269 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2271 memcpy(*ppMemory, pStubMsg->Buffer, size);
2273 pStubMsg->BufferMark = pStubMsg->Buffer;
2274 pStubMsg->Buffer += size;
2276 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2281 /***********************************************************************
2282 * NdrConformantArrayBufferSize [RPCRT4.@]
2284 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2285 unsigned char *pMemory,
2286 PFORMAT_STRING pFormat)
2288 DWORD size, esize = *(const WORD*)(pFormat+2);
2289 unsigned char alignment = pFormat[1] + 1;
2291 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2292 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2294 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2296 SizeConformance(pStubMsg);
2298 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2300 size = safe_multiply(esize, pStubMsg->MaxCount);
2301 /* conformance value plus array */
2302 pStubMsg->BufferLength += size;
2304 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2307 /***********************************************************************
2308 * NdrConformantArrayMemorySize [RPCRT4.@]
2310 unsigned long WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2311 PFORMAT_STRING pFormat)
2313 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2314 unsigned char alignment = pFormat[1] + 1;
2316 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2317 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2319 pFormat = ReadConformance(pStubMsg, pFormat+4);
2320 size = safe_multiply(esize, pStubMsg->MaxCount);
2321 pStubMsg->MemorySize += size;
2323 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2324 pStubMsg->BufferMark = pStubMsg->Buffer;
2325 pStubMsg->Buffer += size;
2327 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2329 return pStubMsg->MemorySize;
2332 /***********************************************************************
2333 * NdrConformantArrayFree [RPCRT4.@]
2335 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2336 unsigned char *pMemory,
2337 PFORMAT_STRING pFormat)
2339 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2340 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2342 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2346 /***********************************************************************
2347 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2349 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2350 unsigned char* pMemory,
2351 PFORMAT_STRING pFormat )
2354 unsigned char alignment = pFormat[1] + 1;
2355 DWORD esize = *(const WORD*)(pFormat+2);
2357 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2359 if (pFormat[0] != RPC_FC_CVARRAY)
2361 ERR("invalid format type %x\n", pFormat[0]);
2362 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2366 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2367 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2369 WriteConformance(pStubMsg);
2370 WriteVariance(pStubMsg);
2372 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2374 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2376 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
2377 pStubMsg->BufferMark = pStubMsg->Buffer;
2378 pStubMsg->Buffer += bufsize;
2380 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2382 STD_OVERFLOW_CHECK(pStubMsg);
2388 /***********************************************************************
2389 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2391 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2392 unsigned char** ppMemory,
2393 PFORMAT_STRING pFormat,
2394 unsigned char fMustAlloc )
2396 ULONG bufsize, memsize;
2397 unsigned char alignment = pFormat[1] + 1;
2398 DWORD esize = *(const WORD*)(pFormat+2);
2400 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2402 if (pFormat[0] != RPC_FC_CVARRAY)
2404 ERR("invalid format type %x\n", pFormat[0]);
2405 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2409 pFormat = ReadConformance(pStubMsg, pFormat+4);
2410 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2412 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2414 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2415 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2417 if (!*ppMemory || fMustAlloc)
2418 *ppMemory = NdrAllocate(pStubMsg, memsize);
2419 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
2420 pStubMsg->Buffer += bufsize;
2422 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2428 /***********************************************************************
2429 * NdrConformantVaryingArrayFree [RPCRT4.@]
2431 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2432 unsigned char* pMemory,
2433 PFORMAT_STRING pFormat )
2435 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2437 if (pFormat[0] != RPC_FC_CVARRAY)
2439 ERR("invalid format type %x\n", pFormat[0]);
2440 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2444 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2445 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2447 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2451 /***********************************************************************
2452 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2454 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2455 unsigned char* pMemory, PFORMAT_STRING pFormat )
2457 unsigned char alignment = pFormat[1] + 1;
2458 DWORD esize = *(const WORD*)(pFormat+2);
2460 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2462 if (pFormat[0] != RPC_FC_CVARRAY)
2464 ERR("invalid format type %x\n", pFormat[0]);
2465 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2470 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2471 /* compute length */
2472 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2474 SizeConformance(pStubMsg);
2475 SizeVariance(pStubMsg);
2477 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2479 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
2481 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2485 /***********************************************************************
2486 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2488 unsigned long WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2489 PFORMAT_STRING pFormat )
2496 /***********************************************************************
2497 * NdrComplexArrayMarshall [RPCRT4.@]
2499 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2500 unsigned char *pMemory,
2501 PFORMAT_STRING pFormat)
2503 ULONG i, count, def;
2504 BOOL variance_present;
2505 unsigned char alignment;
2507 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2509 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2511 ERR("invalid format type %x\n", pFormat[0]);
2512 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2516 alignment = pFormat[1] + 1;
2518 def = *(const WORD*)&pFormat[2];
2521 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2522 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2524 variance_present = IsConformanceOrVariancePresent(pFormat);
2525 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2526 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2528 WriteConformance(pStubMsg);
2529 if (variance_present)
2530 WriteVariance(pStubMsg);
2532 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2534 count = pStubMsg->ActualCount;
2535 for (i = 0; i < count; i++)
2536 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2538 STD_OVERFLOW_CHECK(pStubMsg);
2543 /***********************************************************************
2544 * NdrComplexArrayUnmarshall [RPCRT4.@]
2546 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2547 unsigned char **ppMemory,
2548 PFORMAT_STRING pFormat,
2549 unsigned char fMustAlloc)
2551 ULONG i, count, esize, memsize;
2552 unsigned char alignment;
2553 unsigned char *pMemory;
2554 unsigned char *Buffer;
2556 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2558 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2560 ERR("invalid format type %x\n", pFormat[0]);
2561 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2565 alignment = pFormat[1] + 1;
2569 pFormat = ReadConformance(pStubMsg, pFormat);
2570 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2572 Buffer = pStubMsg->Buffer;
2573 pStubMsg->MemorySize = 0;
2574 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2575 pStubMsg->Buffer = Buffer;
2577 /* do multiply here instead of inside if block to verify MaxCount */
2578 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2579 if (fMustAlloc || !*ppMemory)
2581 *ppMemory = NdrAllocate(pStubMsg, memsize);
2582 memset(*ppMemory, 0, memsize);
2585 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2587 pMemory = *ppMemory;
2588 count = pStubMsg->ActualCount;
2589 for (i = 0; i < count; i++)
2590 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
2595 /***********************************************************************
2596 * NdrComplexArrayBufferSize [RPCRT4.@]
2598 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2599 unsigned char *pMemory,
2600 PFORMAT_STRING pFormat)
2602 ULONG i, count, def;
2603 unsigned char alignment;
2604 BOOL variance_present;
2606 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2608 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2610 ERR("invalid format type %x\n", pFormat[0]);
2611 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2615 alignment = pFormat[1] + 1;
2617 def = *(const WORD*)&pFormat[2];
2620 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2621 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2622 SizeConformance(pStubMsg);
2624 variance_present = IsConformanceOrVariancePresent(pFormat);
2625 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2626 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2628 if (variance_present)
2629 SizeVariance(pStubMsg);
2631 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2633 count = pStubMsg->ActualCount;
2634 for (i = 0; i < count; i++)
2635 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
2638 /***********************************************************************
2639 * NdrComplexArrayMemorySize [RPCRT4.@]
2641 unsigned long WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2642 PFORMAT_STRING pFormat)
2644 ULONG i, count, esize;
2645 unsigned char alignment;
2646 unsigned char *Buffer;
2647 unsigned long SavedMemorySize;
2648 unsigned long MemorySize;
2650 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2652 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2654 ERR("invalid format type %x\n", pFormat[0]);
2655 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2659 alignment = pFormat[1] + 1;
2663 pFormat = ReadConformance(pStubMsg, pFormat);
2664 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2666 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2668 SavedMemorySize = pStubMsg->MemorySize;
2670 Buffer = pStubMsg->Buffer;
2671 pStubMsg->MemorySize = 0;
2672 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2673 pStubMsg->Buffer = Buffer;
2675 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
2677 count = pStubMsg->ActualCount;
2678 for (i = 0; i < count; i++)
2679 ComplexStructMemorySize(pStubMsg, pFormat);
2681 pStubMsg->MemorySize = SavedMemorySize;
2683 pStubMsg->MemorySize += MemorySize;
2687 /***********************************************************************
2688 * NdrComplexArrayFree [RPCRT4.@]
2690 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2691 unsigned char *pMemory,
2692 PFORMAT_STRING pFormat)
2694 ULONG i, count, def;
2696 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2698 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2700 ERR("invalid format type %x\n", pFormat[0]);
2701 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2705 def = *(const WORD*)&pFormat[2];
2708 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2709 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2711 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2712 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2714 count = pStubMsg->ActualCount;
2715 for (i = 0; i < count; i++)
2716 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2719 static unsigned long UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
2721 return MAKELONG(pStubMsg->dwDestContext,
2722 pStubMsg->RpcMsg->DataRepresentation);
2725 #define USER_MARSHAL_PTR_PREFIX \
2726 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
2727 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
2729 /***********************************************************************
2730 * NdrUserMarshalMarshall [RPCRT4.@]
2732 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2733 unsigned char *pMemory,
2734 PFORMAT_STRING pFormat)
2736 unsigned flags = pFormat[1];
2737 unsigned index = *(const WORD*)&pFormat[2];
2738 unsigned long uflag = UserMarshalFlags(pStubMsg);
2739 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2740 TRACE("index=%d\n", index);
2742 if (flags & USER_MARSHAL_POINTER)
2744 ALIGN_POINTER(pStubMsg->Buffer, 4);
2745 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
2746 pStubMsg->Buffer += 4;
2747 ALIGN_POINTER(pStubMsg->Buffer, 8);
2750 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2753 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
2754 &uflag, pStubMsg->Buffer, pMemory);
2756 STD_OVERFLOW_CHECK(pStubMsg);
2761 /***********************************************************************
2762 * NdrUserMarshalUnmarshall [RPCRT4.@]
2764 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2765 unsigned char **ppMemory,
2766 PFORMAT_STRING pFormat,
2767 unsigned char fMustAlloc)
2769 unsigned flags = pFormat[1];
2770 unsigned index = *(const WORD*)&pFormat[2];
2771 DWORD memsize = *(const WORD*)&pFormat[4];
2772 unsigned long uflag = UserMarshalFlags(pStubMsg);
2773 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2774 TRACE("index=%d\n", index);
2776 if (flags & USER_MARSHAL_POINTER)
2778 ALIGN_POINTER(pStubMsg->Buffer, 4);
2779 /* skip pointer prefix */
2780 pStubMsg->Buffer += 4;
2781 ALIGN_POINTER(pStubMsg->Buffer, 8);
2784 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2786 if (fMustAlloc || !*ppMemory)
2787 *ppMemory = NdrAllocate(pStubMsg, memsize);
2790 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
2791 &uflag, pStubMsg->Buffer, *ppMemory);
2796 /***********************************************************************
2797 * NdrUserMarshalBufferSize [RPCRT4.@]
2799 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2800 unsigned char *pMemory,
2801 PFORMAT_STRING pFormat)
2803 unsigned flags = pFormat[1];
2804 unsigned index = *(const WORD*)&pFormat[2];
2805 DWORD bufsize = *(const WORD*)&pFormat[6];
2806 unsigned long uflag = UserMarshalFlags(pStubMsg);
2807 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2808 TRACE("index=%d\n", index);
2810 if (flags & USER_MARSHAL_POINTER)
2812 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2813 /* skip pointer prefix */
2814 pStubMsg->BufferLength += 4;
2815 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
2818 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
2821 TRACE("size=%ld\n", bufsize);
2822 pStubMsg->BufferLength += bufsize;
2826 pStubMsg->BufferLength =
2827 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
2828 &uflag, pStubMsg->BufferLength, pMemory);
2831 /***********************************************************************
2832 * NdrUserMarshalMemorySize [RPCRT4.@]
2834 unsigned long WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2835 PFORMAT_STRING pFormat)
2837 unsigned flags = pFormat[1];
2838 unsigned index = *(const WORD*)&pFormat[2];
2839 DWORD memsize = *(const WORD*)&pFormat[4];
2840 DWORD bufsize = *(const WORD*)&pFormat[6];
2842 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2843 TRACE("index=%d\n", index);
2845 pStubMsg->MemorySize += memsize;
2847 if (flags & USER_MARSHAL_POINTER)
2849 ALIGN_POINTER(pStubMsg->Buffer, 4);
2850 /* skip pointer prefix */
2851 pStubMsg->Buffer += 4;
2852 ALIGN_POINTER(pStubMsg->Buffer, 8);
2855 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2857 pStubMsg->Buffer += bufsize;
2859 return pStubMsg->MemorySize;
2862 /***********************************************************************
2863 * NdrUserMarshalFree [RPCRT4.@]
2865 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
2866 unsigned char *pMemory,
2867 PFORMAT_STRING pFormat)
2869 /* unsigned flags = pFormat[1]; */
2870 unsigned index = *(const WORD*)&pFormat[2];
2871 unsigned long uflag = UserMarshalFlags(pStubMsg);
2872 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2873 TRACE("index=%d\n", index);
2875 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
2879 /***********************************************************************
2880 * NdrClearOutParameters [RPCRT4.@]
2882 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
2883 PFORMAT_STRING pFormat,
2886 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
2889 /***********************************************************************
2890 * NdrConvert [RPCRT4.@]
2892 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
2894 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
2895 /* FIXME: since this stub doesn't do any converting, the proper behavior
2896 is to raise an exception */
2899 /***********************************************************************
2900 * NdrConvert2 [RPCRT4.@]
2902 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, long NumberParams )
2904 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %ld): stub.\n",
2905 pStubMsg, pFormat, NumberParams);
2906 /* FIXME: since this stub doesn't do any converting, the proper behavior
2907 is to raise an exception */
2910 typedef struct _NDR_CSTRUCT_FORMAT
2913 unsigned char alignment;
2914 unsigned short memory_size;
2915 short offset_to_array_description;
2916 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
2918 /***********************************************************************
2919 * NdrConformantStructMarshall [RPCRT4.@]
2921 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2922 unsigned char *pMemory,
2923 PFORMAT_STRING pFormat)
2925 const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
2926 PFORMAT_STRING pCArrayFormat;
2927 ULONG esize, bufsize;
2929 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2931 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2932 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2934 ERR("invalid format type %x\n", pCStructFormat->type);
2935 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2939 pCArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
2940 pCStructFormat->offset_to_array_description;
2941 if (*pCArrayFormat != RPC_FC_CARRAY)
2943 ERR("invalid array format type %x\n", pCStructFormat->type);
2944 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2947 esize = *(const WORD*)(pCArrayFormat+2);
2949 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
2950 pCArrayFormat + 4, 0);
2952 WriteConformance(pStubMsg);
2954 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
2956 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2958 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
2959 /* copy constant sized part of struct */
2960 pStubMsg->BufferMark = pStubMsg->Buffer;
2961 memcpy(pStubMsg->Buffer, pMemory, pCStructFormat->memory_size + bufsize);
2962 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
2964 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2965 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2967 STD_OVERFLOW_CHECK(pStubMsg);
2972 /***********************************************************************
2973 * NdrConformantStructUnmarshall [RPCRT4.@]
2975 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2976 unsigned char **ppMemory,
2977 PFORMAT_STRING pFormat,
2978 unsigned char fMustAlloc)
2980 const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
2981 PFORMAT_STRING pCArrayFormat;
2982 ULONG esize, bufsize;
2984 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2986 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2987 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2989 ERR("invalid format type %x\n", pCStructFormat->type);
2990 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2993 pCArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
2994 pCStructFormat->offset_to_array_description;
2995 if (*pCArrayFormat != RPC_FC_CARRAY)
2997 ERR("invalid array format type %x\n", pCStructFormat->type);
2998 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3001 esize = *(const WORD*)(pCArrayFormat+2);
3003 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3005 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3007 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3009 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3010 /* work out how much memory to allocate if we need to do so */
3011 if (!*ppMemory || fMustAlloc)
3013 SIZE_T size = pCStructFormat->memory_size + bufsize;
3014 *ppMemory = NdrAllocate(pStubMsg, size);
3017 /* now copy the data */
3018 pStubMsg->BufferMark = pStubMsg->Buffer;
3019 memcpy(*ppMemory, pStubMsg->Buffer, pCStructFormat->memory_size + bufsize);
3020 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
3022 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3023 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3028 /***********************************************************************
3029 * NdrConformantStructBufferSize [RPCRT4.@]
3031 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3032 unsigned char *pMemory,
3033 PFORMAT_STRING pFormat)
3035 const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
3036 PFORMAT_STRING pCArrayFormat;
3039 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3041 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3042 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3044 ERR("invalid format type %x\n", pCStructFormat->type);
3045 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3048 pCArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
3049 pCStructFormat->offset_to_array_description;
3050 if (*pCArrayFormat != RPC_FC_CARRAY)
3052 ERR("invalid array format type %x\n", pCStructFormat->type);
3053 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3056 esize = *(const WORD*)(pCArrayFormat+2);
3058 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
3059 SizeConformance(pStubMsg);
3061 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
3063 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3065 pStubMsg->BufferLength += pCStructFormat->memory_size +
3066 safe_multiply(pStubMsg->MaxCount, esize);
3068 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3069 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3072 /***********************************************************************
3073 * NdrConformantStructMemorySize [RPCRT4.@]
3075 unsigned long WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3076 PFORMAT_STRING pFormat)
3082 /***********************************************************************
3083 * NdrConformantStructFree [RPCRT4.@]
3085 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3086 unsigned char *pMemory,
3087 PFORMAT_STRING pFormat)
3092 /***********************************************************************
3093 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3095 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3096 unsigned char *pMemory,
3097 PFORMAT_STRING pFormat)
3099 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3100 PFORMAT_STRING pCVArrayFormat;
3101 ULONG esize, bufsize;
3103 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3105 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3106 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3108 ERR("invalid format type %x\n", pCVStructFormat->type);
3109 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3113 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3114 pCVStructFormat->offset_to_array_description;
3115 switch (*pCVArrayFormat)
3117 case RPC_FC_CVARRAY:
3118 esize = *(const WORD*)(pCVArrayFormat+2);
3120 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3121 pCVArrayFormat + 4, 0);
3122 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3125 case RPC_FC_C_CSTRING:
3126 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3127 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3128 esize = sizeof(char);
3129 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3130 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3131 pCVArrayFormat + 2, 0);
3133 pStubMsg->MaxCount = pStubMsg->ActualCount;
3135 case RPC_FC_C_WSTRING:
3136 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3137 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3138 esize = sizeof(WCHAR);
3139 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3140 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3141 pCVArrayFormat + 2, 0);
3143 pStubMsg->MaxCount = pStubMsg->ActualCount;
3146 ERR("invalid array format type %x\n", *pCVArrayFormat);
3147 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3151 WriteConformance(pStubMsg);
3153 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3155 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3157 /* write constant sized part */
3158 pStubMsg->BufferMark = pStubMsg->Buffer;
3159 memcpy(pStubMsg->Buffer, pMemory, pCVStructFormat->memory_size);
3160 pStubMsg->Buffer += pCVStructFormat->memory_size;
3162 WriteVariance(pStubMsg);
3164 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3166 /* write array part */
3167 memcpy(pStubMsg->Buffer, pMemory + pCVStructFormat->memory_size, bufsize);
3168 pStubMsg->Buffer += bufsize;
3170 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3172 STD_OVERFLOW_CHECK(pStubMsg);
3177 /***********************************************************************
3178 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3180 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3181 unsigned char **ppMemory,
3182 PFORMAT_STRING pFormat,
3183 unsigned char fMustAlloc)
3185 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3186 PFORMAT_STRING pCVArrayFormat;
3187 ULONG esize, bufsize;
3188 unsigned char cvarray_type;
3190 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3192 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3193 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3195 ERR("invalid format type %x\n", pCVStructFormat->type);
3196 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3200 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3201 pCVStructFormat->offset_to_array_description;
3202 cvarray_type = *pCVArrayFormat;
3203 switch (cvarray_type)
3205 case RPC_FC_CVARRAY:
3206 esize = *(const WORD*)(pCVArrayFormat+2);
3207 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3209 case RPC_FC_C_CSTRING:
3210 esize = sizeof(char);
3211 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3212 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3214 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3216 case RPC_FC_C_WSTRING:
3217 esize = sizeof(WCHAR);
3218 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3219 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3221 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3224 ERR("invalid array format type %x\n", *pCVArrayFormat);
3225 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3229 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3231 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3233 /* work out how much memory to allocate if we need to do so */
3234 if (!*ppMemory || fMustAlloc)
3236 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3237 *ppMemory = NdrAllocate(pStubMsg, size);
3240 /* copy the constant data */
3241 pStubMsg->BufferMark = pStubMsg->Buffer;
3242 memcpy(*ppMemory, pStubMsg->Buffer, pCVStructFormat->memory_size);
3243 pStubMsg->Buffer += pCVStructFormat->memory_size;
3245 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3247 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3249 if ((cvarray_type == RPC_FC_C_CSTRING) ||
3250 (cvarray_type == RPC_FC_C_WSTRING))
3253 /* strings must always have null terminating bytes */
3254 if (bufsize < esize)
3256 ERR("invalid string length of %ld\n", pStubMsg->ActualCount);
3257 RpcRaiseException(RPC_S_INVALID_BOUND);
3260 for (i = bufsize - esize; i < bufsize; i++)
3261 if (pStubMsg->Buffer[i] != 0)
3263 ERR("string not null-terminated at byte position %ld, data is 0x%x\n",
3264 i, pStubMsg->Buffer[i]);
3265 RpcRaiseException(RPC_S_INVALID_BOUND);
3270 /* copy the array data */
3271 memcpy(*ppMemory + pCVStructFormat->memory_size, pStubMsg->Buffer,
3273 pStubMsg->Buffer += bufsize;
3275 if (cvarray_type == RPC_FC_C_CSTRING)
3276 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3277 else if (cvarray_type == RPC_FC_C_WSTRING)
3278 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3280 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3285 /***********************************************************************
3286 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3288 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3289 unsigned char *pMemory,
3290 PFORMAT_STRING pFormat)
3292 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3293 PFORMAT_STRING pCVArrayFormat;
3296 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3298 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3299 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3301 ERR("invalid format type %x\n", pCVStructFormat->type);
3302 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3306 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3307 pCVStructFormat->offset_to_array_description;
3308 switch (*pCVArrayFormat)
3310 case RPC_FC_CVARRAY:
3311 esize = *(const WORD*)(pCVArrayFormat+2);
3313 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3314 pCVArrayFormat + 4, 0);
3315 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3318 case RPC_FC_C_CSTRING:
3319 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3320 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3321 esize = sizeof(char);
3322 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3323 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3324 pCVArrayFormat + 2, 0);
3326 pStubMsg->MaxCount = pStubMsg->ActualCount;
3328 case RPC_FC_C_WSTRING:
3329 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3330 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3331 esize = sizeof(WCHAR);
3332 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3333 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3334 pCVArrayFormat + 2, 0);
3336 pStubMsg->MaxCount = pStubMsg->ActualCount;
3339 ERR("invalid array format type %x\n", *pCVArrayFormat);
3340 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3344 SizeConformance(pStubMsg);
3346 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
3348 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3350 pStubMsg->BufferLength += pCVStructFormat->memory_size;
3351 SizeVariance(pStubMsg);
3352 pStubMsg->BufferLength += safe_multiply(pStubMsg->MaxCount, esize);
3354 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3357 /***********************************************************************
3358 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3360 unsigned long WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3361 PFORMAT_STRING pFormat)
3363 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3364 PFORMAT_STRING pCVArrayFormat;
3366 unsigned char cvarray_type;
3368 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3370 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3371 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3373 ERR("invalid format type %x\n", pCVStructFormat->type);
3374 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3378 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3379 pCVStructFormat->offset_to_array_description;
3380 cvarray_type = *pCVArrayFormat;
3381 switch (cvarray_type)
3383 case RPC_FC_CVARRAY:
3384 esize = *(const WORD*)(pCVArrayFormat+2);
3385 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3387 case RPC_FC_C_CSTRING:
3388 esize = sizeof(char);
3389 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3390 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3392 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3394 case RPC_FC_C_WSTRING:
3395 esize = sizeof(WCHAR);
3396 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3397 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3399 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3402 ERR("invalid array format type %x\n", *pCVArrayFormat);
3403 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3407 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3409 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3411 pStubMsg->Buffer += pCVStructFormat->memory_size;
3412 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3413 pStubMsg->Buffer += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->ActualCount);
3415 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3417 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3419 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3422 /***********************************************************************
3423 * NdrConformantVaryingStructFree [RPCRT4.@]
3425 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3426 unsigned char *pMemory,
3427 PFORMAT_STRING pFormat)
3429 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3430 PFORMAT_STRING pCVArrayFormat;
3433 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3435 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3436 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3438 ERR("invalid format type %x\n", pCVStructFormat->type);
3439 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3443 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3444 pCVStructFormat->offset_to_array_description;
3445 switch (*pCVArrayFormat)
3447 case RPC_FC_CVARRAY:
3448 esize = *(const WORD*)(pCVArrayFormat+2);
3450 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3451 pCVArrayFormat + 4, 0);
3452 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3455 case RPC_FC_C_CSTRING:
3456 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3457 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3458 esize = sizeof(char);
3459 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3460 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3461 pCVArrayFormat + 2, 0);
3463 pStubMsg->MaxCount = pStubMsg->ActualCount;
3465 case RPC_FC_C_WSTRING:
3466 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3467 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3468 esize = sizeof(WCHAR);
3469 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3470 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3471 pCVArrayFormat + 2, 0);
3473 pStubMsg->MaxCount = pStubMsg->ActualCount;
3476 ERR("invalid array format type %x\n", *pCVArrayFormat);
3477 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3481 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3483 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3489 unsigned char alignment;
3490 unsigned short total_size;
3491 } NDR_SMFARRAY_FORMAT;
3496 unsigned char alignment;
3497 unsigned long total_size;
3498 } NDR_LGFARRAY_FORMAT;
3500 /***********************************************************************
3501 * NdrFixedArrayMarshall [RPCRT4.@]
3503 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3504 unsigned char *pMemory,
3505 PFORMAT_STRING pFormat)
3507 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3508 unsigned long total_size;
3510 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3512 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3513 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3515 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3516 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3520 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3522 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3524 total_size = pSmFArrayFormat->total_size;
3525 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3529 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3530 total_size = pLgFArrayFormat->total_size;
3531 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3533 memcpy(pStubMsg->Buffer, pMemory, total_size);
3534 pStubMsg->Buffer += total_size;
3536 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3541 /***********************************************************************
3542 * NdrFixedArrayUnmarshall [RPCRT4.@]
3544 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3545 unsigned char **ppMemory,
3546 PFORMAT_STRING pFormat,
3547 unsigned char fMustAlloc)
3549 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3550 unsigned long total_size;
3552 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3554 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3555 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3557 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3558 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3562 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3564 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3566 total_size = pSmFArrayFormat->total_size;
3567 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3571 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3572 total_size = pLgFArrayFormat->total_size;
3573 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3576 if (fMustAlloc || !*ppMemory)
3577 *ppMemory = NdrAllocate(pStubMsg, total_size);
3578 memcpy(*ppMemory, pStubMsg->Buffer, total_size);
3579 pStubMsg->Buffer += total_size;
3581 pFormat = EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3586 /***********************************************************************
3587 * NdrFixedArrayBufferSize [RPCRT4.@]
3589 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3590 unsigned char *pMemory,
3591 PFORMAT_STRING pFormat)
3593 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3594 unsigned long total_size;
3596 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3598 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3599 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3601 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3602 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3606 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
3608 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3610 total_size = pSmFArrayFormat->total_size;
3611 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3615 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3616 total_size = pLgFArrayFormat->total_size;
3617 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3619 pStubMsg->BufferLength += total_size;
3621 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3624 /***********************************************************************
3625 * NdrFixedArrayMemorySize [RPCRT4.@]
3627 unsigned long WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3628 PFORMAT_STRING pFormat)
3630 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3631 unsigned long total_size;
3633 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3635 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3636 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3638 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3639 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3643 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3645 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3647 total_size = pSmFArrayFormat->total_size;
3648 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3652 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3653 total_size = pLgFArrayFormat->total_size;
3654 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3656 pStubMsg->Buffer += total_size;
3657 pStubMsg->MemorySize += total_size;
3659 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3664 /***********************************************************************
3665 * NdrFixedArrayFree [RPCRT4.@]
3667 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3668 unsigned char *pMemory,
3669 PFORMAT_STRING pFormat)
3671 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3673 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3675 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3676 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3678 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3679 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3683 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3684 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3687 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3688 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3691 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3694 /***********************************************************************
3695 * NdrVaryingArrayMarshall [RPCRT4.@]
3697 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3698 unsigned char *pMemory,
3699 PFORMAT_STRING pFormat)
3701 unsigned char alignment;
3702 DWORD elements, esize;
3705 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3707 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3708 (pFormat[0] != RPC_FC_LGVARRAY))
3710 ERR("invalid format type %x\n", pFormat[0]);
3711 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3715 alignment = pFormat[1] + 1;
3717 if (pFormat[0] == RPC_FC_SMVARRAY)
3720 pFormat += sizeof(WORD);
3721 elements = *(const WORD*)pFormat;
3722 pFormat += sizeof(WORD);
3727 pFormat += sizeof(DWORD);
3728 elements = *(const DWORD*)pFormat;
3729 pFormat += sizeof(DWORD);
3732 esize = *(const WORD*)pFormat;
3733 pFormat += sizeof(WORD);
3735 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3736 if ((pStubMsg->ActualCount > elements) ||
3737 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3739 RpcRaiseException(RPC_S_INVALID_BOUND);
3743 WriteVariance(pStubMsg);
3745 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3747 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3748 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
3749 pStubMsg->BufferMark = pStubMsg->Buffer;
3750 pStubMsg->Buffer += bufsize;
3752 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3754 STD_OVERFLOW_CHECK(pStubMsg);
3759 /***********************************************************************
3760 * NdrVaryingArrayUnmarshall [RPCRT4.@]
3762 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3763 unsigned char **ppMemory,
3764 PFORMAT_STRING pFormat,
3765 unsigned char fMustAlloc)
3767 unsigned char alignment;
3768 DWORD size, elements, esize;
3771 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3773 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3774 (pFormat[0] != RPC_FC_LGVARRAY))
3776 ERR("invalid format type %x\n", pFormat[0]);
3777 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3781 alignment = pFormat[1] + 1;
3783 if (pFormat[0] == RPC_FC_SMVARRAY)
3786 size = *(const WORD*)pFormat;
3787 pFormat += sizeof(WORD);
3788 elements = *(const WORD*)pFormat;
3789 pFormat += sizeof(WORD);
3794 size = *(const DWORD*)pFormat;
3795 pFormat += sizeof(DWORD);
3796 elements = *(const DWORD*)pFormat;
3797 pFormat += sizeof(DWORD);
3800 esize = *(const WORD*)pFormat;
3801 pFormat += sizeof(WORD);
3803 pFormat = ReadVariance(pStubMsg, pFormat, elements);
3805 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3807 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3809 if (!*ppMemory || fMustAlloc)
3810 *ppMemory = NdrAllocate(pStubMsg, size);
3811 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
3812 pStubMsg->Buffer += bufsize;
3814 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3819 /***********************************************************************
3820 * NdrVaryingArrayBufferSize [RPCRT4.@]
3822 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3823 unsigned char *pMemory,
3824 PFORMAT_STRING pFormat)
3826 unsigned char alignment;
3827 DWORD elements, esize;
3829 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3831 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3832 (pFormat[0] != RPC_FC_LGVARRAY))
3834 ERR("invalid format type %x\n", pFormat[0]);
3835 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3839 alignment = pFormat[1] + 1;
3841 if (pFormat[0] == RPC_FC_SMVARRAY)
3844 pFormat += sizeof(WORD);
3845 elements = *(const WORD*)pFormat;
3846 pFormat += sizeof(WORD);
3851 pFormat += sizeof(DWORD);
3852 elements = *(const DWORD*)pFormat;
3853 pFormat += sizeof(DWORD);
3856 esize = *(const WORD*)pFormat;
3857 pFormat += sizeof(WORD);
3859 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3860 if ((pStubMsg->ActualCount > elements) ||
3861 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3863 RpcRaiseException(RPC_S_INVALID_BOUND);
3867 SizeVariance(pStubMsg);
3869 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3871 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
3873 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3876 /***********************************************************************
3877 * NdrVaryingArrayMemorySize [RPCRT4.@]
3879 unsigned long WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3880 PFORMAT_STRING pFormat)
3882 unsigned char alignment;
3883 DWORD size, elements, esize;
3885 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3887 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3888 (pFormat[0] != RPC_FC_LGVARRAY))
3890 ERR("invalid format type %x\n", pFormat[0]);
3891 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3895 alignment = pFormat[1] + 1;
3897 if (pFormat[0] == RPC_FC_SMVARRAY)
3900 size = *(const WORD*)pFormat;
3901 pFormat += sizeof(WORD);
3902 elements = *(const WORD*)pFormat;
3903 pFormat += sizeof(WORD);
3908 size = *(const DWORD*)pFormat;
3909 pFormat += sizeof(DWORD);
3910 elements = *(const DWORD*)pFormat;
3911 pFormat += sizeof(DWORD);
3914 esize = *(const WORD*)pFormat;
3915 pFormat += sizeof(WORD);
3917 pFormat = ReadVariance(pStubMsg, pFormat, elements);
3919 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3921 pStubMsg->Buffer += safe_multiply(esize, pStubMsg->ActualCount);
3922 pStubMsg->MemorySize += size;
3924 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3926 return pStubMsg->MemorySize;
3929 /***********************************************************************
3930 * NdrVaryingArrayFree [RPCRT4.@]
3932 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3933 unsigned char *pMemory,
3934 PFORMAT_STRING pFormat)
3936 unsigned char alignment;
3939 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3941 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3942 (pFormat[0] != RPC_FC_LGVARRAY))
3944 ERR("invalid format type %x\n", pFormat[0]);
3945 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3949 alignment = pFormat[1] + 1;
3951 if (pFormat[0] == RPC_FC_SMVARRAY)
3954 pFormat += sizeof(WORD);
3955 elements = *(const WORD*)pFormat;
3956 pFormat += sizeof(WORD);
3961 pFormat += sizeof(DWORD);
3962 elements = *(const DWORD*)pFormat;
3963 pFormat += sizeof(DWORD);
3966 pFormat += sizeof(WORD);
3968 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3969 if ((pStubMsg->ActualCount > elements) ||
3970 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3972 RpcRaiseException(RPC_S_INVALID_BOUND);
3976 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3979 /***********************************************************************
3980 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
3982 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3983 unsigned char *pMemory,
3984 PFORMAT_STRING pFormat)
3990 /***********************************************************************
3991 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
3993 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3994 unsigned char **ppMemory,
3995 PFORMAT_STRING pFormat,
3996 unsigned char fMustAlloc)
4002 /***********************************************************************
4003 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4005 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4006 unsigned char *pMemory,
4007 PFORMAT_STRING pFormat)
4012 /***********************************************************************
4013 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4015 unsigned long WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4016 PFORMAT_STRING pFormat)
4022 /***********************************************************************
4023 * NdrEncapsulatedUnionFree [RPCRT4.@]
4025 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4026 unsigned char *pMemory,
4027 PFORMAT_STRING pFormat)
4032 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4033 unsigned long discriminant,
4034 PFORMAT_STRING pFormat)
4036 unsigned short num_arms, arm, type;
4038 num_arms = *(const SHORT*)pFormat & 0x0fff;
4040 for(arm = 0; arm < num_arms; arm++)
4042 if(discriminant == *(const ULONG*)pFormat)
4050 type = *(const unsigned short*)pFormat;
4051 TRACE("type %04x\n", type);
4052 if(arm == num_arms) /* default arm extras */
4056 ERR("no arm for 0x%lx and no default case\n", discriminant);
4057 RpcRaiseException(RPC_S_INVALID_TAG);
4062 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
4069 static PFORMAT_STRING get_non_encapsulated_union_arm(PMIDL_STUB_MESSAGE pStubMsg,
4071 PFORMAT_STRING pFormat)
4073 pFormat += *(const SHORT*)pFormat;
4076 return get_arm_offset_from_union_arm_selector(pStubMsg, value, pFormat);
4079 /***********************************************************************
4080 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
4082 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4083 unsigned char *pMemory,
4084 PFORMAT_STRING pFormat)
4086 unsigned short type;
4087 unsigned char switch_type;
4089 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4092 switch_type = *pFormat;
4095 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4096 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4097 /* Marshall discriminant */
4098 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4100 pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
4104 type = *(const unsigned short*)pFormat;
4105 if((type & 0xff00) == 0x8000)
4107 unsigned char basetype = LOBYTE(type);
4108 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
4112 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4113 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
4116 unsigned char *saved_buffer = NULL;
4123 saved_buffer = pStubMsg->Buffer;
4124 pStubMsg->Buffer += 4; /* for pointer ID */
4125 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
4128 m(pStubMsg, pMemory, desc);
4131 else FIXME("no marshaller for embedded type %02x\n", *desc);
4136 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
4137 PFORMAT_STRING *ppFormat)
4139 long discriminant = 0;
4147 discriminant = *(UCHAR *)pStubMsg->Buffer;
4148 pStubMsg->Buffer += sizeof(UCHAR);
4153 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4154 discriminant = *(USHORT *)pStubMsg->Buffer;
4155 pStubMsg->Buffer += sizeof(USHORT);
4159 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4160 discriminant = *(ULONG *)pStubMsg->Buffer;
4161 pStubMsg->Buffer += sizeof(ULONG);
4164 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
4168 if (pStubMsg->fHasNewCorrDesc)
4172 return discriminant;
4175 /**********************************************************************
4176 * NdrNonEncapsulatedUnionUnmarshall[RPCRT4.@]
4178 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4179 unsigned char **ppMemory,
4180 PFORMAT_STRING pFormat,
4181 unsigned char fMustAlloc)
4184 unsigned short type, size;
4186 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4189 /* Unmarshall discriminant */
4190 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4191 TRACE("unmarshalled discriminant %lx\n", discriminant);
4193 pFormat += *(const SHORT*)pFormat;
4195 size = *(const unsigned short*)pFormat;
4198 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4202 if(!*ppMemory || fMustAlloc)
4203 *ppMemory = NdrAllocate(pStubMsg, size);
4205 type = *(const unsigned short*)pFormat;
4206 if((type & 0xff00) == 0x8000)
4208 unsigned char basetype = LOBYTE(type);
4209 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, fMustAlloc);
4213 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4214 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
4217 unsigned char *saved_buffer = NULL;
4224 ALIGN_POINTER(pStubMsg->Buffer, 4);
4225 saved_buffer = pStubMsg->Buffer;
4226 pStubMsg->Buffer += 4; /* for pointer ID */
4227 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, desc, TRUE);
4230 m(pStubMsg, ppMemory, desc, fMustAlloc);
4233 else FIXME("no marshaller for embedded type %02x\n", *desc);
4238 /***********************************************************************
4239 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
4241 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4242 unsigned char *pMemory,
4243 PFORMAT_STRING pFormat)
4245 unsigned short type;
4246 unsigned char switch_type;
4248 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4251 switch_type = *pFormat;
4254 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4255 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4256 /* Add discriminant size */
4257 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4259 pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
4263 type = *(const unsigned short*)pFormat;
4264 if((type & 0xff00) == 0x8000)
4266 unsigned char basetype = LOBYTE(type);
4267 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
4271 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4272 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
4281 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4282 pStubMsg->BufferLength += 4; /* for pointer ID */
4283 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
4286 m(pStubMsg, pMemory, desc);
4289 else FIXME("no buffersizer for embedded type %02x\n", *desc);
4294 /***********************************************************************
4295 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
4297 unsigned long WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4298 PFORMAT_STRING pFormat)
4300 unsigned long discriminant;
4301 unsigned short type, size;
4304 /* Unmarshall discriminant */
4305 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4306 TRACE("unmarshalled discriminant 0x%lx\n", discriminant);
4308 pFormat += *(const SHORT*)pFormat;
4310 size = *(const unsigned short*)pFormat;
4313 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4317 pStubMsg->Memory += size;
4319 type = *(const unsigned short*)pFormat;
4320 if((type & 0xff00) == 0x8000)
4322 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
4326 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4327 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
4328 unsigned char *saved_buffer;
4337 ALIGN_POINTER(pStubMsg->Buffer, 4);
4338 saved_buffer = pStubMsg->Buffer;
4339 pStubMsg->Buffer += 4;
4340 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
4341 pStubMsg->MemorySize += 4;
4342 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
4345 return m(pStubMsg, desc);
4348 else FIXME("no marshaller for embedded type %02x\n", *desc);
4351 TRACE("size %d\n", size);
4355 /***********************************************************************
4356 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
4358 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4359 unsigned char *pMemory,
4360 PFORMAT_STRING pFormat)
4365 /***********************************************************************
4366 * NdrByteCountPointerMarshall [RPCRT4.@]
4368 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4369 unsigned char *pMemory,
4370 PFORMAT_STRING pFormat)
4376 /***********************************************************************
4377 * NdrByteCountPointerUnmarshall [RPCRT4.@]
4379 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4380 unsigned char **ppMemory,
4381 PFORMAT_STRING pFormat,
4382 unsigned char fMustAlloc)
4388 /***********************************************************************
4389 * NdrByteCountPointerBufferSize [RPCRT4.@]
4391 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4392 unsigned char *pMemory,
4393 PFORMAT_STRING pFormat)
4398 /***********************************************************************
4399 * NdrByteCountPointerMemorySize [RPCRT4.@]
4401 unsigned long WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4402 PFORMAT_STRING pFormat)
4408 /***********************************************************************
4409 * NdrByteCountPointerFree [RPCRT4.@]
4411 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
4412 unsigned char *pMemory,
4413 PFORMAT_STRING pFormat)
4418 /***********************************************************************
4419 * NdrXmitOrRepAsMarshall [RPCRT4.@]
4421 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4422 unsigned char *pMemory,
4423 PFORMAT_STRING pFormat)
4429 /***********************************************************************
4430 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
4432 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4433 unsigned char **ppMemory,
4434 PFORMAT_STRING pFormat,
4435 unsigned char fMustAlloc)
4441 /***********************************************************************
4442 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
4444 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4445 unsigned char *pMemory,
4446 PFORMAT_STRING pFormat)
4451 /***********************************************************************
4452 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
4454 unsigned long WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4455 PFORMAT_STRING pFormat)
4461 /***********************************************************************
4462 * NdrXmitOrRepAsFree [RPCRT4.@]
4464 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
4465 unsigned char *pMemory,
4466 PFORMAT_STRING pFormat)
4471 /***********************************************************************
4472 * NdrBaseTypeMarshall [internal]
4474 static unsigned char *WINAPI NdrBaseTypeMarshall(
4475 PMIDL_STUB_MESSAGE pStubMsg,
4476 unsigned char *pMemory,
4477 PFORMAT_STRING pFormat)
4479 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4487 *(UCHAR *)pStubMsg->Buffer = *(UCHAR *)pMemory;
4488 pStubMsg->Buffer += sizeof(UCHAR);
4489 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
4494 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4495 *(USHORT *)pStubMsg->Buffer = *(USHORT *)pMemory;
4496 pStubMsg->Buffer += sizeof(USHORT);
4497 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
4501 case RPC_FC_ERROR_STATUS_T:
4503 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4504 *(ULONG *)pStubMsg->Buffer = *(ULONG *)pMemory;
4505 pStubMsg->Buffer += sizeof(ULONG);
4506 TRACE("value: 0x%08lx\n", *(ULONG *)pMemory);
4509 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
4510 *(float *)pStubMsg->Buffer = *(float *)pMemory;
4511 pStubMsg->Buffer += sizeof(float);
4514 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
4515 *(double *)pStubMsg->Buffer = *(double *)pMemory;
4516 pStubMsg->Buffer += sizeof(double);
4519 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
4520 *(ULONGLONG *)pStubMsg->Buffer = *(ULONGLONG *)pMemory;
4521 pStubMsg->Buffer += sizeof(ULONGLONG);
4522 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
4525 /* only 16-bits on the wire, so do a sanity check */
4526 if (*(UINT *)pMemory > USHRT_MAX)
4527 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
4528 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4529 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
4530 pStubMsg->Buffer += sizeof(USHORT);
4531 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
4534 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4537 STD_OVERFLOW_CHECK(pStubMsg);
4539 /* FIXME: what is the correct return value? */
4543 /***********************************************************************
4544 * NdrBaseTypeUnmarshall [internal]
4546 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
4547 PMIDL_STUB_MESSAGE pStubMsg,
4548 unsigned char **ppMemory,
4549 PFORMAT_STRING pFormat,
4550 unsigned char fMustAlloc)
4552 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
4554 #define BASE_TYPE_UNMARSHALL(type) \
4555 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
4556 if (fMustAlloc || !*ppMemory) \
4557 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
4558 TRACE("*ppMemory: %p\n", *ppMemory); \
4559 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
4560 pStubMsg->Buffer += sizeof(type);
4568 BASE_TYPE_UNMARSHALL(UCHAR);
4569 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
4574 BASE_TYPE_UNMARSHALL(USHORT);
4575 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
4579 case RPC_FC_ERROR_STATUS_T:
4581 BASE_TYPE_UNMARSHALL(ULONG);
4582 TRACE("value: 0x%08lx\n", **(ULONG **)ppMemory);
4585 BASE_TYPE_UNMARSHALL(float);
4586 TRACE("value: %f\n", **(float **)ppMemory);
4589 BASE_TYPE_UNMARSHALL(double);
4590 TRACE("value: %f\n", **(double **)ppMemory);
4593 BASE_TYPE_UNMARSHALL(ULONGLONG);
4594 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
4597 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4598 if (fMustAlloc || !*ppMemory)
4599 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
4600 TRACE("*ppMemory: %p\n", *ppMemory);
4601 /* 16-bits on the wire, but int in memory */
4602 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
4603 pStubMsg->Buffer += sizeof(USHORT);
4604 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
4607 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4609 #undef BASE_TYPE_UNMARSHALL
4611 /* FIXME: what is the correct return value? */
4616 /***********************************************************************
4617 * NdrBaseTypeBufferSize [internal]
4619 static void WINAPI NdrBaseTypeBufferSize(
4620 PMIDL_STUB_MESSAGE pStubMsg,
4621 unsigned char *pMemory,
4622 PFORMAT_STRING pFormat)
4624 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4632 pStubMsg->BufferLength += sizeof(UCHAR);
4638 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
4639 pStubMsg->BufferLength += sizeof(USHORT);
4644 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
4645 pStubMsg->BufferLength += sizeof(ULONG);
4648 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
4649 pStubMsg->BufferLength += sizeof(float);
4652 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
4653 pStubMsg->BufferLength += sizeof(double);
4656 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
4657 pStubMsg->BufferLength += sizeof(ULONGLONG);
4659 case RPC_FC_ERROR_STATUS_T:
4660 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
4661 pStubMsg->BufferLength += sizeof(error_status_t);
4664 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4668 /***********************************************************************
4669 * NdrBaseTypeMemorySize [internal]
4671 static unsigned long WINAPI NdrBaseTypeMemorySize(
4672 PMIDL_STUB_MESSAGE pStubMsg,
4673 PFORMAT_STRING pFormat)
4681 pStubMsg->Buffer += sizeof(UCHAR);
4682 pStubMsg->MemorySize += sizeof(UCHAR);
4683 return sizeof(UCHAR);
4687 pStubMsg->Buffer += sizeof(USHORT);
4688 pStubMsg->MemorySize += sizeof(USHORT);
4689 return sizeof(USHORT);
4692 pStubMsg->Buffer += sizeof(ULONG);
4693 pStubMsg->MemorySize += sizeof(ULONG);
4694 return sizeof(ULONG);
4696 pStubMsg->Buffer += sizeof(float);
4697 pStubMsg->MemorySize += sizeof(float);
4698 return sizeof(float);
4700 pStubMsg->Buffer += sizeof(double);
4701 pStubMsg->MemorySize += sizeof(double);
4702 return sizeof(double);
4704 pStubMsg->Buffer += sizeof(ULONGLONG);
4705 pStubMsg->MemorySize += sizeof(ULONGLONG);
4706 return sizeof(ULONGLONG);
4707 case RPC_FC_ERROR_STATUS_T:
4708 pStubMsg->Buffer += sizeof(error_status_t);
4709 pStubMsg->MemorySize += sizeof(error_status_t);
4710 return sizeof(error_status_t);
4713 pStubMsg->Buffer += sizeof(INT);
4714 pStubMsg->MemorySize += sizeof(INT);
4717 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4722 /***********************************************************************
4723 * NdrBaseTypeFree [internal]
4725 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
4726 unsigned char *pMemory,
4727 PFORMAT_STRING pFormat)
4729 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4734 /***********************************************************************
4735 * NdrClientContextMarshall
4737 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4738 NDR_CCONTEXT ContextHandle,
4741 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
4743 ALIGN_POINTER(pStubMsg->Buffer, 4);
4745 /* FIXME: what does fCheck do? */
4746 NDRCContextMarshall(ContextHandle,
4749 pStubMsg->Buffer += cbNDRContext;
4752 /***********************************************************************
4753 * NdrClientContextUnmarshall
4755 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4756 NDR_CCONTEXT * pContextHandle,
4757 RPC_BINDING_HANDLE BindHandle)
4759 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
4761 ALIGN_POINTER(pStubMsg->Buffer, 4);
4763 NDRCContextUnmarshall(pContextHandle,
4766 pStubMsg->RpcMsg->DataRepresentation);
4768 pStubMsg->Buffer += cbNDRContext;
4771 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4772 NDR_SCONTEXT ContextHandle,
4773 NDR_RUNDOWN RundownRoutine )
4775 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
4778 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
4780 FIXME("(%p): stub\n", pStubMsg);
4784 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
4785 unsigned char* pMemory,
4786 PFORMAT_STRING pFormat)
4788 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
4791 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
4792 PFORMAT_STRING pFormat)
4794 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
4798 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4799 NDR_SCONTEXT ContextHandle,
4800 NDR_RUNDOWN RundownRoutine,
4801 PFORMAT_STRING pFormat)
4803 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
4806 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4807 PFORMAT_STRING pFormat)
4809 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
4813 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
4815 typedef struct ndr_context_handle
4819 } ndr_context_handle;
4821 struct context_handle_entry
4825 RPC_BINDING_HANDLE handle;
4826 ndr_context_handle wire_data;
4829 static struct list context_handle_list = LIST_INIT(context_handle_list);
4831 static CRITICAL_SECTION ndr_context_cs;
4832 static CRITICAL_SECTION_DEBUG ndr_context_debug =
4834 0, 0, &ndr_context_cs,
4835 { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
4836 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
4838 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
4840 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
4842 struct context_handle_entry *che = (struct context_handle_entry*) CContext;
4844 if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
4849 static struct context_handle_entry *context_entry_from_guid(LPGUID uuid)
4851 struct context_handle_entry *che;
4852 LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
4853 if (IsEqualGUID(&che->wire_data.uuid, uuid))
4858 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
4860 struct context_handle_entry *che;
4861 RPC_BINDING_HANDLE handle = NULL;
4863 TRACE("%p\n", CContext);
4865 EnterCriticalSection(&ndr_context_cs);
4866 che = get_context_entry(CContext);
4868 handle = che->handle;
4869 LeaveCriticalSection(&ndr_context_cs);
4872 RpcRaiseException(ERROR_INVALID_HANDLE);
4876 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
4878 struct context_handle_entry *che;
4880 TRACE("%p %p\n", CContext, pBuff);
4884 EnterCriticalSection(&ndr_context_cs);
4885 che = get_context_entry(CContext);
4886 memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
4887 LeaveCriticalSection(&ndr_context_cs);
4891 ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
4892 wire_data->attributes = 0;
4893 wire_data->uuid = GUID_NULL;
4897 static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
4898 RPC_BINDING_HANDLE hBinding,
4899 ndr_context_handle *chi)
4901 struct context_handle_entry *che = NULL;
4903 /* a null UUID means we should free the context handle */
4904 if (IsEqualGUID(&chi->uuid, &GUID_NULL))
4908 che = get_context_entry(*CContext);
4910 return ERROR_INVALID_HANDLE;
4911 list_remove(&che->entry);
4912 RpcBindingFree(&che->handle);
4913 HeapFree(GetProcessHeap(), 0, che);
4917 /* if there's no existing entry matching the GUID, allocate one */
4918 else if (!(che = context_entry_from_guid(&chi->uuid)))
4920 che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
4922 return ERROR_NOT_ENOUGH_MEMORY;
4923 che->magic = NDR_CONTEXT_HANDLE_MAGIC;
4924 RpcBindingCopy(hBinding, &che->handle);
4925 list_add_tail(&context_handle_list, &che->entry);
4926 memcpy(&che->wire_data, chi, sizeof *chi);
4931 return ERROR_SUCCESS;
4934 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
4935 RPC_BINDING_HANDLE hBinding,
4937 unsigned long DataRepresentation)
4941 TRACE("*%p=(%p) %p %p %08lx\n",
4942 CContext, *CContext, hBinding, pBuff, DataRepresentation);
4944 EnterCriticalSection(&ndr_context_cs);
4945 r = ndr_update_context_handle(CContext, hBinding, pBuff);
4946 LeaveCriticalSection(&ndr_context_cs);
4948 RpcRaiseException(r);
4951 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
4953 NDR_RUNDOWN userRunDownIn)
4955 FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn);
4958 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
4959 NDR_SCONTEXT CContext,
4961 NDR_RUNDOWN userRunDownIn)
4963 FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn);
4966 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
4967 NDR_SCONTEXT CContext,
4969 NDR_RUNDOWN userRunDownIn,
4971 unsigned long Flags)
4973 FIXME("(%p %p %p %p %p %lu): stub\n",
4974 hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags);
4977 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
4978 unsigned long DataRepresentation)
4980 FIXME("(%p %08lx): stub\n", pBuff, DataRepresentation);
4984 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
4986 unsigned long DataRepresentation)
4988 FIXME("(%p %p %08lx): stub\n", hBinding, pBuff, DataRepresentation);
4992 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
4994 unsigned long DataRepresentation,
4996 unsigned long Flags)
4998 FIXME("(%p %p %08lx %p %lu): stub\n",
4999 hBinding, pBuff, DataRepresentation, CtxGuard, Flags);