4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 * - Non-conformant strings
24 * - Encapsulated unions
25 * - Byte count pointers
26 * - transmit_as/represent as
27 * - Multi-dimensional arrays
28 * - Conversion functions (NdrConvert)
29 * - Checks for integer overflow when calculating array sizes
30 * - Checks for out-of-memory conditions
47 #include "wine/unicode.h"
48 #include "wine/rpcfc.h"
50 #include "wine/debug.h"
51 #include "wine/list.h"
53 WINE_DEFAULT_DEBUG_CHANNEL(ole);
56 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
57 (*((UINT32 *)(pchar)) = (uint32))
59 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
60 (*((UINT32 *)(pchar)))
62 /* these would work for i386 too, but less efficient */
63 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
64 (*(pchar) = LOBYTE(LOWORD(uint32)), \
65 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
66 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
67 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
68 (uint32)) /* allow as r-value */
70 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
72 MAKEWORD(*(pchar), *((pchar)+1)), \
73 MAKEWORD(*((pchar)+2), *((pchar)+3))))
76 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
77 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
78 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
79 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
80 *(pchar) = HIBYTE(HIWORD(uint32)), \
81 (uint32)) /* allow as r-value */
83 #define BIG_ENDIAN_UINT32_READ(pchar) \
85 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
86 MAKEWORD(*((pchar)+1), *(pchar))))
88 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
89 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
90 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
91 # define NDR_LOCAL_UINT32_READ(pchar) \
92 BIG_ENDIAN_UINT32_READ(pchar)
94 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
95 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
96 # define NDR_LOCAL_UINT32_READ(pchar) \
97 LITTLE_ENDIAN_UINT32_READ(pchar)
100 /* _Align must be the desired alignment,
101 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
102 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
103 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
104 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
105 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
107 #define STD_OVERFLOW_CHECK(_Msg) do { \
108 TRACE("buffer=%d/%ld\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
109 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
110 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
113 #define NDR_TABLE_SIZE 128
114 #define NDR_TABLE_MASK 127
116 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
117 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
118 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
119 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
120 static unsigned long WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
122 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
124 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
125 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
126 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
127 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
131 NdrPointerMarshall, NdrPointerMarshall,
132 NdrPointerMarshall, NdrPointerMarshall,
134 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
135 NdrConformantStructMarshall, NdrConformantStructMarshall,
136 NdrConformantVaryingStructMarshall,
137 NdrComplexStructMarshall,
139 NdrConformantArrayMarshall,
140 NdrConformantVaryingArrayMarshall,
141 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
142 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
143 NdrComplexArrayMarshall,
145 NdrConformantStringMarshall, 0, 0,
146 NdrConformantStringMarshall,
147 NdrNonConformantStringMarshall, 0, 0, 0,
149 NdrEncapsulatedUnionMarshall,
150 NdrNonEncapsulatedUnionMarshall,
151 NdrByteCountPointerMarshall,
152 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
154 NdrInterfacePointerMarshall,
157 NdrUserMarshalMarshall
159 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
161 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
162 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
163 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
164 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
166 NdrBaseTypeUnmarshall,
168 NdrPointerUnmarshall, NdrPointerUnmarshall,
169 NdrPointerUnmarshall, NdrPointerUnmarshall,
171 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
172 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
173 NdrConformantVaryingStructUnmarshall,
174 NdrComplexStructUnmarshall,
176 NdrConformantArrayUnmarshall,
177 NdrConformantVaryingArrayUnmarshall,
178 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
179 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
180 NdrComplexArrayUnmarshall,
182 NdrConformantStringUnmarshall, 0, 0,
183 NdrConformantStringUnmarshall,
184 NdrNonConformantStringUnmarshall, 0, 0, 0,
186 NdrEncapsulatedUnionUnmarshall,
187 NdrNonEncapsulatedUnionUnmarshall,
188 NdrByteCountPointerUnmarshall,
189 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
191 NdrInterfacePointerUnmarshall,
194 NdrUserMarshalUnmarshall
196 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
198 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
199 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
200 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
201 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
203 NdrBaseTypeBufferSize,
205 NdrPointerBufferSize, NdrPointerBufferSize,
206 NdrPointerBufferSize, NdrPointerBufferSize,
208 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
209 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
210 NdrConformantVaryingStructBufferSize,
211 NdrComplexStructBufferSize,
213 NdrConformantArrayBufferSize,
214 NdrConformantVaryingArrayBufferSize,
215 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
216 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
217 NdrComplexArrayBufferSize,
219 NdrConformantStringBufferSize, 0, 0,
220 NdrConformantStringBufferSize,
221 NdrNonConformantStringBufferSize, 0, 0, 0,
223 NdrEncapsulatedUnionBufferSize,
224 NdrNonEncapsulatedUnionBufferSize,
225 NdrByteCountPointerBufferSize,
226 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
228 NdrInterfacePointerBufferSize,
231 NdrUserMarshalBufferSize
233 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
235 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
236 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
237 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
238 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
240 NdrBaseTypeMemorySize,
242 NdrPointerMemorySize, NdrPointerMemorySize,
243 NdrPointerMemorySize, NdrPointerMemorySize,
245 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
246 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
247 NdrConformantVaryingStructMemorySize,
248 NdrComplexStructMemorySize,
250 NdrConformantArrayMemorySize,
251 NdrConformantVaryingArrayMemorySize,
252 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
253 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
254 NdrComplexArrayMemorySize,
256 NdrConformantStringMemorySize, 0, 0,
257 NdrConformantStringMemorySize,
258 NdrNonConformantStringMemorySize, 0, 0, 0,
260 NdrEncapsulatedUnionMemorySize,
261 NdrNonEncapsulatedUnionMemorySize,
262 NdrByteCountPointerMemorySize,
263 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
265 NdrInterfacePointerMemorySize,
268 NdrUserMarshalMemorySize
270 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
272 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
273 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
274 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
275 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
279 NdrPointerFree, NdrPointerFree,
280 NdrPointerFree, NdrPointerFree,
282 NdrSimpleStructFree, NdrSimpleStructFree,
283 NdrConformantStructFree, NdrConformantStructFree,
284 NdrConformantVaryingStructFree,
285 NdrComplexStructFree,
287 NdrConformantArrayFree,
288 NdrConformantVaryingArrayFree,
289 NdrFixedArrayFree, NdrFixedArrayFree,
290 NdrVaryingArrayFree, NdrVaryingArrayFree,
296 NdrEncapsulatedUnionFree,
297 NdrNonEncapsulatedUnionFree,
299 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
301 NdrInterfacePointerFree,
307 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
309 /* hmm, this is probably supposed to do more? */
310 return pStubMsg->pfnAllocate(len);
313 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
315 pStubMsg->pfnFree(Pointer);
318 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
320 return (*(const ULONG *)pFormat != -1);
323 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
325 ALIGN_POINTER(pStubMsg->Buffer, 4);
326 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
327 pStubMsg->Buffer += 4;
328 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
329 if (pStubMsg->fHasNewCorrDesc)
335 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
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);
353 if (pStubMsg->fHasNewCorrDesc)
359 /* writes the conformance value to the buffer */
360 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
362 ALIGN_POINTER(pStubMsg->Buffer, 4);
363 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
364 pStubMsg->Buffer += 4;
367 /* writes the variance values to the buffer */
368 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
370 ALIGN_POINTER(pStubMsg->Buffer, 4);
371 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
372 pStubMsg->Buffer += 4;
373 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
374 pStubMsg->Buffer += 4;
377 /* requests buffer space for the conformance value */
378 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
380 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
381 pStubMsg->BufferLength += 4;
384 /* requests buffer space for the variance values */
385 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
387 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
388 pStubMsg->BufferLength += 8;
391 PFORMAT_STRING ComputeConformanceOrVariance(
392 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
393 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG *pCount)
395 BYTE dtype = pFormat[0] & 0xf;
396 short ofs = *(short *)&pFormat[2];
400 if (!IsConformanceOrVariancePresent(pFormat)) {
401 /* null descriptor */
406 switch (pFormat[0] & 0xf0) {
407 case RPC_FC_NORMAL_CONFORMANCE:
408 TRACE("normal conformance, ofs=%d\n", ofs);
411 case RPC_FC_POINTER_CONFORMANCE:
412 TRACE("pointer conformance, ofs=%d\n", ofs);
413 ptr = pStubMsg->Memory;
415 case RPC_FC_TOP_LEVEL_CONFORMANCE:
416 TRACE("toplevel conformance, ofs=%d\n", ofs);
417 if (pStubMsg->StackTop) {
418 ptr = pStubMsg->StackTop;
421 /* -Os mode, *pCount is already set */
425 case RPC_FC_CONSTANT_CONFORMANCE:
426 data = ofs | ((DWORD)pFormat[1] << 16);
427 TRACE("constant conformance, val=%ld\n", data);
430 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
431 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
432 if (pStubMsg->StackTop) {
433 ptr = pStubMsg->StackTop;
441 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
444 switch (pFormat[1]) {
445 case RPC_FC_DEREFERENCE:
446 ptr = *(LPVOID*)((char *)ptr + ofs);
448 case RPC_FC_CALLBACK:
450 unsigned char *old_stack_top = pStubMsg->StackTop;
451 pStubMsg->StackTop = ptr;
453 /* ofs is index into StubDesc->apfnExprEval */
454 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
455 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
457 pStubMsg->StackTop = old_stack_top;
461 ptr = (char *)ptr + ofs;
474 data = *(USHORT*)ptr;
485 FIXME("unknown conformance data type %x\n", dtype);
488 TRACE("dereferenced data type %x at %p, got %ld\n", dtype, ptr, data);
491 switch (pFormat[1]) {
492 case RPC_FC_DEREFERENCE: /* already handled */
509 FIXME("unknown conformance op %d\n", pFormat[1]);
514 TRACE("resulting conformance is %ld\n", *pCount);
515 if (pStubMsg->fHasNewCorrDesc)
521 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
522 * the result overflows 32-bits */
523 static ULONG inline safe_multiply(ULONG a, ULONG b)
525 ULONGLONG ret = (ULONGLONG)a * b;
526 if (ret > 0xffffffff)
528 RpcRaiseException(RPC_S_INVALID_BOUND);
536 * NdrConformantString:
538 * What MS calls a ConformantString is, in DCE terminology,
539 * a Varying-Conformant String.
541 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
542 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
543 * into unmarshalled string)
544 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
546 * data: CHARTYPE[maxlen]
548 * ], where CHARTYPE is the appropriate character type (specified externally)
552 /***********************************************************************
553 * NdrConformantStringMarshall [RPCRT4.@]
555 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
556 unsigned char *pszMessage, PFORMAT_STRING pFormat)
560 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
562 if (*pFormat == RPC_FC_C_CSTRING) {
563 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
564 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
567 else if (*pFormat == RPC_FC_C_WSTRING) {
568 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
569 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
573 ERR("Unhandled string type: %#x\n", *pFormat);
574 /* FIXME: raise an exception. */
578 if (pFormat[1] == RPC_FC_STRING_SIZED)
579 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
581 pStubMsg->MaxCount = pStubMsg->ActualCount;
582 pStubMsg->Offset = 0;
583 WriteConformance(pStubMsg);
584 WriteVariance(pStubMsg);
586 size = safe_multiply(esize, pStubMsg->ActualCount);
587 memcpy(pStubMsg->Buffer, pszMessage, size); /* the string itself */
588 pStubMsg->Buffer += size;
590 STD_OVERFLOW_CHECK(pStubMsg);
593 return NULL; /* is this always right? */
596 /***********************************************************************
597 * NdrConformantStringBufferSize [RPCRT4.@]
599 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
600 unsigned char* pMemory, PFORMAT_STRING pFormat)
604 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
606 SizeConformance(pStubMsg);
607 SizeVariance(pStubMsg);
609 if (*pFormat == RPC_FC_C_CSTRING) {
610 TRACE("string=%s\n", debugstr_a((char*)pMemory));
611 pStubMsg->ActualCount = strlen((char*)pMemory)+1;
614 else if (*pFormat == RPC_FC_C_WSTRING) {
615 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
616 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;
620 ERR("Unhandled string type: %#x\n", *pFormat);
621 /* FIXME: raise an exception */
625 if (pFormat[1] == RPC_FC_STRING_SIZED)
626 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
628 pStubMsg->MaxCount = pStubMsg->ActualCount;
630 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
633 /************************************************************************
634 * NdrConformantStringMemorySize [RPCRT4.@]
636 unsigned long WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
637 PFORMAT_STRING pFormat )
639 unsigned long rslt = 0;
641 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
643 assert(pStubMsg && pFormat);
645 if (*pFormat == RPC_FC_C_CSTRING) {
646 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
648 else if (*pFormat == RPC_FC_C_WSTRING) {
649 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
652 ERR("Unhandled string type: %#x\n", *pFormat);
653 /* FIXME: raise an exception */
656 if (pFormat[1] != RPC_FC_PAD) {
657 FIXME("sized string format=%d\n", pFormat[1]);
660 TRACE(" --> %lu\n", rslt);
664 /************************************************************************
665 * NdrConformantStringUnmarshall [RPCRT4.@]
667 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
668 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
670 unsigned long size, esize;
672 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
673 pStubMsg, *ppMemory, pFormat, fMustAlloc);
675 assert(pFormat && ppMemory && pStubMsg);
677 ReadConformance(pStubMsg, NULL);
678 ReadVariance(pStubMsg, NULL);
680 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
681 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
683 ERR("Unhandled string type: %#x\n", *pFormat);
684 /* FIXME: raise an exception */
688 size = safe_multiply(esize, pStubMsg->ActualCount);
690 if (fMustAlloc || !*ppMemory)
691 *ppMemory = NdrAllocate(pStubMsg, size);
693 memcpy(*ppMemory, pStubMsg->Buffer, size);
695 pStubMsg->Buffer += size;
697 if (*pFormat == RPC_FC_C_CSTRING) {
698 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
700 else if (*pFormat == RPC_FC_C_WSTRING) {
701 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
704 return NULL; /* FIXME: is this always right? */
707 /***********************************************************************
708 * NdrNonConformantStringMarshall [RPCRT4.@]
710 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
711 unsigned char *pMemory,
712 PFORMAT_STRING pFormat)
718 /***********************************************************************
719 * NdrNonConformantStringUnmarshall [RPCRT4.@]
721 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
722 unsigned char **ppMemory,
723 PFORMAT_STRING pFormat,
724 unsigned char fMustAlloc)
730 /***********************************************************************
731 * NdrNonConformantStringBufferSize [RPCRT4.@]
733 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
734 unsigned char *pMemory,
735 PFORMAT_STRING pFormat)
740 /***********************************************************************
741 * NdrNonConformantStringMemorySize [RPCRT4.@]
743 unsigned long WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
744 PFORMAT_STRING pFormat)
750 static inline void dump_pointer_attr(unsigned char attr)
752 if (attr & RPC_FC_P_ALLOCALLNODES)
753 TRACE(" RPC_FC_P_ALLOCALLNODES");
754 if (attr & RPC_FC_P_DONTFREE)
755 TRACE(" RPC_FC_P_DONTFREE");
756 if (attr & RPC_FC_P_ONSTACK)
757 TRACE(" RPC_FC_P_ONSTACK");
758 if (attr & RPC_FC_P_SIMPLEPOINTER)
759 TRACE(" RPC_FC_P_SIMPLEPOINTER");
760 if (attr & RPC_FC_P_DEREF)
761 TRACE(" RPC_FC_P_DEREF");
765 /***********************************************************************
768 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
769 unsigned char *Buffer,
770 unsigned char *Pointer,
771 PFORMAT_STRING pFormat)
773 unsigned type = pFormat[0], attr = pFormat[1];
776 unsigned long pointer_id;
777 int pointer_needs_marshaling;
779 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
780 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
782 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
783 else desc = pFormat + *(const SHORT*)pFormat;
786 case RPC_FC_RP: /* ref pointer (always non-null) */
787 #if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
789 RpcRaiseException(RPC_X_NULL_REF_POINTER);
791 pointer_needs_marshaling = 1;
793 case RPC_FC_UP: /* unique pointer */
794 case RPC_FC_OP: /* object pointer - same as unique here */
796 pointer_needs_marshaling = 1;
798 pointer_needs_marshaling = 0;
799 pointer_id = (unsigned long)Pointer;
800 TRACE("writing 0x%08lx to buffer\n", pointer_id);
801 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
804 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
805 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
806 TRACE("writing 0x%08lx to buffer\n", pointer_id);
807 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
810 FIXME("unhandled ptr type=%02x\n", type);
811 RpcRaiseException(RPC_X_BAD_STUB_DATA);
815 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
817 if (pointer_needs_marshaling) {
818 if (attr & RPC_FC_P_DEREF) {
819 Pointer = *(unsigned char**)Pointer;
820 TRACE("deref => %p\n", Pointer);
822 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
823 if (m) m(pStubMsg, Pointer, desc);
824 else FIXME("no marshaller for data type=%02x\n", *desc);
827 STD_OVERFLOW_CHECK(pStubMsg);
830 /***********************************************************************
833 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
834 unsigned char *Buffer,
835 unsigned char **pPointer,
836 PFORMAT_STRING pFormat,
837 unsigned char fMustAlloc)
839 unsigned type = pFormat[0], attr = pFormat[1];
842 DWORD pointer_id = 0;
843 int pointer_needs_unmarshaling;
845 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pFormat, fMustAlloc);
846 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
848 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
849 else desc = pFormat + *(const SHORT*)pFormat;
852 case RPC_FC_RP: /* ref pointer (always non-null) */
853 pointer_needs_unmarshaling = 1;
855 case RPC_FC_UP: /* unique pointer */
856 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
857 TRACE("pointer_id is 0x%08lx\n", pointer_id);
859 pointer_needs_unmarshaling = 1;
862 pointer_needs_unmarshaling = 0;
865 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
866 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
867 TRACE("pointer_id is 0x%08lx\n", pointer_id);
868 if (!fMustAlloc && *pPointer)
870 FIXME("free object pointer %p\n", *pPointer);
874 pointer_needs_unmarshaling = 1;
876 pointer_needs_unmarshaling = 0;
879 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
880 TRACE("pointer_id is 0x%08lx\n", pointer_id);
881 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
882 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
885 FIXME("unhandled ptr type=%02x\n", type);
886 RpcRaiseException(RPC_X_BAD_STUB_DATA);
890 if (pointer_needs_unmarshaling) {
891 if (attr & RPC_FC_P_DEREF) {
892 if (!*pPointer || fMustAlloc)
893 *pPointer = NdrAllocate(pStubMsg, sizeof(void *));
894 pPointer = *(unsigned char***)pPointer;
895 TRACE("deref => %p\n", pPointer);
897 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
898 if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
899 else FIXME("no unmarshaller for data type=%02x\n", *desc);
901 if (type == RPC_FC_FP)
902 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
906 TRACE("pointer=%p\n", *pPointer);
909 /***********************************************************************
912 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
913 unsigned char *Pointer,
914 PFORMAT_STRING pFormat)
916 unsigned type = pFormat[0], attr = pFormat[1];
919 int pointer_needs_sizing;
920 unsigned long pointer_id;
922 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
923 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
925 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
926 else desc = pFormat + *(const SHORT*)pFormat;
929 case RPC_FC_RP: /* ref pointer (always non-null) */
933 /* NULL pointer has no further representation */
938 pointer_needs_sizing = !NdrFullPointerQueryPointer(
939 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
940 if (!pointer_needs_sizing)
944 FIXME("unhandled ptr type=%02x\n", type);
945 RpcRaiseException(RPC_X_BAD_STUB_DATA);
949 if (attr & RPC_FC_P_DEREF) {
950 Pointer = *(unsigned char**)Pointer;
951 TRACE("deref => %p\n", Pointer);
954 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
955 if (m) m(pStubMsg, Pointer, desc);
956 else FIXME("no buffersizer for data type=%02x\n", *desc);
959 /***********************************************************************
960 * PointerMemorySize [RPCRT4.@]
962 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
963 unsigned char *Buffer,
964 PFORMAT_STRING pFormat)
966 unsigned type = pFormat[0], attr = pFormat[1];
970 FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat);
971 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
973 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
974 else desc = pFormat + *(const SHORT*)pFormat;
977 case RPC_FC_RP: /* ref pointer (always non-null) */
980 FIXME("unhandled ptr type=%02x\n", type);
981 RpcRaiseException(RPC_X_BAD_STUB_DATA);
984 if (attr & RPC_FC_P_DEREF) {
988 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
989 if (m) m(pStubMsg, desc);
990 else FIXME("no memorysizer for data type=%02x\n", *desc);
995 /***********************************************************************
996 * PointerFree [RPCRT4.@]
998 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
999 unsigned char *Pointer,
1000 PFORMAT_STRING pFormat)
1002 unsigned type = pFormat[0], attr = pFormat[1];
1003 PFORMAT_STRING desc;
1006 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1007 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1008 if (attr & RPC_FC_P_DONTFREE) return;
1010 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1011 else desc = pFormat + *(const SHORT*)pFormat;
1013 if (!Pointer) return;
1015 if (type == RPC_FC_FP) {
1016 int pointer_needs_freeing = NdrFullPointerFree(
1017 pStubMsg->FullPtrXlatTables, Pointer);
1018 if (!pointer_needs_freeing)
1022 if (attr & RPC_FC_P_DEREF) {
1023 Pointer = *(unsigned char**)Pointer;
1024 TRACE("deref => %p\n", Pointer);
1027 m = NdrFreer[*desc & NDR_TABLE_MASK];
1028 if (m) m(pStubMsg, Pointer, desc);
1030 /* hmm... is this sensible?
1031 * perhaps we should check if the memory comes from NdrAllocate,
1032 * and deallocate only if so - checking if the pointer is between
1033 * BufferStart and BufferEnd is probably no good since the buffer
1034 * may be reallocated when the server wants to marshal the reply */
1036 case RPC_FC_BOGUS_STRUCT:
1037 case RPC_FC_BOGUS_ARRAY:
1038 case RPC_FC_USER_MARSHAL:
1040 case RPC_FC_CVARRAY:
1043 FIXME("unhandled data type=%02x\n", *desc);
1045 case RPC_FC_C_CSTRING:
1046 case RPC_FC_C_WSTRING:
1047 if (pStubMsg->ReuseBuffer) goto notfree;
1053 if (attr & RPC_FC_P_ONSTACK) {
1054 TRACE("not freeing stack ptr %p\n", Pointer);
1057 TRACE("freeing %p\n", Pointer);
1058 NdrFree(pStubMsg, Pointer);
1061 TRACE("not freeing %p\n", Pointer);
1064 /***********************************************************************
1065 * EmbeddedPointerMarshall
1067 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1068 unsigned char *pMemory,
1069 PFORMAT_STRING pFormat)
1071 unsigned char *Mark = pStubMsg->BufferMark;
1072 unsigned long Offset = pStubMsg->Offset;
1073 unsigned ofs, rep, count, stride, xofs;
1076 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1078 if (*pFormat != RPC_FC_PP) return NULL;
1081 while (pFormat[0] != RPC_FC_END) {
1082 switch (pFormat[0]) {
1084 FIXME("unknown repeat type %d\n", pFormat[0]);
1085 case RPC_FC_NO_REPEAT:
1093 case RPC_FC_FIXED_REPEAT:
1094 rep = *(const WORD*)&pFormat[2];
1095 stride = *(const WORD*)&pFormat[4];
1096 ofs = *(const WORD*)&pFormat[6];
1097 count = *(const WORD*)&pFormat[8];
1101 case RPC_FC_VARIABLE_REPEAT:
1102 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1103 stride = *(const WORD*)&pFormat[2];
1104 ofs = *(const WORD*)&pFormat[4];
1105 count = *(const WORD*)&pFormat[6];
1106 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1110 for (i = 0; i < rep; i++) {
1111 PFORMAT_STRING info = pFormat;
1112 unsigned char *membase = pMemory + (i * stride);
1113 unsigned char *bufbase = Mark + (i * stride);
1115 /* ofs doesn't seem to matter in this context */
1116 for (u=0; u<count; u++,info+=8) {
1117 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1118 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1119 unsigned char *saved_memory = pStubMsg->Memory;
1121 pStubMsg->Memory = pMemory;
1122 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1123 pStubMsg->Memory = saved_memory;
1126 pFormat += 8 * count;
1129 STD_OVERFLOW_CHECK(pStubMsg);
1134 /***********************************************************************
1135 * EmbeddedPointerUnmarshall
1137 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1138 unsigned char **ppMemory,
1139 PFORMAT_STRING pFormat,
1140 unsigned char fMustAlloc)
1142 unsigned char *Mark = pStubMsg->BufferMark;
1143 unsigned long Offset = pStubMsg->Offset;
1144 unsigned ofs, rep, count, stride, xofs;
1147 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1149 if (*pFormat != RPC_FC_PP) return NULL;
1152 while (pFormat[0] != RPC_FC_END) {
1153 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1154 switch (pFormat[0]) {
1156 FIXME("unknown repeat type %d\n", pFormat[0]);
1157 case RPC_FC_NO_REPEAT:
1165 case RPC_FC_FIXED_REPEAT:
1166 rep = *(const WORD*)&pFormat[2];
1167 stride = *(const WORD*)&pFormat[4];
1168 ofs = *(const WORD*)&pFormat[6];
1169 count = *(const WORD*)&pFormat[8];
1173 case RPC_FC_VARIABLE_REPEAT:
1174 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1175 stride = *(const WORD*)&pFormat[2];
1176 ofs = *(const WORD*)&pFormat[4];
1177 count = *(const WORD*)&pFormat[6];
1178 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1182 /* ofs doesn't seem to matter in this context */
1183 for (i = 0; i < rep; i++) {
1184 PFORMAT_STRING info = pFormat;
1185 unsigned char *membase = *ppMemory + (i * stride);
1186 unsigned char *bufbase = Mark + (i * stride);
1188 for (u=0; u<count; u++,info+=8) {
1189 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1190 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1191 PointerUnmarshall(pStubMsg, bufptr, (unsigned char**)memptr, info+4, TRUE);
1194 pFormat += 8 * count;
1200 /***********************************************************************
1201 * EmbeddedPointerBufferSize
1203 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1204 unsigned char *pMemory,
1205 PFORMAT_STRING pFormat)
1207 unsigned long Offset = pStubMsg->Offset;
1208 unsigned ofs, rep, count, stride, xofs;
1211 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1213 if (pStubMsg->IgnoreEmbeddedPointers) return;
1215 if (*pFormat != RPC_FC_PP) return;
1218 while (pFormat[0] != RPC_FC_END) {
1219 switch (pFormat[0]) {
1221 FIXME("unknown repeat type %d\n", pFormat[0]);
1222 case RPC_FC_NO_REPEAT:
1230 case RPC_FC_FIXED_REPEAT:
1231 rep = *(const WORD*)&pFormat[2];
1232 stride = *(const WORD*)&pFormat[4];
1233 ofs = *(const WORD*)&pFormat[6];
1234 count = *(const WORD*)&pFormat[8];
1238 case RPC_FC_VARIABLE_REPEAT:
1239 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1240 stride = *(const WORD*)&pFormat[2];
1241 ofs = *(const WORD*)&pFormat[4];
1242 count = *(const WORD*)&pFormat[6];
1243 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1247 /* ofs doesn't seem to matter in this context */
1248 for (i = 0; i < rep; i++) {
1249 PFORMAT_STRING info = pFormat;
1250 unsigned char *membase = pMemory + (i * stride);
1252 for (u=0; u<count; u++,info+=8) {
1253 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1254 unsigned char *saved_memory = pStubMsg->Memory;
1256 pStubMsg->Memory = pMemory;
1257 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1258 pStubMsg->Memory = saved_memory;
1261 pFormat += 8 * count;
1265 /***********************************************************************
1266 * EmbeddedPointerMemorySize
1268 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1269 PFORMAT_STRING pFormat)
1271 unsigned long Offset = pStubMsg->Offset;
1272 unsigned char *Mark = pStubMsg->BufferMark;
1273 unsigned ofs, rep, count, stride, xofs;
1276 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1278 if (*pFormat != RPC_FC_PP) return 0;
1281 while (pFormat[0] != RPC_FC_END) {
1282 switch (pFormat[0]) {
1284 FIXME("unknown repeat type %d\n", pFormat[0]);
1285 case RPC_FC_NO_REPEAT:
1293 case RPC_FC_FIXED_REPEAT:
1294 rep = *(const WORD*)&pFormat[2];
1295 stride = *(const WORD*)&pFormat[4];
1296 ofs = *(const WORD*)&pFormat[6];
1297 count = *(const WORD*)&pFormat[8];
1301 case RPC_FC_VARIABLE_REPEAT:
1302 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1303 stride = *(const WORD*)&pFormat[2];
1304 ofs = *(const WORD*)&pFormat[4];
1305 count = *(const WORD*)&pFormat[6];
1306 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1310 /* ofs doesn't seem to matter in this context */
1311 for (i = 0; i < rep; i++) {
1312 PFORMAT_STRING info = pFormat;
1313 unsigned char *bufbase = Mark + (i * stride);
1315 for (u=0; u<count; u++,info+=8) {
1316 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1317 PointerMemorySize(pStubMsg, bufptr, info+4);
1320 pFormat += 8 * count;
1326 /***********************************************************************
1327 * EmbeddedPointerFree
1329 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1330 unsigned char *pMemory,
1331 PFORMAT_STRING pFormat)
1333 unsigned long Offset = pStubMsg->Offset;
1334 unsigned ofs, rep, count, stride, xofs;
1337 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1338 if (*pFormat != RPC_FC_PP) return;
1341 while (pFormat[0] != RPC_FC_END) {
1342 switch (pFormat[0]) {
1344 FIXME("unknown repeat type %d\n", pFormat[0]);
1345 case RPC_FC_NO_REPEAT:
1353 case RPC_FC_FIXED_REPEAT:
1354 rep = *(const WORD*)&pFormat[2];
1355 stride = *(const WORD*)&pFormat[4];
1356 ofs = *(const WORD*)&pFormat[6];
1357 count = *(const WORD*)&pFormat[8];
1361 case RPC_FC_VARIABLE_REPEAT:
1362 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1363 stride = *(const WORD*)&pFormat[2];
1364 ofs = *(const WORD*)&pFormat[4];
1365 count = *(const WORD*)&pFormat[6];
1366 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1370 /* ofs doesn't seem to matter in this context */
1371 for (i = 0; i < rep; i++) {
1372 PFORMAT_STRING info = pFormat;
1373 unsigned char *membase = pMemory + (i * stride);
1375 for (u=0; u<count; u++,info+=8) {
1376 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1377 unsigned char *saved_memory = pStubMsg->Memory;
1379 pStubMsg->Memory = pMemory;
1380 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1381 pStubMsg->Memory = saved_memory;
1384 pFormat += 8 * count;
1388 /***********************************************************************
1389 * NdrPointerMarshall [RPCRT4.@]
1391 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1392 unsigned char *pMemory,
1393 PFORMAT_STRING pFormat)
1395 unsigned char *Buffer;
1397 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1399 /* incremement the buffer here instead of in PointerMarshall,
1400 * as that is used by embedded pointers which already handle the incrementing
1401 * the buffer, and shouldn't write any additional pointer data to the wire */
1402 if (*pFormat != RPC_FC_RP)
1404 ALIGN_POINTER(pStubMsg->Buffer, 4);
1405 Buffer = pStubMsg->Buffer;
1406 pStubMsg->Buffer += 4;
1409 Buffer = pStubMsg->Buffer;
1411 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1413 STD_OVERFLOW_CHECK(pStubMsg);
1418 /***********************************************************************
1419 * NdrPointerUnmarshall [RPCRT4.@]
1421 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1422 unsigned char **ppMemory,
1423 PFORMAT_STRING pFormat,
1424 unsigned char fMustAlloc)
1426 unsigned char *Buffer;
1428 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1430 /* incremement the buffer here instead of in PointerUnmarshall,
1431 * as that is used by embedded pointers which already handle the incrementing
1432 * the buffer, and shouldn't read any additional pointer data from the
1434 if (*pFormat != RPC_FC_RP)
1436 ALIGN_POINTER(pStubMsg->Buffer, 4);
1437 Buffer = pStubMsg->Buffer;
1438 pStubMsg->Buffer += 4;
1441 Buffer = pStubMsg->Buffer;
1443 PointerUnmarshall(pStubMsg, Buffer, ppMemory, pFormat, fMustAlloc);
1448 /***********************************************************************
1449 * NdrPointerBufferSize [RPCRT4.@]
1451 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1452 unsigned char *pMemory,
1453 PFORMAT_STRING pFormat)
1455 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1457 /* incremement the buffer length here instead of in PointerBufferSize,
1458 * as that is used by embedded pointers which already handle the buffer
1459 * length, and shouldn't write anything more to the wire */
1460 if (*pFormat != RPC_FC_RP)
1462 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1463 pStubMsg->BufferLength += 4;
1466 PointerBufferSize(pStubMsg, pMemory, pFormat);
1469 /***********************************************************************
1470 * NdrPointerMemorySize [RPCRT4.@]
1472 unsigned long WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1473 PFORMAT_STRING pFormat)
1475 /* unsigned size = *(LPWORD)(pFormat+2); */
1476 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1477 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1481 /***********************************************************************
1482 * NdrPointerFree [RPCRT4.@]
1484 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1485 unsigned char *pMemory,
1486 PFORMAT_STRING pFormat)
1488 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1489 PointerFree(pStubMsg, pMemory, pFormat);
1492 /***********************************************************************
1493 * NdrSimpleTypeMarshall [RPCRT4.@]
1495 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1496 unsigned char FormatChar )
1501 /***********************************************************************
1502 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1504 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1505 unsigned char FormatChar )
1510 /***********************************************************************
1511 * NdrSimpleStructMarshall [RPCRT4.@]
1513 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1514 unsigned char *pMemory,
1515 PFORMAT_STRING pFormat)
1517 unsigned size = *(const WORD*)(pFormat+2);
1518 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1520 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1522 memcpy(pStubMsg->Buffer, pMemory, size);
1523 pStubMsg->BufferMark = pStubMsg->Buffer;
1524 pStubMsg->Buffer += size;
1526 if (pFormat[0] != RPC_FC_STRUCT)
1527 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1529 STD_OVERFLOW_CHECK(pStubMsg);
1534 /***********************************************************************
1535 * NdrSimpleStructUnmarshall [RPCRT4.@]
1537 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1538 unsigned char **ppMemory,
1539 PFORMAT_STRING pFormat,
1540 unsigned char fMustAlloc)
1542 unsigned size = *(const WORD*)(pFormat+2);
1543 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1545 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1548 *ppMemory = NdrAllocate(pStubMsg, size);
1549 memcpy(*ppMemory, pStubMsg->Buffer, size);
1551 if (!pStubMsg->IsClient && !*ppMemory)
1552 /* for servers, we just point straight into the RPC buffer */
1553 *ppMemory = pStubMsg->Buffer;
1555 /* for clients, memory should be provided by caller */
1556 memcpy(*ppMemory, pStubMsg->Buffer, size);
1559 pStubMsg->BufferMark = pStubMsg->Buffer;
1560 pStubMsg->Buffer += size;
1562 if (pFormat[0] != RPC_FC_STRUCT)
1563 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat+4, fMustAlloc);
1568 /***********************************************************************
1569 * NdrSimpleStructBufferSize [RPCRT4.@]
1571 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1572 unsigned char *pMemory,
1573 PFORMAT_STRING pFormat)
1575 unsigned size = *(const WORD*)(pFormat+2);
1576 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1578 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1580 pStubMsg->BufferLength += size;
1581 if (pFormat[0] != RPC_FC_STRUCT)
1582 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1585 /***********************************************************************
1586 * NdrSimpleStructMemorySize [RPCRT4.@]
1588 unsigned long WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1589 PFORMAT_STRING pFormat)
1591 unsigned short size = *(LPWORD)(pFormat+2);
1593 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1595 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1596 pStubMsg->MemorySize += size;
1597 pStubMsg->Buffer += size;
1599 if (pFormat[0] != RPC_FC_STRUCT)
1600 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1604 /***********************************************************************
1605 * NdrSimpleStructFree [RPCRT4.@]
1607 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1608 unsigned char *pMemory,
1609 PFORMAT_STRING pFormat)
1611 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1612 if (pFormat[0] != RPC_FC_STRUCT)
1613 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1617 static unsigned long EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg,
1618 PFORMAT_STRING pFormat)
1622 case RPC_FC_PSTRUCT:
1623 case RPC_FC_CSTRUCT:
1624 case RPC_FC_BOGUS_STRUCT:
1625 return *(const WORD*)&pFormat[2];
1626 case RPC_FC_USER_MARSHAL:
1627 return *(const WORD*)&pFormat[4];
1628 case RPC_FC_NON_ENCAPSULATED_UNION:
1630 if (pStubMsg->fHasNewCorrDesc)
1635 pFormat += *(const SHORT*)pFormat;
1636 return *(const SHORT*)pFormat;
1638 return sizeof(void *);
1640 FIXME("unhandled embedded type %02x\n", *pFormat);
1646 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1647 PFORMAT_STRING pFormat)
1649 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1653 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1657 return m(pStubMsg, pFormat);
1661 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1662 unsigned char *pMemory,
1663 PFORMAT_STRING pFormat,
1664 PFORMAT_STRING pPointer)
1666 PFORMAT_STRING desc;
1670 while (*pFormat != RPC_FC_END) {
1676 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
1677 memcpy(pStubMsg->Buffer, pMemory, 1);
1678 pStubMsg->Buffer += 1;
1684 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1685 memcpy(pStubMsg->Buffer, pMemory, 2);
1686 pStubMsg->Buffer += 2;
1692 TRACE("long=%ld <= %p\n", *(DWORD*)pMemory, pMemory);
1693 memcpy(pStubMsg->Buffer, pMemory, 4);
1694 pStubMsg->Buffer += 4;
1697 case RPC_FC_POINTER:
1698 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1699 NdrPointerMarshall(pStubMsg, *(unsigned char**)pMemory, pPointer);
1703 case RPC_FC_ALIGNM4:
1704 ALIGN_POINTER(pMemory, 4);
1706 case RPC_FC_ALIGNM8:
1707 ALIGN_POINTER(pMemory, 8);
1709 case RPC_FC_STRUCTPAD2:
1712 case RPC_FC_EMBEDDED_COMPLEX:
1713 pMemory += pFormat[1];
1715 desc = pFormat + *(const SHORT*)pFormat;
1716 size = EmbeddedComplexSize(pStubMsg, desc);
1717 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1718 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1719 if (m) m(pStubMsg, pMemory, desc);
1720 else FIXME("no marshaller for embedded type %02x\n", *desc);
1727 FIXME("unhandled format %02x\n", *pFormat);
1735 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1736 unsigned char *pMemory,
1737 PFORMAT_STRING pFormat,
1738 PFORMAT_STRING pPointer)
1740 PFORMAT_STRING desc;
1744 while (*pFormat != RPC_FC_END) {
1750 memcpy(pMemory, pStubMsg->Buffer, 1);
1751 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
1752 pStubMsg->Buffer += 1;
1758 memcpy(pMemory, pStubMsg->Buffer, 2);
1759 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1760 pStubMsg->Buffer += 2;
1766 memcpy(pMemory, pStubMsg->Buffer, 4);
1767 TRACE("long=%ld => %p\n", *(DWORD*)pMemory, pMemory);
1768 pStubMsg->Buffer += 4;
1771 case RPC_FC_POINTER:
1772 TRACE("pointer => %p\n", pMemory);
1773 NdrPointerUnmarshall(pStubMsg, (unsigned char**)pMemory, pPointer, TRUE);
1777 case RPC_FC_ALIGNM4:
1778 ALIGN_POINTER(pMemory, 4);
1780 case RPC_FC_ALIGNM8:
1781 ALIGN_POINTER(pMemory, 8);
1783 case RPC_FC_STRUCTPAD2:
1786 case RPC_FC_EMBEDDED_COMPLEX:
1787 pMemory += pFormat[1];
1789 desc = pFormat + *(const SHORT*)pFormat;
1790 size = EmbeddedComplexSize(pStubMsg, desc);
1791 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
1792 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1793 memset(pMemory, 0, size); /* just in case */
1794 if (m) m(pStubMsg, &pMemory, desc, FALSE);
1795 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
1802 FIXME("unhandled format %d\n", *pFormat);
1810 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1811 unsigned char *pMemory,
1812 PFORMAT_STRING pFormat,
1813 PFORMAT_STRING pPointer)
1815 PFORMAT_STRING desc;
1819 while (*pFormat != RPC_FC_END) {
1825 pStubMsg->BufferLength += 1;
1831 pStubMsg->BufferLength += 2;
1837 pStubMsg->BufferLength += 4;
1840 case RPC_FC_POINTER:
1841 NdrPointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
1845 case RPC_FC_ALIGNM4:
1846 ALIGN_POINTER(pMemory, 4);
1848 case RPC_FC_ALIGNM8:
1849 ALIGN_POINTER(pMemory, 8);
1851 case RPC_FC_STRUCTPAD2:
1854 case RPC_FC_EMBEDDED_COMPLEX:
1855 pMemory += pFormat[1];
1857 desc = pFormat + *(const SHORT*)pFormat;
1858 size = EmbeddedComplexSize(pStubMsg, desc);
1859 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1860 if (m) m(pStubMsg, pMemory, desc);
1861 else FIXME("no buffersizer for embedded type %02x\n", *desc);
1868 FIXME("unhandled format %d\n", *pFormat);
1876 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
1877 unsigned char *pMemory,
1878 PFORMAT_STRING pFormat,
1879 PFORMAT_STRING pPointer)
1881 PFORMAT_STRING desc;
1885 while (*pFormat != RPC_FC_END) {
1903 case RPC_FC_POINTER:
1904 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
1908 case RPC_FC_ALIGNM4:
1909 ALIGN_POINTER(pMemory, 4);
1911 case RPC_FC_ALIGNM8:
1912 ALIGN_POINTER(pMemory, 8);
1914 case RPC_FC_STRUCTPAD2:
1917 case RPC_FC_EMBEDDED_COMPLEX:
1918 pMemory += pFormat[1];
1920 desc = pFormat + *(const SHORT*)pFormat;
1921 size = EmbeddedComplexSize(pStubMsg, desc);
1922 m = NdrFreer[*desc & NDR_TABLE_MASK];
1923 if (m) m(pStubMsg, pMemory, desc);
1924 else FIXME("no freer for embedded type %02x\n", *desc);
1931 FIXME("unhandled format %d\n", *pFormat);
1939 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1940 PFORMAT_STRING pFormat)
1942 PFORMAT_STRING desc;
1943 unsigned long size = 0;
1945 while (*pFormat != RPC_FC_END) {
1952 pStubMsg->Buffer += 1;
1958 pStubMsg->Buffer += 2;
1964 pStubMsg->Buffer += 4;
1966 case RPC_FC_POINTER:
1968 pStubMsg->Buffer += 4;
1970 case RPC_FC_ALIGNM4:
1971 ALIGN_LENGTH(size, 4);
1972 ALIGN_POINTER(pStubMsg->Buffer, 4);
1974 case RPC_FC_ALIGNM8:
1975 ALIGN_LENGTH(size, 8);
1976 ALIGN_POINTER(pStubMsg->Buffer, 8);
1978 case RPC_FC_STRUCTPAD2:
1980 pStubMsg->Buffer += 2;
1982 case RPC_FC_EMBEDDED_COMPLEX:
1985 desc = pFormat + *(const SHORT*)pFormat;
1986 size += EmbeddedComplexMemorySize(pStubMsg, desc);
1992 FIXME("unhandled format %d\n", *pFormat);
2000 /***********************************************************************
2001 * NdrComplexStructMarshall [RPCRT4.@]
2003 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2004 unsigned char *pMemory,
2005 PFORMAT_STRING pFormat)
2007 PFORMAT_STRING conf_array = NULL;
2008 PFORMAT_STRING pointer_desc = NULL;
2009 unsigned char *OldMemory = pStubMsg->Memory;
2011 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2013 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2016 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2018 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2021 pStubMsg->Memory = pMemory;
2023 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2026 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2028 pStubMsg->Memory = OldMemory;
2030 STD_OVERFLOW_CHECK(pStubMsg);
2035 /***********************************************************************
2036 * NdrComplexStructUnmarshall [RPCRT4.@]
2038 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2039 unsigned char **ppMemory,
2040 PFORMAT_STRING pFormat,
2041 unsigned char fMustAlloc)
2043 unsigned size = *(const WORD*)(pFormat+2);
2044 PFORMAT_STRING conf_array = NULL;
2045 PFORMAT_STRING pointer_desc = NULL;
2046 unsigned char *pMemory;
2048 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2050 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2052 if (fMustAlloc || !*ppMemory)
2054 *ppMemory = NdrAllocate(pStubMsg, size);
2055 memset(*ppMemory, 0, size);
2059 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2061 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2064 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2067 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2072 /***********************************************************************
2073 * NdrComplexStructBufferSize [RPCRT4.@]
2075 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2076 unsigned char *pMemory,
2077 PFORMAT_STRING pFormat)
2079 PFORMAT_STRING conf_array = NULL;
2080 PFORMAT_STRING pointer_desc = NULL;
2081 unsigned char *OldMemory = pStubMsg->Memory;
2083 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2085 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2088 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2090 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2093 pStubMsg->Memory = pMemory;
2095 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2098 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2100 pStubMsg->Memory = OldMemory;
2103 /***********************************************************************
2104 * NdrComplexStructMemorySize [RPCRT4.@]
2106 unsigned long WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2107 PFORMAT_STRING pFormat)
2109 unsigned size = *(const WORD*)(pFormat+2);
2110 PFORMAT_STRING conf_array = NULL;
2111 PFORMAT_STRING pointer_desc = NULL;
2113 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2115 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2118 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2120 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2123 ComplexStructMemorySize(pStubMsg, pFormat);
2126 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2131 /***********************************************************************
2132 * NdrComplexStructFree [RPCRT4.@]
2134 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2135 unsigned char *pMemory,
2136 PFORMAT_STRING pFormat)
2138 PFORMAT_STRING conf_array = NULL;
2139 PFORMAT_STRING pointer_desc = NULL;
2140 unsigned char *OldMemory = pStubMsg->Memory;
2142 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2145 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2147 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2150 pStubMsg->Memory = pMemory;
2152 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2155 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2157 pStubMsg->Memory = OldMemory;
2160 /***********************************************************************
2161 * NdrConformantArrayMarshall [RPCRT4.@]
2163 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2164 unsigned char *pMemory,
2165 PFORMAT_STRING pFormat)
2167 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2168 unsigned char alignment = pFormat[1] + 1;
2170 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2171 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2173 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2174 size = pStubMsg->MaxCount;
2176 WriteConformance(pStubMsg);
2178 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2180 memcpy(pStubMsg->Buffer, pMemory, size*esize);
2181 pStubMsg->BufferMark = pStubMsg->Buffer;
2182 pStubMsg->Buffer += size*esize;
2184 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2186 STD_OVERFLOW_CHECK(pStubMsg);
2191 /***********************************************************************
2192 * NdrConformantArrayUnmarshall [RPCRT4.@]
2194 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2195 unsigned char **ppMemory,
2196 PFORMAT_STRING pFormat,
2197 unsigned char fMustAlloc)
2199 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2200 unsigned char alignment = pFormat[1] + 1;
2202 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2203 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2205 pFormat = ReadConformance(pStubMsg, pFormat+4);
2206 size = pStubMsg->MaxCount;
2208 if (fMustAlloc || !*ppMemory)
2209 *ppMemory = NdrAllocate(pStubMsg, size*esize);
2211 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2213 memcpy(*ppMemory, pStubMsg->Buffer, size*esize);
2215 pStubMsg->BufferMark = pStubMsg->Buffer;
2216 pStubMsg->Buffer += size*esize;
2218 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2223 /***********************************************************************
2224 * NdrConformantArrayBufferSize [RPCRT4.@]
2226 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2227 unsigned char *pMemory,
2228 PFORMAT_STRING pFormat)
2230 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2231 unsigned char alignment = pFormat[1] + 1;
2233 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2234 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2236 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2237 size = pStubMsg->MaxCount;
2239 SizeConformance(pStubMsg);
2241 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2243 /* conformance value plus array */
2244 pStubMsg->BufferLength += size*esize;
2246 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2249 /***********************************************************************
2250 * NdrConformantArrayMemorySize [RPCRT4.@]
2252 unsigned long WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2253 PFORMAT_STRING pFormat)
2255 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2256 unsigned char alignment = pFormat[1] + 1;
2258 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2259 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2261 pFormat = ReadConformance(pStubMsg, pFormat+4);
2262 size = pStubMsg->MaxCount;
2263 pStubMsg->MemorySize += size*esize;
2265 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2266 pStubMsg->BufferMark = pStubMsg->Buffer;
2267 pStubMsg->Buffer += size*esize;
2269 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2271 return pStubMsg->MemorySize;
2274 /***********************************************************************
2275 * NdrConformantArrayFree [RPCRT4.@]
2277 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2278 unsigned char *pMemory,
2279 PFORMAT_STRING pFormat)
2281 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2282 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2284 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2288 /***********************************************************************
2289 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2291 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2292 unsigned char* pMemory,
2293 PFORMAT_STRING pFormat )
2295 unsigned char alignment = pFormat[1] + 1;
2296 DWORD esize = *(const WORD*)(pFormat+2);
2298 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2300 if (pFormat[0] != RPC_FC_CVARRAY)
2302 ERR("invalid format type %x\n", pFormat[0]);
2303 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2307 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2308 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2310 WriteConformance(pStubMsg);
2311 WriteVariance(pStubMsg);
2313 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2315 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, pStubMsg->ActualCount*esize);
2316 pStubMsg->BufferMark = pStubMsg->Buffer;
2317 pStubMsg->Buffer += pStubMsg->ActualCount*esize;
2319 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2321 STD_OVERFLOW_CHECK(pStubMsg);
2327 /***********************************************************************
2328 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2330 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2331 unsigned char** ppMemory,
2332 PFORMAT_STRING pFormat,
2333 unsigned char fMustAlloc )
2335 unsigned char alignment = pFormat[1] + 1;
2336 DWORD esize = *(const WORD*)(pFormat+2);
2338 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2340 if (pFormat[0] != RPC_FC_CVARRAY)
2342 ERR("invalid format type %x\n", pFormat[0]);
2343 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2347 pFormat = ReadConformance(pStubMsg, pFormat+4);
2348 pFormat = ReadVariance(pStubMsg, pFormat);
2350 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2352 if (!*ppMemory || fMustAlloc)
2353 *ppMemory = NdrAllocate(pStubMsg, pStubMsg->MaxCount * esize);
2354 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, pStubMsg->ActualCount * esize);
2355 pStubMsg->Buffer += pStubMsg->ActualCount * esize;
2357 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2363 /***********************************************************************
2364 * NdrConformantVaryingArrayFree [RPCRT4.@]
2366 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2367 unsigned char* pMemory,
2368 PFORMAT_STRING pFormat )
2370 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2372 if (pFormat[0] != RPC_FC_CVARRAY)
2374 ERR("invalid format type %x\n", pFormat[0]);
2375 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2379 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2380 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2382 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2386 /***********************************************************************
2387 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2389 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2390 unsigned char* pMemory, PFORMAT_STRING pFormat )
2392 unsigned char alignment = pFormat[1] + 1;
2393 DWORD esize = *(const WORD*)(pFormat+2);
2395 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2397 if (pFormat[0] != RPC_FC_CVARRAY)
2399 ERR("invalid format type %x\n", pFormat[0]);
2400 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2405 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2406 /* compute length */
2407 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2409 SizeConformance(pStubMsg);
2410 SizeVariance(pStubMsg);
2412 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2414 pStubMsg->BufferLength += pStubMsg->ActualCount*esize;
2416 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2420 /***********************************************************************
2421 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2423 unsigned long WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2424 PFORMAT_STRING pFormat )
2431 /***********************************************************************
2432 * NdrComplexArrayMarshall [RPCRT4.@]
2434 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2435 unsigned char *pMemory,
2436 PFORMAT_STRING pFormat)
2438 ULONG i, count, def;
2439 BOOL variance_present;
2440 unsigned char alignment;
2442 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2444 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2446 ERR("invalid format type %x\n", pFormat[0]);
2447 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2451 alignment = pFormat[1] + 1;
2453 def = *(const WORD*)&pFormat[2];
2456 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2457 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2459 variance_present = IsConformanceOrVariancePresent(pFormat);
2460 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2461 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2463 WriteConformance(pStubMsg);
2464 if (variance_present)
2465 WriteVariance(pStubMsg);
2467 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2469 count = pStubMsg->ActualCount;
2470 for (i = 0; i < count; i++)
2471 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2473 STD_OVERFLOW_CHECK(pStubMsg);
2478 /***********************************************************************
2479 * NdrComplexArrayUnmarshall [RPCRT4.@]
2481 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2482 unsigned char **ppMemory,
2483 PFORMAT_STRING pFormat,
2484 unsigned char fMustAlloc)
2486 ULONG i, count, esize;
2487 unsigned char alignment;
2488 unsigned char *pMemory;
2489 unsigned char *Buffer;
2491 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2493 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2495 ERR("invalid format type %x\n", pFormat[0]);
2496 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2500 alignment = pFormat[1] + 1;
2504 pFormat = ReadConformance(pStubMsg, pFormat);
2505 pFormat = ReadVariance(pStubMsg, pFormat);
2507 Buffer = pStubMsg->Buffer;
2508 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2509 pStubMsg->Buffer = Buffer;
2511 if (fMustAlloc || !*ppMemory)
2513 *ppMemory = NdrAllocate(pStubMsg, pStubMsg->MaxCount * esize);
2514 memset(*ppMemory, 0, pStubMsg->MaxCount * esize);
2517 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2519 pMemory = *ppMemory;
2520 count = pStubMsg->ActualCount;
2521 for (i = 0; i < count; i++)
2522 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
2527 /***********************************************************************
2528 * NdrComplexArrayBufferSize [RPCRT4.@]
2530 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2531 unsigned char *pMemory,
2532 PFORMAT_STRING pFormat)
2534 ULONG i, count, def;
2535 unsigned char alignment;
2536 BOOL variance_present;
2538 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2540 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2542 ERR("invalid format type %x\n", pFormat[0]);
2543 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2547 alignment = pFormat[1] + 1;
2549 def = *(const WORD*)&pFormat[2];
2552 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2553 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2554 SizeConformance(pStubMsg);
2556 variance_present = IsConformanceOrVariancePresent(pFormat);
2557 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2558 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2560 if (variance_present)
2561 SizeVariance(pStubMsg);
2563 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2565 count = pStubMsg->ActualCount;
2566 for (i = 0; i < count; i++)
2567 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
2570 /***********************************************************************
2571 * NdrComplexArrayMemorySize [RPCRT4.@]
2573 unsigned long WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2574 PFORMAT_STRING pFormat)
2576 ULONG i, count, esize;
2577 unsigned char alignment;
2578 unsigned char *Buffer;
2579 unsigned long SavedMemorySize;
2580 unsigned long MemorySize;
2582 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2584 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2586 ERR("invalid format type %x\n", pFormat[0]);
2587 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2591 alignment = pFormat[1] + 1;
2595 pFormat = ReadConformance(pStubMsg, pFormat);
2596 pFormat = ReadVariance(pStubMsg, pFormat);
2598 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2600 SavedMemorySize = pStubMsg->MemorySize;
2602 Buffer = pStubMsg->Buffer;
2603 pStubMsg->MemorySize = 0;
2604 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2605 pStubMsg->Buffer = Buffer;
2607 MemorySize = esize * pStubMsg->MaxCount;
2609 count = pStubMsg->ActualCount;
2610 for (i = 0; i < count; i++)
2611 ComplexStructMemorySize(pStubMsg, pFormat);
2613 pStubMsg->MemorySize = SavedMemorySize;
2615 pStubMsg->MemorySize += MemorySize;
2619 /***********************************************************************
2620 * NdrComplexArrayFree [RPCRT4.@]
2622 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2623 unsigned char *pMemory,
2624 PFORMAT_STRING pFormat)
2626 ULONG i, count, def;
2628 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2630 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2632 ERR("invalid format type %x\n", pFormat[0]);
2633 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2637 def = *(const WORD*)&pFormat[2];
2640 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2641 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2643 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2644 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2646 count = pStubMsg->ActualCount;
2647 for (i = 0; i < count; i++)
2648 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2651 static unsigned long UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
2653 return MAKELONG(pStubMsg->dwDestContext,
2654 pStubMsg->RpcMsg->DataRepresentation);
2657 #define USER_MARSHAL_PTR_PREFIX \
2658 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
2659 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
2661 /***********************************************************************
2662 * NdrUserMarshalMarshall [RPCRT4.@]
2664 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2665 unsigned char *pMemory,
2666 PFORMAT_STRING pFormat)
2668 unsigned flags = pFormat[1];
2669 unsigned index = *(const WORD*)&pFormat[2];
2670 unsigned long uflag = UserMarshalFlags(pStubMsg);
2671 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2672 TRACE("index=%d\n", index);
2674 if (flags & USER_MARSHAL_POINTER)
2676 ALIGN_POINTER(pStubMsg->Buffer, 4);
2677 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
2678 pStubMsg->Buffer += 4;
2679 ALIGN_POINTER(pStubMsg->Buffer, 8);
2682 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2685 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
2686 &uflag, pStubMsg->Buffer, pMemory);
2688 STD_OVERFLOW_CHECK(pStubMsg);
2693 /***********************************************************************
2694 * NdrUserMarshalUnmarshall [RPCRT4.@]
2696 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2697 unsigned char **ppMemory,
2698 PFORMAT_STRING pFormat,
2699 unsigned char fMustAlloc)
2701 unsigned flags = pFormat[1];
2702 unsigned index = *(const WORD*)&pFormat[2];
2703 DWORD memsize = *(const WORD*)&pFormat[4];
2704 unsigned long uflag = UserMarshalFlags(pStubMsg);
2705 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2706 TRACE("index=%d\n", index);
2708 if (flags & USER_MARSHAL_POINTER)
2710 ALIGN_POINTER(pStubMsg->Buffer, 4);
2711 /* skip pointer prefix */
2712 pStubMsg->Buffer += 4;
2713 ALIGN_POINTER(pStubMsg->Buffer, 8);
2716 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2718 if (fMustAlloc || !*ppMemory)
2719 *ppMemory = NdrAllocate(pStubMsg, memsize);
2722 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
2723 &uflag, pStubMsg->Buffer, *ppMemory);
2728 /***********************************************************************
2729 * NdrUserMarshalBufferSize [RPCRT4.@]
2731 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2732 unsigned char *pMemory,
2733 PFORMAT_STRING pFormat)
2735 unsigned flags = pFormat[1];
2736 unsigned index = *(const WORD*)&pFormat[2];
2737 DWORD bufsize = *(const WORD*)&pFormat[6];
2738 unsigned long uflag = UserMarshalFlags(pStubMsg);
2739 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2740 TRACE("index=%d\n", index);
2742 if (flags & USER_MARSHAL_POINTER)
2744 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2745 /* skip pointer prefix */
2746 pStubMsg->BufferLength += 4;
2747 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
2750 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
2753 TRACE("size=%ld\n", bufsize);
2754 pStubMsg->BufferLength += bufsize;
2758 pStubMsg->BufferLength =
2759 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
2760 &uflag, pStubMsg->BufferLength, pMemory);
2763 /***********************************************************************
2764 * NdrUserMarshalMemorySize [RPCRT4.@]
2766 unsigned long WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2767 PFORMAT_STRING pFormat)
2769 unsigned flags = pFormat[1];
2770 unsigned index = *(const WORD*)&pFormat[2];
2771 DWORD memsize = *(const WORD*)&pFormat[4];
2772 DWORD bufsize = *(const WORD*)&pFormat[6];
2774 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2775 TRACE("index=%d\n", index);
2777 pStubMsg->MemorySize += memsize;
2779 if (flags & USER_MARSHAL_POINTER)
2781 ALIGN_POINTER(pStubMsg->Buffer, 4);
2782 /* skip pointer prefix */
2783 pStubMsg->Buffer += 4;
2784 ALIGN_POINTER(pStubMsg->Buffer, 8);
2787 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2789 pStubMsg->Buffer += bufsize;
2791 return pStubMsg->MemorySize;
2794 /***********************************************************************
2795 * NdrUserMarshalFree [RPCRT4.@]
2797 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
2798 unsigned char *pMemory,
2799 PFORMAT_STRING pFormat)
2801 /* unsigned flags = pFormat[1]; */
2802 unsigned index = *(const WORD*)&pFormat[2];
2803 unsigned long uflag = UserMarshalFlags(pStubMsg);
2804 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2805 TRACE("index=%d\n", index);
2807 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
2811 /***********************************************************************
2812 * NdrClearOutParameters [RPCRT4.@]
2814 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
2815 PFORMAT_STRING pFormat,
2818 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
2821 /***********************************************************************
2822 * NdrConvert [RPCRT4.@]
2824 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
2826 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
2827 /* FIXME: since this stub doesn't do any converting, the proper behavior
2828 is to raise an exception */
2831 /***********************************************************************
2832 * NdrConvert2 [RPCRT4.@]
2834 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, long NumberParams )
2836 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %ld): stub.\n",
2837 pStubMsg, pFormat, NumberParams);
2838 /* FIXME: since this stub doesn't do any converting, the proper behavior
2839 is to raise an exception */
2842 typedef struct _NDR_CSTRUCT_FORMAT
2845 unsigned char alignment;
2846 unsigned short memory_size;
2847 short offset_to_array_description;
2848 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
2850 /***********************************************************************
2851 * NdrConformantStructMarshall [RPCRT4.@]
2853 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2854 unsigned char *pMemory,
2855 PFORMAT_STRING pFormat)
2857 const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
2858 PFORMAT_STRING pCArrayFormat;
2861 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2863 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2864 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2866 ERR("invalid format type %x\n", pCStructFormat->type);
2867 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2871 pCArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
2872 pCStructFormat->offset_to_array_description;
2873 if (*pCArrayFormat != RPC_FC_CARRAY)
2875 ERR("invalid array format type %x\n", pCStructFormat->type);
2876 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2879 esize = *(const WORD*)(pCArrayFormat+2);
2881 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
2882 pCArrayFormat + 4, 0);
2884 WriteConformance(pStubMsg);
2886 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
2888 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2890 /* copy constant sized part of struct */
2891 pStubMsg->BufferMark = pStubMsg->Buffer;
2892 memcpy(pStubMsg->Buffer, pMemory, pCStructFormat->memory_size + pStubMsg->MaxCount * esize);
2893 pStubMsg->Buffer += pCStructFormat->memory_size + pStubMsg->MaxCount * esize;
2895 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2896 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2898 STD_OVERFLOW_CHECK(pStubMsg);
2903 /***********************************************************************
2904 * NdrConformantStructUnmarshall [RPCRT4.@]
2906 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2907 unsigned char **ppMemory,
2908 PFORMAT_STRING pFormat,
2909 unsigned char fMustAlloc)
2911 const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
2912 PFORMAT_STRING pCArrayFormat;
2915 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2917 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2918 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2920 ERR("invalid format type %x\n", pCStructFormat->type);
2921 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2924 pCArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
2925 pCStructFormat->offset_to_array_description;
2926 if (*pCArrayFormat != RPC_FC_CARRAY)
2928 ERR("invalid array format type %x\n", pCStructFormat->type);
2929 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2932 esize = *(const WORD*)(pCArrayFormat+2);
2934 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
2936 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
2938 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2940 /* work out how much memory to allocate if we need to do so */
2941 if (!*ppMemory || fMustAlloc)
2943 SIZE_T size = pCStructFormat->memory_size + pStubMsg->MaxCount * esize;
2944 *ppMemory = NdrAllocate(pStubMsg, size);
2947 /* now copy the data */
2948 pStubMsg->BufferMark = pStubMsg->Buffer;
2949 memcpy(*ppMemory, pStubMsg->Buffer, pCStructFormat->memory_size + pStubMsg->MaxCount * esize);
2950 pStubMsg->Buffer += pCStructFormat->memory_size + pStubMsg->MaxCount * esize;
2952 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2953 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2958 /***********************************************************************
2959 * NdrConformantStructBufferSize [RPCRT4.@]
2961 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2962 unsigned char *pMemory,
2963 PFORMAT_STRING pFormat)
2965 const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
2966 PFORMAT_STRING pCArrayFormat;
2969 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2971 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2972 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2974 ERR("invalid format type %x\n", pCStructFormat->type);
2975 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2978 pCArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
2979 pCStructFormat->offset_to_array_description;
2980 if (*pCArrayFormat != RPC_FC_CARRAY)
2982 ERR("invalid array format type %x\n", pCStructFormat->type);
2983 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2986 esize = *(const WORD*)(pCArrayFormat+2);
2988 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
2989 SizeConformance(pStubMsg);
2991 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
2993 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2995 pStubMsg->BufferLength += pCStructFormat->memory_size + esize * pStubMsg->MaxCount;
2997 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2998 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3001 /***********************************************************************
3002 * NdrConformantStructMemorySize [RPCRT4.@]
3004 unsigned long WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3005 PFORMAT_STRING pFormat)
3011 /***********************************************************************
3012 * NdrConformantStructFree [RPCRT4.@]
3014 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3015 unsigned char *pMemory,
3016 PFORMAT_STRING pFormat)
3021 /***********************************************************************
3022 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3024 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3025 unsigned char *pMemory,
3026 PFORMAT_STRING pFormat)
3028 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3029 PFORMAT_STRING pCVArrayFormat;
3032 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3034 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3035 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3037 ERR("invalid format type %x\n", pCVStructFormat->type);
3038 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3042 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3043 pCVStructFormat->offset_to_array_description;
3044 switch (*pCVArrayFormat)
3046 case RPC_FC_CVARRAY:
3047 esize = *(const WORD*)(pCVArrayFormat+2);
3049 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3050 pCVArrayFormat + 4, 0);
3051 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3054 case RPC_FC_C_CSTRING:
3055 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3056 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3057 esize = sizeof(char);
3058 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3059 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3060 pCVArrayFormat + 2, 0);
3062 pStubMsg->MaxCount = pStubMsg->ActualCount;
3064 case RPC_FC_C_WSTRING:
3065 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3066 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3067 esize = sizeof(WCHAR);
3068 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3069 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3070 pCVArrayFormat + 2, 0);
3072 pStubMsg->MaxCount = pStubMsg->ActualCount;
3075 ERR("invalid array format type %x\n", *pCVArrayFormat);
3076 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3080 WriteConformance(pStubMsg);
3082 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3084 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3086 /* write constant sized part */
3087 pStubMsg->BufferMark = pStubMsg->Buffer;
3088 memcpy(pStubMsg->Buffer, pMemory, pCVStructFormat->memory_size);
3089 pStubMsg->Buffer += pCVStructFormat->memory_size;
3091 WriteVariance(pStubMsg);
3093 /* write array part */
3094 memcpy(pStubMsg->Buffer, pMemory + pCVStructFormat->memory_size, pStubMsg->ActualCount * esize);
3095 pStubMsg->Buffer += pStubMsg->ActualCount * esize;
3097 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3099 STD_OVERFLOW_CHECK(pStubMsg);
3104 /***********************************************************************
3105 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3107 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3108 unsigned char **ppMemory,
3109 PFORMAT_STRING pFormat,
3110 unsigned char fMustAlloc)
3112 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3113 PFORMAT_STRING pCVArrayFormat;
3115 unsigned char cvarray_type;
3117 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3119 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3120 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3122 ERR("invalid format type %x\n", pCVStructFormat->type);
3123 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3127 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3128 pCVStructFormat->offset_to_array_description;
3129 cvarray_type = *pCVArrayFormat;
3130 switch (cvarray_type)
3132 case RPC_FC_CVARRAY:
3133 esize = *(const WORD*)(pCVArrayFormat+2);
3134 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3136 case RPC_FC_C_CSTRING:
3137 esize = sizeof(char);
3138 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3139 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3141 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3143 case RPC_FC_C_WSTRING:
3144 esize = sizeof(WCHAR);
3145 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3146 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3148 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3151 ERR("invalid array format type %x\n", *pCVArrayFormat);
3152 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3156 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3158 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3160 /* work out how much memory to allocate if we need to do so */
3161 if (!*ppMemory || fMustAlloc)
3163 SIZE_T size = pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3164 *ppMemory = NdrAllocate(pStubMsg, size);
3167 /* copy the constant data */
3168 pStubMsg->BufferMark = pStubMsg->Buffer;
3169 memcpy(*ppMemory, pStubMsg->Buffer, pCVStructFormat->memory_size);
3170 pStubMsg->Buffer += pCVStructFormat->memory_size;
3172 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat);
3174 /* copy the array data */
3175 memcpy(*ppMemory + pCVStructFormat->memory_size, pStubMsg->Buffer,
3176 pStubMsg->ActualCount * esize);
3177 pStubMsg->Buffer += pStubMsg->ActualCount * esize;
3179 if (cvarray_type == RPC_FC_C_CSTRING)
3180 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3181 else if (cvarray_type == RPC_FC_C_WSTRING)
3182 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3184 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3189 /***********************************************************************
3190 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3192 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3193 unsigned char *pMemory,
3194 PFORMAT_STRING pFormat)
3196 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3197 PFORMAT_STRING pCVArrayFormat;
3200 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3202 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3203 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3205 ERR("invalid format type %x\n", pCVStructFormat->type);
3206 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3210 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3211 pCVStructFormat->offset_to_array_description;
3212 switch (*pCVArrayFormat)
3214 case RPC_FC_CVARRAY:
3215 esize = *(const WORD*)(pCVArrayFormat+2);
3217 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3218 pCVArrayFormat + 4, 0);
3219 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3222 case RPC_FC_C_CSTRING:
3223 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3224 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3225 esize = sizeof(char);
3226 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3227 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3228 pCVArrayFormat + 2, 0);
3230 pStubMsg->MaxCount = pStubMsg->ActualCount;
3232 case RPC_FC_C_WSTRING:
3233 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3234 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3235 esize = sizeof(WCHAR);
3236 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3237 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3238 pCVArrayFormat + 2, 0);
3240 pStubMsg->MaxCount = pStubMsg->ActualCount;
3243 ERR("invalid array format type %x\n", *pCVArrayFormat);
3244 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3248 SizeConformance(pStubMsg);
3250 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
3252 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3254 pStubMsg->BufferLength += pCVStructFormat->memory_size;
3255 SizeVariance(pStubMsg);
3256 pStubMsg->BufferLength += esize * pStubMsg->MaxCount;
3258 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3261 /***********************************************************************
3262 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3264 unsigned long WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3265 PFORMAT_STRING pFormat)
3267 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3268 PFORMAT_STRING pCVArrayFormat;
3270 unsigned char cvarray_type;
3272 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3274 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3275 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3277 ERR("invalid format type %x\n", pCVStructFormat->type);
3278 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3282 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3283 pCVStructFormat->offset_to_array_description;
3284 cvarray_type = *pCVArrayFormat;
3285 switch (cvarray_type)
3287 case RPC_FC_CVARRAY:
3288 esize = *(const WORD*)(pCVArrayFormat+2);
3289 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3291 case RPC_FC_C_CSTRING:
3292 esize = sizeof(char);
3293 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3294 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3296 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3298 case RPC_FC_C_WSTRING:
3299 esize = sizeof(WCHAR);
3300 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3301 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3303 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3306 ERR("invalid array format type %x\n", *pCVArrayFormat);
3307 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3311 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3313 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3315 pStubMsg->Buffer += pCVStructFormat->memory_size;
3316 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat);
3317 pStubMsg->Buffer += pCVStructFormat->memory_size + pStubMsg->ActualCount * esize;
3319 pStubMsg->MemorySize += pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3321 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3323 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3326 /***********************************************************************
3327 * NdrConformantVaryingStructFree [RPCRT4.@]
3329 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3330 unsigned char *pMemory,
3331 PFORMAT_STRING pFormat)
3333 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3334 PFORMAT_STRING pCVArrayFormat;
3337 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3339 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3340 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3342 ERR("invalid format type %x\n", pCVStructFormat->type);
3343 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3347 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3348 pCVStructFormat->offset_to_array_description;
3349 switch (*pCVArrayFormat)
3351 case RPC_FC_CVARRAY:
3352 esize = *(const WORD*)(pCVArrayFormat+2);
3354 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3355 pCVArrayFormat + 4, 0);
3356 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3359 case RPC_FC_C_CSTRING:
3360 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3361 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3362 esize = sizeof(char);
3363 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3364 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3365 pCVArrayFormat + 2, 0);
3367 pStubMsg->MaxCount = pStubMsg->ActualCount;
3369 case RPC_FC_C_WSTRING:
3370 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3371 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3372 esize = sizeof(WCHAR);
3373 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3374 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3375 pCVArrayFormat + 2, 0);
3377 pStubMsg->MaxCount = pStubMsg->ActualCount;
3380 ERR("invalid array format type %x\n", *pCVArrayFormat);
3381 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3385 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3387 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3393 unsigned char alignment;
3394 unsigned short total_size;
3395 } NDR_SMFARRAY_FORMAT;
3400 unsigned char alignment;
3401 unsigned long total_size;
3402 } NDR_LGFARRAY_FORMAT;
3404 /***********************************************************************
3405 * NdrFixedArrayMarshall [RPCRT4.@]
3407 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3408 unsigned char *pMemory,
3409 PFORMAT_STRING pFormat)
3411 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3412 unsigned long total_size;
3414 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3416 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3417 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3419 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3420 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3424 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3426 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3428 total_size = pSmFArrayFormat->total_size;
3429 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3433 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3434 total_size = pLgFArrayFormat->total_size;
3435 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3437 memcpy(pStubMsg->Buffer, pMemory, total_size);
3438 pStubMsg->Buffer += total_size;
3440 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3445 /***********************************************************************
3446 * NdrFixedArrayUnmarshall [RPCRT4.@]
3448 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3449 unsigned char **ppMemory,
3450 PFORMAT_STRING pFormat,
3451 unsigned char fMustAlloc)
3453 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3454 unsigned long total_size;
3456 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3458 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3459 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3461 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3462 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3466 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3468 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3470 total_size = pSmFArrayFormat->total_size;
3471 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3475 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3476 total_size = pLgFArrayFormat->total_size;
3477 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3480 if (fMustAlloc || !*ppMemory)
3481 *ppMemory = NdrAllocate(pStubMsg, total_size);
3482 memcpy(*ppMemory, pStubMsg->Buffer, total_size);
3483 pStubMsg->Buffer += total_size;
3485 pFormat = EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3490 /***********************************************************************
3491 * NdrFixedArrayBufferSize [RPCRT4.@]
3493 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3494 unsigned char *pMemory,
3495 PFORMAT_STRING pFormat)
3497 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3498 unsigned long total_size;
3500 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3502 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3503 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3505 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3506 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3510 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
3512 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3514 total_size = pSmFArrayFormat->total_size;
3515 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3519 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3520 total_size = pLgFArrayFormat->total_size;
3521 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3523 pStubMsg->BufferLength += total_size;
3525 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3528 /***********************************************************************
3529 * NdrFixedArrayMemorySize [RPCRT4.@]
3531 unsigned long WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3532 PFORMAT_STRING pFormat)
3534 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3535 unsigned long total_size;
3537 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3539 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3540 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3542 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3543 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3547 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3549 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3551 total_size = pSmFArrayFormat->total_size;
3552 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3556 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3557 total_size = pLgFArrayFormat->total_size;
3558 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3560 pStubMsg->Buffer += total_size;
3561 pStubMsg->MemorySize += total_size;
3563 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3568 /***********************************************************************
3569 * NdrFixedArrayFree [RPCRT4.@]
3571 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3572 unsigned char *pMemory,
3573 PFORMAT_STRING pFormat)
3575 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3577 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3579 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3580 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3582 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3583 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3587 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3588 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3591 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3592 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3595 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3598 /***********************************************************************
3599 * NdrVaryingArrayMarshall [RPCRT4.@]
3601 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3602 unsigned char *pMemory,
3603 PFORMAT_STRING pFormat)
3605 unsigned char alignment;
3606 DWORD elements, esize;
3608 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3610 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3611 (pFormat[0] != RPC_FC_LGVARRAY))
3613 ERR("invalid format type %x\n", pFormat[0]);
3614 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3618 alignment = pFormat[1] + 1;
3620 if (pFormat[0] == RPC_FC_SMVARRAY)
3623 pFormat += sizeof(WORD);
3624 elements = *(const WORD*)pFormat;
3625 pFormat += sizeof(WORD);
3630 pFormat += sizeof(DWORD);
3631 elements = *(const DWORD*)pFormat;
3632 pFormat += sizeof(DWORD);
3635 esize = *(const WORD*)pFormat;
3636 pFormat += sizeof(WORD);
3638 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3639 if ((pStubMsg->ActualCount > elements) ||
3640 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3642 RpcRaiseException(RPC_S_INVALID_BOUND);
3646 WriteVariance(pStubMsg);
3648 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3650 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, pStubMsg->ActualCount*esize);
3651 pStubMsg->BufferMark = pStubMsg->Buffer;
3652 pStubMsg->Buffer += pStubMsg->ActualCount*esize;
3654 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3656 STD_OVERFLOW_CHECK(pStubMsg);
3661 /***********************************************************************
3662 * NdrVaryingArrayUnmarshall [RPCRT4.@]
3664 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3665 unsigned char **ppMemory,
3666 PFORMAT_STRING pFormat,
3667 unsigned char fMustAlloc)
3669 unsigned char alignment;
3670 DWORD size, elements, esize;
3672 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3674 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3675 (pFormat[0] != RPC_FC_LGVARRAY))
3677 ERR("invalid format type %x\n", pFormat[0]);
3678 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3682 alignment = pFormat[1] + 1;
3684 if (pFormat[0] == RPC_FC_SMVARRAY)
3687 size = *(const WORD*)pFormat;
3688 pFormat += sizeof(WORD);
3689 elements = *(const WORD*)pFormat;
3690 pFormat += sizeof(WORD);
3695 size = *(const DWORD*)pFormat;
3696 pFormat += sizeof(DWORD);
3697 elements = *(const DWORD*)pFormat;
3698 pFormat += sizeof(DWORD);
3701 esize = *(const WORD*)pFormat;
3702 pFormat += sizeof(WORD);
3704 pFormat = ReadVariance(pStubMsg, pFormat);
3705 if ((pStubMsg->ActualCount > elements) ||
3706 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3708 RpcRaiseException(RPC_S_INVALID_BOUND);
3712 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3714 if (!*ppMemory || fMustAlloc)
3715 *ppMemory = NdrAllocate(pStubMsg, size);
3716 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, pStubMsg->ActualCount * esize);
3717 pStubMsg->Buffer += pStubMsg->ActualCount * esize;
3719 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3724 /***********************************************************************
3725 * NdrVaryingArrayBufferSize [RPCRT4.@]
3727 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3728 unsigned char *pMemory,
3729 PFORMAT_STRING pFormat)
3731 unsigned char alignment;
3732 DWORD elements, esize;
3734 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3736 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3737 (pFormat[0] != RPC_FC_LGVARRAY))
3739 ERR("invalid format type %x\n", pFormat[0]);
3740 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3744 alignment = pFormat[1] + 1;
3746 if (pFormat[0] == RPC_FC_SMVARRAY)
3749 pFormat += sizeof(WORD);
3750 elements = *(const WORD*)pFormat;
3751 pFormat += sizeof(WORD);
3756 pFormat += sizeof(DWORD);
3757 elements = *(const DWORD*)pFormat;
3758 pFormat += sizeof(DWORD);
3761 esize = *(const WORD*)pFormat;
3762 pFormat += sizeof(WORD);
3764 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3765 if ((pStubMsg->ActualCount > elements) ||
3766 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3768 RpcRaiseException(RPC_S_INVALID_BOUND);
3772 SizeVariance(pStubMsg);
3774 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3776 pStubMsg->BufferLength += pStubMsg->ActualCount * esize;
3778 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3781 /***********************************************************************
3782 * NdrVaryingArrayMemorySize [RPCRT4.@]
3784 unsigned long WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3785 PFORMAT_STRING pFormat)
3787 unsigned char alignment;
3788 DWORD size, elements, esize;
3790 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3792 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3793 (pFormat[0] != RPC_FC_LGVARRAY))
3795 ERR("invalid format type %x\n", pFormat[0]);
3796 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3800 alignment = pFormat[1] + 1;
3802 if (pFormat[0] == RPC_FC_SMVARRAY)
3805 size = *(const WORD*)pFormat;
3806 pFormat += sizeof(WORD);
3807 elements = *(const WORD*)pFormat;
3808 pFormat += sizeof(WORD);
3813 size = *(const DWORD*)pFormat;
3814 pFormat += sizeof(DWORD);
3815 elements = *(const DWORD*)pFormat;
3816 pFormat += sizeof(DWORD);
3819 esize = *(const WORD*)pFormat;
3820 pFormat += sizeof(WORD);
3822 pFormat = ReadVariance(pStubMsg, pFormat);
3823 if ((pStubMsg->ActualCount > elements) ||
3824 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3826 RpcRaiseException(RPC_S_INVALID_BOUND);
3830 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3832 pStubMsg->Buffer += pStubMsg->ActualCount * esize;
3833 pStubMsg->MemorySize += size;
3835 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3837 return pStubMsg->MemorySize;
3840 /***********************************************************************
3841 * NdrVaryingArrayFree [RPCRT4.@]
3843 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3844 unsigned char *pMemory,
3845 PFORMAT_STRING pFormat)
3847 unsigned char alignment;
3850 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3852 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3853 (pFormat[0] != RPC_FC_LGVARRAY))
3855 ERR("invalid format type %x\n", pFormat[0]);
3856 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3860 alignment = pFormat[1] + 1;
3862 if (pFormat[0] == RPC_FC_SMVARRAY)
3865 pFormat += sizeof(WORD);
3866 elements = *(const WORD*)pFormat;
3867 pFormat += sizeof(WORD);
3872 pFormat += sizeof(DWORD);
3873 elements = *(const DWORD*)pFormat;
3874 pFormat += sizeof(DWORD);
3877 pFormat += sizeof(WORD);
3879 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3880 if ((pStubMsg->ActualCount > elements) ||
3881 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3883 RpcRaiseException(RPC_S_INVALID_BOUND);
3887 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3890 /***********************************************************************
3891 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
3893 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3894 unsigned char *pMemory,
3895 PFORMAT_STRING pFormat)
3901 /***********************************************************************
3902 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
3904 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3905 unsigned char **ppMemory,
3906 PFORMAT_STRING pFormat,
3907 unsigned char fMustAlloc)
3913 /***********************************************************************
3914 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
3916 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3917 unsigned char *pMemory,
3918 PFORMAT_STRING pFormat)
3923 /***********************************************************************
3924 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
3926 unsigned long WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3927 PFORMAT_STRING pFormat)
3933 /***********************************************************************
3934 * NdrEncapsulatedUnionFree [RPCRT4.@]
3936 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
3937 unsigned char *pMemory,
3938 PFORMAT_STRING pFormat)
3943 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
3944 unsigned long discriminant,
3945 PFORMAT_STRING pFormat)
3947 unsigned short num_arms, arm, type;
3949 num_arms = *(const SHORT*)pFormat & 0x0fff;
3951 for(arm = 0; arm < num_arms; arm++)
3953 if(discriminant == *(const ULONG*)pFormat)
3961 type = *(const unsigned short*)pFormat;
3962 TRACE("type %04x\n", type);
3963 if(arm == num_arms) /* default arm extras */
3967 ERR("no arm for 0x%lx and no default case\n", discriminant);
3968 RpcRaiseException(RPC_S_INVALID_TAG);
3973 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
3980 static PFORMAT_STRING get_non_encapsulated_union_arm(PMIDL_STUB_MESSAGE pStubMsg,
3982 PFORMAT_STRING pFormat)
3984 pFormat += *(const SHORT*)pFormat;
3987 return get_arm_offset_from_union_arm_selector(pStubMsg, value, pFormat);
3990 /***********************************************************************
3991 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
3993 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3994 unsigned char *pMemory,
3995 PFORMAT_STRING pFormat)
3997 unsigned short type;
3998 unsigned char switch_type;
4000 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4003 switch_type = *pFormat;
4006 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4007 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4008 /* Marshall discriminant */
4009 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4011 pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
4015 type = *(const unsigned short*)pFormat;
4016 if((type & 0xff00) == 0x8000)
4018 unsigned char basetype = LOBYTE(type);
4019 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
4023 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4024 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
4027 unsigned char *saved_buffer = NULL;
4034 saved_buffer = pStubMsg->Buffer;
4035 pStubMsg->Buffer += 4; /* for pointer ID */
4036 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
4039 m(pStubMsg, pMemory, desc);
4042 else FIXME("no marshaller for embedded type %02x\n", *desc);
4047 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
4048 PFORMAT_STRING *ppFormat)
4050 long discriminant = 0;
4058 discriminant = *(UCHAR *)pStubMsg->Buffer;
4059 pStubMsg->Buffer += sizeof(UCHAR);
4064 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4065 discriminant = *(USHORT *)pStubMsg->Buffer;
4066 pStubMsg->Buffer += sizeof(USHORT);
4070 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4071 discriminant = *(ULONG *)pStubMsg->Buffer;
4072 pStubMsg->Buffer += sizeof(ULONG);
4075 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
4079 if (pStubMsg->fHasNewCorrDesc)
4083 return discriminant;
4086 /**********************************************************************
4087 * NdrNonEncapsulatedUnionUnmarshall[RPCRT4.@]
4089 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4090 unsigned char **ppMemory,
4091 PFORMAT_STRING pFormat,
4092 unsigned char fMustAlloc)
4095 unsigned short type, size;
4097 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4100 /* Unmarshall discriminant */
4101 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4102 TRACE("unmarshalled discriminant %lx\n", discriminant);
4104 pFormat += *(const SHORT*)pFormat;
4106 size = *(const unsigned short*)pFormat;
4109 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4113 if(!*ppMemory || fMustAlloc)
4114 *ppMemory = NdrAllocate(pStubMsg, size);
4116 type = *(const unsigned short*)pFormat;
4117 if((type & 0xff00) == 0x8000)
4119 unsigned char basetype = LOBYTE(type);
4120 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, fMustAlloc);
4124 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4125 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
4128 unsigned char *saved_buffer = NULL;
4135 ALIGN_POINTER(pStubMsg->Buffer, 4);
4136 saved_buffer = pStubMsg->Buffer;
4137 pStubMsg->Buffer += 4; /* for pointer ID */
4138 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, desc, TRUE);
4141 m(pStubMsg, ppMemory, desc, fMustAlloc);
4144 else FIXME("no marshaller for embedded type %02x\n", *desc);
4149 /***********************************************************************
4150 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
4152 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4153 unsigned char *pMemory,
4154 PFORMAT_STRING pFormat)
4156 unsigned short type;
4157 unsigned char switch_type;
4159 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4162 switch_type = *pFormat;
4165 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4166 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4167 /* Add discriminant size */
4168 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4170 pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
4174 type = *(const unsigned short*)pFormat;
4175 if((type & 0xff00) == 0x8000)
4177 unsigned char basetype = LOBYTE(type);
4178 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
4182 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4183 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
4192 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4193 pStubMsg->BufferLength += 4; /* for pointer ID */
4194 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
4197 m(pStubMsg, pMemory, desc);
4200 else FIXME("no buffersizer for embedded type %02x\n", *desc);
4205 /***********************************************************************
4206 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
4208 unsigned long WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4209 PFORMAT_STRING pFormat)
4211 unsigned long discriminant;
4212 unsigned short type, size;
4215 /* Unmarshall discriminant */
4216 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4217 TRACE("unmarshalled discriminant 0x%lx\n", discriminant);
4219 pFormat += *(const SHORT*)pFormat;
4221 size = *(const unsigned short*)pFormat;
4224 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4228 pStubMsg->Memory += size;
4230 type = *(const unsigned short*)pFormat;
4231 if((type & 0xff00) == 0x8000)
4233 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
4237 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4238 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
4239 unsigned char *saved_buffer;
4248 ALIGN_POINTER(pStubMsg->Buffer, 4);
4249 saved_buffer = pStubMsg->Buffer;
4250 pStubMsg->Buffer += 4;
4251 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
4252 pStubMsg->MemorySize += 4;
4253 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
4256 return m(pStubMsg, desc);
4259 else FIXME("no marshaller for embedded type %02x\n", *desc);
4262 TRACE("size %d\n", size);
4266 /***********************************************************************
4267 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
4269 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4270 unsigned char *pMemory,
4271 PFORMAT_STRING pFormat)
4276 /***********************************************************************
4277 * NdrByteCountPointerMarshall [RPCRT4.@]
4279 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4280 unsigned char *pMemory,
4281 PFORMAT_STRING pFormat)
4287 /***********************************************************************
4288 * NdrByteCountPointerUnmarshall [RPCRT4.@]
4290 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4291 unsigned char **ppMemory,
4292 PFORMAT_STRING pFormat,
4293 unsigned char fMustAlloc)
4299 /***********************************************************************
4300 * NdrByteCountPointerBufferSize [RPCRT4.@]
4302 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4303 unsigned char *pMemory,
4304 PFORMAT_STRING pFormat)
4309 /***********************************************************************
4310 * NdrByteCountPointerMemorySize [RPCRT4.@]
4312 unsigned long WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4313 PFORMAT_STRING pFormat)
4319 /***********************************************************************
4320 * NdrByteCountPointerFree [RPCRT4.@]
4322 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
4323 unsigned char *pMemory,
4324 PFORMAT_STRING pFormat)
4329 /***********************************************************************
4330 * NdrXmitOrRepAsMarshall [RPCRT4.@]
4332 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4333 unsigned char *pMemory,
4334 PFORMAT_STRING pFormat)
4340 /***********************************************************************
4341 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
4343 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4344 unsigned char **ppMemory,
4345 PFORMAT_STRING pFormat,
4346 unsigned char fMustAlloc)
4352 /***********************************************************************
4353 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
4355 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4356 unsigned char *pMemory,
4357 PFORMAT_STRING pFormat)
4362 /***********************************************************************
4363 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
4365 unsigned long WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4366 PFORMAT_STRING pFormat)
4372 /***********************************************************************
4373 * NdrXmitOrRepAsFree [RPCRT4.@]
4375 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
4376 unsigned char *pMemory,
4377 PFORMAT_STRING pFormat)
4382 /***********************************************************************
4383 * NdrBaseTypeMarshall [internal]
4385 static unsigned char *WINAPI NdrBaseTypeMarshall(
4386 PMIDL_STUB_MESSAGE pStubMsg,
4387 unsigned char *pMemory,
4388 PFORMAT_STRING pFormat)
4390 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4398 *(UCHAR *)pStubMsg->Buffer = *(UCHAR *)pMemory;
4399 pStubMsg->Buffer += sizeof(UCHAR);
4400 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
4405 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4406 *(USHORT *)pStubMsg->Buffer = *(USHORT *)pMemory;
4407 pStubMsg->Buffer += sizeof(USHORT);
4408 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
4412 case RPC_FC_ERROR_STATUS_T:
4414 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4415 *(ULONG *)pStubMsg->Buffer = *(ULONG *)pMemory;
4416 pStubMsg->Buffer += sizeof(ULONG);
4417 TRACE("value: 0x%08lx\n", *(ULONG *)pMemory);
4420 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
4421 *(float *)pStubMsg->Buffer = *(float *)pMemory;
4422 pStubMsg->Buffer += sizeof(float);
4425 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
4426 *(double *)pStubMsg->Buffer = *(double *)pMemory;
4427 pStubMsg->Buffer += sizeof(double);
4430 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
4431 *(ULONGLONG *)pStubMsg->Buffer = *(ULONGLONG *)pMemory;
4432 pStubMsg->Buffer += sizeof(ULONGLONG);
4433 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
4436 /* only 16-bits on the wire, so do a sanity check */
4437 if (*(UINT *)pMemory > USHRT_MAX)
4438 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
4439 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4440 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
4441 pStubMsg->Buffer += sizeof(USHORT);
4442 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
4445 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4448 STD_OVERFLOW_CHECK(pStubMsg);
4450 /* FIXME: what is the correct return value? */
4454 /***********************************************************************
4455 * NdrBaseTypeUnmarshall [internal]
4457 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
4458 PMIDL_STUB_MESSAGE pStubMsg,
4459 unsigned char **ppMemory,
4460 PFORMAT_STRING pFormat,
4461 unsigned char fMustAlloc)
4463 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
4465 #define BASE_TYPE_UNMARSHALL(type) \
4466 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
4467 if (fMustAlloc || !*ppMemory) \
4468 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
4469 TRACE("*ppMemory: %p\n", *ppMemory); \
4470 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
4471 pStubMsg->Buffer += sizeof(type);
4479 BASE_TYPE_UNMARSHALL(UCHAR);
4480 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
4485 BASE_TYPE_UNMARSHALL(USHORT);
4486 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
4490 case RPC_FC_ERROR_STATUS_T:
4492 BASE_TYPE_UNMARSHALL(ULONG);
4493 TRACE("value: 0x%08lx\n", **(ULONG **)ppMemory);
4496 BASE_TYPE_UNMARSHALL(float);
4497 TRACE("value: %f\n", **(float **)ppMemory);
4500 BASE_TYPE_UNMARSHALL(double);
4501 TRACE("value: %f\n", **(double **)ppMemory);
4504 BASE_TYPE_UNMARSHALL(ULONGLONG);
4505 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
4508 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4509 if (fMustAlloc || !*ppMemory)
4510 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
4511 TRACE("*ppMemory: %p\n", *ppMemory);
4512 /* 16-bits on the wire, but int in memory */
4513 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
4514 pStubMsg->Buffer += sizeof(USHORT);
4515 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
4518 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4520 #undef BASE_TYPE_UNMARSHALL
4522 /* FIXME: what is the correct return value? */
4527 /***********************************************************************
4528 * NdrBaseTypeBufferSize [internal]
4530 static void WINAPI NdrBaseTypeBufferSize(
4531 PMIDL_STUB_MESSAGE pStubMsg,
4532 unsigned char *pMemory,
4533 PFORMAT_STRING pFormat)
4535 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4543 pStubMsg->BufferLength += sizeof(UCHAR);
4549 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
4550 pStubMsg->BufferLength += sizeof(USHORT);
4555 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
4556 pStubMsg->BufferLength += sizeof(ULONG);
4559 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
4560 pStubMsg->BufferLength += sizeof(float);
4563 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
4564 pStubMsg->BufferLength += sizeof(double);
4567 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
4568 pStubMsg->BufferLength += sizeof(ULONGLONG);
4570 case RPC_FC_ERROR_STATUS_T:
4571 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
4572 pStubMsg->BufferLength += sizeof(error_status_t);
4575 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4579 /***********************************************************************
4580 * NdrBaseTypeMemorySize [internal]
4582 static unsigned long WINAPI NdrBaseTypeMemorySize(
4583 PMIDL_STUB_MESSAGE pStubMsg,
4584 PFORMAT_STRING pFormat)
4592 pStubMsg->Buffer += sizeof(UCHAR);
4593 pStubMsg->MemorySize += sizeof(UCHAR);
4594 return sizeof(UCHAR);
4598 pStubMsg->Buffer += sizeof(USHORT);
4599 pStubMsg->MemorySize += sizeof(USHORT);
4600 return sizeof(USHORT);
4603 pStubMsg->Buffer += sizeof(ULONG);
4604 pStubMsg->MemorySize += sizeof(ULONG);
4605 return sizeof(ULONG);
4607 pStubMsg->Buffer += sizeof(float);
4608 pStubMsg->MemorySize += sizeof(float);
4609 return sizeof(float);
4611 pStubMsg->Buffer += sizeof(double);
4612 pStubMsg->MemorySize += sizeof(double);
4613 return sizeof(double);
4615 pStubMsg->Buffer += sizeof(ULONGLONG);
4616 pStubMsg->MemorySize += sizeof(ULONGLONG);
4617 return sizeof(ULONGLONG);
4618 case RPC_FC_ERROR_STATUS_T:
4619 pStubMsg->Buffer += sizeof(error_status_t);
4620 pStubMsg->MemorySize += sizeof(error_status_t);
4621 return sizeof(error_status_t);
4624 pStubMsg->Buffer += sizeof(INT);
4625 pStubMsg->MemorySize += sizeof(INT);
4628 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4633 /***********************************************************************
4634 * NdrBaseTypeFree [internal]
4636 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
4637 unsigned char *pMemory,
4638 PFORMAT_STRING pFormat)
4640 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4645 /***********************************************************************
4646 * NdrClientContextMarshall
4648 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4649 NDR_CCONTEXT ContextHandle,
4652 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
4654 ALIGN_POINTER(pStubMsg->Buffer, 4);
4656 /* FIXME: what does fCheck do? */
4657 NDRCContextMarshall(ContextHandle,
4660 pStubMsg->Buffer += cbNDRContext;
4663 /***********************************************************************
4664 * NdrClientContextUnmarshall
4666 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4667 NDR_CCONTEXT * pContextHandle,
4668 RPC_BINDING_HANDLE BindHandle)
4670 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
4672 ALIGN_POINTER(pStubMsg->Buffer, 4);
4674 NDRCContextUnmarshall(pContextHandle,
4677 pStubMsg->RpcMsg->DataRepresentation);
4679 pStubMsg->Buffer += cbNDRContext;
4682 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4683 NDR_SCONTEXT ContextHandle,
4684 NDR_RUNDOWN RundownRoutine )
4686 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
4689 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
4691 FIXME("(%p): stub\n", pStubMsg);
4695 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
4696 unsigned char* pMemory,
4697 PFORMAT_STRING pFormat)
4699 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
4702 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
4703 PFORMAT_STRING pFormat)
4705 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
4709 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4710 NDR_SCONTEXT ContextHandle,
4711 NDR_RUNDOWN RundownRoutine,
4712 PFORMAT_STRING pFormat)
4714 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
4717 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4718 PFORMAT_STRING pFormat)
4720 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
4724 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
4726 typedef struct ndr_context_handle
4730 } ndr_context_handle;
4732 struct context_handle_entry
4736 RPC_BINDING_HANDLE handle;
4737 ndr_context_handle wire_data;
4740 static struct list context_handle_list = LIST_INIT(context_handle_list);
4742 static CRITICAL_SECTION ndr_context_cs;
4743 static CRITICAL_SECTION_DEBUG ndr_context_debug =
4745 0, 0, &ndr_context_cs,
4746 { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
4747 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
4749 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
4751 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
4753 struct context_handle_entry *che = (struct context_handle_entry*) CContext;
4755 if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
4760 static struct context_handle_entry *context_entry_from_guid(LPGUID uuid)
4762 struct context_handle_entry *che;
4763 LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
4764 if (IsEqualGUID(&che->wire_data.uuid, uuid))
4769 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
4771 struct context_handle_entry *che;
4772 RPC_BINDING_HANDLE handle = NULL;
4774 TRACE("%p\n", CContext);
4776 EnterCriticalSection(&ndr_context_cs);
4777 che = get_context_entry(CContext);
4779 handle = che->handle;
4780 LeaveCriticalSection(&ndr_context_cs);
4783 RpcRaiseException(ERROR_INVALID_HANDLE);
4787 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
4789 struct context_handle_entry *che;
4791 TRACE("%p %p\n", CContext, pBuff);
4795 EnterCriticalSection(&ndr_context_cs);
4796 che = get_context_entry(CContext);
4797 memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
4798 LeaveCriticalSection(&ndr_context_cs);
4802 ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
4803 wire_data->attributes = 0;
4804 wire_data->uuid = GUID_NULL;
4808 static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
4809 RPC_BINDING_HANDLE hBinding,
4810 ndr_context_handle *chi)
4812 struct context_handle_entry *che = NULL;
4814 /* a null UUID means we should free the context handle */
4815 if (IsEqualGUID(&chi->uuid, &GUID_NULL))
4819 che = get_context_entry(*CContext);
4821 return ERROR_INVALID_HANDLE;
4822 list_remove(&che->entry);
4823 RpcBindingFree(&che->handle);
4824 HeapFree(GetProcessHeap(), 0, che);
4828 /* if there's no existing entry matching the GUID, allocate one */
4829 else if (!(che = context_entry_from_guid(&chi->uuid)))
4831 che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
4833 return ERROR_NOT_ENOUGH_MEMORY;
4834 che->magic = NDR_CONTEXT_HANDLE_MAGIC;
4835 RpcBindingCopy(hBinding, &che->handle);
4836 list_add_tail(&context_handle_list, &che->entry);
4837 memcpy(&che->wire_data, chi, sizeof *chi);
4842 return ERROR_SUCCESS;
4845 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
4846 RPC_BINDING_HANDLE hBinding,
4848 unsigned long DataRepresentation)
4852 TRACE("*%p=(%p) %p %p %08lx\n",
4853 CContext, *CContext, hBinding, pBuff, DataRepresentation);
4855 EnterCriticalSection(&ndr_context_cs);
4856 r = ndr_update_context_handle(CContext, hBinding, pBuff);
4857 LeaveCriticalSection(&ndr_context_cs);
4859 RpcRaiseException(r);
4862 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
4864 NDR_RUNDOWN userRunDownIn)
4866 FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn);
4869 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
4870 NDR_SCONTEXT CContext,
4872 NDR_RUNDOWN userRunDownIn)
4874 FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn);
4877 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
4878 NDR_SCONTEXT CContext,
4880 NDR_RUNDOWN userRunDownIn,
4882 unsigned long Flags)
4884 FIXME("(%p %p %p %p %p %lu): stub\n",
4885 hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags);
4888 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
4889 unsigned long DataRepresentation)
4891 FIXME("(%p %08lx): stub\n", pBuff, DataRepresentation);
4895 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
4897 unsigned long DataRepresentation)
4899 FIXME("(%p %p %08lx): stub\n", hBinding, pBuff, DataRepresentation);
4903 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
4905 unsigned long DataRepresentation,
4907 unsigned long Flags)
4909 FIXME("(%p %p %08lx %p %lu): stub\n",
4910 hBinding, pBuff, DataRepresentation, CtxGuard, Flags);