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 = *(const short *)&pFormat[2];
409 if (!IsConformanceOrVariancePresent(pFormat)) {
410 /* null descriptor */
415 switch (pFormat[0] & 0xf0) {
416 case RPC_FC_NORMAL_CONFORMANCE:
417 TRACE("normal conformance, ofs=%d\n", ofs);
420 case RPC_FC_POINTER_CONFORMANCE:
421 TRACE("pointer conformance, ofs=%d\n", ofs);
422 ptr = pStubMsg->Memory;
424 case RPC_FC_TOP_LEVEL_CONFORMANCE:
425 TRACE("toplevel conformance, ofs=%d\n", ofs);
426 if (pStubMsg->StackTop) {
427 ptr = pStubMsg->StackTop;
430 /* -Os mode, *pCount is already set */
434 case RPC_FC_CONSTANT_CONFORMANCE:
435 data = ofs | ((DWORD)pFormat[1] << 16);
436 TRACE("constant conformance, val=%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 FIXME("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
655 assert(pStubMsg && pFormat);
657 if (*pFormat == RPC_FC_C_CSTRING) {
658 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
660 else if (*pFormat == RPC_FC_C_WSTRING) {
661 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
664 ERR("Unhandled string type: %#x\n", *pFormat);
665 /* FIXME: raise an exception */
668 if (pFormat[1] != RPC_FC_PAD) {
669 FIXME("sized string format=%d\n", pFormat[1]);
672 TRACE(" --> %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 bufsize, memsize, esize, i;
684 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
685 pStubMsg, *ppMemory, pFormat, fMustAlloc);
687 assert(pFormat && ppMemory && pStubMsg);
689 ReadConformance(pStubMsg, NULL);
690 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
692 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
693 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
695 ERR("Unhandled string type: %#x\n", *pFormat);
696 /* FIXME: raise an exception */
700 memsize = safe_multiply(esize, pStubMsg->MaxCount);
701 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
703 /* strings must always have null terminating bytes */
706 ERR("invalid string length of %ld\n", pStubMsg->ActualCount);
707 RpcRaiseException(RPC_S_INVALID_BOUND);
710 for (i = bufsize - esize; i < bufsize; i++)
711 if (pStubMsg->Buffer[i] != 0)
713 ERR("string not null-terminated at byte position %ld, data is 0x%x\n",
714 i, pStubMsg->Buffer[i]);
715 RpcRaiseException(RPC_S_INVALID_BOUND);
719 if (fMustAlloc || !*ppMemory)
720 *ppMemory = NdrAllocate(pStubMsg, memsize);
722 memcpy(*ppMemory, pStubMsg->Buffer, bufsize);
724 pStubMsg->Buffer += bufsize;
726 if (*pFormat == RPC_FC_C_CSTRING) {
727 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
729 else if (*pFormat == RPC_FC_C_WSTRING) {
730 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
733 return NULL; /* FIXME: is this always right? */
736 /***********************************************************************
737 * NdrNonConformantStringMarshall [RPCRT4.@]
739 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
740 unsigned char *pMemory,
741 PFORMAT_STRING pFormat)
747 /***********************************************************************
748 * NdrNonConformantStringUnmarshall [RPCRT4.@]
750 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
751 unsigned char **ppMemory,
752 PFORMAT_STRING pFormat,
753 unsigned char fMustAlloc)
759 /***********************************************************************
760 * NdrNonConformantStringBufferSize [RPCRT4.@]
762 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
763 unsigned char *pMemory,
764 PFORMAT_STRING pFormat)
769 /***********************************************************************
770 * NdrNonConformantStringMemorySize [RPCRT4.@]
772 unsigned long WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
773 PFORMAT_STRING pFormat)
779 static inline void dump_pointer_attr(unsigned char attr)
781 if (attr & RPC_FC_P_ALLOCALLNODES)
782 TRACE(" RPC_FC_P_ALLOCALLNODES");
783 if (attr & RPC_FC_P_DONTFREE)
784 TRACE(" RPC_FC_P_DONTFREE");
785 if (attr & RPC_FC_P_ONSTACK)
786 TRACE(" RPC_FC_P_ONSTACK");
787 if (attr & RPC_FC_P_SIMPLEPOINTER)
788 TRACE(" RPC_FC_P_SIMPLEPOINTER");
789 if (attr & RPC_FC_P_DEREF)
790 TRACE(" RPC_FC_P_DEREF");
794 /***********************************************************************
797 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
798 unsigned char *Buffer,
799 unsigned char *Pointer,
800 PFORMAT_STRING pFormat)
802 unsigned type = pFormat[0], attr = pFormat[1];
805 unsigned long pointer_id;
806 int pointer_needs_marshaling;
808 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
809 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
811 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
812 else desc = pFormat + *(const SHORT*)pFormat;
815 case RPC_FC_RP: /* ref pointer (always non-null) */
816 #if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
818 RpcRaiseException(RPC_X_NULL_REF_POINTER);
820 pointer_needs_marshaling = 1;
822 case RPC_FC_UP: /* unique pointer */
823 case RPC_FC_OP: /* object pointer - same as unique here */
825 pointer_needs_marshaling = 1;
827 pointer_needs_marshaling = 0;
828 pointer_id = (unsigned long)Pointer;
829 TRACE("writing 0x%08lx to buffer\n", pointer_id);
830 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
833 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
834 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
835 TRACE("writing 0x%08lx to buffer\n", pointer_id);
836 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
839 FIXME("unhandled ptr type=%02x\n", type);
840 RpcRaiseException(RPC_X_BAD_STUB_DATA);
844 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
846 if (pointer_needs_marshaling) {
847 if (attr & RPC_FC_P_DEREF) {
848 Pointer = *(unsigned char**)Pointer;
849 TRACE("deref => %p\n", Pointer);
851 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
852 if (m) m(pStubMsg, Pointer, desc);
853 else FIXME("no marshaller for data type=%02x\n", *desc);
856 STD_OVERFLOW_CHECK(pStubMsg);
859 /***********************************************************************
862 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
863 unsigned char *Buffer,
864 unsigned char **pPointer,
865 PFORMAT_STRING pFormat,
866 unsigned char fMustAlloc)
868 unsigned type = pFormat[0], attr = pFormat[1];
871 DWORD pointer_id = 0;
872 int pointer_needs_unmarshaling;
874 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pFormat, fMustAlloc);
875 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
877 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
878 else desc = pFormat + *(const SHORT*)pFormat;
881 case RPC_FC_RP: /* ref pointer (always non-null) */
882 pointer_needs_unmarshaling = 1;
884 case RPC_FC_UP: /* unique pointer */
885 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
886 TRACE("pointer_id is 0x%08lx\n", pointer_id);
888 pointer_needs_unmarshaling = 1;
891 pointer_needs_unmarshaling = 0;
894 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
895 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
896 TRACE("pointer_id is 0x%08lx\n", pointer_id);
897 if (!fMustAlloc && *pPointer)
899 FIXME("free object pointer %p\n", *pPointer);
903 pointer_needs_unmarshaling = 1;
905 pointer_needs_unmarshaling = 0;
908 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
909 TRACE("pointer_id is 0x%08lx\n", pointer_id);
910 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
911 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
914 FIXME("unhandled ptr type=%02x\n", type);
915 RpcRaiseException(RPC_X_BAD_STUB_DATA);
919 if (pointer_needs_unmarshaling) {
920 if (attr & RPC_FC_P_DEREF) {
921 if (!*pPointer || fMustAlloc)
922 *pPointer = NdrAllocate(pStubMsg, sizeof(void *));
923 pPointer = *(unsigned char***)pPointer;
924 TRACE("deref => %p\n", pPointer);
926 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
927 if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
928 else FIXME("no unmarshaller for data type=%02x\n", *desc);
930 if (type == RPC_FC_FP)
931 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
935 TRACE("pointer=%p\n", *pPointer);
938 /***********************************************************************
941 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
942 unsigned char *Pointer,
943 PFORMAT_STRING pFormat)
945 unsigned type = pFormat[0], attr = pFormat[1];
948 int pointer_needs_sizing;
949 unsigned long pointer_id;
951 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
952 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
954 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
955 else desc = pFormat + *(const SHORT*)pFormat;
958 case RPC_FC_RP: /* ref pointer (always non-null) */
962 /* NULL pointer has no further representation */
967 pointer_needs_sizing = !NdrFullPointerQueryPointer(
968 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
969 if (!pointer_needs_sizing)
973 FIXME("unhandled ptr type=%02x\n", type);
974 RpcRaiseException(RPC_X_BAD_STUB_DATA);
978 if (attr & RPC_FC_P_DEREF) {
979 Pointer = *(unsigned char**)Pointer;
980 TRACE("deref => %p\n", Pointer);
983 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
984 if (m) m(pStubMsg, Pointer, desc);
985 else FIXME("no buffersizer for data type=%02x\n", *desc);
988 /***********************************************************************
989 * PointerMemorySize [RPCRT4.@]
991 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
992 unsigned char *Buffer,
993 PFORMAT_STRING pFormat)
995 unsigned type = pFormat[0], attr = pFormat[1];
999 FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat);
1000 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1002 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1003 else desc = pFormat + *(const SHORT*)pFormat;
1006 case RPC_FC_RP: /* ref pointer (always non-null) */
1009 FIXME("unhandled ptr type=%02x\n", type);
1010 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1013 if (attr & RPC_FC_P_DEREF) {
1017 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1018 if (m) m(pStubMsg, desc);
1019 else FIXME("no memorysizer for data type=%02x\n", *desc);
1024 /***********************************************************************
1025 * PointerFree [RPCRT4.@]
1027 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1028 unsigned char *Pointer,
1029 PFORMAT_STRING pFormat)
1031 unsigned type = pFormat[0], attr = pFormat[1];
1032 PFORMAT_STRING desc;
1035 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1036 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1037 if (attr & RPC_FC_P_DONTFREE) return;
1039 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1040 else desc = pFormat + *(const SHORT*)pFormat;
1042 if (!Pointer) return;
1044 if (type == RPC_FC_FP) {
1045 int pointer_needs_freeing = NdrFullPointerFree(
1046 pStubMsg->FullPtrXlatTables, Pointer);
1047 if (!pointer_needs_freeing)
1051 if (attr & RPC_FC_P_DEREF) {
1052 Pointer = *(unsigned char**)Pointer;
1053 TRACE("deref => %p\n", Pointer);
1056 m = NdrFreer[*desc & NDR_TABLE_MASK];
1057 if (m) m(pStubMsg, Pointer, desc);
1059 /* hmm... is this sensible?
1060 * perhaps we should check if the memory comes from NdrAllocate,
1061 * and deallocate only if so - checking if the pointer is between
1062 * BufferStart and BufferEnd is probably no good since the buffer
1063 * may be reallocated when the server wants to marshal the reply */
1065 case RPC_FC_BOGUS_STRUCT:
1066 case RPC_FC_BOGUS_ARRAY:
1067 case RPC_FC_USER_MARSHAL:
1069 case RPC_FC_CVARRAY:
1072 FIXME("unhandled data type=%02x\n", *desc);
1074 case RPC_FC_C_CSTRING:
1075 case RPC_FC_C_WSTRING:
1076 if (pStubMsg->ReuseBuffer) goto notfree;
1082 if (attr & RPC_FC_P_ONSTACK) {
1083 TRACE("not freeing stack ptr %p\n", Pointer);
1086 TRACE("freeing %p\n", Pointer);
1087 NdrFree(pStubMsg, Pointer);
1090 TRACE("not freeing %p\n", Pointer);
1093 /***********************************************************************
1094 * EmbeddedPointerMarshall
1096 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1097 unsigned char *pMemory,
1098 PFORMAT_STRING pFormat)
1100 unsigned char *Mark = pStubMsg->BufferMark;
1101 unsigned long Offset = pStubMsg->Offset;
1102 unsigned ofs, rep, count, stride, xofs;
1105 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1107 if (*pFormat != RPC_FC_PP) return NULL;
1110 while (pFormat[0] != RPC_FC_END) {
1111 switch (pFormat[0]) {
1113 FIXME("unknown repeat type %d\n", pFormat[0]);
1114 case RPC_FC_NO_REPEAT:
1122 case RPC_FC_FIXED_REPEAT:
1123 rep = *(const WORD*)&pFormat[2];
1124 stride = *(const WORD*)&pFormat[4];
1125 ofs = *(const WORD*)&pFormat[6];
1126 count = *(const WORD*)&pFormat[8];
1130 case RPC_FC_VARIABLE_REPEAT:
1131 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1132 stride = *(const WORD*)&pFormat[2];
1133 ofs = *(const WORD*)&pFormat[4];
1134 count = *(const WORD*)&pFormat[6];
1135 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1139 for (i = 0; i < rep; i++) {
1140 PFORMAT_STRING info = pFormat;
1141 unsigned char *membase = pMemory + (i * stride);
1142 unsigned char *bufbase = Mark + (i * stride);
1144 /* ofs doesn't seem to matter in this context */
1145 for (u=0; u<count; u++,info+=8) {
1146 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1147 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1148 unsigned char *saved_memory = pStubMsg->Memory;
1150 pStubMsg->Memory = pMemory;
1151 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1152 pStubMsg->Memory = saved_memory;
1155 pFormat += 8 * count;
1158 STD_OVERFLOW_CHECK(pStubMsg);
1163 /***********************************************************************
1164 * EmbeddedPointerUnmarshall
1166 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1167 unsigned char **ppMemory,
1168 PFORMAT_STRING pFormat,
1169 unsigned char fMustAlloc)
1171 unsigned char *Mark = pStubMsg->BufferMark;
1172 unsigned long Offset = pStubMsg->Offset;
1173 unsigned ofs, rep, count, stride, xofs;
1176 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1178 if (*pFormat != RPC_FC_PP) return NULL;
1181 while (pFormat[0] != RPC_FC_END) {
1182 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1183 switch (pFormat[0]) {
1185 FIXME("unknown repeat type %d\n", pFormat[0]);
1186 case RPC_FC_NO_REPEAT:
1194 case RPC_FC_FIXED_REPEAT:
1195 rep = *(const WORD*)&pFormat[2];
1196 stride = *(const WORD*)&pFormat[4];
1197 ofs = *(const WORD*)&pFormat[6];
1198 count = *(const WORD*)&pFormat[8];
1202 case RPC_FC_VARIABLE_REPEAT:
1203 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1204 stride = *(const WORD*)&pFormat[2];
1205 ofs = *(const WORD*)&pFormat[4];
1206 count = *(const WORD*)&pFormat[6];
1207 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1211 /* ofs doesn't seem to matter in this context */
1212 for (i = 0; i < rep; i++) {
1213 PFORMAT_STRING info = pFormat;
1214 unsigned char *membase = *ppMemory + (i * stride);
1215 unsigned char *bufbase = Mark + (i * stride);
1217 for (u=0; u<count; u++,info+=8) {
1218 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1219 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1220 PointerUnmarshall(pStubMsg, bufptr, (unsigned char**)memptr, info+4, TRUE);
1223 pFormat += 8 * count;
1229 /***********************************************************************
1230 * EmbeddedPointerBufferSize
1232 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1233 unsigned char *pMemory,
1234 PFORMAT_STRING pFormat)
1236 unsigned long Offset = pStubMsg->Offset;
1237 unsigned ofs, rep, count, stride, xofs;
1240 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1242 if (pStubMsg->IgnoreEmbeddedPointers) return;
1244 if (*pFormat != RPC_FC_PP) return;
1247 while (pFormat[0] != RPC_FC_END) {
1248 switch (pFormat[0]) {
1250 FIXME("unknown repeat type %d\n", pFormat[0]);
1251 case RPC_FC_NO_REPEAT:
1259 case RPC_FC_FIXED_REPEAT:
1260 rep = *(const WORD*)&pFormat[2];
1261 stride = *(const WORD*)&pFormat[4];
1262 ofs = *(const WORD*)&pFormat[6];
1263 count = *(const WORD*)&pFormat[8];
1267 case RPC_FC_VARIABLE_REPEAT:
1268 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1269 stride = *(const WORD*)&pFormat[2];
1270 ofs = *(const WORD*)&pFormat[4];
1271 count = *(const WORD*)&pFormat[6];
1272 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1276 /* ofs doesn't seem to matter in this context */
1277 for (i = 0; i < rep; i++) {
1278 PFORMAT_STRING info = pFormat;
1279 unsigned char *membase = pMemory + (i * stride);
1281 for (u=0; u<count; u++,info+=8) {
1282 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1283 unsigned char *saved_memory = pStubMsg->Memory;
1285 pStubMsg->Memory = pMemory;
1286 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1287 pStubMsg->Memory = saved_memory;
1290 pFormat += 8 * count;
1294 /***********************************************************************
1295 * EmbeddedPointerMemorySize
1297 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1298 PFORMAT_STRING pFormat)
1300 unsigned long Offset = pStubMsg->Offset;
1301 unsigned char *Mark = pStubMsg->BufferMark;
1302 unsigned ofs, rep, count, stride, xofs;
1305 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1307 if (*pFormat != RPC_FC_PP) return 0;
1310 while (pFormat[0] != RPC_FC_END) {
1311 switch (pFormat[0]) {
1313 FIXME("unknown repeat type %d\n", pFormat[0]);
1314 case RPC_FC_NO_REPEAT:
1322 case RPC_FC_FIXED_REPEAT:
1323 rep = *(const WORD*)&pFormat[2];
1324 stride = *(const WORD*)&pFormat[4];
1325 ofs = *(const WORD*)&pFormat[6];
1326 count = *(const WORD*)&pFormat[8];
1330 case RPC_FC_VARIABLE_REPEAT:
1331 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1332 stride = *(const WORD*)&pFormat[2];
1333 ofs = *(const WORD*)&pFormat[4];
1334 count = *(const WORD*)&pFormat[6];
1335 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1339 /* ofs doesn't seem to matter in this context */
1340 for (i = 0; i < rep; i++) {
1341 PFORMAT_STRING info = pFormat;
1342 unsigned char *bufbase = Mark + (i * stride);
1344 for (u=0; u<count; u++,info+=8) {
1345 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1346 PointerMemorySize(pStubMsg, bufptr, info+4);
1349 pFormat += 8 * count;
1355 /***********************************************************************
1356 * EmbeddedPointerFree
1358 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1359 unsigned char *pMemory,
1360 PFORMAT_STRING pFormat)
1362 unsigned long Offset = pStubMsg->Offset;
1363 unsigned ofs, rep, count, stride, xofs;
1366 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1367 if (*pFormat != RPC_FC_PP) return;
1370 while (pFormat[0] != RPC_FC_END) {
1371 switch (pFormat[0]) {
1373 FIXME("unknown repeat type %d\n", pFormat[0]);
1374 case RPC_FC_NO_REPEAT:
1382 case RPC_FC_FIXED_REPEAT:
1383 rep = *(const WORD*)&pFormat[2];
1384 stride = *(const WORD*)&pFormat[4];
1385 ofs = *(const WORD*)&pFormat[6];
1386 count = *(const WORD*)&pFormat[8];
1390 case RPC_FC_VARIABLE_REPEAT:
1391 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1392 stride = *(const WORD*)&pFormat[2];
1393 ofs = *(const WORD*)&pFormat[4];
1394 count = *(const WORD*)&pFormat[6];
1395 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1399 /* ofs doesn't seem to matter in this context */
1400 for (i = 0; i < rep; i++) {
1401 PFORMAT_STRING info = pFormat;
1402 unsigned char *membase = pMemory + (i * stride);
1404 for (u=0; u<count; u++,info+=8) {
1405 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1406 unsigned char *saved_memory = pStubMsg->Memory;
1408 pStubMsg->Memory = pMemory;
1409 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1410 pStubMsg->Memory = saved_memory;
1413 pFormat += 8 * count;
1417 /***********************************************************************
1418 * NdrPointerMarshall [RPCRT4.@]
1420 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1421 unsigned char *pMemory,
1422 PFORMAT_STRING pFormat)
1424 unsigned char *Buffer;
1426 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1428 /* incremement the buffer here instead of in PointerMarshall,
1429 * as that is used by embedded pointers which already handle the incrementing
1430 * the buffer, and shouldn't write any additional pointer data to the wire */
1431 if (*pFormat != RPC_FC_RP)
1433 ALIGN_POINTER(pStubMsg->Buffer, 4);
1434 Buffer = pStubMsg->Buffer;
1435 pStubMsg->Buffer += 4;
1438 Buffer = pStubMsg->Buffer;
1440 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1442 STD_OVERFLOW_CHECK(pStubMsg);
1447 /***********************************************************************
1448 * NdrPointerUnmarshall [RPCRT4.@]
1450 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1451 unsigned char **ppMemory,
1452 PFORMAT_STRING pFormat,
1453 unsigned char fMustAlloc)
1455 unsigned char *Buffer;
1457 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1459 /* incremement the buffer here instead of in PointerUnmarshall,
1460 * as that is used by embedded pointers which already handle the incrementing
1461 * the buffer, and shouldn't read any additional pointer data from the
1463 if (*pFormat != RPC_FC_RP)
1465 ALIGN_POINTER(pStubMsg->Buffer, 4);
1466 Buffer = pStubMsg->Buffer;
1467 pStubMsg->Buffer += 4;
1470 Buffer = pStubMsg->Buffer;
1472 PointerUnmarshall(pStubMsg, Buffer, ppMemory, pFormat, fMustAlloc);
1477 /***********************************************************************
1478 * NdrPointerBufferSize [RPCRT4.@]
1480 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1481 unsigned char *pMemory,
1482 PFORMAT_STRING pFormat)
1484 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1486 /* incremement the buffer length here instead of in PointerBufferSize,
1487 * as that is used by embedded pointers which already handle the buffer
1488 * length, and shouldn't write anything more to the wire */
1489 if (*pFormat != RPC_FC_RP)
1491 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1492 pStubMsg->BufferLength += 4;
1495 PointerBufferSize(pStubMsg, pMemory, pFormat);
1498 /***********************************************************************
1499 * NdrPointerMemorySize [RPCRT4.@]
1501 unsigned long WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1502 PFORMAT_STRING pFormat)
1504 /* unsigned size = *(LPWORD)(pFormat+2); */
1505 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1506 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1510 /***********************************************************************
1511 * NdrPointerFree [RPCRT4.@]
1513 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1514 unsigned char *pMemory,
1515 PFORMAT_STRING pFormat)
1517 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1518 PointerFree(pStubMsg, pMemory, pFormat);
1521 /***********************************************************************
1522 * NdrSimpleTypeMarshall [RPCRT4.@]
1524 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1525 unsigned char FormatChar )
1530 /***********************************************************************
1531 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1533 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1534 unsigned char FormatChar )
1539 /***********************************************************************
1540 * NdrSimpleStructMarshall [RPCRT4.@]
1542 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1543 unsigned char *pMemory,
1544 PFORMAT_STRING pFormat)
1546 unsigned size = *(const WORD*)(pFormat+2);
1547 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1549 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1551 memcpy(pStubMsg->Buffer, pMemory, size);
1552 pStubMsg->BufferMark = pStubMsg->Buffer;
1553 pStubMsg->Buffer += size;
1555 if (pFormat[0] != RPC_FC_STRUCT)
1556 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1558 STD_OVERFLOW_CHECK(pStubMsg);
1563 /***********************************************************************
1564 * NdrSimpleStructUnmarshall [RPCRT4.@]
1566 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1567 unsigned char **ppMemory,
1568 PFORMAT_STRING pFormat,
1569 unsigned char fMustAlloc)
1571 unsigned size = *(const WORD*)(pFormat+2);
1572 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1574 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1577 *ppMemory = NdrAllocate(pStubMsg, size);
1578 memcpy(*ppMemory, pStubMsg->Buffer, size);
1580 if (!pStubMsg->IsClient && !*ppMemory)
1581 /* for servers, we just point straight into the RPC buffer */
1582 *ppMemory = pStubMsg->Buffer;
1584 /* for clients, memory should be provided by caller */
1585 memcpy(*ppMemory, pStubMsg->Buffer, size);
1588 pStubMsg->BufferMark = pStubMsg->Buffer;
1589 pStubMsg->Buffer += size;
1591 if (pFormat[0] != RPC_FC_STRUCT)
1592 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat+4, fMustAlloc);
1597 /***********************************************************************
1598 * NdrSimpleStructBufferSize [RPCRT4.@]
1600 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1601 unsigned char *pMemory,
1602 PFORMAT_STRING pFormat)
1604 unsigned size = *(const WORD*)(pFormat+2);
1605 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1607 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1609 pStubMsg->BufferLength += size;
1610 if (pFormat[0] != RPC_FC_STRUCT)
1611 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1614 /***********************************************************************
1615 * NdrSimpleStructMemorySize [RPCRT4.@]
1617 unsigned long WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1618 PFORMAT_STRING pFormat)
1620 unsigned short size = *(const WORD *)(pFormat+2);
1622 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1624 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1625 pStubMsg->MemorySize += size;
1626 pStubMsg->Buffer += size;
1628 if (pFormat[0] != RPC_FC_STRUCT)
1629 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1633 /***********************************************************************
1634 * NdrSimpleStructFree [RPCRT4.@]
1636 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1637 unsigned char *pMemory,
1638 PFORMAT_STRING pFormat)
1640 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1641 if (pFormat[0] != RPC_FC_STRUCT)
1642 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1646 static unsigned long EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg,
1647 PFORMAT_STRING pFormat)
1651 case RPC_FC_PSTRUCT:
1652 case RPC_FC_CSTRUCT:
1653 case RPC_FC_BOGUS_STRUCT:
1654 case RPC_FC_SMFARRAY:
1655 case RPC_FC_SMVARRAY:
1656 return *(const WORD*)&pFormat[2];
1657 case RPC_FC_USER_MARSHAL:
1658 return *(const WORD*)&pFormat[4];
1659 case RPC_FC_NON_ENCAPSULATED_UNION:
1661 if (pStubMsg->fHasNewCorrDesc)
1666 pFormat += *(const SHORT*)pFormat;
1667 return *(const SHORT*)pFormat;
1669 return sizeof(void *);
1671 FIXME("unhandled embedded type %02x\n", *pFormat);
1677 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1678 PFORMAT_STRING pFormat)
1680 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1684 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1688 return m(pStubMsg, pFormat);
1692 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1693 unsigned char *pMemory,
1694 PFORMAT_STRING pFormat,
1695 PFORMAT_STRING pPointer)
1697 PFORMAT_STRING desc;
1701 while (*pFormat != RPC_FC_END) {
1707 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
1708 memcpy(pStubMsg->Buffer, pMemory, 1);
1709 pStubMsg->Buffer += 1;
1715 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1716 memcpy(pStubMsg->Buffer, pMemory, 2);
1717 pStubMsg->Buffer += 2;
1723 TRACE("long=%ld <= %p\n", *(DWORD*)pMemory, pMemory);
1724 memcpy(pStubMsg->Buffer, pMemory, 4);
1725 pStubMsg->Buffer += 4;
1729 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1730 memcpy(pStubMsg->Buffer, pMemory, 8);
1731 pStubMsg->Buffer += 8;
1734 case RPC_FC_POINTER:
1735 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1736 NdrPointerMarshall(pStubMsg, *(unsigned char**)pMemory, pPointer);
1740 case RPC_FC_ALIGNM4:
1741 ALIGN_POINTER(pMemory, 4);
1743 case RPC_FC_ALIGNM8:
1744 ALIGN_POINTER(pMemory, 8);
1746 case RPC_FC_STRUCTPAD1:
1747 case RPC_FC_STRUCTPAD2:
1748 case RPC_FC_STRUCTPAD3:
1749 case RPC_FC_STRUCTPAD4:
1750 case RPC_FC_STRUCTPAD5:
1751 case RPC_FC_STRUCTPAD6:
1752 case RPC_FC_STRUCTPAD7:
1753 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1755 case RPC_FC_EMBEDDED_COMPLEX:
1756 pMemory += pFormat[1];
1758 desc = pFormat + *(const SHORT*)pFormat;
1759 size = EmbeddedComplexSize(pStubMsg, desc);
1760 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1761 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1762 if (m) m(pStubMsg, pMemory, desc);
1763 else FIXME("no marshaller for embedded type %02x\n", *desc);
1770 FIXME("unhandled format 0x%02x\n", *pFormat);
1778 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1779 unsigned char *pMemory,
1780 PFORMAT_STRING pFormat,
1781 PFORMAT_STRING pPointer)
1783 PFORMAT_STRING desc;
1787 while (*pFormat != RPC_FC_END) {
1793 memcpy(pMemory, pStubMsg->Buffer, 1);
1794 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
1795 pStubMsg->Buffer += 1;
1801 memcpy(pMemory, pStubMsg->Buffer, 2);
1802 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1803 pStubMsg->Buffer += 2;
1809 memcpy(pMemory, pStubMsg->Buffer, 4);
1810 TRACE("long=%ld => %p\n", *(DWORD*)pMemory, pMemory);
1811 pStubMsg->Buffer += 4;
1815 memcpy(pMemory, pStubMsg->Buffer, 8);
1816 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1817 pStubMsg->Buffer += 8;
1820 case RPC_FC_POINTER:
1821 TRACE("pointer => %p\n", pMemory);
1822 NdrPointerUnmarshall(pStubMsg, (unsigned char**)pMemory, pPointer, TRUE);
1826 case RPC_FC_ALIGNM4:
1827 ALIGN_POINTER(pMemory, 4);
1829 case RPC_FC_ALIGNM8:
1830 ALIGN_POINTER(pMemory, 8);
1832 case RPC_FC_STRUCTPAD1:
1833 case RPC_FC_STRUCTPAD2:
1834 case RPC_FC_STRUCTPAD3:
1835 case RPC_FC_STRUCTPAD4:
1836 case RPC_FC_STRUCTPAD5:
1837 case RPC_FC_STRUCTPAD6:
1838 case RPC_FC_STRUCTPAD7:
1839 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1841 case RPC_FC_EMBEDDED_COMPLEX:
1842 pMemory += pFormat[1];
1844 desc = pFormat + *(const SHORT*)pFormat;
1845 size = EmbeddedComplexSize(pStubMsg, desc);
1846 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
1847 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1848 memset(pMemory, 0, size); /* just in case */
1849 if (m) m(pStubMsg, &pMemory, desc, FALSE);
1850 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
1857 FIXME("unhandled format %d\n", *pFormat);
1865 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1866 unsigned char *pMemory,
1867 PFORMAT_STRING pFormat,
1868 PFORMAT_STRING pPointer)
1870 PFORMAT_STRING desc;
1874 while (*pFormat != RPC_FC_END) {
1880 pStubMsg->BufferLength += 1;
1886 pStubMsg->BufferLength += 2;
1892 pStubMsg->BufferLength += 4;
1896 pStubMsg->BufferLength += 8;
1899 case RPC_FC_POINTER:
1900 NdrPointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
1904 case RPC_FC_ALIGNM4:
1905 ALIGN_POINTER(pMemory, 4);
1907 case RPC_FC_ALIGNM8:
1908 ALIGN_POINTER(pMemory, 8);
1910 case RPC_FC_STRUCTPAD1:
1911 case RPC_FC_STRUCTPAD2:
1912 case RPC_FC_STRUCTPAD3:
1913 case RPC_FC_STRUCTPAD4:
1914 case RPC_FC_STRUCTPAD5:
1915 case RPC_FC_STRUCTPAD6:
1916 case RPC_FC_STRUCTPAD7:
1917 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1919 case RPC_FC_EMBEDDED_COMPLEX:
1920 pMemory += pFormat[1];
1922 desc = pFormat + *(const SHORT*)pFormat;
1923 size = EmbeddedComplexSize(pStubMsg, desc);
1924 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1925 if (m) m(pStubMsg, pMemory, desc);
1926 else FIXME("no buffersizer for embedded type %02x\n", *desc);
1933 FIXME("unhandled format 0x%02x\n", *pFormat);
1941 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
1942 unsigned char *pMemory,
1943 PFORMAT_STRING pFormat,
1944 PFORMAT_STRING pPointer)
1946 PFORMAT_STRING desc;
1950 while (*pFormat != RPC_FC_END) {
1971 case RPC_FC_POINTER:
1972 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
1976 case RPC_FC_ALIGNM4:
1977 ALIGN_POINTER(pMemory, 4);
1979 case RPC_FC_ALIGNM8:
1980 ALIGN_POINTER(pMemory, 8);
1982 case RPC_FC_STRUCTPAD1:
1983 case RPC_FC_STRUCTPAD2:
1984 case RPC_FC_STRUCTPAD3:
1985 case RPC_FC_STRUCTPAD4:
1986 case RPC_FC_STRUCTPAD5:
1987 case RPC_FC_STRUCTPAD6:
1988 case RPC_FC_STRUCTPAD7:
1989 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1991 case RPC_FC_EMBEDDED_COMPLEX:
1992 pMemory += pFormat[1];
1994 desc = pFormat + *(const SHORT*)pFormat;
1995 size = EmbeddedComplexSize(pStubMsg, desc);
1996 m = NdrFreer[*desc & NDR_TABLE_MASK];
1997 if (m) m(pStubMsg, pMemory, desc);
1998 else FIXME("no freer for embedded type %02x\n", *desc);
2005 FIXME("unhandled format 0x%02x\n", *pFormat);
2013 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2014 PFORMAT_STRING pFormat)
2016 PFORMAT_STRING desc;
2017 unsigned long size = 0;
2019 while (*pFormat != RPC_FC_END) {
2026 pStubMsg->Buffer += 1;
2032 pStubMsg->Buffer += 2;
2038 pStubMsg->Buffer += 4;
2042 pStubMsg->Buffer += 8;
2044 case RPC_FC_POINTER:
2046 pStubMsg->Buffer += 4;
2048 case RPC_FC_ALIGNM4:
2049 ALIGN_LENGTH(size, 4);
2050 ALIGN_POINTER(pStubMsg->Buffer, 4);
2052 case RPC_FC_ALIGNM8:
2053 ALIGN_LENGTH(size, 8);
2054 ALIGN_POINTER(pStubMsg->Buffer, 8);
2056 case RPC_FC_STRUCTPAD1:
2057 case RPC_FC_STRUCTPAD2:
2058 case RPC_FC_STRUCTPAD3:
2059 case RPC_FC_STRUCTPAD4:
2060 case RPC_FC_STRUCTPAD5:
2061 case RPC_FC_STRUCTPAD6:
2062 case RPC_FC_STRUCTPAD7:
2063 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2065 case RPC_FC_EMBEDDED_COMPLEX:
2068 desc = pFormat + *(const SHORT*)pFormat;
2069 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2075 FIXME("unhandled format 0x%02x\n", *pFormat);
2083 /***********************************************************************
2084 * NdrComplexStructMarshall [RPCRT4.@]
2086 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2087 unsigned char *pMemory,
2088 PFORMAT_STRING pFormat)
2090 PFORMAT_STRING conf_array = NULL;
2091 PFORMAT_STRING pointer_desc = NULL;
2092 unsigned char *OldMemory = pStubMsg->Memory;
2094 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2096 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2099 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2101 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2104 pStubMsg->Memory = pMemory;
2106 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2109 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2111 pStubMsg->Memory = OldMemory;
2113 STD_OVERFLOW_CHECK(pStubMsg);
2118 /***********************************************************************
2119 * NdrComplexStructUnmarshall [RPCRT4.@]
2121 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2122 unsigned char **ppMemory,
2123 PFORMAT_STRING pFormat,
2124 unsigned char fMustAlloc)
2126 unsigned size = *(const WORD*)(pFormat+2);
2127 PFORMAT_STRING conf_array = NULL;
2128 PFORMAT_STRING pointer_desc = NULL;
2129 unsigned char *pMemory;
2131 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2133 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2135 if (fMustAlloc || !*ppMemory)
2137 *ppMemory = NdrAllocate(pStubMsg, size);
2138 memset(*ppMemory, 0, size);
2142 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2144 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2147 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2150 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2155 /***********************************************************************
2156 * NdrComplexStructBufferSize [RPCRT4.@]
2158 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2159 unsigned char *pMemory,
2160 PFORMAT_STRING pFormat)
2162 PFORMAT_STRING conf_array = NULL;
2163 PFORMAT_STRING pointer_desc = NULL;
2164 unsigned char *OldMemory = pStubMsg->Memory;
2166 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2168 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2171 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2173 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2176 pStubMsg->Memory = pMemory;
2178 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2181 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2183 pStubMsg->Memory = OldMemory;
2186 /***********************************************************************
2187 * NdrComplexStructMemorySize [RPCRT4.@]
2189 unsigned long WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2190 PFORMAT_STRING pFormat)
2192 unsigned size = *(const WORD*)(pFormat+2);
2193 PFORMAT_STRING conf_array = NULL;
2194 PFORMAT_STRING pointer_desc = NULL;
2196 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2198 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2201 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2203 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2206 ComplexStructMemorySize(pStubMsg, pFormat);
2209 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2214 /***********************************************************************
2215 * NdrComplexStructFree [RPCRT4.@]
2217 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2218 unsigned char *pMemory,
2219 PFORMAT_STRING pFormat)
2221 PFORMAT_STRING conf_array = NULL;
2222 PFORMAT_STRING pointer_desc = NULL;
2223 unsigned char *OldMemory = pStubMsg->Memory;
2225 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2228 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2230 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2233 pStubMsg->Memory = pMemory;
2235 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2238 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2240 pStubMsg->Memory = OldMemory;
2243 /***********************************************************************
2244 * NdrConformantArrayMarshall [RPCRT4.@]
2246 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2247 unsigned char *pMemory,
2248 PFORMAT_STRING pFormat)
2250 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2251 unsigned char alignment = pFormat[1] + 1;
2253 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2254 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2256 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2258 WriteConformance(pStubMsg);
2260 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2262 size = safe_multiply(esize, pStubMsg->MaxCount);
2263 memcpy(pStubMsg->Buffer, pMemory, size);
2264 pStubMsg->BufferMark = pStubMsg->Buffer;
2265 pStubMsg->Buffer += size;
2267 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2269 STD_OVERFLOW_CHECK(pStubMsg);
2274 /***********************************************************************
2275 * NdrConformantArrayUnmarshall [RPCRT4.@]
2277 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2278 unsigned char **ppMemory,
2279 PFORMAT_STRING pFormat,
2280 unsigned char fMustAlloc)
2282 DWORD size, esize = *(const WORD*)(pFormat+2);
2283 unsigned char alignment = pFormat[1] + 1;
2285 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2286 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2288 pFormat = ReadConformance(pStubMsg, pFormat+4);
2290 size = safe_multiply(esize, pStubMsg->MaxCount);
2292 if (fMustAlloc || !*ppMemory)
2293 *ppMemory = NdrAllocate(pStubMsg, size);
2295 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2297 memcpy(*ppMemory, pStubMsg->Buffer, size);
2299 pStubMsg->BufferMark = pStubMsg->Buffer;
2300 pStubMsg->Buffer += size;
2302 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2307 /***********************************************************************
2308 * NdrConformantArrayBufferSize [RPCRT4.@]
2310 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2311 unsigned char *pMemory,
2312 PFORMAT_STRING pFormat)
2314 DWORD size, esize = *(const WORD*)(pFormat+2);
2315 unsigned char alignment = pFormat[1] + 1;
2317 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2318 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2320 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2322 SizeConformance(pStubMsg);
2324 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2326 size = safe_multiply(esize, pStubMsg->MaxCount);
2327 /* conformance value plus array */
2328 pStubMsg->BufferLength += size;
2330 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2333 /***********************************************************************
2334 * NdrConformantArrayMemorySize [RPCRT4.@]
2336 unsigned long WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2337 PFORMAT_STRING pFormat)
2339 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2340 unsigned char alignment = pFormat[1] + 1;
2342 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2343 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2345 pFormat = ReadConformance(pStubMsg, pFormat+4);
2346 size = safe_multiply(esize, pStubMsg->MaxCount);
2347 pStubMsg->MemorySize += size;
2349 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2350 pStubMsg->BufferMark = pStubMsg->Buffer;
2351 pStubMsg->Buffer += size;
2353 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2355 return pStubMsg->MemorySize;
2358 /***********************************************************************
2359 * NdrConformantArrayFree [RPCRT4.@]
2361 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2362 unsigned char *pMemory,
2363 PFORMAT_STRING pFormat)
2365 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2366 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2368 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2370 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2374 /***********************************************************************
2375 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2377 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2378 unsigned char* pMemory,
2379 PFORMAT_STRING pFormat )
2382 unsigned char alignment = pFormat[1] + 1;
2383 DWORD esize = *(const WORD*)(pFormat+2);
2385 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2387 if (pFormat[0] != RPC_FC_CVARRAY)
2389 ERR("invalid format type %x\n", pFormat[0]);
2390 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2394 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2395 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2397 WriteConformance(pStubMsg);
2398 WriteVariance(pStubMsg);
2400 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2402 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2404 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
2405 pStubMsg->BufferMark = pStubMsg->Buffer;
2406 pStubMsg->Buffer += bufsize;
2408 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2410 STD_OVERFLOW_CHECK(pStubMsg);
2416 /***********************************************************************
2417 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2419 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2420 unsigned char** ppMemory,
2421 PFORMAT_STRING pFormat,
2422 unsigned char fMustAlloc )
2424 ULONG bufsize, memsize;
2425 unsigned char alignment = pFormat[1] + 1;
2426 DWORD esize = *(const WORD*)(pFormat+2);
2428 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2430 if (pFormat[0] != RPC_FC_CVARRAY)
2432 ERR("invalid format type %x\n", pFormat[0]);
2433 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2437 pFormat = ReadConformance(pStubMsg, pFormat+4);
2438 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2440 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2442 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2443 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2445 if (!*ppMemory || fMustAlloc)
2446 *ppMemory = NdrAllocate(pStubMsg, memsize);
2447 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
2448 pStubMsg->Buffer += bufsize;
2450 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2456 /***********************************************************************
2457 * NdrConformantVaryingArrayFree [RPCRT4.@]
2459 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2460 unsigned char* pMemory,
2461 PFORMAT_STRING pFormat )
2463 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2465 if (pFormat[0] != RPC_FC_CVARRAY)
2467 ERR("invalid format type %x\n", pFormat[0]);
2468 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2472 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2473 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2475 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2479 /***********************************************************************
2480 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2482 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2483 unsigned char* pMemory, PFORMAT_STRING pFormat )
2485 unsigned char alignment = pFormat[1] + 1;
2486 DWORD esize = *(const WORD*)(pFormat+2);
2488 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2490 if (pFormat[0] != RPC_FC_CVARRAY)
2492 ERR("invalid format type %x\n", pFormat[0]);
2493 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2498 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2499 /* compute length */
2500 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2502 SizeConformance(pStubMsg);
2503 SizeVariance(pStubMsg);
2505 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2507 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
2509 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2513 /***********************************************************************
2514 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2516 unsigned long WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2517 PFORMAT_STRING pFormat )
2524 /***********************************************************************
2525 * NdrComplexArrayMarshall [RPCRT4.@]
2527 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2528 unsigned char *pMemory,
2529 PFORMAT_STRING pFormat)
2531 ULONG i, count, def;
2532 BOOL variance_present;
2533 unsigned char alignment;
2535 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2537 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2539 ERR("invalid format type %x\n", pFormat[0]);
2540 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2544 alignment = pFormat[1] + 1;
2546 def = *(const WORD*)&pFormat[2];
2549 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2550 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2552 variance_present = IsConformanceOrVariancePresent(pFormat);
2553 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2554 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2556 WriteConformance(pStubMsg);
2557 if (variance_present)
2558 WriteVariance(pStubMsg);
2560 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2562 count = pStubMsg->ActualCount;
2563 for (i = 0; i < count; i++)
2564 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2566 STD_OVERFLOW_CHECK(pStubMsg);
2571 /***********************************************************************
2572 * NdrComplexArrayUnmarshall [RPCRT4.@]
2574 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2575 unsigned char **ppMemory,
2576 PFORMAT_STRING pFormat,
2577 unsigned char fMustAlloc)
2579 ULONG i, count, esize, memsize;
2580 unsigned char alignment;
2581 unsigned char *pMemory;
2582 unsigned char *Buffer;
2584 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2586 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2588 ERR("invalid format type %x\n", pFormat[0]);
2589 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2593 alignment = pFormat[1] + 1;
2597 pFormat = ReadConformance(pStubMsg, pFormat);
2598 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2600 Buffer = pStubMsg->Buffer;
2601 pStubMsg->MemorySize = 0;
2602 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2603 pStubMsg->Buffer = Buffer;
2605 /* do multiply here instead of inside if block to verify MaxCount */
2606 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2607 if (fMustAlloc || !*ppMemory)
2609 *ppMemory = NdrAllocate(pStubMsg, memsize);
2610 memset(*ppMemory, 0, memsize);
2613 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2615 pMemory = *ppMemory;
2616 count = pStubMsg->ActualCount;
2617 for (i = 0; i < count; i++)
2618 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
2623 /***********************************************************************
2624 * NdrComplexArrayBufferSize [RPCRT4.@]
2626 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2627 unsigned char *pMemory,
2628 PFORMAT_STRING pFormat)
2630 ULONG i, count, def;
2631 unsigned char alignment;
2632 BOOL variance_present;
2634 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2636 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2638 ERR("invalid format type %x\n", pFormat[0]);
2639 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2643 alignment = pFormat[1] + 1;
2645 def = *(const WORD*)&pFormat[2];
2648 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2649 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2650 SizeConformance(pStubMsg);
2652 variance_present = IsConformanceOrVariancePresent(pFormat);
2653 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2654 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2656 if (variance_present)
2657 SizeVariance(pStubMsg);
2659 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2661 count = pStubMsg->ActualCount;
2662 for (i = 0; i < count; i++)
2663 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
2666 /***********************************************************************
2667 * NdrComplexArrayMemorySize [RPCRT4.@]
2669 unsigned long WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2670 PFORMAT_STRING pFormat)
2672 ULONG i, count, esize;
2673 unsigned char alignment;
2674 unsigned char *Buffer;
2675 unsigned long SavedMemorySize;
2676 unsigned long MemorySize;
2678 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2680 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2682 ERR("invalid format type %x\n", pFormat[0]);
2683 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2687 alignment = pFormat[1] + 1;
2691 pFormat = ReadConformance(pStubMsg, pFormat);
2692 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2694 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2696 SavedMemorySize = pStubMsg->MemorySize;
2698 Buffer = pStubMsg->Buffer;
2699 pStubMsg->MemorySize = 0;
2700 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2701 pStubMsg->Buffer = Buffer;
2703 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
2705 count = pStubMsg->ActualCount;
2706 for (i = 0; i < count; i++)
2707 ComplexStructMemorySize(pStubMsg, pFormat);
2709 pStubMsg->MemorySize = SavedMemorySize;
2711 pStubMsg->MemorySize += MemorySize;
2715 /***********************************************************************
2716 * NdrComplexArrayFree [RPCRT4.@]
2718 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2719 unsigned char *pMemory,
2720 PFORMAT_STRING pFormat)
2722 ULONG i, count, def;
2724 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2726 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2728 ERR("invalid format type %x\n", pFormat[0]);
2729 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2733 def = *(const WORD*)&pFormat[2];
2736 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2737 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2739 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2740 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2742 count = pStubMsg->ActualCount;
2743 for (i = 0; i < count; i++)
2744 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2747 static unsigned long UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
2749 return MAKELONG(pStubMsg->dwDestContext,
2750 pStubMsg->RpcMsg->DataRepresentation);
2753 #define USER_MARSHAL_PTR_PREFIX \
2754 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
2755 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
2757 /***********************************************************************
2758 * NdrUserMarshalMarshall [RPCRT4.@]
2760 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2761 unsigned char *pMemory,
2762 PFORMAT_STRING pFormat)
2764 unsigned flags = pFormat[1];
2765 unsigned index = *(const WORD*)&pFormat[2];
2766 unsigned long uflag = UserMarshalFlags(pStubMsg);
2767 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2768 TRACE("index=%d\n", index);
2770 if (flags & USER_MARSHAL_POINTER)
2772 ALIGN_POINTER(pStubMsg->Buffer, 4);
2773 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
2774 pStubMsg->Buffer += 4;
2775 ALIGN_POINTER(pStubMsg->Buffer, 8);
2778 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2781 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
2782 &uflag, pStubMsg->Buffer, pMemory);
2784 STD_OVERFLOW_CHECK(pStubMsg);
2789 /***********************************************************************
2790 * NdrUserMarshalUnmarshall [RPCRT4.@]
2792 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2793 unsigned char **ppMemory,
2794 PFORMAT_STRING pFormat,
2795 unsigned char fMustAlloc)
2797 unsigned flags = pFormat[1];
2798 unsigned index = *(const WORD*)&pFormat[2];
2799 DWORD memsize = *(const WORD*)&pFormat[4];
2800 unsigned long uflag = UserMarshalFlags(pStubMsg);
2801 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2802 TRACE("index=%d\n", index);
2804 if (flags & USER_MARSHAL_POINTER)
2806 ALIGN_POINTER(pStubMsg->Buffer, 4);
2807 /* skip pointer prefix */
2808 pStubMsg->Buffer += 4;
2809 ALIGN_POINTER(pStubMsg->Buffer, 8);
2812 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2814 if (fMustAlloc || !*ppMemory)
2815 *ppMemory = NdrAllocate(pStubMsg, memsize);
2818 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
2819 &uflag, pStubMsg->Buffer, *ppMemory);
2824 /***********************************************************************
2825 * NdrUserMarshalBufferSize [RPCRT4.@]
2827 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2828 unsigned char *pMemory,
2829 PFORMAT_STRING pFormat)
2831 unsigned flags = pFormat[1];
2832 unsigned index = *(const WORD*)&pFormat[2];
2833 DWORD bufsize = *(const WORD*)&pFormat[6];
2834 unsigned long uflag = UserMarshalFlags(pStubMsg);
2835 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2836 TRACE("index=%d\n", index);
2838 if (flags & USER_MARSHAL_POINTER)
2840 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2841 /* skip pointer prefix */
2842 pStubMsg->BufferLength += 4;
2843 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
2846 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
2849 TRACE("size=%ld\n", bufsize);
2850 pStubMsg->BufferLength += bufsize;
2854 pStubMsg->BufferLength =
2855 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
2856 &uflag, pStubMsg->BufferLength, pMemory);
2859 /***********************************************************************
2860 * NdrUserMarshalMemorySize [RPCRT4.@]
2862 unsigned long WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2863 PFORMAT_STRING pFormat)
2865 unsigned flags = pFormat[1];
2866 unsigned index = *(const WORD*)&pFormat[2];
2867 DWORD memsize = *(const WORD*)&pFormat[4];
2868 DWORD bufsize = *(const WORD*)&pFormat[6];
2870 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2871 TRACE("index=%d\n", index);
2873 pStubMsg->MemorySize += memsize;
2875 if (flags & USER_MARSHAL_POINTER)
2877 ALIGN_POINTER(pStubMsg->Buffer, 4);
2878 /* skip pointer prefix */
2879 pStubMsg->Buffer += 4;
2880 ALIGN_POINTER(pStubMsg->Buffer, 8);
2883 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2885 pStubMsg->Buffer += bufsize;
2887 return pStubMsg->MemorySize;
2890 /***********************************************************************
2891 * NdrUserMarshalFree [RPCRT4.@]
2893 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
2894 unsigned char *pMemory,
2895 PFORMAT_STRING pFormat)
2897 /* unsigned flags = pFormat[1]; */
2898 unsigned index = *(const WORD*)&pFormat[2];
2899 unsigned long uflag = UserMarshalFlags(pStubMsg);
2900 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2901 TRACE("index=%d\n", index);
2903 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
2907 /***********************************************************************
2908 * NdrClearOutParameters [RPCRT4.@]
2910 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
2911 PFORMAT_STRING pFormat,
2914 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
2917 /***********************************************************************
2918 * NdrConvert [RPCRT4.@]
2920 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
2922 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
2923 /* FIXME: since this stub doesn't do any converting, the proper behavior
2924 is to raise an exception */
2927 /***********************************************************************
2928 * NdrConvert2 [RPCRT4.@]
2930 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, long NumberParams )
2932 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %ld): stub.\n",
2933 pStubMsg, pFormat, NumberParams);
2934 /* FIXME: since this stub doesn't do any converting, the proper behavior
2935 is to raise an exception */
2938 typedef struct _NDR_CSTRUCT_FORMAT
2941 unsigned char alignment;
2942 unsigned short memory_size;
2943 short offset_to_array_description;
2944 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
2946 /***********************************************************************
2947 * NdrConformantStructMarshall [RPCRT4.@]
2949 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2950 unsigned char *pMemory,
2951 PFORMAT_STRING pFormat)
2953 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
2954 PFORMAT_STRING pCArrayFormat;
2955 ULONG esize, bufsize;
2957 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2959 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2960 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2962 ERR("invalid format type %x\n", pCStructFormat->type);
2963 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2967 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
2968 pCStructFormat->offset_to_array_description;
2969 if (*pCArrayFormat != RPC_FC_CARRAY)
2971 ERR("invalid array format type %x\n", pCStructFormat->type);
2972 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2975 esize = *(const WORD*)(pCArrayFormat+2);
2977 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
2978 pCArrayFormat + 4, 0);
2980 WriteConformance(pStubMsg);
2982 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
2984 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2986 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
2987 /* copy constant sized part of struct */
2988 pStubMsg->BufferMark = pStubMsg->Buffer;
2989 memcpy(pStubMsg->Buffer, pMemory, pCStructFormat->memory_size + bufsize);
2990 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
2992 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2993 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2995 STD_OVERFLOW_CHECK(pStubMsg);
3000 /***********************************************************************
3001 * NdrConformantStructUnmarshall [RPCRT4.@]
3003 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3004 unsigned char **ppMemory,
3005 PFORMAT_STRING pFormat,
3006 unsigned char fMustAlloc)
3008 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3009 PFORMAT_STRING pCArrayFormat;
3010 ULONG esize, bufsize;
3012 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3014 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3015 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3017 ERR("invalid format type %x\n", pCStructFormat->type);
3018 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3021 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3022 pCStructFormat->offset_to_array_description;
3023 if (*pCArrayFormat != RPC_FC_CARRAY)
3025 ERR("invalid array format type %x\n", pCStructFormat->type);
3026 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3029 esize = *(const WORD*)(pCArrayFormat+2);
3031 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3033 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3035 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3037 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3038 /* work out how much memory to allocate if we need to do so */
3039 if (!*ppMemory || fMustAlloc)
3041 SIZE_T size = pCStructFormat->memory_size + bufsize;
3042 *ppMemory = NdrAllocate(pStubMsg, size);
3045 /* now copy the data */
3046 pStubMsg->BufferMark = pStubMsg->Buffer;
3047 memcpy(*ppMemory, pStubMsg->Buffer, pCStructFormat->memory_size + bufsize);
3048 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
3050 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3051 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3056 /***********************************************************************
3057 * NdrConformantStructBufferSize [RPCRT4.@]
3059 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3060 unsigned char *pMemory,
3061 PFORMAT_STRING pFormat)
3063 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3064 PFORMAT_STRING pCArrayFormat;
3067 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3069 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3070 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3072 ERR("invalid format type %x\n", pCStructFormat->type);
3073 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3076 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3077 pCStructFormat->offset_to_array_description;
3078 if (*pCArrayFormat != RPC_FC_CARRAY)
3080 ERR("invalid array format type %x\n", pCStructFormat->type);
3081 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3084 esize = *(const WORD*)(pCArrayFormat+2);
3086 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
3087 SizeConformance(pStubMsg);
3089 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
3091 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3093 pStubMsg->BufferLength += pCStructFormat->memory_size +
3094 safe_multiply(pStubMsg->MaxCount, esize);
3096 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3097 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3100 /***********************************************************************
3101 * NdrConformantStructMemorySize [RPCRT4.@]
3103 unsigned long WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3104 PFORMAT_STRING pFormat)
3110 /***********************************************************************
3111 * NdrConformantStructFree [RPCRT4.@]
3113 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3114 unsigned char *pMemory,
3115 PFORMAT_STRING pFormat)
3120 /***********************************************************************
3121 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3123 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3124 unsigned char *pMemory,
3125 PFORMAT_STRING pFormat)
3127 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3128 PFORMAT_STRING pCVArrayFormat;
3129 ULONG esize, bufsize;
3131 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3133 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3134 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3136 ERR("invalid format type %x\n", pCVStructFormat->type);
3137 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3141 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3142 pCVStructFormat->offset_to_array_description;
3143 switch (*pCVArrayFormat)
3145 case RPC_FC_CVARRAY:
3146 esize = *(const WORD*)(pCVArrayFormat+2);
3148 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3149 pCVArrayFormat + 4, 0);
3150 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3153 case RPC_FC_C_CSTRING:
3154 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3155 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3156 esize = sizeof(char);
3157 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3158 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3159 pCVArrayFormat + 2, 0);
3161 pStubMsg->MaxCount = pStubMsg->ActualCount;
3163 case RPC_FC_C_WSTRING:
3164 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3165 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3166 esize = sizeof(WCHAR);
3167 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3168 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3169 pCVArrayFormat + 2, 0);
3171 pStubMsg->MaxCount = pStubMsg->ActualCount;
3174 ERR("invalid array format type %x\n", *pCVArrayFormat);
3175 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3179 WriteConformance(pStubMsg);
3181 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3183 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3185 /* write constant sized part */
3186 pStubMsg->BufferMark = pStubMsg->Buffer;
3187 memcpy(pStubMsg->Buffer, pMemory, pCVStructFormat->memory_size);
3188 pStubMsg->Buffer += pCVStructFormat->memory_size;
3190 WriteVariance(pStubMsg);
3192 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3194 /* write array part */
3195 memcpy(pStubMsg->Buffer, pMemory + pCVStructFormat->memory_size, bufsize);
3196 pStubMsg->Buffer += bufsize;
3198 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3200 STD_OVERFLOW_CHECK(pStubMsg);
3205 /***********************************************************************
3206 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3208 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3209 unsigned char **ppMemory,
3210 PFORMAT_STRING pFormat,
3211 unsigned char fMustAlloc)
3213 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3214 PFORMAT_STRING pCVArrayFormat;
3215 ULONG esize, bufsize;
3216 unsigned char cvarray_type;
3218 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3220 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3221 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3223 ERR("invalid format type %x\n", pCVStructFormat->type);
3224 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3228 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3229 pCVStructFormat->offset_to_array_description;
3230 cvarray_type = *pCVArrayFormat;
3231 switch (cvarray_type)
3233 case RPC_FC_CVARRAY:
3234 esize = *(const WORD*)(pCVArrayFormat+2);
3235 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3237 case RPC_FC_C_CSTRING:
3238 esize = sizeof(char);
3239 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3240 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3242 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3244 case RPC_FC_C_WSTRING:
3245 esize = sizeof(WCHAR);
3246 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3247 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3249 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3252 ERR("invalid array format type %x\n", *pCVArrayFormat);
3253 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3257 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3259 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3261 /* work out how much memory to allocate if we need to do so */
3262 if (!*ppMemory || fMustAlloc)
3264 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3265 *ppMemory = NdrAllocate(pStubMsg, size);
3268 /* copy the constant data */
3269 pStubMsg->BufferMark = pStubMsg->Buffer;
3270 memcpy(*ppMemory, pStubMsg->Buffer, pCVStructFormat->memory_size);
3271 pStubMsg->Buffer += pCVStructFormat->memory_size;
3273 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3275 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3277 if ((cvarray_type == RPC_FC_C_CSTRING) ||
3278 (cvarray_type == RPC_FC_C_WSTRING))
3281 /* strings must always have null terminating bytes */
3282 if (bufsize < esize)
3284 ERR("invalid string length of %ld\n", pStubMsg->ActualCount);
3285 RpcRaiseException(RPC_S_INVALID_BOUND);
3288 for (i = bufsize - esize; i < bufsize; i++)
3289 if (pStubMsg->Buffer[i] != 0)
3291 ERR("string not null-terminated at byte position %ld, data is 0x%x\n",
3292 i, pStubMsg->Buffer[i]);
3293 RpcRaiseException(RPC_S_INVALID_BOUND);
3298 /* copy the array data */
3299 memcpy(*ppMemory + pCVStructFormat->memory_size, pStubMsg->Buffer,
3301 pStubMsg->Buffer += bufsize;
3303 if (cvarray_type == RPC_FC_C_CSTRING)
3304 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3305 else if (cvarray_type == RPC_FC_C_WSTRING)
3306 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3308 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3313 /***********************************************************************
3314 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3316 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3317 unsigned char *pMemory,
3318 PFORMAT_STRING pFormat)
3320 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3321 PFORMAT_STRING pCVArrayFormat;
3324 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3326 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3327 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3329 ERR("invalid format type %x\n", pCVStructFormat->type);
3330 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3334 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3335 pCVStructFormat->offset_to_array_description;
3336 switch (*pCVArrayFormat)
3338 case RPC_FC_CVARRAY:
3339 esize = *(const WORD*)(pCVArrayFormat+2);
3341 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3342 pCVArrayFormat + 4, 0);
3343 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3346 case RPC_FC_C_CSTRING:
3347 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3348 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3349 esize = sizeof(char);
3350 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3351 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3352 pCVArrayFormat + 2, 0);
3354 pStubMsg->MaxCount = pStubMsg->ActualCount;
3356 case RPC_FC_C_WSTRING:
3357 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3358 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3359 esize = sizeof(WCHAR);
3360 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3361 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3362 pCVArrayFormat + 2, 0);
3364 pStubMsg->MaxCount = pStubMsg->ActualCount;
3367 ERR("invalid array format type %x\n", *pCVArrayFormat);
3368 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3372 SizeConformance(pStubMsg);
3374 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
3376 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3378 pStubMsg->BufferLength += pCVStructFormat->memory_size;
3379 SizeVariance(pStubMsg);
3380 pStubMsg->BufferLength += safe_multiply(pStubMsg->MaxCount, esize);
3382 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3385 /***********************************************************************
3386 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3388 unsigned long WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3389 PFORMAT_STRING pFormat)
3391 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3392 PFORMAT_STRING pCVArrayFormat;
3394 unsigned char cvarray_type;
3396 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3398 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3399 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3401 ERR("invalid format type %x\n", pCVStructFormat->type);
3402 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3406 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3407 pCVStructFormat->offset_to_array_description;
3408 cvarray_type = *pCVArrayFormat;
3409 switch (cvarray_type)
3411 case RPC_FC_CVARRAY:
3412 esize = *(const WORD*)(pCVArrayFormat+2);
3413 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3415 case RPC_FC_C_CSTRING:
3416 esize = sizeof(char);
3417 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3418 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3420 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3422 case RPC_FC_C_WSTRING:
3423 esize = sizeof(WCHAR);
3424 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3425 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3427 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3430 ERR("invalid array format type %x\n", *pCVArrayFormat);
3431 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3435 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3437 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3439 pStubMsg->Buffer += pCVStructFormat->memory_size;
3440 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3441 pStubMsg->Buffer += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->ActualCount);
3443 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3445 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3447 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3450 /***********************************************************************
3451 * NdrConformantVaryingStructFree [RPCRT4.@]
3453 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3454 unsigned char *pMemory,
3455 PFORMAT_STRING pFormat)
3457 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3458 PFORMAT_STRING pCVArrayFormat;
3461 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3463 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3464 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3466 ERR("invalid format type %x\n", pCVStructFormat->type);
3467 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3471 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3472 pCVStructFormat->offset_to_array_description;
3473 switch (*pCVArrayFormat)
3475 case RPC_FC_CVARRAY:
3476 esize = *(const WORD*)(pCVArrayFormat+2);
3478 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3479 pCVArrayFormat + 4, 0);
3480 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3483 case RPC_FC_C_CSTRING:
3484 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3485 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3486 esize = sizeof(char);
3487 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3488 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3489 pCVArrayFormat + 2, 0);
3491 pStubMsg->MaxCount = pStubMsg->ActualCount;
3493 case RPC_FC_C_WSTRING:
3494 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3495 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3496 esize = sizeof(WCHAR);
3497 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3498 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3499 pCVArrayFormat + 2, 0);
3501 pStubMsg->MaxCount = pStubMsg->ActualCount;
3504 ERR("invalid array format type %x\n", *pCVArrayFormat);
3505 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3509 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3511 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3517 unsigned char alignment;
3518 unsigned short total_size;
3519 } NDR_SMFARRAY_FORMAT;
3524 unsigned char alignment;
3525 unsigned long total_size;
3526 } NDR_LGFARRAY_FORMAT;
3528 /***********************************************************************
3529 * NdrFixedArrayMarshall [RPCRT4.@]
3531 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3532 unsigned char *pMemory,
3533 PFORMAT_STRING pFormat)
3535 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3536 unsigned long total_size;
3538 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3540 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3541 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3543 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3544 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3548 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3550 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3552 total_size = pSmFArrayFormat->total_size;
3553 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3557 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3558 total_size = pLgFArrayFormat->total_size;
3559 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3562 memcpy(pStubMsg->Buffer, pMemory, total_size);
3563 pStubMsg->BufferMark = pStubMsg->Buffer;
3564 pStubMsg->Buffer += total_size;
3566 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3571 /***********************************************************************
3572 * NdrFixedArrayUnmarshall [RPCRT4.@]
3574 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3575 unsigned char **ppMemory,
3576 PFORMAT_STRING pFormat,
3577 unsigned char fMustAlloc)
3579 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3580 unsigned long total_size;
3582 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3584 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3585 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3587 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3588 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3592 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3594 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3596 total_size = pSmFArrayFormat->total_size;
3597 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3601 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3602 total_size = pLgFArrayFormat->total_size;
3603 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3606 if (fMustAlloc || !*ppMemory)
3607 *ppMemory = NdrAllocate(pStubMsg, total_size);
3608 memcpy(*ppMemory, pStubMsg->Buffer, total_size);
3609 pStubMsg->BufferMark = pStubMsg->Buffer;
3610 pStubMsg->Buffer += total_size;
3612 pFormat = EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3617 /***********************************************************************
3618 * NdrFixedArrayBufferSize [RPCRT4.@]
3620 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3621 unsigned char *pMemory,
3622 PFORMAT_STRING pFormat)
3624 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3625 unsigned long total_size;
3627 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3629 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3630 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3632 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3633 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3637 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
3639 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3641 total_size = pSmFArrayFormat->total_size;
3642 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3646 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3647 total_size = pLgFArrayFormat->total_size;
3648 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3650 pStubMsg->BufferLength += total_size;
3652 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3655 /***********************************************************************
3656 * NdrFixedArrayMemorySize [RPCRT4.@]
3658 unsigned long WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3659 PFORMAT_STRING pFormat)
3661 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3662 unsigned long total_size;
3664 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3666 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3667 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3669 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3670 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3674 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3676 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3678 total_size = pSmFArrayFormat->total_size;
3679 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3683 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3684 total_size = pLgFArrayFormat->total_size;
3685 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3687 pStubMsg->BufferMark = pStubMsg->Buffer;
3688 pStubMsg->Buffer += total_size;
3689 pStubMsg->MemorySize += total_size;
3691 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3696 /***********************************************************************
3697 * NdrFixedArrayFree [RPCRT4.@]
3699 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3700 unsigned char *pMemory,
3701 PFORMAT_STRING pFormat)
3703 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3705 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3707 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3708 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3710 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3711 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3715 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3716 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3719 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3720 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3723 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3726 /***********************************************************************
3727 * NdrVaryingArrayMarshall [RPCRT4.@]
3729 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3730 unsigned char *pMemory,
3731 PFORMAT_STRING pFormat)
3733 unsigned char alignment;
3734 DWORD elements, esize;
3737 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3739 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3740 (pFormat[0] != RPC_FC_LGVARRAY))
3742 ERR("invalid format type %x\n", pFormat[0]);
3743 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3747 alignment = pFormat[1] + 1;
3749 if (pFormat[0] == RPC_FC_SMVARRAY)
3752 pFormat += sizeof(WORD);
3753 elements = *(const WORD*)pFormat;
3754 pFormat += sizeof(WORD);
3759 pFormat += sizeof(DWORD);
3760 elements = *(const DWORD*)pFormat;
3761 pFormat += sizeof(DWORD);
3764 esize = *(const WORD*)pFormat;
3765 pFormat += sizeof(WORD);
3767 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3768 if ((pStubMsg->ActualCount > elements) ||
3769 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3771 RpcRaiseException(RPC_S_INVALID_BOUND);
3775 WriteVariance(pStubMsg);
3777 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3779 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3780 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
3781 pStubMsg->BufferMark = pStubMsg->Buffer;
3782 pStubMsg->Buffer += bufsize;
3784 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3786 STD_OVERFLOW_CHECK(pStubMsg);
3791 /***********************************************************************
3792 * NdrVaryingArrayUnmarshall [RPCRT4.@]
3794 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3795 unsigned char **ppMemory,
3796 PFORMAT_STRING pFormat,
3797 unsigned char fMustAlloc)
3799 unsigned char alignment;
3800 DWORD size, elements, esize;
3803 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3805 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3806 (pFormat[0] != RPC_FC_LGVARRAY))
3808 ERR("invalid format type %x\n", pFormat[0]);
3809 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3813 alignment = pFormat[1] + 1;
3815 if (pFormat[0] == RPC_FC_SMVARRAY)
3818 size = *(const WORD*)pFormat;
3819 pFormat += sizeof(WORD);
3820 elements = *(const WORD*)pFormat;
3821 pFormat += sizeof(WORD);
3826 size = *(const DWORD*)pFormat;
3827 pFormat += sizeof(DWORD);
3828 elements = *(const DWORD*)pFormat;
3829 pFormat += sizeof(DWORD);
3832 esize = *(const WORD*)pFormat;
3833 pFormat += sizeof(WORD);
3835 pFormat = ReadVariance(pStubMsg, pFormat, elements);
3837 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3839 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3841 if (!*ppMemory || fMustAlloc)
3842 *ppMemory = NdrAllocate(pStubMsg, size);
3843 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
3844 pStubMsg->Buffer += bufsize;
3846 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3851 /***********************************************************************
3852 * NdrVaryingArrayBufferSize [RPCRT4.@]
3854 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3855 unsigned char *pMemory,
3856 PFORMAT_STRING pFormat)
3858 unsigned char alignment;
3859 DWORD elements, esize;
3861 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3863 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3864 (pFormat[0] != RPC_FC_LGVARRAY))
3866 ERR("invalid format type %x\n", pFormat[0]);
3867 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3871 alignment = pFormat[1] + 1;
3873 if (pFormat[0] == RPC_FC_SMVARRAY)
3876 pFormat += sizeof(WORD);
3877 elements = *(const WORD*)pFormat;
3878 pFormat += sizeof(WORD);
3883 pFormat += sizeof(DWORD);
3884 elements = *(const DWORD*)pFormat;
3885 pFormat += sizeof(DWORD);
3888 esize = *(const WORD*)pFormat;
3889 pFormat += sizeof(WORD);
3891 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3892 if ((pStubMsg->ActualCount > elements) ||
3893 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3895 RpcRaiseException(RPC_S_INVALID_BOUND);
3899 SizeVariance(pStubMsg);
3901 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3903 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
3905 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3908 /***********************************************************************
3909 * NdrVaryingArrayMemorySize [RPCRT4.@]
3911 unsigned long WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3912 PFORMAT_STRING pFormat)
3914 unsigned char alignment;
3915 DWORD size, elements, esize;
3917 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3919 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3920 (pFormat[0] != RPC_FC_LGVARRAY))
3922 ERR("invalid format type %x\n", pFormat[0]);
3923 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3927 alignment = pFormat[1] + 1;
3929 if (pFormat[0] == RPC_FC_SMVARRAY)
3932 size = *(const WORD*)pFormat;
3933 pFormat += sizeof(WORD);
3934 elements = *(const WORD*)pFormat;
3935 pFormat += sizeof(WORD);
3940 size = *(const DWORD*)pFormat;
3941 pFormat += sizeof(DWORD);
3942 elements = *(const DWORD*)pFormat;
3943 pFormat += sizeof(DWORD);
3946 esize = *(const WORD*)pFormat;
3947 pFormat += sizeof(WORD);
3949 pFormat = ReadVariance(pStubMsg, pFormat, elements);
3951 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3953 pStubMsg->Buffer += safe_multiply(esize, pStubMsg->ActualCount);
3954 pStubMsg->MemorySize += size;
3956 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3958 return pStubMsg->MemorySize;
3961 /***********************************************************************
3962 * NdrVaryingArrayFree [RPCRT4.@]
3964 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3965 unsigned char *pMemory,
3966 PFORMAT_STRING pFormat)
3968 unsigned char alignment;
3971 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3973 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3974 (pFormat[0] != RPC_FC_LGVARRAY))
3976 ERR("invalid format type %x\n", pFormat[0]);
3977 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3981 alignment = pFormat[1] + 1;
3983 if (pFormat[0] == RPC_FC_SMVARRAY)
3986 pFormat += sizeof(WORD);
3987 elements = *(const WORD*)pFormat;
3988 pFormat += sizeof(WORD);
3993 pFormat += sizeof(DWORD);
3994 elements = *(const DWORD*)pFormat;
3995 pFormat += sizeof(DWORD);
3998 pFormat += sizeof(WORD);
4000 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4001 if ((pStubMsg->ActualCount > elements) ||
4002 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4004 RpcRaiseException(RPC_S_INVALID_BOUND);
4008 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4011 /***********************************************************************
4012 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4014 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4015 unsigned char *pMemory,
4016 PFORMAT_STRING pFormat)
4022 /***********************************************************************
4023 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4025 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4026 unsigned char **ppMemory,
4027 PFORMAT_STRING pFormat,
4028 unsigned char fMustAlloc)
4034 /***********************************************************************
4035 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4037 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4038 unsigned char *pMemory,
4039 PFORMAT_STRING pFormat)
4044 /***********************************************************************
4045 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4047 unsigned long WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4048 PFORMAT_STRING pFormat)
4054 /***********************************************************************
4055 * NdrEncapsulatedUnionFree [RPCRT4.@]
4057 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4058 unsigned char *pMemory,
4059 PFORMAT_STRING pFormat)
4064 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4065 unsigned long discriminant,
4066 PFORMAT_STRING pFormat)
4068 unsigned short num_arms, arm, type;
4070 num_arms = *(const SHORT*)pFormat & 0x0fff;
4072 for(arm = 0; arm < num_arms; arm++)
4074 if(discriminant == *(const ULONG*)pFormat)
4082 type = *(const unsigned short*)pFormat;
4083 TRACE("type %04x\n", type);
4084 if(arm == num_arms) /* default arm extras */
4088 ERR("no arm for 0x%lx and no default case\n", discriminant);
4089 RpcRaiseException(RPC_S_INVALID_TAG);
4094 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
4101 static PFORMAT_STRING get_non_encapsulated_union_arm(PMIDL_STUB_MESSAGE pStubMsg,
4103 PFORMAT_STRING pFormat)
4105 pFormat += *(const SHORT*)pFormat;
4108 return get_arm_offset_from_union_arm_selector(pStubMsg, value, pFormat);
4111 /***********************************************************************
4112 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
4114 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4115 unsigned char *pMemory,
4116 PFORMAT_STRING pFormat)
4118 unsigned short type;
4119 unsigned char switch_type;
4121 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4124 switch_type = *pFormat;
4127 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4128 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4129 /* Marshall discriminant */
4130 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4132 pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
4136 type = *(const unsigned short*)pFormat;
4137 if((type & 0xff00) == 0x8000)
4139 unsigned char basetype = LOBYTE(type);
4140 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
4144 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4145 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
4148 unsigned char *saved_buffer = NULL;
4155 saved_buffer = pStubMsg->Buffer;
4156 pStubMsg->Buffer += 4; /* for pointer ID */
4157 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
4160 m(pStubMsg, pMemory, desc);
4163 else FIXME("no marshaller for embedded type %02x\n", *desc);
4168 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
4169 PFORMAT_STRING *ppFormat)
4171 long discriminant = 0;
4179 discriminant = *(UCHAR *)pStubMsg->Buffer;
4180 pStubMsg->Buffer += sizeof(UCHAR);
4185 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4186 discriminant = *(USHORT *)pStubMsg->Buffer;
4187 pStubMsg->Buffer += sizeof(USHORT);
4191 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4192 discriminant = *(ULONG *)pStubMsg->Buffer;
4193 pStubMsg->Buffer += sizeof(ULONG);
4196 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
4200 if (pStubMsg->fHasNewCorrDesc)
4204 return discriminant;
4207 /**********************************************************************
4208 * NdrNonEncapsulatedUnionUnmarshall[RPCRT4.@]
4210 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4211 unsigned char **ppMemory,
4212 PFORMAT_STRING pFormat,
4213 unsigned char fMustAlloc)
4216 unsigned short type, size;
4218 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4221 /* Unmarshall discriminant */
4222 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4223 TRACE("unmarshalled discriminant %lx\n", discriminant);
4225 pFormat += *(const SHORT*)pFormat;
4227 size = *(const unsigned short*)pFormat;
4230 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4234 if(!*ppMemory || fMustAlloc)
4235 *ppMemory = NdrAllocate(pStubMsg, size);
4237 type = *(const unsigned short*)pFormat;
4238 if((type & 0xff00) == 0x8000)
4240 unsigned char basetype = LOBYTE(type);
4241 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, fMustAlloc);
4245 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4246 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
4249 unsigned char *saved_buffer = NULL;
4256 ALIGN_POINTER(pStubMsg->Buffer, 4);
4257 saved_buffer = pStubMsg->Buffer;
4258 pStubMsg->Buffer += 4; /* for pointer ID */
4259 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, desc, TRUE);
4262 m(pStubMsg, ppMemory, desc, fMustAlloc);
4265 else FIXME("no marshaller for embedded type %02x\n", *desc);
4270 /***********************************************************************
4271 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
4273 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4274 unsigned char *pMemory,
4275 PFORMAT_STRING pFormat)
4277 unsigned short type;
4278 unsigned char switch_type;
4280 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4283 switch_type = *pFormat;
4286 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4287 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4288 /* Add discriminant size */
4289 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4291 pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
4295 type = *(const unsigned short*)pFormat;
4296 if((type & 0xff00) == 0x8000)
4298 unsigned char basetype = LOBYTE(type);
4299 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
4303 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4304 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
4313 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4314 pStubMsg->BufferLength += 4; /* for pointer ID */
4315 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
4318 m(pStubMsg, pMemory, desc);
4321 else FIXME("no buffersizer for embedded type %02x\n", *desc);
4326 /***********************************************************************
4327 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
4329 unsigned long WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4330 PFORMAT_STRING pFormat)
4332 unsigned long discriminant;
4333 unsigned short type, size;
4336 /* Unmarshall discriminant */
4337 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4338 TRACE("unmarshalled discriminant 0x%lx\n", discriminant);
4340 pFormat += *(const SHORT*)pFormat;
4342 size = *(const unsigned short*)pFormat;
4345 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4349 pStubMsg->Memory += size;
4351 type = *(const unsigned short*)pFormat;
4352 if((type & 0xff00) == 0x8000)
4354 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
4358 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4359 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
4360 unsigned char *saved_buffer;
4369 ALIGN_POINTER(pStubMsg->Buffer, 4);
4370 saved_buffer = pStubMsg->Buffer;
4371 pStubMsg->Buffer += 4;
4372 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
4373 pStubMsg->MemorySize += 4;
4374 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
4377 return m(pStubMsg, desc);
4380 else FIXME("no marshaller for embedded type %02x\n", *desc);
4383 TRACE("size %d\n", size);
4387 /***********************************************************************
4388 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
4390 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4391 unsigned char *pMemory,
4392 PFORMAT_STRING pFormat)
4397 /***********************************************************************
4398 * NdrByteCountPointerMarshall [RPCRT4.@]
4400 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4401 unsigned char *pMemory,
4402 PFORMAT_STRING pFormat)
4408 /***********************************************************************
4409 * NdrByteCountPointerUnmarshall [RPCRT4.@]
4411 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4412 unsigned char **ppMemory,
4413 PFORMAT_STRING pFormat,
4414 unsigned char fMustAlloc)
4420 /***********************************************************************
4421 * NdrByteCountPointerBufferSize [RPCRT4.@]
4423 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4424 unsigned char *pMemory,
4425 PFORMAT_STRING pFormat)
4430 /***********************************************************************
4431 * NdrByteCountPointerMemorySize [RPCRT4.@]
4433 unsigned long WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4434 PFORMAT_STRING pFormat)
4440 /***********************************************************************
4441 * NdrByteCountPointerFree [RPCRT4.@]
4443 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
4444 unsigned char *pMemory,
4445 PFORMAT_STRING pFormat)
4450 /***********************************************************************
4451 * NdrXmitOrRepAsMarshall [RPCRT4.@]
4453 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4454 unsigned char *pMemory,
4455 PFORMAT_STRING pFormat)
4461 /***********************************************************************
4462 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
4464 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4465 unsigned char **ppMemory,
4466 PFORMAT_STRING pFormat,
4467 unsigned char fMustAlloc)
4473 /***********************************************************************
4474 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
4476 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4477 unsigned char *pMemory,
4478 PFORMAT_STRING pFormat)
4483 /***********************************************************************
4484 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
4486 unsigned long WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4487 PFORMAT_STRING pFormat)
4493 /***********************************************************************
4494 * NdrXmitOrRepAsFree [RPCRT4.@]
4496 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
4497 unsigned char *pMemory,
4498 PFORMAT_STRING pFormat)
4503 /***********************************************************************
4504 * NdrBaseTypeMarshall [internal]
4506 static unsigned char *WINAPI NdrBaseTypeMarshall(
4507 PMIDL_STUB_MESSAGE pStubMsg,
4508 unsigned char *pMemory,
4509 PFORMAT_STRING pFormat)
4511 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4519 *(UCHAR *)pStubMsg->Buffer = *(UCHAR *)pMemory;
4520 pStubMsg->Buffer += sizeof(UCHAR);
4521 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
4526 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4527 *(USHORT *)pStubMsg->Buffer = *(USHORT *)pMemory;
4528 pStubMsg->Buffer += sizeof(USHORT);
4529 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
4533 case RPC_FC_ERROR_STATUS_T:
4535 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4536 *(ULONG *)pStubMsg->Buffer = *(ULONG *)pMemory;
4537 pStubMsg->Buffer += sizeof(ULONG);
4538 TRACE("value: 0x%08lx\n", *(ULONG *)pMemory);
4541 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
4542 *(float *)pStubMsg->Buffer = *(float *)pMemory;
4543 pStubMsg->Buffer += sizeof(float);
4546 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
4547 *(double *)pStubMsg->Buffer = *(double *)pMemory;
4548 pStubMsg->Buffer += sizeof(double);
4551 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
4552 *(ULONGLONG *)pStubMsg->Buffer = *(ULONGLONG *)pMemory;
4553 pStubMsg->Buffer += sizeof(ULONGLONG);
4554 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
4557 /* only 16-bits on the wire, so do a sanity check */
4558 if (*(UINT *)pMemory > USHRT_MAX)
4559 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
4560 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4561 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
4562 pStubMsg->Buffer += sizeof(USHORT);
4563 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
4566 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4569 STD_OVERFLOW_CHECK(pStubMsg);
4571 /* FIXME: what is the correct return value? */
4575 /***********************************************************************
4576 * NdrBaseTypeUnmarshall [internal]
4578 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
4579 PMIDL_STUB_MESSAGE pStubMsg,
4580 unsigned char **ppMemory,
4581 PFORMAT_STRING pFormat,
4582 unsigned char fMustAlloc)
4584 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
4586 #define BASE_TYPE_UNMARSHALL(type) \
4587 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
4588 if (fMustAlloc || !*ppMemory) \
4589 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
4590 TRACE("*ppMemory: %p\n", *ppMemory); \
4591 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
4592 pStubMsg->Buffer += sizeof(type);
4600 BASE_TYPE_UNMARSHALL(UCHAR);
4601 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
4606 BASE_TYPE_UNMARSHALL(USHORT);
4607 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
4611 case RPC_FC_ERROR_STATUS_T:
4613 BASE_TYPE_UNMARSHALL(ULONG);
4614 TRACE("value: 0x%08lx\n", **(ULONG **)ppMemory);
4617 BASE_TYPE_UNMARSHALL(float);
4618 TRACE("value: %f\n", **(float **)ppMemory);
4621 BASE_TYPE_UNMARSHALL(double);
4622 TRACE("value: %f\n", **(double **)ppMemory);
4625 BASE_TYPE_UNMARSHALL(ULONGLONG);
4626 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
4629 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4630 if (fMustAlloc || !*ppMemory)
4631 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
4632 TRACE("*ppMemory: %p\n", *ppMemory);
4633 /* 16-bits on the wire, but int in memory */
4634 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
4635 pStubMsg->Buffer += sizeof(USHORT);
4636 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
4639 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4641 #undef BASE_TYPE_UNMARSHALL
4643 /* FIXME: what is the correct return value? */
4648 /***********************************************************************
4649 * NdrBaseTypeBufferSize [internal]
4651 static void WINAPI NdrBaseTypeBufferSize(
4652 PMIDL_STUB_MESSAGE pStubMsg,
4653 unsigned char *pMemory,
4654 PFORMAT_STRING pFormat)
4656 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4664 pStubMsg->BufferLength += sizeof(UCHAR);
4670 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
4671 pStubMsg->BufferLength += sizeof(USHORT);
4676 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
4677 pStubMsg->BufferLength += sizeof(ULONG);
4680 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
4681 pStubMsg->BufferLength += sizeof(float);
4684 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
4685 pStubMsg->BufferLength += sizeof(double);
4688 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
4689 pStubMsg->BufferLength += sizeof(ULONGLONG);
4691 case RPC_FC_ERROR_STATUS_T:
4692 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
4693 pStubMsg->BufferLength += sizeof(error_status_t);
4696 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4700 /***********************************************************************
4701 * NdrBaseTypeMemorySize [internal]
4703 static unsigned long WINAPI NdrBaseTypeMemorySize(
4704 PMIDL_STUB_MESSAGE pStubMsg,
4705 PFORMAT_STRING pFormat)
4713 pStubMsg->Buffer += sizeof(UCHAR);
4714 pStubMsg->MemorySize += sizeof(UCHAR);
4715 return sizeof(UCHAR);
4719 pStubMsg->Buffer += sizeof(USHORT);
4720 pStubMsg->MemorySize += sizeof(USHORT);
4721 return sizeof(USHORT);
4724 pStubMsg->Buffer += sizeof(ULONG);
4725 pStubMsg->MemorySize += sizeof(ULONG);
4726 return sizeof(ULONG);
4728 pStubMsg->Buffer += sizeof(float);
4729 pStubMsg->MemorySize += sizeof(float);
4730 return sizeof(float);
4732 pStubMsg->Buffer += sizeof(double);
4733 pStubMsg->MemorySize += sizeof(double);
4734 return sizeof(double);
4736 pStubMsg->Buffer += sizeof(ULONGLONG);
4737 pStubMsg->MemorySize += sizeof(ULONGLONG);
4738 return sizeof(ULONGLONG);
4739 case RPC_FC_ERROR_STATUS_T:
4740 pStubMsg->Buffer += sizeof(error_status_t);
4741 pStubMsg->MemorySize += sizeof(error_status_t);
4742 return sizeof(error_status_t);
4745 pStubMsg->Buffer += sizeof(INT);
4746 pStubMsg->MemorySize += sizeof(INT);
4749 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4754 /***********************************************************************
4755 * NdrBaseTypeFree [internal]
4757 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
4758 unsigned char *pMemory,
4759 PFORMAT_STRING pFormat)
4761 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4766 /***********************************************************************
4767 * NdrClientContextMarshall
4769 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4770 NDR_CCONTEXT ContextHandle,
4773 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
4775 ALIGN_POINTER(pStubMsg->Buffer, 4);
4777 /* FIXME: what does fCheck do? */
4778 NDRCContextMarshall(ContextHandle,
4781 pStubMsg->Buffer += cbNDRContext;
4784 /***********************************************************************
4785 * NdrClientContextUnmarshall
4787 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4788 NDR_CCONTEXT * pContextHandle,
4789 RPC_BINDING_HANDLE BindHandle)
4791 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
4793 ALIGN_POINTER(pStubMsg->Buffer, 4);
4795 NDRCContextUnmarshall(pContextHandle,
4798 pStubMsg->RpcMsg->DataRepresentation);
4800 pStubMsg->Buffer += cbNDRContext;
4803 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4804 NDR_SCONTEXT ContextHandle,
4805 NDR_RUNDOWN RundownRoutine )
4807 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
4810 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
4812 FIXME("(%p): stub\n", pStubMsg);
4816 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
4817 unsigned char* pMemory,
4818 PFORMAT_STRING pFormat)
4820 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
4823 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
4824 PFORMAT_STRING pFormat)
4826 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
4830 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4831 NDR_SCONTEXT ContextHandle,
4832 NDR_RUNDOWN RundownRoutine,
4833 PFORMAT_STRING pFormat)
4835 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
4838 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4839 PFORMAT_STRING pFormat)
4841 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
4845 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
4847 typedef struct ndr_context_handle
4851 } ndr_context_handle;
4853 struct context_handle_entry
4857 RPC_BINDING_HANDLE handle;
4858 ndr_context_handle wire_data;
4861 static struct list context_handle_list = LIST_INIT(context_handle_list);
4863 static CRITICAL_SECTION ndr_context_cs;
4864 static CRITICAL_SECTION_DEBUG ndr_context_debug =
4866 0, 0, &ndr_context_cs,
4867 { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
4868 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
4870 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
4872 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
4874 struct context_handle_entry *che = (struct context_handle_entry*) CContext;
4876 if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
4881 static struct context_handle_entry *context_entry_from_guid(LPGUID uuid)
4883 struct context_handle_entry *che;
4884 LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
4885 if (IsEqualGUID(&che->wire_data.uuid, uuid))
4890 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
4892 struct context_handle_entry *che;
4893 RPC_BINDING_HANDLE handle = NULL;
4895 TRACE("%p\n", CContext);
4897 EnterCriticalSection(&ndr_context_cs);
4898 che = get_context_entry(CContext);
4900 handle = che->handle;
4901 LeaveCriticalSection(&ndr_context_cs);
4904 RpcRaiseException(ERROR_INVALID_HANDLE);
4908 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
4910 struct context_handle_entry *che;
4912 TRACE("%p %p\n", CContext, pBuff);
4916 EnterCriticalSection(&ndr_context_cs);
4917 che = get_context_entry(CContext);
4918 memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
4919 LeaveCriticalSection(&ndr_context_cs);
4923 ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
4924 wire_data->attributes = 0;
4925 wire_data->uuid = GUID_NULL;
4929 static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
4930 RPC_BINDING_HANDLE hBinding,
4931 ndr_context_handle *chi)
4933 struct context_handle_entry *che = NULL;
4935 /* a null UUID means we should free the context handle */
4936 if (IsEqualGUID(&chi->uuid, &GUID_NULL))
4940 che = get_context_entry(*CContext);
4942 return ERROR_INVALID_HANDLE;
4943 list_remove(&che->entry);
4944 RpcBindingFree(&che->handle);
4945 HeapFree(GetProcessHeap(), 0, che);
4949 /* if there's no existing entry matching the GUID, allocate one */
4950 else if (!(che = context_entry_from_guid(&chi->uuid)))
4952 che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
4954 return ERROR_NOT_ENOUGH_MEMORY;
4955 che->magic = NDR_CONTEXT_HANDLE_MAGIC;
4956 RpcBindingCopy(hBinding, &che->handle);
4957 list_add_tail(&context_handle_list, &che->entry);
4958 memcpy(&che->wire_data, chi, sizeof *chi);
4963 return ERROR_SUCCESS;
4966 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
4967 RPC_BINDING_HANDLE hBinding,
4969 unsigned long DataRepresentation)
4973 TRACE("*%p=(%p) %p %p %08lx\n",
4974 CContext, *CContext, hBinding, pBuff, DataRepresentation);
4976 EnterCriticalSection(&ndr_context_cs);
4977 r = ndr_update_context_handle(CContext, hBinding, pBuff);
4978 LeaveCriticalSection(&ndr_context_cs);
4980 RpcRaiseException(r);
4983 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
4985 NDR_RUNDOWN userRunDownIn)
4987 FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn);
4990 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
4991 NDR_SCONTEXT CContext,
4993 NDR_RUNDOWN userRunDownIn)
4995 FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn);
4998 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
4999 NDR_SCONTEXT CContext,
5001 NDR_RUNDOWN userRunDownIn,
5003 unsigned long Flags)
5005 FIXME("(%p %p %p %p %p %lu): stub\n",
5006 hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags);
5009 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
5010 unsigned long DataRepresentation)
5012 FIXME("(%p %08lx): stub\n", pBuff, DataRepresentation);
5016 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
5018 unsigned long DataRepresentation)
5020 FIXME("(%p %p %08lx): stub\n", hBinding, pBuff, DataRepresentation);
5024 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
5026 unsigned long DataRepresentation,
5028 unsigned long Flags)
5030 FIXME("(%p %p %08lx %p %lu): stub\n",
5031 hBinding, pBuff, DataRepresentation, CtxGuard, Flags);